/* ============================================================
   AP PASSARELA — style.css
   Apart-hotel de autoatendimento · Passarela do Álcool
   Porto Seguro — BA

   Identidade própria, aprovada em 14/08/2026. NÃO herda a paleta
   nem a tipografia da base Komplexa (navy/champagne, Fraunces +
   Hanken Grotesk) de propósito: dois clientes com a mesma cara é
   falha de entrega.

   Índice
    01 Reset            08 Vantagens da reserva direta
    02 Tokens           09 Painel de Acesso (assinatura)
    03 Tipografia       10 Fichas de apartamento
    04 Layout           11 Blocos de conteúdo
    05 Botões           12 Galeria e lightbox
    06 Cabeçalho        13 Localização
    07 Hero + triagem   14 Contato e formulários
                        15 CONFIRMAR e foto pendente
                        16 Rodapé
                        17 Painel de WhatsApp  ← exceção documentada
                        18 Modal de reserva e calendário
                        19 Banner de cookies
                        20 Responsivo
   ============================================================ */


/* ═══ 01 · RESET ══════════════════════════════════════════ */

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

html {
  /* auto, e não smooth: o scroll suave é do Lenis. As duas coisas
     ligadas ao mesmo tempo brigam e o scroll fica com solavanco. */
  scroll-behavior:auto;
  -webkit-text-size-adjust:100%;
}

body {
  background:var(--base);
  color:var(--tinta);
  font-family:var(--fonte-corpo);
  font-size:1rem;
  line-height:1.65;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}

img, svg, video, iframe { display:block; max-width:100%; }
img, video { object-fit:cover; }
a { color:inherit; text-decoration:none; }
button { cursor:pointer; font:inherit; color:inherit; }
ul, ol { list-style:none; }

:focus-visible { outline:2px solid var(--travessia); outline-offset:3px; border-radius:2px; }


/* ═══ 02 · TOKENS ═════════════════════════════════════════ */

:root {
  /* ── Paleta ──
     Puxada do lugar: o azul da travessia de balsa para Arraial, o
     amarelo da sinalização e da luz noturna da Passarela, o cinza
     claro do concreto do calçadão. */
  --base:        #F1F4F6;   /* fundo da página */
  --superficie:  #FFFFFF;   /* cartão, ficha, painel */
  --tinta:       #0C1F2B;   /* texto e barra de navegação */
  --travessia:   #0F6A87;   /* sinalética: numeração, ícone, link */
  --luz:         #FFC24B;   /* ação. Escassa, só no acesso e nos CTAs */
  --linha:       #D6DFE3;   /* fios e bordas */

  /* Derivados. Ficam aqui para não haver rgba() solto no arquivo
     com número mágico que ninguém sabe de onde veio. */
  --tinta-rgb:      12, 31, 43;
  --travessia-rgb:  15, 106, 135;
  --luz-rgb:        255, 194, 75;
  --tinta-70:    rgba(12,31,43,.70);   /* texto de apoio sobre claro */
  --tinta-55:    rgba(12,31,43,.55);   /* legenda, rótulo */
  --sobre-tinta: rgba(255,255,255,.72);/* texto de apoio sobre --tinta */
  --travessia-fraca: rgba(15,106,135,.08);
  --luz-fraca:       rgba(255,194,75,.16);

  /* Estados de erro. Não são da paleta da marca de propósito:
     vermelho de formulário precisa ler como vermelho de formulário. */
  --erro:     #C62828;
  --erro-bg:  #FDECEC;
  --erro-txt: #9B1C1C;

  /* ── Tipografia ──
     Archivo tem eixo de largura (wdth). O display usa a versão
     estreita/normal conforme o tamanho; o corpo é Instrument Sans. */
  --fonte-display: 'Archivo', system-ui, -apple-system, sans-serif;
  --fonte-corpo:   'Instrument Sans', system-ui, -apple-system, sans-serif;

  /* ── Ritmo ── */
  --gap-xs:  clamp(.5rem, 1vw, .75rem);
  --gap-sm:  clamp(1rem, 2vw, 1.5rem);
  --gap-md:  clamp(1.75rem, 3.5vw, 2.75rem);
  --gap-lg:  clamp(3rem, 6vw, 5rem);
  --gap-xl:  clamp(4.5rem, 9vw, 7.5rem);

  --largura:   1220px;
  --largura-estreita: 780px;
  --raio:      4px;   /* cantos quase retos: é sinalética, não app */
  --raio-md:   8px;

  --sombra:    0 2px 10px rgba(12,31,43,.05), 0 10px 34px rgba(12,31,43,.06);
  --sombra-lg: 0 8px 24px rgba(12,31,43,.08), 0 24px 70px rgba(12,31,43,.12);

  --ease: cubic-bezier(.22,.61,.36,1);

  /* Publicados por main.js. Sem JS valem 0 e o layout não quebra. */
  --kx-fixed-offset: 0px;
  --kx-kb-inset:     0px;
}


/* ═══ 03 · TIPOGRAFIA ═════════════════════════════════════ */

h1, h2, h3, .display {
  font-family:var(--fonte-display);
  font-weight:700;
  line-height:1.08;
  letter-spacing:-.022em;
  color:var(--tinta);
  text-wrap:balance;
}

h1 { font-size:clamp(2.35rem, 5.4vw, 4.15rem); font-variation-settings:'wdth' 92; }
h2 { font-size:clamp(1.75rem, 3.6vw, 2.8rem);  font-variation-settings:'wdth' 95; }
h3 { font-size:clamp(1.1rem, 1.9vw, 1.4rem); font-weight:600; letter-spacing:-.012em; line-height:1.22; }

h4 {
  font-family:var(--fonte-corpo);
  font-size:.7rem; font-weight:700;
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--tinta);
}

p { max-width:64ch; color:var(--tinta-70); }
p strong { color:var(--tinta); font-weight:600; }

/* Rótulo de sinalética. É o elemento que amarra o sistema: aparece
   antes de todo título de seção, sempre em --travessia. */
.rotulo {
  display:block;
  font-family:var(--fonte-corpo);
  font-size:.68rem; font-weight:700;
  letter-spacing:.2em; text-transform:uppercase;
  color:var(--travessia);
  margin-bottom:.85rem;
}
.rotulo--claro { color:var(--luz); }

.lead { font-size:clamp(1rem, 1.35vw, 1.14rem); color:var(--tinta-70); line-height:1.6; }

/* Fio curto sob o título. Substitui o divisor champagne da base. */
.fio { width:44px; height:3px; background:var(--luz); margin:1.1rem 0 0; }
.fio--centro { margin-left:auto; margin-right:auto; }


/* ═══ 04 · LAYOUT ═════════════════════════════════════════ */

.faixa { padding:var(--gap-xl) 0; }
.faixa--curta { padding:var(--gap-lg) 0; }
.faixa--branca { background:var(--superficie); }
.faixa--escura { background:var(--tinta); }
.faixa--escura h1, .faixa--escura h2, .faixa--escura h3 { color:#fff; }
.faixa--escura p { color:var(--sobre-tinta); }

.container { width:100%; max-width:var(--largura); margin:0 auto; padding:0 clamp(1.25rem, 4vw, 2.75rem); }
.container--estreito { max-width:var(--largura-estreita); }

.cabeca { margin-bottom:var(--gap-md); }
.cabeca--centro { text-align:center; }
.cabeca--centro p { margin-left:auto; margin-right:auto; }
.cabeca p { margin-top:1rem; }

.grade-2 { display:grid; grid-template-columns:1fr 1fr; gap:var(--gap-lg); align-items:center; }
.grade-3 { display:grid; grid-template-columns:repeat(3, 1fr); gap:var(--gap-sm); }
.grade-4 { display:grid; grid-template-columns:repeat(4, 1fr); gap:var(--gap-sm); }

.sr { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }


/* ═══ 05 · BOTÕES ═════════════════════════════════════════ */

.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:.5rem;
  min-height:48px; padding:.8rem 1.9rem;
  font-family:var(--fonte-corpo); font-size:.74rem; font-weight:700;
  letter-spacing:.15em; text-transform:uppercase;
  border:1.5px solid transparent; border-radius:var(--raio);
  transition:background .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease);
}

/* Ação principal. --luz é escassa de propósito: só aqui e no
   Painel de Acesso. Texto em --tinta porque branco sobre o amarelo
   dá ~1.7:1 e reprova em qualquer nível. */
.btn--luz { background:var(--luz); color:var(--tinta); }
.btn--luz:hover { background:#F2AF2E; }

.btn--tinta { background:var(--tinta); color:#fff; }
.btn--tinta:hover { background:#16354A; }

.btn--contorno { background:transparent; color:var(--tinta); border-color:var(--tinta); }
.btn--contorno:hover { background:var(--tinta); color:#fff; }

.btn--contorno-claro { background:transparent; color:#fff; border-color:rgba(255,255,255,.55); }
.btn--contorno-claro:hover { background:#fff; color:var(--tinta); }

.btn--bloco { width:100%; }

/* Link com seta. Usado no fim de cada bloco de preview. */
.link-seta {
  display:inline-flex; align-items:center; gap:.45rem;
  font-size:.78rem; font-weight:700; letter-spacing:.1em; text-transform:uppercase;
  color:var(--travessia);
  border-bottom:2px solid var(--travessia); padding-bottom:2px;
  transition:gap .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease);
}
.link-seta:hover { gap:.8rem; }
.link-seta--claro { color:var(--luz); border-color:var(--luz); }


/* ═══ 06 · CABEÇALHO ══════════════════════════════════════ */

/* Sem barra. Só a marca e os três risquinhos, flutuando sobre o que
   estiver embaixo. A tarja sólida existia de quando o hero era
   tipográfico; agora que ele tem foto, ela cortava a imagem em duas
   e aparecia como um bloco azul assim que a página descia. */
.topo {
  position:fixed; inset:0 0 auto 0; z-index:1000;
  background:transparent;
  border-bottom:none;
  transition:padding .3s var(--ease);
}
.topo-i {
  max-width:1400px; margin:0 auto;
  padding:.85rem clamp(1.25rem, 4vw, 2.75rem);
  display:grid; grid-template-columns:1fr auto 1fr; align-items:center; gap:1rem;
  transition:padding .3s var(--ease);
}
.topo-i .sanduiche { grid-column:1; justify-self:start; }
.topo-i .marca     { grid-column:2; justify-self:center; }
/* .rolado agora só encolhe o respiro. A sombra saiu junto com a
   tarja: sem fundo atrás dela, sombra vira borrão sobre o conteúdo. */
.topo.rolado .topo-i { padding-top:.6rem; padding-bottom:.6rem; }

/* ── A marca troca de cor conforme a seção que passa por baixo ──
   Sem a tarja, a marca branca e os três risquinhos brancos sumiam
   sobre as seções claras: medido, 1,10:1 sobre o --base e 1,00:1
   sobre o branco dos cards. Invisível, não "pouco contraste".

   Como o menu é a única porta de navegação do site, isso deixava o
   visitante sem saída assim que ele rolava para a primeira seção
   clara. O main.js liga .topo--claro quando a faixa do cabeçalho
   está sobre fundo claro, e aqui a marca vira navy.

   O logo é PNG e não aceita recolorir por CSS, então existe um
   segundo arquivo, -escuro.png, gerado do mesmo alfa. Quem troca o
   src é o JS. */
/* `.topo--claro` faz duas coisas: diz ao main.js qual dos dois PNG da
   marca carregar, e inverte o botão do menu, cujas regras estão na
   seção dele, mais abaixo. */

/* Logomarca vetorizada, entregue pelo cliente em 14/08/2026.
   O site usa o PNG em 3x, não o SVG: o mosaico tem 2613 pedras e o
   vetor pesa 365 KB em toda página, contra 30 KB do PNG, sem ganho
   visível em 46 ou 64px. As pedras são transparentes de verdade, então
   a marca funciona sobre qualquer fundo escuro.
   Em assets/img/logo/ ficam os vetores: logo-ap-passarela.svg é o
   arquivo do cliente, intacto, e -claro.svg é a mesma arte em branco,
   de onde o PNG é gerado. */
.marca { display:flex; align-items:center; color:#fff; }
.marca img { height:46px; width:auto; display:block; }
.rodape .marca img { height:64px; }

/* Na barra sobraram duas coisas: o botão do menu, à esquerda, e a marca,
   centralizada. A terceira coluna existe vazia de propósito — sem ela a
   marca centralizaria no espaço que sobra à direita do botão, e não no
   meio da tela. */

/* Sempre visível, em qualquer largura: é a única porta de navegação
   do site agora, e não pode depender do tamanho da tela. */
/* 17/08/2026: eram três traços de 2px soltos, sem fundo e sem rótulo.
   Sumia, e agora que todo cabeçalho tem foto atrás sumia ainda mais.
   Virou pílula com contorno, fundo próprio e a palavra Menu ao lado:
   sendo a única porta de navegação do site, precisa ser lido como botão
   à primeira vista, não adivinhado.

   O amarelo --luz aparece só no hover e no foco. Deixá-lo fixo aqui
   diluiria a cor de ação, que no site inteiro significa reservar. */
.sanduiche {
  display:inline-flex; flex-direction:row; align-items:center; gap:.6rem;
  width:auto; min-height:44px; padding:.5rem 1.05rem .5rem .9rem;
  /* O botão INVERTE conforme o fundo por baixo da barra, igual à marca.
     A primeira tentativa foi um botão único, navy com anel branco, para
     não depender do JS: sobre o navy do site o corpo se fundia e sobrava
     só o anel, e na prática ele sumia.

     Estado padrão, que é o fundo escuro: corpo BRANCO com traços e texto
     navy. Contra o navy do site dá 16,9:1, não tem como sumir. Quando o
     main.js detecta seção clara e liga .topo--claro, ele inverte para
     navy com texto branco, 14,2:1.

     A borda navy no estado padrão é o seguro: se o JS não rodar, o botão
     branco continua delimitado sobre fundo claro em vez de virar um
     borrão sem contorno. */
  background-color:#fff;
  border:1.5px solid rgba(11,26,42,.75); border-radius:999px;
  box-shadow:0 2px 12px rgba(11,26,42,.28);
  /* Colado na borda ESQUERDA DA TELA, não na coluna do conteúdo.
     Enquanto ele vivia dentro do .topo-i, que tem max-width de 1400px
     centralizado, num monitor de 1920 o botão nascia a 261px da borda,
     medido: alinhado com o texto, mas visualmente no meio do nada.
     Fora do grid ele fica a 16px da borda em qualquer largura.

     Sair do grid não mexe na marca: a coluna 1 fica vazia e o
     `1fr auto 1fr` continua centralizando a logo na tela. */
  position:absolute; left:clamp(.75rem, 1.4vw, 1rem); top:50%;
  transform:translateY(-50%);
  cursor:pointer;
  transition:background-color .25s var(--ease), border-color .25s var(--ease), box-shadow .25s var(--ease);
}
.sanduiche-icone { display:flex; flex-direction:column; justify-content:center; gap:4px; width:20px; height:13px; }
.sanduiche span { display:block; width:100%; height:2.5px; border-radius:2px; background-color:var(--tinta); transition:transform .3s var(--ease), opacity .2s, background-color .25s var(--ease); }
.sanduiche-txt {
  font-family:var(--fonte-corpo); font-size:.72rem; font-weight:700;
  letter-spacing:.16em; text-transform:uppercase; color:var(--tinta); line-height:1;
  transition:color .25s var(--ease);
}

/* Sobre seção clara ele vira o negativo de si mesmo. */
.topo--claro .sanduiche { background-color:var(--tinta); border-color:rgba(255,255,255,.75); }
.topo--claro .sanduiche span { background-color:#fff; }
.topo--claro .sanduiche-txt { color:#fff; }
.sanduiche:hover, .sanduiche:focus-visible { background-color:var(--luz); border-color:var(--luz); box-shadow:0 2px 14px rgba(11,26,42,.45); outline:none; }
.sanduiche:hover span, .sanduiche:focus-visible span { background-color:var(--tinta); }
.sanduiche:hover .sanduiche-txt, .sanduiche:focus-visible .sanduiche-txt { color:var(--tinta); }

/* Aberto vira X. O rótulo sai, senão sobra a palavra Menu ao lado de um
   X de fechar. O deslocamento é 6px porque o vão entre traços é 4 e o
   traço tem 2,5 de altura. */
.sanduiche.aberto .sanduiche-txt { display:none; }
.sanduiche.aberto span:nth-child(1) { transform:translateY(6px) rotate(45deg); }
.sanduiche.aberto span:nth-child(2) { opacity:0; }
.sanduiche.aberto span:nth-child(3) { transform:translateY(-6px) rotate(-45deg); }


/* Menu em tela cheia. Navy chapado, sem transparência e sem blur: o
   painel flutuante anterior abria por cima do vídeo sem cobrir a tela,
   e a cena atrás competia com os seis links.

   Grid de três linhas: topo, corpo e rodapé. O corpo é que se divide
   em duas colunas no desktop. Sem barra de rolagem interna, os seis
   itens têm que caber na viewport. */
/* Lugar na pilha: acima da faixa de cookies (9000) e do botão de
   WhatsApp (8000), que precisam sumir atrás do menu, e abaixo do modal
   de reserva (9500), que é aberto POR um botão daqui de dentro e tem
   que vir por cima. */
.menu-ov {
  position:fixed; inset:0; z-index:9200;
  background:#0B1A2A;
  display:grid; grid-template-rows:auto 1fr auto;
  padding:clamp(1rem, 2.5vh, 1.6rem) clamp(1.25rem, 4vw, 2.75rem) clamp(1.25rem, 3vh, 2rem);
  opacity:0;
  transition:opacity .25s var(--ease);
}
.menu-ov[hidden] { display:none; }
.menu-ov.aberto { opacity:1; }

/* Topo: marca no centro, X na direita, na mesma altura. O X ficava
   solto no canto superior esquerdo, longe do painel que ele fecha. */
.menu-ov-topo {
  display:grid; grid-template-columns:1fr auto 1fr; align-items:center;
}
.menu-ov-topo .marca { grid-column:2; justify-self:center; }
.menu-ov-topo .marca img { height:46px; }
.menu-x {
  grid-column:3; justify-self:end;
  position:relative; width:44px; height:44px;
  background:none; border:none; cursor:pointer;
}
.menu-x span {
  position:absolute; left:10px; top:21px;
  display:block; width:24px; height:2px; background:#fff;
  transition:background .2s var(--ease);
}
.menu-x span:nth-child(1) { transform:rotate(45deg); }
.menu-x span:nth-child(2) { transform:rotate(-45deg); }
.menu-x:hover span { background:var(--luz); }

.menu-ov-corpo {
  display:grid; grid-template-columns:45% 55%;
  gap:clamp(1.5rem, 4vw, 3.5rem);
  align-items:center;
  min-height:0;
}

/* Coluna da imagem. Duas camadas empilhadas fazem o crossfade: a que
   está saindo continua no lugar enquanto a que entra ganha opacidade,
   então nunca aparece buraco entre uma foto e outra. */
.menu-ov-foto {
  position:relative; aspect-ratio:4/3;
  border-radius:12px; overflow:hidden;
  background:rgba(255,255,255,.04);
}
.menu-ov-foto img {
  position:absolute; inset:0;
  width:100%; height:100%; object-fit:cover;
  opacity:0; transition:opacity .4s ease;
}
.menu-ov-foto img.ativa { opacity:1; }

.menu-ov-col {
  display:flex; flex-direction:column; justify-content:center;
  gap:clamp(1.25rem, 3vh, 2rem);
  min-height:0;
}
.menu-ov-nav { display:flex; flex-direction:column; align-items:flex-start; gap:clamp(.35rem, 1.4vh, .9rem); }
.menu-ov-nav a {
  font-family:var(--fonte-display); font-weight:400;
  /* 17/08/2026: era clamp(2rem, 4vw, 3.25rem). Com seis itens e a foto
     ao lado, o menu ocupava a tela inteira e o CTA de reserva ficava
     espremido no pé. Reduzido cerca de 28%, continua sendo o maior
     texto da tela e sobra respiro entre os itens. */
  font-size:clamp(1.5rem, 2.8vw, 2.35rem);
  font-variation-settings:'wdth' 92;
  letter-spacing:-.02em; line-height:1.1; color:#fff;
  padding:8px 24px; margin-left:-24px;
  border:1px solid transparent; border-radius:4px;
  transition:border-color .25s var(--ease);
}
/* Só o contorno muda. Sem troca de fundo e sem troca de cor: com seis
   itens grandes, qualquer preenchimento no hover vira lampejo. */
.menu-ov-nav a:hover,
.menu-ov-nav a:focus-visible,
.menu-ov-nav a[aria-current="page"] { border-color:rgba(255,255,255,.35); outline:none; }

.menu-ov-cta { align-self:flex-start; font-size:.76rem; }

.menu-ov-pe {
  display:flex; align-items:flex-end; justify-content:space-between;
  gap:1.5rem; flex-wrap:wrap;
  padding-top:clamp(1rem, 2.5vh, 1.5rem);
}
.menu-ov-links { display:flex; gap:1.5rem; flex-wrap:wrap; }
.menu-ov-links a {
  font-size:.8rem; color:rgba(255,255,255,.7);
  border-bottom:1px solid rgba(255,255,255,.25); padding-bottom:2px;
  transition:color .2s var(--ease), border-color .2s var(--ease);
}
.menu-ov-links a:hover { color:#fff; border-color:var(--luz); }
.menu-ov-redes { display:flex; gap:1rem; }
.menu-ov-redes a { color:rgba(255,255,255,.7); transition:color .2s var(--ease); }
.menu-ov-redes a:hover { color:var(--luz); }
.menu-ov-redes i { font-size:1.5rem; }

/* Entrada escalonada dos itens. O estado inicial é aplicado pelo JS
   junto com a classe .anima, então sem script os seis já estão no
   lugar. */
@keyframes menuItemEntra {
  from { opacity:0; transform:translateY(12px); }
  to   { opacity:1; transform:none; }
}
.menu-ov.anima .menu-ov-nav a,
.menu-ov.anima .menu-ov-cta {
  animation:menuItemEntra .3s var(--ease) both;
  animation-delay:calc(var(--i, 0) * 40ms);
}

@media (max-width: 900px) {
  /* A coluna de imagem sai: sem hover ela nunca troca, e come a altura
     que os seis itens precisam para caber sem rolagem. */
  .menu-ov-foto { display:none; }
  .menu-ov-corpo { grid-template-columns:1fr; }
  .menu-ov-nav { align-items:center; }
  .menu-ov-nav a { margin-left:0; }
  .menu-ov-col { align-items:center; text-align:center; }
  .menu-ov-cta { align-self:stretch; }
  .menu-ov-pe { justify-content:center; gap:1rem; }
  .menu-ov-links { justify-content:center; }
}

/* Compensação da barra fixa nas páginas internas. */
.espaco-topo { height:70px; }


/* ═══ 06B · ABERTURA EM VÍDEO ═════════════════════════════ */

/* Só na home. O vídeo institucional ocupa a primeira tela inteira e
   nada mais entra nela: sem título, sem lead, sem painel. A triagem
   de capacidade continua inteira, na tela seguinte.

   O autoplay é mudo por obrigação do navegador, não por escolha de
   design. O botão de som está sempre visível e diz em que estado o
   vídeo está — som ligado sem aviso é o que faz o visitante fechar
   a aba com pressa. */
/* Vídeo de borda a borda, ocupando a seção inteira. Existiu aqui uma
   folga de 56px de navy embaixo do vídeo, para tirar a legenda queimada
   de dentro do degradê. Ela saiu: deixava uma faixa navy no pé da tela
   e o vídeo não cobria a viewport toda. Quem tira a legenda do degradê
   agora são os stops dele, não um pedaço vazio de tela.

   A faixa de prova nunca esteve sobreposta ao vídeo, sempre foi seção
   em fluxo normal: quem comia a legenda era o degradê. */
.abertura {
  position:relative; overflow:hidden;
  height:100svh; min-height:480px; max-height:1080px;
  background:#0B1A2A;
}
/* object-position bottom: com o corte centralizado, os 125px de baixo
   do quadro eram descartados em telas largas e levavam a legenda junto.
   Ancorando embaixo, o corte sai todo do topo, que é céu e telhado, e a
   base do quadro nunca se perde, em qualquer proporção de tela. */
.abertura-video {
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover; object-position:center bottom;
  /* O vídeo é decoração de fundo: nenhum clique nele, para não
     pausar sem querer ao tocar na tela do celular. */
  pointer-events:none;
}
/* Foto que substitui o vídeo no celular. No desktop ela não existe:
   display:none e o navegador nem busca o arquivo. */
/* Foto de entrada do celular, dentro do hero. No desktop não existe:
   display:none e o navegador nem busca o arquivo. */
.hero-foto { display:none; }

/* Véu. Em cima, garante o contraste do cabeçalho transparente sobre
   qualquer cena clara do vídeo. Embaixo ele quase não existe mais.

   A ponta de baixo fechava em .78 e era ela, não o degradê de emenda,
   que apagava a legenda queimada: medido, jogava de 51% a 60% de
   escurecimento exatamente na faixa onde a legenda fica. O trabalho de
   costurar a passagem para a faixa de prova já é do .abertura::after,
   então esta camada não precisa repetir. Agora ela segura .06 até 90%
   da altura e só fecha em .32 no último décimo, onde não há texto. */
.abertura-veu {
  position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(
    180deg,
    rgba(12,31,43,.62) 0%,
    rgba(12,31,43,.12) 22%,
    rgba(12,31,43,.04) 55%,
    rgba(12,31,43,.06) 90%,
    rgba(12,31,43,.32) 100%
  );
}
/* Emenda de baixo, 160px, fechando no #0B1A2A exato da faixa de prova.

   Os stops são o que protege a legenda queimada. Sem a folga de 56px,
   a legenda passou a cair a cerca de 80px da base do vídeo, com a
   caixa de texto indo até uns 98px. Por isso a parte transparente do
   degradê vai até 60%, ou seja, os 96px de cima dele não lavam nada.
   A legenda fica inteira acima da rampa e o fade acontece nos últimos
   64px, onde só existe calçada. */
.abertura::after {
  content:''; position:absolute; bottom:0; left:0; right:0;
  height:110px; pointer-events:none;
  background:linear-gradient(180deg,
    transparent 0%,
    transparent 55%,
    rgba(11,26,42,.65) 82%,
    #0B1A2A 100%);
}


/* ═══ 06C · STRIP DE PROVA ════════════════════════════════ */

/* Faixa de navy chapado entre o vídeo e o hero. Faz dois trabalhos:
   entrega os quatro fatos que decidem a reserva e serve de zona de
   respiro entre duas mídias que antes se encostavam.
   Sem borda em cima nem embaixo de propósito: a emenda tem que
   desaparecer, não ganhar um traço marcando onde ela está. */
/* Faixa baixa de propósito. Ela é apoio, não seção: são quatro fatos
   de uma linha só, e 80px de padding para 24px de conteúdo empurravam
   o hero inteiro para fora da primeira rolagem.
   O respiro entre o vídeo e ela já é feito pelo degradê da abertura,
   então a faixa não precisa carregar essa folga também. */
/* O que encolheu foi a CAIXA, não a tipografia. O texto está no mesmo
   tamanho de sempre; o que sumiu foram os 80px de padding que faziam
   uma faixa de 104px para 22px de conteúdo.
   A folga entre o vídeo e a faixa é feita pelo degradê da abertura, e
   a folga para o hero é feita pelo padding do próprio hero. A faixa
   não precisa repetir nenhuma das duas.

   20px simétricos, sem height nem min-height: a altura passa a ser só
   conteúdo mais padding, e o mesmo valor vale no celular. */
.prova {
  background:#0B1A2A;
  padding:20px 0;
}
/* O container global entra aqui só pela largura e pelo padding lateral.
   Zerar o vertical evita que qualquer margem herdada some altura ao
   bloco por cima dos 20px. */
.prova .container { display:flex; align-items:center; justify-content:center; padding-top:0; padding-bottom:0; }
/* flex centralizado, não grade de quatro colunas iguais. Em 1400px de
   container, quatro colunas de 1fr jogavam "22 apartamentos" para a
   ponta esquerda e "entrada por autoatendimento" para a direita, com
   um vão morto no meio. Aqui cada item ocupa só a largura do próprio
   texto e o conjunto fica junto, no centro. */
.prova-l {
  display:flex; flex-wrap:wrap;
  justify-content:center; align-items:center;
  margin:0; width:100%;
  font-size:.72rem; font-weight:600;
  letter-spacing:.06em; text-transform:uppercase;
  color:rgba(255,255,255,.75);
  /* line-height 1: o texto é todo em caixa alta e não tem nenhuma
     letra com perna descendo. Com 1.25, a caixa de linha reservava
     essa descida que ninguém usa e o resultado era o texto colado no
     topo da faixa, com um vão vazio embaixo. */
  line-height:1;
}
/* Cada item é um flex próprio, para o número de 16,8px e o texto de
   11,5px centralizarem juntos no meio da faixa em vez de dividirem a
   mesma linha de base. */
.prova-l li {
  position:relative;
  display:flex; align-items:center; justify-content:center; gap:.32em;
  padding:0 clamp(.9rem, 1.8vw, 1.5rem); text-align:center;
}
/* Divisor em pseudo-elemento, não em border-left. Como border ele
   assumia a altura do item, e os itens têm alturas diferentes: os que
   têm número medem 16,8px e "entrada por autoatendimento" mede 11,5px.
   Ficavam quatro traços de tamanhos distintos. Absoluto, ele tem 16px
   fixos e fica centrado na linha, independente do conteúdo do item. */
.prova-l li + li { border-left:none; }
.prova-l li + li::before {
  content:''; position:absolute; left:0; top:50%;
  transform:translateY(-50%);
  width:1px; height:16px;
  background:rgba(255,255,255,.14);
}
/* Só o número recebe cor e peso. O resto da linha é apoio.
   nowrap e flex-shrink:0 porque, como item flex, o "400 M" encolhia e
   quebrava em duas linhas na coluna estreita do celular. */
.prova-l b {
  color:var(--luz); font-weight:700;
  font-size:1.05rem; letter-spacing:.02em;
  white-space:nowrap; flex-shrink:0;
}

/* Canto inferior ESQUERDO de propósito: o painel de WhatsApp mora no
   direito, e dois botões flutuantes no mesmo canto brigam no celular. */
.som-btn {
  position:absolute; z-index:3;
  left:24px;
  /* 24px acima da base do VÍDEO, não da seção: o bottom de um
     absoluto conta a partir da caixa de padding, então a folga da
     legenda entra na conta ou o botão cairia dentro da faixa de navy.
     Continua subindo junto com os outros flutuantes enquanto a faixa
     de cookies está no ar, senão nasce escondido atrás dela logo na
     primeira visita, que é quando a abertura importa.
     Canto ESQUERDO: o painel de WhatsApp mora no direito, e a legenda
     do vídeo é centralizada, então os três nunca se cruzam. */
  bottom:calc(24px + var(--kx-fixed-offset, 0px));
  display:inline-flex; align-items:center; gap:.6rem;
  padding:.72rem 1.2rem;
  border:1px solid rgba(255,255,255,.34); border-radius:999px;
  background:rgba(12,31,43,.5);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
  color:#fff; font-family:var(--fonte-corpo);
  font-size:.7rem; font-weight:600; letter-spacing:.11em; text-transform:uppercase;
  cursor:pointer; min-height:44px;
  transition:background .25s var(--ease), border-color .25s var(--ease);
}
.som-btn:hover { background:rgba(12,31,43,.78); border-color:var(--luz); }
.som-btn i { font-size:1.15rem; color:var(--luz); line-height:1; }
.som-btn[aria-pressed="true"] { border-color:var(--luz); }

/* Nada mais fica por cima do vídeo além do botão de som. A seta de
   rolagem saía bem em cima das legendas queimadas do vídeo, e a marca
   central saiu porque a marca da barra já ocupa o meio da tela. */

/* A regra que deixava a barra sem fundo só durante a abertura saiu:
   agora ela é transparente o tempo todo, em todas as páginas, e a
   exceção virou redundância.

   Esconder a barra por completo foi tentado antes e descartado: deixava
   o visitante sem nenhuma porta de navegação na primeira tela. */

/* O painel de WhatsApp não aparece sobre o vídeo. Ele é o elemento mais
   pesado da tela e roubava a abertura inteira; entra quando a página
   desce, junto com o resto da interface. A classe sai do body pelo
   main.js assim que a abertura deixa a tela.
   visibility, e não display: o botão precisa continuar ocupando lugar
   no cálculo do --kx-fixed-offset da faixa de cookies. */
body.na-abertura .wa-btn,
body.na-abertura .wa-balao {
  opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity .4s var(--ease), visibility .4s var(--ease);
}
/* Sem a barra fixa para compensar: quem está acima do hero agora é o
   vídeo, não o topo da página. */
body.tem-abertura .hero { padding-top:var(--gap-lg); }

@media (max-width: 768px) {
  /* Altura reservada para a faixa da logo. Fixa de propósito: o resto
     do cabeçalho entra depois, na rolagem, e sem altura reservada a
     página daria um salto quando ele chegasse. */
  :root {
    --faixa-logo:64px;
  }

  /* ── Composição da primeira tela ──
     UMA tela: a foto do prédio ocupando a viewport inteira, com o
     título e o parágrafo por cima. Depois dela vem o painel de
     reservas, depois a faixa de números.

     A ABERTURA SAI DA TELA INTEIRA no celular. Ela existia para o
     vídeo institucional, que já não roda aqui, e sem ele virava uma
     segunda foto do mesmo prédio empilhada em cima do hero. Duas fotos
     da mesma fachada em duas telas seguidas não acrescentam nada, e a
     que sobra é a do hero, porque é ela que carrega o argumento.

     O vídeo continua inteiro no desktop, onde a tela é deitada como
     ele e o download não sai do 4G de ninguém.

     A faixa de números desceu para depois do painel de reservas. Ela
     ficava entre a abertura e o hero, que era o meio da primeira
     rolagem; sem a abertura esse meio não existe mais, e antes do
     título ela só empurraria a foto para fora da tela. */
  main { display:flex; flex-direction:column; }
  .abertura { display:none; }
  .hero     { order:0; }
  .prova    { order:1; }
  main > *:not(.abertura):not(.hero):not(.prova) { order:2; }

  /* ── A faixa da logo ──
     A barra fica desde o carregamento, transparente como no desktop, e
     quem entra e sai na rolagem é só o hambúrguer.

     Fixa no topo, sem mais nada. Ela já morou encostada no pé da foto,
     de quando a abertura era uma faixa própria acima do hero; com a
     abertura fora da tela no celular a foto passou a ser o hero
     inteiro, e uma marca ancorada no rodapé de uma tela cheia fica
     longe demais do alto para funcionar como cabeçalho. */
  body.tem-abertura .topo {
    transform:none; opacity:1; pointer-events:auto;
    background:transparent;
    /* NO ALTO DA PRIMEIRA TELA (18/08/2026, a pedido). Ela morou no pé
       enquanto o título ocupava o topo da foto: em cima, os dois
       disputavam o mesmo espaço. Com o texto no rodapé da tela esse
       conflito não existe mais, e a marca volta a funcionar como
       cabeçalho, que é o lugar onde o olho procura por ela.
       absolute e não fixed: aqui ela precisa rolar junto com a foto. */
    position:absolute;
    top:0;
  }
  /* Fixa no topo a partir do y em que a barra absoluta ENCOSTA lá em
     cima. Nesse ponto a posição na tela é a mesma nos dois modos, e a
     troca não tem pulo. Quem calcula o y é o main.js, medindo a foto,
     para não virar número copiado que envelhece.
     .topo--visivel não entra nesta conta: ela cuida do hambúrguer. */
  body.tem-abertura .topo--fixo {
    position:fixed;
    top:0;
  }
  body.tem-abertura .topo-i {
    min-height:var(--faixa-logo);
    padding-top:0; padding-bottom:0;
  }
  body.tem-abertura .sanduiche {
    opacity:0; pointer-events:none;
    transition:opacity .25s var(--ease);
  }
  body.tem-abertura .topo--visivel .sanduiche {
    opacity:1; pointer-events:auto;
  }

  /* A abertura inteira está em display:none aqui, então tudo que era
     regra de dentro dela saiu: foto, véu, emenda e botão de som. O que
     vale para o celular agora está na media query do hero, mais
     abaixo. O desktop continua com o bloco original, lá em cima. */
}

/* Movimento reduzido não precisa de regra própria: o main.js tira o
   autoplay e pausa o vídeo, e <video> pausado mostra o próprio poster.
   O poster herda o mesmo object-fit contain e o mesmo fundo navy do
   vídeo, então o resultado é idêntico, só parado. */


/* ═══ 07 · HERO E TRIAGEM DE CAPACIDADE ═══════════════════ */

/* O hero NÃO é vitrine: é triagem. A primeira decisão de quem
   viaja em grupo para Porto Seguro é quantas pessoas cabem, e o
   painel responde isso antes de qualquer outra coisa. A mídia de
   fundo dá contexto de lugar, mas quem manda na tela é o painel.
   Nenhuma foto de mar acima da dobra, em nenhuma página — regra do
   projeto. A mídia aqui é a fachada e o calçadão, não praia.

   O --tinta continua como fundo do .hero: é o que aparece enquanto
   o poster carrega e se a mídia falhar. Nunca fica branco. */
.hero {
  position:relative; overflow:hidden;
  background:var(--tinta);
  padding:calc(70px + var(--gap-lg)) 0 var(--gap-lg);
  min-height:min(94vh, 820px);
  display:flex; align-items:center;
}
/* Fundo em três camadas: mídia (0), scrim (1), conteúdo (2). */
/* object-position 50%: com a fachada no lugar do quarto, o assunto da
   foto passou a ser o próprio prédio, e ele está centrado no quadro.
   Os 70% de antes serviam ao quarto, cujo ponto de interesse ficava à
   direita; nesta foto eles jogavam o corte do celular para a casa
   amarela do vizinho e deixavam a placa AV PORTUGAL 526 na borda.
   No desktop a foto cabe inteira na largura e o corte é só vertical,
   então isto muda o enquadramento apenas no celular.
   Efeito colateral medido e bem-vindo: centrado, o que fica atrás da
   barra de capacidade é a parede navy da fachada, e o contraste ali
   sobe de 4.5 para 6.5. */
.hero-midia {
  position:absolute; inset:0; z-index:0;
  width:100%; height:100%;
  object-fit:cover; object-position:50% center;
  pointer-events:none;
}
/* ── A ÚNICA camada que escurece a foto ──
   Auditado no computed style de .hero e de todos os descendentes, nos
   três estados (elemento, ::before, ::after): não existe filter,
   backdrop-filter, mix-blend-mode, background-blend-mode, box-shadow
   inset nem opacity em nenhum deles. Os únicos outros fundos são de
   componente, o amarelo sólido do rótulo e do CTA e o branco a 10%
   dos quatro botões, e nenhum cobre a foto.

   O background-color rgb(12,31,43) do próprio .hero não conta: fica
   ATRÁS da mídia e só aparece enquanto o poster carrega.

   Este ::after tinha TRÊS gradientes empilhados, e é isso que
   desenhava a faixa clara horizontal na altura do parágrafo: o
   segundo terminava em 25% e o terceiro em 15%, então a foto trocava
   de densidade duas vezes em linha reta. Agora são dois, e o de cima
   é curto de propósito, só para o cabeçalho transparente não sumir
   dentro de um quadro claro.

   O direcional termina em transparent, não mais em .10: o terço
   direito da foto fica limpo de verdade.

   Os dois primeiros stops estão em .90 e .82, acima dos .80 e .55
   especificados, e a diferença foi medida, não estimada. Com .80/.55,
   nas posições reais do texto em 1366, cinco dos oito alvos reprovam:
   lead 2.51:1, rótulo PESSOAS 2.63:1, "São 5 categorias" 3.42:1, VER
   TODAS 4.35:1 e chips 3.73:1, contra 4.5. O h1 raspava em 3.12:1
   contra 3. Com .90/.82 em 40%, o pior ponto de todos os oito é
   4.93:1. Os stops de 62% e 100% ficaram exatamente como pedidos: é
   por eles que a fachada aparece.

   Remedido em 18/08/2026, quando hero-01.jpg passou a ser o recorte
   16:9 da arrumado1: o lado esquerdo do quadro, que é onde o texto
   mora, ficou mais escuro que na foto anterior, e sobrou folga. Os
   sete alvos medidos no render, com o texto escondido, dão de 11,2:1
   a 16,1:1 de mediana e 10,7:1 no pior 5% de todos eles. Nenhum pixel
   abaixo do mínimo. Os stops NÃO foram afrouxados por causa disso: a
   calibração acima é o piso, e ela precisa continuar valendo se a
   foto for trocada de novo. */
.hero::after {
  content:''; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:
    linear-gradient(180deg, rgba(11,26,42,.75) 0%, transparent 18%),
    linear-gradient(100deg,
      rgba(11,26,42,.90) 0%,
      rgba(11,26,42,.82) 40%,
      rgba(11,26,42,.20) 62%,
      transparent 100%);
}
.hero .container { position:relative; z-index:2; }

/* Coluna única. Antes eram duas, 1.12fr para o texto e .88fr para o
   painel de triagem. O painel virou barra horizontal dentro da própria
   coluna de texto, então não sobrou segunda coluna para a grade
   organizar.
   O max-width segura a medida de leitura: sem ele o h1 esticaria pelos
   1400px do container e viraria uma linha só, ilegível. */
.hero-texto { max-width:900px; }

/* Rótulo em etiqueta sólida, não em texto amarelo solto. Sobre mídia
   em movimento, texto colorido sem fundo é a primeira coisa que some.
   Sólido, ele funciona sobre qualquer quadro do vídeo. */
.hero-texto .rotulo {
  display:inline-block;
  padding:4px 10px;
  background:var(--luz);
  color:var(--tinta);
  border-radius:3px;
  letter-spacing:.08em;
}
/* 18ch mantém a quebra em quatro linhas que o h1 tinha na coluna antiga.
   A barra de capacidade precisa de mais largura que isso, por isso o
   limite fica no h1 e não no bloco inteiro.

   Escala própria, menor que a global. O h1 global vai a 4.15rem e aqui
   virava um bloco de 66px de altura de linha por quatro linhas, o
   maior elemento da dobra por larga margem, com a barra de capacidade
   e o CTA espremidos embaixo dele. Em 1366 cai de 66,4px para 49,6px.
   O piso de 1.95rem é o que vale em 375px, onde o vw é pequeno demais
   para o termo do meio entrar. */
.hero-texto h1 {
  color:#fff; margin-bottom:1.15rem; max-width:18ch;
  font-size:clamp(1.95rem, 4vw, 3.1rem);
}
/* Um degrau abaixo do lead global: com o h1 menor, os dois tamanhos
   quase se encostavam e a hierarquia entre título e apoio sumia. */
.hero-texto .lead { color:var(--sobre-tinta); max-width:46ch; font-size:clamp(.95rem, 1.15vw, 1.05rem); }
.hero-marcas { display:flex; flex-wrap:wrap; gap:.45rem; margin-top:1.8rem; }
.hero-marca {
  display:inline-flex; align-items:center; gap:.4rem;
  padding:.38rem .8rem;
  font-size:.68rem; font-weight:600; letter-spacing:.08em; text-transform:uppercase;
  color:rgba(255,255,255,.86);
  border:1px solid rgba(255,255,255,.22); border-radius:999px;
}
.hero-marca i { font-size:1rem; color:var(--luz); }

/* ── A barra de capacidade ──
   Era um card de vidro flutuando na metade direita do hero. Cobria
   justamente o lado da foto que o scrim deixa limpo, e o CTA dele
   duplicava a única ação da dobra.

   Agora é uma barra horizontal dentro da coluna de texto, sem fundo,
   sem blur e sem moldura. A consequência é que o contraste dela passa
   a depender só do scrim do hero: o card carregava rgba(11,26,42,.62)
   mais blur(20px) por conta própria, e essa camada não existe mais.
   Por isso o scrim ganhou um patamar reto até 78% da altura, medido
   para cobrir a barra inteira. */
.capacidade { margin:32px 0; }
/* Sombra sutil na barra e no VER TODAS, em vez de mais scrim.
   Estes são os elementos que caem sobre a parte mais clara da foto, e
   escurecer o fundo inteiro por causa deles apagaria a fachada de novo.

   Aviso técnico: text-shadow NÃO entra na conta de contraste da WCAG.
   A fórmula compara duas cores chapadas, e sombra não é cor de fundo.
   Ela ajuda a leitura na prática, principalmente em cima de textura,
   mas não substitui o scrim. Quem faz os números passarem aqui são os
   dois primeiros stops do gradiente, medidos elemento por elemento;
   esta camada é ganho perceptual em cima disso, não a rede de
   segurança. */
.capacidade-t,
.hero .triagem-op b,
.hero .triagem-op span,
.capacidade-pe small,
.capacidade-pe .link-seta { text-shadow:0 1px 3px rgba(11,26,42,.6); }
/* Selecionado é amarelo sólido com número em navy: a sombra escura,
   feita para texto claro, engorda o traço e suja a leitura. */
.hero .triagem-op:active b, .hero .triagem-op.ativo b,
.hero .triagem-op:active span, .hero .triagem-op.ativo span { text-shadow:none; }
/* Linha única no desktop: rótulo, os quatro números, CTA fechando à
   direita. wrap para não estourar em largura intermediária. */
.capacidade-l {
  display:flex; flex-wrap:wrap; align-items:center; gap:1rem;
}
.capacidade-t {
  font-size:1rem; font-weight:600; line-height:1.2;
  letter-spacing:-.005em; color:#fff;
  margin:0; flex-shrink:0;
}
/* Alinhado com a altura dos quatro botões, não com a altura padrão do
   .btn: na mesma linha, dois alvos de alturas diferentes leem como
   erro de montagem. */
.capacidade-cta { min-height:52px; padding:.6rem 1.6rem; flex-shrink:0; }
/* Rodapé da barra: a linha de apoio e o VER TODAS saíram de dentro do
   card e ficaram aqui, alinhados à esquerda com o resto do bloco. */
.capacidade-pe {
  display:flex; align-items:center; gap:1rem; flex-wrap:wrap;
  margin-top:.7rem;
}
.capacidade-pe small { font-size:.75rem; color:rgba(255,255,255,.65); }
/* Branco com fio amarelo: sobre a foto o --travessia sumia, e era o
   último resto de teal dentro do hero. */
.capacidade-pe .link-seta { color:#fff; border-bottom-color:var(--luz); }
.capacidade-pe .link-seta:hover { color:var(--luz); }

.triagem-opcoes { display:grid; grid-template-columns:repeat(4, 1fr); gap:.6rem; }
.triagem-op {
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:.15rem;
  padding:.95rem .3rem .8rem;
  background:var(--base);
  border:1.5px solid var(--linha); border-radius:var(--raio);
  transition:border-color .22s var(--ease), background .22s var(--ease), transform .22s var(--ease);
}
.triagem-op:hover { border-color:var(--travessia); background:var(--travessia-fraca); transform:translateY(-2px); }
.triagem-op b {
  font-family:var(--fonte-display); font-weight:800; font-size:1.85rem;
  font-variation-settings:'wdth' 84; line-height:1; color:var(--travessia);
}
.triagem-op span { font-size:.62rem; font-weight:700; letter-spacing:.09em; text-transform:uppercase; color:var(--tinta-55); }

/* ── Os quatro botões DENTRO do hero ──
   Escopado em .hero de propósito: as mesmas classes .triagem-op são
   reaproveitadas em /apartamentos/, sobre fundo claro, e lá a versão
   original continua valendo sem alteração nenhuma.

   Em linha com o rótulo e o CTA, os quatro não podem mais ocupar a
   largura toda: viram colunas do tamanho do conteúdo, com 52px de piso
   para o alvo de toque não depender do texto.
   O número perdeu o --travessia porque o teal era a terceira cor
   competindo na mesma tela. O teal segue de sinalética no resto do
   site, só não aqui. */
.hero .triagem-opcoes { grid-template-columns:repeat(4, minmax(52px, auto)); gap:.5rem; }
.hero .triagem-op {
  background:rgba(255,255,255,.10);
  border:1px solid rgba(255,255,255,.30);
  border-radius:10px;
  /* Os 44px de alvo de toque ficam garantidos pelo min-height e pelo
     min-width, nunca pelo padding: se a fonte falhar em carregar, o
     alvo continua do mesmo tamanho. */
  padding:.42rem .5rem .38rem;
  min-height:52px; min-width:52px;
  transition:background .2s var(--ease), border-color .2s var(--ease), transform .2s var(--ease);
}
.hero .triagem-op b { font-size:1.25rem; color:#fff; font-weight:700; }
.hero .triagem-op span { font-size:.625rem; color:rgba(255,255,255,.7); }
.hero .triagem-op:hover,
.hero .triagem-op:focus-visible {
  background:rgba(255,255,255,.18);
  border-color:var(--luz);
  transform:translateY(-2px);
}
/* Selecionado: amarelo sólido com número em navy, o mesmo par do CTA.
   Vale no toque (:active) e na classe, para o dia em que o painel
   guardar a escolha em vez de navegar direto. */
.hero .triagem-op:active,
.hero .triagem-op.ativo {
  background:var(--luz);
  border-color:var(--luz);
  transform:translateY(-2px);
}
.hero .triagem-op:active b,
.hero .triagem-op.ativo b { color:var(--tinta); }
.hero .triagem-op:active span,
.hero .triagem-op.ativo span { color:rgba(var(--tinta-rgb), .72); }

/* ── Carregamento dos números ──
   O painel é a mecânica principal do hero, e chegar com os quatro
   números já postos não diz que há uma escolha a fazer. O shimmer
   segura meio segundo e a revelação escalonada faz o olho passar
   pelos quatro antes de decidir.

   A classe .skeleton é aplicada PELO main.js, nunca no HTML: se o
   script não rodar, os números nascem visíveis em vez de sumirem.
   Mesma regra do resto do motion do site. */
@keyframes triagemShimmer { to { background-position:-200% 0; } }
@keyframes triagemRevela {
  from { opacity:0; transform:translateY(8px); }
  to   { opacity:1; transform:none; }
}
.hero .triagem-op b.skeleton {
  display:inline-block; min-width:1.5rem;
  color:transparent;
  background:linear-gradient(
    90deg,
    rgba(255,255,255,.08) 25%,
    rgba(255,255,255,.22) 50%,
    rgba(255,255,255,.08) 75%
  );
  background-size:200% 100%;
  border-radius:6px;
  animation:triagemShimmer 1.1s linear infinite;
}
.hero .triagem-op b.revelado {
  animation:triagemRevela .45s cubic-bezier(.22,.9,.3,1) both;
}

/* .triagem-pe, .triagem-pe-linha, .triagem-sub, .triagem e o @supports
   de backdrop-filter saíram junto com o card. O que era o pé do card
   virou .capacidade-pe, e o vidro não existe mais em lugar nenhum do
   hero.

   .triagem-dados já tinha saído antes. Os três números que ele
   carregava, 22 apartamentos, 5 categorias e 400 m da balsa, estão
   todos na faixa de prova logo abaixo do hero. */


/* ── Topo das páginas internas ──
   Tipográfico, nunca fotográfico. Além de manter a regra de não ter
   foto de mar acima da dobra em nenhuma página, resolve o problema
   real de o cliente ainda não ter mandado as fotos: o topo não
   depende de arquivo nenhum para ficar de pé. */
.pagina-hero {
  position:relative; overflow:hidden;
  background:var(--tinta);
  padding:calc(70px + var(--gap-md)) 0 var(--gap-md);
}
.pagina-hero::before {
  content:''; position:absolute; inset:0; pointer-events:none;
  background:repeating-linear-gradient(-52deg, rgba(255,255,255,.045) 0 2px, transparent 2px 22px);
}
.pagina-hero .container { position:relative; z-index:2; }
.pagina-hero h1 { color:#fff; max-width:20ch; }
.pagina-hero .lead { color:var(--sobre-tinta); margin-top:1.1rem; max-width:56ch; }

/* ── Cabeçalho com foto ──
   Pedido de 17/08/2026, estendido no mesmo dia para as dez páginas com
   topo. A única sem foto é a do Apartamento PCD, que não tem material.

   O scrim reaproveita o mesmo ::before das listras em vez de somar uma
   camada nova. Duas imagens de fundo no MESMO pseudo-elemento, não dois
   pseudo-elementos empilhados:

   1. o direcional, forte à esquerda, onde fica o texto, e quase limpo à
      direita, onde a foto aparece de verdade
   2. uma tira curta no topo, só para a marca e o botão do menu terem
      onde se apoiar

   Não existe terceira camada, nem filter, nem box-shadow inset. Ajuste
   de 17/08/2026: o scrim anterior era vertical e encobria a foto por
   igual na altura toda.

   Os dois primeiros stops estão em .90 e .72, e não nos .85 e .62 do
   pedido, porque o eyebrow e o breadcrumb ficavam raspando no limite do
   AA. Os stops de 68% e 100% não foram tocados: são eles que deixam a
   foto respirar à direita. */
.pagina-hero--foto::before {
  z-index:1;
  background:
    linear-gradient(180deg, rgba(11,26,42,.70) 0%, transparent 22%),
    linear-gradient(100deg,
      rgba(11,26,42,.90) 0%,
      rgba(11,26,42,.72) 38%,
      rgba(11,26,42,.25) 68%,
      rgba(11,26,42,.08) 100%);
}
/* Variante para foto de fundo muito clara. Só os dois primeiros stops
   sobem, os de 68% e 100% ficam onde estão para a foto continuar
   respirando à direita. Usada no Apartamento PCD, onde a parede é
   madeira clara sob luz forte: com o scrim padrão o lead parava em
   3,48:1, abaixo do AA, e com .95/.90 vai a 4,58:1. */
.pagina-hero--foto.pagina-hero--clara::before {
  background:
    linear-gradient(180deg, rgba(11,26,42,.70) 0%, transparent 22%),
    linear-gradient(100deg,
      rgba(11,26,42,.95) 0%,
      rgba(11,26,42,.90) 38%,
      rgba(11,26,42,.25) 68%,
      rgba(11,26,42,.08) 100%);
}
.pagina-hero-fundo { position:absolute; inset:0; z-index:0; display:block; }
.pagina-hero-fundo img { width:100%; height:100%; object-fit:cover; object-position:center; }

/* O breadcrumb é o menor texto da área e o primeiro a sofrer quando o
   scrim clareia. Ganha peso próprio em vez de forçar o gradiente
   inteiro para cima por causa de uma linha de 11px. */
.pagina-hero--foto .migalhas { color:rgba(255,255,255,.80); text-shadow:0 1px 3px rgba(11,26,42,.7); }

/* O lead é a linha mais LARGA do cabeçalho: ele atravessa o segundo
   stop do gradiente e termina já na parte clara, onde a foto aparece.
   Subir os dois primeiros stops não alcança esse trecho, medido: nem
   com .97/.92 o rgba(.72) do padrão chega ao AA, para em 4,03:1. Então
   o texto ganha opacidade cheia aqui, em vez de fechar o scrim inteiro
   e perder a foto.

   O max-width de 50ch, no lugar dos 56ch do padrão, é a mesma história:
   em /apartamentos/ e em /contato/ o lead ia a 4,40:1 e 4,36:1 com 56ch,
   porque a última linha entrava na faixa clara. Com 50ch sobe para
   6,77:1 e 4,91:1, e nenhuma outra página piorou. */
.pagina-hero--foto .lead { color:#fff; max-width:50ch; }

/* No celular o texto ocupa a largura toda, então gradiente lateral não
   protege nada. Aqui ele volta a ser vertical. */
@media (max-width:768px) {
  .pagina-hero--foto::before {
    background:linear-gradient(180deg,
      rgba(11,26,42,.68) 0%,
      rgba(11,26,42,.80) 65%,
      rgba(11,26,42,.90) 100%);
  }
  /* A variante de foto clara também precisa da versão vertical, senão o
     celular volta ao gradiente padrão e o lead do PCD cai para 1,7:1. */
  .pagina-hero--foto.pagina-hero--clara::before {
    background:linear-gradient(180deg,
      rgba(11,26,42,.84) 0%,
      rgba(11,26,42,.90) 65%,
      rgba(11,26,42,.94) 100%);
  }
}

/* Cabeçalho liso, sem listras e sem foto. Sobrou como recurso para
   qualquer categoria que volte a ficar sem material próprio: o
   Apartamento PCD usou até 17/08/2026 e hoje já tem as fotos dele. */
.pagina-hero--liso::before { background:none; }

.migalhas { display:flex; flex-wrap:wrap; align-items:center; gap:.45rem; margin-bottom:1.1rem; font-size:.72rem; letter-spacing:.06em; color:rgba(255,255,255,.55); }
.migalhas a { color:rgba(255,255,255,.75); }
.migalhas a:hover { color:var(--luz); }
.migalhas i { font-size:.85rem; opacity:.6; }


/* ═══ 08 · VANTAGENS DA RESERVA DIRETA ════════════════════ */

/* Faixa fina logo abaixo do hero. Os quatro argumentos comerciais do
   site, todos vindos do briefing.

   auto-fit e não repeat(4, 1fr): com número fixo de colunas, tirar um
   item deixa buraco. Foi exatamente o que aconteceu quando o desconto
   no Pix saiu e a faixa ficou com dois itens numa grade de três, com
   metade vazia e um divisor solto no meio do nada. Com auto-fit a
   faixa se refaz sozinha para qualquer quantidade. */
.vantagens { background:var(--superficie); border-bottom:1px solid var(--linha); }
.vantagens-g {
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(230px, 1fr));
}
.vantagem {
  display:flex; align-items:flex-start; gap:.8rem;
  padding:clamp(24px, 2.4vw, 32px) clamp(.85rem, 2vw, 1.5rem);
}
/* Divisor só ENTRE colunas. O :first-child de cada linha da grade
   perde a borda, senão sobra um fio na margem esquerda quando a faixa
   quebra em 2x2. */
.vantagem + .vantagem { border-left:1px solid rgba(11,26,42,.12); }
.vantagem i {
  font-size:1.6rem; color:var(--tinta);
  flex-shrink:0; line-height:1;
}
.vantagem b { display:block; font-size:.88rem; font-weight:600; color:#0B1A2A; line-height:1.3; }
.vantagem span { display:block; font-size:.76rem; color:rgba(11,26,42,.65); line-height:1.4; margin-top:.15rem; }


/* Portas do site, na home. Existem porque a navegação escrita saiu da
   barra: sem elas, descobrir a galeria exigiria voltar ao topo e abrir
   o menu. Cartão inteiro clicável, não só o título. */
.portas {
  display:grid; grid-template-columns:repeat(3, 1fr);
  gap:clamp(.9rem, 1.6vw, 1.25rem);
  margin-top:var(--gap-sm);
}
.portas a {
  position:relative;
  display:flex; flex-direction:column; align-items:flex-start; gap:.3rem;
  padding:1.6rem 1.5rem 1.7rem;
  background:var(--base);
  border:1px solid var(--linha); border-radius:var(--raio-md);
  transition:border-color .25s var(--ease), transform .25s var(--ease),
             box-shadow .25s var(--ease), background .25s var(--ease);
}
.portas a:hover {
  background:var(--superficie);
  border-color:var(--travessia);
  transform:translateY(-3px);
  box-shadow:0 14px 34px rgba(12,31,43,.10);
}
.portas i { font-size:1.6rem; color:var(--travessia); margin-bottom:.35rem; }
.portas b {
  font-family:var(--fonte-display); font-weight:700;
  font-size:1.06rem; color:var(--tinta); line-height:1.25;
}
.portas span { font-size:.82rem; color:var(--tinta-55); line-height:1.45; }

@media (max-width: 980px) { .portas { grid-template-columns:repeat(2, 1fr); } }
@media (max-width: 560px) { .portas { grid-template-columns:1fr; } }


/* ═══ 09 · PAINEL DE ACESSO (assinatura) ══════════════════ */

/* É a assinatura do site e o único lugar onde a ousadia foi gasta.
   Os três dígitos entram em sequência (main.js, com GSAP quando
   disponível) e é o único momento de motion orquestrado do site.
   Sem JS ou sem GSAP, tudo já nasce visível — o estado inicial
   escondido é aplicado PELO script, nunca pelo CSS. */
/* Navy chapado. A trama de listras diagonais saiu: sobre ela cada
   bloco de texto ficava com um fundo diferente e a leitura embolava.
   Ficou só um clarão radial de 3% no topo, que dá profundidade sem
   virar textura. */
.acesso { background:var(--tinta); position:relative; overflow:hidden; }
.acesso::before {
  content:''; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(ellipse 70% 50% at 50% 0%, rgba(255,255,255,.03) 0%, transparent 70%);
}
.acesso .container { position:relative; z-index:2; }
.acesso h2 { color:#fff; }
/* A regra global `p` tem especificidade 0,0,1 e vence a herança:
   sem redeclarar aqui, todo parágrafo desta seção sai em --tinta-70
   sobre --tinta e some. Foi o que aconteceu com o rodapé do painel
   e com o bloco do princípio fundador em sobre/. Vale para a seção
   inteira, não só para os filhos que já tinham regra própria. */
.acesso p, .acesso li { color:var(--sobre-tinta); }

.passos { display:grid; grid-template-columns:repeat(3, 1fr); gap:clamp(1rem, 2.5vw, 2rem); margin-top:var(--gap-md); }

/* Alinhado à esquerda, não centralizado. Em três colunas centralizadas
   o olho precisa reencontrar o início da linha a cada bloco; com tudo
   na mesma margem ele desce reto.
   O divisor vertical entre colunas substitui o fio que passava por
   trás dos números. */
.passo { position:relative; padding-top:.4rem; }
.passo + .passo { border-left:1px solid rgba(255,255,255,.10); padding-left:clamp(1rem, 2.5vw, 2rem); }

/* Número sem caixa. O quadrado amarelo sólido era o elemento de maior
   peso da seção e roubava a atenção do título que vem logo abaixo.
   Agora é só o algarismo em serif, na cor de ação, com um fio curto
   marcando o início da coluna. */
.passo-num {
  position:relative;
  font-family:var(--fonte-display); font-weight:400; font-size:3rem;
  font-variation-settings:'wdth' 90;
  color:var(--luz); line-height:1;
  margin-bottom:.85rem;
  transition:opacity .4s var(--ease);
}
.passo-num::after {
  content:''; display:block;
  width:40px; height:1px; margin-top:.85rem;
  background:rgba(255,255,255,.22);
}
/* Estado apagado aplicado PELO main.js, nunca pelo CSS: se o script
   não rodar, os três números nascem acesos em vez de ficarem a 45%
   para sempre. Mesma regra do resto do motion do site. */
.passos.tem-motion .passo:not(.aceso) .passo-num { opacity:.45; }

.passo-txt { text-align:left; }
.passo-txt h3 { color:#fff; font-size:1.5rem; font-weight:700; margin-bottom:.7rem; }
.passo-txt p { color:rgba(255,255,255,.72); font-size:1rem; line-height:1.6; margin:0; max-width:34ch; }

.acesso-pe {
  margin-top:var(--gap-md); padding-top:var(--gap-sm);
  border-top:1px solid rgba(255,255,255,.12);
  display:flex; align-items:center; justify-content:space-between; gap:1.25rem; flex-wrap:wrap;
}
.acesso-pe p { margin:0; font-size:.88rem; }

/* Versão longa da página como-funciona/: cada passo vira uma linha
   com a ficha de detalhe ao lado do número. */
.passos--lista { grid-template-columns:1fr; gap:0; }
.passos--lista .passo { display:grid; grid-template-columns:68px 1fr; gap:clamp(1.25rem, 3vw, 2.25rem); align-items:start; padding:var(--gap-sm) 0; }
/* Aqui os passos são linhas empilhadas: o divisor é horizontal, e o
   vertical da versão em três colunas não vale. */
.passos--lista .passo + .passo { border-top:1px solid rgba(255,255,255,.12); border-left:none; padding-left:0; }
.passos--lista .passo::after { content:none; }
.passos--lista .passo-num { margin:0 0 .5rem; }
.passos--lista .passo-txt { text-align:left; }
.passos--lista .passo-txt p { margin:0; max-width:60ch; }
.passo-detalhe { display:flex; flex-direction:column; gap:.55rem; margin-top:.9rem; }
.passo-detalhe li { display:flex; gap:.6rem; font-size:.88rem; color:var(--sobre-tinta); line-height:1.5; }
.passo-detalhe i { color:var(--luz); font-size:1.05rem; flex-shrink:0; margin-top:.1rem; }


/* ═══ 10 · FICHAS DE APARTAMENTO ══════════════════════════ */

/* Ordenadas por capacidade, sempre. É o critério de escolha real
   do hóspede e o mesmo eixo da triagem do hero. */
/* Seis colunas com cada ficha ocupando duas, não três colunas de 1fr.
   São cinco categorias: em três colunas, as duas últimas ficavam
   encostadas à esquerda e sobrava um buraco do tamanho de uma ficha na
   ponta direita da segunda linha. Com a grade dobrada, a quarta ficha
   pode começar na coluna 2 e a linha de baixo fica centrada.

   O seletor pega a quarta ficha só quando ela é a penúltima, ou seja,
   só quando existem exatamente cinco. Com quatro ou seis, nada muda e
   a grade volta a preencher normalmente. */
.fichas { display:grid; grid-template-columns:repeat(6, 1fr); gap:var(--gap-sm); }
.ficha { grid-column:span 2; }
.fichas .ficha:nth-child(4):nth-last-child(2) { grid-column:2 / span 2; }
/* PCD OCULTO: com quatro fichas a quarta ficava sozinha e encostada à
   esquerda na segunda linha. Este seletor só pega a quarta quando ela é
   a última, ou seja, só quando existem exatamente quatro, e a joga para
   o meio. Ao reativar o PCD voltam a ser cinco e a regra se desliga
   sozinha, igual à de cima. */
.fichas .ficha:nth-child(4):nth-last-child(1) { grid-column:3 / span 2; }

/* ── Carrossel das fichas ──
   Pedido de 17/08/2026, só onde as categorias aparecem JUNTAS: a home e
   o índice de apartamentos. Dentro da página de cada categoria não há
   carrossel nenhum.

   É scroll nativo com scroll-snap, não um slider de biblioteca. Funciona
   sem JS, com dedo no celular, com trackpad no desktop, com Tab no
   teclado, e continua funcionando se o GSAP não carregar. As setas são
   um atalho, não o mecanismo.

   Os dois seletores nth-child da grade precisam ser anulados aqui, senão
   ganham por especificidade e a ficha do meio nasce fora de lugar. */
.fichas--carrossel {
  display:flex;
  overflow-x:auto;
  scroll-snap-type:x mandatory;
  scroll-behavior:smooth;
  scroll-padding:0;
  padding-bottom:.35rem;
  /* a barra some, o scroll continua: quem usa dedo ou trackpad não
     precisa dela, e ela cortava a sombra do card. */
  scrollbar-width:none; -ms-overflow-style:none;
  /* espaço para a sombra e para o contorno de foco não serem cortados */
  margin-inline:-4px; padding-inline:4px;
}
.fichas--carrossel::-webkit-scrollbar { display:none; }
.fichas--carrossel .ficha,
.fichas--carrossel .ficha:nth-child(4):nth-last-child(2),
.fichas--carrossel .ficha:nth-child(4):nth-last-child(1) {
  grid-column:auto;
  flex:0 0 clamp(270px, 31%, 380px);
  scroll-snap-align:start;
}

.carrossel { position:relative; }
.carrossel-ctrl { display:flex; gap:.6rem; justify-content:flex-end; margin-top:1rem; }
.carrossel-btn {
  width:44px; height:44px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:var(--superficie); border:1px solid var(--linha);
  color:var(--tinta); font-size:1.15rem;
  transition:border-color .2s var(--ease), background .2s var(--ease), color .2s var(--ease);
}
.carrossel-btn:hover { border-color:var(--travessia); color:var(--travessia); }
.carrossel-btn[disabled] { opacity:.35; pointer-events:none; }

/* ── O que vem dentro da cozinha ──
   A lista chegou do cliente em 17/08/2026 e responde a pergunta que
   estava aberta em PENDENCIAS, grupo 1, item 14: "cozinha completa
   inclui o quê?". Vale para todas as categorias, então o texto diz
   "todas acompanham" e o bloco é igual nas quatro páginas.

   São dez itens: em lista corrida viravam um parágrafo que ninguém lê.
   Em pastilha, o olho varre e para no que interessa a ele, que costuma
   ser fogão, micro-ondas ou cafeteira. */
/* ── O que a cozinha traz ──
   Vive dentro do card largo, na coluna da direita, separada do texto por
   um fio. Empilhada embaixo do parágrafo virava um bloco comprido sem
   hierarquia: o olho não sabia onde terminava a descrição e onde
   começava a lista. */
.cozinha-itens { flex:1; min-width:0; padding-left:1.6rem; border-left:1px solid var(--linha); }
.cozinha-itens-titulo {
  margin:0 0 .55rem;
  font-family:var(--fonte-corpo); font-size:.68rem; font-weight:700;
  letter-spacing:.14em; text-transform:uppercase; color:var(--travessia);
}
.cozinha-itens ul { display:flex; flex-wrap:wrap; gap:.4rem; list-style:none; margin:0; padding:0; }
.cozinha-itens li {
  padding:.36rem .8rem;
  font-size:.76rem; font-weight:600; color:var(--tinta);
  background:var(--base); border:1px solid var(--linha); border-radius:999px;
}


/* ── Ampliar foto ──
   Envolve a foto num botão de verdade, montado pelo main.js, para a
   ampliação funcionar no teclado e ser anunciada pelo leitor de tela.
   Se o script não rodar, sobra a foto, que é o comportamento de antes.

   O selo da lupa fica sempre visível no canto, não só no hover: em tela
   de toque não existe hover, e sem ele ninguém descobre que dá para
   ampliar. No hover ele só ganha contraste. */
.amplia {
  display:block; width:100%; height:100%;
  padding:0; border:none; background:none;
  position:relative; cursor:zoom-in;
}
.amplia::after {
  content:''; position:absolute; right:.7rem; bottom:.7rem;
  width:38px; height:38px; border-radius:50%;
  background:rgba(11,26,42,.55) no-repeat center/18px 18px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='M15.5 15.5 21 21M10.5 7.5v6M7.5 10.5h6'/%3E%3C/svg%3E");
  border:1px solid rgba(255,255,255,.35);
  transition:background-color .2s var(--ease), transform .2s var(--ease);
  pointer-events:none;
}
.amplia:hover::after, .amplia:focus-visible::after { background-color:rgba(11,26,42,.85); transform:scale(1.06); }
.amplia:focus-visible { outline:2px solid var(--luz); outline-offset:3px; }

/* Botão de ação logo abaixo de uma foto grande, nas páginas de
   categoria. Centralizado, porque a foto ocupa a largura toda. */
.acao-foto { display:flex; justify-content:center; margin-top:1.15rem; }
/* Estes dois vêm logo depois de uma foto que ocupa a largura toda, e no
   padrão de 48px pareciam pequenos demais para o peso da imagem acima.
   Sobem para 58px de altura, com mais respiro lateral e a letra um passo
   maior. É o único botão do site nessa medida: os outros continuam no
   padrão, e a diferença é justamente o que marca onde está a ação. */
.acao-foto .btn {
  min-height:58px; padding:1rem 2.6rem;
  font-size:.82rem; letter-spacing:.16em;
}
@media (max-width:560px) {
  /* no celular a foto tem a largura da tela, então o botão acompanha */
  .acao-foto { align-self:stretch; }
  .acao-foto .btn { width:100%; padding-inline:1.25rem; }
}

@media (prefers-reduced-motion:reduce) {
  .fichas--carrossel { scroll-behavior:auto; }
}

.ficha {
  display:flex; flex-direction:column;
  background:var(--superficie);
  border:1px solid var(--linha); border-radius:var(--raio-md);
  overflow:hidden;
  transition:transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease);
}
.ficha:hover { transform:translateY(-4px); box-shadow:var(--sombra-lg); border-color:transparent; }

.ficha-foto { position:relative; aspect-ratio:4/3; overflow:hidden; background:var(--base); }
.ficha-foto img { width:100%; height:100%; transition:transform .6s var(--ease); }
.ficha:hover .ficha-foto img { transform:scale(1.05); }

/* Selo de capacidade sobre a foto: é o dado que decide a compra. */
.ficha-cap {
  position:absolute; top:.75rem; left:.75rem; z-index:2;
  display:inline-flex; align-items:center; gap:.35rem;
  padding:.35rem .7rem;
  background:var(--luz); color:var(--tinta);
  font-size:.7rem; font-weight:700; letter-spacing:.06em;
  border-radius:var(--raio);
}
.ficha-cap i { font-size:.95rem; }

.ficha-corpo { display:flex; flex-direction:column; flex:1; padding:1.25rem 1.35rem 1.35rem; }
.ficha-corpo h3 { margin-bottom:.4rem; }
.ficha-camas { font-size:.8rem; color:var(--travessia); font-weight:600; margin-bottom:.85rem; }
.ficha-itens { display:flex; flex-wrap:wrap; gap:.3rem; margin-bottom:1.1rem; }
.ficha-item {
  padding:.24rem .58rem;
  font-size:.66rem; font-weight:600; letter-spacing:.05em;
  color:var(--tinta-70); background:var(--base);
  border:1px solid var(--linha); border-radius:var(--raio);
}
.ficha-corpo .btn { margin-top:auto; }

/* Faixa "vista mar" — só o Superior Quíntuplo tem, segundo o
   briefing. Nenhum outro apartamento pode receber esta marca. */
.ficha-vista {
  display:inline-flex; align-items:center; gap:.4rem;
  font-size:.72rem; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:var(--travessia); margin-bottom:.75rem;
}
.ficha-vista i { font-size:1rem; }

/* Ficha larga, usada na página de apartamentos. */
.ficha--larga { grid-column:1 / -1; display:grid; grid-template-columns:.9fr 1.1fr; }
.ficha--larga .ficha-foto { aspect-ratio:auto; min-height:320px; }
.ficha--larga .ficha-corpo { padding:clamp(1.5rem, 3vw, 2.4rem); justify-content:center; }
.ficha--larga .ficha-corpo .btn { margin-top:1.4rem; align-self:flex-start; }


/* ── Página de uma categoria ──
   Cada uma das 5 categorias tem página própria. O que muda de uma
   para a outra é capacidade, camas e ambientes, então esses três
   viram a primeira coisa da página, antes de qualquer descrição. */
.numeros {
  display:grid; grid-template-columns:repeat(3, 1fr);
  background:var(--superficie);
  border:1px solid var(--linha); border-radius:var(--raio-md);
  overflow:hidden;
}
.numero { padding:1.35rem 1.4rem; }
.numero + .numero { border-left:1px solid var(--linha); }
.numero b {
  display:block;
  font-family:var(--fonte-display); font-weight:800; font-size:2.1rem;
  font-variation-settings:'wdth' 84;
  line-height:1; color:var(--travessia); margin-bottom:.3rem;
}
.numero span { display:block; font-size:.68rem; font-weight:700; letter-spacing:.13em; text-transform:uppercase; color:var(--tinta-55); }
.numero small { display:block; font-size:.82rem; color:var(--tinta-70); line-height:1.4; margin-top:.35rem; }

/* Fotos da categoria. Por padrão a primeira ocupa a linha inteira,
   porque é a que o hóspede usa para decidir. */
.fotos-cat { display:grid; grid-template-columns:1fr 1fr; gap:.8rem; }
.fotos-cat > *:first-child { grid-column:1 / -1; aspect-ratio:16/9; }
.fotos-cat > * { aspect-ratio:4/3; overflow:hidden; border-radius:var(--raio-md); background:var(--base); }
.fotos-cat img { width:100%; height:100%; }

/* Modificador para quando a foto que decide já está na abertura da
   página: aqui a grade não tem primeira foto larga, são quadros
   iguais em duas colunas. Usado nas quatro páginas de categoria. */
.fotos-cat--par > *:first-child { grid-column:auto; aspect-ratio:4/3; }

/* Três quadros iguais lado a lado. É o que sobra na grade depois que a
   foto do cabeçalho, a principal e a da cozinha saem do pool da
   categoria: 6 fotos, 6 lugares, nenhuma repetida. */
.fotos-cat--tres { grid-template-columns:repeat(3, 1fr); }
.fotos-cat--tres > *:first-child { grid-column:auto; aspect-ratio:4/3; }

/* Foto de abertura da página de categoria. No desktop é 16/9, como
   qualquer bloco largo. No celular a grade abaixo dela vira uma
   coluna em 4/3, e em 16/9 a foto principal acabava sendo a MENOR
   da página. Aqui ela acompanha a mesma proporção das outras. */
@media (max-width:768px) {
  .bloco-foto--abertura { aspect-ratio:4/3; }
}

/* Ficha técnica. Duas colunas de rótulo e valor, com fio entre as
   linhas: o que já existe e o que ainda é CONFIRMAR ficam lado a
   lado, sem um disfarçar o outro. */
.especs { border-top:1px solid var(--linha); }
.espec {
  display:grid; grid-template-columns:minmax(0,.9fr) minmax(0,1.4fr);
  gap:1rem; align-items:baseline;
  padding:.9rem 0; border-bottom:1px solid var(--linha);
}
.espec dt { font-size:.72rem; font-weight:700; letter-spacing:.12em; text-transform:uppercase; color:var(--tinta-55); }
.espec dd { font-size:.95rem; color:var(--tinta); line-height:1.5; }

/* Navegação entre categorias, no fim de cada página. Ordenada por
   capacidade, igual ao resto do site. */
.outras { display:grid; grid-template-columns:repeat(4, 1fr); gap:.7rem; }
/* PCD OCULTO: sobraram três por página nesta grade de quatro, e a quarta
   coluna ficava vazia. Vale só quando existem exatamente três, então se
   desliga sozinha ao reativar a categoria. */
.outras:has(> :nth-child(3):last-child) { grid-template-columns:repeat(3, 1fr); }
.outra {
  display:flex; flex-direction:column; gap:.2rem;
  padding:1rem 1.1rem;
  background:var(--superficie);
  border:1px solid var(--linha); border-radius:var(--raio-md);
  transition:border-color .22s var(--ease), transform .22s var(--ease);
}
.outra:hover { border-color:var(--travessia); transform:translateY(-2px); }
.outra b { font-family:var(--fonte-display); font-weight:700; font-size:1rem; letter-spacing:-.01em; color:var(--tinta); }
.outra span { font-size:.75rem; color:var(--travessia); font-weight:600; }

/* ── Tabela de comparação (índice de apartamentos) ──
   É o que faz a página de índice valer a visita: as cinco categorias
   no mesmo eixo, em vez de cinco descrições soltas. Rola sozinha na
   horizontal no celular, dentro do próprio contêiner: a página nunca
   rola de lado. */
.tabela-rolo { overflow-x:auto; -webkit-overflow-scrolling:touch; border:1px solid var(--linha); border-radius:var(--raio-md); background:var(--superficie); }
.tabela-cap { width:100%; min-width:660px; border-collapse:collapse; font-size:.88rem; }
.tabela-cap th, .tabela-cap td { padding:.85rem 1rem; text-align:left; border-bottom:1px solid var(--linha); vertical-align:middle; }
.tabela-cap thead th {
  position:sticky; top:0; z-index:1;
  background:var(--tinta); color:#fff;
  font-size:.66rem; font-weight:700; letter-spacing:.13em; text-transform:uppercase;
  white-space:nowrap;
}
.tabela-cap tbody tr:last-child td { border-bottom:none; }
.tabela-cap tbody tr:hover { background:var(--base); }
.tabela-cap td:first-child { font-weight:600; color:var(--tinta); white-space:nowrap; }
.tabela-cap td:first-child a { color:var(--tinta); border-bottom:2px solid var(--luz); }
.tabela-cap td:first-child a:hover { color:var(--travessia); }
.tabela-cap .cap { font-family:var(--fonte-display); font-weight:800; font-size:1.15rem; color:var(--travessia); font-variation-settings:'wdth' 84; }
.tabela-cap .sim { color:var(--travessia); font-weight:700; }
.tabela-cap .nao { color:var(--tinta-55); }
.tabela-nota { font-size:.78rem; color:var(--tinta-55); margin-top:.7rem; }


/* ═══ 11 · BLOCOS DE CONTEÚDO ═════════════════════════════ */

.bloco-foto { position:relative; overflow:hidden; border-radius:var(--raio-md); background:var(--base); aspect-ratio:4/5; }
.bloco-foto img { width:100%; height:100%; }
.bloco-foto--larga { aspect-ratio:16/9; }
/* O Apartamento PCD foi fotografado no celular, em 4:3, e não no 16:9 do
   ensaio profissional das outras categorias. Forçado a 16/9 o quadro
   cortava um quarto da altura e sobrava só a cama, sem o ambiente. */
.bloco-foto--43 { aspect-ratio:4/3; }

/* ── Foto do bloco "O lugar", na home ──
   Escopada num modificador: as mesmas classes servem /sobre/ e
   /localizacao/, e lá o retrato 4/5 continua valendo.

   A proporção é 6/5, ou seja, levemente DEITADA, e não o 3/4 que foi
   pedido. Motivo aritmético: 3/4 é 0,75 e 4/5 é 0,80, então 3/4 é mais
   ALTO que o de hoje, e o pedido era justamente encurtar. Medido em
   1440px: coluna de 526px de largura, texto ao lado com 442px de
   altura, foto com 658px. Em 6/5 a foto vai para 438px e as duas
   colunas terminam na mesma linha.

   O corte deixou de ser problema junto: em 6/5 aparecem 89% da largura
   do quadro, contra 60% antes, e a placa "AP PASSARELA · AV PORTUGAL
   526" volta inteira sem sacrificar a porta 526. */
.bloco-foto--lugar {
  aspect-ratio:6/5;
  border-radius:12px;
  box-shadow:0 12px 32px rgba(11,26,42,.12);
}
.bloco-foto--lugar img {
  /* 60% no eixo Y para privilegiar a base do quadro, onde estão as
     portas, o número e o calçadão. Em telas onde o corte for vertical,
     é isso que descarta o excesso de céu e de telhado. */
  object-position:50% 60%;
  /* A foto é de sol direto e chega lavada. Correção leve, no CSS, para
     não depender de reprocessar o arquivo do cliente. */
  filter:contrast(1.06) saturate(1.08);
}
/* ── Foto do bloco "O entorno", em /localizacao/ ──
   Mesmo problema do bloco da home, em dose maior: em 4/5 a foto ficava
   com 658px de altura contra 325px do texto ao lado, e mostrava só 60%
   da largura do quadro. Dava parede e janela, não dava prédio numa rua,
   que é o que o bloco precisa provar.

   Em 3/2 a foto cai para 351px, encosta na altura do texto, e passa a
   mostrar a largura INTEIRA do quadro: fachada completa, as duas
   portas, o 526 e a placa. O corte agora é vertical e come só excesso
   de céu, que é o que menos importa aqui. */
.bloco-foto--entorno { aspect-ratio:3/2; }
.bloco-foto--entorno img { object-position:50% 62%; }

.bloco-figura { margin:0; display:flex; flex-direction:column; gap:.6rem; }
.bloco-legenda {
  font-size:.78rem; line-height:1.4;
  color:rgba(11,26,42,.55);
}

/* Lista de itens do apartamento e afins. */
/* Seis colunas com cada card ocupando duas, mesmo truque das fichas de
   apartamento. O motivo é o card largo da cozinha: com três colunas
   fixas, ele mais os cinco cards restantes davam duas linhas cheias e
   uma terceira com dois cards e um BURACO na ponta direita.

   Com a grade dobrada, os dois últimos podem começar na coluna 2 e a
   linha de baixo fica centrada, sem sobra visível de um lado só. */
.itens { display:grid; grid-template-columns:repeat(6, 1fr); gap:.9rem; margin-top:var(--gap-sm); }
.item-card { grid-column:span 2; }
/* Só vale na grade que TEM o card largo, e só para o quinto card quando
   ele é o penúltimo. Sem o :has(), a regra pegava também as páginas de
   seis cards normais, como a home e a /sobre/: lá ela empurrava o quinto
   para o meio e deixava o quarto sozinho numa linha. */
/* O card da cozinha ocupa a linha inteira: é o único que traz uma lista
   de dez pastilhas dentro, e em dois sextos da largura elas quebravam em
   cinco linhas e esticavam os cards vizinhos. Sendo a cozinha o
   diferencial de venda da casa, o card mais largo também diz, sem
   escrever, qual dos seis itens pesa mais.

   Precisa vir DEPOIS de .item-card: mesma especificidade, quem ganha é
   quem está por último. */
.item-card--largo { grid-column:1 / -1; align-items:center; gap:1.3rem; padding:1.35rem 1.5rem; }
.item-card--largo .item-card-txt { flex:0 0 32%; }
.item-card--largo .item-card-txt p { max-width:38ch; }
.itens:has(.item-card--largo) .item-card:nth-child(5):nth-last-child(2) { grid-column:2 / span 2; }
.item-card {
  display:flex; gap:.9rem; align-items:flex-start;
  padding:1.15rem 1.25rem;
  background:var(--superficie); border:1px solid var(--linha); border-radius:var(--raio-md);
}
.item-card i { font-size:1.6rem; color:var(--travessia); flex-shrink:0; }
.item-card h4 { margin-bottom:.25rem; letter-spacing:.02em; text-transform:none; font-size:.92rem; }
.item-card p { font-size:.82rem; margin:0; }

/* Lista de checagem simples. */
.lista-check { display:flex; flex-direction:column; gap:.65rem; margin-top:1.2rem; }
.lista-check li { display:flex; gap:.65rem; align-items:flex-start; font-size:.92rem; color:var(--tinta-70); line-height:1.5; }
.lista-check i { color:var(--travessia); font-size:1.15rem; flex-shrink:0; margin-top:.05rem; }

/* Perguntas frequentes. */
.faq { display:flex; flex-direction:column; border-top:1px solid var(--linha); margin-top:var(--gap-sm); }
.faq-item { border-bottom:1px solid var(--linha); }
.faq-p {
  display:flex; align-items:center; justify-content:space-between; gap:1rem;
  width:100%; padding:1.15rem 0; background:none; border:none; text-align:left;
  font-family:var(--fonte-corpo); font-size:1rem; font-weight:600; color:var(--tinta);
}
.faq-p i { font-size:1.25rem; color:var(--travessia); flex-shrink:0; transition:transform .3s var(--ease); }
.faq-item.aberto .faq-p i { transform:rotate(45deg); }
.faq-r { overflow:hidden; max-height:0; transition:max-height .35s var(--ease); }
.faq-r p { padding:0 0 1.2rem; font-size:.94rem; }

/* ── Política de privacidade ──
   O site inteiro é feito de blocos curtos; esta é a única página de
   texto corrido longo. Precisa de escala e respiro próprios, senão os
   h2 encostam no parágrafo anterior e a leitura vira parede. */
.pol h2 {
  font-size:clamp(1.35rem, 2.2vw, 1.7rem);
  margin:var(--gap-md) 0 .9rem;
  padding-top:var(--gap-sm);
  border-top:1px solid var(--linha);
}
.pol h2:first-of-type { border-top:none; padding-top:0; }
.pol p { font-size:.98rem; line-height:1.7; color:var(--tinta-70); margin:0 0 1rem; }
.pol p b, .pol li b { color:var(--tinta); }
.pol a { color:var(--travessia); text-decoration:underline; text-underline-offset:3px; }
.pol a:hover { color:var(--tinta); }
.pol .lista-check { margin:0 0 1.3rem; }
.pol .faq { border-top:none; margin-top:0; margin-bottom:1.3rem; }
.pol .faq-item { padding:1.05rem 0; }
.pol .faq-item:last-child { border-bottom:none; }
.pol .faq-item h3 { font-size:1rem; font-weight:700; color:var(--tinta); margin-bottom:.35rem; }
.pol .faq-item p { margin:0; }
.pol-data {
  font-size:.8rem; letter-spacing:.04em; color:var(--tinta-55);
  margin-bottom:var(--gap-sm) !important;
}
.pol-acao { margin-top:1.4rem; }

/* Chamada final de página. */
.chamada { background:var(--tinta); text-align:center; position:relative; overflow:hidden; }
.chamada::before {
  content:''; position:absolute; inset:0; pointer-events:none;
  background:repeating-linear-gradient(-52deg, rgba(255,255,255,.04) 0 2px, transparent 2px 22px);
}
.chamada .container { position:relative; z-index:2; }
.chamada h2 { color:#fff; }
.chamada p { color:var(--sobre-tinta); margin:1rem auto 0; }

/* ── Chamada com foto de fundo ──
   Mesmo mecanismo do cabeçalho: o ::before das listras vira scrim, sem
   camada nova. A diferença é que aqui o texto é centralizado e curto,
   então o scrim é vertical e uniforme, não direcional: não existe lado
   livre para deixar a foto aparecer.

   O parágrafo sobe para branco cheio pelo mesmo motivo do lead do
   cabeçalho, o rgba(.72) do padrão não chega ao AA sobre foto. */
.chamada--foto::before {
  z-index:1;
  background:linear-gradient(180deg,
    rgba(11,26,42,.88) 0%,
    rgba(11,26,42,.80) 50%,
    rgba(11,26,42,.90) 100%);
}
.chamada-fundo { position:absolute; inset:0; z-index:0; display:block; }
.chamada-fundo img { width:100%; height:100%; object-fit:cover; object-position:center; }
.chamada--foto p { color:#fff; }
.chamada-botoes { display:flex; gap:.85rem; justify-content:center; flex-wrap:wrap; margin-top:var(--gap-sm); }


/* ═══ 12 · GALERIA E LIGHTBOX ═════════════════════════════ */

.filtros { display:flex; flex-wrap:wrap; gap:.5rem; justify-content:center; margin-bottom:var(--gap-md); }
.filtro {
  min-height:40px; padding:.45rem 1.1rem;
  background:transparent; border:1.5px solid var(--linha); border-radius:999px;
  font-size:.7rem; font-weight:700; letter-spacing:.1em; text-transform:uppercase;
  color:var(--tinta-70);
  transition:background .22s var(--ease), color .22s var(--ease), border-color .22s var(--ease);
}
.filtro:hover { border-color:var(--travessia); color:var(--travessia); }
.filtro.ativo { background:var(--tinta); border-color:var(--tinta); color:#fff; }

.galeria { display:grid; grid-template-columns:repeat(4, 1fr); gap:.7rem; }
.gal-item { aspect-ratio:1; overflow:hidden; border-radius:var(--raio); background:var(--base); border:none; padding:0; }
.gal-item img { width:100%; height:100%; transition:transform .5s var(--ease); }
.gal-item:hover img { transform:scale(1.06); }

#lb { position:fixed; inset:0; z-index:9700; background:rgba(6,16,22,.96); display:flex; align-items:center; justify-content:center; opacity:0; visibility:hidden; transition:opacity .3s var(--ease), visibility .3s var(--ease); }
#lb.aberto { opacity:1; visibility:visible; }
#lbImg { max-width:92vw; max-height:84vh; object-fit:contain; }
.lb-btn { position:absolute; background:rgba(255,255,255,.10); border:none; color:#fff; width:52px; height:52px; border-radius:50%; font-size:1.5rem; display:flex; align-items:center; justify-content:center; transition:background .2s; }
.lb-btn:hover { background:rgba(255,255,255,.22); }
.lb-fechar { top:1.25rem; right:1.25rem; }
.lb-ant { left:1.25rem; top:50%; transform:translateY(-50%); }
.lb-prox { right:1.25rem; top:50%; transform:translateY(-50%); }
#lbCnt { position:absolute; bottom:1.25rem; left:50%; transform:translateX(-50%); color:rgba(255,255,255,.6); font-size:.78rem; letter-spacing:.12em; }


/* ═══ 13 · LOCALIZAÇÃO ════════════════════════════════════ */

.mapa { width:100%; height:440px; border-radius:var(--raio-md); overflow:hidden; border:1px solid var(--linha); background:var(--base); }
.mapa iframe { width:100%; height:100%; border:0; }
.mapa-nota { font-size:.8rem; color:var(--tinta-55); margin-top:.7rem; }

.perto { display:flex; flex-direction:column; gap:.6rem; margin-top:var(--gap-sm); }
.perto-item {
  display:flex; align-items:center; gap:.95rem;
  padding:.9rem 1.1rem;
  background:var(--superficie); border:1px solid var(--linha); border-radius:var(--raio-md);
  border-left:3px solid var(--luz);
}
.perto-item i { font-size:1.4rem; color:var(--travessia); flex-shrink:0; }
.perto-item b { display:block; font-size:.9rem; color:var(--tinta); }
.perto-item span { display:block; font-size:.8rem; color:var(--tinta-55); }


/* ═══ 14 · CONTATO E FORMULÁRIOS ══════════════════════════ */

.contato-grade { display:grid; grid-template-columns:.85fr 1.15fr; gap:var(--gap-lg); align-items:start; }

.contato-bloco { display:flex; gap:1rem; align-items:flex-start; padding:1.1rem 0; }
.contato-bloco + .contato-bloco { border-top:1px solid var(--linha); }
.contato-icone {
  width:44px; height:44px; flex-shrink:0; border-radius:var(--raio-md);
  background:var(--travessia-fraca); color:var(--travessia);
  display:flex; align-items:center; justify-content:center; font-size:1.3rem;
}
.contato-bloco h4 { text-transform:none; letter-spacing:.02em; font-size:.9rem; margin-bottom:.2rem; }
.contato-bloco p { font-size:.9rem; margin:0; }

.form {
  background:var(--superficie);
  border:1px solid var(--linha); border-radius:var(--raio-md);
  padding:clamp(1.5rem, 3vw, 2.4rem);
}
.campo { display:flex; flex-direction:column; gap:.35rem; margin-bottom:1rem; }
.campo label { font-size:.68rem; font-weight:700; letter-spacing:.11em; text-transform:uppercase; color:var(--tinta-55); }
.campo input, .campo select, .campo textarea {
  width:100%; min-height:48px; padding:.75rem .9rem;
  background:var(--base); color:var(--tinta);
  border:1.5px solid var(--linha); border-radius:var(--raio);
  font-family:var(--fonte-corpo); font-size:.95rem;
  outline:none; transition:border-color .22s var(--ease), background .22s var(--ease);
}
.campo textarea { min-height:130px; resize:vertical; line-height:1.55; }
.campo input:focus, .campo select:focus, .campo textarea:focus { border-color:var(--travessia); background:var(--superficie); }
.campo input::placeholder, .campo textarea::placeholder { color:rgba(12,31,43,.45); }
.campo-duplo { display:grid; grid-template-columns:1fr 1fr; gap:1rem; }

/* Opt-in do formulário de contato. Mesma regra do painel: marcado
   por padrão e obrigatório. */
.optin {
  display:flex; align-items:flex-start; gap:.65rem;
  padding:.75rem .9rem; margin:.2rem 0 1.1rem;
  background:var(--travessia-fraca); border:1.5px solid transparent; border-radius:var(--raio);
  /* Texto cheio, não --tinta-70: é uma declaração de consentimento,
     e o texto exibido tem que ser idêntico e tão legível quanto o que
     vai gravado em optin_texto. */
  font-size:.82rem; line-height:1.45; color:var(--tinta); cursor:pointer;
}
.optin input { width:17px; height:17px; margin-top:.15rem; flex-shrink:0; accent-color:var(--travessia); cursor:pointer; }
.optin--erro { background:var(--erro-bg); border-color:var(--erro); }

.form-aviso {
  display:none; align-items:center; gap:.5rem;
  padding:.85rem 1rem; margin-top:1rem; border-radius:var(--raio);
  font-size:.86rem; font-weight:600; line-height:1.4;
}
.form-aviso.mostra { display:flex; }
.form-aviso--ok  { background:var(--travessia-fraca); color:var(--travessia); border:1px solid rgba(15,106,135,.28); }
.form-aviso--err { background:var(--erro-bg); color:var(--erro-txt); border:1px solid var(--erro); }


/* ═══ 15 · FOTO PENDENTE ══════════════════════════════════ */

/* O estilo .confirmar foi removido junto com os 117 marcadores que ele
   pintava. Eram anotação interna de revisão, nunca copy de site, e
   estavam sendo renderizados em produção como tarja vermelha no meio
   das frases. Onde o dado não veio, o trecho saiu em vez de anunciar
   que está faltando. */

/* Quadro que aparece no lugar da foto enquanto o arquivo não
   existe. main.js liga a classe no onerror do <img> e escreve o
   nome esperado em data-foto — é só colocar o arquivo na pasta com
   aquele nome que a foto aparece, sem editar HTML nenhum. */
.foto-pendente { position:relative; background:var(--base); }
.foto-pendente img { opacity:0; }
.foto-pendente::after {
  content:'FOTO PENDENTE\A' attr(data-foto);
  white-space:pre;
  position:absolute; inset:0;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:.3rem; padding:1rem; text-align:center;
  font-family:var(--fonte-corpo); font-size:.66rem; font-weight:700;
  letter-spacing:.12em; line-height:2;
  color:var(--tinta-55);
  background:repeating-linear-gradient(-45deg, var(--base) 0 10px, #E7ECEF 10px 20px);
  border:1px dashed var(--linha); border-radius:inherit;
}


/* ═══ 16 · RODAPÉ ═════════════════════════════════════════ */

.rodape { background:var(--tinta); color:var(--sobre-tinta); padding:var(--gap-lg) 0 1.75rem; }
/* Cinco colunas: marca, as 5 categorias de apartamento, navegação,
   contato e atendimento. A coluna de categorias existe para o hóspede
   pular direto da página que está lendo para o apartamento do tamanho
   dele, sem passar pelo índice. */
.rodape-g { display:grid; grid-template-columns:1.5fr 1fr 1fr 1.05fr 1.05fr; gap:var(--gap-sm) var(--gap-md); }
.rodape .marca { margin-bottom:1rem; }
.rodape-sobre { font-size:.85rem; color:rgba(255,255,255,.55); max-width:32ch; }
.rodape h4 { color:rgba(255,255,255,.45); font-size:.64rem; letter-spacing:.18em; margin-bottom:1.05rem; }
.rodape-col a, .rodape-col span {
  display:flex; align-items:center; gap:.5rem;
  font-size:.85rem; color:rgba(255,255,255,.62); margin-bottom:.6rem;
  transition:color .2s;
}
.rodape-col a:hover { color:var(--luz); }
.rodape-col i { font-size:1.05rem; color:rgba(255,255,255,.4); flex-shrink:0; }

.rodape-social { display:flex; gap:.6rem; margin-top:1.35rem; }
.rodape-social a {
  width:40px; height:40px; border-radius:50%;
  background:rgba(255,255,255,.07); color:rgba(255,255,255,.7);
  display:flex; align-items:center; justify-content:center;
  transition:background .2s, color .2s;
}
.rodape-social a:hover { background:var(--luz); color:var(--tinta); }
.rodape-social svg { width:17px; height:17px; fill:currentColor; }

.rodape-pe {
  margin-top:var(--gap-md); padding-top:1.6rem;
  border-top:1px solid rgba(255,255,255,.10);
  display:flex; justify-content:space-between; align-items:center; gap:1rem; flex-wrap:wrap;
}
.rodape-pe p { font-size:.74rem; color:rgba(255,255,255,.38); margin:0; max-width:none; }
.rodape-pe a { color:var(--luz); }


/* ═══ 17 · PAINEL DE WHATSAPP ═════════════════════════════ */

/* Painel lateral ancorado acima do botão flutuante, canto DIREITO,
   SEM overlay: a página continua visível e rolável.
   Especificação em padroes/conversao.md.

   ┌── EXCEÇÃO DOCUMENTADA AO PADRÃO KOMPLEXA ──────────────┐
   │ padroes/conversao.md pede o botão secundário            │
   │ "RESERVAR AGORA ONLINE" em pílula CHAMPAGNE (#C9A96A).  │
   │ Aqui ele usa --luz (#FFC24B).                           │
   │                                                          │
   │ Motivo: champagne é herança da base Komplexa            │
   │ (navy + champagne). Este cliente não é boutique e não    │
   │ herda essa base — a paleta saiu do próprio lugar. O      │
   │ champagne ao lado de --travessia e --luz lê como um      │
   │ quarto tom sem função, e o painel é justamente onde a    │
   │ ação precisa ser inconfundível.                          │
   │                                                          │
   │ --luz é a cor de AÇÃO deste site: aparece no CTA do      │
   │ hero, no Painel de Acesso e aqui. Nada mais.             │
   │ Aprovado por Cauã em 14/08/2026.                        │
   └──────────────────────────────────────────────────────────┘

   O verde do cabeçalho NÃO é exceção: é a cor do WhatsApp e vale
   em todos os sites da Komplexa, para o hóspede reconhecer o canal
   antes de ler o título.

   A âncora inteira mora em --wl-base para que a altura máxima do
   card seja sempre "o que sobra da tela acima do botão" — é isso
   que garante que o cabeçalho verde nunca saia pelo topo. */
.wl-ov {
  --wl-verde:      #12793F;
  --wl-verde-esc:  #0E5F31;
  --wl-verde-fraco:#EAF5EE;

  --wa-btn-size:   58px;
  --wa-btn-bottom: 1.75rem;
  --wl-gap:        12px;   /* respiro entre o topo do botão e a base do card */
  --wl-margem:     12px;   /* respiro mínimo entre o topo do card e a tela */

  /* --wl-base é a folga abaixo do card SEM o teclado; --wl-anchor
     soma o teclado. A altura máxima usa a BASE porque --kx-vv-h já
     é a altura visível — somar o inset de novo encolheria o card. */
  --wl-base:   calc(var(--wa-btn-bottom) + var(--wa-btn-size) + var(--wl-gap) + var(--kx-fixed-offset, 0px));
  --wl-anchor: calc(var(--wl-base) + var(--kx-kb-inset, 0px));

  display:none; position:fixed; z-index:9600;
  right:1.75rem; bottom:var(--wl-anchor);
  width:342px; max-width:calc(100vw - 2.4rem);
  transition:bottom .3s var(--ease);
}
.wl-ov.aberto { display:block; }

/* Teclado aberto: o botão flutuante e o banner de cookies estão
   atrás dele, então o card pode usar toda a faixa que sobrou em vez
   de reservar altura para coisa invisível. main.js liga a classe
   quando o inset passa de 40px. */
.kx-kb-open .wl-ov { --wl-base:12px; }

.wl-box {
  position:relative; display:flex; flex-direction:column;
  background:var(--superficie); border-radius:14px; overflow:hidden;
  box-shadow:0 18px 60px rgba(12,31,43,.26);
  max-height:min(620px, calc(var(--kx-vv-h, 100dvh) - var(--wl-base) - var(--wl-margem)));
  transform-origin:100% 100%;
  animation:wlEntra .26s var(--ease) both;
}
@keyframes wlEntra { from { opacity:0; transform:scale(.84) translate(6px,10px); } to { opacity:1; transform:none; } }

/* Só os campos rolam: cabeçalho e rodapé ficam sempre visíveis. */
.wl-form   { display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }
.wl-scroll { flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch; padding:.85rem .9rem .7rem; }
.wl-foot   { flex:0 0 auto; background:var(--superficie); box-shadow:0 -4px 14px rgba(12,31,43,.08); padding:.55rem .9rem .65rem; }

.wl-hdr { display:flex; align-items:center; gap:.7rem; flex-shrink:0; background:var(--wl-verde); color:#fff; padding:.9rem 1rem; }
.wl-icone { width:34px; height:34px; border-radius:50%; background:rgba(255,255,255,.16); display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.wl-titulo { font-family:var(--fonte-corpo); font-size:.88rem; font-weight:700; letter-spacing:0; text-transform:none; color:#fff; margin:0; line-height:1.25; flex:1; min-width:0; }
.wl-fechar { display:flex; align-items:center; justify-content:center; flex-shrink:0; background:none; border:none; color:#fff; padding:.25rem; border-radius:8px; opacity:.9; transition:opacity .2s, background .2s; }
.wl-fechar:hover { opacity:1; background:rgba(255,255,255,.15); }
.wl-fechar:focus-visible { outline:2px solid #fff; outline-offset:2px; }

.wl-saudacao { background:var(--base); color:var(--tinta); font-size:.86rem; line-height:1.45; max-width:100%; margin:0 0 .6rem; padding:.62rem .85rem; border-radius:12px 12px 12px 2px; }

/* Três campos em container único, separados por fio. */
.wl-campos { background:var(--superficie); border:1px solid var(--linha); border-radius:10px; overflow:hidden; }
.wl-fg { display:flex; align-items:center; gap:.55rem; min-height:46px; padding:0 .85rem; transition:background .2s; }
.wl-fg + .wl-fg { border-top:1px solid var(--linha); }
.wl-fg:focus-within { background:var(--base); }
.wl-fg input { flex:1; min-width:0; background:transparent; border:none; color:var(--tinta); font-family:var(--fonte-corpo); font-size:.92rem; padding:.6rem 0; outline:none; }
/* Contraste do placeholder: rgba(12,31,43,.62) dá ~5.4:1 sobre o
   branco. O .45 usado nos formulários de página não passaria aqui,
   onde o rótulo visível É o placeholder. */
.wl-fg input::placeholder { color:rgba(12,31,43,.62); }
.wl-bandeira { display:block; flex-shrink:0; border-radius:2px; }

/* Opt-in: caixa verde clara, MARCADO por padrão e obrigatório. */
.wl-optin { display:flex; align-items:flex-start; gap:.6rem; margin:.6rem 0 0; padding:.6rem .8rem; background:var(--wl-verde-fraco); border:1px solid transparent; border-radius:10px; font-size:.78rem; line-height:1.4; color:var(--tinta); cursor:pointer; transition:background .2s, border-color .2s; }
.wl-optin input { width:16px; height:16px; margin:.1rem 0 0; flex-shrink:0; accent-color:var(--wl-verde); cursor:pointer; }
.wl-optin--erro { background:var(--erro-bg); border-color:var(--erro); }
.wl-optin-err { display:flex; align-items:center; gap:.4rem; margin:.5rem 0 0; color:var(--erro-txt); font-size:.75rem; font-weight:700; line-height:1.35; }
.wl-optin-err[hidden] { display:none; }

.wl-enviar { display:flex; align-items:center; justify-content:center; gap:.5rem; min-width:172px; margin:0 auto; background:var(--wl-verde); color:#fff; border:none; border-radius:999px; padding:.72rem 1.6rem; font-family:var(--fonte-corpo); font-size:.82rem; font-weight:700; transition:background .25s; }
.wl-enviar:hover { background:var(--wl-verde-esc); }
.wl-enviar svg { flex-shrink:0; }

.wl-ou { display:flex; align-items:center; gap:.7rem; margin:.7rem 0 .6rem; color:var(--tinta-55); font-size:.64rem; letter-spacing:.16em; text-transform:uppercase; font-weight:700; }
.wl-ou::before, .wl-ou::after { content:''; flex:1; height:1px; background:var(--linha); }

/* ↓ a exceção documentada no topo desta seção vive nesta regra ↓ */
.wl-reservar {
  display:flex; align-items:center; justify-content:center; gap:.45rem;
  width:100%; padding:.74rem;
  background:var(--luz); color:var(--tinta);
  border:none; border-radius:8px;
  font-family:var(--fonte-corpo); font-size:.72rem; font-weight:700;
  letter-spacing:.14em; text-transform:uppercase;
  transition:background .25s;
}
.wl-reservar:hover { background:#F2AF2E; }
.wl-reservar svg { flex-shrink:0; }

.wl-credito { font-size:.68rem; color:var(--tinta-55); text-align:center; margin:.45rem 0 0; }
.wl-credito a { color:var(--tinta-55); text-decoration:underline; }
.wl-credito a:hover { color:var(--tinta); }

/* Botão flutuante e balão. */
.wa-btn {
  position:fixed; z-index:8000;
  right:1.75rem; bottom:calc(1.75rem + var(--kx-fixed-offset, 0px));
  width:58px; height:58px; border-radius:50%;
  background:#25D366; color:#fff; border:none;
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 6px 22px rgba(37,211,102,.42);
  transition:transform .25s var(--ease), bottom .3s var(--ease);
}
.wa-btn:hover { transform:scale(1.08); }
.wa-btn svg { width:28px; height:28px; fill:#fff; }

.wa-balao {
  position:fixed; z-index:8001;
  right:1.75rem; bottom:calc(6rem + var(--kx-fixed-offset, 0px));
  max-width:232px; padding:.7rem 2.1rem .7rem 1rem;
  background:var(--superficie); color:var(--tinta);
  border-radius:12px; box-shadow:0 8px 26px rgba(12,31,43,.18);
  font-size:.88rem; font-weight:600; line-height:1.3;
  opacity:0; transform:translateY(8px) scale(.96); pointer-events:none;
  transition:opacity .3s var(--ease), transform .3s var(--ease), bottom .3s var(--ease);
  cursor:pointer;
}
.wa-balao.mostra { opacity:1; transform:none; pointer-events:auto; }
.wa-balao::after { content:''; position:absolute; right:18px; bottom:-7px; width:14px; height:14px; background:var(--superficie); transform:rotate(45deg); box-shadow:3px 3px 6px rgba(12,31,43,.06); }
.wa-balao-x { position:absolute; top:3px; right:5px; width:20px; height:20px; border:none; background:transparent; color:var(--tinta-55); font-size:1.15rem; line-height:1; display:flex; align-items:center; justify-content:center; }
.wa-balao-x:hover { color:var(--tinta); }
/* O balão cede lugar ao painel enquanto ele está aberto. Não é
   dispensa: volta quando o painel fecha. */
body.wl-aberto .wa-balao { opacity:0; visibility:hidden; pointer-events:none; }


/* ═══ 18 · MODAL DE RESERVA E CALENDÁRIO ══════════════════ */

.bk-modal {
  --bk-pad:16px;
  position:fixed; inset:0; z-index:9500; background:rgba(6,16,22,.62);
  display:flex; align-items:center; justify-content:center;
  padding:var(--bk-pad);
  padding-bottom:calc(var(--bk-pad) + var(--kx-kb-inset, 0px));
  opacity:0; visibility:hidden;
  transition:opacity .3s var(--ease), visibility .3s var(--ease);
}
@media (min-width:561px) { .bk-modal { --bk-pad:24px; } }
.bk-modal.aberto { opacity:1; visibility:visible; }

/* Caixa em 3 partes: cabeçalho fixo · corpo rolável · rodapé fixo.
   A altura é limitada e SÓ o corpo rola, então "Ver disponibilidade"
   fica sempre à vista, mesmo com o calendário aberto no celular. */
.bk-box {
  background:var(--superficie); width:100%; max-width:470px;
  border-radius:var(--raio-md); position:relative;
  box-shadow:var(--sombra-lg);
  display:flex; flex-direction:column;
  max-height:min(88dvh, 100%); overflow:hidden;
}
.bk-modal.aberto .bk-box { animation:bkSobe .32s var(--ease); }
@keyframes bkSobe { from { opacity:0; transform:translateY(22px); } to { opacity:1; transform:none; } }

.bk-x { position:absolute; top:.65rem; right:.65rem; z-index:3; width:34px; height:34px; border-radius:50%; background:var(--base); border:none; color:var(--tinta); font-size:1.4rem; line-height:1; display:flex; align-items:center; justify-content:center; transition:background .2s; }
.bk-x:hover { background:var(--linha); }

.bk-hdr { flex:0 0 auto; padding:1.1rem 3.2rem .8rem 1.3rem; border-bottom:1px solid var(--linha); }
.bk-hdr h3 { font-size:1.05rem; margin-bottom:.15rem; }
.bk-hdr p { font-size:.78rem; color:var(--tinta-55); margin:0; }

.bk-form { display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }
/* min-height:0 é o que autoriza este filho de flex a encolher e rolar */
.bk-body { flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch; padding:1rem 1.3rem .6rem; }
.bk-foot { flex:0 0 auto; position:sticky; bottom:0; z-index:2; background:var(--superficie); box-shadow:0 -4px 14px rgba(12,31,43,.08); padding:.8rem 1.3rem .95rem; }

.bk-campos { display:flex; gap:.5rem; flex-wrap:wrap; margin-bottom:.6rem; }
.bk-campo { flex:1; min-width:120px; border:1.5px solid var(--linha); border-radius:var(--raio); padding:.4rem .65rem; background:var(--base); transition:border-color .2s, box-shadow .2s; }
.bk-campo.ativo { border-color:var(--travessia); box-shadow:0 0 0 2px rgba(15,106,135,.18); }
.bk-campo label { display:block; font-size:.6rem; font-weight:700; text-transform:uppercase; letter-spacing:.08em; color:var(--tinta-55); margin-bottom:.05rem; }
.bk-campo input, .bk-campo select { width:100%; border:none; background:transparent; padding:0; font-family:var(--fonte-corpo); font-size:.92rem; color:var(--tinta); outline:none; }
/* Dica de próximo passo: --luz, não vermelho. É orientação, não
   erro. Declarada ANTES do --err de propósito. */
.bk-campo--proximo { border-color:var(--luz); box-shadow:0 0 0 2px rgba(255,194,75,.32); }
.bk-campo--erro { border-color:var(--erro) !important; box-shadow:0 0 0 2px rgba(198,40,40,.24); }

.bk-cal[hidden] { display:none; }
.bk-cal { margin:0 0 .4rem; }
.bk-cal-nav { display:flex; align-items:center; justify-content:space-between; margin-bottom:.15rem; }
.bk-cal-titulos { display:flex; flex:1; justify-content:center; }
.bk-cal-titulo { font-size:.82rem; font-weight:700; color:var(--tinta); }
.bk-cal-seta { width:28px; height:28px; border:1px solid var(--linha); border-radius:var(--raio); background:transparent; color:var(--tinta); font-size:1.05rem; line-height:1; transition:background .2s; }
.bk-cal-seta:hover { background:var(--base); }

/* Um mês só, com largura travada e centrado. Sem o teto, os sete dias
   esticavam na caixa inteira e o calendário virava uma grade larga e
   vazia, que é justamente o que consumia tela sem entregar nada. */
.bk-meses { display:flex; justify-content:center; }
.bk-mes { width:100%; max-width:300px; min-width:0; }
.bk-dow, .bk-grade { display:grid; grid-template-columns:repeat(7, 1fr); }
/* 6 linhas fixas = 42 células: a altura não muda ao navegar entre
   meses de 28, 30 ou 31 dias, e a caixa não pula. */
.bk-grade { grid-template-rows:repeat(6, 1fr); }
.bk-dow span { text-align:center; font-size:.56rem; letter-spacing:.05em; text-transform:uppercase; color:var(--tinta-55); padding:.1rem 0; }

.bk-dia { height:28px; display:flex; align-items:center; justify-content:center; background:transparent; border:none; font-family:var(--fonte-corpo); font-size:.82rem; color:var(--tinta); padding:0; }
.bk-dia .n { width:26px; height:26px; display:flex; align-items:center; justify-content:center; border-radius:50%; transition:background .15s; }
.bk-dia:hover:not(.off):not(.sel) .n { background:var(--base); }
/* Só o passado é apagado; dia disponível fica na cor cheia. */
.bk-dia.off { color:rgba(12,31,43,.32); cursor:default; }
.bk-dia.meio  { background:var(--luz-fraca); }
.bk-dia.ini   { background:linear-gradient(90deg, transparent 50%, rgba(255,194,75,.16) 50%); }
.bk-dia.fim   { background:linear-gradient(90deg, rgba(255,194,75,.16) 50%, transparent 50%); }
.bk-dia.unico { background:transparent; }
/* Entrada e saída: disco --luz sólido com o número ESCURO (~11:1).
   Número branco sobre o amarelo daria ~1.7:1 e reprovaria. */
.bk-dia.sel .n { background:var(--luz); color:var(--tinta); font-weight:700; }
.bk-dia.hoje:not(.sel) .n { box-shadow:inset 0 0 0 1.5px rgba(12,31,43,.32); }

.bk-resumo-l { display:flex; align-items:center; justify-content:space-between; gap:1rem; flex-wrap:wrap; margin:.6rem 0 .2rem; }
.bk-resumo { font-size:.8rem; font-weight:600; color:var(--tinta); line-height:1.35; min-width:0; }
.bk-limpar { flex:0 0 auto; padding:.35rem .8rem; font-size:.72rem; background:transparent; border:1px solid var(--linha); border-radius:var(--raio); color:var(--tinta); transition:background .2s; }
.bk-limpar:hover { background:var(--base); }

.bk-alerta { display:flex; align-items:center; gap:.45rem; background:var(--erro-bg); border:1px solid var(--erro); border-left-width:4px; border-radius:var(--raio); padding:.5rem .7rem; margin:0 0 .6rem; color:var(--erro-txt); font-size:.78rem; font-weight:700; line-height:1.3; }
.bk-alerta[hidden] { display:none; }

.bk-enviar { width:100%; min-height:50px; }
.bk-alt { text-align:center; font-size:.76rem; color:var(--tinta-55); margin:.6rem 0 0; }
.bk-alt button { background:none; border:none; color:var(--wl-verde, #12793F); font-weight:700; text-decoration:underline; font-size:inherit; }

/* As regras de dois meses lado a lado saíram junto com o segundo mês.
   A caixa não precisa mais dos 780px que existiam só para caber a
   segunda grade. */


/* ═══ 19 · BANNER DE COOKIES ══════════════════════════════ */

.kx-cookie {
  position:fixed; left:0; right:0; bottom:0; z-index:9000;
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between;
  gap:.75rem 1.75rem;
  padding:.9rem clamp(1.25rem, 5vw, 2.75rem);
  background:var(--tinta); color:rgba(255,255,255,.85);
  border-top:1px solid rgba(255,255,255,.12);
  box-shadow:0 -6px 24px rgba(12,31,43,.3);
  font-family:var(--fonte-corpo); font-size:.83rem; line-height:1.55;
  animation:kxCookieEntra .32s var(--ease) both;
}
@keyframes kxCookieEntra { from { transform:translateY(100%); } to { transform:none; } }
/* A regra global `p` tem especificidade 0,0,1 e venceria a herança:
   o texto sairia em --tinta-70 sobre --tinta, ~2:1, reprovado.
   Precisa ser redeclarado aqui, com especificidade de classe. */
.kx-cookie__text { flex:1 1 320px; max-width:70ch; margin:0; color:rgba(255,255,255,.85); font-size:.83rem; line-height:1.55; }
.kx-cookie__text a { color:var(--luz); text-decoration:underline; }
.kx-cookie__actions { display:flex; flex-wrap:wrap; gap:.6rem; flex-shrink:0; }
.kx-cookie__btn {
  display:inline-flex; align-items:center; justify-content:center;
  min-height:44px; padding:.55rem 1.6rem;
  font-size:.68rem; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  border:1px solid transparent; border-radius:var(--raio);
  transition:background .18s var(--ease), color .18s var(--ease), border-color .18s var(--ease);
}
.kx-cookie__btn--aceitar { background:var(--luz); color:var(--tinta); }
.kx-cookie__btn--aceitar:hover { background:#F2AF2E; }
.kx-cookie__btn--recusar { background:transparent; color:#fff; border-color:rgba(255,255,255,.5); }
.kx-cookie__btn--recusar:hover { background:#fff; color:var(--tinta); border-color:#fff; }
.kx-cookie__btn:focus-visible { outline:2px solid var(--luz); outline-offset:2px; }


/* ═══ 20 · RESPONSIVO ═════════════════════════════════════ */

@media (max-width:1080px) {
  /* Duas por linha: quatro colunas, ficha em duas. Com cinco fichas a
     quinta fica sozinha na terceira linha, e aqui ela vai para o meio
     pelo mesmo motivo da regra de seis colunas. */
  .fichas { grid-template-columns:repeat(4, 1fr); }
  .fichas .ficha:nth-child(4):nth-last-child(2) { grid-column:auto / span 2; }
  .fichas .ficha:nth-child(5):nth-last-child(1) { grid-column:2 / span 2; }
  /* Quatro fichas em quatro colunas dão duas linhas cheias: a regra de
     centralizar a última não tem mais o que resolver aqui. */
  .fichas .ficha:nth-child(4):nth-last-child(1) { grid-column:auto / span 2; }
  .galeria { grid-template-columns:repeat(3, 1fr); }
  /* A marca ocupa a linha inteira e as quatro colunas de links ficam
     em 2x2 embaixo: em 1080px as cinco colunas espremiam "Superior
     Quíntuplo" em duas linhas cada. */
  .rodape-g { grid-template-columns:repeat(4, 1fr); }
  .rodape-g > *:first-child { grid-column:1 / -1; }
  /* Duas colunas: a grade volta ao esquema simples e as regras de
     centragem da linha de baixo saem de cena. */
  .itens { grid-template-columns:repeat(2, 1fr); }
  .item-card, .itens:has(.item-card--largo) .item-card:nth-child(5):nth-last-child(2) { grid-column:auto; }
  .item-card--largo { grid-column:1 / -1; }
  /* Em duas colunas sobram cinco cards depois do largo, número ímpar:
     o último ficaria sozinho com metade da linha vazia ao lado. Ele
     estica e a grade fecha. */
  .itens:has(.item-card--largo) .item-card:last-child { grid-column:1 / -1; }
}

@media (max-width:900px) {
  .hero { min-height:0; padding-bottom:var(--gap-md); }

  /* ── O HERO É A TELA DE ENTRADA ──
     No celular a abertura sai e quem abre a página é o hero: a foto do
     prédio ocupando a viewport inteira, com o rótulo, o título e o
     parágrafo por cima dela.

     A mídia não é mais o <video class="hero-midia">, que é deitado e
     em tela de celular só entregaria a faixa central do quadro. É uma
     <img class="hero-foto"> com recorte retrato próprio, feito no
     arquivo original. O vídeo continua sendo a mídia do desktop.

     O SCRIM DE TRÊS GRADIENTES SAIU. Era a regra mais cara do arquivo,
     calibrada stop a stop para o texto passar em AA por cima de foto
     clara, e o preço era lavar a fachada inteira. No lugar dele
     entraram duas pontas curtas, medidas na regra do .hero::after
     logo abaixo: o meio do quadro, que é onde estão as janelas, a
     faixa branca, a placa e a fechadura de código, chega na tela sem
     perder luz.

     Isto NÃO vale no desktop: lá o hero continua com o vídeo, o scrim
     inteiro e a composição em que ele foi medido. */
  .hero-midia { display:none; }
  /* Duas pontas, e o meio do quadro fica intocado.

     Em cima, 16% da altura, e não é para o texto: é para a marca
     branca não sumir dentro do céu.

     Embaixo, a partir de 46%, para o texto. A foto tem os batentes
     brancos das duas portas e o calçadão vermelho correndo pela metade
     de baixo, e eles cruzam a área do título: medido recorte a
     recorte, em 21 posições e 7 alturas de corte, o melhor caso ainda
     deixava 4,2% do retângulo do texto abaixo de 4,5:1. Não existe
     enquadramento desta foto que dispense o degradê.

     O que ele NÃO faz é escurecer a fachada: acima de 46% a camada é
     transparente, então roof, janelas, faixa branca, placa AP
     PASSARELA e a fechadura de código chegam na tela sem perder luz.
     Os três gradientes do scrim antigo, que lavavam o quadro inteiro,
     continuam fora. */
  .hero::after {
    /* Preso à PRIMEIRA TELA, não à altura do hero. O hero é bem mais
       alto que uma tela, porque leva o painel de reservas dentro, e
       com inset:0 as porcentagens dos stops se esticavam por tudo:
       o degradê do pé caía atrás do painel, onde ninguém vê, e a marca
       ficava sem camada nenhuma. Amarrado em 100svh, cada stop cai
       onde foi calculado. */
    inset:0 0 auto 0; height:100svh;
    /* ── O degradê MUDOU DE LADO em 18/08/2026 ──
       Com o texto no pé, a camada que existia para ele não tem mais
       razão de cobrir o alto do quadro. O ganho é o que o cliente
       pediu: a fachada, a faixa branca, a placa AP PASSARELA, a
       lanterna e a FECHADURA DE CÓDIGO — que é o argumento do site —
       ficam sem camada nenhuma em cima. Os 56% de cima da foto agora
       chegam à tela com a luz que a foto tem.

       O que sobra é uma camada só, atrás do texto, e ela não é
       decoração: medida linha a linha nesta foto (900x1948, que entra
       sem corte numa tela de 375x812), a metade de baixo tem mediana
       escura, entre 0,05 e 0,22 de luminância, mas manchas claras
       pontuais — caixilho de janela, lanterna, o calçadão — que sem
       camada deixam a letra branca em 1,68:1 na faixa de 70-75% e em
       2,74:1 na de 85-90%, contra o mínimo de 4,5:1.

       O alpha de cada stop é o necessário calculado para o PIOR 5% de
       cada faixa passar em 4,5:1, não um número escolhido a olho:
       0,40 em 60-65%, 0,70 em 70-75%, 0,52 em 80-85%, 0,31 no rodapé.
       Os stops abaixo cobrem o pior de cada trecho com folga.
       Se a foto do celular for trocada, esta conta precisa ser refeita. */
    background:
      linear-gradient(180deg,
        transparent 52%,
        rgba(11,26,42,.45) 62%,
        rgba(11,26,42,.60) 66%,
        rgba(11,26,42,.75) 71%,
        rgba(11,26,42,.78) 100%);
  }
  .hero {
    min-height:100svh;
    padding-bottom:0;
    display:block;
  }
  /* Precisa vencer o body.tem-abertura .hero lá de cima, que reservava
     respiro para a barra fixa. Aqui a foto começa no pixel zero. */
  body.tem-abertura .hero { padding-top:0; }
  /* 100svh e NÃO inset:0. O hero é mais alto que uma tela, porque leva
     o painel de reservas dentro; esticar a foto por toda essa altura
     empurraria o recorte para cima e a primeira tela mostraria só céu
     e janelas, com a placa e a porta caindo atrás do painel. Presa em
     uma tela, ela aparece com o enquadramento para o qual foi cortada. */
  .hero-foto {
    display:block; position:absolute; top:0; left:0; z-index:0;
    width:100%; height:100svh;
    object-fit:cover; object-position:center;
  }
  /* O texto ocupa a primeira tela inteira e encosta no pé dela, que é
     onde a parede lisa está. justify-content:flex-end e não center: no
     meio do quadro o texto cairia em cima dos caixilhos brancos das
     janelas do segundo andar.
     O padding de baixo tira o texto de cima do calçadão, que é a única
     parte clara do recorte. */
  /* Sombra no título e no lead, a mesma camada que o painel de
     capacidade já usava quando vivia sobre a foto.

     Ela NÃO entra na conta de contraste da WCAG, e não é por isso que
     está aqui: quem faz os números passarem é o degradê do topo, e os
     números estão no comentário do .hero::after. Isto é ganho
     perceptual em cima disso, para a letra branca não perder a borda
     quando cruza os caixilhos brancos das janelas do segundo andar,
     que é o que passa por trás do título nesta composição. */
  .hero-copy h1,
  .hero-copy .lead { text-shadow:0 1px 4px rgba(11,26,42,.55); }
  /* Rótulo sem etiqueta no celular (a pedido, 18/08/2026). Na tela
     pequena a barra sólida amarela era o elemento de maior peso da
     dobra, acima do próprio h1. Fundo transparente, letra em --luz e
     corpo menor: vira sinalética, não bloco.
     A sombra entra no lugar do fundo sólido. Sem ela, texto amarelo
     fino sobre a foto some no primeiro trecho claro do recorte. */
  .hero-texto .rotulo {
    background:none;
    padding:0;
    color:var(--luz);
    font-size:.58rem;
    letter-spacing:.16em;
    margin-bottom:.6rem;
    text-shadow:0 1px 4px rgba(11,26,42,.75);
  }
  /* Texto no PÉ da primeira tela, marca no alto (invertido em
     18/08/2026, a pedido). O padding de cima agora reserva a faixa da
     logo, que subiu; o de baixo é respiro de leitura e mantém a última
     linha fora do calçadão, que é a parte clara do recorte.
     justify-content:flex-end é o que encosta o bloco no rodapé da tela:
     no meio do quadro o texto cairia sobre os caixilhos brancos das
     janelas do segundo andar. */
  .hero-copy {
    min-height:100svh;
    display:flex; flex-direction:column; justify-content:flex-end;
    padding-top:calc(var(--faixa-logo) + var(--gap-sm));
    /* 6svh e não 9: com 9 o topo do bloco subia para a faixa de 55-60%
       da foto, onde estão os caixilhos brancos do segundo andar — o pior
       ponto de contraste do quadro inteiro. Em 6svh o h1 nasce em 62%,
       que é onde o degradê já está em 0,45. */
    padding-bottom:6svh;
  }
  /* A barra empilha: rótulo, os quatro números na largura toda, CTA na
     largura toda. Em 375px a linha única do desktop caberia só cortando
     os alvos de toque abaixo de 44px. */
  .capacidade-l { display:grid; grid-template-columns:1fr; gap:.9rem; }
  .hero .triagem-opcoes { grid-template-columns:repeat(4, 1fr); }
  .capacidade-cta { width:100%; }
  /* ── O painel de reservas em tamanho de decisão ──
     Empilhado, ele nascia no tamanho MÍNIMO: botões de 52px, que é o
     piso de alvo de toque, número em 1,25rem e rótulo do tamanho do
     texto corrido. Resultado, a única coisa da home que existe para
     ser tocada tinha menos peso na tela que o parágrafo acima dela.
     Aqui ele cresce até o tamanho do trabalho que faz. Os valores são
     de tela, não de gosto: 68px de botão é o alvo confortável de
     polegar, e o número em 1,75rem é o mesmo corpo do h3 do site.
     Nada disso empurra a dobra: o que cresce são os quatro botões e o
     CTA, e os dois já ficavam abaixo dela. */
  .capacidade { margin:26px 0; }
  .capacidade-t { font-size:1.15rem; }
  .hero .triagem-opcoes { gap:.55rem; }
  .hero .triagem-op {
    min-height:68px; border-radius:12px;
    padding:.55rem .35rem .45rem;
  }
  .hero .triagem-op b { font-size:1.75rem; }
  .hero .triagem-op span { font-size:.66rem; }
  .capacidade-cta { min-height:58px; }
  .capacidade-pe { margin-top:.9rem; }
  .capacidade-pe small { font-size:.8rem; }

  /* ── O bloco de ação sai de cima da foto ──
     capacidade e pílulas viram faixa de navy chapado, de borda a
     borda, encostada no pé do hero e logo acima das vantagens.

     Por que sair da foto: é a única coisa da primeira tela que existe
     para ser tocada, e empilhada ela ocupava metade da altura do hero
     disputando atenção com a fachada. Solta em cima da imagem, lia
     como legenda da foto; em faixa própria, lê como o passo seguinte.

     A faixa é CLARA, não navy. Tentou-se navy chapado antes e ficou
     pesado: com a faixa de prova em navy no alto da tela, o hero
     escuro no meio e mais um bloco navy embaixo, a primeira rolagem
     virava três blocos escuros seguidos, e o painel lia como mais uma
     tarja em vez de ler como o passo da reserva.

     Em claro ele passa a usar a MESMA variante que já está no ar em
     /apartamentos/: número em --travessia na fonte display, botão em
     --base com fio de --linha. Nada de estilo novo, é a versão que o
     projeto já tinha para este componente sobre fundo claro, e é por
     isso que ele parece do site e não parece remendo.

     O fio de baixo separa da faixa de vantagens, que também é branca.
     Sem ele as duas leem como um bloco só.

     Contraste medido na tela depois da troca: título 16,9:1, número
     5,5:1, rótulo PESSOAS 6,0:1, "São 5 categorias" 6,3:1, VER TODAS
     6,1:1 e pílulas 6,3:1. O pior alvo sobre a foto era 4,9:1, então
     todos subiram, e o menor agora é o número, que tem 28px e só
     precisaria de 3. O text-shadow, que existia só para segurar leitura
     em cima de textura, sai junto.

     A faixa vaza o container por 100vw mais margem negativa de meia
     diferença. Percentual de margem resolve pela largura do bloco pai,
     que aqui é a largura interna do container, então a conta acerta
     sozinha em qualquer largura de tela, sem repetir o valor do
     padding do container. */
  .hero { padding-bottom:0; }
  .hero-acao {
    width:100vw; margin-left:calc(50% - 50vw);
    /* Sem respiro em cima: o .hero-copy já ocupa a tela inteira, e o
       que sobrasse aqui viraria uma tira de navy entre o pé da foto e
       a faixa clara, que lê como emenda. */
    margin-top:0;
    background:var(--superficie);
    border-bottom:1px solid var(--linha);
    padding:var(--gap-md) clamp(1.25rem, 4vw, 2.75rem);
  }
  /* O respiro de cima agora é da faixa, não da barra. */
  .hero-acao .capacidade { margin:0; }
  /* ── Da variante sobre foto para a variante sobre claro ──
     Tudo abaixo é um par de mesma especificidade com as regras
     .hero .triagem-op lá de cima, e ganha por vir depois no arquivo.
     Os valores não são inventados aqui: são os mesmos da regra base
     .triagem-op, que /apartamentos/ usa. */
  .hero-acao .capacidade-t { color:var(--tinta); }
  .hero-acao .capacidade-t,
  .hero-acao .triagem-op b,
  .hero-acao .triagem-op span,
  .hero-acao .capacidade-pe small,
  .hero-acao .capacidade-pe .link-seta { text-shadow:none; }
  .hero-acao .triagem-op {
    background:var(--base);
    border:1.5px solid var(--linha);
  }
  .hero-acao .triagem-op b {
    font-family:var(--fonte-display); font-weight:800;
    font-variation-settings:'wdth' 84;
    color:var(--travessia);
  }
  /* --tinta-70 e não o --tinta-55 da regra base. Medido na tela: em
     10,5px o --tinta-55 sobre o botão claro dá 3,72:1 e reprova em AA,
     que pede 4,5 para texto pequeno. O --tinta-70 leva a 5,9:1 sem
     mudar nada de forma. Mesmo motivo no "São 5 categorias" abaixo. */
  .hero-acao .triagem-op span { color:var(--tinta-70); }
  .hero-acao .triagem-op:hover,
  .hero-acao .triagem-op:focus-visible {
    background:var(--travessia-fraca); border-color:var(--travessia);
  }
  /* Selecionado continua amarelo com número em navy, o mesmo par do
     CTA, porque esse estado não depende do fundo. */
  .hero-acao .triagem-op:active,
  .hero-acao .triagem-op.ativo { background:var(--luz); border-color:var(--luz); }
  .hero-acao .triagem-op:active b,
  .hero-acao .triagem-op.ativo b { color:var(--tinta); }
  .hero-acao .triagem-op:active span,
  .hero-acao .triagem-op.ativo span { color:rgba(var(--tinta-rgb), .72); }
  /* O shimmer era branco sobre escuro e sumia no claro. */
  .hero-acao .triagem-op b.skeleton {
    background:linear-gradient(
      90deg,
      rgba(12,31,43,.05) 25%,
      rgba(12,31,43,.13) 50%,
      rgba(12,31,43,.05) 75%
    );
    background-size:200% 100%;
  }
  .hero-acao .capacidade-pe small { color:var(--tinta-70); }
  .hero-acao .capacidade-pe .link-seta {
    color:var(--travessia); border-bottom-color:var(--travessia);
  }
  /* As pílulas em fio claro. O ícone sai do --luz: amarelo sobre
     branco dá 1,7:1 e o ícone some. */
  .hero-acao .hero-marca { color:var(--tinta-70); border-color:var(--linha); }
  .hero-acao .hero-marca i { color:var(--travessia); }
  /* O scrim vertical do hero no celular saiu inteiro. Ele existia para
     o texto passar em AA por cima da fachada, com três gradientes
     calibrados stop a stop, e o preço era apagar a foto justamente
     onde ela aparecia. O que vale para o celular agora está mais acima
     nesta mesma media query: duas pontas curtas presas à primeira
     tela, uma atrás do título e outra atrás da marca, com o meio do
     quadro intocado.
     A calibração antiga continua viva no desktop, na regra
     .hero::after lá de cima, que é onde ela foi medida. */
  /* Strip de prova em 2x2: quatro colunas em 375px espremem
     "5 categorias, de 3 a 7 pessoas" em cinco linhas. */
  /* Volta a ser grade aqui: em 375px o flex centralizado quebraria em
     quatro linhas, e 2x2 continua sendo a forma mais compacta. */
  .prova-l { display:grid; grid-template-columns:repeat(2, 1fr); gap:.45rem .4rem; font-size:.64rem; }
  .prova-l li { padding:0 .4rem; }
  /* No 2x2 o divisor fica só entre as duas colunas, nunca entre as
     linhas: o 2º e o 4º item recebem, o 1º e o 3º não. */
  .prova-l li + li::before { content:none; }
  .prova-l li:nth-child(even)::before {
    content:''; position:absolute; left:0; top:50%;
    transform:translateY(-50%);
    width:1px; height:16px;
    background:rgba(255,255,255,.14);
  }
  .prova-l b { font-size:.95rem; }
  /* Passos em coluna única, sem divisor: empilhados, o fio vertical
     não separa nada, só sobra. */
  .passo + .passo { border-left:none; padding-left:0; }
  /* Alvo de toque garantido nos quatro números. Com a fonte atual eles
     já passam de 44px, mas isso é consequência do tamanho do dígito, e
     não vale depender disso: se a tipografia mudar, o alvo encolhe
     junto sem ninguém perceber. */
  .hero .triagem-op { min-height:44px; min-width:44px; }
  .grade-2, .contato-grade { grid-template-columns:1fr; gap:var(--gap-md); }
  /* Texto antes da foto quando a grade empilha. Com a foto em primeiro,
     o leitor recebe uma imagem sem o rótulo e sem o título por cima,
     ou seja, sem saber do que o bloco está falando, e ainda passa por
     uma legenda antes de qualquer argumento. É a mesma ordem que
     /sobre/ e /localizacao/ já usam.
     Vale só no empilhado: no desktop a composição continua com a foto
     à esquerda e o texto à direita. */
  .grade-2--texto-antes > .bloco-figura { order:2; }
  .ficha--larga { grid-template-columns:1fr; }
  .ficha--larga .ficha-foto { min-height:0; aspect-ratio:4/3; }
  .passos { grid-template-columns:1fr; gap:var(--gap-sm); }
  .passo:not(:last-child)::after { content:none; }
  /* 2x2. O divisor vertical fica só entre as duas colunas; entre as
     linhas ele vira horizontal. Sem isso o item 3 nasce com um fio na
     margem esquerda, que é o defeito de divisor solto de novo. */
  .vantagens-g { grid-template-columns:repeat(2, 1fr); }
  .vantagem:nth-child(odd) { border-left:none; }
  .vantagem:nth-child(n+3) { border-top:1px solid rgba(11,26,42,.12); }
}

@media (max-width:520px) {
  /* Coluna única: em 375px o par de colunas espremia
     "Sem recepção, sem espera, sem fila" em quatro linhas. */
  .vantagens-g { grid-template-columns:1fr; }
  .vantagem { border-left:none; }
  .vantagem + .vantagem { border-left:none; border-top:1px solid rgba(11,26,42,.12); }
}

@media (max-width:900px) {
  .outras { grid-template-columns:1fr 1fr; }
  /* Repete o seletor de três para vencer a especificidade do :has lá de
     cima, senão as três ficariam espremidas em uma linha só no celular. */
  .outras:has(> :nth-child(3):last-child) { grid-template-columns:1fr 1fr; }
}

@media (max-width:768px) {
  .itens, .grade-3, .grade-4 { grid-template-columns:1fr; }
  /* Sem largura para duas colunas, o card da cozinha empilha e o fio
     vertical vira horizontal. */
  .item-card--largo { flex-wrap:wrap; align-items:flex-start; }
  /* o texto continua ao LADO do ícone; só a lista quebra para baixo.
     Com flex-basis de 100% o ícone ficava sozinho numa linha. */
  .item-card--largo .item-card-txt { flex:1 1 auto; min-width:0; }
  .cozinha-itens {
    flex:1 1 100%;
    padding:1rem 0 0; border-left:none; border-top:1px solid var(--linha);
  }
  .item-card, .item-card--largo, .itens:has(.item-card--largo) .item-card:nth-child(5):nth-last-child(2) { grid-column:auto; }
  /* Os três números viram coluna: lado a lado em 375px o rótulo
     "CAPACIDADE" quebraria em três linhas. */
  .numeros { grid-template-columns:1fr; }
  .numero + .numero { border-left:none; border-top:1px solid var(--linha); }
  .fotos-cat { grid-template-columns:1fr; }
  .fotos-cat > *:first-child { aspect-ratio:4/3; }
  .espec { grid-template-columns:1fr; gap:.2rem; }
  .galeria { grid-template-columns:repeat(2, 1fr); }
  .rodape-g { grid-template-columns:1fr 1fr; gap:var(--gap-sm); }
  .rodape-sobre { max-width:none; }
  .mapa { height:340px; }
  .passos--lista .passo { grid-template-columns:52px 1fr; gap:1rem; }
  .passos--lista .passo-num { width:52px; height:52px; font-size:1.45rem; }

  /* iOS dá zoom quando o campo em foco tem fonte abaixo de 16px.
     Forçar 16px resolve sem mexer no user-scalable, que quebraria
     o pinch-to-zoom de quem precisa dele. */
  input, select, textarea { font-size:16px !important; }
}

@media (max-width:560px) {
  /* Coluna única: as regras de centralizar a última linha perdem o
     sentido e precisam ser desfeitas, senão a quarta e a quinta ficha
     continuariam presas na coluna 2 de uma grade que não existe mais. */
  .fichas { grid-template-columns:1fr; }
  .ficha,
  .fichas .ficha:nth-child(4):nth-last-child(2),
  .fichas .ficha:nth-child(4):nth-last-child(1),
  .fichas .ficha:nth-child(5):nth-last-child(1) { grid-column:auto; }
  .campo-duplo { grid-template-columns:1fr; }
  .chamada-botoes { flex-direction:column; }
  .chamada-botoes .btn { width:100%; }
  .rodape-g { grid-template-columns:1fr; }
  .triagem-opcoes { grid-template-columns:repeat(4, 1fr); gap:.4rem; }
  .triagem-op { padding:.75rem .2rem .65rem; }
  .triagem-op b { font-size:1.5rem; }
  .rodape-pe { flex-direction:column; text-align:center; gap:.4rem; }

  /* Painel e botão flutuante acompanham a mesma margem, senão o
     card se ancora numa posição que o botão ainda não assumiu. */
  .wa-btn   { right:1.1rem; bottom:calc(1.1rem + var(--kx-fixed-offset, 0px)); }
  .wa-balao { right:1.1rem; bottom:calc(5.2rem + var(--kx-fixed-offset, 0px)); font-size:.83rem; }
  .wl-ov {
    --wa-btn-bottom:1.1rem;
    right:1.1rem;
    width:calc(100vw - 2.2rem); max-width:380px;
  }
  .wl-box { max-height:min(85dvh, calc(var(--kx-vv-h, 100dvh) - var(--wl-base) - var(--wl-margem))); }

  /* Calendário: célula de 44x44, o mínimo de alvo de toque que
     padroes/conversao.md exige, com o disco menor dentro — a grade
     encolhe sem encolher a área clicável. Medido em 375px: o modal
     continua cabendo na tela com o calendário aberto. */
  .bk-dia { height:44px; font-size:.92rem; font-weight:600; }
  .bk-dia .n { width:34px; height:34px; }
  .bk-dia.off { font-weight:400; }
  .bk-campo:nth-child(1), .bk-campo:nth-child(2) { flex:1 1 0; min-width:0; }
  .bk-campo:nth-child(3) { flex:1 1 100%; }
  .bk-body { padding:.9rem 1rem .5rem; }
  .bk-foot { padding:.7rem 1rem .85rem; }

  .kx-cookie { flex-direction:column; align-items:stretch; gap:.6rem; padding:.75rem 1rem calc(.75rem + env(safe-area-inset-bottom)); }
  /* Em coluna o flex-basis do texto passaria a valer como ALTURA e
     esticaria a faixa para meia tela. Aqui ele não cresce nem encolhe. */
  .kx-cookie__text { flex:0 0 auto; max-width:none; font-size:.8rem; line-height:1.4; }
  /* nowrap: com wrap os dois botões quebram um por linha e a faixa
     dobra de altura, comendo a tela do celular. */
  .kx-cookie__actions { flex-wrap:nowrap; gap:.5rem; }
  .kx-cookie__btn { flex:1 1 0; min-width:0; min-height:44px; padding:.5rem .6rem; font-size:.63rem; letter-spacing:.1em; }

  .lb-btn { width:44px; height:44px; }
  .lb-ant { left:.5rem; }
  .lb-prox { right:.5rem; }
}

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

/* Exceção única à regra acima. Quem pediu menos movimento não recebe
   shimmer nem deslocamento nos números da triagem: o main.js já pula
   o esqueleto e revela os quatro de uma vez. Sobra um fade de 180ms,
   curto o bastante para não incomodar e longo o bastante para o
   número não aparecer com corte seco. */
@keyframes triagemFade { from { opacity:0; } to { opacity:1; } }
@media (prefers-reduced-motion:reduce) {
  .hero .triagem-op b.revelado {
    animation:triagemFade .18s linear both !important;
  }
}

@media print {
  .topo, .menu-mob, .wa-btn, .wa-balao, .wl-ov, .bk-modal, .kx-cookie, #lb { display:none !important; }
}
