/* ============================================================
   HOTEL {{HOTEL_NOME}} — v2
   Direção de arte: referência aprovada Hotel Colline de France
   (cinema, movimento, luxo) adaptada à identidade {{HOTEL_NOME}}.

   Ordem do arquivo (não reordenar — a cascata depende disto):
      1. Tokens             9. Estrutura / parallax
      2. Base e tipografia 10. Depoimentos
      3. Utilitários       11. CTA final
      4. Separador ornam.  12. Rodapé
      (11 = faixa .ctab: foto + véu escuro, só nas 16 internas)
      5. Botões            13. Páginas internas
      6. Header + menus    13b. Componentes das páginas novas
      7. Hero cinemático   13c. Botão flutuante "Faça sua Reserva"
      8. Acomodações       14. Widget WhatsApp (port {{AGENCIA_NOME}} — NÃO alterar)
                           15. Cookie banner LGPD
                           16. Lightbox / 16b slots / reveal / reduced-motion
   ============================================================ */

/* ============================================================
   1. TOKENS
   PALETA v3 — definida pelo cliente:
     primária   #B99470  dourado amarronzado
     secundária #D4C2AF  bege
     fundo      #F9F6F3  off-white morno
     + um escuro NEUTRO (#2d2d2d e derivados) para textos e rodapé.

   A paleta anterior (dourado #7C7C7C sobre marrom-café #323232) saiu
   do site inteiro — não deve sobrar nenhum resto dela. Continua
   valendo: SEM azul e SEM verde. A única exceção verde é o widget do
   WhatsApp (bloco 14), que é padrão {{AGENCIA_NOME}} e não é da marca.

   Por que existem DOIS dourados: o #B99470 da marca é claro demais
   para texto (2.7:1 sobre o off-white) e não passa nem os 3:1 que o
   WCAG pede para ícone e fio informativo. Ele fica para preenchimento
   (botão, pílula, chip) e para ornamento decorativo.
   Todo texto, ícone e indicador de estado em fundo claro usa
   --gold-text #9A7856, indicado pelo cliente para passar AA nos TRÊS fundos claros
   do site: off-white 5.1:1, areia 4.6:1, bege diluído 4.6:1.
   ============================================================ */
/* ============================================================
   PALETA — TODA EM ESCALA DE CINZA NEUTRA, DE PROPOSITO.
   Nenhuma cor de marca sobrou neste arquivo.

   Para aplicar a marca do hotel, troque SO os valores abaixo.
   Mantenha o mesmo nivel de contraste do cinza que esta ali:
   se o valor atual e escuro, escolha uma cor escura — senao o
   texto claro por cima some.

   As unicas cores que restam no arquivo sao funcionais e nao
   pertencem a marca: verde do WhatsApp e vermelho de erro.
   ============================================================ */
:root {
  /* Cor — marca */
  --accent:      #B99470;   /* dourado suave — primária de interação */
  --accent-lite: #D4C2AF;   /* bege — secundária: fios, brilhos, gradientes */
  --accent-deep: #9A7856;   /* dourado escuro — hover (branco por cima) */
  --gold-text:   #9A7856;   /* dourado legível sobre QUALQUER fundo claro (AA) */
  --beige:       #D4C2AF;   /* apelido de leitura para a secundária */
  --accent-soft: #EEE6DD;   /* bege diluído — fundos de destaque */
  --btn-text:    #FFFFFF;   /* texto escuro sobre dourado */

  /* Cor — neutros
     O SITE É CLARO. O escuro sobrou em três
     lugares e só neles: o rodapé, o véu do hero da home sobre a foto e
     os lightbox. Não existe mais seção de conteúdo com fundo escuro. */
  --dark:        #1C1917;   /* escuro neutro — só rodapé e lightbox */
  --dark-2:      #141110;   /* rodapé */
  --dark-3:      #0E0C0B;   /* véu do hero e fundo do lightbox */
  --taupe:       #817365;   /* taupe de apoio */
  --taupe-lite:  #AA9E92;
  --bg:          #F9F6F3;   /* off-white — fundo padrão do site */
  --surface:     #FFFFFF;   /* branco puro — alterna com o off-white */
  --surface-2:   #F3EBE2;   /* bege suave (tinta de #bdbdbd) — 3ª alternância */
  --text:        #1C1917;
  --text-muted:  #74695F;
  /* Sobre o bege cheio (#bdbdbd) o --text-muted cai para 3.3:1 e reprova.
     Este é o cinza mais claro que ainda passa AA lá (5.4:1). */
  --text-onBeige: #585048;
  --text-onDark: rgba(255,255,255,.78);
  --line:        rgba(28,25,23,.14);
  --line-onDark: rgba(255,255,255,.16);

  /* Tipografia
     Cormorant Garamond entrega o contraste alto e o ar de cinema da
     referência em tamanhos grandes — é o que Lora (do v1) não faz.
     Source Sans 3 fica no corpo, como já era. */
  --font-display: 'Cormorant Garamond', Lora, Georgia, 'Times New Roman', serif;
  --font-body:    'Source Sans 3', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  /* Ritmo — --space-xl é o padding vertical de cada seção.
     Recalibrado em revisão: estava em clamp(6rem, 11vw, 10.5rem),
     ou seja, 96px no celular e até 168px no desktop — 336px de respiro
     entre dois blocos de texto, o que deixava as páginas curtas com
     cara de vazio. A faixa agora é 48–64px no mobile e 80–120px no
     desktop, com o degrau em 1024px logo abaixo. */
  --space-xs: .5rem;
  --space-sm: 1rem;
  --space-md: 2rem;
  --space-lg: 3.25rem;
  --space-xl: clamp(3rem, 6vw, 4rem);   /* 48 → 64px */

  /* Vão entre um título e o texto que o explica. Antes cada componente
     tinha o seu, entre 1.1rem e 1.8rem, e o conjunto lia como se título
     e descrição fossem dois assuntos. São um só: o texto é a segunda
     linha da mesma frase, e o espaço tem que dizer isso.
     Recalibrado DUAS VEZES em revisão: primeiro de ~1.25rem para
     0.8rem, depois para 0.55rem — o cliente pediu mais apertado nas
     duas. Ficou colado de propósito: título e descrição leem como um
     bloco só.
     · --gap-over  sobrelinha → título
     · --gap-title título → descrição
     Onde o tipo é grande (hero, CTA), multiplicar em vez de inventar
     outro valor: um título de 5rem precisa de mais ar que um de 1.3rem,
     mas na mesma proporção.
     ⚠️ Daqui para baixo não dá para ir muito: com a Cormorant Garamond
     em 3.5rem e line-height 1.14, abaixo de ~7px a descida do "g" do
     título quase encosta na primeira linha do parágrafo. */
  --gap-over:  .42rem;
  --gap-title: .55rem;

  /* Os outros dois vãos de texto. Estes NÃO encolheram junto com os de
     cima: apertar título contra descrição junta o que é um assunto só;
     apertar parágrafo contra parágrafo, ou texto contra botão, cola o
     que é separado.
     · --gap-p    parágrafo → parágrafo
     · --gap-cta  último texto → o botão/link de saída do bloco */
  --gap-p:   1.15rem;
  --gap-cta: 2.2rem;

  /* Vão entre o BLOCO de cabeçalho (`.sec-head`: sobrelinha + título +
     descrição) e o conteúdo que ele apresenta — a grade, os cards, a
     tabela, o carrossel.
     Era `--space-lg`: 52px no celular e **64px** no desktop. Com o
     título já colado na descrição (--gap-title), esse vão virava o
     maior buraco da página e devolvia justamente a impressão que os
     tokens de cima tinham acabado de resolver: o cabeçalho lia como
     um bloco solto, não como a entrada do conteúdo. Medido em
      nas 18 páginas: aparecia 20 vezes, sempre a 64px.
     Agora 28px / 36px. Continua sendo o MAIOR dos vãos de texto
     (mais que --gap-cta), porque aqui muda o tipo de conteúdo — e é
     por isso que ele não desceu ao nível dos outros. */
  --gap-head: 1.75rem;

  --container: 1200px;
  --container-narrow: 780px;

  /* Movimento — uma curva só no site inteiro */
  --ease: cubic-bezier(.25,.46,.45,.94);
  /* Duração do reveal SEM GSAP (fallback do IntersectionObserver,
     seção 17). Espelha `ANIM.dur` em main.js — Komplexa 25/08/2026,
     de .9s para .5s junto com as entradas do GSAP, para os dois
     caminhos terem a mesma cara. Mudou lá, muda aqui. */
  --dur:  .5s;

  /* Sombra */
  --shadow:    0 4px 24px rgba(28,25,23,.08);
  --shadow-lg: 0 18px 60px rgba(28,25,23,.18);

  /* Header */
  --hdr-h: 88px;
}
@media (max-width: 768px) { :root { --hdr-h: 68px; } }

/* Degrau do ritmo vertical: do tablet grande para cima o respiro sobe
   para 80–120px. Abaixo disso vale o clamp do :root (48–64px). */
@media (min-width: 1024px) {
  :root {
    --space-lg: 4rem;
    --space-xl: clamp(5rem, 7vw, 7.5rem);   /* 80 → 120px */
    --gap-head: 2.25rem;                    /* 28 → 36px */
  }
}

/* ============================================================
   2. BASE E TIPOGRAFIA
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;          /* fallback: se o Lenis não carregar */
  -webkit-text-size-adjust: 100%;
}
/* Com o Lenis ativo o scroll suave é dele — o nativo brigaria com o dele. */
html.lenis, html.lenis body { height: auto; }
html.lenis { scroll-behavior: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }

body {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 1rem;
  line-height: 1.75;
  color: var(--text);
  background: var(--bg);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.14;
  letter-spacing: -.005em;
  color: var(--text);
}
h1 { font-size: clamp(2.6rem, 6.5vw, 5.2rem); }
h2 { font-size: clamp(2.1rem, 4.6vw, 3.5rem); }
h3 { font-size: clamp(1.35rem, 2.2vw, 1.75rem); }
h4 { font-size: 1.05rem; }

p { color: var(--text-muted); }
a { color: inherit; text-decoration: none; }
img, svg, video { display: block; max-width: 100%; }
img { height: auto; }
ul { list-style: none; }
button, input, select, textarea { font: inherit; color: inherit; }

::selection { background: var(--accent); color: var(--btn-text); }

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

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

/* Pular para o conteúdo — some até receber foco */
.skip {
  position: absolute; left: 1rem; top: -60px; z-index: 9999;
  background: var(--accent); color: var(--btn-text);
  padding: .6rem 1.2rem; border-radius: 3px; font-size: .85rem; font-weight: 600;
  transition: top .25s var(--ease);
}
.skip:focus { top: 1rem; }

/* ============================================================
   3. UTILITÁRIOS
   ============================================================ */
.container { width: 100%; max-width: var(--container); margin: 0 auto; padding: 0 1.5rem; }
.container--narrow { max-width: var(--container-narrow); }
@media (max-width: 640px) { .container { padding: 0 1.25rem; } }

/* Seção: o respiro entre blocos vem daqui, não de margens soltas */
.sec { padding: var(--space-xl) 0; position: relative; }
.sec--tight { padding: calc(var(--space-xl) * .62) 0; }
/* As TRÊS alternâncias do site claro. Não existe `.sec--dark`: foi
   removida em revisão junto com a inversão do tema. */
.sec--light { background: var(--bg); }        /* off-white — padrão */
.sec--white { background: var(--surface); }   /* branco puro */
.sec--sand  { background: var(--surface-2); } /* bege suave */

/* Bloco de destaque em bege CHEIO (#bdbdbd). Use com parcimônia — é a
   cor mais forte do site claro, e nela o --text-muted reprova contraste.
   Por isso aqui o parágrafo vai em --text-onBeige, não em --text-muted. */
.sec--beige { background: var(--beige); }
.sec--beige p { color: var(--text-onBeige); }
/* O dourado de texto dá só 3.3:1 sobre o bege cheio: a sobrelinha vira
   texto normal aqui, em vez de dourada. */
.sec--beige .overline { color: var(--text); }
/* Dourado sobre bege quase nao tem borda (1.7:1). O --accent-deep
   desenha o limite do botão (3.3:1) sem mexer no preenchimento. */
.sec--beige .btn-primary { border-color: var(--accent-deep); }
/* Pelo mesmo 1.7:1, o losango do separador sumia sobre o bege — era
   assim no antigo CTA final e ninguém notava porque ele é decorativo.
   Agora que o bege é a seção de estrutura da home, o ornamento fica no
   meio do conteúdo: escurece para o dourado profundo e volta a existir. */
.sec--beige .orn { color: var(--accent-deep); }

/* Sobrelinha dourada em versalete — assina cada seção */
.overline {
  display: block;
  font-family: var(--font-body);
  font-size: .7rem; font-weight: 600;
  letter-spacing: .28em; text-transform: uppercase;
  color: var(--gold-text);
  margin-bottom: var(--gap-over);
}

.sec-head { text-align: center; max-width: 720px; margin: 0 auto var(--gap-head); }
.sec-head p { font-size: 1.06rem; margin-top: var(--gap-title); }
.sec-head--left { text-align: left; margin-left: 0; }

.lead { font-size: clamp(1.05rem, 1.7vw, 1.22rem); line-height: 1.85; }

/* ============================================================
   4. SEPARADOR ORNAMENTAL
   Losango dourado entre dois fios que afinam nas pontas. Dourado
   sobre fundo claro, branco sobre fundo escuro (.orn--light).
   ============================================================ */
.orn {
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto; color: var(--accent);
}
.orn svg { width: clamp(150px, 26vw, 230px); height: auto; overflow: visible; }
.orn--light { color: rgba(255,255,255,.85); }
.orn--sec { margin-bottom: var(--space-md); }

/* Ornamento ENTRE o cabeçalho da seção e o conteúdo (3 lugares: duas
   seções da home e a de estrutura da /comodidades/). Estava inline com
   `margin-bottom: var(--space-lg)`, e somado ao vão do próprio
   cabeçalho punha o título a ~120px do conteúdo — de longe o pior caso
   do site. Aqui quem separa é o losango, então os dois vãos ao redor
   dele valem ~55% do `--gap-head` cada: no total ~60px, contra 36px de
   um cabeçalho sem ornamento. Se o `:has()` faltar, o cabeçalho fica
   nos 36px de sempre e nada quebra. */
.orn--head { margin-bottom: calc(var(--gap-head) * .55); }
.sec-head:has(+ .orn--head) { margin-bottom: calc(var(--gap-head) * .55); }

/* Separador entre seções: fica na borda, meio dentro meio fora */
.orn-band { padding: var(--space-lg) 0 0; background: transparent; }

/* ============================================================
   5. BOTÕES
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
  min-height: 50px; padding: .85rem 2.1rem;
  font-family: var(--font-body);
  font-size: .74rem; font-weight: 700;
  letter-spacing: .17em; text-transform: uppercase;
  border: 1.5px solid transparent; border-radius: 2px;
  cursor: pointer; position: relative; overflow: hidden;
  transition: color .45s var(--ease), border-color .45s var(--ease), background-color .45s var(--ease);
}
/* Preenchimento que sobe de baixo no hover — sem trocar cor "seca" */
.btn::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  transform: scaleY(0); transform-origin: bottom;
  transition: transform .45s var(--ease);
}
.btn:hover::after { transform: scaleY(1); }
.btn > * { position: relative; z-index: 1; }

.btn-primary { background: var(--accent); color: var(--btn-text); border-color: var(--accent); }
.btn-primary::after { background: var(--accent-deep); }
.btn-primary:hover { color: #fff; border-color: var(--accent-deep); }

.btn-outline { background: transparent; color: var(--text); border-color: var(--text); }
.btn-outline::after { background: var(--text); }
.btn-outline:hover { color: var(--bg); }

.btn-ghost { background: transparent; color: #fff; border-color: rgba(255,255,255,.55); }
.btn-ghost::after { background: #fff; }
.btn-ghost:hover { color: var(--dark); border-color: #fff; }

.btn-sm { min-height: 42px; padding: .6rem 1.5rem; font-size: .68rem; }

/* Link com fio dourado que cresce da esquerda */
.link-u {
  display: inline-block; position: relative;
  font-size: .74rem; font-weight: 700;
  letter-spacing: .17em; text-transform: uppercase;
  color: var(--gold-text); padding-bottom: .35rem;
}
.link-u::after {
  content: ''; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px;
  background: currentColor; transform: scaleX(.32); transform-origin: left;
  transition: transform .5s var(--ease);
}
.link-u:hover::after { transform: scaleX(1); }

/* ============================================================
   6. HEADER — CLARO em todas as páginas
   Antes ele nascia transparente sobre o hero e virava escuro no
   scroll. Agora é sempre off-white translúcido com blur: sobre a foto
   do hero da home ele funciona como uma faixa clara, e nas internas
   nem se nota a diferença. Um só estado visual em 13 páginas.
   O .is-solid (posto pelo JS a partir de 80px) só encorpa: opacidade
   maior, sombra e 14px a menos de altura.
   A logo aqui é a COLORIDA (logo.png). A branca só no rodapé escuro.
   ============================================================ */
.hdr {
  position: fixed; top: 0; left: 0; right: 0; z-index: 900;
  height: var(--hdr-h);
  display: flex; align-items: center;
  background: rgba(249,246,243,.90);
  backdrop-filter: saturate(140%) blur(12px);
  -webkit-backdrop-filter: saturate(140%) blur(12px);
  border-bottom: 1px solid rgba(28,25,23,.08);
  transition: background-color .4s var(--ease), border-color .4s var(--ease),
              height .4s var(--ease), box-shadow .4s var(--ease);
}
/* Estado rolado (>80px). Passou a ser BRANCO SÓLIDO com fio dourado na
   base em revisão, pela especificação da entrada em dois tempos —
   antes era off-white a 97% com um fio de dourado a 35%. Vale nas 18
   páginas, e não só nas 6 que têm a entrada em dois tempos: dois
   headers rolados diferentes no mesmo site seria pior do que a
   mudança. */
.hdr.is-solid {
  background: #fff;
  border-bottom: 2px solid var(--accent);
  box-shadow: 0 4px 22px rgba(28,25,23,.09);
  height: calc(var(--hdr-h) - 14px);
}
/* A classe `.hdr--inner` foi removida do HTML junto com esta mudança:
   com um header só, ela não tinha mais o que fazer. */

.hdr-inner {
  width: 100%; max-width: var(--container); margin: 0 auto; padding: 0 1.5rem;
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
}
.logo-link { display: flex; align-items: center; flex-shrink: 0; }

/* ---- WORDMARK EM SVG INLINE (.logo-svg) —  ----
   Substituiu o `.logo-img` (PNG) no header das 18 páginas. O PNG saiu a
   pedido da cliente e por um motivo técnico: `fill: currentColor` só
   funciona com o SVG INLINE no HTML. Em `<img src="...svg">` o arquivo
   vira documento externo e o CSS da página não alcança o traço.

   Com currentColor, a cor do wordmark passa a ser a propriedade `color`
   do elemento — muda por estado do header em uma linha, sem trocar de
   arquivo. É isso que permite dourado no header sólido e branco sobre
   foto, se um dia o header voltar a ser transparente no topo.

   ⛔ O arquivo `assets/img/brand/wordmark.svg` ainda não chegou. O que
   está no HTML é placeholder marcado — ver o comentário lá. */
.logo-svg {
  /* Komplexa 21/08/2026: era `width: 300px; height: auto`, medida do wordmark
     9:1 que nunca chegou. A logo do Apollo e 1,89:1, entao naquela caixa o
     desenho ocupava 170 dos 300px e o header, que centraliza a CAIXA, o
     jogava 65px para a esquerda do centro. Dimensionar pela ALTURA faz a
     caixa valer o desenho e a centralizacao passa a ser real. */
  display: block; width: auto; height: 55px;
  color: var(--accent);                 /* o fill herda daqui */
  transition: height .4s var(--ease), color .4s var(--ease);
}
/* No desktop a faixa inteira colapsa no scroll, então não há mais
   "wordmark menor" — a regra de largura reduzida ficou só para o
   mobile, onde nada colapsa. */
@media (max-width: 1099px) { .logo-svg, .hdr.is-solid .logo-svg { height: 46px; } }
@media (max-width: 768px)  { .logo-svg, .hdr.is-solid .logo-svg { height: 38px; } }

/* ⚠️ O BRANCO SOBRE O HERO NÃO ESTÁ LIGADO, e não é esquecimento.
   A regra pronta seria:
       .hdr:not(.is-solid) .logo-svg { color: #fff; }
   Ela pressupõe o header TRANSPARENTE no topo, que é como a referência
   funciona — mas o nosso header é claro em todas as páginas desde
   , por decisão da cliente: `.is-solid` só encorpa e encolhe,
   não troca mais de tema. Ligar o branco hoje deixaria o wordmark
   invisível sobre a faixa off-white no topo de TODAS as páginas.
   Para valer, o header precisa voltar a nascer transparente sobre o
   hero — e aí são duas mudanças, não uma. */

/* O `.logo-img` continua definido: o PNG saiu do header, mas a regra
   fica porque o bloco temporário do vídeo ainda a referencia. */
.logo-img { height: 42px; width: auto; transition: height .4s var(--ease); }
.hdr.is-solid .logo-img { height: 36px; }
@media (max-width: 768px) { .logo-img, .hdr.is-solid .logo-img { height: 32px; } }

.nav { display: none; align-items: center; gap: 1.9rem; }
@media (min-width: 1100px) { .nav { display: flex; } }

/* `.nav > a` e não `.nav a`: os links do submenu (.nav-drop a) vivem
   dentro do .nav e têm visual próprio — fundo claro, caixa baixa. */
.nav > a, .nav-top {
  position: relative;
  font-family: var(--font-body);
  font-size: .72rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--text);
  padding: .4rem 0;
  background: transparent; border: none;
  transition: color .3s var(--ease);
}
.nav-top { display: inline-flex; align-items: center; gap: .42rem; cursor: pointer; }
.nav > a::after, .nav-top::after {
  content: ''; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px;
  background: var(--gold-text); transform: scaleX(0); transform-origin: right;
  transition: transform .4s var(--ease);
}
.nav > a:hover, .nav-top:hover,
.nav-grp:hover .nav-top, .nav-grp:focus-within .nav-top { color: var(--gold-text); }
.nav > a:hover::after, .nav-top:hover::after,
.nav-grp:hover .nav-top::after, .nav-grp:focus-within .nav-top::after,
.nav > a[aria-current="page"]::after, .nav-grp.is-current .nav-top::after {
  transform: scaleX(1); transform-origin: left;
}
.nav > a[aria-current="page"], .nav-grp.is-current .nav-top { color: var(--gold-text); }

/* ---- Grupos com submenu: "O Hotel" e "Experiências" ----
   Abrem no :hover E no :focus-within, ou seja, SEM JS NENHUM — mouse e
   teclado funcionam com o main.js quebrado. O JS só espelha o estado em
   aria-expanded e fecha no Escape; a classe .open é um terceiro caminho,
   nunca o único. Fail-open, como o resto do site.

   O padding vertical (com margin negativa que o anula no layout) estica
   a área de hover do grupo até encostar no painel — sem ele o cursor
   atravessa o vão entre o botão e o submenu e o menu fecha no caminho. */
.nav-grp { position: relative; padding: 1.15rem 0; margin: -1.15rem 0; }
.nav-top svg {
  width: 9px; height: 9px; flex-shrink: 0;
  fill: none; stroke: currentColor; stroke-width: 2.4;
  stroke-linecap: round; stroke-linejoin: round;
  transition: transform .3s var(--ease);
}
.nav-grp:hover .nav-top svg, .nav-grp:focus-within .nav-top svg { transform: rotate(180deg); }

.nav-drop {
  position: absolute; top: 100%; left: -1.25rem; z-index: 5;
  min-width: 234px; padding: .55rem 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 2px solid var(--accent);
  box-shadow: var(--shadow-lg);
  opacity: 0; visibility: hidden; transform: translateY(-8px);
  transition: opacity .3s var(--ease), transform .3s var(--ease), visibility .3s var(--ease);
}
.nav-grp:hover .nav-drop, .nav-grp:focus-within .nav-drop, .nav-drop.open {
  opacity: 1; visibility: visible; transform: none;
}
.nav-drop a {
  display: block; padding: .62rem 1.35rem;
  font-size: .84rem; font-weight: 400; letter-spacing: .01em; text-transform: none;
  color: var(--text);
  border-left: 2px solid transparent;
  transition: color .3s var(--ease), background-color .3s var(--ease), border-color .3s var(--ease);
}
.nav-drop a:hover, .nav-drop a[aria-current="page"] {
  color: var(--gold-text); background: var(--accent-soft); border-left-color: var(--accent);
}

/* O CTA "Reservar" acompanha o menu: some junto quando ele vira hambúrguer
   (o menu mobile tem o seu próprio). Casar sempre com o 1100px do .nav. */
.hdr-cta { flex-shrink: 0; }
@media (max-width: 1099px) { .hdr-cta { display: none; } }

/* ============================================================
   6b. FAIXA SUPERIOR DO HEADER — wordmark centralizado
   O wordmark pediu ficar "sozinho na faixa superior, centralizado,
   com respiro de ~28px": isso é um header de DUAS LINHAS, então a
   navegação desce para a segunda.

   ⚠️ ESCOPO: este bloco faz SÓ isso. A versão anterior do header em
   duas linhas trazia junto menu em serifa, separadores dourados,
   RESERVAR colado na borda da tela e fio dourado na base — tudo aquilo
   foi desfeito a pedido e NÃO voltou aqui. A segunda linha continua
   com o menu exatamente como era.

   Só de 1100px para cima: abaixo o menu já é hambúrguer e o header de
   uma linha segue intacto.
   ============================================================ */
@media (min-width: 1100px) {
  /* 26 + 33 do wordmark + 26 + 52 da linha do menu = 137.
     ⚠️ O ARQUIVO DEFINITIVO chegou em revisão e a proporção real é
     **9.07:1** (viewBox 3543.57 x 390.62), não os 3.33:1 que o
     placeholder supunha. A 300px de largura ele tem 33px de altura,
     não 90 — por isso o header encolheu de 194 para 137. Ao mexer na
     largura do wordmark, refazer esta conta. */
  :root { --hdr-h: 137px; }

  .hdr { display: block; }
  .hdr-inner {
    position: relative; height: 100%;
    /* ⚠️ A segunda linha é FIXA (52px), não `1fr`. Com `1fr` ela toma
       toda a sobra e a primeira linha, que é `auto`, acaba espremida
       contra a altura fixa do header — o wordmark encolhia sozinho de
       420px para 338px e o respiro de 28px virava 20. Com a linha do
       menu fixa, a de cima recebe exatamente o que o wordmark pede.
       O menu ocupa 33px naturais; 52 dá área de clique confortável. */
    display: grid; grid-template-rows: auto 52px; gap: 0;
    /* `justify-items` centra o item dentro da coluna e `justify-content`
       centra a coluna dentro do header. Sem o segundo a coluna nasce
       colada à esquerda — foi o erro do primeiro teste. */
    justify-items: center; justify-content: center;
  }
  /* `max-height` com valor definido (e não `none`) porque é ele que a
     transição do colapso anima — de `none` para 0 não há animação.
     200px é folgado sobre os 142 reais da faixa: o excesso não aparece
     porque a caixa cresce até o conteúdo, não até o teto. */
  .logo-link {
    /* Komplexa 21/08/2026: a conta da faixa e --hdr-h 137 = logo + padding + 52
       do menu. Com o wordmark 9:1 original a logo tinha 33px e o respiro era
       26/26. A logo do Apollo e 1,49:1 e foi para 55px de altura, entao o
       respiro caiu para 20/10: 55+20+10 = 85, +52 = 137, fecha exato de novo.
       Assimetrico de proposito, para a logo ficar mais para baixo. */
    padding: 20px 0 10px; max-height: 200px; overflow: hidden;
    transition: max-height .4s var(--ease), padding .4s var(--ease),
                opacity .4s var(--ease), transform .4s var(--ease);
  }

  /* ---- Compacto: a faixa do wordmark COLAPSA ----
     Passados os 80px sobra só a barra do menu, com 64px. O wordmark
     não sai do DOM nem ganha `display: none` — ele fica com altura 0,
     opacidade 0 e 12px de subida, e volta pelo mesmo caminho.
     A linha 1 do grid vira 0 explícito e a 2 vira `1fr`: assim o menu
     se centra nos 64px. `1fr` aqui é seguro porque não há mais linha
     `auto` para ele espremer — foi esse conflito que, no primeiro
     teste, encolhia o wordmark sozinho. */
  .hdr.is-solid { height: 64px; }
  .hdr.is-solid .hdr-inner { grid-template-rows: 0 1fr; }
  .hdr.is-solid .logo-link {
    max-height: 0; padding: 0;
    opacity: 0; transform: translateY(-12px);
    pointer-events: none;
  }

  /* O CTA sai do fluxo para não disputar a coluna central com o menu.
     `right: 0` aqui é a borda do container (o .hdr-inner mantém o
     max-width), e não a da tela — de propósito: o bloco colado na
     borda da tela era da versão desfeita.
     O `bottom` muda com o estado porque a barra muda de altura: 1px
     centra o botão de 50px na linha de 52; 7px centra na barra de 64. */
  .hdr-cta {
    position: absolute; right: 0; bottom: 1px;
    transition: opacity .45s var(--ease), transform .45s var(--ease),
                bottom .4s var(--ease);
  }
  .hdr.is-solid .hdr-cta { bottom: 7px; }
}

/* ============================================================
   6c. ENTRADA EM DOIS TEMPOS
   No topo: só o wordmark, branco, grande, sobre header transparente.
   Passados 80px de rolagem: o header vira branco sólido, o wordmark
   encolhe e vira dourado, e menu + RESERVAR entram em cascata.

   ONDE VALE, E POR QUÊ SÓ AÍ:
   `body:has(.hero, .ghero)` — a home e as 5 páginas de categoria. São
   as únicas com topo ESCURO: o hero da home tem véu escuro e o `.ghero`
   tem um degradê de topo em rgba(14,12,11,.42) feito justamente para o
   header ler sobre foto clara.
   ⛔ As outras 12 páginas usam `.phero`, cujo véu é
   `rgba(249,246,243,.86)` — off-white. Wordmark branco ali seria branco
   sobre quase-branco, invisível. Nessas o header segue como está.

   POR QUE PENDURADO EM `.js-anim`, E NÃO NUMA CLASSE PRÓPRIA:
   três coisas de uma vez, todas do jeito que o resto do site já faz.
   (1) `.js-anim` entra pelo snippet do <head>, ANTES da primeira
   pintura — não há lampejo do header completo antes de encolher, que
   é o que aconteceria se a classe viesse no DOMContentLoaded.
   (2) O watchdog de 4s de lá remove `.js-anim` se o main.js morrer, e
   o header volta inteiro sozinho: menu escondido por CSS que nunca
   mais aparece seria exatamente o tipo de falha que a regra 2 do
   projeto proíbe.
   (3) Com `prefers-reduced-motion` a classe nunca é aplicada — então
   "mostrar tudo direto, sem transição" sai de graça, sem uma linha a
   mais.

   O `inert`/`aria-hidden` dos links é a única parte em JS
   (`initHeaderIntro`), porque atributo não se escreve por CSS.
   ============================================================ */
@media (min-width: 1100px) {
  .js-anim body:has(.hero, .ghero) .hdr:not(.is-solid) {
    background: transparent;
    backdrop-filter: none; -webkit-backdrop-filter: none;
    border-bottom-color: transparent; box-shadow: none;
    /* Sem altura nem padding próprios: desde  o estado de
       topo tem exatamente a mesma caixa do header não rolado das outras
       páginas (194px, respiro de 26). O que muda aqui é só cor e
       transparência. */
    transition: background-color .45s var(--ease), border-color .45s var(--ease),
                height .45s var(--ease), box-shadow .45s var(--ease);
  }
  /* ⛔ O WORDMARK É DOURADO EM TODO ESTADO (pedido da cliente,
     ). Aqui existia `color: #fff` para o topo escuro; saiu.
     A marca não troca mais de cor com o scroll — o que muda no header
     é só o fundo.
     Contraste conferido: o dourado sobre o véu do hero
     (rgba(14,12,11,.74)) dá **6.3:1**, folgado. É o mesmo par que a
     sobrelinha do hero já usa; não é um caso novo.
     Se o branco voltar algum dia, é esta linha:
         .js-anim body:has(.hero,.ghero) .hdr:not(.is-solid)
           .logo-svg { color: #fff; } */

  /* Menu e CTA: somem sem sair do fluxo nem do DOM. Nada de
     `display:none` — os links continuam no HTML para o rastreador e
     para o leitor de tela quando o header abre. */
  .nav > *, .hdr-cta {
    transition: opacity .45s var(--ease), transform .45s var(--ease);
  }
  .js-anim body:has(.hero, .ghero) .hdr:not(.is-solid) .nav > *,
  .js-anim body:has(.hero, .ghero) .hdr:not(.is-solid) .hdr-cta {
    opacity: 0; transform: translateY(-8px); pointer-events: none;
  }

  /* Cascata de 0.06s, da esquerda para a direita. Os atrasos moram no
     estado ABERTO: ao voltar para o topo tudo some junto, sem atraso —
     cascata na saída faria o menu "escorrer" para fora, que é o
     contrário do que a entrada quer dizer. */
  .hdr.is-solid .nav > *:nth-child(1) { transition-delay: 0s; }
  .hdr.is-solid .nav > *:nth-child(2) { transition-delay: .06s; }
  .hdr.is-solid .nav > *:nth-child(3) { transition-delay: .12s; }
  .hdr.is-solid .nav > *:nth-child(4) { transition-delay: .18s; }
  .hdr.is-solid .nav > *:nth-child(5) { transition-delay: .24s; }
  .hdr.is-solid .nav > *:nth-child(6) { transition-delay: .30s; }
  .hdr.is-solid .nav > *:nth-child(7) { transition-delay: .36s; }
  .hdr.is-solid .hdr-cta { transition-delay: .42s; }

  /* Entrada do wordmark ao carregar: fade + subida leve, 0.9s.
     Fica no `.hdr` e NÃO no `:not(.is-solid)` de propósito — assim
     roda uma vez, no carregamento, e não se repete a cada volta ao
     topo (lá quem manda é a transição de 0.45s). */
  .js-anim body:has(.hero, .ghero) .hdr .logo-svg {
    animation: hdrWordmarkIn .9s ease-out both;
  }
}
@keyframes hdrWordmarkIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* Teto de altura do wordmark, nas duas larguras. Existe porque o
   arquivo definitivo ainda não chegou e a proporção dele é
   desconhecida: se vier mais alto que o placeholder, a faixa
   superior estoura a altura fixa do header e o menu some por baixo.
   Com o teto, o SVG encolhe sozinho e nada quebra.
   ⚠️ Com o arquivo real (9.07:1), 300px de largura dão 33px de altura,
   e o teto abaixo nem chega a valer — ele fica como guarda para o dia
   em que o arquivo for trocado por outro de proporção diferente. */
.logo-svg { max-height: 55px; }
@media (max-width: 1099px) { .logo-svg { max-height: 46px; } }

/* Hambúrguer */
.ham {
  display: flex; flex-direction: column; justify-content: center; gap: 5px;
  width: 44px; height: 44px; padding: 0 9px;
  background: transparent; border: none; cursor: pointer;
}
@media (min-width: 1100px) { .ham { display: none; } }
.ham span {
  display: block; height: 1.5px; width: 100%; background: var(--text); border-radius: 2px;
  transition: transform .35s var(--ease), opacity .25s var(--ease);
}
.ham.open span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.ham.open span:nth-child(2) { opacity: 0; }
.ham.open span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* Menu mobile em tela cheia */
.mobnav {
  position: fixed; inset: 0; z-index: 890;
  background: var(--bg);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1.6rem; padding: var(--hdr-h) 1.5rem 2rem;
  opacity: 0; visibility: hidden; transform: translateY(-14px);
  transition: opacity .4s var(--ease), transform .4s var(--ease), visibility .4s var(--ease);
  overflow-y: auto;
}
.mobnav.open { opacity: 1; visibility: visible; transform: none; }
/* `> a`: os links de dentro do acordeão têm corpo menor, ver .mobnav-sub */
.mobnav > a, .mobnav-top {
  font-family: var(--font-display); font-size: 1.7rem; color: var(--text);
  transition: color .3s var(--ease);
}
.mobnav > a:hover, .mobnav > a[aria-current="page"] { color: var(--gold-text); }
.mobnav .btn { margin-top: 1rem; font-family: var(--font-body); font-size: .74rem; }

/* ---- ACORDEÃO DO MENU MOBILE ----
   FAIL-OPEN: por padrão o submenu está ABERTO. Quem o recolhe é a classe
   .is-acc, posta pelo JS em initMobileAccordion(). Se o main.js não
   carregar, o menu mobile vira uma lista longa com TODOS os links à
   vista — nunca um botão que não abre nada. */
.mobnav-grp { display: flex; flex-direction: column; align-items: center; width: 100%; }
.mobnav-top {
  display: inline-flex; align-items: center; gap: .65rem;
  background: transparent; border: none; padding: 0; cursor: pointer;
}
.mobnav-top:hover, .mobnav-grp.open .mobnav-top, .mobnav-grp.is-current .mobnav-top { color: var(--gold-text); }
.mobnav-top .mob-ico {
  width: 11px; height: 11px; flex-shrink: 0;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .35s var(--ease);
}
.mobnav-grp.open .mob-ico { transform: rotate(225deg) translate(-2px, -2px); }

.mobnav-sub {
  display: flex; flex-direction: column; align-items: center; gap: .8rem;
  padding: .95rem 0 .35rem;
}
.mobnav-sub a {
  font-family: var(--font-body); font-size: .8rem; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-muted);
  transition: color .3s var(--ease);
}
.mobnav-sub a:hover, .mobnav-sub a[aria-current="page"] { color: var(--gold-text); }

.mobnav-grp.is-acc .mobnav-sub {
  max-height: 0; padding-top: 0; padding-bottom: 0; overflow: hidden;
  transition: max-height .4s var(--ease), padding .4s var(--ease);
}
/* 380px e não 260px: o submenu de Acomodações tem 6 links (as cinco
   categorias mais "Todas"). max-height é um teto para a transição, não
   uma altura — sobrar não custa nada, faltar recorta o último link. */
.mobnav-grp.is-acc.open .mobnav-sub { max-height: 380px; padding: .95rem 0 .35rem; }

/* ============================================================
   7. HERO DA HOME — foto única, full-height
   Revisão de revisão. Saíram daqui, de propósito:
     · o vídeo de fundo e o fallback Ken Burns
     · a logo gigante (ela já está no header, agora colorido)
     · o botão "Assista ao vídeo completo" e o indicador "ROLE"
   O hotel não tem vídeo publicado; quando tiver, o caminho de volta
   está descrito em ATUALIZACOES-PENDENTES.md.

   Este é o ÚNICO lugar do site, fora o rodapé e os lightbox, onde
   ainda há escuro — e é um véu sobre a foto, para o texto branco ter
   contraste. Sem foto por trás, não haveria motivo para ele existir.
   ============================================================ */
.hero {
  position: relative; width: 100%; height: 100vh; height: 100svh;
  min-height: 560px;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; background: var(--dark-3);
}
.hero-media { position: absolute; inset: 0; z-index: 0; }
.hero-media img { width: 100%; height: 100%; object-fit: cover; }

/* Véu: mais forte no topo (onde passa o header claro, para o logo
   colorido não sumir na foto) e na base (onde fica o texto). */
.hero-veil {
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(to bottom,
      rgba(14,12,11,.55) 0%,
      rgba(14,12,11,.28) 30%,
      rgba(14,12,11,.34) 60%,
      rgba(14,12,11,.72) 100%);
}

.hero-inner {
  position: relative; z-index: 2;
  width: 100%; max-width: 940px; padding: 0 1.5rem;
  text-align: center; color: #fff;
}
.hero h1 {
  color: #fff; font-weight: 300;
  font-size: clamp(2.4rem, 5.8vw, 4.6rem);
  line-height: 1.1; letter-spacing: .01em;
  text-shadow: 0 2px 30px rgba(0,0,0,.4);
}
.hero-sub {
  margin: calc(var(--gap-title) * 1.5) auto 0; max-width: 620px;
  color: rgba(255,255,255,.9);
  font-size: clamp(.98rem, 1.5vw, 1.12rem); line-height: 1.8;
  text-shadow: 0 1px 16px rgba(0,0,0,.45);
}
.hero-actions {
  margin-top: 2.6rem;
  display: flex; flex-wrap: wrap; gap: 1rem; justify-content: center;
}

/* ============================================================
   7b. BARRA DE CONSULTA DE TARIFAS
   Um <form method="get"> apontando para o motor. Não é modal e não
   rola a página: é a regra 1 cumprida, só que com datas.

   Ela nasceu sobreposta ao hero (margin-top: -56px) e SAIU DE LÁ em
   : sobre a foto de abertura o card roubava a primeira
   imagem do hotel. Hoje a barra vive entre os painéis de acomodação e
   o mosaico de estrutura — o visitante acabou de ver as cinco
   categorias, que é quando ele quer saber o preço.

   O componente não depende de onde está: sem margem negativa e sem
   z-index de sobreposição, é uma faixa como outra qualquer. Para
   mudá-lo de lugar, mover a <section> no HTML e nada mais.
   ============================================================ */
/* O fundo é o MESMO `--surface-2` da seção de acomodações logo acima:
   sem emenda visível, a barra lê como o fecho daquele bloco em vez de
   uma quarta faixa de cor. O respiro de cima já é o padding-bottom da
   seção vizinha — daí o padding-top zerado. */
.bookbar-wrap { position: relative; background: var(--surface-2); padding: 0 0 var(--space-xl); }

.bookbar {
  display: grid; gap: 1rem;
  grid-template-columns: 1fr;
  align-items: end;
  padding: 1.6rem 1.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 2px solid var(--accent);
  box-shadow: var(--shadow-lg);
}
@media (min-width: 700px) { .bookbar { grid-template-columns: 1fr 1fr; padding: 1.7rem 1.8rem; } }
@media (min-width: 900px) { .bookbar { grid-template-columns: 1fr 1fr 1fr auto; gap: 1.3rem; } }

.bookbar-f { display: flex; flex-direction: column; gap: .5rem; min-width: 0; }
.bookbar-f label {
  font-size: .64rem; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  color: var(--gold-text);
}
.bookbar-f input, .bookbar-f select {
  width: 100%; min-height: 48px;
  padding: .6rem .85rem;
  font-family: var(--font-body); font-size: .95rem; color: var(--text);
  background: var(--bg);
  border: 1px solid var(--line); border-radius: 0;
  transition: border-color .3s var(--ease), background-color .3s var(--ease);
  /* iOS encolhe input[type=date] até o texto sumir; o appearance:none
     devolve a caixa ao tamanho que o CSS pede. */
  -webkit-appearance: none; appearance: none;
}
.bookbar-f select {
  /* a seta nativa some com o appearance:none — esta é a de volta, em SVG
     inline para não custar uma requisição. Cor #9A7856 = --gold-text. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5L6 6.5l5-5' fill='none' stroke='%239A7856' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 1rem center; background-size: 11px;
  padding-right: 2.4rem;
}
.bookbar-f input:focus, .bookbar-f select:focus {
  outline: none; border-color: var(--accent); background: var(--surface);
}
.bookbar-f input:focus-visible, .bookbar-f select:focus-visible {
  outline: 2px solid var(--gold-text); outline-offset: 2px;
}
.bookbar-go { min-height: 48px; width: 100%; }
@media (min-width: 900px) { .bookbar-go { width: auto; } }

.bookbar-nota {
  margin-top: .9rem; font-size: .76rem; line-height: 1.5;
  color: var(--text-muted); text-align: center;
}

/* ------------------------------------------------------------
   CALENDÁRIO DE INTERVALO (initDatePicker)
   O <input type="date"> nativo continua no DOM e continua sendo o que
   o formulário envia — o painel do navegador é que some. Isso não é
   detalhe: com o JS morto, `.is-enhanced` nunca é aplicada, o campo
   nativo reaparece inteiro e a consulta segue funcionando.

   Por que trocar: o painel nativo não é estilizável por CSS (nem um
   pixel), muda de cara em cada navegador e no desktop obriga a clicar
   num ícone minúsculo. Num site de hotel a escolha de datas é O gesto
   principal, então ele é feito à mão.
   ------------------------------------------------------------ */
.bookbar { position: relative; }

/* Some com o campo nativo SEM tirá-lo do formulário. `display:none`
   não serve: campo escondido assim ainda envia, mas deixa de ser
   focável por âncora e alguns navegadores ignoram o `min`. */
.bookbar-f.is-enhanced input[type="date"] {
  position: absolute; width: 1px; height: 1px;
  opacity: 0; pointer-events: none; margin: -1px;
}

.bb-trig {
  display: flex; align-items: center; gap: .6rem;
  width: 100%; min-height: 48px; padding: .6rem .85rem;
  font-family: var(--font-body); font-size: .95rem; text-align: left;
  color: var(--text); background: var(--bg);
  border: 1px solid var(--line); border-radius: 0; cursor: pointer;
  transition: border-color .3s var(--ease), background-color .3s var(--ease);
}
.bb-trig:hover { border-color: var(--accent); }
/* `.is-alvo` = a ponta que o próximo clique no calendário vai definir.
   Ela acompanha o painel: escolhido o check-in, o destaque PULA para o
   campo de check-out sozinho. Sem isso o visitante escolhia a entrada e
   nada na barra dizia que faltava a saída. */
.bb-trig.is-alvo {
  border-color: var(--accent); background: var(--surface);
  box-shadow: inset 0 -2px 0 var(--accent);
}
/* O campo pedido e ainda vazio ganha um ponto piscando, do tamanho de
   um acento — chama o olho sem virar enfeite. */
.bb-trig.is-alvo.is-empty .bb-trig-v { color: var(--gold-text); font-weight: 600; }
.bb-trig.is-alvo.is-empty::after {
  content: ''; margin-left: auto; flex-shrink: 0;
  width: 6px; height: 6px; border-radius: 50%; background: var(--accent);
  animation: bbPulso 1.6s var(--ease) infinite;
}
@keyframes bbPulso { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) {
  .bb-trig.is-alvo.is-empty::after { animation: none; }
}
.bb-trig:focus-visible { outline: 2px solid var(--gold-text); outline-offset: 2px; }
.bb-trig svg {
  width: 15px; height: 15px; flex-shrink: 0;
  fill: none; stroke: var(--gold-text); stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
}
/* Placeholder: mesmo tom do texto de apoio, para "Selecionar" não
   competir com uma data de verdade já escolhida. */
.bb-trig.is-empty .bb-trig-v { color: var(--text-muted); }

.bb-cal {
  position: absolute; top: calc(100% + 10px); left: 0; z-index: 60;
  width: 100%; padding: 1.1rem 1.2rem 1rem;
  background: var(--surface);
  border: 1px solid var(--line); border-top: 2px solid var(--accent);
  box-shadow: var(--shadow-lg);
}
@media (min-width: 720px) { .bb-cal { width: 620px; max-width: 100%; } }
/* No celular os dois meses ficam um sob o outro e o painel passa da
   tela. Rola dentro dele mesmo, sem virar modal e sem travar a página. */
@media (max-width: 719px) { .bb-cal { max-height: 72vh; overflow-y: auto; -webkit-overflow-scrolling: touch; } }
.bb-cal[hidden] { display: none; }

.bb-cal-top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-bottom: .9rem;
}
.bb-cal-hint {
  font-size: .64rem; font-weight: 700; letter-spacing: .17em; text-transform: uppercase;
  color: var(--gold-text);
}
/* Quando o painel está esperando a segunda data, a dica deixa de ser
   rótulo e vira pedido: ganha a pílula de destaque. */
.bb-cal-hint.is-pedindo {
  background: var(--accent-soft); border: 1px solid var(--beige);
  padding: .3rem .8rem; border-radius: 999px;
}
.bb-nav { display: flex; gap: .4rem; }
.bb-nav button {
  width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--line); color: var(--text);
  cursor: pointer;
  transition: border-color .3s var(--ease), background-color .3s var(--ease), color .3s var(--ease);
}
.bb-nav button:hover:not(:disabled) { border-color: var(--accent); background: var(--accent); color: var(--btn-text); }
.bb-nav button:disabled { opacity: .3; cursor: default; }
.bb-nav svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }

.bb-months { display: grid; gap: 1.6rem; grid-template-columns: 1fr; }
@media (min-width: 720px) { .bb-months { grid-template-columns: 1fr 1fr; } }
.bb-m-title {
  text-align: center; margin-bottom: .7rem;
  font-family: var(--font-display); font-size: 1.12rem; color: var(--text);
  text-transform: capitalize;
}
.bb-wd, .bb-grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.bb-wd span {
  text-align: center; padding-bottom: .45rem;
  font-size: .6rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-muted);
}
.bb-grid { gap: 2px 0; }

.bb-d {
  position: relative;
  aspect-ratio: 1; min-height: 36px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-body); font-size: .86rem; color: var(--text);
  background: transparent; border: none; cursor: pointer;
  transition: background-color .2s var(--ease), color .2s var(--ease);
}
.bb-d:disabled { color: var(--text-muted); opacity: .35; cursor: default; }
.bb-d:not(:disabled):hover { background: var(--accent-soft); }
.bb-d:focus-visible { outline: 2px solid var(--gold-text); outline-offset: -2px; }
.bb-d.is-empty { visibility: hidden; }

/* Faixa entre as duas pontas. Fundo `--accent-soft` (bege diluído):
   passa AA com o texto normal e não briga com as pontas cheias. */
.bb-d.in-range { background: var(--accent-soft); }

/* PRÉVIA: com o check-in escolhido e o check-out em aberto, passar o
   mouse (ou o foco) por um dia já pinta a faixa até ele. É o aviso mais
   direto de que o painel está esperando a segunda data. A faixa da
   prévia é a mesma da seleção; o dia sob o cursor fica em bege cheio,
   um degrau abaixo do dourado das pontas confirmadas. */
.bb-d.in-previa { background: var(--accent-soft); }
.bb-d.is-fim-previa { background: var(--beige); color: var(--text); font-weight: 600; }
/* As pontas usam o dourado CHEIO — é preenchimento, o caso em que
   #B99470 pode aparecer. O texto por cima é o mesmo dos botões. */
.bb-d.is-start, .bb-d.is-end {
  background: var(--accent); color: var(--btn-text); font-weight: 600;
}
.bb-d.is-start:hover, .bb-d.is-end:hover { background: var(--accent-deep); color: #fff; }
/* Hoje: só um ponto embaixo, para não competir com a seleção */
.bb-d.is-today::after {
  content: ''; position: absolute; bottom: 5px; left: 50%; transform: translateX(-50%);
  width: 3px; height: 3px; border-radius: 50%; background: var(--gold-text);
}
.bb-d.is-start.is-today::after, .bb-d.is-end.is-today::after { background: var(--btn-text); }

.bb-cal-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  margin-top: 1rem; padding-top: .9rem; border-top: 1px solid var(--line);
}
.bb-noites { font-size: .8rem; color: var(--text-muted); }
.bb-noites b { color: var(--text); font-weight: 600; }
.bb-cal-acts { display: flex; gap: .6rem; align-items: center; }
.bb-limpar {
  background: transparent; border: none; cursor: pointer; padding: .4rem .2rem;
  font-family: var(--font-body); font-size: .74rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted);
  transition: color .3s var(--ease);
}
.bb-limpar:hover { color: var(--gold-text); }

/* ============================================================
   8. INSTITUCIONAL + ACOMODAÇÕES
   ============================================================ */
/* Bloco institucional: texto centrado, respiro grande, sem enfeite */
.inst { text-align: center; max-width: 820px; margin: 0 auto; }
.inst h2 { margin-bottom: calc(var(--gap-title) * 1.35); }
/* ---- Ritmo dos blocos de texto: .inst e a coluna de texto do .split ----
   BUG encontrado em revisão: o `.split` nunca teve nenhuma destas
   regras. Como o reset zera a margem de tudo, na coluna de texto dele os
   parágrafos ficavam ENCOSTADOS uns nos outros e o link de saída colava
   na última linha — em 6 páginas (home, sobre, gastronomia, piscina,
   bem-estar e localização). O `.inst` tinha as regras; o `.split`, não.

   O parágrafo do CTA usa `:has()` para SUBSTITUIR o vão de parágrafo em
   vez de somar com ele. Antes, no `.inst`, os dois se acumulavam (1.4rem
   do `p + p` mais 2.4rem do link) e davam 61px — quase o dobro do que o
   bloco pedia, e fora de escala com o resto do site.
   Sem suporte a `:has()` o CTA ainda recebe `--gap-p`: menos ar do que o
   ideal, nunca zero. */
.inst p + p,
.split p + p { margin-top: var(--gap-p); }

.inst p:has(> .btn), .inst p:has(> .link-u),
.split p:has(> .btn), .split p:has(> .link-u) { margin-top: var(--gap-cta); }

/* Assinatura manuscrita/atribuição sob o texto institucional */
.inst-sign {
  margin-top: 2.2rem; font-family: var(--font-display);
  font-size: 1.15rem; font-style: italic; color: var(--gold-text);
}

/* Split imagem + texto */
.split { display: grid; gap: clamp(2.5rem, 5vw, 5rem); align-items: center; }
/* 1.15fr para a foto: meio a meio deixava a imagem do mesmo tamanho
   de um bloco de texto, e é a foto que a cliente quer grande. */
@media (min-width: 900px) { .split { grid-template-columns: 1.15fr 1fr; } }
.split--rev .split-img { order: 2; }
@media (max-width: 899px) { .split--rev .split-img { order: 0; } }
.split-img { position: relative; overflow: hidden; }
.split-img img { width: 100%; aspect-ratio: 4/5; object-fit: cover; }
@media (max-width: 899px) { .split-img img { aspect-ratio: 4/3; } }
/* Moldura dourada deslocada — detalhe de luxo, não decoração gratuita */
.split-img::after {
  content: ''; position: absolute; inset: 14px; border: 1px solid rgba(255,255,255,.35);
  pointer-events: none;
}

/* ------------------------------------------------------------
   8a. PAINÉIS EXPANSIVOS DE ACOMODAÇÃO (.panels / .panel)
   Componente da home, referência: seção de suítes do
   collinedefrance.com.br. Cinco faixas que abrem no ponteiro.

   HISTÓRICO, porque este componente já foi e voltou: saiu em
    (dependia de hover, que não existe em touch) e deu lugar
   ao carrossel de cartões; voltou no mesmo dia, a pedido do cliente,
   com o carrossel ficando SÓ na /acomodacoes/. A objeção de touch
   continua de pé e está resolvida aqui pela regra de `hover`, não
   pela de largura — ver abaixo.

   ⚠️ O SEGREDO DESTE BLOCO É ONDE CADA REGRA MORA:
   · o estado "sem texto" NÃO é o padrão. O padrão é o nome visível
     sobre gradiente; quem esconde é `(min-width:1100px) and
     (hover:hover)`. Assim, qualquer aparelho que não tenha ponteiro
     — tablet, celular, laptop com tela sensível ao toque — mostra o
     nome sem depender de nada. É a mesma ideia do fail-open do resto
     do site: o estado bonito é o condicional, o estado útil é o
     padrão.
   · a soma dos `flex` é constante (4×1 + 1×3), então os vizinhos
     comprimem sozinhos e não há salto de layout. O ativo fica com
     3/7 ≈ 43% da faixa.
   · `will-change: flex-grow` evita o tremor de passar o mouse rápido
     entre painéis. Só no desktop: em telas pequenas nada expande e
     `will-change` custa memória à toa.

   O painel inteiro é um <a>, então TODO o conteúdo é <span> e o "Ver"
   é um span estilizado — <a> dentro de <a> é inválido e quebra a
   navegação por teclado. Pela mesma razão o teclado não precisa de JS:
   `:focus-within` casa com o próprio elemento focado.

   `.panel-img` fica FORA do LB_SEL de propósito: aqui o clique navega,
   não amplia.
   ------------------------------------------------------------ */
.panels {
  /* Véu do estado de repouso e gradiente do rótulo ficam em variável
     porque o bloco 18 (reduced-motion) precisa repor o gradiente. */
  --panel-veil: linear-gradient(to top,
                  rgba(28,25,23,.72) 0%,
                  rgba(28,25,23,.34) 42%,
                  rgba(28,25,23,0) 74%);
  display: flex; flex-direction: column; gap: 2px;
}
/* No desktop os painéis ficam colados (gap 0), como na referência: a
   faixa lê como uma fita de foto contínua. O gap de 2px do empilhado
   existe só para as fotos não se fundirem uma na outra na vertical. */
.panel {
  position: relative; display: block; overflow: hidden;
  height: 180px;
}
.panel-img { position: absolute; inset: 0; display: block; }
.panel-img img {
  width: 100%; height: 100%; object-fit: cover; object-position: center;
  transition: transform .8s var(--ease);
}
/* Enquanto a foto não chega, o mesmo tratamento do hero e da faixa de
   CTA: escuro sólido por baixo e o placeholder a 20%. Sem isto o texto
   branco do painel aberto cai em cima do placeholder, que é claro, e
   fica ilegível — foi o que apareceu no teste de revisão.
   As duas regras deixam de casar sozinhas quando `tools/fotos.py
   --aplicar` tirar o `data-src`. Nada a remover depois. */
.panel-img:has(img[data-src]) {
  background: linear-gradient(160deg, #4A4239 0%, #322C26 45%, #1C1917 100%);
}
.panel-img img[data-src] { opacity: .28; }
/* Véu leve, só para uniformizar fotos de exposições diferentes */
.panel::before {
  content: ''; position: absolute; inset: 0; z-index: 1;
  background: rgba(28,25,23,.15);
  transition: background-color .8s var(--ease);
}
.panel-in {
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column;
  align-items: flex-start; justify-content: flex-end;
  padding: 1.15rem 1.25rem; text-align: left;
  background: var(--panel-veil);
  transition: opacity .5s var(--ease), transform .5s var(--ease);
}
.panel-over {
  font-family: var(--font-body); font-weight: 300;
  font-size: .64rem; letter-spacing: .22em; text-transform: uppercase;
  color: rgba(255,255,255,.82);
  margin-bottom: var(--gap-over);
}
.panel-name {
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(1.45rem, 2.2vw, 2rem); line-height: 1.14;
  color: #fff;
}
.panel-btn {
  margin-top: calc(var(--gap-cta) * .55);
  padding: 14px 34px;
  border: 1px solid rgba(255,255,255,.8); border-radius: 2px;
  background: transparent; color: #fff;
  font-family: var(--font-body); font-size: .68rem; font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase;
  transition: background-color .45s var(--ease), color .45s var(--ease),
              border-color .45s var(--ease);
}
/* O botão não é um alvo de clique próprio — o <a> é o painel inteiro —,
   mas o ponteiro pode estar sobre ele, e é aí que inverte. Sem isto o
   botão inverteria junto com a abertura do painel e a distinção entre
   "painel aberto" e "estou sobre o botão" se perderia. */
.panel-btn:hover { background: #fff; color: var(--dark); border-color: #fff; }
/* Até 768px o botão sai: em 180px de altura ele briga com o nome, e o
   painel inteiro já é clicável. */
.panel-btn { display: none; }

/* ---- Tablet (769–1099px): duas colunas ----
   Cinco painéis lado a lado em tablet dariam fatias de ~150px. O
   último ocupa a linha inteira para não sobrar buraco. */
@media (min-width: 769px) and (max-width: 1099px) {
  .panels { display: grid; grid-template-columns: repeat(2, 1fr); }
  .panel { height: 260px; }
  .panel:last-child { grid-column: 1 / -1; }
}

/* ---- Desktop (≥1100px): a faixa horizontal ----
   1100 e não 1024 para casar com o ponto em que o menu vira
   hambúrguer: são as duas peças largas do topo da página. */
@media (min-width: 1100px) {
  /* 460px é a altura medida na faixa do Colline (1140x460). O clamp
     protege telas baixas; o teto era 580px e desceu para 460px em
     , quando a cliente pediu a estrutura igual à referência. */
  .panels { flex-direction: row; height: clamp(380px, 63vh, 460px); gap: 0; }
  .panel {
    flex: 1 1 0%; min-width: 0; height: auto;
    will-change: flex-grow;
    /* 1s é a transição da referência (era .9s). */
    transition: flex 1s var(--ease);
  }
  /* flex 4 contra quatro flex 1: o aberto fica com 4/8 = METADE exata da
     faixa, que é a proporção medida no Colline. Com flex 3 dava 43%. */
  .panel:hover, .panel:focus-within { flex: 4 1 0%; }
  .panel:hover::before, .panel:focus-within::before { background: rgba(28,25,23,.45); }
  .panel:hover .panel-img img,
  .panel:focus-within .panel-img img { transform: scale(1.05); }
  .panel-btn { display: inline-block; }
}

/* ---- Só onde existe ponteiro: repouso sem texto ----
   Esta é a única regra que esconde o conteúdo. Se o aparelho não tem
   hover, nada aqui casa e o nome continua à vista. */
@media (min-width: 1100px) and (hover: hover) {
  .panel-in {
    align-items: center; justify-content: center; text-align: center;
    padding: 1.5rem;
    background: none;
    opacity: 0; transform: translateY(10px);
  }
  .panel:hover .panel-in, .panel:focus-within .panel-in {
    opacity: 1; transform: none;
    /* atraso só na entrada: o conteúdo aparece depois de a expansão
       ter começado. Na saída ele some junto, sem atraso. */
    transition-delay: .2s;
  }
}

/* ------------------------------------------------------------
   8b. MOSAICO DE ESTRUTURA (.mos / .mos-c)
   Componente da home, referência: página /estrutura do
   collinedefrance.com.br. Grid assimétrico de 5 áreas com padrão
   alternado — linha 1 com o card grande à esquerda, linha 3 invertida.

   ⚠️ Este bloco foi RECONSTRUÍDO em revisão: um corte de CSS morto
   (o dos painéis expansivos, que ficavam logo acima) levou o mosaico
   junto. Foi refeito a partir do que o CLAUDE.md documenta e das
   medidas conferidas antes do corte. Se algum detalhe fino divergir do
   original, é daí que vem.

   As colunas são `repeat(3, 1fr)`, NÃO `2fr 1fr`: é o que permite a
   inversão. Com duas colunas fixas o card grande não teria como trocar
   de lado; em três trilhas iguais, 2 = dois terços e 1 = um terço, e
   cada área escolhe o seu lado.

   ⚠️ AS MEDIDAS VIERAM DA REFERÊNCIA, MEDIDA NO NAVEGADOR:
   grade de 1140px com cards de 753 e 367 (gap 20) e linhas de 250px,
   com o card grande ocupando duas linhas. Era `repeat(5,1fr)` com
   60/40 e linhas de 340/340/520 — proporção bem mais vertical, que
   deixava o mosaico ~460px mais alto que o da referência.

   São TRÊS `grid-template-areas` (desktop, tablet, celular) e todas
   usam exatamente os mesmos 5 nomes. Ao acrescentar uma área, mexer
   nas três — no celular as áreas são declaradas explicitamente em vez
   de `areas: none`, para não depender de posicionamento automático com
   nomes órfãos.
   ------------------------------------------------------------ */
.mos {
  display: grid; gap: 20px;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 250px);
  grid-template-areas:
    "cafe  cafe  piscina"
    "cafe  cafe  gourmet"
    "recep estac estac";
}
@media (max-width: 1023px) {
  .mos {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 400px 360px 360px;
    grid-template-areas:
      "cafe    cafe"
      "piscina gourmet"
      "recep   estac";
  }
}
@media (max-width: 640px) {
  .mos {
    gap: 16px;
    grid-template-columns: 1fr;
    grid-template-rows: repeat(5, 360px);
    grid-template-areas: "cafe" "piscina" "gourmet" "recep" "estac";
  }
}
.mos-c--cafe    { grid-area: cafe; }
.mos-c--piscina { grid-area: piscina; }
.mos-c--gourmet { grid-area: gourmet; }
.mos-c--recep   { grid-area: recep; }
.mos-c--estac   { grid-area: estac; }

/* Cada card é um <a> inteiro; por isso o conteúdo lá dentro é todo
   <span> — <a> dentro de <a> é inválido e quebra o teclado. */
.mos-c {
  position: relative; overflow: hidden;
  display: block; text-decoration: none;
  min-width: 0; min-height: 0;
  background: var(--surface-2);
}
.mos-img { width: 100%; height: 100%; object-fit: cover; transition: transform .9s var(--ease); }
.mos-c:hover .mos-img, .mos-c:focus-within .mos-img { transform: scale(1.06); }

/* DOIS gradientes sobrepostos, e não um que muda: `background-image`
   não é animável, então não dá para escurecer um gradiente com
   `transition` — só sobrepor outro e animar a opacidade dele. */
.mos-c::before, .mos-c::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
}
.mos-c::before {
  background: linear-gradient(to top, rgba(14,12,11,.78) 0%, rgba(14,12,11,.20) 45%, rgba(14,12,11,0) 72%);
}
.mos-c::after {
  background: linear-gradient(to top, rgba(14,12,11,.88) 0%, rgba(14,12,11,.42) 55%, rgba(14,12,11,.12) 100%);
  opacity: 0; transition: opacity .6s var(--ease);
}
.mos-c:hover::after, .mos-c:focus-within::after { opacity: 1; }

.mos-body {
  position: absolute; z-index: 2; left: 0; right: 0; bottom: 0;
  display: block; padding: clamp(1.3rem, 2.4vw, 2rem);
  color: #fff;
}
.mos-cap {
  display: block; margin-bottom: .5rem;
  font-family: var(--font-body);
  font-size: .62rem; font-weight: 700; letter-spacing: .22em; text-transform: uppercase;
  color: var(--accent-lite);
}
.mos-title {
  display: block;
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(1.3rem, 2.2vw, 1.9rem); line-height: 1.15; color: #fff;
  transition: transform .6s var(--ease);
}
.mos-c:hover .mos-title, .mos-c:focus-within .mos-title { transform: translateY(-4px); }

/* O reveal deste componente sobe 50px, e não os 40px do padrão do
   site: especificidade (0,3,0), vence o global (0,2,0). */
.js-anim .mos-c.reveal { transform: translateY(50px); }

/* ============================================================
   9. ESTRUTURA — imagem de fundo em parallax (~60% do scroll)
   O deslocamento real é aplicado pelo GSAP/ScrollTrigger no
   .px-img; o CSS só garante a sobra de altura para ele se mover.
   ============================================================ */
/* A faixa continua com foto em parallax, mas agora o véu por cima é
   CLARO: a foto vira textura de fundo e o texto é escuro, como no
   resto do site. Era a única seção de conteúdo escura que sobrava. */
.px {
  position: relative; overflow: hidden;
  padding: calc(var(--space-xl) * 1.1) 0;
  color: var(--text); isolation: isolate;
}
.px-img {
  position: absolute; top: -22%; left: 0; width: 100%; height: 144%;
  z-index: -2; will-change: transform;
}
.px-img img { width: 100%; height: 100%; object-fit: cover; }
.px::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to bottom, rgba(249,246,243,.93), rgba(249,246,243,.90));
}
.px h2, .px h3 { color: var(--text); }
.px p { color: var(--text-muted); }

/* Contadores — o margin-top é o mesmo vão do `.sec-head` acima deles.
   Tem que ser --gap-head, e não --space-lg: as duas margens colapsam e
   vence a maior, então deixar 64px aqui anularia o aperto do cabeçalho
   nas duas páginas que têm contador (home e /sobre/). */
.counters {
  display: grid; gap: 2.5rem 1.5rem; margin-top: var(--gap-head);
  grid-template-columns: repeat(2, 1fr); text-align: center;
}
@media (min-width: 860px) { .counters { grid-template-columns: repeat(4, 1fr); } }
.counter-n {
  font-family: var(--font-display); font-size: clamp(2.6rem, 5vw, 3.9rem);
  line-height: 1; color: var(--gold-text);
}
.counter-l {
  margin-top: .7rem; font-size: .68rem; font-weight: 600;
  letter-spacing: .19em; text-transform: uppercase; color: var(--text-onDark);
}
.px .counter-l { color: var(--text-muted); }

/* ============================================================
   10. DEPOIMENTOS — carrossel com transição suave, fundo escuro
   ============================================================ */
.tst { position: relative; }
.tst-view {
  position: relative; max-width: 800px; margin: 0 auto;
  min-height: 260px;
}
.tst-slide {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center;
  opacity: 0; transform: translateY(14px); pointer-events: none;
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.tst-slide.is-active { opacity: 1; transform: none; pointer-events: auto; }
.tst-quote {
  font-family: var(--font-display); font-weight: 300; font-style: italic;
  font-size: clamp(1.3rem, 2.6vw, 1.95rem); line-height: 1.55;
  color: var(--text); max-width: 42ch;
}
.tst-mark { color: var(--gold-text); font-size: 3rem; line-height: 1; margin-bottom: .8rem; font-family: var(--font-display); }
.tst-author { margin-top: 1.8rem; }
.tst-author strong {
  display: block; font-size: .78rem; font-weight: 700;
  letter-spacing: .17em; text-transform: uppercase; color: var(--gold-text);
}
.tst-author span { font-size: .82rem; color: var(--text-muted); }
.tst-stars { display: flex; gap: .3rem; justify-content: center; margin-top: 1rem; }
.tst-stars svg { width: 15px; height: 15px; fill: var(--gold-text); }

.tst-nav { display: flex; align-items: center; justify-content: center; gap: 1.6rem; margin-top: 2.6rem; }
.tst-arrow {
  width: 46px; height: 46px; border-radius: 50%;
  background: transparent; border: 1px solid var(--line);
  color: var(--text); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: border-color .35s var(--ease), background-color .35s var(--ease), color .35s var(--ease);
}
.tst-arrow:hover { border-color: var(--accent); background: var(--accent); color: var(--btn-text); }
.tst-arrow svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.tst-dots { display: flex; gap: .55rem; }
.tst-dot {
  width: 7px; height: 7px; border-radius: 50%; padding: 0;
  background: rgba(28,25,23,.22); border: none; cursor: pointer;
  transition: background-color .35s var(--ease), transform .35s var(--ease);
}
.tst-dot.is-active { background: var(--accent); transform: scale(1.45); }

/* ============================================================
   11. CTA FINAL — faixa `.ctab` (foto + véu escuro)
   Refeito em revisão. Antes era `.sec.sec--beige` + `.cta-final`:
   bege chapado, separador ornamental solto no topo e o respiro da
   seção inteira acima do texto — muito vazio e sem hierarquia.
   Agora é uma faixa de altura fixa com foto ao fundo, véu escuro por
   cima e cinco linhas em cascata, centradas.

   Vale nas 16 páginas internas. A HOME NÃO TEM ESTE BLOCO (saiu em
    a pedido do cliente) — o bege cheio da home é o
   #estrutura, e ele continua onde está.

   Três coisas que dependem de outros lugares do arquivo:
   · a foto é um `<img>` com `data-src`, como todo slot do site, para o
     `tools/fotos.py` continuar enxergando — daí o bloco 16b desenhar
     nela o estado de "slot vazio" e o `:has()` logo abaixo pintar o
     escuro por baixo enquanto a foto não chega;
   · o parallax é o mesmo do `.px`: quem move é o GSAP, no
     `.ctab-media`, e o CSS só reserva a sobra de altura;
   · o texto é branco sobre o véu, então NADA aqui usa --gold-text
     (que é calibrado para fundo claro). Em fundo escuro o --accent
     passa AA de sobra: 6.3:1 sobre o véu.
   ============================================================ */
.ctab {
  position: relative; isolation: isolate; overflow: hidden;
  min-height: clamp(560px, 72vh, 820px);
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-lg) 0;
  text-align: center; color: #fff;
}
/* A sobra de 12% em cima e embaixo é o curso do parallax. O GSAP move
   ±8% de 124% ≈ 9.9% da faixa — sempre dentro da sobra, então a borda
   da foto nunca aparece. Mexeu num número, conferir o outro. */
.ctab-media {
  position: absolute; top: -12%; left: 0; width: 100%; height: 124%;
  z-index: -2; will-change: transform;
}
.ctab-media img { width: 100%; height: 100%; object-fit: cover; }
/* Véu chapado: o texto tem que ser legível sobre qualquer foto que o
   hotel mandar, e não dá para calibrar um degradê contra foto que
   ainda não existe. */
.ctab::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(rgba(14,12,11,.74), rgba(14,12,11,.78));
}

.ctab-in {
  width: 100%; max-width: 780px; margin: 0 auto; padding: 0 1.5rem;
  display: flex; flex-direction: column; align-items: center;
}
.ctab-over {
  font-size: .7rem; font-weight: 700; letter-spacing: .25em;
  text-transform: uppercase; color: var(--accent);
}
.ctab h2 {
  margin-top: calc(var(--gap-over) * 1.6);
  font-weight: 300; font-size: clamp(2rem, 4vw, 3.2rem);
  line-height: 1.2; max-width: 20ch; color: #fff;
}
.ctab-sub { margin-top: calc(var(--gap-title) * 1.1); max-width: 48ch; color: var(--text-onDark); }
.ctab .btn { margin-top: 2.1rem; padding: 18px 48px; }
.ctab-meta {
  margin-top: 1.6rem; font-size: .74rem; letter-spacing: .16em;
  text-transform: uppercase; color: rgba(255,255,255,.6);
}
.ctab-meta a { color: #fff; text-decoration: underline; text-underline-offset: 3px; }
.ctab-meta a:hover { color: var(--accent-lite); }

/* O reveal desta faixa sobe 30px, não os 40px do padrão do site:
   as cinco linhas entram em cascata curta e 40px dá solavanco.
   Especificidade (0,3,0) — vence o global (0,2,0), como em .mos-c. */
.js-anim .ctab-in .reveal { transform: translateY(30px); }

/* Enquanto a foto não chega, o placeholder é CLARO e deixaria o texto
   branco ilegível: por baixo dele vai um escuro sólido e ele cai para
   20% de opacidade. Mesma solução do hero da home (bloco 16b). Quando
   `tools/fotos.py --aplicar` tirar o data-src, esta regra para de
   casar sozinha — não há nada a remover depois. */
.ctab-media:has(img[data-src]) {
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(212,194,175,.2) 0%, rgba(212,194,175,0) 60%),
    linear-gradient(160deg, #4A4239 0%, #322C26 55%, #1C1917 100%);
}
.ctab-media img[data-src] { opacity: .28; }

/* ============================================================
   12. RODAPÉ
   ============================================================ */
.footer { background: var(--dark-2); color: rgba(255,255,255,.62); padding: var(--space-lg) 0 2rem; }
.ft-grid { display: grid; gap: 2.75rem; grid-template-columns: 1fr; }
@media (min-width: 700px)  { .ft-grid { grid-template-columns: 1.6fr 1fr 1fr; } }
@media (min-width: 1000px) { .ft-grid { grid-template-columns: 1.7fr 1fr 1fr 1.2fr; } }

.ft-brand img { width: 210px; height: auto; margin-bottom: 1.4rem; }
.ft-brand p { font-size: .88rem; line-height: 1.8; color: rgba(255,255,255,.6); }
.ft-brand p + p { margin-top: .9rem; }

.ft-col h4 {
  font-family: var(--font-body); color: #fff;
  font-size: .68rem; font-weight: 700; letter-spacing: .21em; text-transform: uppercase;
  /* Era 1.3rem (20.8px) — o maior vão título→texto do site inteiro, em
     todas as 18 páginas. O primeiro link já traz .32rem de padding
     próprio, então o vão ótico é maior do que o número diz. */
  margin-bottom: calc(var(--gap-title) * 1.4);
}
.ft-col a {
  display: block; font-size: .89rem; padding: .32rem 0;
  color: rgba(255,255,255,.62);
  transition: color .3s var(--ease), transform .3s var(--ease);
}
.ft-col a:hover { color: var(--accent); transform: translateX(3px); }
.ft-ico { display: flex !important; align-items: center; gap: .6rem; }
.ft-ico svg { flex-shrink: 0; }
/* Os contatos migraram da 4ª coluna para o bloco da marca: lá não existe
   a regra `.ft-col a`, então cor e espaçamento vêm daqui. */
.ft-brand .ft-ico {
  margin-top: .75rem; font-size: .88rem;
  color: rgba(255,255,255,.62);
  transition: color .3s var(--ease);
}
.ft-brand .ft-ico:hover { color: var(--accent); }

.ft-bot {
  border-top: 1px solid rgba(255,255,255,.1);
  margin-top: var(--space-lg); padding-top: 1.8rem;
  display: flex; flex-direction: column; gap: .6rem;
  font-size: .78rem; color: rgba(255,255,255,.42); text-align: center;
}
@media (min-width: 768px) { .ft-bot { flex-direction: row; justify-content: space-between; text-align: left; } }
/* Assinatura {{AGENCIA_NOME}} — dourado #B99470, com link e UTMs */
.ft-bot a { color: var(--accent); }
.ft-bot a:hover { color: var(--accent-lite); }

/* ============================================================
   13. PÁGINAS INTERNAS
   ============================================================ */
/* Hero curto das internas */
/* CLARO desde . A foto continua lá, mas sob um véu off-white:
   o texto é escuro, como no resto do site. O único hero que ainda tem
   véu escuro é o da home, porque lá a foto é o assunto. */
/* 72svh, e não os 52vh de antes: a cliente pediu foto grande em todo
   o site, no espírito da referência. Fica abaixo da tela cheia de
   propósito — aqui o título e a chamada ficam DENTRO do hero, e a
   fresta de conteúdo embaixo é o que diz que a página continua. */
.phero {
  position: relative; min-height: 72vh; min-height: 72svh;
  display: flex; align-items: flex-end;
  padding: calc(var(--hdr-h) + 3rem) 0 3.5rem;
  overflow: hidden; background: var(--bg);
}
.phero-img { position: absolute; inset: 0; z-index: 0; }
.phero-img img { width: 100%; height: 100%; object-fit: cover; }
/* Komplexa 21/08/2026: o veu original ia de 80% a 94% de opacidade e a foto
   praticamente sumia. Usava tambem o branco frio antigo, rgba(246,246,246),
   que escapou da troca de paleta por ser rgba e nao hex.

   O texto do topo fica na BASE da faixa, e o terco inferior das quatro fotos
   de topo tem luminancia media entre 44 e 145 -- e escuro. Medido foto a foto:
   com o texto na tinta, o veu pode cair ate 0,46 ali embaixo e ainda passar
   AA 4,5:1. Com o cinza claro anterior precisaria de 0,95.

   Por isso o gradiente abre no topo, onde nao ha texto, e so fecha nos ultimos
   25%. A foto aparece na maior parte da faixa. */
.phero::after {
  content: ''; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to bottom,
    rgba(249,246,243,.30) 0%,
    rgba(249,246,243,.36) 40%,
    rgba(249,246,243,.70) 75%,
    rgba(249,246,243,.92) 100%);
}
.phero .container { position: relative; z-index: 2; }
.phero h1 { color: var(--text); font-weight: 300; }
/* Sobre foto, o --text-muted da 1,5:1 e some. Estes tres vao na tinta.
   O dourado do rotulo tambem nao sobrevive: passaria a exigir #2F1D0C,
   que ja nao le como dourado. Ele continua dourado no resto da pagina. */
.phero p { color: var(--text); max-width: 58ch; margin-top: var(--gap-title); }
.phero .crumbs { color: var(--text); }
.phero .overline { color: var(--text); }

/* Migalhas */
.crumbs { font-size: .74rem; color: var(--text-muted); margin-bottom: 1.2rem; letter-spacing: .05em; }
.crumbs a { color: var(--text); }
.crumbs a:hover { color: var(--gold-text); }
.crumbs span { margin: 0 .45rem; opacity: .5; }

/* Faixa "em todas as acomodações" */
.incl {
  background: var(--accent-soft); border: 1px solid rgba(185,148,112,.3);
  padding: 2.2rem 2rem; margin-bottom: var(--space-lg);
}
.incl h3 { margin-bottom: var(--gap-title); font-size: 1.3rem; }
.incl ul { display: grid; gap: .7rem 1.6rem; grid-template-columns: 1fr; }
@media (min-width: 640px)  { .incl ul { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .incl ul { grid-template-columns: repeat(3, 1fr); } }
.incl li { position: relative; padding-left: 1.5rem; font-size: .92rem; color: var(--text-muted); }
.incl li::before {
  content: ''; position: absolute; left: 0; top: .62em;
  width: 7px; height: 7px; transform: rotate(45deg); background: var(--gold-text);
}

/* Os antigos .rgroup / .room-c / .room-pill / .rooms-cols saíram em
   : agrupavam as acomodações por capacidade (2/3/4 hóspedes) e
   foram substituídos pelas fichas .rcat do bloco 13b, uma por categoria. */

/* Galeria */
.gal-filters { display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center; margin-bottom: var(--space-lg); }
.fbtn {
  background: transparent; border: 1px solid var(--line);
  padding: .55rem 1.3rem; cursor: pointer; border-radius: 999px;
  font-size: .68rem; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-muted);
  transition: all .35s var(--ease);
}
.fbtn:hover { border-color: var(--accent); color: var(--gold-text); }
.fbtn.active { background: var(--accent); border-color: var(--accent); color: var(--btn-text); }

/* Uma coluna a menos em cada faixa (era 2/3/4): com 34 fotos, quatro
   colunas davam miniatura de álbum, não galeria de hotel. Em três, a
   mesma foto fica ~33% maior sem mudar o aspecto. */
.gal-g { display: grid; gap: 1rem; grid-template-columns: repeat(2, 1fr); }
@media (min-width: 760px)  { .gal-g { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .gal-g { grid-template-columns: repeat(3, 1fr); } }
.gi { position: relative; overflow: hidden; aspect-ratio: 4/3; background: var(--surface-2); }
.gi img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .8s ease;      /* mesmo hover dos cards */
}
.gi:hover img { transform: scale(1.06); }
.gi::after {
  content: '⊕'; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(14,12,11,.42); color: #fff; font-size: 1.6rem;
  opacity: 0; transition: opacity .45s var(--ease);
}
.gi:hover::after, .gi:focus-visible::after { opacity: 1; }
.gi.zoomable { cursor: zoom-in; }

/* Formulários */
.form-card { background: var(--surface); border: 1px solid var(--line); padding: clamp(1.8rem, 4vw, 3rem); }
/* Estava inline no HTML da /contato/, com `margin-bottom: 1.6rem` — 26px,
   o maior vão título → conteúdo que sobrou depois da passada de
   , e o único que ainda era um número solto. */
.form-card h2 { font-size: 1.7rem; margin-bottom: calc(var(--gap-title) * 1.6); }
.fg { margin-bottom: 1.3rem; }
.fg label {
  display: block; font-size: .68rem; font-weight: 700;
  letter-spacing: .15em; text-transform: uppercase; color: var(--text-muted);
  margin-bottom: .5rem;
}
.fg input, .fg select, .fg textarea {
  width: 100%; padding: .85rem 1rem; min-height: 48px;
  background: var(--bg); border: 1px solid var(--line); border-radius: 2px;
  font-size: 16px;                      /* 16px trava o zoom do Safari iOS */
  transition: border-color .3s var(--ease), background-color .3s var(--ease);
}
.fg textarea { min-height: 140px; resize: vertical; line-height: 1.7; }
.fg input:focus, .fg select:focus, .fg textarea:focus {
  outline: none; border-color: var(--accent); background: var(--surface);
}
.fg input.invalid, .fg textarea.invalid { border-color: #c0392b; background: #fff5f4; }
.form-row { display: grid; gap: 0 1.2rem; grid-template-columns: 1fr; }
@media (min-width: 620px) { .form-row { grid-template-columns: 1fr 1fr; } }
.form-ok {
  display: none; margin-top: 1.2rem; padding: 1rem 1.2rem;
  background: var(--accent-soft); border-left: 3px solid var(--accent);
  font-size: .92rem; color: var(--text);
}
.form-ok.show { display: block; }
.form-err {
  display: none; margin-top: 1.2rem; padding: 1rem 1.2rem;
  background: #fff5f4; border-left: 3px solid #c0392b;
  font-size: .92rem; color: #8e2b20;
}
.form-err.show { display: block; }
/* Enquanto o POST para o n8n nao volta, o botao fica travado: sem isso o
   visitante clica duas vezes e o lead entra duplicado na planilha. */
.btn[disabled], .btn.is-loading { opacity: .55; cursor: wait; pointer-events: none; }
.form-note { font-size: .78rem; color: var(--text-muted); margin-top: 1rem; line-height: 1.6; }

/* Blocos de contato / info */
.info-grid { display: grid; gap: 1.5rem; grid-template-columns: 1fr; }
@media (min-width: 700px) { .info-grid { grid-template-columns: repeat(2, 1fr); } }
.info-card { background: var(--surface); border: 1px solid var(--line); padding: 1.7rem 1.8rem; }
.info-card svg { width: 24px; height: 24px; stroke: var(--gold-text); fill: none; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; margin-bottom: .9rem; }
.info-card h3 { font-size: 1.15rem; margin-bottom: var(--gap-title); }
.info-card p, .info-card a { font-size: .93rem; color: var(--text-muted); line-height: 1.7; }
.info-card a:hover { color: var(--gold-text); }
/* `.info-card a` é (0,1,1) e venceria `.btn` (0,1,0): sem estas duas linhas
   o botão "Como chegar" herda corpo de parágrafo e perde o hover invertido. */
.info-card .btn { font-size: .68rem; line-height: 1; color: var(--text); }
.info-card .btn:hover { color: var(--bg); }

/* Mapa */
.map-wrap { position: relative; width: 100%; aspect-ratio: 16/9; min-height: 340px; background: var(--surface-2); overflow: hidden; }
.map-wrap iframe { width: 100%; height: 100%; border: 0; display: block; }

/* Lista de referências próximas */
.near { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); grid-template-columns: 1fr; }
@media (min-width: 700px) { .near { grid-template-columns: repeat(2, 1fr); } }
.near-i { background: var(--surface); padding: 1.3rem 1.6rem; display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; }
.near-i span:first-child { font-size: .96rem; color: var(--text); }
.near-i span:last-child { font-size: .8rem; letter-spacing: .1em; text-transform: uppercase; color: var(--gold-text); white-space: nowrap; }

/* FAQ */
.faq { max-width: 800px; margin: 0 auto; }
.faq-i { border-bottom: 1px solid var(--line); }
.faq-q {
  width: 100%; background: transparent; border: none; cursor: pointer;
  display: flex; justify-content: space-between; align-items: center; gap: 1.5rem;
  padding: 1.5rem 0; text-align: left;
  font-family: var(--font-display); font-size: 1.16rem; color: var(--text);
  transition: color .3s var(--ease);
}
.faq-q:hover { color: var(--gold-text); }
.faq-q .faq-ico {
  flex-shrink: 0; width: 22px; height: 22px; position: relative;
}
/* Indica estado (aberto/fechado), entao segue a regra de 3:1 — por isso
   --gold-text e nao --accent. */
.faq-q .faq-ico::before, .faq-q .faq-ico::after {
  content: ''; position: absolute; background: var(--gold-text); transition: transform .4s var(--ease);
}
.faq-q .faq-ico::before { top: 50%; left: 0; width: 100%; height: 1.5px; transform: translateY(-50%); }
.faq-q .faq-ico::after  { left: 50%; top: 0; width: 1.5px; height: 100%; transform: translateX(-50%); }
.faq-i.open .faq-q .faq-ico::after { transform: translateX(-50%) rotate(90deg); }
.faq-a { max-height: 0; overflow: hidden; transition: max-height .5s var(--ease); }
.faq-a p { padding: 0 0 1.5rem; font-size: .96rem; max-width: 68ch; }

/* Texto corrido (privacidade) */
.prose { max-width: 780px; margin: 0 auto; }
.prose h2 { font-size: 1.55rem; margin: 2.6rem 0 var(--gap-title); }
.prose h3 { font-size: 1.2rem; margin: 2rem 0 calc(var(--gap-title) * .8); }
.prose p, .prose li { font-size: .97rem; line-height: 1.85; color: var(--text-muted); }
.prose p { margin-bottom: 1.1rem; }
.prose ul { padding-left: 1.4rem; margin-bottom: 1.2rem; list-style: disc; }
.prose li { margin-bottom: .45rem; }
.prose a { color: var(--gold-text); text-decoration: underline; }

/* Linha de saida ao fim de um bloco de texto. Komplexa 21/08/2026: o
   template deixava esses <p> com texto de chamada e sem link nenhum --
   21 frases do tipo "Ver as acomodacoes." que nao levavam a lugar
   algum. Agora sao <a>, e a cor vem de --gold-text para acompanhar a
   paleta em vez de ficar cravada. */
.lnk-saida {
  color: var(--gold-text); text-decoration: underline;
  text-underline-offset: .22em; text-decoration-thickness: 1px;
  transition: color .25s var(--ease);
}
.lnk-saida:hover, .lnk-saida:focus-visible { color: var(--accent-deep); }
.prose strong { color: var(--text); }

/* Aviso de conteúdo pendente — usado nas seções que esperam texto do
   cliente (Política do Hotel, Avaliações). Deliberadamente feio e
   visível: é para NÃO passar despercebido numa revisão antes do ar. */
.todo {
  border: 1px dashed var(--accent);
  background: var(--accent-soft);
  padding: 1.1rem 1.3rem; margin: 1.2rem 0;
  font-size: .88rem; line-height: 1.6; color: var(--text-muted);
}
.todo strong {
  display: block; color: var(--gold-text);
  font-size: .68rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  margin-bottom: .4rem;
}

/* ============================================================
   13b. COMPONENTES DAS PÁGINAS NOVAS
   Comodidades, Piscina, Gastronomia, Centro de Bem-Estar, Avaliações
   e Política do Hotel (escopo de revisão).

   ⚠️ ORDEM: este bloco precisa ficar ANTES do 16b. `.rcat-hero img`,
   `.mcard-media img` e `.amen-i img` têm a mesma especificidade (0,1,1)
   do `img[data-src]` de lá — quem desempata é a posição no arquivo, e o
   estado de slot vazio tem que vencer.
   ============================================================ */

/* ---- Destaques com foto (.feat) — NÍVEL 1 da /comodidades/ ----
   Reestruturação de revisão: a página passou a ter DOIS níveis. Aqui
   em cima, 6 comodidades apresentadas com foto; abaixo, a lista completa
   em ícones (`.amen`). São seções separadas de propósito — **não misturar
   card com foto e card sem foto na mesma grade**, que é o que fazia a
   página inteira parecer uma tabela.

   Blocos alternados, texto 40% / foto 60%, com a foto SANGRANDO até a
   borda da janela. O `.split` (bloco 8) não serve aqui: ele é 1.15fr/1fr
   dentro do container, com moldura dourada, e as duas fotos ficariam do
   mesmo tamanho de um bloco de texto.

   ⚠️ A sangria é `margin` negativa em `--feat-bleed`, que mede a
   distância da borda do container até a borda da janela:
   `max(0px, 100vw - --container) / 2` é a metade da sobra (0 quando a
   janela é menor que o container) e `1.5rem` é o padding do `.container`.
   ⚠️ Em telas de até 640px o `.container` cai para 1.25rem de padding, e
   o token acompanha — senão a foto sangraria 4px a menos de cada lado.

   ⚠️ `100vw` INCLUI a barra de rolagem, então a conta passa metade da
   largura dela (~8px, medido) e a página ganha rolagem horizontal. O
   `overflow-x: hidden` que o `body` tem desde sempre NÃO resolve: como
   o `<html>` está em `visible`, o overflow do body não é propagado para
   a viewport — testado em revisão, a página rolava 8px para o lado.
   Quem apara é o `.sec--bleed` na `<section>`, que é full-width e
   portanto tem exatamente a largura útil.
   `clip` em vez de `hidden` porque `overflow-x: hidden` obrigaria o eixo
   Y a virar `auto` e transformaria a seção em contêiner de rolagem;
   `visible` + `clip` é combinação válida e não cria nenhum. A linha do
   `hidden` fica antes como reserva para quem não tem `clip`. */
.sec--bleed { overflow-x: hidden; overflow-x: clip; }
.feat {
  --feat-bleed: calc(max(0px, 100vw - var(--container)) / 2 + 1.5rem);
  display: grid; gap: clamp(1.6rem, 3.5vw, 2.5rem); align-items: center;
}
@media (max-width: 640px) {
  .feat { --feat-bleed: calc(max(0px, 100vw - var(--container)) / 2 + 1.25rem); }
}
/* Até 899px a foto sangra dos DOIS lados e o texto mantém o padding do
   container — é o enquadramento que a foto grande pede no celular. */
.feat-img { margin-inline: calc(var(--feat-bleed) * -1); }
.feat-img img { width: 100%; aspect-ratio: 4/3; object-fit: cover; }
/* Ritmo de texto: o `.split` ficou 3 meses sem isto e os parágrafos
   colavam (ver o bloco 8). Não repetir o erro em componente novo. */
.feat-txt p + p { margin-top: var(--gap-p); }
.feat-txt p:has(> .btn), .feat-txt p:has(> .link-u) { margin-top: var(--gap-cta); }
.feat-txt h3 { margin-bottom: var(--gap-title); }
.feat + .feat { margin-top: var(--space-xl); }

@media (min-width: 900px) {
  .feat { grid-template-columns: 40fr 60fr; gap: clamp(2.5rem, 5vw, 4.5rem); }
  .feat-img { order: 2; margin-left: 0; }          /* foto à direita */
  .feat-img img { aspect-ratio: 3/2; }
  /* Invertido: a foto troca de lado, sangra do outro lado, e as trilhas
     trocam junto — senão a foto ficaria com os 40% e o texto com os 60%. */
  .feat--rev { grid-template-columns: 60fr 40fr; }
  .feat--rev .feat-img { order: 0; margin-right: 0; margin-left: calc(var(--feat-bleed) * -1); }
}
/* Sem a moldura dourada do `.split-img`: num retângulo que sangra, o
   quadro fecharia de três lados e ficaria pendurado no quarto.
   E sem lightbox — `.feat-img img` está FORA do LB_SEL de propósito: o
   bloco inteiro leva à página do assunto, e ampliar a foto competiria
   com esse clique. */

/* ---- Grade de comodidades com ícone ----
   ⚠️ NÃO é grid, e não é por acaso. A versão anterior era
   `display:grid` com `gap:1px` sobre `background: var(--line)`: os fios
   entre as células eram o fundo do container aparecendo pelo gap. Bonito
   enquanto a contagem fechava a última linha — e um retângulo cinza
   sólido quando não fechava, porque ali o que se via era o fundo do
   container sem nada por cima. Com 10 itens em 4 colunas ("Dentro do
   apartamento") sobravam DUAS células e o bloco terminava com um vazio
   bege do tamanho de meia linha.

   Agora quem pinta fundo e fio é SÓ o item — o container não tem
   `background` nem `border`, então célula que não existe não desenha
   nada. Isso resolve o defeito para qualquer contagem, sem depender de
   múltiplo de 12 nem de item novo confirmado pelo hotel.

   Flexbox, e não grid, por causa da última linha incompleta: `grid` não
   sabe centralizar sobras (`justify-content` move a faixa inteira de
   trilhas, não a última linha). Com `flex-wrap` + `justify-content:
   center`, os 2 itens que sobram ficam centrados sob os de cima.
   `--amen-cols` é o único lugar onde a contagem de colunas muda. */
.amen {
  display: flex; flex-wrap: wrap;
  justify-content: center; align-items: stretch;
  --amen-cols: 2;
}
@media (min-width: 700px)  { .amen { --amen-cols: 3; } }
@media (min-width: 1024px) { .amen { --amen-cols: 4; } }
.amen-i {
  flex: 0 0 calc(100% / var(--amen-cols));
  background: var(--surface);
  /* Fio no item, não no container. O `margin` negativo sobrepõe a borda
     do vizinho da esquerda e a da linha de cima — sem isso todo fio
     interno viraria 2px. É também o que faz a última linha FECHAR: cada
     célula é uma caixa completa, então não sobra traço solto. */
  border: 1px solid var(--line);
  margin: -1px 0 0 -1px;
  /* Alturas iguais tenha ou não a legenda pequena ("conforme a
     categoria"). O `stretch` do container já iguala dentro da linha; o
     min-height iguala TAMBÉM entre linhas. 9.25rem = 148px, medido: o
     item mais alto das duas grades dá 146.73px (ícone + rótulo de uma
     linha + legenda + os 1.7rem de padding). Em rem, e não em px,
     porque tudo aqui é rem menos os 27px do ícone.
     ⚠️ É piso, não altura: em 2 colunas os rótulos longos quebram em
     duas linhas e passam disso — aí manda o stretch da linha. */
  min-height: 9.25rem;
  padding: 1.7rem 1.1rem;
  display: flex; flex-direction: column; align-items: center;
  justify-content: center;
  text-align: center; gap: .85rem;
}
/* O `:hover { background: var(--accent-soft) }` SAIU em revisão. A
   célula não é link nem botão — o realce prometia um clique que não
   existe, e era a única coisa capaz de deixar um item com fundo
   diferente dos outros (foi o que o cliente viu na "TV de tela plana":
   o cursor estava em cima dela). Em touch ele ainda ficava grudado
   depois do toque. Se um dia a célula virar link, o realce volta com
   ele — e aí terá motivo. */

/* --gold-text, nao --accent: icone informativo precisa de 3:1 e o
   #B99470 sobre branco da 2.79:1. Ver a nota do bloco 1. */
.amen-i svg {
  width: 27px; height: 27px; flex-shrink: 0;
  fill: none; stroke: var(--gold-text); stroke-width: 1.3;
  stroke-linecap: round; stroke-linejoin: round;
}
.amen-i b { font-weight: 400; font-size: .88rem; line-height: 1.45; color: var(--text); }
.amen-i small { font-size: .72rem; line-height: 1.4; color: var(--text-muted); }

/* ---- Grupos temáticos da lista completa (.amen-g) —  ----
   Lazer · Gastronomia · Serviços · Conforto · Segurança. Rótulo
   deliberadamente DISCRETO: 24 itens seguidos não se leem, mas cinco
   subtítulos grandes competiriam com o `<h2>` da seção. Daí o corpo em
   versalete dourado e o fio que atravessa o resto da linha — o mesmo
   peso visual da `.overline`, sem ser uma segunda sobrelinha. */
.amen-g + .amen-g { margin-top: clamp(2.2rem, 4vw, 3rem); }
.amen-gt {
  font-family: var(--font-body);
  font-size: .72rem; font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--gold-text);
  display: flex; align-items: center; gap: .9rem;
  margin-bottom: .9rem;
}
.amen-gt::after { content: ''; flex: 1; height: 1px; background: var(--line); }

/* Nota do asterisco (itens "conforme categoria") */
.amen-nota { margin-top: 1.1rem; font-size: .8rem; color: var(--text-muted); }

/* As FICHAS `.rcat` da /acomodacoes/ saíram em revisão: a listagem
   virou o carrossel de cartões do bloco 13e. Antes delas houve o
   `.rcard`, com foto e texto lado a lado.
   ⚠️ Os painéis da home saíram no mesmo movimento, mas VOLTARAM ainda
   em revisão (bloco 8a). Hoje o carrossel é só da /acomodacoes/.
   ------------------------------------------------------------ */

/* ---- Card com foto em cima (gastronomia, piscina) ---- */
.mcards { display: grid; gap: 1.5rem; grid-template-columns: 1fr; }
@media (min-width: 700px)  { .mcards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .mcards { grid-template-columns: repeat(3, 1fr); } }
.mcard {
  background: var(--surface); border: 1px solid var(--line);
  display: flex; flex-direction: column; overflow: hidden;
  transition: border-color .5s var(--ease), transform .5s var(--ease), box-shadow .5s var(--ease);
}
.mcard:hover { border-color: var(--accent); transform: translateY(-3px); box-shadow: var(--shadow); }
/* 5/4 no lugar de 4/3: em três colunas o cartão é estreito, e uma
   foto mais alta ganha área sem empurrar o texto para fora da dobra. */
.mcard-media { position: relative; overflow: hidden; aspect-ratio: 5/4; background: var(--surface-2); }
.mcard-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .8s ease; }
.mcard:hover .mcard-media img { transform: scale(1.06); }
.mcard-body { padding: 1.5rem 1.6rem 1.7rem; display: flex; flex-direction: column; flex: 1; }
.mcard-body h3 { font-size: 1.28rem; margin-bottom: var(--gap-title); }
.mcard-body p { font-size: .93rem; flex: 1; }
.mcard-tags { margin-top: 1.2rem; display: flex; flex-wrap: wrap; gap: .4rem; }
.mcard-tags li {
  font-size: .7rem; color: var(--text-muted);
  border: 1px solid var(--beige); border-radius: 999px; padding: .2rem .68rem;
}

/* ---- Cartões de tratamento (Centro de Bem-Estar) ---- */
.treats {
  display: grid; gap: 1px;
  background: var(--line); border: 1px solid var(--line);
  grid-template-columns: 1fr;
}
@media (min-width: 880px) { .treats { grid-template-columns: repeat(3, 1fr); } }
.treat { background: var(--surface); padding: 2.1rem 1.9rem; display: flex; flex-direction: column; }
.treat h3 { font-size: 1.38rem; margin-bottom: var(--gap-title); }
.treat-dur {
  display: block;
  font-size: .66rem; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  color: var(--gold-text);
}
/* O `.treat` é flex-column, e em flex NÃO há colapso de margem: o
   `margin-bottom` do h3 SOMAVA com o `margin-top` daqui e dava 18px onde
   os outros cartões do site dão 9. Só o cartão que tem `.treat-dur` no
   meio precisa do vão dos dois lados — os outros herdam o do h3. */
.treat > p { font-size: .93rem; flex: 1; }
.treat-dur + p { margin-top: var(--gap-title); }
.treat-price { margin-top: 1.6rem; border-top: 1px solid var(--beige); padding-top: 1.2rem; }
.treat-price div { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; }
.treat-price div + div { margin-top: .55rem; }
.treat-price dt { font-size: .84rem; color: var(--text-muted); }
.treat-price dd { font-family: var(--font-display); font-size: 1.45rem; color: var(--text); white-space: nowrap; }

/* ---- Avaliações ---- */
.rev-g { display: grid; gap: 1.5rem; grid-template-columns: 1fr; }
@media (min-width: 760px)  { .rev-g { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .rev-g { grid-template-columns: repeat(3, 1fr); } }
.rev-c {
  background: var(--surface); border: 1px solid var(--line);
  padding: 1.9rem 1.8rem; display: flex; flex-direction: column;
}
.rev-c .tst-stars { justify-content: flex-start; margin: 0 0 1.1rem; }
/* No carrossel da home as estrelas ficam sobre fundo escuro e --accent
   basta; aqui o fundo e branco, entao escurece. */
.rev-c .tst-stars svg { fill: var(--gold-text); }
.rev-q {
  font-family: var(--font-display); font-style: italic;
  font-size: 1.12rem; line-height: 1.6; color: var(--text); flex: 1;
}
.rev-a { margin-top: 1.5rem; padding-top: 1.1rem; border-top: 1px solid var(--line); }
.rev-a strong {
  display: block;
  font-size: .72rem; font-weight: 700; letter-spacing: .17em; text-transform: uppercase;
  color: var(--gold-text);
}
.rev-a span { font-size: .82rem; color: var(--text-muted); }

/* ============================================================
   13c. BOTÃO FLUTUANTE "FAÇA SUA RESERVA"
   Canto inferior ESQUERDO, de propósito: o canto direito é do botão do
   WhatsApp (mesmo z-index 90) e do widget de captação. Como todo CTA de
   reserva do site, é um <a> real para o motor com target="_blank" —
   nada de modal, nada de âncora.
   Com o banner de cookies na tela ele sobe junto com o WhatsApp; a regra
   fica no bloco 15, junto das outras. Mexeu num flutuante, mexer nos três.
   ============================================================ */
.res-btn {
  position: fixed; left: 1.5rem; bottom: 1.5rem; z-index: 90;
  display: inline-flex; align-items: center; gap: .6rem;
  min-height: 52px; padding: .8rem 1.55rem;
  background: var(--accent); color: var(--btn-text);
  border: 1.5px solid var(--accent); border-radius: 999px;
  font-family: var(--font-body);
  font-size: .68rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  box-shadow: 0 6px 26px rgba(28,25,23,.3);
  transition: background-color .35s var(--ease), color .35s var(--ease),
              border-color .35s var(--ease), transform .35s var(--ease), bottom .3s var(--ease);
}
.res-btn:hover {
  background: var(--accent-deep); border-color: var(--accent-deep); color: #fff;
  transform: translateY(-2px);
}
.res-btn svg {
  width: 16px; height: 16px; flex-shrink: 0;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
@media (max-width: 640px) {
  .res-btn {
    left: 1rem; bottom: 1rem;
    min-height: 46px; padding: .58rem 1.05rem;
    font-size: .6rem; letter-spacing: .11em; gap: .45rem;
  }
  .res-btn svg { width: 14px; height: 14px; }
}

/* ============================================================
   13d. PÁGINA DE UMA CATEGORIA (/acomodacoes/<categoria>/)
   Do bloco original sobraram DUAS regras. A primeira versão desta
   página (, manhã) era: cabeçalho compacto → foto larga →
   galeria de 3 miniaturas → descrição → comodidades → anterior/próxima.
   À tarde ela foi refeita na arquitetura da referência — galeria em
   slider de tela cheia, marca d'água, ficha rápida e grade de serviços,
   tudo no bloco 13e — e `.rpg-head`, `.rpg-lead`, `.rpg-gal`,
   `.rpg-galnota` e `.rpg-nav` deixaram de ter markup.

   O que ficou é o miolo de texto da apresentação, que a página nova
   continua usando.
   ============================================================ */

/* Descrição centrada, no mesmo espírito do `.inst` da home */
.rpg-desc { max-width: 820px; margin: 0 auto; text-align: center; }
.rpg-desc h2 { margin-bottom: calc(var(--gap-title) * 1.2); }
.rpg-desc p { max-width: 62ch; margin-left: auto; margin-right: auto; }
.rpg-desc .todo { text-align: left; }
.rpg-cta { margin-top: 2.4rem; }

/* ============================================================
   13e. ACOMODAÇÕES — arquitetura da referência (escopo )
   Três componentes novos, todos usados na listagem e nas cinco
   páginas de categoria:
     · `.acar`  carrossel de cartões (listagem e home)
     · `.ghero` galeria em slider, no topo da página de categoria
     · `.wt` / `.ficha` / `.svc`  título com marca d'água, ficha
       rápida e grade de serviços

   ⚠️ PALETA: o escopo pedia ícones em #7C7C7C (dourado) e #323232
   (marrom). São da paleta v1, substituída pela v3 em revisão —
   ver o bloco 1. Aqui vale a v3, e todo ícone informativo usa
   `--gold-text` (#9A7856), não `--accent`: sobre off-white o #B99470
   dá 2.7:1, abaixo dos 3:1 que o WCAG pede para ícone informativo.
   ============================================================ */

/* ------------------------------------------------------------
   CARROSSEL DE CATEGORIAS (.acar)
   Três cartões à vista no desktop, um no celular.

   FAIL-OPEN: a trilha é um `overflow-x: auto` com scroll-snap, ou
   seja, ELA JÁ ROLA E DÁ SWIPE SEM JS NENHUM. As setas e os traços
   são INJETADOS por `initRoomCarousel()` — se o módulo morrer, não
   sobra controle morto na tela, só a trilha arrastável.
   ------------------------------------------------------------ */
.acar-wrap { position: relative; }

.acar {
  display: grid; grid-auto-flow: column;
  grid-auto-columns: 86%;
  gap: 28px;
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  /* o respiro embaixo é para a sombra do cartão não ser cortada */
  padding-bottom: .5rem;
  scrollbar-width: none;
}
.acar::-webkit-scrollbar { display: none; }
@media (min-width: 700px)  { .acar { grid-auto-columns: calc((100% - 28px) / 2); } }
@media (min-width: 1024px) { .acar { grid-auto-columns: calc((100% - 56px) / 3); } }

.acar-c {
  scroll-snap-align: start;
  display: flex; flex-direction: column;
  background: var(--surface);
  box-shadow: 0 2px 18px rgba(28,25,23,.07);
  transition: box-shadow .5s var(--ease), transform .5s var(--ease);
  text-align: center;
}
.acar-c:hover { box-shadow: 0 10px 34px rgba(28,25,23,.13); transform: translateY(-3px); }

/* A foto encosta nas bordas do cartão: nada de padding em volta dela. */
.acar-media { display: block; overflow: hidden; background: var(--surface-2); }
/* clamp em vez dos 280px fixos: num monitor largo o cartão fica com
   1/3 da tela e uma foto baixa vira tarja. O piso de 300px segura o
   cartão de celular, onde ele ocupa 86% da largura. */
.acar-media img {
  width: 100%; height: clamp(300px, 26vw, 420px); object-fit: cover;
  transition: transform .8s var(--ease);
}
.acar-c:hover .acar-media img { transform: scale(1.05); }

.acar-body {
  display: flex; flex-direction: column; align-items: center;
  padding: 40px 32px 44px;
  flex: 1;
}
.acar-body h3 { font-size: clamp(1.5rem, 2vw, 2rem); line-height: 1.16; }
.acar-body h3 a { color: inherit; transition: color .3s var(--ease); }
.acar-c:hover .acar-body h3 a { color: var(--gold-text); }

/* 3 linhas e reticências. `line-clamp` sem o `-webkit-` não é
   suportado em lugar nenhum ainda, então as duas formas ficam. */
.acar-desc {
  margin-top: var(--gap-title);
  font-size: .94rem; line-height: 1.75;
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 3; line-clamp: 3;
  overflow: hidden;
}

/* `margin-top:auto` alinha os botões dos três cartões mesmo com
   descrições de alturas diferentes; o respiro MÍNIMO acima dele vem
   do `margin-bottom` da descrição, senão num cartão de texto curto o
   auto colaria o botão no parágrafo. */
.acar-desc { margin-bottom: 1.8rem; }
.acar-cta {
  margin-top: auto;
  display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
  min-height: 46px; padding: .9rem 1.6rem;
  background: transparent; color: var(--text);
  border: 1px solid var(--text);
  font-family: var(--font-body);
  font-size: .66rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  transition: background-color .45s var(--ease), color .45s var(--ease), border-color .45s var(--ease);
}
.acar-c:hover .acar-cta, .acar-cta:hover { background: var(--dark); color: #fff; border-color: var(--dark); }
.acar-cta svg {
  width: 15px; height: 9px; flex-shrink: 0;
  fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ---- controles: setas e TRAÇOS (não bolinhas) ---- */
.acar-nav {
  display: flex; align-items: center; justify-content: center; gap: 1.4rem;
  margin-top: 2.2rem;
}
.acar-arrow {
  width: 42px; height: 42px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--beige);
  color: var(--gold-text); cursor: pointer;
  transition: background-color .35s var(--ease), color .35s var(--ease), border-color .35s var(--ease), opacity .35s var(--ease);
}
.acar-arrow:hover:not(:disabled) { background: var(--accent); border-color: var(--accent); color: var(--btn-text); }
.acar-arrow:disabled { opacity: .3; cursor: default; }
.acar-arrow svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

.acar-dots { display: flex; align-items: center; gap: .55rem; }
.acar-dot {
  width: 26px; height: 2px; padding: 0;
  background: var(--beige); border: none; cursor: pointer;
  transition: background-color .35s var(--ease), width .35s var(--ease);
}
.acar-dot.is-on { width: 44px; background: var(--gold-text); }

/* ------------------------------------------------------------
   GALERIA HERO DA CATEGORIA (.ghero)
   Slider de altura quase cheia, crossfade de 0.8s.

   FAIL-OPEN: o CSS mostra a PRIMEIRA foto sozinho. Só quando
   `initRoomHero()` põe `.is-live` é que o controle passa para a
   classe `.is-on` — e os botões, como no carrossel, são injetados.
   ------------------------------------------------------------ */
/* Altura cheia, como o hero da home. Era 85vh com teto de 900px até
    — o cliente pediu que a foto tomasse a tela.
   O teto de 900px saiu junto: numa tela grande ele deixava uma faixa
   clara embaixo da foto, exatamente o contrário do pedido.
   `svh` antes de `vh`: no celular o `vh` conta a barra de endereço que
   some ao rolar, e a foto ficava alta demais na primeira pintura. Quem
   não conhece `svh` usa a linha de cima. */
.ghero {
  position: relative; overflow: hidden;
  height: 100vh; height: 100svh;
  min-height: 520px;
  background: var(--dark-3);
  /* Komplexa 21/08/2026: a legenda voltou para cima da foto, nas 17 paginas.
     O ghero era so foto; agora alinha o conteudo na base, como o phero fazia. */
  display: flex; align-items: flex-end;
  padding: calc(var(--hdr-h) + 3rem) 0 3.5rem;
}
.ghero .container { position: relative; z-index: 2; }
/* Foto limpa: hero SEM legenda nao precisa do veu claro nem do respiro da base.
   Komplexa 21/08/2026, a pedido, para as paginas de acomodacao. O seletor olha
   o proprio conteudo em vez de exigir uma classe nova, entao qualquer hero sem
   legenda se comporta assim sozinho. */
.ghero:not(:has(.container)) { padding-bottom: 0; }
.ghero:not(:has(.container))::after {
  background: linear-gradient(to bottom,
    rgba(14,12,11,.42) 0%,
    rgba(14,12,11,0) 28%,
    rgba(14,12,11,0) 74%,
    rgba(14,12,11,.26) 100%);
}
.ghero .crumbs, .ghero p { color: var(--text); }
.ghero .overline { color: var(--text); }
.ghero h1 { color: var(--text); font-weight: 300; }
.ghero p { max-width: 58ch; margin-top: var(--gap-title); }
.ghero-s {
  position: absolute; inset: 0;
  opacity: 0; transition: opacity .8s var(--ease);
}
.ghero:not(.is-live) .ghero-s:first-child, .ghero-s.is-on { opacity: 1; }
.ghero-s img { width: 100%; height: 100%; object-fit: cover; }
/* Véu de topo: o header é claro e translúcido, e sem isto a logo
   colorida some sobre uma foto clara. */
.ghero::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  /* Duas metades com jobs diferentes: escuro no topo, para a logo dourada
     sobreviver sobre foto clara; claro na base, onde agora fica a legenda em
     tinta. O meio fica limpo e a foto aparece. Medido contra o terco inferior
     das fotos de topo, que tem luminancia media entre 44 e 145: com a tinta,
     0,55 ja da 6:1. */
  background: linear-gradient(to bottom,
    rgba(14,12,11,.42) 0%,
    rgba(14,12,11,0) 26%,
    rgba(249,246,243,0) 46%,
    rgba(249,246,243,.55) 68%,
    rgba(249,246,243,.90) 100%);
}

.ghero-btn {
  position: absolute; z-index: 3;
  display: flex; align-items: center; justify-content: center;
  background: rgba(14,12,11,.34); border: 1px solid rgba(255,255,255,.4);
  color: #fff; cursor: pointer;
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  transition: background-color .35s var(--ease), border-color .35s var(--ease);
}
.ghero-btn:hover { background: rgba(14,12,11,.62); border-color: #fff; }
.ghero-btn svg { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }

/* setas laterais, discretas */
.ghero-prev, .ghero-next { top: 50%; transform: translateY(-50%); width: 46px; height: 62px; }
.ghero-prev { left: clamp(.75rem, 2vw, 1.75rem); }
.ghero-next { right: clamp(.75rem, 2vw, 1.75rem); }
.ghero-prev svg, .ghero-next svg { width: 17px; height: 17px; }

/* Tela cheia, no canto superior esquerdo. O botão de PLAY (slideshow
   automático) foi removido em revisão a pedido do cliente; o
   contêiner ficou porque a tela cheia continua nele — e porque, se um
   dia voltar um segundo botão, o `gap` já está aqui. */
.ghero-tools {
  position: absolute; z-index: 3;
  top: calc(var(--hdr-h) + .9rem); left: clamp(.75rem, 2vw, 1.75rem);
  display: flex; gap: .5rem;
}
.ghero-tools .ghero-btn { position: static; width: 40px; height: 40px; }
.ghero-tools svg { width: 15px; height: 15px; }

.ghero-count {
  position: absolute; z-index: 3; bottom: 1.5rem; right: clamp(.75rem, 2vw, 1.75rem);
  font-size: .72rem; letter-spacing: .18em; color: rgba(255,255,255,.85);
}
.ghero-count b { color: #fff; font-weight: 600; }

/* ------------------------------------------------------------
   TÍTULO COM MARCA D'ÁGUA (.wt)
   O mesmo nome, gigante e quase invisível, atrás do título.
   `overflow: hidden` fica na SEÇÃO, não aqui: nomes longos
   ("Suíte Luxo com Sacada") passam da largura de propósito, e é a
   seção que apara o excesso.
   ------------------------------------------------------------ */
.sec--clip { overflow: hidden; }
.wt { position: relative; text-align: center; }
.wt-ghost {
  position: absolute; left: 50%; top: 46%; transform: translate(-50%, -50%);
  font-family: var(--font-display); font-weight: 300; font-style: italic;
  font-size: clamp(4rem, 13vw, 11rem); line-height: 1;
  color: var(--text); opacity: .06;
  white-space: nowrap; pointer-events: none; user-select: none;
  z-index: 0;
}
.wt > .overline, .wt > h1, .wt > h2, .wt > .orn,
.wt > p { position: relative; z-index: 1; }

/* ---- A marca d'água nos cabeçalhos de seção da HOME ----
   Na referência ela não é exclusividade das páginas de categoria: toda
   seção da home tem o assunto repetido, gigante e quase invisível,
   atrás do título. Medido lá: 122px, e a cor é o dourado a 11% — que
   por acaso é `rgba(185,148,112,.11)`, exatamente o nosso `--accent`.

   Aqui o tamanho e a posição mudam porque o bloco é outro: o
   `.sec-head` tem sobrelinha + título + descrição, e não só o título,
   então a marca sobe para ficar centrada no TÍTULO e não no conjunto.
   O `clamp` fecha em 7.6rem ≈ 122px, o tamanho da referência.
   ⚠️ Quem apara o excesso é `.sec--clip` na <section> — a marca é
   `nowrap` de propósito e "Acomodações" passa da largura do bloco. */
.sec-head.wt .wt-ghost {
  top: 40%;
  font-size: clamp(3.4rem, 9vw, 7.6rem);
  color: var(--accent); opacity: .11;
}
/* Sobre o bege cheio o dourado a 11% some. Ali quem marca é o escuro. */
.sec--beige .sec-head.wt .wt-ghost { color: var(--dark); opacity: .08; }

/* ------------------------------------------------------------
   FICHA RÁPIDA (.ficha) — metragem, cama, capacidade
   ------------------------------------------------------------ */
.ficha {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 1.6rem clamp(2rem, 6vw, 4.5rem);
  margin-top: clamp(2rem, 4vw, 3rem);
}
.ficha li { display: flex; align-items: center; gap: .8rem; text-align: left; }
.ficha svg {
  width: 26px; height: 26px; flex-shrink: 0;
  fill: none; stroke: var(--gold-text); stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
}
.ficha b { display: block; font-weight: 400; font-size: .98rem; color: var(--text); }
.ficha small {
  display: block; font-size: .64rem; font-weight: 700;
  letter-spacing: .17em; text-transform: uppercase; color: var(--text-muted);
}

/* ------------------------------------------------------------
   SERVIÇOS E FACILIDADES (.svc)
   Ícone à ESQUERDA, texto à direita alinhado a ele. Sem moldura e
   sem fio: o que separa é o espaço.
   ------------------------------------------------------------ */
.svc {
  display: grid; grid-template-columns: 1fr;
  gap: 48px clamp(1.5rem, 3vw, 2.75rem);
  margin-top: clamp(2rem, 4vw, 3.25rem);
}
@media (min-width: 640px)  { .svc { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .svc { grid-template-columns: repeat(4, 1fr); } }
.svc li { display: flex; align-items: flex-start; gap: .95rem; text-align: left; }
.svc svg {
  width: 26px; height: 26px; flex-shrink: 0; margin-top: .1rem;
  fill: none; stroke: var(--gold-text); stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
}
.svc b { display: block; font-weight: 400; font-size: .96rem; line-height: 1.45; color: var(--text); }
.svc small { display: block; margin-top: .3rem; font-size: .8rem; line-height: 1.5; color: var(--text-muted); }

/* Botão outline com seta — o padrão de CTA destas páginas */
.btn-arrow svg {
  width: 15px; height: 9px; flex-shrink: 0;
  fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
}

/* prefers-reduced-motion: sem zoom de foto, sem crossfade, sem
   deslize. O carrossel continua rolando (é a informação dele). */
@media (prefers-reduced-motion: reduce) {
  .acar-c:hover .acar-media img { transform: none; }
  .ghero-s { transition: none; }
  .acar { scroll-behavior: auto; }
}

/* ============================================================
   14. WHATSAPP — BOTÃO + WIDGET DE CAPTAÇÃO (padrão {{AGENCIA_NOME}})
   PORT LITERAL do site v1 (assets/css/style.css 808-817 e 1017-1180),
   que por sua vez veio da Fazenda dos Cordeiros / {{HOTEL_NOME}}.
   Visual NÃO pode mudar: cabeçalho verde escuro com chevron, balão
   lilás, três campos num card único, checkbox verde, pílula "Enviar ➤",
   rodapé "Feito por {{AGENCIA_NOME}} · Política de Privacidade".
   A única adaptação é --font-body, que aqui é Source Sans 3 igual ao v1.
   ============================================================ */
.wa-btn {
  position: fixed; bottom: 1.5rem; right: 1.5rem; z-index: 90;
  width: 56px; height: 56px;
  background: #25D366; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 20px rgba(37,211,102,0.4);
  border: none; transition: transform 0.2s, bottom 0.3s var(--ease);
}
.wa-btn:hover { transform: scale(1.1); cursor: pointer; }

:root {
  --wa-bottom: 1.5rem; --wa-side: 1.5rem; --wa-size: 56px;
  --wa-green: #25D366;        /* verde oficial do WhatsApp */
  --wa-green-dark: #464646;   /* cabeçalho do widget */
  --wa-green-rgb: 37, 211, 102;
  --wa-bubble: #E6E6E6;       /* lilás claro do balão de saudação */
  --wa-border: rgba(28,25,23,.12);
}

.wa-form-modal {
  position: fixed; z-index: 9600;
  right: var(--wa-side);
  bottom: calc(var(--wa-bottom) + var(--wa-size) + .75rem);
  width: 370px; max-width: calc(100vw - 2 * var(--wa-side));
  opacity: 0; visibility: hidden;
  transform: scale(.85) translateY(12px);
  transform-origin: bottom right;
  transition: opacity .22s var(--ease), transform .22s var(--ease), visibility .22s var(--ease);
}
.wa-form-modal.open { opacity: 1; visibility: visible; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .wa-form-modal { transition: opacity .15s linear, visibility .15s linear; transform: none; }
}
.wa-form-box {
  background: #fff; width: 100%;
  border-radius: 14px; overflow: hidden; position: relative;
  box-shadow: 0 10px 40px rgba(0,0,0,.22);
  display: flex; flex-direction: column;
  /* Guarda para telas baixas (ou com o teclado virtual no ar): o painel nunca
     vaza a viewport — se faltar altura, rola por dentro. */
  max-height: calc(100vh - var(--wa-bottom) - var(--wa-size) - 1.5rem);
  max-height: calc(100svh - var(--wa-bottom) - var(--wa-size) - 1.5rem);
  overflow-y: auto;
}

/* ---- cabeçalho verde: balão de chat, título e chevron que fecha ---- */
.wa-form-header {
  background: var(--wa-green-dark); padding: .85rem .9rem;
  display: flex; gap: .6rem; align-items: center; flex-shrink: 0;
}
.wa-form-icon {
  width: 30px; height: 30px; flex-shrink: 0;
  background: rgba(255,255,255,.16); border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.wa-form-icon svg { width: 17px; height: 17px; fill: #fff; }
.wa-form-header h3 {
  font-family: var(--font-body); font-size: .95rem; font-weight: 700;
  margin: 0; color: #fff; flex: 1; line-height: 1.3;
}
.wa-form-close {
  flex-shrink: 0; background: transparent; border: none;
  width: 28px; height: 28px; border-radius: 50%;
  cursor: pointer; color: #fff;
  display: flex; align-items: center; justify-content: center;
  transition: background .2s;
}
.wa-form-close svg { width: 20px; height: 20px; fill: none; stroke: #fff; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.wa-form-close:hover { background: rgba(255,255,255,.18); }

.wa-form { padding: .9rem 1rem 1rem; display: flex; flex-direction: column; gap: .7rem; }

/* ---- balão de saudação em lilás, com a pontinha virada para o ícone ---- */
.wa-form-intro {
  position: relative; align-self: flex-start;
  background: var(--wa-bubble); color: #1A1A1A;
  font-size: .8rem; line-height: 1.45; margin: .15rem 0 0;
  padding: .6rem .75rem; border-radius: 4px 10px 10px 10px;
}
.wa-form-intro::before {
  content: ''; position: absolute; top: 0; left: -6px;
  border-width: 0 6px 8px 0; border-style: solid;
  border-color: transparent var(--wa-bubble) transparent transparent;
}

/* rótulo só para leitor de tela — o campo se identifica pelo placeholder */
.wa-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---- os três campos num único container, separados por fio ---- */
.wa-fields {
  border: 1px solid var(--wa-border); border-radius: 8px;
  background: #fff; overflow: hidden;
}
.wa-form .fg { display: flex; align-items: center; gap: .5rem; margin: 0; padding: 0 .7rem; }
.wa-form .fg + .fg { border-top: 1px solid var(--wa-border); }
.wa-form input {
  padding: .65rem 0; border: none; border-radius: 0;
  font-size: 16px; /* 16px trava o zoom automático do Safari no iOS */
  font-family: var(--font-body);
  background: transparent; min-height: 44px; width: 100%;
  color: #1A1A1A; transition: background .2s;
}
.wa-form input::placeholder { color: #5A5A5A; opacity: 1; }
.wa-form input:focus { outline: none; }
.wa-form .fg:focus-within { background: rgba(28,25,23,.06); }
/* sem borda própria: o campo inválido se marca pelo fundo e por um fio interno */
.wa-form input.invalid { background: #fff5f4; box-shadow: inset 2px 0 0 #c0392b; padding-left: .5rem; }
.wa-flag { flex-shrink: 0; display: flex; align-items: center; }
.wa-flag svg { width: 22px; height: 16px; border-radius: 2px; display: block; }
/* o autopreenchimento do Chrome pintava o campo de azulado dentro da caixa branca */
.wa-form input:-webkit-autofill,
.wa-form input:-webkit-autofill:hover,
.wa-form input:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px #fff inset;
          box-shadow: 0 0 0 1000px #fff inset;
}

/* ---- aceite em caixa verde clara, marcado por padrão (NÃO é obrigatório) ---- */
.wa-form .wa-optin {
  display: flex; align-items: flex-start; gap: .55rem; margin: 0;
  background: rgba(var(--wa-green-rgb), .10);
  border: 1px solid rgba(var(--wa-green-rgb), .55); border-radius: 8px;
  padding: .6rem .7rem; cursor: pointer;
  font-size: .76rem; font-weight: 400; line-height: 1.4;
  letter-spacing: normal; color: #1A1A1A;
  transition: background .2s, border-color .2s;
}
.wa-form .wa-optin input {
  width: auto; min-height: 0; flex-shrink: 0; margin-top: .12rem;
  accent-color: var(--wa-green);
}

/* ---- pílula verde centralizada ---- */
.wa-form-submit {
  margin-top: .15rem; align-self: center; width: auto;
  background: var(--wa-green); color: #fff;
  border: none; border-radius: 999px;
  padding: .6rem 1.5rem; min-height: 42px;
  font-weight: 700; font-size: .9rem; font-family: var(--font-body);
  letter-spacing: normal;
  cursor: pointer; transition: background .2s, opacity .2s;
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
}
.wa-send-ico { width: 16px; height: 16px; fill: currentColor; flex-shrink: 0; }
.wa-form-submit:hover { background: #6e6e6e; }
.wa-form-submit:disabled, .wa-form-submit.is-loading { opacity: .7; cursor: wait; }

.wa-form-foot {
  text-align: center; font-size: .7rem; color: #5A5A5A;
  margin: 0; padding: 0 1rem .8rem; line-height: 1.4;
}
.wa-form-foot a { color: #5A5A5A; text-decoration: underline; }

/* ---- MOBILE: o widget ocupa a largura da tela menos as margens ---- */
@media (max-width: 640px) {
  .wa-form-modal { left: var(--wa-side); right: var(--wa-side); width: auto; max-width: none; }
}

/* ============================================================
   14b. FLUTUANTES QUE SÓ APARECEM DEPOIS DE ROLAR
   Os dois botões (WhatsApp à direita, "Faça sua Reserva" à esquerda)
   nascem invisíveis e entram quando o visitante desce a primeira tela.
   Motivo: no topo eles cobrem os cantos da foto de abertura, que é a
   primeira imagem do hotel.

   O ESTADO ESCONDIDO PENDE DE `.js-anim`, e isso é de propósito:
     · a classe é posta pelo snippet inline do <head> de cada página,
       antes da primeira pintura — então não há flash de botão que
       aparece e some;
     · o mesmo snippet tem um watchdog de 4s: se o main.js não sinalizar
       `kxReady`, a classe cai e os botões voltam à vista. JS morto =
       botões visíveis, nunca o contrário;
     · com `prefers-reduced-motion` a classe nunca é aplicada, então os
       botões ficam SEMPRE visíveis. É a regra do site: movimento
       desligado desliga este tipo de comportamento.

   Quem acende é `initFlutuantes()`, pondo `.flut-on` no <html>.

   Só opacidade e visibilidade — nada de transform no `.wa-btn`. Ele é
   port literal do padrão {{AGENCIA_NOME}} e já usa `transform: scale(1.1)` no
   hover; animar transform aqui brigaria com aquilo. O `.res-btn`, que
   é nosso, ganha o deslize de 10px.
   ============================================================ */
.js-anim .wa-btn,
.js-anim .res-btn {
  opacity: 0; visibility: hidden;
  transition: opacity .45s var(--ease), visibility .45s var(--ease),
              transform .45s var(--ease), bottom .3s var(--ease);
}
.js-anim .res-btn { transform: translateY(10px); }

.js-anim.flut-on .wa-btn,
.js-anim.flut-on .res-btn { opacity: 1; visibility: visible; }
.js-anim.flut-on .res-btn { transform: none; }

/* Exceção: com o widget do WhatsApp aberto o botão continua à vista,
   mesmo se o visitante voltar ao topo — ele é o botão que FECHA o
   widget, e sumir com ele deixaria o painel sem saída. */
body:has(#waFormModal.open) .wa-btn { opacity: 1; visibility: visible; }

/* ============================================================
   15. COOKIE BANNER LGPD (Consent Mode · kxConsent)
   z-index 95: acima do botão do WhatsApp (90) e abaixo do widget (9600).
   Enquanto a barra está na tela, botão e widget sobem — mexeu em um,
   mexer no outro.
   ============================================================ */
:root { --kx-cookie-h: 78px; }
@media (max-width: 640px) { :root { --kx-cookie-h: 124px; } }
body:has(#kx-cookie-banner) .wa-btn,
body:has(#kx-cookie-banner) .res-btn { bottom: calc(var(--kx-cookie-h) + 0.75rem); }
body:has(#kx-cookie-banner) .wa-form-modal {
  bottom: calc(var(--kx-cookie-h) + 0.75rem + var(--wa-size) + 0.75rem);
}

.kx-cookie {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 95;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 1rem 1.75rem;
  padding: 1rem clamp(1.25rem, 5vw, 2.5rem);
  background: var(--accent); color: var(--dark);
  border-top: 1px solid rgba(28,25,23,0.2);
  box-shadow: 0 -6px 24px rgba(0,0,0,0.28);
  font-family: var(--font-body); font-size: 0.82rem; line-height: 1.55;
  animation: kx-cookie-in 0.3s var(--ease) both;
}
@keyframes kx-cookie-in { from { transform: translateY(100%); } to { transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) { .kx-cookie { animation: none; } }

.kx-cookie__text { flex: 1 1 320px; max-width: 70ch; margin: 0; color: var(--dark); }
.kx-cookie__text a { color: var(--dark); text-decoration: underline; }
.kx-cookie__actions { display: flex; flex-wrap: wrap; gap: 0.6rem; flex-shrink: 0; }
.kx-cookie__btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0.55rem 1.6rem;
  font-family: var(--font-body); font-size: 0.68rem; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  border: 1.5px solid transparent; border-radius: 4px; cursor: pointer;
  transition: background-color .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease);
}
.kx-cookie__btn--ghost { background: transparent; color: var(--dark); border-color: rgba(28,25,23,.45); }
.kx-cookie__btn--ghost:hover { background: rgba(28,25,23,.1); border-color: var(--dark); }
.kx-cookie__btn--accept { background: var(--dark); color: #fff; border-color: var(--dark); }
.kx-cookie__btn--accept:hover { background: #1A1A1A; }

/* ============================================================
   16. LIGHTBOX DE FOTO
   ============================================================ */
.lb {
  position: fixed; inset: 0; z-index: 9650;
  background: rgba(14,12,11,.94);
  display: flex; align-items: center; justify-content: center; padding: 3.5rem 1.5rem;
  opacity: 0; visibility: hidden; transition: opacity .35s var(--ease), visibility .35s var(--ease);
}
.lb.open { opacity: 1; visibility: visible; }
.lb img { max-width: 100%; max-height: 100%; object-fit: contain; }
.lb-close, .lb-prev, .lb-next {
  position: absolute; background: transparent; color: #fff; cursor: pointer;
  border: 1px solid rgba(255,255,255,.3); border-radius: 50%;
  width: 46px; height: 46px; font-size: 1.5rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  transition: border-color .3s var(--ease), background-color .3s var(--ease), color .3s var(--ease);
}
.lb-close:hover, .lb-prev:hover, .lb-next:hover { border-color: var(--accent); background: var(--accent); color: var(--btn-text); }
.lb-close { top: 1.3rem; right: 1.5rem; }
.lb-prev  { left: 1.2rem; top: 50%; transform: translateY(-50%); }
.lb-next  { right: 1.2rem; top: 50%; transform: translateY(-50%); }
@media (max-width: 640px) { .lb-prev { left: .6rem; } .lb-next { right: .6rem; } }

/* ============================================================
   16b. SLOTS DE FOTO (estado "só estrutura")
   Enquanto o cliente não envia o material novo, todo <img> de foto
   serve `assets/img/_placeholder.svg` e guarda o caminho definitivo
   em `data-src`. Ver tools/fotos.py e assets/img/FOTOS.md.

   Este bloco precisa vir DEPOIS dos componentes: `img[data-src]` tem a
   mesma especificidade de `.gi img`, `.px-img img` etc. (0,1,1), então
   quem decide é a ordem no arquivo. Quando as fotos entrarem, o
   atributo some e todo este bloco deixa de casar sozinho — nada a
   remover depois.
   ============================================================ */
img[data-src] {
  /* cover: o placeholder agora é um bloco bronze chapado do catálogo de
     demonstração, então preencher o slot inteiro é o comportamento certo
     (com `contain` sobrariam faixas do fundo nas proporções extremas). */
  object-fit: cover;
  background: linear-gradient(150deg, #BFBFBF 0%, #8F8F8F 45%, #6A6A6A 100%);
}

/* Hero sem a foto ainda: o placeholder é claro demais para o texto
   branco por cima dele. Enquanto o slot estiver vazio, o .hero-media
   ganha um degradê escuro por baixo do placeholder — some sozinho
   quando `tools/fotos.py --aplicar` tirar o data-src. */
.hero-media:has(img[data-src]) {
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(212,194,175,.22) 0%, rgba(212,194,175,0) 60%),
    linear-gradient(160deg, #4A4239 0%, #322C26 45%, #1C1917 100%);
}
.hero-media img[data-src] { opacity: .28; }

/* ============================================================
   17. REVEAL — base das animações
   FAIL-OPEN por construção: `.reveal` sozinho NÃO esconde nada. O
   estado inicial é aplicado por JS (classe .js-anim no <html>, posta
   pelo próprio main.js). Se o JS falhar ou o GSAP não carregar, a
   página aparece completa e estática — nunca invisível.
   ============================================================ */
.js-anim .reveal { opacity: 0; transform: translateY(40px); }
.js-anim .reveal-line .line-inner { opacity: 0; transform: translateY(100%); }
.reveal-line .line { overflow: hidden; }

/* Reveal sem GSAP (fallback do IntersectionObserver) */
.reveal.in-view {
  animation: revealUp var(--dur) var(--ease) forwards;
}
@keyframes revealUp { to { opacity: 1; transform: none; } }

/* ============================================================
   18. PREFERS-REDUCED-MOTION
   Tudo que se move é desligado — inclusive o Ken Burns e o parallax
   (o JS também checa a media query e nem registra os ScrollTriggers).
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .js-anim .reveal,
  .js-anim .reveal-line .line-inner { opacity: 1 !important; transform: none !important; }

  /* Painéis de acomodação: o painel AINDA EXPANDE — a expansão é a
     informação do componente, não enfeite —, mas sem animar o flex
     (o `transition-duration` global acima já resolve) e sem zoom na
     foto. O conteúdo volta ao rótulo de repouso: nome sempre à vista,
     no canto, sobre o gradiente. Sem repor o gradiente aqui, o texto
     branco ficaria centrado sobre foto clara e sumiria. */
  .panel-in {
    opacity: 1 !important; transform: none !important;
    background: var(--panel-veil) !important;
    align-items: flex-start !important; justify-content: flex-end !important;
    text-align: left !important;
  }
  .panel:hover .panel-img img,
  .panel:focus-within .panel-img img { transform: none !important; }

  /* Mosaico: sem zoom na foto e sem o deslize do título */
  .mos-img, .mos-c:hover .mos-img, .mos-c:focus-within .mos-img { transform: none !important; }
  .mos-title, .mos-c:hover .mos-title, .mos-c:focus-within .mos-title { transform: none !important; }
  .mos-c::after { transition: none !important; }
}

/* ============================================================
   19. IMPRESSÃO
   ============================================================ */
@media print {
  .hdr, .wa-btn, .res-btn, .wa-form-modal, .kx-cookie, .footer,
  .mobnav, .lb { display: none !important; }
  body { background: #fff; color: #000; }
  .sec { padding: 1.5rem 0; }
}
