/* ==========================================================================
   SEASON ONE · seasonone.miami
   A roupa do site. Miami Insider Club.
   Elephant Skin Group para BI Group USA · 1200 SW 2nd Ave, Brickell, Miami

   Duas regras da casa que este arquivo faz cumprir:
   1. Nenhum tamanho de tipo escrito no HTML. Só as classes .d1 a .d4 e os
      corpos declarados aqui.
   2. Nenhum travessão em conteúdo. Ponto, vírgula, meio-ponto ou quebra.
   ========================================================================== */

/* ---------- 0. FONTES, auto-hospedadas ---------- */
@font-face{font-family:"Heliora";src:url("../assets/fonts/heliora-thin.woff2") format("woff2");font-weight:100;font-display:swap}
@font-face{font-family:"Heliora";src:url("../assets/fonts/heliora-extralight.woff2") format("woff2");font-weight:200;font-display:swap}
@font-face{font-family:"Heliora";src:url("../assets/fonts/heliora-light.woff2") format("woff2");font-weight:300;font-display:swap}
@font-face{font-family:"Heliora";src:url("../assets/fonts/heliora-regular.woff2") format("woff2");font-weight:400;font-display:swap}
@font-face{font-family:"Inter";src:url("../assets/fonts/inter-latin-wght-normal.woff2") format("woff2");font-weight:100 900;font-style:normal;font-display:swap}

/* ---------- 1. RESET ---------- */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;background:var(--wine-deep)}
img,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
::selection{background:rgba(228,187,176,.30)}

/* ---------- 2. TOKENS ---------- */
:root{
  --display:"Heliora","Inter","Helvetica Neue",Arial,sans-serif;
  --ui:"Inter","Helvetica Neue",Helvetica,Arial,sans-serif;

  /* Miami Insider Club */
  --wine-deep:#380C18;
  --wine:#4A1220;
  --wine-mid:#7A1E32;
  --choc:#2A1216;
  --cream:#F4E7D7;
  --blush:#E4BBB0;
  --coral:#D9563C;
  --paper:#F0E2D2;
  --paper-2:#E6D3C0;

  /* --- A ESCALA OLHA AS DUAS MEDIDAS DA TELA. -----------------------------
     A rampa media só a LARGURA, e é por isso que a página quebrava justamente
     nas telas de trabalho: um notebook é largo e baixo. A 1337x595 de área
     útil — que é o que sobra de um 1366x768 depois da barra do navegador — a
     manchete recebia 96px de corpo por causa dos 1337 de largura, e a altura
     não tinha voz nenhuma na conta. O resultado, medido: o formulário passava
     220px do espaço livre, `residence` passava 94, `house` 62. O que passava ia
     parar embaixo do índice fixo do rodapé ou atrás da logo.

     Cada degrau agora é o MENOR entre a medida de largura e uma medida de
     altura. Numa tela alta nada muda — a medida de largura continua sendo a
     menor, e o desenho é exatamente o que era. Numa tela baixa a altura assume,
     e o texto encolhe na proporção do espaço que existe de verdade.

     `svh` e não `vh`: no celular a barra do navegador muda a altura da janela
     durante a rolagem, e uma rampa de tipo em `vh` faria o texto inteiro mudar
     de corpo a cada movimento da barra. `svh` é estável. */
  --d1:clamp(34px,min(7.2vw,12.4svh),104px);
  --d2:clamp(26px,min(4.4vw,6.4svh),62px);
  --d3:clamp(20px,min(2.8vw,4.9svh),38px);
  --d4:clamp(16px,min(1.8vw,3.1svh),25px);
  --t-lede:clamp(15px,min(1.35vw,2.4svh),20px);
  --t-body:clamp(14px,min(1.02vw,1.85svh),17px);
  --t-small:clamp(12px,min(.86vw,1.5svh),14px);
  /* O RÓTULO DEIXA DE SER UM NÚMERO FIXO.
     Toda a rampa desta página é fluida e este degrau era o único cravado em
     11px: numa tela de 2560 os rótulos ficavam do mesmo tamanho que numa de
     1366, e é por isso que a linha de código da capa ficou pequena demais para
     ler. O piso continua sendo 11, então em celular e em notebook baixo nada
     encolhe nem cresce; o teto é 15, que é onde caixa alta com entrelinha larga
     para de parecer legenda e começa a parecer texto. */
  --t-label:clamp(11px,min(.82vw,1.4svh),15px);

  --pad-x:clamp(22px,5vw,96px);
  --gap:clamp(18px,min(3.4vw,4.6svh),56px);

  /* O ESPAÇO QUE A MOBÍLIA FIXA OCUPA, declarado uma vez.
     O cabeçalho mora no alto e o índice de seção no pé, os dois presos à tela.
     Nenhum dos dois empurra nada, porque nenhum dos dois está no fluxo — então
     o conteúdo passava por baixo deles. Reservar essa altura como piso do
     respiro de cada seção é o que impede a colisão, e é a única forma que não
     depende de adivinhar o tamanho do texto. */
  /* o vermelho de erro do formulário: coral clareado, para passar contraste
     tanto no campo vinho quanto no campo papel */
  --erro:#F0A08C;

  --pe-topo:62px;
  --pe-base:44px;
  --band:clamp(72px,9vh,140px);
  --ease:cubic-bezier(.22,.61,.28,1);
  --maxw:1560px;
  --head-h:58px;
}

/* campos de cor. o site alterna entre o vinho e o papel */
.field{--bg:var(--wine);--bg2:var(--wine-deep);--ink:var(--cream);--mute:#C9948E;--line:rgba(244,231,215,.20);--accent:var(--blush)}
.field--deep{--bg:var(--wine-deep);--bg2:var(--choc)}
.field--mid{--bg:var(--wine-mid);--bg2:var(--wine)}
.field--choc{--bg:var(--choc);--bg2:#1B0C0F}
.field--paper{--bg:var(--paper);--bg2:var(--paper-2);--ink:var(--wine);--mute:#8A5548;--line:rgba(74,18,32,.20);--accent:var(--wine-mid);--erro:#A32B12}

/* CAMPO CORAL. A receita e a do deck, tela coral com tipo em vinho:
   `.f-o2-coral` e o bloco `coral-screen` do `style.css` do playbook.
   Sobre coral o proprio coral nao pode se marcar, entao o fio por baixo da
   palavra vira creme e o tique antes do rotulo vira vinho. */
.field--coral{--bg:var(--coral);--bg2:#C24A32;--ink:var(--choc);
  --mute:rgba(74,18,32,.82);--line:rgba(74,18,32,.30);--accent:var(--wine)}
/* Sobre coral o fio coral nao existe, entao ali ele vira creme e o tique do
   rotulo vira vinho. Precisa repetir a classe do tipo: `.d2 em` pesa mais que
   `.field--coral em`. */
.field--coral .d1 em,.field--coral .d2 em,.field--coral .d3 em,
.field--coral .d4 em,.field--coral .lede em,.field--coral .slip__msg em{
  background-image:linear-gradient(var(--cream),var(--cream));
}
.field--coral .code::before{background:var(--wine)}.field{background:var(--bg);color:var(--ink)}

body{
  font-family:var(--ui);
  font-size:var(--t-body);
  line-height:1.62;
  background:var(--wine-deep);
  color:var(--cream);
  font-synthesis:none;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
}

/* ---------- 3. TIPOGRAFIA ---------- */
.d1,.d2,.d3,.d4{font-family:var(--display);font-weight:200;letter-spacing:-.012em}
.d1{font-size:var(--d1);line-height:1.02;font-weight:100;letter-spacing:-.02em}
.d2{font-size:var(--d2);line-height:1.06}
.d3{font-size:var(--d3);line-height:1.14}
.d4{font-size:var(--d4);line-height:1.28}
.d1 em,.d2 em,.d3 em,.d4 em,.lede em,.slip__msg em{
  font-style:normal;color:inherit;
  background-image:linear-gradient(var(--coral),var(--coral));
  background-repeat:no-repeat;
  background-size:0% max(2px,.045em);   /* nasce sem fio: ele é traçado na entrada */
  background-position:0 92%;
  padding-bottom:.06em;
  transition:background-size 820ms var(--ease-rev) calc(var(--cd, var(--d, 0ms)) + 620ms);
}

.lede{font-size:var(--t-lede);line-height:1.5;max-width:58ch;color:var(--ink)}
.body{max-width:64ch}
.small{font-size:var(--t-small);line-height:1.55;color:var(--mute)}
.label{
  font-size:var(--t-label);letter-spacing:.18em;text-transform:uppercase;
  color:var(--mute);font-weight:400;
}
.mute{color:var(--mute)}
.accent{color:var(--accent)}

/* ---------- 4. ESTRUTURA ---------- */
.wrap{max-width:var(--maxw);margin:0 auto;padding-inline:var(--pad-x);width:100%}

/* Uma seção, uma tela. Fora o rodapé, toda seção mede a altura da janela e
   centra o conteúdo. Se o conteúdo passar disso, ele empurra, e é sinal de que
   a seção precisa ser dividida em duas, não de que a regra deve ceder. */
section.field{
  min-height:100svh;
  /* o `max` é o piso: por mais que a tela encolha, o respiro nunca fica menor
     que a mobília fixa que mora nessas duas bordas */
  display:flex;align-items:center;
  padding-top:max(var(--pe-topo),clamp(56px,9svh,150px));
  padding-bottom:max(var(--pe-base),clamp(46px,9svh,150px));
}
.band{
  padding-top:max(var(--pe-topo),clamp(56px,9svh,150px));
  padding-bottom:max(var(--pe-base),clamp(46px,9svh,150px));
}
.band--tight{
  padding-top:max(var(--pe-topo),clamp(48px,7svh,120px));
  padding-bottom:max(var(--pe-base),clamp(40px,7svh,120px));
}
.band--head{padding-top:max(var(--pe-topo),clamp(64px,11svh,170px))}
.rule{height:1px;background:var(--line);border:0;margin-block:clamp(28px,3.4vw,54px)}
.cols{display:grid;gap:var(--gap)}
.cols--2{grid-template-columns:repeat(2,1fr)}
.cols--3{grid-template-columns:repeat(3,1fr)}
.cols--4{grid-template-columns:repeat(4,1fr)}
.cols--sidebar{grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);align-items:start}
.stack-s > * + *{margin-top:14px}
.stack-m > * + *{margin-top:clamp(10px,min(2vw,2.5svh),30px)}
.stack-l > * + *{margin-top:clamp(20px,min(4vw,5.6svh),60px)}
/* um respiro acima do `mt-l`, para quando a manchete pesa e o bloco de baixo
   encosta nela. O `mt-l` dá 46px reais sob uma manchete de 62px, que é pouco. */
.mt-xl{margin-top:clamp(32px,min(6.4vw,9svh),104px)}

/* ---------- 5. CABEÇALHO ---------- */
/* A BARRA SAIU, E COM ELA A ÚLTIMA COISA QUE SEPARAVA A PÁGINA DA TELA.
   O cabeçalho era um campo de vidro com uma pluma embaixo, e um campo de vidro
   é uma faixa: ele corta a fotografia no alto e anuncia que ali começa uma
   interface. Sem ele restam duas marcas soltas sobre a cena — a logo e o gesto
   de abrir — e a fotografia chega até a borda de cima da tela.

   O cabeçalho inteiro fica transparente ao toque; só a logo e o ícone pegam o
   dedo. Sem isso, uma faixa invisível de 60 pixels de altura roubaria todo
   clique no alto da página. */
.head{
  position:fixed;inset:0 0 auto 0;z-index:60;
  display:flex;align-items:center;
  padding:18px var(--pad-x);
  color:var(--cream);
  pointer-events:none;
  transition:color 320ms var(--ease);
}
.head > *{pointer-events:auto}

/* A TINTA DA LOGO É A TINTA DO CAMPO EM QUE ELA PISA.
   Quem decide é o `site.js`, medindo. A transição é longa de propósito: uma
   troca de tinta instantânea no meio da rolagem parece um defeito de
   renderização; em meio segundo, parece luz mudando. */
.head--tinta-escura{color:var(--wine)}

/* UMA SOMBRA DE UM SUSPIRO, E ELA EXISTE POR UMA MEDIÇÃO.
   A troca de tinta acerta onde o fundo é estável — o campo coral, as placas, o
   mapa. Onde ela não tem como acertar é na galeria: os quadros passam por baixo
   da marca alternando claro e escuro a cada cem pixels de rolagem, e uma tinta
   que perseguisse isso PISCARIA. A escolha foi deixá-la atrasar de propósito, e
   o preço é que por uma fração de segundo a marca pode estar em creme em cima
   de uma sala bege.

   A sombra cobre exatamente essa fração. Sobre fundo escuro ela é invisível —
   preto sobre preto; sobre fundo claro ela devolve à letra o contorno que a
   tinta ainda não deu. Não é um véu atrás da marca: é o mesmo recurso de
   sempre, um halo do tamanho da haste. */
.head__mark{display:flex;align-items:center;gap:10px;flex:0 0 auto}
.head__logo{
  display:block;height:19px;width:auto;color:inherit;
  filter:drop-shadow(0 1px 2px rgba(42,18,22,.85)) drop-shadow(0 0 16px rgba(42,18,22,.7));
}
.head--tinta-escura .head__logo{filter:drop-shadow(0 1px 2px rgba(244,231,215,.8)) drop-shadow(0 0 16px rgba(244,231,215,.65))}
.burger span{filter:drop-shadow(0 1px 2px rgba(42,18,22,.8)) drop-shadow(0 0 12px rgba(42,18,22,.6))}
.head--tinta-escura .burger span{filter:drop-shadow(0 1px 2px rgba(244,231,215,.75)) drop-shadow(0 0 12px rgba(244,231,215,.6))}
body.menu-open .head__logo,body.menu-open .burger span{filter:none}

.burger{display:block;width:34px;height:22px;position:relative;color:inherit}
/* O DESENHO TEM 34x22; O ALVO DO DEDO TEM 44x44.
   Duas barras de um pixel são um desenho bonito e um alvo ruim: 34 por 22 é
   menos da metade da área que a Apple pede para qualquer controle, e agora este
   botão é a única navegação que existe em qualquer tela. O alvo cresce por um
   pseudo-elemento posicionado, que não ocupa espaço nenhum na diagramação. */
.burger::before{
  content:"";position:absolute;left:50%;top:50%;
  width:44px;height:44px;transform:translate(-50%,-50%);
}
.burger span{
  position:absolute;left:0;right:0;height:1px;background:currentColor;
  transition:transform 420ms var(--ease),opacity 200ms,background 560ms var(--ease);
}
.burger span:nth-child(1){top:4px}
.burger span:nth-child(2){bottom:4px}
/* aberto, o ícone é um X — e ele fica SEMPRE claro, porque o que está atrás
   dele deixou de ser a página e passou a ser o véu do menu */
body.menu-open .head{color:var(--cream)}
body.menu-open .burger span:nth-child(1){transform:translateY(7px) rotate(45deg)}
body.menu-open .burger span:nth-child(2){transform:translateY(-7px) rotate(-45deg)}

/* --- O MENU. -------------------------------------------------------------
   Não é uma tela nova por cima da página: é a MESMA página, fora de foco. O
   `backdrop-filter` desfoca o que está atrás em vez de cobrir, então a cena
   continua ali — reconhecível, e claramente em segundo plano. É a diferença
   entre trocar de assunto e recuar um passo.

   O véu de cor existe por necessidade e não por estilo: desfocar não escurece,
   e sobre um quadro claro da galeria o texto creme sumiria. A camada de vinho
   a 42% garante o contraste sem fechar a imagem. */
.menu{
  position:fixed;inset:0;z-index:55;
  /* A LISTA MORA DO LADO DO ÍCONE.
     O gesto começa no canto de cima à direita e a resposta abre embaixo dele,
     no mesmo eixo: a mão não atravessa a tela para ler o que ela mesma pediu.
     E a borda direita alinhada dá à lista a mesma margem que a marca tem do
     outro lado, o que fecha a composição em vez de deixá-la pendendo. */
  display:flex;flex-direction:column;justify-content:center;align-items:flex-end;
  text-align:right;
  padding:calc(64px + var(--pad-x)) var(--pad-x) var(--pad-x);
  background:rgba(56,12,24,.42);
  -webkit-backdrop-filter:blur(30px) saturate(150%);
  backdrop-filter:blur(30px) saturate(150%);
  opacity:0;visibility:hidden;
  transition:opacity 520ms var(--ease),visibility 0s linear 520ms;
}
body.menu-open .menu{
  opacity:1;visibility:visible;
  transition:opacity 420ms var(--ease);
}
/* o índice de seção mora ACIMA do menu na pilha, e mostrar em que seção a
   pessoa estava enquanto ela escolhe outra não serve para nada */

/* onde não há `backdrop-filter` o véu fecha, porque um menu semitransparente
   sobre uma página nítida é ilegível */
@supports not ((backdrop-filter:blur(2px)) or (-webkit-backdrop-filter:blur(2px))){
  .menu{background:rgba(56,12,24,.97)}
}

.menu__lista{display:flex;flex-direction:column;gap:clamp(2px,.8vh,12px)}
/* `block` e não `flex`: o número é um `inline-block` de largura fixa dentro da
   linha. Com `flex`, cada palavra que o SplitText cria viraria um item da
   caixa e a frase se espalharia pela linha inteira. */
.menu a{
  display:block;
  font-family:var(--display);font-weight:100;
  font-size:clamp(30px,6.6vw,72px);line-height:1.18;
  color:var(--cream);
  transition:color 300ms var(--ease);
}
/* O número vira sufixo sem trocar a marcação: a ordem no HTML continua sendo
   número-e-depois-nome, que é como os três dicionários de idioma escrevem
   esses itens — mexer nisso seria mexer em três arquivos de tradução para
   resolver um problema de desenho.

   Ele sai do fluxo e encosta na margem direita, formando a coluna alinhada que
   os nomes, de comprimento variável, não formariam sozinhos. Centrado na
   altura da linha, e não pendurado no topo dela: um índice que flutua na altura
   das maiúsculas parece expoente, e não numeração. */
.menu a{position:relative;padding-right:clamp(38px,4.4vw,64px)}
.menu a .n{
  position:absolute;right:0;top:50%;transform:translateY(-50%);
  font-family:var(--ui);font-weight:400;
  font-size:var(--t-label);letter-spacing:.18em;
  color:var(--blush);
}
.menu a:hover{color:var(--blush)}

/* --- OS IDIOMAS, NO CABEÇALHO. -------------------------------------------

   Eles moravam no pé do menu. Numa página que se apresenta em três línguas,
   pôr a troca de idioma atrás de um gesto é esconder a mais óbvia das escolhas
   — e quem chega em espanhol não abre um menu em inglês para procurar.

   A TINTA É `currentColor`, e isso não é preguiça: o cabeçalho troca de tinta
   conforme o campo que passa por baixo dele (`head--tinta-escura` desce a
   página inteira para o vinho), e o `site.js` decide isso medindo. Escrever a
   cor aqui seria criar uma segunda verdade que a medição não governa — foi o
   erro que o instrumento cometeu no campo coral, e que custou creme sobre
   coral a 3,23:1.

   A SOMBRA É A MESMA DO ÍCONE DO MENU, pelo mesmo motivo: estes três rótulos
   passam por cima de fotografia, e um rótulo de onze pixels sobre uma foto
   clara desaparece sem ela. Ela inverte junto com a tinta. */
.head .lang{
  display:flex;align-items:center;gap:clamp(12px,1.1vw,18px);
  margin-left:auto;margin-right:clamp(18px,2.2vw,36px);
}
.head .lang button{
  font-family:var(--ui);font-size:var(--t-label);font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;
  color:currentColor;opacity:.72;
  padding:6px 2px;
  transition:opacity 300ms var(--ease);
  /* A SOMBRA É A CONTRASTE, e não enfeite. Medido sobre o campo coral, creme a
     52% dava 1,71:1 contra o fundo — o mesmo buraco em que o instrumento caiu
     ali. A opacidade subiu para 72% e o halo ficou fechado e opaco: é ele que
     cerca a letra, e é contra ele que o olho lê. */
  text-shadow:0 1px 2px rgba(30,10,14,.95),0 0 7px rgba(30,10,14,.9),0 0 14px rgba(30,10,14,.55);
}
.head--tinta-escura .lang button{text-shadow:0 1px 2px rgba(244,231,215,.9),0 0 7px rgba(244,231,215,.85),0 0 14px rgba(244,231,215,.5)}
body.menu-open .lang button{text-shadow:none}
.head .lang button:hover{opacity:.82}
/* NO CELULAR OS TRÊS SÃO ALVO, e não enfeite: a barra é a única forma de trocar
   de língua sem abrir menu. A 72% o rótulo apagado media 2,2:1 sobre a parte
   clara do render — o halo segura o tipo, mas não a mancha. Subir a opacidade
   é mais barato que engrossar o halo, que a essa altura já viraria caixa. */
@media (max-width:880px){
  .head .lang button{opacity:.88}
}
.head .lang button[aria-pressed="true"]{opacity:1}
.head .lang button:focus-visible{outline:1px solid currentColor;outline-offset:3px}

/* O ALVO DO DEDO, como no ícone do menu: o desenho tem onze pixels de altura e
   o dedo precisa de quarenta e quatro. Cresce por pseudo-elemento, que não
   ocupa espaço nenhum na diagramação — senão os três rótulos se afastariam. */
.head .lang button{position:relative}
.head .lang button::before{
  content:"";position:absolute;left:50%;top:50%;
  width:clamp(34px,4vw,44px);height:44px;transform:translate(-50%,-50%);
}

@media (max-width:560px){
  .menu a{font-size:clamp(28px,8.4vw,44px)}
}

/* ---------- 6. HERO ---------- */
/* A CAPA CENTRALIZA, e isso muda o que ela diz.
   Ancorada embaixo, a manchete lia como legenda da fotografia: a imagem era o
   assunto e o texto vinha depois dela, no rodapé. Centralizada, os dois passam
   a ocupar o mesmo lugar na tela — a frase é o assunto e a fotografia é onde
   ela acontece.

   E o contraste foi CONFERIDO, não suposto: o véu do `::after` é mais fraco
   justo no meio (.28 contra .72 no topo e .88 na base), então a primeira
   suspeita era que a manchete perdesse legibilidade ao subir para lá. Medido a
   1920x1080, com o texto escondido e só o fundo na conta: luminância média de
   0.038 atrás da manchete, o que dá 9.5:1 contra o creme, e 5.6:1 mesmo nos 10%
   mais claros da área. A fotografia é escura naquela faixa por conta própria, e
   o véu fraco não chega a ser um problema. Se a fotografia da capa trocar por
   uma mais clara no meio, esta conta precisa ser refeita. */
section.hero{position:relative;min-height:100svh;display:flex;align-items:center;overflow:hidden;padding-block:0}
.hero__media{position:absolute;inset:0}
.hero__media img{width:100%;height:100%;object-fit:cover}
.hero__media::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(56,12,24,.72) 0%,rgba(56,12,24,.28) 38%,rgba(56,12,24,.88) 100%);
}

/* ---------- 6.1 O FILME DA CAPA ----------
   Três clipes de cinco segundos, mudos, um puxando o outro e voltando ao
   primeiro. Eles vivem ENTRE a fotografia e o véu vinho: o véu que já existia
   continua por cima, então o tom avermelhado da capa é o mesmo de antes, e não
   um tratamento novo em cima do vídeo.

   O véu extra é por clipe, e foi MEDIDO, não escolhido. Com o degradê atual e
   nada mais, o pior 5% dos pixels atrás da manchete dá 3,96:1 no clipe da
   noite, 2,52:1 no da esquina e 2,78:1 no da fachada — os dois últimos abaixo
   do 3:1 que o texto de cartaz precisa. Cada clipe ganhou então a menor dose de
   vinho que devolve 3,6:1 no pior quadro: nada na noite, .22 na esquina, .17 na
   fachada. No retrato do celular o recorte fecha em cima das lâminas iluminadas
   e a conta muda, então ali as doses sobem para .28 e .30. Se trocarem um
   clipe, esta conta precisa ser refeita — o script está em `_scripts`. */
.hero__filme{
  position:absolute;inset:0;opacity:0;
  /* a mesma pousada da fotografia, para que o filme não entre por outro caminho */
  transform:scale(1.06);
  transition:opacity 900ms var(--ease-rev), transform 2200ms var(--ease-rev);
}
.sec-in .hero__media .hero__filme{transform:scale(1)}
.hero__filme.is-ligado{opacity:1}
.hero__clipe{position:absolute;inset:0;opacity:0;transition:opacity var(--cruz,700ms) linear}
.hero__clipe.is-agora{opacity:1}
.hero__clipe video{display:block;width:100%;height:100%;object-fit:cover}
/* O véu de cada clipe mora DENTRO dele, e por isso ele entra e sai junto com o
   clipe na mistura. Fosse uma camada só por cima, a dose do clipe que chega
   apareceria no clipe que ainda está saindo. */
.hero__clipe::after{content:"";position:absolute;inset:0;background:rgba(56,12,24,var(--veu,0))}
.hero__inner{position:relative;z-index:2;width:100%;padding-block:clamp(60px,9vh,120px)}
/* A LINHA DE CÓDIGO DA CAPA É A PRIMEIRA COISA QUE ALGUÉM LÊ NA PÁGINA, e lê
   por cima de um filme. Ela ganha um degrau a mais que os outros rótulos e
   perde entrelinha: `.30em` de espaçamento em caixa alta é assinatura, não
   leitura, e sobre imagem em movimento a assinatura vira ruído. Com `.24em` as
   palavras voltam a ser palavras. */
#capa .code{
  font-size:clamp(12px,min(1.05vw,1.8svh),19px);
  letter-spacing:.24em;
}
section.hero--short{min-height:100svh}

/* ---------- 6.2 A TELA DA POSIÇÃO ----------
   O cliente pediu fundo mais forte aqui: "a marca é energia, esta tela está
   entediante". Ela estava mesmo: campo laranja liso, três linhas de tipo no
   alto, dois terços de nada embaixo.

   O desenho é o que ele mesmo rabiscou: a frase quebra mais curta à esquerda e
   um retângulo à direita traz um MOSAICO de cinco imagens. Chegamos aqui depois
   de quatro tentativas que valem ficar registradas, porque cada uma ensinou o
   que não fazer:
     · grafismo desenhado sozinho — campo desenhado é textura, não é imagem;
     · foto nítida sangrando na borda — bela composição, manchete espremida;
     · foto desfocada com véu coral — o fundo sob o texto caía para 2,33:1;
     · foto desfocada assada em campo escuro — funcionava, mas trocava a cor da
       tela, e a cor coral é o batimento da página inteira.
   O mosaico resolve as duas coisas ao mesmo tempo: o coral volta e a energia
   vem das imagens, que é de onde ela deveria vir desde o começo.

   AS CINCO IMAGENS SÃO CINCO MOMENTOS, e não cinco fotos do prédio: a rua de
   Brickell ao anoitecer, o café no balcão de manhã, a porta do restaurante de
   noite, a taça no bar, o batom no espelho. A frase diz que isto não é um
   prédio com mais, é um jeito de tirar mais de Miami. Um mosaico do edifício
   contradiria a frase; um mosaico do dia a prova.

   O TIPO VIROU CHOC. `--ink` do campo coral era `#7A1E32`, o vinho médio, que
   sobre coral dá 2,60:1 e nunca fechou o 3:1 que texto de cartaz pede. O
   playbook usa `--o2-choc` (#2A1216) na sua própria tela coral, e ali são
   4,47:1. Não é escolha de gosto: é o valor que já estava documentado, e ele
   resolve a única coisa desta tela que estava tecnicamente errada. */
/* `34vw` E NÃO `34%`, e a diferença não é cosmética.
   Enquanto o mosaico era absoluto na seção, aquele `34%` media contra a largura
   da SEÇÃO, que é a janela inteira. Ao virar coluna de grade dentro do `.wrap`,
   a mesma conta passou a medir contra a largura da COLUNA, que tem `max-width`
   e respiro: numa tela de 2000 o mosaico caiu de 580 para 465 pixels, e as
   peças ficaram visivelmente mais estreitas. `vw` devolve a referência original
   e a proporção de antes, que é a que o cliente aprovou. */
.posicao{position:relative;overflow:hidden;--mos:clamp(250px,34vw,580px)}
/* O campo ganha direção de luz. `--bg2` do campo coral já existia nos tokens e
   nunca tinha sido usado. Vai no `.campo` e não na seção porque quem pinta a
   cor de uma seção aqui é o span que o `site.js` injeta, e a própria seção é
   `background:transparent`. */
.posicao .campo{
  background-image:radial-gradient(152% 128% at 8% 2%,
    #EE7152 0%,#E06044 36%,var(--coral) 74%,#CD5237 92%,var(--bg2) 100%);
}
/* A FRASE E O MOSAICO SÃO DUAS COLUNAS DA MESMA CAIXA, e não duas coisas
   posicionadas cada uma por conta.

   Antes o mosaico era absoluto na seção, centrado com `top:50%`, e a frase
   vivia no `.wrap`. Em teoria os dois centros coincidem; na prática coincidem
   só enquanto a seção mede exatamente uma janela, e basta a seção crescer um
   fio — um pin recalculado, uma barra de navegador, um nível de zoom — para os
   dois passarem a se referir a alturas diferentes. Foi o que apareceu na tela
   do cliente: as imagens descendo em relação ao texto.

   Numa grade de duas colunas com `align-items:center` esse desacordo deixa de
   ser possível: os dois são centrados pela MESMA caixa, e quem garante é o
   navegador. De quebra somem três remendos — a reserva de `padding-right` para
   o mosaico não passar por baixo da frase, o `right` calculado para achar a
   borda da coluna em telas largas, e o `translateY(-50%)`. */
.posicao .wrap{
  position:relative;z-index:3;
  display:grid;grid-template-columns:minmax(0,1fr) var(--mos);
  column-gap:clamp(28px,3vw,72px);align-items:center;
}

/* A QUEBRA DA FRASE É ESCRITA, NÃO SORTEADA.
   O cliente aprovou a frase em quatro linhas, quebrando depois de "not", de
   "more." e de "get". Quebra assim não se pede à largura: se pede ao texto. As
   quatro linhas estão nos `<br>` do HTML e dos dois dicionários, e cada língua
   tem a sua — em português a terceira linha é a mais longa, em inglês é a
   segunda.

   `max-width` sai daqui. A `.cartaz--m` limita a 22ch, e 22ch é uma medida que
   depende do corpo do tipo: com a quebra escrita, esse limite só criaria um
   segundo lugar decidindo onde a linha termina, e os dois discordariam.

   A classe `frase-presa` é posta pelo `lp.js`, nunca pelo HTML. Ela é que
   proíbe a quebra automática, e proibir sem alguém garantindo que o texto cabe
   é como arrancar o freio: sem script, a frase volta a quebrar sozinha, que é
   feio mas é legível. Com script, o bloco 8 do `lp.js` mede e encolhe. */
.posicao h2{max-width:none}
.posicao h2.frase-presa{white-space:nowrap}

/* O MOSAICO.
   Cinco imagens em duas colunas e três fileiras, com uma delas ocupando duas
   fileiras. A que se estica é a da rua, porque é a única panorâmica de cidade
   do jogo e é ela que ancora o retângulo; as outras quatro são cenas de perto e
   funcionam pequenas.

   A altura é `min` de duas medidas. Numa tela alta manda a fração da janela;
   numa tela baixa manda o teto em pixels, senão o mosaico cresce junto com a
   janela e empurra a manchete para fora da seção. É a mesma regra da rampa de
   tipo do projeto: o menor entre uma medida de tela e um limite. */
.posicao__mosaico{
  position:relative;z-index:2;
  height:min(74svh,700px);
  /* `minmax(0, …fr)` E NÃO `…fr` SECO, e isto não é preciosismo de sintaxe.
     Um `1fr` é `minmax(auto, 1fr)`, e esse `auto` quer dizer "nunca menor que o
     conteúdo". O conteúdo aqui é uma imagem cujo tamanho intrínseco passa de
     setecentos pixels de altura, então as fileiras se recusavam a encolher e as
     peças vazavam para fora da caixa de 320 pixels do empilhado — medido: uma
     célula de 766px dentro de um mosaico de 320. Com o mínimo em zero, quem
     manda é a fração, que é o que se quis dizer desde o começo. O `min-height`
     nas células é a mesma conversa, um nível abaixo. */
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  grid-template-rows:minmax(0,1.18fr) minmax(0,.92fr) minmax(0,1.04fr);
  gap:clamp(5px,.55vw,9px);
}
/* SEM `overflow:hidden` E SEM FUNDO, e as duas coisas pelo mesmo motivo.
   Enquanto o desfoque morava na imagem DENTRO de uma célula que recortava, a
   parte macia do borrão batia na borda do recorte e era cortada a prumo: a peça
   voava desfocada por dentro e com quatro arestas afiadas por fora, que é
   exatamente o contrário do que desfoque quer dizer. O texto desta mesma tela,
   que o `cena.js` desfoca, não tem esse problema porque nada o recorta.
   Agora o desfoque é da CÉLULA, e ela não recorta nada: `object-fit:cover` já
   faz o corte dentro da caixa da imagem, então não há o que transbordar. O
   fundo da célula saiu junto — desfocado, ele viraria uma auréola escura em
   volta da foto, e a foto tem que diluir no coral, não numa moldura. */
.posicao__mosaico figure{position:relative;min-width:0;min-height:0}
.posicao__mosaico img{width:100%;height:100%;object-fit:cover;display:block}

/* ---- O VOO DAS IMAGENS ----------------------------------------------------
   As cinco entram de fora da tela e pousam na grade. A máscara é a própria
   seção: ela é `overflow:hidden`, então enquanto o ladrilho está lá fora ele
   simplesmente não existe, e o campo coral é tudo o que se vê. Não há máscara
   nova para manter — é o recorte que a seção já tinha.

   A DIREÇÃO DE CADA UM É A DO LUGAR ONDE ELE VAI PARAR, e essa é a única regra
   aqui. Os da coluna esquerda vêm de cima e de baixo, o de cima puxado mais
   para a esquerda; os da direita entram pela borda direita, o de cima um pouco
   mais alto e o de baixo um pouco mais baixo. Quem vem da direção certa parece
   estar chegando; quem vem de qualquer direção parece estar sendo jogado.

   Três coisas acontecem no mesmo gesto, e nenhuma delas sozinha:
   · a POSIÇÃO, que é o gesto principal;
   · a ESCALA, que começa em 1,25 e cai para 1 — é o que faz parecer que a peça
     está caindo em direção à página em vez de deslizando sobre ela;
   · o DESFOQUE, que começa em 12px e some. Foco é a coisa que o olho usa para
     saber a que distância uma coisa está: sem ele a escala vira zoom, com ele
     vira profundidade. O desfoque acaba ANTES do movimento, porque uma peça
     ainda borrada parada no lugar parece defeito.
   A rotação subiu duas vezes a pedido do cliente: de quatro graus para doze, e
   de doze para vinte e um a vinte e sete. Com quatro a peça parecia apenas mal
   encaixada. Com doze ela já girava, mas discretamente demais para alguém
   reparar. Com vinte e cinco a rotação vira parte do gesto: a peça chega de
   lado e se endireita, e a última coisa que ela faz antes de pousar é ficar
   reta. Foi preciso conferir de novo as posições de partida depois de subir:
   caixa girada é caixa mais larga, e ninguém pode começar já dentro da tela.

   `filter` termina em `none` e não em `blur(0)`: zero de desfoque ainda é um
   filtro ativo, e um filtro ativo é uma camada de composição que o navegador
   segura para sempre depois que a animação acabou. Pela mesma razão não há
   `will-change` aqui: uma transição de `transform` já promove o elemento
   sozinha enquanto dura, e um `will-change` escrito na folha são cinco camadas
   penduradas para o resto da visita por causa de um voo de um segundo e meio. */
/* `translate`, `rotate` E `scale` SEPARADOS, e não um `transform` só.
   Um `transform` é uma propriedade única: as três coisas dentro dele são
   obrigadas a compartilhar a mesma curva e o mesmo tempo. Só que elas não
   contam a mesma história. O deslocamento é o gesto e vai do começo ao fim; o
   GIRO é o que faz a peça parecer estar chegando, e por isso ele precisa
   SEGURAR e endireitar só no último trecho, junto com o desfoque. Com as três
   propriedades separadas cada uma anda no tempo dela, e o CSS moderno as compõe
   na ordem translate, rotate, scale, que é exatamente a que estava escrita à
   mão antes.
   O giro e o desfoque compartilham o mesmo atraso de propósito: a peça chega
   torta e borrada, e as duas coisas se resolvem no instante em que ela pousa. */
.posicao__mosaico figure{
  translate:var(--tx,0) var(--ty,0);
  rotate:var(--rot,0deg);
  scale:var(--sc,1);
  filter:blur(var(--desfoque));
  transition:translate 1500ms cubic-bezier(.16,.74,.22,1) var(--cd,0ms),
             scale 1500ms cubic-bezier(.16,.74,.22,1) var(--cd,0ms),
             rotate 1080ms cubic-bezier(.3,.7,.3,1) calc(var(--cd,0ms) + 420ms),
             filter 1080ms cubic-bezier(.3,.7,.3,1) calc(var(--cd,0ms) + 420ms);
}
/* O DESFOQUE MORA NUMA VARIÁVEL SÓ, porque ele é lido em dois lugares — o modo
   tempo aqui e o modo rolagem lá embaixo — e um número escrito duas vezes é um
   número que vai ficar diferente de si mesmo na próxima vez que alguém mexer.

   Ele é aplicado na CÉLULA e não na imagem. Na imagem, dentro de uma célula que
   recortava, a parte macia do borrão morria na borda do recorte: a peça voava
   desfocada por dentro e afiada por fora. Na célula, com o recorte fora do
   caminho, o borrão se espalha para todos os lados e a peça se dilui no coral —
   que é como o texto desfocado desta mesma tela se comporta, e era esse o
   parâmetro. */
.posicao__mosaico{--desfoque:48px}
section.sec-in .posicao__mosaico figure{translate:none;rotate:none;scale:none;filter:none}

/* A geometria de cada peça mora aqui e só aqui. `--cd` é a cascata em
   milissegundos, para o modo tempo; `--s` é a mesma cascata em fração da
   entrada, para o modo rolagem. */
.posicao__mosaico figure:nth-child(1){--tx:-14vw;--ty:-98svh;--rot:-24deg;--sc:1.28;--cd:0ms;--s:0}
.posicao__mosaico figure:nth-child(2){--tx:78vw;--ty:-24svh;--rot:22deg;--sc:1.24;--cd:150ms;--s:.10}
.posicao__mosaico figure:nth-child(3){--tx:84vw;--ty:0px;--rot:27deg;--sc:1.26;--cd:300ms;--s:.20}
.posicao__mosaico figure:nth-child(4){--tx:-9vw;--ty:96svh;--rot:21deg;--sc:1.30;--cd:220ms;--s:.15}
.posicao__mosaico figure:nth-child(5){--tx:76vw;--ty:26svh;--rot:-25deg;--sc:1.22;--cd:430ms;--s:.28}

/* ---- O MESMO VOO, MAS PUXADO PELA ROLAGEM ---------------------------------
   O cliente pediu que o voo aconteça JUNTO COM O SCROLL, e nesta página isso
   já tem um dono: o `cena.js` prende cada seção e forma o conteúdo dela em
   função do quanto a pessoa rolou. Então o voo entra nessa mesma linha do
   tempo em vez de inventar uma segunda.

   A cena escreve UMA variável, `--voo`, de 0 a 1. É tudo o que ela sabe sobre
   o mosaico. A geometria — direção, rotação, escala, desfoque, cascata — fica
   aqui, e é a mesma do modo tempo, lida das mesmas custom properties. Uma
   metade sabe quando; a outra sabe onde; nenhuma das duas precisa saber as
   duas coisas.

   `--a` é o avanço desta peça: a fração de `--voo` que já passou do começo
   dela, recortada entre 0 e 1. `--f` é o que falta, e é por ele que a
   distância, o ângulo e a sobra de escala são multiplicados. O desfoque SEGURA E SÓ
   DEPOIS SOLTA: `--ab` ignora os primeiros 30% do voo da peça e gasta os outros
   70% limpando. Antes ele corria na frente do movimento e a peça chegava nítida
   a um terço do caminho, voando afiada o resto do trajeto — que foi o que o
   cliente viu. A regra que eu estava seguindo, "peça borrada parada no lugar
   parece defeito", continua valendo: por isso o desfoque termina no instante em
   que o movimento termina, e não depois. Terminar antes nunca foi parte dela.

   Quem decide qual dos dois modos vale é a classe `voo-na-cena`, que o
   `cena.js` põe na seção só quando ela PRENDE — ou seja, no desktop. Sem ela
   vale o modo tempo acima: é o que roda no celular, onde a seção não prende e a
   linha do tempo dela cabe em pouco mais de duzentos pixels de rolagem, e é
   também o que roda quando o GSAP não carrega. */
html.com-cena .posicao.voo-na-cena .posicao__mosaico figure{
  --a:clamp(0,calc((var(--voo,1) - var(--s,0)) / var(--dur,.62)),1);
  --f:calc(1 - var(--a));
  --ab:clamp(0,calc((var(--a) - .30) / .70),1);
  translate:calc(var(--tx,0px) * var(--f)) calc(var(--ty,0px) * var(--f));
  /* o giro segue `--ab` e não `--f`: ele acompanha o desfoque, segura enquanto a
     peça viaja e só se endireita no fim. Seguindo `--f` ele já estaria quase
     reto na metade do caminho, que foi o que o cliente viu como "discreto". */
  rotate:calc(var(--rot,0deg) * (1 - var(--ab,1)));
  scale:calc(1 + (var(--sc,1) - 1) * var(--f));
  filter:blur(calc(var(--desfoque) * (1 - var(--ab,1))));
  transition:none;
}
/* Passada a seção, o desfoque some de vez em vez de ficar em `blur(0px)`: zero
   de desfoque ainda é um filtro ativo, e filtro ativo é camada de composição
   que o navegador segura. `cena-viva` é a própria cena dizendo se esta seção
   ainda é a que está no ar. */
html.com-cena section.posicao.voo-na-cena:not(.cena-viva) .posicao__mosaico figure{filter:none}
.posicao__mosaico figure:nth-child(1){grid-column:1;grid-row:1 / 3}
.posicao__mosaico figure:nth-child(2){grid-column:2;grid-row:1}
.posicao__mosaico figure:nth-child(3){grid-column:2;grid-row:2}
.posicao__mosaico figure:nth-child(4){grid-column:1;grid-row:3}
.posicao__mosaico figure:nth-child(5){grid-column:2;grid-row:3}
/* os enquadramentos: cada corte foi escolhido olhando, não pelo centro */
.posicao__mosaico figure:nth-child(2) img{object-position:62% 50%}
.posicao__mosaico figure:nth-child(3) img{object-position:54% 46%}
.posicao__mosaico figure:nth-child(4) img{object-position:44% 42%}
.posicao__mosaico figure:nth-child(5) img{object-position:56% 40%}

/* QUANDO A COMPOSIÇÃO DEIXA DE CABER, o mosaico desce para baixo da frase e
   ocupa a largura inteira. A manchete fica em cima, sobre coral limpo.

   A condição não é só largura: é largura OU retrato. Num tablet em pé, 900 por
   1200, a largura passa de 880 e a regra de duas colunas valia — o mosaico
   virava uma tira de 300px e a manchete um bloco espremido do lado. Duas
   colunas lado a lado só fazem sentido numa janela deitada. */
@media (max-width:880px), (max-width:1180px) and (orientation:portrait){
  /* uma coluna só, e o mosaico vira a segunda LINHA: a frase em cima, sobre
     coral limpo, e as imagens no pé. Quem separa os dois é o `row-gap` da
     mesma grade, não mais um `padding-bottom` calculado à mão para reservar a
     altura de um bloco absoluto. */
  .posicao .wrap{grid-template-columns:minmax(0,1fr);row-gap:clamp(26px,5svh,60px)}
  .posicao__mosaico{
    height:min(40svh,320px);
    grid-template-rows:minmax(0,1fr) minmax(0,1fr);
  }
  .posicao__mosaico figure:nth-child(1){grid-column:1;grid-row:1 / 3}
  .posicao__mosaico figure:nth-child(2){grid-column:2;grid-row:1}
  .posicao__mosaico figure:nth-child(3){grid-column:2;grid-row:2}
  .posicao__mosaico figure:nth-child(4),
  .posicao__mosaico figure:nth-child(5){display:none}
  /* Empilhado, o mosaico mora no pé da tela, e o ladrilho alto medido com a
     escala de partida passa de quatrocentos pixels: a `-98svh` do desenho largo
     deixava a barra de baixo dele aparecendo no alto da tela antes da hora.
     Aqui a distância é maior, e a regra segue sendo a mesma: ninguém começa
     dentro da máscara. */
  .posicao__mosaico figure:nth-child(1){--ty:-138svh}
}

/* quem pediu menos movimento recebe o mosaico posto, sem voo */
@media (prefers-reduced-motion:reduce){
  .posicao__mosaico figure{translate:none;rotate:none;scale:none;filter:none;transition:none}
}

/* ---------- 6.3 A TELA DA LOCALIZAÇÃO ----------
   Texto do cliente, para abrir a seção do mapa. Cento e quarenta palavras numa
   página cujas outras telas de texto carregam de quinze a vinte e cinco, então
   a tela é desenhada PARA esse tamanho em vez de tentar escondê-lo.

   DUAS COLUNAS, DUAS VOZES. À esquerda ficam as duas frases que o cliente
   mandou em negrito, a de abertura e a de fecho — que são a mesma ideia dita
   duas vezes, e é justamente o vazio entre elas que faz a segunda soar como
   conclusão da primeira. À direita fica o caminho de uma à outra, em corpo de
   leitura: o ritmo do dia, a virada, o que é Brickell, o que a casa faz com
   isso.

   A coluna da direita é a MAIOR das duas (`cols--sidebar` dá 1 para 1,15), o
   contrário do que a hierarquia sugeriria. É de propósito: a voz alta não
   precisa de espaço, precisa de silêncio em volta; a voz baixa precisa de
   medida para ser lida. */
/* Três itens, e a colocação é escrita à mão: a voz alta em cima à esquerda, o
   texto de leitura ocupando as duas fileiras da direita, e o fecho no pé da
   esquerda. A fileira de baixo é `1fr` para receber toda a sobra de altura, e
   é ela que empurra o fecho para o pé — o vazio entre as duas frases é o que
   faz a segunda soar como conclusão da primeira. */
.cidade__ato--voz{column-gap:clamp(32px,5vw,110px);grid-template-rows:auto 1fr;align-items:stretch}
.miami__voz{grid-column:1;grid-row:1}
.miami__corpo{grid-column:2;grid-row:1 / 3}
.miami__fecho{grid-column:1;grid-row:2;align-self:end;margin-top:clamp(30px,4.4svh,64px)}
/* a voz baixa centra na altura da voz alta. As duas colunas se esticam à mesma
   altura e o texto de leitura fica no meio dela: assim o bloco da direita não
   fica pendurado no alto com um vazio embaixo, e a linha de cima dele cai perto
   da manchete, que é onde o olho está quando chega aqui */
.miami__corpo{display:flex;flex-direction:column;justify-content:center}
/* o corpo não precisa dos 64ch da regra geral: numa coluna de duas, a medida
   que a coluna já dá é mais curta do que isso, e travar em 64 só criaria uma
   segunda régua discordando da primeira */
.miami__corpo .body{max-width:none}
.miami__corpo .lede{max-width:none}

/* Tela estreita: uma coluna só, na ordem em que se lê. O fecho perde o
   `margin-top:auto` — empurrar para o pé de uma caixa que agora tem a altura do
   próprio conteúdo não empurra para lugar nenhum — e ganha um respiro escrito. */
@media (max-width:880px), (max-width:1180px) and (orientation:portrait){
  .cidade__ato--voz{grid-template-columns:minmax(0,1fr);grid-template-rows:none;
    row-gap:clamp(26px,4svh,52px);align-items:start}
  /* cai tudo na ordem em que se lê: voz, texto, fecho */
  .miami__voz,.miami__corpo,.miami__fecho{grid-column:auto;grid-row:auto}
  .miami__corpo{display:block}
  .miami__fecho{align-self:auto;margin-top:0}
}

/* ---------- 7. COMPONENTES ---------- */
.eyebrow{display:flex;align-items:center;gap:12px}
.eyebrow::after{content:"";flex:1;height:1px;background:var(--line)}

.btn{
  display:inline-flex;align-items:center;gap:12px;
  font-size:var(--t-label);letter-spacing:.18em;text-transform:uppercase;
  padding:15px 26px;border:1px solid currentColor;border-radius:999px;
  transition:background 300ms var(--ease),color 300ms var(--ease);
}
.btn:hover{background:var(--ink);color:var(--bg)}
.btn--solid{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.btn--solid:hover{background:transparent;color:var(--ink)}
.link{
  font-size:var(--t-label);letter-spacing:.18em;text-transform:uppercase;
  border-bottom:1px solid var(--line);padding-bottom:5px;display:inline-block;
  transition:border-color 260ms var(--ease)
}
.link:hover{border-bottom-color:currentColor}

/* lista numerada, densidade larga */
.items{border-top:1px solid var(--line)}
.items > li{
  list-style:none;border-bottom:1px solid var(--line);
  padding-block:clamp(20px,2.4vw,34px);
  display:grid;grid-template-columns:64px minmax(0,1fr);gap:clamp(14px,2vw,34px);align-items:baseline;
}
.items .n{font-size:var(--t-label);letter-spacing:.16em;color:var(--accent)}
.items p{color:var(--mute);margin-top:8px;max-width:62ch}

/* variante estreita: número, título e texto na mesma linha. É ela que segura a
   regra de uma seção por tela quando a lista tem cinco itens ou mais. */
.items--tight > li{grid-template-columns:52px minmax(190px,250px) minmax(0,1fr);padding-block:clamp(14px,1.7vw,24px)}
.items--tight > li > div{display:contents}
.items--tight p{margin-top:0}

/* lista numerada, densidade estreita */
.ticks{border-top:1px solid var(--line)}
.ticks > li{
  list-style:none;border-bottom:1px solid var(--line);
  padding-block:14px;display:flex;gap:18px;align-items:baseline;justify-content:space-between;
}
.ticks .t{font-family:var(--display);font-weight:200;font-size:var(--d4)}
.ticks .v{font-size:var(--t-small);letter-spacing:.10em;color:var(--mute);white-space:nowrap}

.card{border:1px solid var(--line);padding:clamp(22px,2.6vw,38px);height:100%}
.card .label{margin-bottom:14px}
.card p{color:var(--mute);margin-top:10px}

/* FIGURA
   A medida vai na imagem, nunca na figura, senão a legenda embaixo é cortada.
   Sem recorte na figura, então também sem crescer no hover: o ganho não paga o
   risco de a imagem vazar por cima do texto. */
.figure{position:relative}
.figure img{width:100%;object-fit:cover;display:block}
.figure--tall img{aspect-ratio:3/4;max-height:64svh}
.figure--wide img{aspect-ratio:16/9}
.figure--square img{aspect-ratio:1/1}
.figure--edit img{height:clamp(300px,56svh,540px)}
.figure--port{width:min(100%,520px);margin-inline:auto}
.figure--port img{aspect-ratio:4/5;max-height:62svh}
.figure figcaption{margin-top:12px;display:block}

/* Numa fileira larga as quatro escolhas ficam na mesma linha; numa estreita a
   quebra continua sendo o certo, e por isso o `wrap` fica. Quem decide é a
   largura disponível, não uma regra escrita. */

/* As duas perguntas empilhadas precisam do mesmo respiro que tinham quando
   eram filhas diretas do formulário: o `stack-m` do `<form>` só alcança os
   filhos dele, e agora elas moram uma caixa mais para dentro. */

.field-input{display:flex;gap:14px;align-items:center;border-bottom:1px solid var(--line);padding-bottom:12px}
.field-input input{
  flex:1;background:none;border:0;color:inherit;font:inherit;padding:6px 0;
}
.field-input input::placeholder{color:var(--mute)}
.field-input input:focus{outline:none}
.field-input button{font-size:var(--t-label);letter-spacing:.18em;text-transform:uppercase;color:var(--accent)}

.gate{border:1px solid var(--line);padding:clamp(20px,2.4vw,32px);display:flex;gap:18px;align-items:flex-start}
.gate .key{font-size:var(--t-label);letter-spacing:.16em;color:var(--accent);white-space:nowrap;padding-top:3px}

/* ---------- 8. RODAPÉ ---------- */
.foot{background:var(--choc);color:var(--cream);padding-block:clamp(56px,7vw,96px)}
.foot a:hover{color:var(--blush)}
.foot__grid{display:grid;grid-template-columns:1.4fr 1fr 1fr 1.4fr;gap:var(--gap)}
.foot__marks{display:flex;align-items:center;gap:26px;margin-top:30px}
/* a opacidade saiu do contêiner e foi para o link: assim o hover pode
   acender a marca em vez de multiplicar dois valores baixos. */
.foot__marks a{display:inline-flex;align-items:center;opacity:.72;transition:opacity 420ms var(--ease)}
.foot__marks a:hover,.foot__marks a:focus-visible{opacity:1}
.foot__marks img,.foot__marks svg{height:22px;width:auto;filter:brightness(0) invert(1)}
.foot ul{list-style:none}
.foot ul li + li{margin-top:9px}
.foot .small{color:rgba(244,231,215,.55)}
/* o aviso das imagens é o texto mais discreto da página, de propósito: ele
   precisa estar lá, não precisa ser lido antes de nada */
.foot__aviso{color:rgba(244,231,215,.34)}

/* O PÉ DO PÉ. Duas letras miúdas na mesma linha: o aviso das imagens à
   esquerda, o crédito de criação encostado na direita. `space-between` com
   `flex-wrap` resolve os dois estados sem media query — enquanto couberem,
   dividem a linha; quando não couberem, o crédito desce e continua à direita,
   porque o `margin-left:auto` dele não depende da linha ser compartilhada.
   `align-items:center` e não `baseline`: de um lado há texto, do outro há uma
   imagem, e imagem não tem linha de base para acertar com a do tipo. */
.foot__pe{
  margin-top:clamp(34px,4.4vw,56px);
  display:flex;align-items:center;justify-content:space-between;
  gap:10px clamp(16px,3vw,48px);flex-wrap:wrap;
}
.foot__es{
  margin-left:auto;display:inline-flex;align-items:center;gap:9px;
  font-family:var(--ui);font-size:clamp(10px,.68vw,12px);
  letter-spacing:.08em;line-height:1;white-space:nowrap;
  color:rgba(244,231,215,.34);
  transition:color 420ms var(--ease);
}
/* A MARCA É O LOCKUP INTEIRO — nome e elefante —, tirado do `logo-white.svg`
   do elephant-skin.com e gravado a 600x97, que é ~6x o tamanho de tela: sobra
   nitidez em qualquer densidade. Vem branca de origem; o filtro fica assim
   mesmo, para normalizar caso um dia entre uma versão colorida. */
.foot__es img{
  height:clamp(14px,1.1vw,18px);width:auto;display:block;
  /* O CENTRO DA IMAGEM NÃO É O CENTRO DO NOME. Medido no arquivo: a palavra
     ELEPHANTSKIN ocupa as linhas 2 a 56 de uma imagem de 97, e o que desce até
     a linha 95 é a tromba do elefante. Centrar pela caixa deixava o texto 20%
     acima do nome — que é o desencontro que se via. Descer a imagem em 20,1%
     da própria altura ((48,5-29)/97) põe o meio do NOME na linha do texto.
     `translate` e não `margin`: assim o ajuste é proporcional à altura que o
     clamp resolver, e não muda a altura da linha. */
  transform:translateY(20.1%);
  filter:brightness(0) invert(1);opacity:.46;
  transition:opacity 420ms var(--ease);
}
/* o crédito acende inteiro — texto e marca juntos —, porque ele é um alvo só */
.foot__es:hover,.foot__es:focus-visible{color:rgba(244,231,215,.66)}
.foot__es:hover img,.foot__es:focus-visible img{opacity:.78}
/* NO CELULAR O CRÉDITO DESCE PARA A LINHA DE BAIXO, e ali a direita deixa de
   fazer sentido: encostado no canto ele fica solto, sem nada acima para se
   alinhar. Alinhado à esquerda ele encosta na margem do aviso das imagens —
   duas letras miúdas, uma sob a outra, pela mesma régua. É só desarmar o
   `margin-left:auto`, que existe para a linha compartilhada. */
@media (max-width:880px){
  .foot__es{margin-left:0}
}

/* ---------- 7b. O APP DENTRO DO SITE ---------- */
/* O webapp do Concierge roda embutido, ocupando a tela inteira abaixo do
   cabeçalho. Acesso livre por enquanto; a camada de níveis entra depois. */
section.field--app{padding-block:0;display:block;position:relative}
.app__frame{
  position:absolute;inset:var(--head-h) 0 0 0;
  background:var(--bg);
}
.app__frame iframe{width:100%;height:100%;border:0;display:block;position:relative;z-index:2}
/* fica atrás do quadro: aparece enquanto ele carrega e se ele não abrir */
.app__wait{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;z-index:1}
.app__out{
  position:absolute;right:var(--pad-x);bottom:22px;z-index:3;
  background:rgba(56,12,24,.55);backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
  padding:11px 18px;border-radius:999px;
  font-size:var(--t-label);letter-spacing:.16em;text-transform:uppercase;
  color:var(--cream);border:1px solid rgba(244,231,215,.22);
}
.app__out:hover{background:rgba(56,12,24,.78)}

/* ---------- 8b. A ROLAGEM É DO NAVEGADOR ---------- */
/* O encaixe saiu junto com o sequestro de rolagem. `scroll-snap` e o `pin` do
   ScrollTrigger disputam a mesma posição de rolagem, e quem perde é o olho:
   a seção pinada tenta ficar parada e o encaixe tenta empurrá-la.

   `scroll-behavior` fica de propósito fora daqui: a rolagem suave dos links de
   âncora é feita no JS, e uma regra global atrapalharia o ScrollTrigger a
   restaurar a posição depois de um refresh. */

/* ---------- 9. REVELAÇÃO ---------- */
/* Três entradas diferentes, uma para cada natureza de elemento. A manchete sobe
   por trás de uma máscara, o fio coral é desenhado depois dela, as listas entram
   em cascata e a foto assenta de uma escala levemente maior. Nada disso é
   enfeite: é o mesmo andamento do deck, aplicado ao que a seção tem. */

:root{--ease-rev:cubic-bezier(.16,.84,.28,1)}

/* base, para o que não é tipo, lista nem foto */
[data-rv]{
  opacity:0;transform:translateY(16px);
  transition:opacity 620ms var(--ease-rev) var(--d,0ms),
             transform 820ms var(--ease-rev) var(--d,0ms);
}
[data-rv].is-in{opacity:1;transform:none}

/* 1 · manchete: sobe por trás de uma máscara */
[data-rv].rv--type{
  opacity:1;transform:translateY(12px);
  clip-path:inset(-10% 0 106% 0);  /* de cima para baixo: a primeira linha aparece primeiro */
  transition:clip-path 980ms var(--ease-rev) var(--d,0ms),
             transform 980ms var(--ease-rev) var(--d,0ms);
}
[data-rv].rv--type.is-in{clip-path:inset(-10% 0 -10% 0);transform:none}
/* O FIO CORAL, UM COMPORTAMENTO SÓ, EM QUALQUER LUGAR.
   Antes só a manchete classificada desenhava o fio, e nas outras posições ele já
   aparecia pronto. Agora vale para todo `em`: ele começa em zero e é desenhado da
   esquerda para a direita 620ms depois do bloco onde está. O atraso vem do próprio
   bloco, por herança de `--cd` ou `--d`, então o fio entra sempre no mesmo tempo
   relativo, seja numa manchete, num item de lista ou dentro de um cartão. */
section.sec-in em,.foot.sec-in em{background-size:100% max(2px,.045em)}

/* 2 · listas e faixas: cascata, item a item */
[data-rv].rv--lines{opacity:1;transform:none;transition:none}
.rv--lines > *{
  opacity:0;transform:translateY(22px);
  transition:opacity 520ms var(--ease-rev) var(--cd,0ms),
             transform 680ms var(--ease-rev) var(--cd,0ms);
}
.rv--lines.is-in > *{opacity:1;transform:none}

/* 3 · foto: assenta de uma escala levemente maior, devagar */
.hero__media img,.plate__media img{
  transform:scale(1.06);
  transition:transform 2200ms var(--ease-rev);
}
.sec-in .hero__media img,.sec-in .plate__media img{transform:scale(1)}

/* A SAÍDA EM CASCATA saiu com o sequestro: ela era acionada pelo `irPara`,
   que era quem virava a seção. Com a rolagem nativa não existe mais "a seção
   que sai": existe o progresso do scroll, e a continuidade entre uma seção e a
   próxima passa a ser feita pelo `cena.js`. */

@media (prefers-reduced-motion:reduce){
  [data-rv],[data-rv].rv--type,.rv--lines > *{
    opacity:1;transform:none;clip-path:none;transition:none;
  }
  .rv--type em{background-size:100% max(2px,.045em);transition:none}
  .hero__media img,.plate__media img{transform:none;transition:none}
  /* o filme nem chega a ser pedido pelo `lp.js`; isto é o cinto de segurança */
  .hero__filme{display:none}
  html{scroll-behavior:auto}
}

/* ---------- 10. RESPONSIVO ---------- */
/* A CONSULTA POR ALTURA VALE SÓ NO COMPUTADOR, e a largura mínima não é
   detalhe: é o conserto de um defeito de celular.

   Uma consulta `max-height` num aparelho de mão é uma armadilha. No Chrome do
   Android a barra do navegador some quando se rola para baixo e volta quando se
   rola para cima, e a altura da janela muda junto — várias vezes por leitura.
   Uma regra pendurada em `max-height:860px` liga e desliga a cada uma dessas
   trocas, e o que ela mexe aqui é ESPAÇAMENTO: a diagramação inteira dá um pulo
   embaixo do dedo de quem está lendo.

   O celular não perde nada com isso: as medidas compactas que esta consulta
   dava a ele passam a valer sempre, no bloco de `max-width:880px`, sem depender
   de altura nenhuma. Telefone é tela baixa por definição — não há por que
   perguntar. */
/* O QUE SOBROU DELA. As linhas de respiro que moravam aqui saíram: elas eram
   valores fixos para "tela baixa", e vinham DEPOIS no arquivo, então
   sobrescreviam a escala nova com 78px de padding num lugar onde a conta pedia
   56. O sintoma era exatamente o que se queria consertar — a seção crescia além
   da tela e o conteúdo ia parar embaixo do índice fixo.

   Respiro agora é uma coisa só, declarada uma vez, e já olha a altura. O que
   fica aqui é o que a escala não cobre: proporções de peças que precisam ceder
   antes do texto numa tela baixa. */
@media (min-width:881px) and (max-height:860px){
  /* A folha de contato dos Amenities é a peça que resiste mais: cinco colunas
     com foto, título e frase. Numa janela muito baixa — 520px de altura útil,
     que é um 1024x768 com a barra do navegador — nem a escala inteira dá conta,
     e o rodapé da seção ia parar embaixo do índice fixo por cinco pixels.
     A margem entre a foto e o título é o que cede: é espaço, não conteúdo. */
  .ficha__foto{margin-bottom:clamp(6px,1.2svh,20px)}
  .figure--tall img{max-height:44svh}
  .figure--edit img{height:clamp(220px,42svh,420px)}
  .items--tight > li{padding-block:clamp(7px,1.3svh,12px)}
  .items > li{padding-block:clamp(9px,1.8svh,24px)}
  .ficha__foto img{max-height:20svh}
}
@media (max-width:1080px){
  .cols--4{grid-template-columns:repeat(2,1fr)}
  .foot__grid{grid-template-columns:1fr 1fr}
}
@media (max-width:1400px){
  .items--tight > li{grid-template-columns:44px minmax(150px,196px) minmax(0,1fr);gap:clamp(12px,1.4vw,24px)}
}
@media (max-width:1080px){
  .items--tight > li{grid-template-columns:52px minmax(0,1fr);gap:8px 18px}
  .items--tight > li > div{display:contents}
  .items--tight .d4{grid-column:2}
  .items--tight p{grid-column:2}
}
@media (max-width:880px){
  /* no celular a rolagem volta a ser livre, mas a regra da casa continua de pé:
     uma seção, uma tela. Antes o `min-height:auto` deixava as seções curtas
     medindo o conteúdo, e a Posição, que é uma frase só, ficava com metade da
     altura da tela. Com `100svh` toda seção alcança a tela inteira e o que passa
     disso empurra, que é o comportamento de sempre.
     `svh` e não `vh`: o `svh` já desconta a barra do navegador, então a seção
     nunca estoura quando a barra aparece. */
  html{scroll-snap-type:none}
  section.field,section.plate,section.hero,section.field--app{min-height:100svh}

  /* as medidas compactas que a consulta por altura dava, agora sem depender
     dela: telefone é tela baixa, e isso não muda no meio da rolagem */
  section.field{padding-block:clamp(78px,9vh,104px)}
  .band,.band--tight{padding-block:clamp(78px,9vh,104px)}
  .band--head{padding-top:clamp(96px,11vh,128px)}
  .figure--tall img{max-height:50svh}
  .items--tight > li{padding-block:12px}

  /* --- A ALTURA DA JANELA NO IPHONE. -------------------------------------
     No Safari do iPhone a janela tem DOIS tamanhos, e a diferença entre eles é
     a barra de endereço — cerca de 90 pixels. `svh` é a janela com a barra à
     mostra, `lvh` é a janela sem ela, e `dvh` é a de agora.

     A seção media `100svh`, que é a menor das duas. Enquanto a barra está lá,
     ela cobre a tela exatamente. Mas a barra some assim que se rola para baixo,
     a janela cresce, e a seção — que não mudou de tamanho — passa a deixar uma
     faixa de quase cem pixels em que já aparece a seção seguinte. É isso que se
     vê como "a página não fica 100% na tela".

     `dvh` resolveria a cobertura e criaria coisa pior: a seção mudaria de
     altura a cada movimento da barra, a página inteira encolheria e cresceria
     embaixo do dedo, e o conteúdo daria saltos. Trocar um defeito visível por
     um defeito que se sente na mão não é conserto.

     A saída é a seção medir a janela MAIOR e guardar a diferença como folga
     embaixo. Assim ela cobre a tela nos dois estados e nunca muda de tamanho:
     com a barra escondida, a seção é exatamente a tela; com a barra à mostra, o
     que fica abaixo da dobra são os noventa pixels de folga, que não têm nada
     dentro. O conteúdo continua inteiro à vista nos dois casos.

     `calc(100lvh - 100svh)` é a altura da barra, escrita sem número mágico:
     quem sabe quanto ela mede é o navegador, e em cada aparelho ela mede uma
     coisa. Num navegador que não conheça `lvh` — e são os anteriores a 2022 —
     esta declaração é descartada e vale a de cima, com `svh`, que é o
     comportamento que havia até aqui. */
  /* 15/09/2026 — MEDIDO NO IPHONE: a seção acabava 53 pixels antes do fim da
     tela, e nesses 53 aparecia o topo da seção seguinte. Não era o véu nem a
     barra: o `lvh` que aquele Safari informa é MENOR que a área que ele de
     fato pinta — a barra virou flutuante e o conteúdo passou a ir até a borda,
     mas a unidade ficou na conta antiga.

     `max()` das três unidades é a rede de segurança barata: onde elas
     concordam, nada muda; onde uma delas for maior, ela manda. Só pode fazer a
     seção crescer, nunca encolher, então não há como piorar. */
  section.field,section.plate,section.hero,section.field--app{
    min-height:100lvh;
    min-height:max(100lvh,100dvh,100vh);
  }

  /* A folga precisa ser DEVOLVIDA a quem alinha pela base ou pelo centro, senão
     ela empurra o conteúdo para fora da tela justamente quando a barra está à
     mostra. A capa alinha embaixo; `.field` centraliza; as placas variam.

     E A FOLGA É `dvh`, NÃO `svh`. Esta é a diferença entre o que estava escrito
     e o que ele fazia.

     Com `svh` a folga é FIXA e vale a altura da barra sempre, esteja a barra à
     mostra ou não. Enquanto ela está lá, a conta fecha: o conteúdo fica
     centrado no que se vê. Assim que ela some, a janela cresce noventa pixels,
     a folga continua embaixo, e o conteúdo passa a ficar 45 pixels ACIMA do
     centro da tela. Era isso que se via como "o conteúdo não está centralizado
     no celular", e se via justamente no estado em que a pessoa passa a maior
     parte do tempo, que é rolando com a barra recolhida.

     `dvh` é a janela DE AGORA. Com ela a folga vale a altura da barra quando a
     barra está lá e vale zero quando ela não está — os dois estados ficam
     centrados. E o aviso do bloco de cima continua respeitado: quem não pode
     mudar de tamanho é a SEÇÃO, e a seção continua medindo `lvh`. O que muda
     com a barra é só o respiro de baixo, e ele muda junto com a barra, no mesmo
     gesto e na mesma direção — o conteúdo acompanha o movimento em vez de
     saltar contra ele.

     As duas linhas de cada par existem para quem não conhece `dvh`: a primeira
     é a de antes e vale como reserva, a segunda a substitui onde `dvh` existe. */
  section.hero .hero__inner{padding-bottom:calc(60px + (100lvh - 100svh))}
  section.field{padding-bottom:calc(clamp(78px,9vh,104px) + (100lvh - 100svh))}
  .plate__inner{padding-bottom:calc(100lvh - 100svh)}
  section.hero .hero__inner{padding-bottom:calc(60px + (100lvh - 100dvh))}
  section.field{padding-bottom:calc(clamp(78px,9vh,104px) + (100lvh - 100dvh))}
  .plate__inner{padding-bottom:calc(100lvh - 100dvh)}
  /* na vertical o recorte fecha em cima das lâminas acesas: dose medida à parte */
  .hero__clipe{--veu:var(--veu-m,0)}
  /* na vertical a foto é mais alta que larga: o texto precisa de mais véu */
  .hero__media::after{
    background:linear-gradient(180deg,rgba(56,12,24,.62) 0%,rgba(56,12,24,.34) 34%,rgba(56,12,24,.92) 100%);
  }
  .plate--tr .plate__inner,.plate--br .plate__inner{align-items:center;justify-content:flex-start;text-align:left}
  .app__out{bottom:16px;right:16px}
  .cols--2,.cols--3,.cols--sidebar{grid-template-columns:1fr}
  .items > li{grid-template-columns:44px minmax(0,1fr)}
}
@media (max-width:560px){
  .cols--4{grid-template-columns:1fr}
  .foot__grid{grid-template-columns:1fr}
  .ticks > li{flex-direction:column;gap:4px}
}

/* --- 10.1 O CONVITE EM CIMA, O FORMULÁRIO EM DUAS COLUNAS EMBAIXO. --------
   Esta é a seção mais alta da página, e por natureza: uma manchete, uma frase,
   quatro campos, duas perguntas, um consentimento, um botão e uma nota.

   A primeira tentativa foi lado a lado: convite numa coluna, formulário na
   outra. Ficava baixo, mas cobrava a manchete — meia largura é onde uma frase
   de cartaz quebra em três linhas, e a frase é o que convence a preencher.

   Agora o título ocupa a linha inteira e o formulário se divide embaixo. As
   duas coisas ganham: a frase cabe numa linha só e o formulário passa de nove
   blocos empilhados para seis fileiras.

   O TÍTULO NÃO QUEBRAVA POR CAUSA DO CORPO, E SIM DO `max-width:22ch` do
   cartaz. Medido nesta página, "The first look is private." pede 9,95px de
   largura para cada pixel de corpo: 859px no corpo de 86px de uma tela de
   1440, contra 1296px disponíveis — sobrava largura de sobra, e a rédea estava
   em outro lugar. Solta, a frase cabe numa linha de 420px de tela para cima;
   abaixo disso ela volta a quebrar, que é o certo.

   Abaixo de 881px o formulário volta a ser uma coluna só: duas colunas num
   espaço estreito é um formulário espremido. */
@media (min-width:881px){
  #enquire h2{max-width:none}

  #enquire .lead{
    display:grid;
    grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    column-gap:clamp(30px,4vw,80px);
    row-gap:clamp(18px,2.2vw,30px);
    align-items:start;
  }
  /* `stack-m` empilha por margem, e margem não tem lugar dentro de uma grade:
     quem separa aqui é o row-gap, senão as duas contas se somam */
  #enquire .lead.stack-m > * + *{margin-top:0}

  /* o que atravessa as duas colunas: o rótulo, os pares de campo, o
     consentimento e o agradecimento */
  #enquire .lead > .code,
  #enquire .lead > .cols--2,
  #enquire .lead > .consent,
  #enquire .lead > .consent__legal,
  #enquire .lead > .lead__ok{grid-column:1 / -1}
  /* a letra miúda é do consentimento, então ela anda colada nele e não ganha
     a fileira inteira de respiro que a grade daria */
  #enquire .lead > .consent__legal{margin-top:calc(-1 * clamp(18px,2.2vw,30px) + .55em)}

  /* A FILEIRA DAS DUAS PERGUNTAS SAIU JUNTO COM A SEGUNDA PERGUNTA.
     Ela existia porque meia coluna não cabia quatro pílulas numa linha. Sem as
     pílulas, a pergunta de corretor volta a ser um item da grade, na primeira
     coluna, que é de onde ela tinha saído. */

  /* o botão divide a última fileira com a nota dos idiomas */
  #enquire .lead > .lead__enviar{grid-column:1;align-self:center;margin-top:4px}
  #enquire .lead > .slug{grid-column:2;align-self:center;margin-top:4px}
}


/* --- 10.9 O FORMULÁRIO. ---------------------------------------------------
   Esta é a única parte da página que tem trabalho a fazer, e não só uma coisa
   a dizer. Por isso ela é a única que ganha rótulo permanente em vez de
   placeholder: placeholder some quando a pessoa digita, e um formulário de
   sete campos sem rótulo obriga a lembrar o que era cada linha. Em captação de
   lead isso é abandono.

   O sublinhado é o mesmo `--line` do resto da página, então o campo continua
   parecendo a página e não um widget colado por cima. */
.lead{max-width:none}

/* A ISCA. Ela precisa estar no documento e ser preenchível — é esse o ponto —
   mas não pode ocupar espaço nem aparecer. `display:none` seria mais simples
   e é exatamente o que não serve: parte dos robôs pula campo escondido assim,
   e aí a isca não pesca nada. Tirar da tela pela esquerda mantém o campo vivo
   para quem preenche tudo sem olhar, que é quem queremos pegar. */
.isca{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden}

.lead__campo{display:flex;flex-direction:column;gap:.5em;min-width:0}
.lead__rot{
  font-family:var(--ui);font-size:var(--t-label);font-weight:500;
  letter-spacing:.18em;text-transform:uppercase;color:var(--mute);
  transition:color 260ms;
}
.lead__campo input[type="text"],
.lead__campo input[type="email"],
.lead__campo input[type="tel"]{
  width:100%;font:inherit;font-size:var(--t-body);color:var(--ink);
  background:none;border:0;border-bottom:1px solid var(--line);
  padding:0 0 10px;border-radius:0;
  transition:border-color 260ms;
}
.lead__campo input:focus{outline:none;border-bottom-color:var(--accent)}
.lead__campo:focus-within .lead__rot{color:var(--ink)}

/* O ERRO NÃO EMPURRA O FORMULÁRIO.
   A linha da mensagem existe sempre, vazia, com altura reservada. Sem isso,
   errar um campo desloca todos os campos abaixo dele, e a pessoa perde o lugar
   no meio de uma correção. */
.lead__erro{
  display:block;min-height:0;
  font-family:var(--ui);font-size:var(--t-small);line-height:1.25;
  color:var(--erro);
}
/* A ALTURA SÓ É RESERVADA DEPOIS DA PRIMEIRA TENTATIVA.
   Reservar uma linha vazia sob cada campo desde o começo custa seis linhas de
   respiro num formulário que já é alto, e ninguém viu erro nenhum ainda. Mas
   reservar tarde demais faz o formulário pular na cara de quem errou. O acordo
   é a classe que o `lp.js` põe no primeiro envio: antes disso o formulário é
   compacto, e a partir dali ele é estável. */
.lead--tentou .lead__erro{min-height:1.25em}
.lead__campo--erro input{border-bottom-color:var(--erro)}
.lead__campo--erro .lead__rot{color:var(--erro)}

.lead__grupo{border:0;padding:0;margin:0}
.lead__grupo legend{padding:0;margin-bottom:.7em}

.radios{display:flex;gap:clamp(18px,2.4vw,34px);flex-wrap:wrap}
.radio{display:inline-flex;align-items:center;gap:10px;cursor:pointer;font-size:var(--t-body)}
.radio input{
  appearance:none;-webkit-appearance:none;
  width:15px;height:15px;flex:0 0 auto;border-radius:50%;
  border:1px solid var(--line);background:none;cursor:pointer;
  transition:border-color 220ms,box-shadow 220ms;
}
.radio input:checked{border-color:var(--accent);box-shadow:inset 0 0 0 3.5px var(--accent)}
.radio input:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.lead__campo--erro .radio input{border-color:var(--erro)}

/* O CONSENTIMENTO É UMA GRADE DE DUAS COLUNAS, e não um flex.
   Com flex, a segunda e a terceira linha do texto correriam por baixo da
   caixinha. A grade prende o texto numa coluna só, e a mensagem de erro nasce
   alinhada com ele. */
.consent{
  display:grid;grid-template-columns:auto 1fr;gap:2px 12px;
  align-items:start;cursor:pointer;
}

/* A LETRA MIÚDA DO CONSENTIMENTO.
   Ela é rodapé da caixa, e não um segundo pedido: por isso nasce colada nela,
   no mesmo recuo do texto que a caixa empurra, e num corpo menor. O recuo é o
   que diz ao olho que as duas frases são a mesma coisa. */
.consent__legal{
  margin-top:.55em;
  padding-left:calc(17px + .75em);      /* a largura da caixa mais o vão dela */
  font-family:var(--ui);font-size:var(--t-small);line-height:1.5;
  color:var(--mute);max-width:92ch;
}
.consent input{
  appearance:none;-webkit-appearance:none;
  width:15px;height:15px;margin-top:.28em;flex:0 0 auto;
  border:1px solid var(--line);background:none;cursor:pointer;
  transition:border-color 220ms,background 220ms;
}
.consent input:checked{
  border-color:var(--accent);background:var(--accent);
  background-image:linear-gradient(45deg,transparent 46%,var(--bg) 46%,var(--bg) 54%,transparent 54%),
                   linear-gradient(-45deg,transparent 46%,var(--bg) 46%,var(--bg) 54%,transparent 54%);
}
.consent input:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.consent__txt{font-size:var(--t-small);line-height:1.55;color:var(--mute)}
.consent .lead__erro{grid-column:2}
.lead__campo--erro.consent input{border-color:var(--erro)}
.lead__campo--erro.consent .consent__txt{color:var(--ink)}

.lead__ok{
  font-family:var(--ui);font-size:var(--t-body);color:var(--accent);
  border-top:1px solid var(--line);padding-top:14px;
}
.lead button[type="submit"][disabled]{opacity:.45;cursor:progress}

/* --- 10.10 A CAPA SE MEXE. ------------------------------------------------
   O cliente pediu abertura com movimento ou vídeo. O vídeo ainda não existe,
   e uma capa parada é uma capa parada. Uma aproximação muito lenta, uma vez
   só, na chegada: não é efeito, é a diferença entre uma fotografia e um plano.
   Oito segundos e três por cento de escala ficam abaixo do limiar de "efeito"
   e acima do limiar de "morto".

   Roda uma vez e para. Um zoom em laço é o clichê que envelheceu. */
@keyframes s1-capa-respira{
  from{transform:scale(1.035)}
  to{transform:scale(1)}
}
.hero__media img{animation:s1-capa-respira 8s cubic-bezier(.22,.61,.36,1) both}
@media (prefers-reduced-motion:reduce){
  .hero__media img{animation:none}
}

/* --- 10.2 A TELA DOS INTERIORES. -----------------------------------------
   O mosaico teve uma versão dividindo a seção de Residences com o texto, e ela
   estava errada por uma razão de escala: nove imagens numa coluna de meia
   largura viram nove miniaturas, e miniatura não vende acabamento. Aqui ele tem
   a tela inteira, e o texto acima é curto de propósito — cada palavra a mais é
   uma imagem menor.

   O mosaico sai da `wrap` e vai de borda a borda. Na vertical ele NÃO vai: o
   respiro da seção continua reservando o alto para o cabeçalho e o pé para o
   índice, senão o índice em creme cairia em cima de um render claro e sumiria. */
.interiores{display:flex;flex-direction:column;gap:clamp(18px,2.4svh,36px)}
.interiores__topo{flex:0 0 auto}

/* O MOSAICO CENTRALIZA EM VEZ DE SANGRAR.
   De borda a borda ele ganhava tamanho e perdia enquadramento: encostado nas
   duas laterais, a parede virava fundo da tela em vez de peça sobre a página, e
   deixava de alinhar com o texto que a apresenta. Na mesma caixa do resto do
   site — a mesma largura máxima e o mesmo respiro lateral — ele volta a ser uma
   coisa POSTA na página, com margem dos dois lados, e as bordas de cima e de
   baixo de cada fila passam a conversar com a coluna de texto acima. */
.interiores .mosaico{
  flex:1 1 auto;
  width:100%;
  max-width:var(--maxw);
  margin-inline:auto;
  padding-inline:var(--pad-x);
}

/* --- O MOSAICO. ----------------------------------------------------------
   Filas em coluna, ambientes em linha, e as duas coisas crescem por `flex-grow`.

   E a classe chama `ambiente`, e não `quadro`, porque `quadro` já é a classe
   dos frames da galeria do One Day. As duas regras conviveriam no mesmo arquivo
   e a minha teria vencido por vir depois — a fita horizontal, que depende de
   cada frame ter largura própria, passaria a repartir a largura em partes
   iguais e o passeio quebraria. Foi pego na medição, não no olho.
   É isso que faz o gesto funcionar: `flex-grow` reparte o espaço que existe, e
   não o espaço que se pede — quando um quadro pede mais, os outros cedem na
   mesma conta, sem ninguém precisar calcular larguras. E `flex-grow` anima,
   coisa que `grid-template-columns` só faz nos navegadores mais recentes.

   RENDERS EM COR VERDADEIRA, sem lavagem de marca: num lançamento de alto
   padrão o acabamento é metade do argumento, e carvalho tingido de vinho não é
   carvalho. O mosaico é, de propósito, o bloco de luz da página. */
.mosaico{
  display:flex;flex-direction:column;
  gap:clamp(4px,.5vw,8px);
  min-height:clamp(260px,40svh,620px);
}
/* TAMANHOS VARIADOS EM REPOUSO, E ELES NÃO SÃO ALEATÓRIOS.
   Sorteados de verdade, mudariam a cada carregamento e a composição seria
   diferente para cada pessoa — o que se lê como acidente, não como desenho.
   Estes nove pesos foram escolhidos: filas de alturas diferentes, e dentro de
   cada fila uma peça que domina e duas que acompanham, alternando o lado. O
   olho percorre a parede em diagonal em vez de varrer uma grade. */
.mosaico__fila{
  display:flex;gap:clamp(4px,.5vw,8px);
  flex:var(--g,1) 1 0;min-height:0;
  transition:flex-grow 640ms var(--ease),flex-basis 640ms var(--ease);
}
/* DUAS, QUATRO E TRÊS. A parede deixou de ser uma grade porque as filas
   deixaram de ter a mesma contagem — e a contagem não é decoração: duas
   fotografias para chegar, quatro para viver, três para recolher. Uma fila com
   duas peças respira e pede altura; uma com quatro é densa e cede altura em
   troca. É por isso que os pesos de altura andam junto com a contagem. */
.mosaico__fila:nth-child(1){--g:1.22}
.mosaico__fila:nth-child(2){--g:.76}
.mosaico__fila:nth-child(3){--g:1.04}

/* E A PAREDE NÃO FECHA NUM RETÂNGULO PERFEITO.
   A última fila recua da borda direita. É a diferença entre uma parede montada
   e uma grade preenchida: o retângulo perfeito é o que faz o olho ler "tabela",
   e nove por cento de vazio no canto é o que faz ler "composição". No celular o
   recuo sai — ali cada pixel de largura é imagem. */
.mosaico__fila--recuo{margin-right:9%}

.ambiente{
  position:relative;overflow:hidden;
  flex:var(--g,1) 1 0;min-width:0;
  padding:0;border:0;background:rgba(244,231,215,.06);
  cursor:pointer;
  transition:flex-grow 640ms var(--ease),flex-basis 640ms var(--ease);
}
.mosaico__fila:nth-child(1) .ambiente:nth-child(1){--g:1.34}
.mosaico__fila:nth-child(1) .ambiente:nth-child(2){--g:.86}
.mosaico__fila:nth-child(2) .ambiente:nth-child(1){--g:.82}
.mosaico__fila:nth-child(2) .ambiente:nth-child(2){--g:1.30}
.mosaico__fila:nth-child(2) .ambiente:nth-child(3){--g:.72}
.mosaico__fila:nth-child(2) .ambiente:nth-child(4){--g:1.14}
.mosaico__fila:nth-child(3) .ambiente:nth-child(1){--g:1.24}
.mosaico__fila:nth-child(3) .ambiente:nth-child(2){--g:.78}
.mosaico__fila:nth-child(3) .ambiente:nth-child(3){--g:1.00}
.ambiente img{
  width:100%;height:100%;object-fit:cover;display:block;
  transition:transform 900ms var(--ease),filter 640ms var(--ease);
}
/* em repouso o quadro cede um pouco de luz para o vizinho aberto não disputar
   atenção com oito irmãos; ao abrir, ele volta inteiro */
.mosaico--aberto .ambiente img{filter:brightness(.62) saturate(.86)}
.mosaico--aberto .ambiente[aria-expanded="true"] img{filter:none}
.ambiente:hover img{transform:scale(1.03)}

/* A CAIXA ABERTA NÃO TEM MEDIDA FIXA: ELA RECEBE A PROPORÇÃO DA FOTOGRAFIA.
   Um valor de `flex-grow` daria uma caixa de proporção arbitrária, e a imagem
   dentro dela seria recortada para caber — que é justamente o que não se quer
   ver quando alguém clica para olhar de perto. Então a altura da fila e a
   largura do ambiente aberto são calculadas pelo `lp.js` a partir da proporção
   real do arquivo, e escritas como `flex-basis` em pixels. A caixa passa a ter
   a forma da foto, e `contain` garante que nem um pixel seja cortado.

   O que o CSS ainda faz é o resto: quem não está aberto continua repartindo o
   espaço que sobrou, na proporção dos pesos de repouso. */
.mosaico--aberto .ambiente[aria-expanded="true"] img{object-fit:contain}

.ambiente__nome{
  position:absolute;left:0;right:0;bottom:0;
  padding:26px clamp(10px,1vw,16px) clamp(9px,.9vw,14px);
  font-family:var(--ui);font-size:var(--t-label);font-weight:500;
  letter-spacing:.18em;text-transform:uppercase;color:var(--cream);
  text-align:left;
  background:linear-gradient(180deg,rgba(26,6,12,0),rgba(26,6,12,.82));
  opacity:0;transform:translateY(6px);
  transition:opacity 420ms var(--ease),transform 420ms var(--ease);
  pointer-events:none;
}
.ambiente:hover .ambiente__nome,
.ambiente:focus-visible .ambiente__nome,
.ambiente[aria-expanded="true"] .ambiente__nome{opacity:1;transform:none}

.ambiente:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* NO CELULAR A GRADE CONTINUA SENDO UMA GRADE.
   A primeira versão empilhava os nove numa coluna só, e medido a 390px isso deu
   NOVE TIRAS DE 55 PIXELS de altura — uma faixa de cor, não uma imagem. Três
   por três a 390 de largura dá miniaturas de 126 por 127, que é quadrado e é
   legível. O gesto é o mesmo, e a proporção de abertura cresce um pouco, porque
   numa tela pequena o ambiente aberto precisa dominar mais para valer a pena. */
@media (max-width:1099px){
  .mosaico{min-height:clamp(280px,46svh,520px)}
  .mosaico__fila--recuo{margin-right:0}
  .mosaico--aberto .mosaico__fila{flex-grow:.5}
  .mosaico--aberto .mosaico__fila--aberta{flex-grow:2.8}
  .mosaico--aberto .ambiente{flex-grow:.42}
  .mosaico--aberto .ambiente[aria-expanded="true"]{flex-grow:3.2}
  .ambiente__nome{padding:20px 10px 9px;font-size:10px;letter-spacing:.14em}
}

@media (prefers-reduced-motion:reduce){
  .mosaico__fila,.ambiente,.ambiente img,.ambiente__nome{transition:none}
}

/* ---------- 11. UTILIDADES DE ESPAÇO ---------- */
.mt-s{margin-top:clamp(8px,1.6svh,14px)}
.mt-m{margin-top:clamp(11px,min(2vw,2.4svh),30px)}
.mt-l{margin-top:clamp(18px,min(4vw,4.8svh),60px)}
.mt-xl{margin-top:clamp(28px,min(5.4vw,7.6svh),84px)}
.narrow{max-width:16ch}
.narrow-24{max-width:24ch}

/* ==========================================================================
   12. A GRAMÁTICA DA MARCA
   Não é decoração nova: é o que as telas `graphic`, `type` e `image` do deck já
   definem, trazido para o site. Cartão de três partes, código de acesso,
   legenda de comanda, grão de film still, numeral como grafismo.
   ========================================================================== */

/* --- 12.1 O cartão. Rótulo na primeira linha, mensagem na última, e o vazio no
   meio, que é o que faz dele um cartão e não um cupom. --- */
.slip{
  border:1px solid var(--line);
  padding:clamp(20px,2.2vw,30px);
  min-height:clamp(200px,26vh,290px);
  display:flex;flex-direction:column;justify-content:space-between;gap:26px;
  transition:border-color 400ms var(--ease);
}
.slip:hover{border-color:var(--accent)}

/* A foto ocupa o vazio do meio do cartão, como fundo, e o véu por cima devolve
   o contraste para o rótulo e o nome. `isolation:isolate` é obrigatório: sem
   ele o z-index negativo escapa para a raiz e a foto some atrás do fundo da
   página. É o mesmo defeito que já nos custou o campo de cor. */
.slip{position:relative;overflow:hidden;isolation:isolate}
.slip__foto{position:absolute;inset:0;z-index:-1}
.slip__foto img{
  width:100%;height:100%;object-fit:cover;display:block;
  transform:scale(1.02);transition:transform 900ms var(--ease);
}
.slip__foto::after{
  /* O `z-index` AQUI É O CONSERTO DE UM VÉU QUE NÃO PINTAVA.
     O cartão que esperava foto dava `z-index:1` à imagem, para a foto cobrir o
     rótulo "foto pendente" quando o arquivo chegasse. Chegaram as dezesseis, e
     com elas um efeito que ninguém procurou: um pseudo-elemento sem nível
     declarado perde para um irmão posicionado com nível 1, então a imagem
     passou a cobrir também o VÉU. Os cartões do mapa ficaram com a fotografia
     a 100% por baixo do texto — medido, "19 min" em 1,66:1 e o nome do lugar
     em 2,1:1, com o véu inteiro escrito na folha e nenhum pixel dele na tela.
     Declarar o nível aqui fecha a porta: o véu está acima de qualquer imagem,
     com ou sem andaime. */
  content:'';position:absolute;inset:0;z-index:2;
  background:linear-gradient(180deg,rgba(42,18,22,.74),rgba(42,18,22,.40) 46%,rgba(42,18,22,.88));
}
.slip:hover .slip__foto img{transform:scale(1.06)}

/* O CARTÃO QUE AINDA ESPERA A FOTO.
   Os dezesseis restaurantes e escolas do mapa não têm foto porque foto de
   estabelecimento é material licenciado — o arquivo que cada um espera está
   nomeado em `assets/mapa/lugares/LEIA-ME.txt`.

   O ESPAÇO JÁ EXISTE E O <img> JÁ APONTA PARA O NOME CERTO. Enquanto o arquivo
   não estiver na pasta, o que se vê é esta caixa escura com o rótulo — o mesmo
   tratamento das fichas de amenidade. Quem esconde a imagem que falhou é o
   bloco 5b do `lp.js`: `alt` vazio NÃO basta, o Chrome desenha o ícone de
   quebrado assim mesmo.

   O RÓTULO FICA ATRÁS DA IMAGEM. No dia em que o arquivo entrar na pasta, a
   foto desenha por cima e o rótulo some sozinho — pôr a foto no ar passa a ser
   copiar o arquivo para a pasta, sem tocar em uma linha de código. */
.slip__foto--espera{
  background:rgba(20,5,10,.58);
  box-shadow:inset 0 0 0 1px rgba(244,231,215,.14);
}
.slip__foto--espera i{
  position:absolute;inset:0;z-index:0;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--ui);font-style:normal;font-weight:500;
  font-size:var(--t-label);letter-spacing:.22em;text-transform:uppercase;
  color:rgba(244,231,215,.46);text-align:center;padding:0 10px;
}
.slip__foto--espera img{position:absolute;inset:0;z-index:1}
/* `hidden` PRECISA SER DITO AQUI. O atributo vale `display:none` pela folha do
   navegador, e `.slip__foto img` acima declara `display:block` — regra de autor
   ganha de regra do navegador, por mais específica que a do navegador pareça.
   Sem esta linha o script marcava a imagem como escondida e ela continuava na
   tela, com o ícone de quebrada e tudo. */
.slip__foto img[hidden]{display:none}
.slip__label{
  font-family:var(--ui);font-size:var(--t-label);font-weight:500;
  letter-spacing:.30em;text-transform:uppercase;color:var(--mute);
}
.slip__msg{
  font-family:var(--display);font-weight:200;
  font-size:var(--d4);line-height:1.18;
}
.slip--live .slip__label{color:var(--coral)}

/* --- 12.2 Código de acesso. Inter 500, 300 de tracking. --- */
.code{
  font-family:var(--ui);font-weight:500;font-size:var(--t-label);
  letter-spacing:.30em;text-transform:uppercase;color:var(--mute);
}
/* o tique coral antes do rótulo. O deck assina cada tela com um, e o site faz
   igual: uma vez por seção, nunca em toda linha em caixa alta. */
/* o tique acompanha o corpo: em `em`, ele cresce junto com o rótulo em vez de
   virar um ponto perdido ao lado de um tipo maior */
.code::before{
  content:"";display:inline-block;width:.55em;height:.55em;
  background:var(--coral);margin-right:1em;vertical-align:.08em;
}
.stagger .code::before,.foot .code::before,.slip__label::before,.slug::before{content:none}
.code--live{color:var(--coral)}

/* --- 12.3 Legenda de comanda. --- */
.slug{
  font-family:var(--ui);font-weight:400;font-size:var(--t-small);
  letter-spacing:.14em;color:var(--mute);
}

/* --- 12.4 Numeral como grafismo. --- */
.rows{border-top:1px solid var(--line)}
.rows > li{
  list-style:none;border-bottom:1px solid var(--line);
  display:grid;grid-template-columns:minmax(96px,.9fr) minmax(0,1.5fr) minmax(0,2fr);
  gap:clamp(16px,2.4vw,40px);align-items:baseline;
  /* o respiro da linha cede com a altura da tela: quatro linhas numa tela baixa
     são oito respiros, e é ali que a lista estoura primeiro */
  padding-block:clamp(10px,min(2.2vw,3.4svh),30px);
}
.rows .num{
  font-family:var(--display);font-weight:100;
  font-size:clamp(30px,min(4.4vw,8.6svh),74px);line-height:.9;color:var(--accent);
}
.rows .ttl{font-family:var(--display);font-weight:200;font-size:var(--d4);line-height:1.2}
.rows p{color:var(--mute)}
/* o alinhamento alternado saiu: quebrava a coluna de leitura */

/* --- 12.5 Tipo que sangra pela borda. Uma vez por página, nunca duas. --- */
.bleed{margin-left:0}  /* era sangria pela esquerda: cortava a primeira letra */
.bleed-r{margin-right:calc(var(--pad-x) * -1)}

/* --- 12.5b Meia tela de foto. A imagem ocupa metade da seção, cortada pelo
   enquadramento e não ampliada. Serve para arquivo pequeno: em 1440 a coluna tem
   uns 690px e a foto tem 928 de origem, então ela é cortada, nunca esticada. --- */
section.half{position:relative;overflow:hidden}
.half__media{position:absolute;top:0;bottom:0;right:0;width:min(48%,880px)}
.half__media img{width:100%;height:100%;object-fit:cover;display:block}
.half__media figcaption{
  position:absolute;left:clamp(18px,2vw,28px);bottom:clamp(16px,2vw,24px);
  color:var(--cream);text-shadow:0 1px 12px rgba(26,6,12,.6);
}
.half .wrap{position:relative;z-index:2}
.half__text{max-width:min(46%,600px)}

/* --- 12.6 Foto de tela cheia com uma linha só por cima. --- */
section.plate{position:relative;overflow:hidden;padding:0;display:flex;align-items:stretch}  /* stretch, senão o inner não ganha altura e todo alinhamento vira centro */
.plate__media{position:absolute;inset:0}
.plate__media img{width:100%;height:100%;object-fit:cover}
.plate__media::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(42,18,22,.55) 0%,rgba(42,18,22,.12) 42%,rgba(42,18,22,.82) 100%);
}
.plate__inner{
  position:relative;z-index:2;flex:1;display:flex;
  padding-block:clamp(60px,9vh,120px);
}
/* height:100% não funcionava aqui: a seção tem min-height, não height, então a
   porcentagem virava auto e o bloco encostava no topo. Com a seção em flex e o
   inner esticando, o alinhamento passa a valer de verdade. */
/* AS PLACAS TAMBÉM CENTRALIZAM NA VERTICAL.
   O `inner` é uma caixa em linha: `align-items` decide a altura e
   `justify-content` decide o lado. O lado continua sendo a decisão de direção
   de arte de cada placa — é ele que tira o texto de cima do assunto da
   fotografia. A altura deixa de ser: em qualquer placa o bloco fica no meio,
   que é onde o olho procura primeiro e onde a página inteira agora conversa. */
.plate--bl .plate__inner{align-items:center;justify-content:flex-start}
.plate--tr .plate__inner{align-items:center;justify-content:flex-end;text-align:right}
.plate--br .plate__inner{align-items:center;justify-content:flex-end;text-align:right}
/* centrada na tela, com véu por cima da foto inteira. Para quando a informação é
   o assunto e a foto é o fundo, não o contrário. */
.plate--center .plate__inner{align-items:center;justify-content:center;text-align:center}
.plate--center .plate__inner > *{margin-inline:auto}
.plate--center .field-input{max-width:46ch;margin-inline:auto}
.plate--center .btn{margin-inline:auto}
.plate--veu .plate__media::after{
  background:
    linear-gradient(180deg,rgba(42,18,22,.72) 0%,rgba(42,18,22,.60) 45%,rgba(42,18,22,.82) 100%),
    radial-gradient(ellipse at 50% 50%,rgba(26,6,12,.45) 0%,rgba(26,6,12,.10) 55%,rgba(26,6,12,.55) 100%);
}
/* véu lateral, para quando a foto é clara ou movimentada justo onde o texto cai.
   Escurece só o lado do texto e deixa o resto da imagem respirar. */
/* --- 12.6b A SEGUNDA TELA DAS RESIDÊNCIAS. -------------------------------

   O render de interiores é CLARO DE PONTA A PONTA — é uma sala ensolarada, e é
   isso que ele tem de bom. Isso muda o que o texto precisa: na placa da varanda,
   que é uma foto de fim de tarde, o véu de lado já bastava; aqui, creme sobre
   uma janela branca não se lê de jeito nenhum.

   Três correções, e nenhuma delas sozinha resolvia. O BLOCO GANHOU LARGURA
   MÁXIMA — sem ela a manchete atravessava a tela e ia parar em cima do voile,
   fora da faixa escurecida. O VÉU FICOU MAIS FUNDO e começa mais cedo do que o
   `--scrim-r` padrão, porque aqui ele não segura uma linha solta e sim cinco
   blocos. E o corpo PERDEU O ABAFADO: medido sobre o render, `mute` dava 2,69:1
   no pior pedaço de fundo, contra os 4,5 que texto pequeno pede.

   A hierarquia entre manchete e corpo continua existindo — ela está no corpo da
   letra e na medida, e não só no tom. */
#interiors .plate__inner > div{max-width:min(460px,34vw)}
/* O VÉU NÃO ESTÁ ESCURECENDO A PAREDE DE MADEIRA — ela já é quase preta, 0,07
   de luminância, e não há o que tirar dali. Ele existe para a TRAVESSIA: o
   painel escuro acaba em 20% da largura e o bloco de texto vai até 34%, então
   os últimos catorze por cento caem sobre o miolo iluminado do lobby. Medido
   sem véu nessa faixa, a manchete dava 2,87:1.
   Por isso ele é forte até 44% e some em 80%: o que se apaga é a passagem, e o
   assunto da fotografia — a sala ao fundo, com a marca no vidro — continua
   inteiro do meio para a direita. */
#interiors .plate__media::after{
  background:
    linear-gradient(90deg,rgba(42,18,22,.90) 0%,rgba(42,18,22,.84) 24%,rgba(42,18,22,.62) 44%,rgba(42,18,22,.22) 64%,rgba(42,18,22,0) 82%),
    linear-gradient(180deg,rgba(42,18,22,.34) 0%,rgba(42,18,22,.16) 44%,rgba(42,18,22,.56) 100%);
}
/* mesmo motivo do render anterior: sobre imagem, `mute` não sobra contraste */
#interiors .body.mute{color:var(--ink)}
#interiors .slug{opacity:.9}
/* na tela estreita o véu vira vertical — é o que a regra geral das placas já
   faz. A largura máxima some junto, senão o bloco fica espremido num terço de
   uma tela que já é estreita. */
@media (max-width:880px){
  #interiors .plate__inner > div{max-width:none}
}

/* --- 12.6a A VARANDA, QUE É UMA FOTO EM PÉ. ------------------------------
   Todas as outras placas são fotografias deitadas e vivem bem de borda a
   borda. Esta não: 1208x1500. Em tela cheia o `cover` cortava 55% da altura
   dela, e o que sobrava era o pilar do meio — o render perdia a varanda, a
   baía e o horizonte, que são o assunto.
   Então a foto encosta na direita, com 56% da largura, e a esquerda continua
   sendo o campo de cor da seção. A emenda some no degradê: ele começa NA COR
   DA SEÇÃO, opaco, e abre até o transparente antes do assunto. Quem olha não
   vê onde a cor acaba e a foto começa.
   No celular a regra não vale: ali a tela é que é em pé, e a foto de tela
   cheia cai perfeita. --- */
@media (min-width:881px){
  #residence .plate__media{left:auto;right:0;width:clamp(460px,56%,1240px)}
  #residence .plate__media::after{
    background:
      linear-gradient(90deg,
        var(--wine-deep) 0%,
        rgba(56,12,24,.97) 10%,
        rgba(56,12,24,.72) 26%,
        rgba(56,12,24,.28) 44%,
        rgba(56,12,24,0) 62%),
      linear-gradient(180deg,rgba(42,18,22,.34) 0%,rgba(42,18,22,.06) 44%,rgba(42,18,22,.58) 100%);
  }
}

.plate--scrim-l .plate__media::after{
  background:
    linear-gradient(90deg,rgba(42,18,22,.88) 0%,rgba(42,18,22,.66) 34%,rgba(42,18,22,0) 80%),
    linear-gradient(180deg,rgba(42,18,22,.52) 0%,rgba(42,18,22,.38) 45%,rgba(42,18,22,.72) 100%);
}
.plate--scrim-r .plate__media::after{
  background:
    linear-gradient(270deg,rgba(42,18,22,.88) 0%,rgba(42,18,22,.62) 30%,rgba(42,18,22,0) 62%),
    linear-gradient(180deg,rgba(42,18,22,.52) 0%,rgba(42,18,22,.10) 42%,rgba(42,18,22,.72) 100%);
}

/* --- O VÉU DAS PLACAS NO RETRATO. ----------------------------------------
   Os véus de cima são LATERAIS: escurecem o lado em que o texto cai e deixam o
   resto do render respirar. Isso vale na tela deitada, onde o texto ocupa uma
   coluna. No celular o texto atravessa a largura inteira, e um véu lateral
   deixa metade da frase sobre a parte clara da imagem — foi o que a medição
   pegou: "Studios to three bedrooms" em 3,29:1 e "Arrival · Brickell" em
   3,47:1, contra os 4,5 que texto pequeno pede.

   ESTE BLOCO PRECISA MORAR AQUI, e não lá em cima com as outras regras de
   celular. Já existia uma versão dele no bloco de `max-width:880px` da seção
   11, escrita há semanas, e ela NUNCA pintou um pixel: tem a mesma
   especificidade das regras desta faixa e vem ANTES delas na folha, então
   perdia no desempate por ordem — media query não vale especificidade. O
   `#interiors` é pior ainda: vem de um seletor com id e ganha de qualquer
   classe, em qualquer ordem. Por isso a lista abaixo repete o id.
   É a mesma armadilha que já tinha custado a tabela de tipologias. --- */
@media (max-width:880px){
  #interiors .plate__media::after,
  .plate--scrim-l .plate__media::after,
  .plate--scrim-r .plate__media::after{
    background:linear-gradient(180deg,rgba(42,18,22,.88) 0%,rgba(42,18,22,.72) 32%,rgba(42,18,22,.95) 100%);
  }
  /* O LOBBY, NO RETRATO, VIROU OUTRA COMPOSIÇÃO.

     Antes: texto no meio da tela e véu forte em cima da imagem inteira. O véu
     resolvia a leitura e matava o render — que é o assunto da seção.

     Agora os três se movem juntos, e só juntos funcionam:

     1. A IMAGEM SOBE. O render é 16:9 e a tela é retrato: com `cover`, a escala
        é ditada pela ALTURA, a imagem preenche na vertical exatamente e sobra
        só na horizontal. Por isso `object-position` no eixo Y não faz nada
        aqui — não há o que deslocar. O jeito de subir é dar mais altura à
        imagem do que a caixa tem e puxá-la para cima: 118% com -18% de margem.
        As poltronas sobem, e o piso vazio que ficava embaixo vira o lugar do
        texto.

     2. O TEXTO DESCE. `align-items:flex-end` no inner: ele encosta na base,
        onde agora há piso liso.

     3. O VÉU VIRA DE BAIXO PARA CIMA. Começa opaco na base, onde o texto está,
        e chega a transparente ANTES das poltronas. O teto, o círculo de luz, a
        vidraça e o S1 ficam sem uma gota de tinta por cima. */
  #interiors .plate__media img{height:138%;margin-top:-38%}
  #interiors .plate__inner{align-items:flex-end}
  #interiors .plate__media::after{
    background:linear-gradient(180deg,
      rgba(42,18,22,0) 0%,
      rgba(42,18,22,.04) 52%,
      rgba(42,18,22,.20) 60%,
      rgba(42,18,22,.80) 66%,
      rgba(42,18,22,.93) 72%,
      rgba(42,18,22,.96) 84%,
      rgba(42,18,22,.97) 100%);
  }
}

/* --- 12.7 Grão. Film still, não render. --- */
.grain::before{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  opacity:.16;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");
}

/* 12.8 saiu: a composição de canto jogava o conteúdo para baixo e destoava do
   resto, que centra na tela. */

/* --- 12.9 Medidas desiguais. O texto não tem sempre a mesma largura. --- */
.m-narrow{max-width:38ch}
.m-wide{max-width:70ch}
.cols--off{grid-template-columns:minmax(0,.78fr) minmax(0,1.4fr)}
.cols--off-r{grid-template-columns:minmax(0,1.4fr) minmax(0,.78fr)}

@media (max-width:880px){
  .rows > li{grid-template-columns:64px minmax(0,1fr)}
  .rows p{grid-column:2}
  .rows--right > li:nth-child(even){text-align:left;direction:ltr}
  .cols--off,.cols--off-r{grid-template-columns:1fr}
  .bleed,.bleed-r{margin-inline:0}
  .slip{min-height:170px}
}

/* --- 12.10 Mais três arranjos, para nenhuma seção repetir a de cima --- */
.plate--tl .plate__inner{align-items:flex-start;justify-content:flex-start}

/* faixa dividida por fios verticais */
.split{display:grid;gap:0;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.split > *{
  padding:clamp(22px,2.6vw,40px) clamp(18px,2vw,32px);
  border-left:1px solid var(--line);
}
.split > *:first-child{border-left:0;padding-left:0}
.split--3{grid-template-columns:repeat(3,1fr)}
.split--4{grid-template-columns:repeat(4,1fr)}
.split--4{grid-template-columns:repeat(4,1fr)}
.split--5{grid-template-columns:repeat(5,1fr)}
/* FOLHA DE CONTATO. Cada coluna do `split` ganha um retrato 4:5 antes do
   titulo. Nenhuma outra secao da pagina usa essa composicao, que e a regra: uma
   secao nunca repete o arranjo da de cima. Nao muda o peso da entrada, porque a
   coluna continua sendo um item so na cascata. */
.ficha__foto{
  /* altura fixa e nao proporcao: a primeira coluna do `split` e mais larga que
     as outras, e com proporcao as fotos sairiam de alturas diferentes. Folha de
     contato pede a mesma linha de base. */
  display:block;overflow:hidden;height:clamp(72px,min(13.6vw,13svh),196px);
  margin-bottom:clamp(9px,min(1.3vw,1.8svh),20px);
  background:rgba(244,231,215,.06);
  clip-path:inset(0 100% 0 0);transition:clip-path 1100ms var(--ease-rev) var(--d,0ms);
}
section.sec-in .ficha__foto{clip-path:inset(0 0 0 0)}
.ficha__foto img{
  width:100%;height:100%;object-fit:cover;display:block;
  transform:scale(1.02);transition:transform 900ms var(--ease);
}
.split > *:hover .ficha__foto img{transform:scale(1.06)}
@media (prefers-reduced-motion:reduce){.ficha__foto{clip-path:none;transition:none}}

/* A CAIXA DA FOTO QUE FALTA.
   Pedido do cliente: "o que não tivermos de imagem, pode colocar um box mais
   escuro para sabermos que precisamos disponibilizar". Quatro das cinco fichas
   estão assim — academia, piscina, o Speak Easy e o Outdoor Theatre.

   Ela ocupa exatamente o lugar da foto, com a mesma altura e a mesma entrada em
   cortina, para a faixa continuar tendo a linha de base que uma folha de
   contato precisa ter. O que muda é só a cor: bem mais escura que o campo, com
   um fio por dentro, e o nome do que falta escrito no meio. Ler "Academia" ali
   é mais útil do que ler um retângulo vazio, porque diz o que pedir.

   É MARCADOR DE PRODUÇÃO, NÃO ESTADO DO COMPONENTE. Não há variante "sem
   imagem" no desenho da ficha: quando a foto chegar, o `<span>` inteiro é
   trocado pelo `<span class="ficha__foto"><img></span>` das outras, e a caixa
   some junto com o motivo dela. */
.ficha__foto--falta{
  background:rgba(20,5,10,.52);
  box-shadow:inset 0 0 0 1px rgba(244,231,215,.16);
  display:flex;align-items:center;justify-content:center;
}
.ficha__foto--falta i{
  font-family:var(--ui);font-style:normal;font-weight:500;
  font-size:var(--t-label);letter-spacing:.22em;text-transform:uppercase;
  color:rgba(244,231,215,.52);text-align:center;padding:0 8px;
}

/* A MARCA DA FOTO PROVISÓRIA: PRETO E BRANCO.
   Estas três imagens são de terraço e o cliente disse que não representam o
   projeto atual. Elas estão aqui para a faixa não ficar oca enquanto as novas
   não chegam, e a marca é o que diz, sem escrever, quais são as que saem.

   Primeiro foi opacidade de 70%, e não deu: sobre o campo vinho uma foto
   esmaecida ainda parece uma foto escolhida. Tirar a cor é outra categoria de
   sinal — numa página que é toda vinho, coral e creme, uma imagem cinza não tem
   como ser confundida com decisão de projeto.

   Quando a foto nova entrar: troque o `src` e apague a classe. Se um dia sobrar
   uma marca esquecida, ela aparece — que é exatamente o que se quer de um
   aviso. */
.ficha__foto--trocar img{filter:grayscale(1) contrast(1.04)}
/* tela baixa: a folha de contato encolhe pela altura, senao a seção passa de uma
   tela em 1440x760 e 1280x720, que são as duas medidas que a gente confere. */
@media (min-width:881px) and (max-height:868px){
  .ficha__foto{height:clamp(96px,17vh,180px);margin-bottom:12px}
  #house .split{margin-top:clamp(24px,3.4vh,46px)}
}

.split .t{font-family:var(--display);font-weight:200;font-size:var(--d4);line-height:1.2;display:block}
.split p{color:var(--mute);margin-top:10px}

/* linhas em escada: cada uma entra um pouco mais */
.stagger{list-style:none}
.stagger > li{
  display:grid;grid-template-columns:96px minmax(0,1fr);
  gap:clamp(16px,2.4vw,44px);align-items:baseline;
  padding-block:clamp(10px,1.3vw,18px);border-top:1px solid var(--line);
}
.stagger > li:first-child{border-top:0}
/* a escada saiu: cada linha começava num ponto diferente e a leitura tropeçava */
.stagger .when{padding-top:.5em}
.stagger .what{font-family:var(--display);font-weight:200;font-size:var(--d3);line-height:1.16}

/* ficha de produto: colunas separadas por fio, sem caixa */
.spec{display:grid;grid-template-columns:repeat(3,1fr);gap:0}
.spec > *{border-left:1px solid var(--line);padding:0 clamp(16px,2vw,30px)}
.spec > *:first-child{border-left:0;padding-left:0}
.spec .size{font-family:var(--display);font-weight:100;font-size:clamp(30px,3.6vw,58px);line-height:1}
/* Sobre a chapa de foto a metragem é detalhe de apoio, não é o assunto, então
   entra num corpo menor. O fio divisor também clareia: sobre imagem, a linha do
   campo escuro some. */
/* A METRAGEM VIROU FAIXA, E FAIXA OCUPA O DOBRO.
   `41 m²` são cinco caracteres; `403–481 SF` são dez. Três desses na mesma
   linha não cabiam no corpo antigo — a faixa quebrava no meio, "505–" em cima e
   "564 SF" embaixo, e cada coluna com uma altura diferente. O bloco ganhou a
   largura que a informação passou a pedir e o corpo cedeu o suficiente para os
   três caberem, com a unidade em corpo pequeno ao lado. O número continua sendo
   o assunto da linha. */
.spec--min .size{font-size:clamp(21px,1.9vw,31px);white-space:nowrap}
.spec--min{max-width:min(80ch,1040px)}
.size .un{
  font-family:var(--ui);font-weight:400;
  font-size:.40em;letter-spacing:.14em;
  vertical-align:.26em;
}
.spec--min > *{border-left-color:rgba(244,231,215,.28)}

/* --- 12.3b A TABELA DE TIPOLOGIAS, EM LINHAS.
   Ela nasceu grade de três colunas, quando eram três tipologias e a metragem
   cabia. Agora são cinco famílias e a maior é `981–1,052 SF`, que não entra numa
   coluna de tela estreita sem quebrar no meio do intervalo — "981–" em cima e
   "1,052 SF" embaixo, cada coluna com uma altura.

   Em linha o problema não existe: o nome de um lado, o número do outro, e o fio
   entre as duas pontas é o que o olho segue. É também a forma em que o cliente
   mandou a informação, o que não é coincidência — é a forma natural dela. --- */
.planta{border-top:1px solid var(--line);max-width:min(70ch,840px)}
.planta__linha{
  display:flex;align-items:baseline;justify-content:space-between;
  gap:14px 28px;flex-wrap:wrap;
  border-bottom:1px solid var(--line);
  /* A LISTA ERA DE CINCO LINHAS E PASSOU A OITO em 15/09/2026. O respiro de
     antes, multiplicado por oito, punha a seção 255px além da tela — e a regra
     da página é uma seção, uma tela. A linha ficou mais apertada e o número
     menor, que é o que uma lista longa pede de qualquer forma: com cinco
     linhas o respiro era composição, com oito seria arrastar. */
  /* A MEDIDA OLHA A ALTURA DA TELA, E NÃO SÓ A LARGURA. É a rampa que a
     página inteira usa (`min(vw, svh)`): num notebook de 1366x768 a conta por
     largura daria o respiro de uma tela grande, e a tabela de oito linhas
     esticaria numa tela que é justamente a mais curta. `svh` e não `vh`: o
     `vh` muda quando a barra do navegador de celular some, e uma tabela que
     muda de altura durante a rolagem é pior que uma tabela apertada. */
  padding-block:clamp(7px,min(1.05vw,1.5svh),13px);
}
.planta__nome{
  font-family:var(--ui);font-size:var(--t-label);font-weight:500;
  letter-spacing:.16em;text-transform:uppercase;color:var(--ink);
}
.planta__sf{
  font-family:var(--display);font-weight:100;
  font-size:clamp(18px,min(1.5vw,2.7svh),25px);line-height:1;
  white-space:nowrap;font-variant-numeric:tabular-nums;
}
/* a nota de aproximação é rodapé da tabela, e não um segundo recado */
.planta__nota{margin-top:6px;opacity:.72}
/* Na tela estreita o número cai para 21px, e 21px de peso 100 sobre fotografia
   é fio de cabelo: medido, o pior 5% dos pixels atrás do "505–660 SF" dá 4,03:1.
   O corte sobe para 200 — não muda a conta do contraste, muda a quantidade de
   tinta, que é o que o olho lê num corpo pequeno sobre imagem. */
@media (max-width:760px){
  .planta__sf{font-weight:200}
}
/* NUMA TELA DE 360px O RÓTULO MAIS LONGO NÃO CABE ao lado do número, e a
   fileira quebrava em duas: o nome em cima, a metragem embaixo, alinhada à
   direita, sem par visível. Medido em espanhol, que é o idioma dos rótulos mais
   longos: "2 DORMITORIOS / 2 BAÑOS" gastava 193px de 320 disponíveis.
   A entreletra cai de .16em para .10em e o vão entre os dois de 28 para 14 —
   sobram 279px, e a fileira volta a ser uma linha só. Caixa alta aguenta a
   entreletra menor; o que ela não aguenta é quebrar no meio. */
@media (max-width:480px){
  .planta__linha{gap:10px 14px;flex-wrap:nowrap}
  .planta__nome{letter-spacing:.10em}
}

/* NA TELA LARGA, DUAS COLUNAS DE QUATRO.
   Com cinco linhas a coluna única cabia na tela. Com oito não cabia em
   notebook nenhum: medido, a seção passava 100px da tela em 1600x900 e 207px
   em 1366x768 em português, onde a manchete ocupa três linhas em vez de duas.
   E a regra da página é uma seção, uma tela.
   As saídas eram encolher a manchete — que é direção de arte já aprovada — ou
   dobrar a tabela. Dobrada, ela cai de 397px para 210px e a seção fecha em
   900px exatos numa tela de 900. A conta está do lado certo: oito rótulos
   curtos em duas colunas leem melhor que oito linhas empilhadas, que era o que
   fazia a tabela parecer planilha.

   `column-count` e não uma grade de duas colunas porque o preenchimento é por
   equilíbrio: se um dia forem sete linhas ou nove, ele reparte sozinho, 4+3 ou
   5+4, sem ninguém reescrever regra.

   O FIO MUDOU DE LADO — era `border-bottom`, virou `border-top` — senão a
   última linha de cada coluna fecha com um traço solto embaixo e as duas
   colunas terminam desalinhadas. Com o fio em cima, as duas começam juntas.

   A COLUNA TEM METADE DA LARGURA, ENTÃO O PAR APERTA. Medido no espanhol, que
   tem os rótulos mais longos: "2 DORMITORIOS / 2 BAÑOS" gastava 213px e a
   metragem 139px numa coluna de 343 — a fileira quebrava em duas e o número
   descia para baixo do nome, órfão. Entreletra em .08em, vão de 16px e a
   metragem um degrau menor resolvem, e nenhum dos três se nota: o que se
   notava era a quebra.

   ESTE BLOCO PRECISA VIR DEPOIS das regras base da fileira. Numa primeira
   tentativa ele ficou logo abaixo de `.planta{}`, antes delas, e como a
   especificidade é a mesma quem vinha depois ganhava: `flex-wrap` continuava
   `wrap` e a fileira quebrava do mesmo jeito. Ordem, não especificidade.

   Abaixo de 1100px volta a ser uma coluna só: aí a largura não comporta duas
   sem quebrar o rótulo mais longo. */
/* A FAIXA ENTRE 881 E 1100px É A MAIS APERTADA DA PÁGINA: a placa já reserva
   56% da largura para a fotografia, e o que sobra não comporta duas colunas —
   mas a tela continua curta. Aqui a fileira usa o respiro mínimo e a metragem
   o corpo menor. Não é bonito de medir, é o que faz caber. */
@media (min-width:881px) and (max-width:1099px){
  .planta__linha{padding-block:clamp(5px,min(.8vw,1.1svh),9px)}
  .planta__sf{font-size:clamp(16px,min(1.25vw,2.1svh),20px)}
}

@media (min-width:1100px){
  .planta{column-count:2;column-gap:clamp(24px,2.2vw,40px);border-top:0}
  .planta__linha{
    break-inside:avoid;
    border-top:1px solid var(--line);border-bottom:0;
    gap:10px 16px;flex-wrap:nowrap;
  }
  .planta__nome{letter-spacing:.08em}
  .planta__sf{font-size:clamp(16px,min(1.2vw,2.2svh),21px)}
}

/* texto que monta sobre a borda da imagem */
.overlap{position:relative;z-index:2;margin-left:clamp(-56px,-3.4vw,-20px);background:var(--bg);padding:clamp(20px,2.4vw,34px)}

@media (max-width:880px){
  .split--3,.split--4,.split--5{grid-template-columns:1fr}
  /* em coluna unica o retrato viraria banner: fica faixa larga e baixa */
  /* no celular a folha de contato vira lista: miniatura quadrada à esquerda, o
     nome e a linha à direita. Empilhada com foto larga a seção media duas telas,
     e a regra da casa é uma. */
  .split > *{
    display:grid;grid-template-columns:88px minmax(0,1fr);
    gap:4px 16px;align-items:center;padding-block:clamp(12px,2.4vw,18px);
  }
  .ficha__foto{height:88px;width:88px;margin-bottom:0;grid-row:span 2;align-self:center}
  .split .t{align-self:end}
  .split p{align-self:start;margin-top:2px}
  .split > *{border-left:0;border-top:1px solid var(--line);padding-inline:0}
  .split > *:first-child{border-top:0}
  .spec{grid-template-columns:1fr;gap:22px}
  .spec > *{border-left:0;padding-left:0}
  .stagger > li{padding-left:0 !important;flex-direction:column;gap:2px}
  .overlap{margin-left:0}
}
/* --- 12.11 Tom da casa. Foto de banco que chega crua, de dia, saturada, num
   site que é todo de noite. `tom-casa` põe a imagem no tom da marca sem refazer
   o arquivo: dessatura, esquenta, e joga uma lavagem vinho por cima em
   multiply. A grade de uma célula é o truque para a lavagem cobrir só a foto e
   nunca a legenda, que fica na linha de baixo. --- */
.tom-casa{display:grid;grid-template-rows:auto auto}
.tom-casa img{grid-area:1/1;width:100%;display:block}
.tom-casa::after{
  content:'';grid-area:1/1;pointer-events:none;
  background:linear-gradient(180deg,rgba(74,18,32,.34),rgba(42,18,22,.46));
  mix-blend-mode:multiply;
}
.tom-casa figcaption{grid-area:2/1}
.tom-casa img{filter:saturate(.48) contrast(1.06) brightness(.94) sepia(.16)}

.center{text-align:center}
/* num bloco centrado, o campo também é centrado como bloco. Só alinhar o texto
   não move a caixa, e ela fica torta em relação ao resto. */
.center .field-input{max-width:46ch;margin-inline:auto}
.center .btn{margin-inline:auto}
.center .m-20,.m-20{max-width:20ch;margin-inline:auto}
.rows--index .num{font-family:var(--ui);font-weight:500;font-size:var(--t-label);letter-spacing:.30em;text-transform:uppercase;color:var(--mute)}


/* ==========================================================================
   13. O CAMPO DE COR, E A TROCA DE PÁGINA
   Duas ideias baratas: uma para a virada de seção, outra para a virada de
   página. Nenhuma das duas anima mais de um elemento por vez.
   ========================================================================== */

/* O campo de cor deixa de ser o fundo da seção e vira um elemento por baixo do
   conteúdo. Assim ele pode se mover sozinho: cresce da base para ocupar a tela
   um instante antes de o texto ser desenhado por cima. Como cresce, e não
   desliza, nunca vaza para a seção vizinha e não precisa de recorte.
   O `span` é criado pelo `site.js`. Sem script, a seção fica com o fundo dela
   e nada disso acontece, que é a degradação certa. */
/* `isolation:isolate` não é enfeite: sem ele a seção não abre contexto de
   empilhamento próprio, o campo com z-index negativo escapa para a raiz e vai
   parar ATRÁS do fundo do body, ou seja, some. Com ele o negativo fica preso
   dentro da seção, que é onde ele serve. */
section.tem-campo{background:transparent;position:relative;isolation:isolate}
/* z-index negativo de propósito: o campo fica atrás de TODO o conteúdo da seção
   sem precisar mexer em nenhum filho. Empurrar os filhos para z-index 1 quebraria
   quem já se posiciona sozinho, como a foto de meia tela do The Guide. */
.campo{
  position:absolute;inset:0;z-index:-1;background:var(--bg);
  transform-origin:bottom;transform:scaleY(.86);
  transition:transform 660ms cubic-bezier(.22,.61,.24,1);
  will-change:transform;
}
section.sec-in .campo{transform:none}

/* A TROCA DE PÁGINA. A tela que sai fica onde está enquanto a próxima carrega,
   e um fio coral corre no topo. É o mesmo gesto do risco coral por baixo da
   palavra: alguma coisa está sendo sublinhada, alguma coisa vem. */
.fio{
  position:fixed;top:0;left:0;height:2px;width:100%;z-index:90;
  background:var(--coral);transform:scaleX(0);transform-origin:left;
  transition:transform 260ms cubic-bezier(.3,.7,.3,1);
  pointer-events:none;
}
.fio.correndo{transform:scaleX(.72)}
.fio.chegou{transform:scaleX(1);transition-duration:130ms}

/* E onde o navegador souber, a troca é de verdade: a página que sai apaga, a
   que entra sobe. Onde não souber, é ignorado e a navegação é a de sempre. */
@view-transition{navigation:auto}
::view-transition-old(root){animation:sai-pagina 200ms cubic-bezier(.4,0,1,1) both}
::view-transition-new(root){animation:entra-pagina 440ms cubic-bezier(.22,.61,.24,1) both}
@keyframes sai-pagina{to{opacity:0}}
@keyframes entra-pagina{from{opacity:0;transform:translateY(16px)}}

@media (prefers-reduced-motion:reduce){
  .campo{transition:none;transform:none}
  .fio{display:none}
  ::view-transition-old(root),::view-transition-new(root){animation:none}
}


/* ==========================================================================
   14. A LP: CARTAZ, INSTRUMENTO E CHEGADA
   Três acréscimos que só existem na LP. Nenhum deles anima mais de um elemento
   por vez, que é a regra de peso fixada no site.
   ========================================================================== */

/* --- 14.1 CARTAZ. As telas de frase ganham corpo de cartaz, perto do deck.
   A escala global não muda: `cartaz` é um modificador, e vale só onde a frase
   É a tela. Usar em duas ou três por página, nunca em todas, senão deixa de
   ser ênfase e vira o tamanho normal. --- */
.cartaz{
  font-size:clamp(52px,9.4vw,150px);
  line-height:.96;
  letter-spacing:-.032em;
  max-width:18ch;
}
.cartaz--m{
  font-size:clamp(38px,6vw,92px);
  line-height:1.0;
  letter-spacing:-.026em;
  max-width:22ch;
}
/* no corpo de cartaz o fio coral fica desproporcional se seguir a altura da
   letra, então ele engrossa devagar e sobe um pouco */
.cartaz em,.cartaz--m em{background-size:0 max(3px,.032em);background-position:0 .90em}
section.sec-in .cartaz em,section.sec-in .cartaz--m em{background-size:100% max(3px,.032em)}


/* A CAPA SEGURA PELO CSS, e não pelo script. O `site.js` revela a capa por um
   IntersectionObserver, que dispara depois do meu script: se eu tirasse as
   classes na mão, ele as repunha e a chegada acontecia atrás do pano. Aqui o
   freio é uma classe em `<html>`, posta antes da primeira pintura e tirada na
   hora certa. A especificidade é alta de propósito, para ganhar do estado que
   o script escreve. Nada de `!important`: só um seletor mais específico. */
html.capa-presa #capa [data-rv],
html.capa-presa #capa [data-rv].is-in{
  opacity:0;transform:translateY(16px);transition:none;
}
html.capa-presa #capa [data-rv].rv--type,
html.capa-presa #capa [data-rv].rv--type.is-in{
  opacity:1;transform:translateY(12px);
  clip-path:inset(-10% 0 106% 0);transition:none;
}
html.capa-presa #capa em{background-size:0 max(2px,.045em);transition:none}
html.capa-presa #capa .hero__media img,
html.capa-presa #capa .hero__filme{transform:scale(1.06);transition:none}

/* --- 14.3b A ABERTURA DAS IMAGENS. Do playbook: a foto nao aparece, ela ABRE,
   da esquerda para a direita. O recorte fica no involucro e a escala na
   imagem, entao os dois nunca brigam pela mesma propriedade. --- */
.plate__media,.lamina__foto,.slip__foto,.figure--edit img{
  clip-path:inset(0 100% 0 0);
  transition:clip-path 1200ms var(--ease-rev) var(--d,0ms);
}
section.sec-in .plate__media,
section.sec-in .lamina__foto,
section.sec-in .slip__foto,
section.sec-in .figure--edit img{clip-path:inset(0 0 0 0)}
@media (prefers-reduced-motion:reduce){
  .plate__media,.lamina__foto,.slip__foto,.figure--edit img{clip-path:none;transition:none}
}

/* --- 14.4 OS ESPAÇOS, EM ACORDEÃO.
   Era o dia em horas — 07:40, 09:10, 11:00 — numa fita horizontal de nove
   fotos de banco de imagem, dirigida pela rolagem. O cliente trocou o conteúdo
   por renders do próprio empreendimento em 14/09/2026, e são quatro. Fita
   dirigida por rolagem com quatro quadros não se sustenta: a viagem dura menos
   que a chegada dela, e a seção presa passa a cobrar do visitante uma rolagem
   que não anda nada.

   Acordeão resolve os dois lados. Quatro lâminas de pé dividem a tela, cada
   uma mostrando a sua faixa da foto; a que recebe o ponteiro (ou o foco do
   teclado, ou o toque) abre e as outras encolhem. A seção volta a ser uma tela
   só, sem `pin` e sem sequestro de rolagem.

   NÃO HÁ SCRIPT AQUI. Abrir é `:hover` e `:focus` — o `:focus` é o que faz o
   toque funcionar no celular e o Tab funcionar no teclado, sem uma linha de
   JS. O custo é uma propriedade animada, `flex-grow`, num elemento por vez.

   O BLOCO DA GALERIA NO `cena.js` CONTINUA LÁ, dormindo: ele sai na primeira
   linha quando não acha `[data-trilho]`, e este HTML não tem mais nenhum. --- */
.espacos .sanfona{
  display:flex;gap:clamp(5px,.5vw,9px);
  height:min(74svh,800px);
  margin-top:clamp(28px,4.4vh,54px);
}
.lamina{
  flex:1 1 0;min-width:0;position:relative;overflow:hidden;
  padding:0;border:0;color:inherit;cursor:pointer;
  background:rgba(20,5,10,.58);
  transition:flex-grow 820ms var(--ease);
}
/* a lâmina aberta cresce e as irmãs cedem. As duas metades da conta vivem em
   regras diferentes de propósito: sem a segunda, a que abre empurraria as
   outras para fora da tela em vez de dividir o que sobra com elas */
/* o `:not()` não é enfeite: `.sanfona:hover .lamina` tem três unidades de
   especificidade e `.lamina:hover` tem duas, então sem ele a regra do encolhe
   ganharia também na lâmina que está aberta — medido, as quatro ficavam em
   344px e nada acontecia */
.sanfona:hover .lamina:not(:hover),
.sanfona:focus-within .lamina:not(:focus){flex-grow:.82}
.lamina:hover,.lamina:focus{flex-grow:4.6}
.lamina__foto{position:absolute;inset:0;display:block}
.lamina__foto img{
  position:absolute;inset:0;z-index:1;
  width:100%;height:100%;object-fit:cover;display:block;
  transition:filter 620ms var(--ease);
}
/* quando uma lâmina está aberta, as outras cedem luz. Sem isso as quatro
   disputam o olho com o mesmo brilho e a que abriu não parece a principal —
   é a mesma conta que o mosaico das amenidades já fazia */
.sanfona:hover .lamina:not(:hover) img,
.sanfona:focus-within .lamina:not(:focus) img{filter:brightness(.68) saturate(.88)}
/* A NUMERAÇÃO, NO LUGAR DA LEGENDA.
   O cliente pediu a fita sem legenda nenhuma — as fotos falam sozinhas. O que
   fica é o número, que não descreve nada: ele só diz quantas são e em que
   ordem, e devolve à lâmina fechada uma marca de leitura que ela perderia sem
   texto algum. Dois dígitos cabem deitados até na lâmina mais estreita, então
   aqui não há a troca de eixo que o nome exigia.

   O véu é só o rodapé da lâmina, na dose medida para o número ficar legível
   sobre a foto mais clara da fita — a do lobby. */
.lamina::after{
  /* O VÉU DEIXOU DE COBRIR A FOTO. Ele existia de ponta a ponta e escurecia o
     terço de baixo de cada lâmina inteira para segurar dois dígitos — e a
     fotografia pagava por isso. Agora é uma sombra de canto, ancorada onde o
     número mora: densa no vértice, dissolvida antes de chegar ao meio da
     imagem. Elipse e não faixa, porque o alvo é um ponto, não uma linha. */
  content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:radial-gradient(
    clamp(110px,13vw,190px) clamp(80px,10vh,140px) at 0% 100%,
    rgba(42,18,22,.90) 0%,
    rgba(42,18,22,.64) 38%,
    rgba(42,18,22,.20) 68%,
    rgba(42,18,22,0) 100%);
}
.lamina__num{
  position:absolute;z-index:3;
  left:clamp(12px,1vw,18px);bottom:clamp(12px,1.6vh,20px);
  font-family:var(--ui);font-weight:500;font-size:var(--t-label);
  letter-spacing:.14em;font-variant-numeric:tabular-nums;
  /* creme, e não coral: medido sobre as seis fotos, o coral devolvia 2,07:1 no
     corredor e 2,25:1 na piscina — o coral é escuro, e o rodapé destas fotos
     é claro. O creme sobre o mesmo véu dá de 4,6 para cima em todas. */
  color:var(--cream);
  opacity:.82;
  text-shadow:0 1px 2px rgba(30,10,14,.92),0 0 12px rgba(30,10,14,.7);
  transition:opacity 420ms var(--ease);
}
.lamina:hover .lamina__num,.lamina:focus .lamina__num{opacity:1}

/* o teclado precisa ver onde está; o ponteiro não */
.lamina:focus-visible{outline:2px solid var(--coral);outline-offset:-2px}

/* A LÂMINA PRECISA DA TRANSIÇÃO DE VOLTA.
   O bloco 15.1 desliga `transition` em TODO `[data-rv]` sob `com-cena` — e com
   razão: ali quem anima é a linha do tempo da rolagem, e uma transição de CSS
   na mesma propriedade brigaria com ela. Só que o `data-rv` das lâminas não foi
   escrito à mão: o `site.js` empurra o atributo do contêiner `.sanfona` para
   cada filho, para escaloná-los na entrada. Resultado medido: `transition`
   computava `none` e a lâmina abria seca, sem os 820ms.
   Aqui a transição volta, e SÓ ela — `flex-grow` é a única propriedade que a
   cena não toca, então as duas não se cruzam.

   E a lista tem as DUAS linhas porque o 15.1 também tem: `[data-rv].is-in`
   empata em especificidade com `.lamina[data-rv]` e vem depois na folha, então
   sem a segunda linha a transição voltava a sumir no instante em que a lâmina
   entrava — que é exatamente quando ela passa a ser clicável. */
html.com-cena main .lamina[data-rv],
html.com-cena main .lamina[data-rv].is-in{transition:flex-grow 820ms var(--ease)}

@media (max-width:880px){
  /* de pé numa tela de 390px cada lâmina teria 90px: nem foto, nem nome.
     Deitadas, viram quatro faixas que abrem para baixo. */
  .espacos .sanfona{flex-direction:column;height:auto;gap:8px}
  .lamina,
  html.com-cena main .lamina[data-rv],
  html.com-cena main .lamina[data-rv].is-in{transition:height 700ms var(--ease)}
  .lamina{flex:0 0 auto;height:clamp(76px,11svh,104px)}
  .sanfona:hover .lamina:not(:hover),
  .sanfona:focus-within .lamina:not(:focus){flex-grow:0}
  .lamina:hover,.lamina:focus{flex-grow:0;height:min(54svh,460px)}
}
@media (prefers-reduced-motion:reduce){
  /* a lista completa: quem pede menos movimento tem que ganhar também das duas
     regras acima, que existem só para furar o bloqueio do 15.1 */
  .lamina,.lamina__foto img,
  html.com-cena main .lamina[data-rv],
  html.com-cena main .lamina[data-rv].is-in{transition:none}
}


/* --- 14.2 O INSTRUMENTO SAIU. ---------------------------------------------
   Era uma barra fixa no pé com o endereço, o número da seção e o nome dela.
   Saiu a pedido do cliente em 14/09/2026, de todas as telas, junto com o `001`
   da linha de código da capa.
   Não deixou buraco de espaçamento: o respiro de baixo das seções é
   `max(var(--pe-base), clamp(46px,9svh,150px))`, e os 44px do `--pe-base` —
   que existiam por causa dela — nunca ganhavam do piso do clamp. --- */


/* --- 14.3 A CORTINA E A CHEGADA. Uma tela de vinho com a marca e a linha de
   código, que sobe e revela a capa. Um elemento só se movendo, dentro da regra
   de peso: a marca aparece, a linha se escreve, e só então a cortina sobe.
   A capa espera a cortina começar a subir para se desenhar, senão a chegada
   dela acontece escondida atrás do pano e ninguém vê.
   Ela vive no HTML e não no script, para não haver piscada antes do script
   rodar. Quem a liga é a classe em `<html>`, posta no `<head>`. Sem script,
   classe nenhuma, cortina nenhuma, e a página abre direto. --- */
.cortina{display:none}
html.com-cortina .cortina{
  display:flex;position:fixed;inset:0;z-index:200;
  align-items:center;justify-content:center;flex-direction:column;gap:clamp(20px,2.6vh,34px);
  background:var(--wine-deep);
  transform:translateY(0);
  transition:transform 850ms cubic-bezier(.62,.02,.24,1);
  will-change:transform;
}
html.com-cortina.cortina-sobe .cortina{transform:translateY(-101%)}
/* A MARCA CHEGA COMO NO PLAYBOOK. O lockup empilhado é duas instâncias
   sobrepostas que dividem o mesmo viewBox, então as duas linhas chegam em
   tempos diferentes e voltam a registrar exatamente. A regra do playbook é que
   o nome chega inteiro: nada de contorno, nada de desenhar as letras.
   SEASON¹ primeiro, One depois, o fio coral abrindo do centro, e só então a
   endline e a linha de código. Cinco batidas, uma de cada vez.
   Os tempos são os do playbook, encurtados: lá a sequência leva quatro
   segundos, e uma cortina não pode. */
.mark-stage{position:relative;display:block;width:min(clamp(240px,28vw,400px),58vw);color:var(--cream)}
.mark-stage svg{display:block;width:100%;height:100%}
.mark-stage .mk-line2{position:absolute;left:0;top:0;width:100%;height:100%}
.mark-stage .mk-word{fill:currentColor;stroke:none;opacity:0;transform:translateY(14px)}

.cortina.p1 .mark-stage .mk-line1{opacity:1;transform:none;
  transition:opacity 900ms var(--ease) 0ms,
             transform 1100ms cubic-bezier(.16,.84,.30,1) 0ms}
.cortina.p2 .mark-stage .mk-line2{opacity:1;transform:none;
  transition:opacity 900ms var(--ease) 0ms,
             transform 1100ms cubic-bezier(.16,.84,.30,1) 0ms}

/* o fio abre do centro, como na tela da marca */
.logo-rule{
  width:min(22vw,240px);height:1px;background:var(--coral);opacity:.9;
  transform:scaleX(0);transform-origin:center;
  transition:transform 1100ms cubic-bezier(.16,.84,.30,1);
}
.cortina.p3 .logo-rule{transform:scaleX(1)}
.cortina__tag{
  font-family:var(--display);font-weight:200;
  font-size:clamp(22px,2.4vw,34px);letter-spacing:-.012em;line-height:1.1;
  color:var(--cream);
  opacity:0;transition:opacity 560ms var(--ease);
}
/* o fio coral por baixo da palavra marcada, a mesma gramatica do resto do site.
   Aqui o traco nao pode depender de `section.sec-in`, porque a cortina nao e
   secao: quem o dispara e a propria batida da tagline. */
.cortina__tag em{
  font-style:normal;color:inherit;
  background-image:linear-gradient(var(--coral),var(--coral));
  background-repeat:no-repeat;
  background-size:0% max(2px,.05em);
  background-position:0 92%;
  padding-bottom:.06em;
  transition:background-size 760ms var(--ease-rev) 300ms;
}
.cortina__code{
  font-family:var(--ui);font-weight:500;font-size:var(--t-label);
  letter-spacing:.30em;text-transform:uppercase;color:var(--mute);
  opacity:0;transition:opacity 460ms var(--ease);
}
.cortina.p4 .cortina__tag{opacity:1}
.cortina.p5 .cortina__code{opacity:1}
/* enquanto a cortina está de pé, a página não rola */
html.com-cortina:not(.cortina-fim){overflow:hidden}

@media (prefers-reduced-motion:reduce){
  html.com-cortina .cortina{display:none}
  html.com-cortina{overflow:auto}
}


/* ---------- 15. AJUSTES DE TELA ESTREITA QUE PRECISAM VIR NO FIM ----------
   Estas regras dependem de vir depois das regras base, senão perdem por ordem. */
@media (max-width:880px){
  /* meia tela de foto vira imagem inteira, embaixo do texto */
  section.half{display:block}
  .half__media{position:relative;width:100%;height:46svh;margin-top:clamp(28px,5vw,44px);right:auto}
  .half__text{max-width:none}
}


/* ---------- 16. O MAPA DO PASSAPORTE ----------
   O chão da seção é o mapa. Ele é o `light-v11` do Mapbox recolorido na paleta
   do projeto por uma rampa de luminância: água quase preta, chão vinho, quadras
   um tom acima, ruas em blush. Nenhum cinza sobrou.
   O `isolation:isolate` é obrigatório de novo: sem ele o `z-index:-1` do chão
   escapa para a raiz e o mapa some atrás do fundo da página. Terceira vez que
   essa armadilha aparece no projeto.
   Nada aqui anima mais de um elemento por vez: o mapa abre da esquerda para a
   direita como as outras imagens, e só depois os pinos acendem, um a um. */
section.mapa{
  position:relative;isolation:isolate;overflow:hidden;
  display:flex;flex-direction:column;justify-content:space-between;align-items:stretch;
  background:var(--wine-deep);
}
.mapa__chao{position:absolute;inset:0;z-index:0;margin:0;overflow:hidden}
.mapa__chao img{
  position:absolute;inset:0;
  width:100%;height:100%;object-fit:cover;display:block;
  clip-path:inset(0 100% 0 0);transition:clip-path 1400ms var(--ease-rev);
}
/* os níveis de desfoque só existem para a cena. Sem ela — celular, GSAP fora
   do ar, quem pede menos movimento — o chão é a imagem nítida e mais nada.

   O seletor é `.mapa__chao img.mapa__desfoque` e não `.mapa__desfoque` porque
   `.mapa__chao img` acima pesa mais do que uma classe sozinha, e media query
   não acrescenta peso nenhum: escrito curto, o `display:block` da regra de
   cima vencia mesmo estando centenas de linhas antes. */
.mapa__chao img.mapa__desfoque{opacity:0}
section.mapa.sec-in .mapa__chao img{clip-path:inset(0 0 0 0)}
/* o véu virou elemento próprio, `.mapa__veu`, porque agora ele precisa cobrir
   também o canvas do mapa vivo, e não só a imagem. */

/* --- 16.0 O mapa vivo. O canvas cobre o chão estático assim que carrega. O
       estático fica embaixo como poster e como plano B para máquina sem rede. --- */
.mapa__gl{position:absolute;inset:0;z-index:0;opacity:0;transition:opacity 900ms var(--ease)}
section.mapa.mapa-vivo .mapa__gl{opacity:1}
.mapa__gl .mapboxgl-canvas{outline:none}
.mapa__gl .mapboxgl-ctrl-logo{opacity:.34}
/* o véu do chão precisa passar por cima do canvas também, senão o título perde
   contraste quando o mapa vivo entra */
.mapa__veu{
  /* O VÉU SANGRA 16px PARA BAIXO, e isso não muda nada do que se vê.
     `section.mapa` tem `overflow:hidden`, então a sobra é aparada exatamente na
     borda da seção: o desenho fica idêntico. O que ela resolve é um relato de
     uma faixa de uns cinco pixels no pé da tela, mais clara que o resto —
     a cor dela variava na horizontal como o mapa SEM véu varia, enquanto a área
     logo acima era achatada como o mapa COM véu. Ou seja: o véu terminava alguns
     pixels antes do chão.
     Não reproduzi em 1600x900, 1920x1080, 2000x1029 nem 2536x1302, com escala de
     tela 1, 1.25, 1.272 e 1.5 — em todas as medidas, véu e chão terminam no mesmo
     pixel. Como a causa é do outro lado e o custo daqui é zero, o véu passa a
     sobrar. Se a faixa insistir, ela não é do véu e o comentário aqui poupa a
     próxima meia hora de caça. */
  position:absolute;inset:0 0 -16px 0;z-index:1;pointer-events:none;
  background:
    linear-gradient(102deg,rgba(23,7,16,.82) 0%,rgba(23,7,16,.44) 26%,rgba(23,7,16,0) 52%,rgba(23,7,16,.14) 100%),
    linear-gradient(180deg,rgba(23,7,16,.36) 0%,rgba(23,7,16,0) 20%,rgba(23,7,16,0) 60%,rgba(23,7,16,.76) 100%);
}
/* o mapa ja e escuro por dentro, entao o veu so precisa segurar o titulo e o pe.
   Antes ele apagava o desenho inteiro, e era metade do motivo de a seção nao se
   ler: escuro sobre escuro nao vira hierarquia, vira mancha. */

.mapa__leme{
  position:absolute;right:var(--pad-x);top:50%;transform:translateY(-50%);z-index:6;
  display:flex;flex-direction:column;gap:8px;
}
/* o leme só existe com o mapa vivo. Sem esta linha o `display:flex` acima ganha
   do `hidden` do navegador e os botões aparecem sobre o mapa estático, sem fazer
   nada. */
.mapa__leme[hidden]{display:none}

/* A DICA DE ARRASTAR.
   O arrasto não tem afordância nenhuma num mapa sem moldura: quem não tenta,
   não descobre. A dica aparece com o mapa vivo, some no primeiro arrasto e não
   volta — e não existe onde não há ponteiro. */
.mapa__dica{
  font-family:var(--ui);font-size:var(--t-small);letter-spacing:.14em;
  text-transform:uppercase;color:var(--mute);
  display:none;align-items:center;gap:9px;
  transition:opacity 520ms var(--ease);
}
.mapa__dica::before{
  content:'';width:15px;height:15px;flex:none;border-radius:50%;
  border:1px solid var(--mute);
  box-shadow:inset 0 0 0 3px rgba(201,148,142,.35);
}
section.mapa.mapa-vivo .mapa__dica{display:inline-flex}
section.mapa.ja-arrastou .mapa__dica{opacity:0;pointer-events:none}
@media (hover:none),(max-width:880px){
  section.mapa.mapa-vivo .mapa__dica{display:none}
}
.leme__b{
  width:40px;height:40px;display:grid;place-items:center;cursor:pointer;
  font-family:var(--ui);font-weight:400;font-size:17px;line-height:1;
  color:var(--cream);background:rgba(36,14,18,.72);border:1px solid rgba(244,231,215,.20);
  -webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px);
  transition:border-color 300ms var(--ease),color 300ms var(--ease),background 300ms var(--ease);
}
.leme__b:hover{border-color:var(--coral);color:var(--coral)}
.leme__b:focus-visible{outline:1px solid var(--coral);outline-offset:2px}
.leme__b--voltar{font-size:15px;margin-top:6px}

.mapa__topo{position:relative;z-index:4;pointer-events:none;max-width:var(--maxw)}
.mapa__topo .d3{max-width:16ch}
.mapa__pe{
  position:relative;z-index:4;
  display:flex;align-items:baseline;justify-content:space-between;gap:24px;flex-wrap:wrap;
}
.mapa__cred{
  font-family:var(--ui);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(244,231,215,.44);white-space:nowrap;
}
/* o pe fica sobre a malha das ruas, entao o texto precisa da propria sombra */
.mapa__pe .slug,.mapa__cred{text-shadow:0 1px 18px rgba(42,18,22,.95),0 0 4px rgba(42,18,22,.7)}

/* --- 16.1 Os pinos. O JS calcula a posição a partir do enquadramento e do
       corte real do `object-fit:cover`, então eles continuam certos em
       qualquer largura. --- */
/* A CAMADA DOS PINOS NÃO PODE RECEBER O GESTO.
   Ela cobre a seção inteira — precisa, para poder pôr um pino em qualquer ponto
   dela — e com isso engolia todo o arrasto antes de ele chegar no mapa. Medido:
   arrastar 180px não movia o mapa um pixel, e o elemento sob o cursor no meio da
   seção era `.mapa__pinos`. A camada deixa de receber ponteiro e cada pino volta
   a receber o seu, que é o único pedaço dela que precisa de clique. */
.mapa__pinos{position:absolute;inset:0;z-index:2;pointer-events:none}
.mapa__pinos .pino{pointer-events:auto}
/* e o canto onde o mapa recebe o gesto avisa que recebe */
section.mapa.mapa-vivo .mapa__gl{cursor:grab}
section.mapa.mapa-vivo .mapa__gl:active{cursor:grabbing}
.pino{
  position:absolute;background:none;border:0;padding:7px 8px;margin:0;cursor:pointer;
  display:flex;align-items:center;gap:11px;color:var(--cream);
  transform:translate(-15px,-50%);
  opacity:0;transition:opacity 620ms var(--ease) var(--d,0ms);
}
section.mapa.sec-in .pino{opacity:1}
.pino--esq{flex-direction:row-reverse;transform:translate(calc(-100% + 15px),-50%)}
/* o mapa tem malha fina demais para um ponto liso: o pino e coral com anel de
   creme e contorno escuro, que e a unica combinacao que nao se perde na rua
   nem no quarteirao. */
.pino__ponto{
  flex:none;width:14px;height:14px;border-radius:50%;background:var(--coral);
  box-shadow:0 0 0 3px rgba(244,231,215,.94),0 0 0 4.5px rgba(36,14,18,.65),
             0 6px 20px rgba(36,14,18,.55);
  transition:box-shadow 320ms var(--ease);
}
/* A PLACA ESPERA A VEZ DELA.
   Com quatro pontos as placas cabiam todas abertas e a seção se lia sem clicar
   em nada. Com vinte não cabem: medido, vinte pinos abertos davam QUINZE pares
   de placa sobrepostos numa tela de 1440 — cada placa tem entre 250 e 330px de
   largura e a seção tem 1440.

   Então a placa sai do fluxo e só aparece em três casos: a casa, que é a
   âncora e não pode sumir; o pino sob o ponteiro ou com foco de teclado; e o
   pino aberto. O ponto coral continua igual, sempre visível — a identidade é
   dele, e ela não muda. O que muda é quando o nome aparece.

   Fora do fluxo também por hit test: placa invisível mas ocupando espaço faz um
   pino roubar o hover do vizinho, e aí o mapa vira campo minado. */
/* A PLACA NÃO ENCOSTA NO PONTO.
   O -4px puxava a placa para cima da folga do botão, e no pino da casa — que
   tem o ponto maior e um halo de 16px que não ocupa espaço de layout — ela
   passava por cima do próprio halo. Seis pixels de ar nos pinos comuns, e
   dezoito no da casa, que é onde o halo termina. */
.pino__nome{
  position:absolute;left:calc(100% + 6px);top:50%;transform:translateY(-50%);
  opacity:0;pointer-events:none;
  transition:opacity 240ms var(--ease);
}
.pino--esq .pino__nome{left:auto;right:calc(100% + 6px)}
.pino--casa .pino__nome{left:calc(100% + 18px)}
.pino--casa.pino--esq .pino__nome{left:auto;right:calc(100% + 18px)}
/* A PLACA NÃO RECEBE PONTEIRO.
   Ela tem 250px e mora dentro de um botão que recebe: a placa do pino aberto
   passava por cima do ponto do vizinho e engolia o hover dele. Medido: quatro
   pinos do nordeste não respondiam por causa disso. Quem recebe é o ponto. */
.pino__nome{pointer-events:none}
.pino--casa .pino__nome,
.pino:hover .pino__nome,
.pino:focus-visible .pino__nome,
.pino.is-aberto .pino__nome{opacity:1}
/* O PINO VIRA SÓ O PONTO, E A FOLGA DE TOQUE ENCOLHE COM ELE.
   Com 9px de folga a área de clique de cada pino tinha 32px, e dois pontos a
   trinta metros de distância — o LPM e o Osaka — tinham as áreas sobrepostas
   mesmo depois de afastados. Com 5px a área fica em 24px e o afastamento de
   26px basta, o que quer dizer meia dúzia de pixels de empurrão em vez de uma
   dúzia: menos mentira na posição. */
.mapa__pinos .pino{padding:5px}
.pino__nome{
  font-family:var(--ui);font-weight:500;font-size:var(--t-label);
  letter-spacing:.22em;text-transform:uppercase;white-space:nowrap;
  display:flex;align-items:center;gap:10px;
  padding:6px 11px;background:rgba(36,14,18,.74);border:1px solid rgba(244,231,215,.16);
  -webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px);
  transition:color 320ms var(--ease),border-color 320ms var(--ease);
}
/* a conta de minutos entra na placa, depois de um fio. Assim a seção se lê sem
   clicar em nada: porta, caminho, lugar, minutos. */
.pino__min{color:var(--coral);font-variant-numeric:tabular-nums;letter-spacing:.16em}
.pino__min:empty{display:none}
.pino__min::before{
  content:'';display:inline-block;width:12px;height:1px;vertical-align:middle;
  margin-right:10px;background:rgba(244,231,215,.34);
}
.pino--casa .pino__nome{gap:0}
.pino:hover .pino__ponto,.pino.is-aberto .pino__ponto{
  box-shadow:0 0 0 3px rgba(244,231,215,1),0 0 0 4.5px rgba(36,14,18,.65),
             0 0 0 13px rgba(217,86,60,.24);
}
.pino:hover .pino__nome,.pino.is-aberto .pino__nome{color:var(--blush);border-color:rgba(217,86,60,.55)}
.pino:focus-visible{outline:1px solid var(--coral);outline-offset:2px}
/* arrastado para fora do enquadramento o pino sai de cena em vez de encostar
   na borda e virar sujeira */
.mapa__pinos .pino.is-fora{opacity:0;pointer-events:none;transition:opacity 200ms linear}
/* com um cartao aberto os outros pinos recuam. O cartao cobre parte do mapa de
   qualquer jeito: recuando eles, o que some parece escolha e nao falha. */
.mapa__pinos.tem-aberto .pino:not(.is-aberto):not(.pino--casa){
  opacity:.30;transition:opacity 300ms var(--ease) 0s;
}

/* a casa não abre cartão: ela é a origem da conta, não um destino */
.pino--casa{pointer-events:none}
.pino--casa .pino__ponto{
  width:18px;height:18px;background:var(--coral);
  box-shadow:0 0 0 4px rgba(244,231,215,.96),0 0 0 5.5px rgba(36,14,18,.70),
             0 0 0 16px rgba(217,86,60,.20),0 8px 26px rgba(36,14,18,.6);
}
.pino--casa .pino__nome{
  font-family:var(--display);font-weight:200;font-size:var(--d4);
  text-transform:none;letter-spacing:0;color:var(--cream);
  padding:8px 15px;border-color:rgba(217,86,60,.45);background:rgba(36,14,18,.80);
}

/* --- 16.2 Os cartões. São os mesmos `.slip` da lista antiga, só que o mapa os
       posiciona ao lado do pino. Um nó só: a tradução acha, e a tela estreita
       mostra a lista inteira de volta. --- */
/* A FICHA VEM NA FRENTE DE TUDO QUE É TEXTO FIXO.
   Ela nasceu em z-index 3, abaixo do pé da seção (4) — e o pé tem duas linhas
   que atravessam a tela inteira: a nota das distâncias e a dica de arrastar.
   Com a foto dentro da ficha elas passaram a aparecer POR CIMA da fotografia,
   o que só se lê como defeito. A ficha subiu para 5.
   O LEME NÃO: ele foi para 6. Os botões de zoom são a única coisa aqui que a
   pessoa pode querer alcançar ENQUANTO uma ficha está aberta, e uma ficha que
   abrisse na borda direita os cobriria. Texto fica atrás, botão fica na
   frente. */
.mapa__lista{position:absolute;inset:0;z-index:5;display:block;gap:0;pointer-events:none}
.mapa__lista .slip{
  position:absolute;width:min(320px,28vw);min-height:0;height:auto;
  padding:clamp(18px,1.6vw,24px);gap:16px;background:var(--choc);
  border-color:rgba(244,231,215,.28);
  opacity:0;visibility:hidden;transform:translateY(10px);pointer-events:none;
  transition:opacity 380ms var(--ease),transform 520ms var(--ease-rev),visibility 0s 420ms;
}
.mapa__lista .slip::before{
  content:'';position:absolute;left:0;top:0;width:100%;height:1px;background:var(--coral);
  transform:scaleX(0);transform-origin:left;transition:transform 620ms var(--ease-rev) 120ms;
}
/* O CARTÃO ABERTO NÃO PODE TAPAR OS PINOS.
   Ele nasce ao lado do ponto e cobre um bom pedaço do mapa — e com vinte pontos
   isso deixou de ser detalhe: medido, oito dos dezenove pinos ficavam embaixo do
   cartão aberto e simplesmente não respondiam ao ponteiro. Era o "alguns nomes
   não acendem".

   No computador o cartão é aviso e não controle: não tem link nem botão dentro.
   Então ele deixa o ponteiro passar direto para o pino que estiver embaixo. Na
   tela estreita, onde o cartão vira item de lista e precisa receber toque, a
   regra não vale. */
/* SEM FOTO O CARTÃO ENCOLHE ATÉ O TEXTO.
   O `min-height` de 290px do cartão existe para a faixa da fotografia. Sem ela
   ele vira um bloco com 170px de vazio em cima do nome — medido, 280px de
   cartão para três linhas de texto. */
.mapa__lista .slip--texto{min-height:0;gap:12px;justify-content:flex-start}

.mapa__lista .slip.is-aberto{
  opacity:1;visibility:visible;transform:none;pointer-events:none;transition-delay:0s;
}
.mapa__lista .slip.is-aberto::before{transform:scaleX(1)}
.mapa__lista .slip__foto{position:absolute;inset:auto 0 auto 0;top:0;height:150px;z-index:-1}
/* no cartao a foto e uma faixa no topo, entao o veu tem que morrer no choc do
   cartao e nao no meio da imagem como faz o veu do cartao de tela cheia */
.mapa__lista .slip__foto::after{
  background:linear-gradient(180deg,rgba(42,18,22,.26) 0%,rgba(42,18,22,.06) 40%,rgba(42,18,22,.72) 82%,rgba(42,18,22,1) 100%);
}
.mapa__lista .slip{padding-top:166px}
/* ...menos os que não têm foto: os 166px são a faixa dela, e sem foto viram
   166px de vazio em cima do nome. Medido: cartão de 276px para três linhas. */
.mapa__lista .slip--texto{padding-top:clamp(18px,1.6vw,24px)}
.slip__txt{
  font-size:var(--t-small);line-height:1.5;color:var(--mute);margin-top:8px;max-width:30ch;
}
.mapa__lista .slip__msg{font-size:clamp(22px,1.7vw,28px)}

@media (prefers-reduced-motion:reduce){
  .mapa__chao img{clip-path:none;transition:none}
  .pino{transition:none}
  .mapa__lista .slip,.mapa__lista .slip::before{transition:none}
}

/* O BOTÃO "VER TODOS" SÓ EXISTE ONDE A LISTA É A SEÇÃO.
   No computador os cartões são pop-up do mapa e nunca estão todos abertos ao
   mesmo tempo; o botão ali não teria o que abrir. */
.mapa__mais{display:none}

/* --- 16.4 OS DOIS ATOS DA CIDADE. ------------------------------------------

   O texto do Miami e o mapa eram duas seções, e a segunda abria com o mapa já
   nítido: um corte seco entre uma tela de palavras e uma tela de desenho. Agora
   são dois atos da mesma cena presa. O mapa está ali desde o primeiro quadro,
   fora de foco, por baixo do texto — e a rolagem é o anel de foco.

   TRÊS FASES, UM NÚMERO SÓ. `--voo` vem da cena, de 0 a 1, e aqui vira três
   janelas que se sobrepõem de propósito: o texto começa a sair antes de o mapa
   terminar de focar, e o mapa termina de focar antes de o segundo ato chegar.
   Sem essa sobreposição seriam três animações em fila, e fila se lê como espera.

   POR QUE O DESFOQUE MORA NA IMAGEM ESTÁTICA, e não no mapa vivo: o Mapbox é um
   canvas WebGL que se redesenha, e desfocar canvas vivo custa a cada quadro. A
   imagem estática já existia como plano B para máquina sem rede — aqui ela ganha
   um segundo emprego. O mapa vivo só aparece quando o desfoque já zerou, e a
   troca acontece no quadro em que ninguém consegue ver a diferença.

   TUDO ISTO É DA CENA E DO DESKTOP. Sem GSAP, `com-cena` nunca é escrita e o ato
   1 volta a ser um bloco de texto em fluxo, acima do mapa; no celular não há
   mapa nenhum, a lista É a seção, e o texto é só texto. */

@media (min-width:881px){
  html.com-cena .cidade.voo-na-cena{
    /* sem a cena viva o número não existe: 1 quer dizer "tudo já aconteceu" */
    --v:var(--voo,1);
    /* AS TRÊS JANELAS, E POR QUE CADA UMA COMEÇA ONDE COMEÇA.
       A regra que manda é uma só: o ato 1 não pode SAIR antes de terminar de
       CHEGAR. Medido peça a peça, a última letra dele pousa em .46 do voo —
       com dez de `data-cena-extra`, que é o que espreme a entrada dos oito
       blocos na primeira metade e deixa a segunda livre para a passagem.
       De .46 a .56 o texto fica parado, inteiro, sem nada acontecendo: esse
       repouso é conteúdo, não sobra. É o tempo de ler.
       Depois as três se cruzam de propósito — o texto começa a sair antes de o
       mapa terminar de focar, o mapa termina antes de o segundo ato chegar.
       Encostadas em fila, seriam três esperas; cruzadas, são um movimento. */
    /* o texto sai */          --sai:clamp(0,calc((var(--v) - .56) / .22),1);
    /* o mapa entra em foco */ --nitido:clamp(0,calc((var(--v) - .52) / .30),1);
    /* o segundo ato chega */  --chega:clamp(0,calc((var(--v) - .80) / .18),1);
  }

  /* O ATO 1 VIRA CAMADA. Em fluxo ele empurraria o mapa para baixo; aqui cobre
     a seção inteira e centra na altura. `margin-inline:auto` com os quatro
     lados presos é o que mantém a medida do `.wrap` no meio da tela. */
  html.com-cena .cidade.voo-na-cena .cidade__ato--voz{
    /* A CAIXA NÃO PODE ESTICAR. `inset:0` parecia o jeito óbvio de cobrir a
       seção e mudava a diagramação: a última fileira da grade é `1fr`, e `1fr`
       recebe A SOBRA DA CAIXA. Com a caixa do tamanho do conteúdo — que é como
       ela nasceu, item de um flex com `align-items:center` — a sobra é pequena
       e o fecho fica logo abaixo da manchete. Esticada até a tela inteira, a
       sobra vira meia tela: a manchete sobe para o topo, o fecho desce para o
       pé, e o que era um bloco vira duas pontas distantes.

       Então a camada continua do tamanho do conteúdo e se centra na altura
       pelo velho `top:50%` com meio corpo de volta. Esse meio corpo entra na
       MESMA declaração da saída, porque `translate` é uma propriedade só e a
       segunda escrita apagaria a primeira. */
    position:absolute;left:0;right:0;top:50%;z-index:5;
    margin-inline:auto;
    opacity:calc(1 - var(--sai));
    translate:0 calc(-50% - var(--sai) * 6svh);
    filter:blur(calc(var(--sai) * 10px));
  }

  /* O FOCO. A escala existe POR CAUSA do desfoque: borrão precisa de material
     além da borda, senão o filtro puxa transparência de fora e a imagem ganha
     uma moldura clara nos quatro lados. Seis por cento cobrem 30px de raio. */
  /* O FOCO, POR TROCA DE NÍVEL E NÃO POR FILTRO.
     Catorze, oito, quatro, zero. Cada nível se apaga sobre o de baixo, e as
     janelas se sobrepõem de propósito: com elas encostadas via-se o degrau, com
     elas cruzadas o olho lê uma passagem contínua. Quatro estados bastam porque
     o véu por cima e o movimento da rolagem escondem o resto.

     A conta de cada linha é a mesma: a camada vale 1 até `a`, cai até `b`, e de
     lá em diante é zero. */
  html.com-cena .cidade.voo-na-cena .mapa__desfoque:nth-of-type(4){   /* 14px */
    opacity:calc(1 - clamp(0,calc((var(--nitido) - .02) / .28),1));
  }
  html.com-cena .cidade.voo-na-cena .mapa__desfoque:nth-of-type(3){   /* 8px  */
    opacity:calc(1 - clamp(0,calc((var(--nitido) - .22) / .36),1));
  }
  html.com-cena .cidade.voo-na-cena .mapa__desfoque:nth-of-type(2){   /* 4px  */
    opacity:calc(1 - clamp(0,calc((var(--nitido) - .50) / .38),1));
  }
  /* O VÉU ANDA POUCO, e por um motivo que não é o óbvio. A tentação era pesá-lo
     no ato 1, onde há seis parágrafos para segurar; só que o escuro que salva o
     texto é o mesmo que apaga o mapa, e apagar o mapa é perder a única coisa que
     o ato 1 tem a dizer sobre o que vem depois. O contraste vem do desfoque, que
     já tira todo o detalhe que competiria com a letra. */
  html.com-cena .cidade.voo-na-cena .mapa__veu{
    opacity:calc(.80 - var(--nitido) * .22);
  }
  /* o mapa vivo espera o foco. Ao quadrado para não assomar cedo: a imagem e o
     canvas não são idênticos, e a sobreposição dos dois meio a meio é a única
     parte da troca que se enxerga */
  html.com-cena .cidade.voo-na-cena.mapa-vivo .mapa__gl{
    opacity:calc(var(--nitido) * var(--nitido));
  }

  /* O ATO 2. Os blocos dele já se formaram por dentro, escondidos; o que se vê
     é esta camada abrindo. Os pinos são conta do `cena.js`, que já os trata
     como tardios. */
  html.com-cena .cidade.voo-na-cena .cidade__ato--mapa{
    opacity:var(--chega);
    translate:0 calc((1 - var(--chega)) * 2.4svh);
  }
  /* O PÉ É DO SEGUNDO ATO TAMBÉM. "Tempos de caminhada medidos porta a porta",
     o crédito do Mapbox e a dica de arrastar falam todos de um mapa — e por
     baixo do texto do Miami não há mapa nenhum a que se referir, só um borrão.
     Legenda de coisa que ainda não chegou é ruído. */
  html.com-cena .cidade.voo-na-cena .mapa__pe{opacity:var(--chega)}

  /* OS CARTÕES TAMBÉM SÃO DO SEGUNDO ATO.
     Um cartão aberto no mapa continuava aberto quando a pessoa rolava de volta,
     e aparecia flutuando sobre o texto do Miami — um pedaço de uma tela por
     cima da outra. Ele não se fecha sozinho porque ninguém mandou: o mapa não
     sabe que a seção tem dois atos.
     Não precisa saber. A lista inteira acompanha a chegada do ato 2, e o que
     estava aberto some junto com ela. Quando a pessoa voltar para a frente, o
     cartão continua onde estava — o que é melhor do que fechá-lo à força. */
  html.com-cena .cidade.voo-na-cena .mapa__lista{opacity:var(--chega)}

  /* O PONTEIRO É DE UM ATO DE CADA VEZ.
     Enquanto o texto está na tela, ele pode ser selecionado e lido, e o mapa
     por baixo — borrado, sem pino aceso — não tem por que responder a nada.
     Quando o texto sai, some também do caminho do ponteiro: invisível e
     clicável é a pior das combinações, porque o clique não vai a lugar nenhum
     e ninguém vê por quê. */
  html.com-cena .cidade.voo-na-cena.cidade--ato2 .cidade__ato--voz{pointer-events:none}
  html.com-cena .cidade.voo-na-cena:not(.cidade--ato2) .mapa__pinos .pino,
  html.com-cena .cidade.voo-na-cena:not(.cidade--ato2) .mapa__gl,
  html.com-cena .cidade.voo-na-cena:not(.cidade--ato2) .mapa__leme{pointer-events:none}
}

/* --- 16.3 Tela estreita: o mapa vira textura e a lista volta a ser lista. --- */
@media (max-width:880px){
  section.mapa{display:flex;flex-direction:column;justify-content:center;gap:clamp(28px,5vw,48px)}
  .mapa__pinos{display:none}
  .mapa__leme{display:none}
  .mapa__gl{display:none}
  .mapa__chao img{opacity:.42}
  /* os níveis de desfoque saem de cena aqui. `.mapa__chao img` vence o
     `opacity:0` deles por especificidade, e o que sobrava eram três borrões
     a 42% empilhados sobre o mapa — a textura que a tela estreita usa como
     fundo ficava lavada. No celular não há foco a puxar: não há mapa vivo,
     não há pin, e a lista É a seção. */
  .mapa__chao img.mapa__desfoque{display:none}

  /* O CHÃO DO MAPA ESTAVA POR CIMA DO TEXTO, e não só no caminho do clique.
     `.mapa__chao` é absoluto, cobre a seção inteira e tem `z-index:0`; o véu
     tem 1. O conteúdo da seção não declara nível nenhum, e num contexto de
     empilhamento quem não declara perde para quem declara zero. Resultado no
     celular: a imagem do mapa a 42% pintada SOBRE a manchete e os parágrafos
     do primeiro ato — a mancha que se via como "uma sombra da tela anterior
     sobrando em cima do texto". Medido: no ponto da manchete a pilha era
     letra > img(.42) > figure.mapa__chao > h2.

     Uma linha antes disto já tinha aparecido o mesmo defeito no botão "ver
     mais", e ele foi resolvido sozinho, com `z-index:3`. Era o sintoma, não a
     causa: quem precisa subir é TODO o conteúdo da seção, não um botão.
     `z-index:2` põe os dois atos acima do chão e do véu, e abaixo da lista
     (5) e do leme (6), que já tinham nível próprio. */
  .cidade__ato,.mapa__topo,.mapa__pe{position:relative;z-index:2}
  .mapa__topo,.mapa__pe{padding-inline:var(--pad-x)}
  /* o chão do mapa é absoluto e cobre a seção inteira: sem subir o botão, ele
     fica embaixo da imagem e o clique nunca chega — medido, a imagem
     interceptava o ponteiro */
  .mapa__mais{display:block;position:relative;z-index:3;padding-inline:var(--pad-x);margin-top:16px}
  .mapa__mais button{
    font-family:var(--ui);font-size:var(--t-label);font-weight:500;
    letter-spacing:.18em;text-transform:uppercase;color:var(--ink);
    border-bottom:1px solid var(--line);padding:6px 0;
  }
  /* do sétimo em diante só a pedido */
  .mapa__lista:not(.tudo-a-mostra) .slip:nth-child(n+7){display:none}
  .mapa__lista{
    position:static;display:grid;grid-template-columns:1fr;gap:14px;
    pointer-events:auto;padding-inline:var(--pad-x);max-width:var(--maxw);
    margin-inline:auto;width:100%;
  }
  /* `relative` e nao `static`: a foto do cartao e absoluta e precisa deste bloco
     como bloco continente. Com `static` ela escapa para a secao e cobre a tela
     inteira. Mesma familia de armadilha do `z-index:-1`. */
  .mapa__lista .slip{
    position:relative;left:auto;top:auto;width:auto;opacity:1;visibility:visible;transform:none;
    pointer-events:auto;min-height:clamp(150px,18vh,190px);padding-top:clamp(16px,1.6vw,20px);
  }
  .mapa__lista .slip__foto{inset:0;height:auto}
  /* de volta ao veu de cartao inteiro: aqui a foto e o fundo todo, entao o
     escuro tem que estar no topo para o rotulo em coral se ler */
  .mapa__lista .slip__foto::after{
    /* MEDIDO EM 393x852, o texto contra o pixel que está debaixo dele: o rótulo
       de minutos ficava entre 1,7 e 4,1 e a descrição entre 3,7 e 4,4 — abaixo
       dos 4,5 que texto de 11 e 12 pixels pede. O véu subiu nas três paradas, e
       o meio é o que mais mudou, porque é onde a descrição se apoia. */
    background:linear-gradient(180deg,rgba(42,18,22,.92),rgba(42,18,22,.72) 46%,rgba(42,18,22,.95));
  }
  .mapa__lista .slip::before{display:none}
}

/* ==========================================================================
   15. A CENA
   O CSS de que o `cena.js` precisa. Tudo aqui existe por causa de uma animação
   dirigida pela rolagem, e nada aqui pinta ou posiciona conteúdo: se o GSAP
   não carregar, `com-cena` nunca é escrita e nenhuma destas regras vale.
   ========================================================================== */

/* --- 15.1 O CONTEÚDO É DA CENA. ------------------------------------------
   Sob `com-cena`, TODO bloco de conteúdo nasce invisível e sem transição, e
   quem o acende é o script, no tempo da rolagem. A revelação por CSS do bloco
   9 continua ali inteira, e é ela que vale quando não há cena — que é o plano
   B do projeto, não um caso de erro. */
html.com-cena main [data-rv],
html.com-cena main [data-rv].is-in,
html.com-cena main [data-rv].rv--type,
html.com-cena main [data-rv].rv--type.is-in{
  opacity:0;
  filter:none;
  transform:none;
  clip-path:none;
  transition:none;
  -webkit-mask-image:none;mask-image:none;
}

/* o fio coral também: quem o traça é a linha do tempo, junto com a frase que
   ele marca. Duas curvas escrevendo a mesma propriedade fazem a transição
   recomeçar a cada quadro, e como esta tem 760ms de atraso, ela nunca sairia
   do atraso. */
html.com-cena main [data-rv] em{transition:none}

/* --- 15.2 O CAMPO DE COR NÃO CRESCE MAIS. --------------------------------
   O campo de cada seção crescia da base, e a folga que ele deixava ficava no
   TOPO da seção — que é justamente a borda que entra na tela primeiro. O
   resultado era uma faixa morta entre uma tela e a seguinte, e nenhum ajuste
   de tempo resolvia: a folga aparecia por construção.

   Com cada seção prendendo na tela e formando o conteúdo dela ali, o gesto do
   campo perdeu a função que tinha e ficou só o defeito. Então ele sai. O fundo
   simplesmente está lá, e quem chega é o conteúdo. */
html.com-cena .campo{transform:none;transition:none}

/* O TIQUE CORAL antes de um rótulo é um `::before`, e um pseudo-elemento não
   existe no documento: nenhuma animação consegue tocá-lo diretamente. Ele
   também não herda a opacidade das letras, porque pertence ao parágrafo e não
   a elas — então ficava desenhado na tela antes de qualquer texto chegar.
   A variável resolve: o pseudo lê `--marca`, e quem anima `--marca` é o
   elemento de verdade. */
html.com-cena .code::before{opacity:var(--marca,1)}

/* --- 15.3 A LETRA. -------------------------------------------------------
   A palavra por fora existe para segurar a quebra de linha: sem ela o
   navegador ganha um ponto de quebra a cada letra e reflui o parágrafo no meio
   da animação. A letra por dentro é o que anima.

   E não há `will-change` aqui. Com a animação conduzida pela rolagem a divisão
   não pode ser desfeita — ela precisa continuar existindo para tocar de trás
   para frente — então os `span` ficam. Sem `will-change`, um `span` que ficou
   é só um `span`; com ele, seria uma camada de composição por letra, guardada
   pela placa de vídeo pelo resto da visita. */
.palavra{display:inline-block}
.letra{display:inline-block}

/* O KERNING SAI DOS TEXTOS DIVIDIDOS, E ESSA É UMA DECISÃO, NÃO UM DESCUIDO.
   Kerning é o ajuste entre DOIS glifos vizinhos, e só existe enquanto os dois
   estão na mesma sequência de modelagem. No instante em que cada letra vira
   uma caixa, cada letra vira a própria sequência, e o ajuste some — em
   qualquer navegador, com `inline` ou `inline-block`, medido e conferido.

   O número: a manchete da capa mede 992px e 1037px com kerning, e 1018px e
   1061px sem. Vinte e seis pixels. Sem desligar, o texto mediria 1018 dividido
   e voltaria para 992 ao ser reunido. O `letter-spacing`, que é a decisão
   tipográfica de verdade do projeto, continua exatamente onde estava. */
.rv--dividido{font-kerning:none;font-variant-ligatures:none}

/* --- 15.3a OS NÚMEROS QUE CONTAM. ----------------------------------------
   Enquanto a metragem sobe de zero até o valor, o texto troca de largura a
   cada quadro — "8" e "1" não medem o mesmo numa fonte proporcional, e o
   número inteiro dança de um lado para o outro dentro da célula. Com dígitos
   de largura fixa a contagem acontece parada, que é o único jeito de o olho
   ler o número em vez de ver o movimento. */
html.com-cena .size{font-variant-numeric:tabular-nums}

/* --- 15.3b A FITA DO DIA SAIU. -------------------------------------------
   Aqui moravam as duas regras que tiravam a rolagem nativa da janela da fita
   enquanto a viagem horizontal era dirigida pela rolagem. A seção 03 virou
   acordeão em 14/09/2026 (bloco 14.4) e não tem mais fita, nem janela, nem
   trilho. */

/* --- 15.4 HERO. ----------------------------------------------------------
   A sombra em que a capa mergulha é um elemento próprio, e não mais uma parada
   no gradiente do `::after`, por uma razão de custo: animar a opacidade de um
   span é composição, que a placa de vídeo resolve sozinha; animar as paradas
   de um gradiente é um repinte de tela inteira a cada quadro. */
.hero__sombra{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  opacity:0;
  background:linear-gradient(180deg,
    rgba(56,12,24,.30) 0%,
    rgba(56,12,24,.74) 46%,
    rgba(42,18,22,.97) 100%);
}

/* A capa fica presa enquanto a seção seguinte sobe por cima dela, e por isso
   precisa ficar POR BAIXO. As seções seguintes já são posicionadas e vêm
   depois no documento, então ganhariam de qualquer jeito; o `z-index` aqui é
   para que isso continue verdade se alguém mexer na ordem mais tarde. */
html.com-cena #capa{z-index:0}
html.com-cena main > section:not(#capa),
html.com-cena .foot{position:relative;z-index:1}

/* --- 15.5 O QUE SOBE PARA A GPU, E QUANDO. -------------------------------
   Só o que está se movendo AGORA. Promover uma caixa por seção pela página
   inteira custaria memória de vídeo o tempo todo para gestos que duram uma
   tela cada. */
html.com-cena #capa.cena-viva .hero__media{will-change:transform}
html.com-cena #capa.cena-viva .hero__inner{will-change:filter,transform}
html.com-cena #capa.cena-viva .hero__inner h1{will-change:filter,transform}
html.com-cena section.saindo-de-foco > .wrap,
html.com-cena section.saindo-de-foco > .plate__inner{will-change:transform,filter}
html.com-cena section.saindo-de-foco h1,
html.com-cena section.saindo-de-foco h2{will-change:filter}

@media (prefers-reduced-motion:reduce){
  .hero__sombra{display:none}
  html.com-cena main [data-rv],
  html.com-cena main [data-rv].is-in,
  html.com-cena main [data-rv].rv--type,
  html.com-cena main [data-rv].rv--type.is-in{opacity:1}
}
