/* ==========================================================================
   Dra. Daniela Carvalho — Endocrinologia e Nutrologia
   Identidade: editorial premium. Mobile-first (base 375px).
   Organização: tokens → base → utilitários → header → seções (1–10) → motion.
   ========================================================================== */

/* ---------------------------------------------------------------- tokens */
:root {
  /* Núcleo */
  --pinho:     #0E2A21;  /* "preto" da marca — fundos de impacto, botões, rodapé */
  --fume:      #0A0A09;  /* blocos fotográficos, overlays */
  --musgo:     #1B3A2E;  /* cards sobre fundo escuro, hover */
  --salvia:    #A3C2A8;  /* ACENTO-ASSINATURA — números, itálicos, eyebrows */
  --creme:     #EFE7D9;  /* texto sobre fundo escuro */
  --areia:     #D9CDBA;  /* fundo das seções de leitura longa */
  --terracota: #A9764A;  /* acento secundário */
  --grafite:   #1A1815;  /* texto sobre fundo claro */
  /* Uso restrito */
  --dourado:   #C9A227;  /* só estrelas de avaliação */
  --whatsapp:  #25D366;  /* SÓ o botão flutuante, em nenhum outro lugar */
  /* Formas */
  --r-card: 20px;
  --r-img: 24px;
  --r-pill: 999px;
  /* Espaçamento */
  --s1: 8px;  --s2: 16px; --s3: 24px; --s4: 40px;
  --s5: 64px; --s6: 96px; --s7: 128px;
  --shadow: 0 6px 22px rgba(26,24,21,.10);
  --shadow-cta: 0 8px 24px rgba(14,42,33,.30);
  --ease: cubic-bezier(.16,1,.3,1);      /* chegadas: desacelera e assenta */
  --ease-exit: cubic-bezier(.4,0,1,1);   /* saídas: segura e acelera para fora */
  /* Derivados */
  --header-h: 64px;        /* altura do miolo do cabeçalho, sem a borda */
  --header-border: 1px;    /* a borda entra na altura real: some nos dois lugares */
}

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

html {
  overflow-x: clip;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 16px);
  -webkit-text-size-adjust: 100%;
  /* A rolagem para no rodapé: sem isso, o telefone deixa arrastar além do fim
     (efeito elástico) e a página volta sozinha, o que se lê como falha. */
  overscroll-behavior-y: none;
}

body {
  margin: 0;
  overflow-x: clip;
  font-family: 'Manrope', system-ui, sans-serif;
  font-size: 1.0625rem;            /* 17px */
  font-weight: 400;
  line-height: 1.7;
  color: var(--grafite);
  background: var(--creme);
}

img, svg, iframe { max-width: 100%; }

h1, h2, h3 {
  font-family: 'Newsreader', Georgia, serif;
  font-weight: 500;
  margin: 0 0 var(--s3);
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.125rem, 1.55rem + 2.9vw, 4rem);   /* 34–40 mobile → 52–64 desktop */
  line-height: 1.08;
  letter-spacing: -0.015em;
}

h2 {
  font-size: clamp(1.75rem, 1.4rem + 1.9vw, 2.75rem);  /* 28–32 mobile → 36–44 desktop */
  line-height: 1.15;
  letter-spacing: -0.01em;
}

h3 {
  font-size: 1.5rem;                                   /* 24px (28 no desktop via seções) */
  line-height: 1.3;
}

p { margin: 0 0 var(--s2); }
p:last-child { margin-bottom: 0; }

a { color: inherit; }

strong, b { font-weight: 600; } /* destaque no corpo: sempre Manrope 600, nunca serifa */

ul[role="list"] { list-style: none; margin: 0; padding: 0; }
dl, dt, dd { margin: 0; }

::selection { background: var(--salvia); color: var(--pinho); }

/* Foco de teclado sempre visível */
:focus-visible { outline: 2px solid var(--grafite); outline-offset: 3px; border-radius: 2px; }
.section--dark :focus-visible,
.site-header :focus-visible,
.site-footer :focus-visible,
.whatsapp-float:focus-visible { outline-color: var(--creme); }

/* Texto só para leitor de tela */
.u-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--pinho); color: var(--creme);
  padding: 12px 20px; border-radius: 0 0 var(--r-card) 0;
  font: 600 0.9375rem/1 'Manrope', sans-serif; text-decoration: none;
}
.skip-link:focus-visible { left: 0; }

/* ------------------------------------------------------------ utilitários */
.container {
  width: min(1180px, 100% - 2 * var(--s3));   /* máx. 1180, gutter 24 */
  margin-inline: auto;
}
.container--narrow { max-width: 820px; }

main > section, .site-footer { padding-block: 72px; }

/* Ritmo escuro/claro */
.section--dark  { background: var(--pinho); color: var(--creme); }
.section--areia { background: var(--areia); color: var(--grafite); }
.section--creme { background: var(--creme); color: var(--grafite); }

/* Regra do itálico: uma palavra por título, sálvia no escuro, terracota no claro.
   Exceção de acessibilidade: sobre AREIA, terracota mede 2.49:1 (< AA 3:1 para
   texto grande) — nessas seções o itálico usa pinho. Sobre CREME passa (3.18:1). */
h1 em, h2 em, .manifesto__phrase em {
  font-style: italic;
  font-weight: 500;
  color: var(--terracota);
}
.section--areia h2 em { color: var(--pinho); }
.section--dark h1 em, .section--dark h2 em, .manifesto__phrase em { color: var(--salvia); }

/* Eyebrow — 12px 600 caps +16%. Sálvia no escuro; verde pinho no claro
   (sálvia e terracota reprovam AA a 12px sobre areia/creme — ver README). */
.eyebrow {
  font: 600 0.75rem/1.4 'Manrope', sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--salvia);
  margin: 0 0 var(--s2);
}
.eyebrow--on-light { color: var(--pinho); }

/* Placeholder pendente — visível e discreto até o dado real entrar */
.pendente {
  text-decoration: underline dashed 1px;
  text-underline-offset: 3px;
  text-decoration-color: currentColor;
}

/* Elemento de assinatura 1 — chip translúcido */
.chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 18px; border-radius: var(--r-pill);
  background: rgba(239,231,217,.14);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  border: 1px solid rgba(239,231,217,.22);
  font: 600 0.875rem/1.4 'Manrope', sans-serif;
  color: var(--creme); letter-spacing: .02em;
}

/* Elemento de assinatura 2 — botão circular de seta */
.arrow-btn {
  width: 44px; height: 44px; border-radius: 50%; flex: none;
  border: 1px solid rgba(239,231,217,.45); background: transparent;
  display: grid; place-items: center; color: var(--creme);
  transition: all .25s var(--ease); cursor: pointer; text-decoration: none;
}
.arrow-btn .icon { width: 18px; height: 18px; }
.arrow-btn:hover { background: var(--salvia); border-color: var(--salvia); color: var(--pinho); }
.arrow-btn--on-light { border-color: rgba(26,24,21,.35); color: var(--grafite); }
.arrow-btn--on-light:hover { background: var(--pinho); border-color: var(--pinho); color: var(--creme); }

/* Elemento de assinatura 3 — assinatura de rodapé de seção */
.signature {
  font-family: 'Newsreader', Georgia, serif;
  font-size: 0.9375rem; font-weight: 400; font-style: italic;
  letter-spacing: .06em;
  color: rgba(239,231,217,.55);
  text-align: center;
  margin: var(--s5) 0 0;
}

/* Botões — CTAs sempre no verde da marca; #25D366 só no flutuante */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  padding: 17px 34px; border-radius: var(--r-pill); border: 0;
  font: 600 1rem/1.2 'Manrope', sans-serif; letter-spacing: .02em;
  text-decoration: none; cursor: pointer;
  transition: background .25s var(--ease), box-shadow .25s var(--ease),
              color .25s var(--ease), transform .25s var(--ease);
}
.btn .icon--wa { width: 20px; height: 20px; flex: none; }

/* Primário sobre fundo claro */
.btn--on-light { background: var(--pinho); color: var(--creme); }
.btn--on-light:hover { background: var(--musgo); box-shadow: var(--shadow-cta); }

/* Primário sobre fundo escuro */
.btn--on-dark { background: var(--creme); color: var(--pinho); }
.btn--on-dark:hover { box-shadow: var(--shadow-cta); transform: translateY(-1px); }

/* Secundário — contorno 1.5px */
.btn--outline-on-light {
  background: transparent; color: var(--pinho);
  box-shadow: inset 0 0 0 1.5px var(--pinho);
}
.btn--outline-on-light:hover { background: var(--pinho); color: var(--creme); }

.btn--lg { padding: 18px 40px; }

/* CTA de fim de seção */
.section-cta { margin-top: var(--s4); }
.section-cta--center { text-align: center; }
.section-cta__ask {
  font-family: 'Newsreader', Georgia, serif; font-style: italic;
  font-size: 1.25rem; margin-bottom: var(--s2);
}

/* Cabeçalho de seção */
.section-head { max-width: 720px; margin-bottom: var(--s4); }
.section-head--center { margin-inline: auto; text-align: center; }
.section-head__intro { font-size: 1.0625rem; }

/* Placeholder de foto — trocar pelas fotos reais (ver README) */
.photo-ph {
  position: relative; margin: 0; overflow: hidden;
  background:
    radial-gradient(130% 90% at 20% 0%, rgba(163,194,168,.16), transparent 55%),
    linear-gradient(160deg, var(--musgo) 0%, var(--pinho) 55%, var(--fume) 100%);
  display: grid; place-items: center;
}
.photo-ph::after { /* gradiente pinho → transparente na base (fotos que recebem texto) */
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(0deg, rgba(14,42,33,.85) 0%, rgba(14,42,33,0) 45%);
  pointer-events: none;
}
.photo-ph__label {
  position: relative; z-index: 1;
  font: 600 0.75rem/1.4 'Manrope', sans-serif;
  text-transform: uppercase; letter-spacing: .12em;
  color: rgba(239,231,217,.5);
}
/* Foto real dentro do placeholder — preenche o bloco e o ::after continua por cima.
   O enquadramento (object-position) é definido por seção. */
.photo-ph picture,
.photo-ph img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
.photo-ph img { object-fit: cover; object-position: 50% 25%; }

/* ==================================================================== header */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: var(--pinho); color: var(--creme);
  border-bottom: var(--header-border) solid rgba(239,231,217,.12);
}
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); min-height: var(--header-h);
}
.site-header__brand { display: flex; flex-direction: column; text-decoration: none; padding-block: 10px; }
.site-header__name {
  font-family: 'Newsreader', Georgia, serif;
  font-size: 1.1875rem; font-weight: 500; line-height: 1.2;
}
.site-header__role {
  font: 600 0.625rem/1.4 'Manrope', sans-serif;
  text-transform: uppercase; letter-spacing: .14em;
  color: var(--salvia);
}

/* Navegação — mobile: painel em tela cheia */
.site-nav {
  position: fixed; inset: var(--header-h) 0 0 0; z-index: 99;
  background: var(--pinho);
  display: none; flex-direction: column; gap: var(--s4);
  padding: var(--s5) var(--s3) var(--s4);
  overflow-y: auto;
}
.site-nav.open { display: flex; }
.site-nav__list { display: flex; flex-direction: column; gap: var(--s3); }
.site-nav__list a {
  font-family: 'Newsreader', Georgia, serif;
  font-size: 1.75rem; font-weight: 500;
  color: var(--creme); text-decoration: none;
}
.site-nav__list a:hover { color: var(--salvia); }
.site-nav__cta { align-self: flex-start; }

.menu-toggle {
  display: inline-flex; flex-direction: column; justify-content: center; gap: 6px;
  width: 44px; height: 44px; padding: 10px;
  background: none; border: 0; cursor: pointer;
}
.menu-toggle__bar {
  display: block; width: 22px; height: 1.5px;
  background: var(--creme); transition: transform .25s var(--ease);
}
.menu-toggle[aria-expanded="true"] .menu-toggle__bar:first-child { transform: translateY(3.75px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] .menu-toggle__bar:last-child { transform: translateY(-3.75px) rotate(-45deg); }

body.menu-open { overflow: hidden; }

@media (min-width: 900px) {
  :root { --header-h: 76px; }
  .site-nav {
    position: static; inset: auto; display: flex; flex-direction: row;
    align-items: center; gap: var(--s3); padding: 0; background: none; overflow: visible;
  }
  .site-nav__list { flex-direction: row; gap: var(--s3); }
  .site-nav__list a {
    font: 500 0.9375rem/1.4 'Manrope', sans-serif;
    color: rgba(239,231,217,.85);
  }
  .site-nav__list a:hover { color: var(--creme); }
  .site-nav__cta { padding: 12px 22px; font-size: 0.875rem; }
  .menu-toggle { display: none; }
}

/* ==================================================================== 1 · hero */
/* A margem negativa puxa o hero para debaixo do cabeçalho, que é sticky e
   ocupa espaço no fluxo. Sem isso não existe foto atrás da barra e um
   cabeçalho transparente revelaria o fundo da página, não a imagem. O
   padding-top do grid devolve exatamente a mesma altura, então o conteúdo do
   hero não se move um pixel: só a foto passou a correr por baixo.

   A conta usa a altura REAL do cabeçalho, miolo mais borda: --header-h sozinho
   deixaria escapar a espessura da borda como uma linha do fundo da página no
   topo da tela, já que a barra em repouso é transparente. */
.hero {
  position: relative; overflow: hidden;
  margin-top: calc(-1 * (var(--header-h) + var(--header-border)));
}
.hero__grid { padding-top: calc(var(--header-h) + var(--header-border)); }

/* Foto de fundo ocupando toda a hero: assunto à direita, parede escura à
   esquerda recebe o texto. O scrim (::before) escurece de leve o lado do
   texto e o ::after mantém o gradiente pinho -> transparente na base, o
   mesmo que a foto sangrada usava (via .photo-ph). */
.hero__bg { position: absolute; inset: 0; margin: 0; }
.hero__bg img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: 72% 30%;
}
.hero__bg::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(10,10,9,.62) 0%, rgba(10,10,9,.28) 52%, rgba(10,10,9,0) 78%);
  pointer-events: none;
}
.hero__bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(0deg, rgba(14,42,33,.85) 0%, rgba(14,42,33,0) 45%);
  pointer-events: none;
}

.hero__grid { display: grid; gap: var(--s4); position: relative; z-index: 1; }
.hero__content { padding-bottom: var(--s2); }
.hero h1 { margin-bottom: var(--s3); }
.hero__sub { max-width: 54ch; color: rgba(239,231,217,.88); }
/* O botão e a microcópia ficam centrados na coluna de texto: sem os chips, a
   chamada é o único elemento depois do parágrafo e o centro dá a ela o peso de
   um convite único.
   A margem de cima preserva o espaço que os chips ocupavam, a pedido: a hero
   mantém a altura de antes e a faixa escura seguinte começa no mesmo ponto. É
   o vão antigo inteiro — 24px acima da lista, as duas linhas dela (83px) e
   40px abaixo. Vale só no desktop: acima de 900px a coluna de texto nunca
   passa de ~600px, então a lista sempre quebrava em duas linhas. No celular a
   base do quadro é resolvida por space-between e esta margem é zerada. */
.hero__cta {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: var(--s2); margin-top: 147px; max-width: 54ch;
}
.hero__microcopy { font-size: 0.875rem; color: rgba(239,231,217,.65); }
/* Linha de registro exclusiva do celular — no desktop o mesmo dado vem dentro
   do .hero__sub, que lá continua na tela. */
.hero__crm { display: none; }

@media (max-width: 899px) {
  /* Primeira tela inteira de retrato: a foto cobre a tela, o título centrado
     abre no topo, a doutora fica ao centro e o convite fecha na base. O svh
     ignora a barra do navegador que aparece e some — sem o pulo do vh.

     A altura da tela mora AQUI, num elemento só, e não numa corrente de
     `flex: 1` do .hero para o grid e do grid para o conteúdo. O motivo é
     prático: o Safari do iPhone não resolve altura de filho flexível contra
     `min-height` do pai, então a corrente se desfazia no aparelho e o
     `margin-top: auto` do convite ficava sem folga para distribuir — título,
     botão e nota colavam no alto da tela. Com um único elemento do tamanho da
     tela, o space-between separa título e convite sem depender de crescimento
     em cadeia, e o resultado é o mesmo em qualquer motor.

     O que é ancorado são as BORDAS QUE ENCOSTAM NA MODELO, não as folgas das
     pontas. Medido na régua, o retrato ocupa sempre a mesma faixa da tela —
     topo da cabeça em 35%, queixo em 69% —, porque o enquadramento é
     proporcional. Então as duas regras viram geometria:

       base do título  ≤ 31%   (4 pontos acima do cabelo)
       topo do botão   ≥ 75%   (6 pontos abaixo do queixo)

     Ancorar as folgas das pontas, como antes, não sustenta isso: título e
     convite têm altura fixa em px, que vira uma fatia maior da tela quanto
     menor o aparelho — o botão subia de 77% no 16 Pro Max para 61% num
     aparelho baixo, indo parar no queixo.

     Por isso a linha 1 do grid tem altura fixa em svh e o título é alinhado ao
     FIM dela: a base dele fica nos 31% em qualquer tela, não importa em
     quantas linhas o texto quebre. O `minmax(...,auto)` é a válvula: se o
     título realmente não couber, a linha cresce em vez de o texto subir para
     trás do cabeçalho.

     E o recuo de baixo deixa de ser 10% fixo: `25svh - 140px` é a conta que
     põe o topo do botão em 75% (140px ≈ a altura do bloco botão+notas), com
     teto de 10svh para o aparelho grande manter a proporção do desenho
     aprovado e piso na área segura do indicador de home do iPhone.
     A primeira linha de cada par é o recurso para navegador sem svh. */
  .hero { padding-block: 0; }
  .hero__grid { padding-top: 0; }
  .hero__content {
    --topo-seguro: calc(var(--header-h) + var(--header-border) + var(--s1));
    min-height: 100vh;
    min-height: 100svh;
    display: grid;
    grid-template-rows: auto 1fr;
    grid-template-rows: minmax(calc(31svh - var(--topo-seguro)), auto) 1fr;
    justify-items: center; text-align: center;
    padding-top: var(--topo-seguro);
    padding-bottom: var(--s3);
    padding-bottom: max(calc(env(safe-area-inset-bottom, 0px) + 12px), min(10svh, calc(25svh - 140px)));
  }
  .hero h1 { align-self: end; }      /* base do título presa nos 31% */
  .hero__cta { align-self: end; }    /* convite encostado na base do quadro */
  /* Enquadramento medido no pixel: o rosto está a 75,6% da largura e 30,8% da
     altura da foto. A altura da caixa é o que escala o retrato — 127% sobre o
     arquivo prolongado deixa a doutora 20% menor que o enquadramento original
     e 15% mais baixa (o arquivo hero-mobile-*.webp, ver index.html, já traz o
     cenário estendido para cima, então a foto alcança o alto do quadro sozinha
     e esses 23% a mais são justamente o trecho estendido).

     O ancoramento NÃO usa object-position em porcentagem: aquele valor mede a
     sobra entre imagem e quadro, que muda com a proporção da tela — o rosto
     escorregava de 39% num aparelho alto para 48% num baixo. Aqui a imagem
     recebe a largura natural (width:auto sobre a altura), a borda esquerda vai
     a 42% da tela e o translate de -75,6% recua a própria imagem até o ponto
     do rosto pousar exatamente nessa marca. Como as duas medidas são da mesma
     imagem, o rosto cai em 42% da largura e 55% da altura em QUALQUER
     telefone. A imagem fica ~1,86x mais larga que a altura da tela, então
     cobre a largura com folga mesmo no aparelho mais estreito.
     max-width precisa ser none: a regra geral de img limita a 100%. */
  .hero__bg img {
    height: 127%;
    width: auto; max-width: none;
    top: 0; bottom: auto; left: 42%; right: auto;
    transform: translateX(-75.6%);
    object-fit: fill;   /* a caixa já tem a proporção natural: nada a cortar */
  }
  /* Sem véu escuro no topo, a pedido: a foto agora chega lá por conta própria. */
  .hero__bg::before { background: none; }
  /* Degradê da base bem mais curto, a pedido: começa a nascer a 30% do pé da
     tela e só fecha em pinho sólido no limite com a seção seguinte. */
  .hero__bg::after {
    background: linear-gradient(0deg, var(--pinho) 0%, rgba(14,42,33,.6) 12%, rgba(14,42,33,0) 30%);
  }
  /* A sombra difusa garante a leitura da linha em sálvia onde ela cruza a
     testa iluminada do retrato — escurecer mais o scrim apagaria a foto. */
  .hero h1 {
    max-width: 24ch; margin-inline: auto;
    text-shadow: 0 2px 28px rgba(10,10,9,.65), 0 1px 4px rgba(10,10,9,.45);
  }
  /* A pedido, o parágrafo de apresentação sai do celular: ele atravessava o
     rosto e é a peça que mais competia com o retrato. O que não podia sair
     junto é o registro profissional — ele reaparece abaixo da microcópia,
     no .hero__crm. O restante (especialidades, atendimento) já é dito nas
     seções de serviços e no rodapé. */
  .hero__sub { display: none; }
  /* O space-between do .hero__content já encosta o convite na base; a margem
     de 147px herdada do desktop precisa sair do caminho. */
  .hero__cta { margin-top: 0; }
  /* A sombra é necessária, não decorativa: o fim das linhas cai sobre a luz
     da janela, onde o creme do texto contra o fundo mede 0,83:1 — o fundo
     fica MAIS claro que a letra e ela some. Escurecer a foto ali resolveria
     também, mas custaria o retrato limpo que a seção pede. */
  .hero__microcopy, .hero__crm {
    text-shadow: 0 1px 3px rgba(10,10,9,.9), 0 0 16px rgba(10,10,9,.75);
  }
  /* A microcópia deixou de ser o último filho e recuperou a margem de
     parágrafo; zerada aqui. O negativo abaixo desconta o gap do flex para
     sobrarem 10px entre as duas linhas — perto o bastante para lerem como uma
     nota só, longe o bastante para o registro não parecer sobra da frase. */
  .hero__microcopy { margin-bottom: 0; }
  .hero__crm {
    display: block;
    margin-top: calc(10px - var(--s2));
    font-size: 0.8125rem; letter-spacing: .04em;
    color: rgba(239,231,217,.85);   /* .7 media 4,16:1 sobre a foto — reprova AA */
  }

  /* Aparelho baixo. O retrato ocupa a mesma fatia da tela em qualquer aparelho,
     mas o texto tem altura fixa em px — numa tela curta ele vira uma fatia
     grande demais e invade as marcas: o título alcançava o cabelo (folga de
     -0,2 no 360x640) e o bloco do convite subia até o queixo. Encolher o
     retrato resolveria um lado e pioraria o outro, porque cabeça e queixo
     sobem juntos. Reduzir a tipografia é o único ajuste que devolve folga nas
     DUAS pontas. O teto em svh amarra o título à altura da tela, que é a
     dimensão que está faltando; a microcópia menor volta a caber em duas
     linhas, encurtando o bloco de baixo. */
  @media (max-height: 740px) {
    .hero h1 { font-size: min(clamp(2.125rem, 1.55rem + 2.9vw, 4rem), 4.4svh); }
    .hero__microcopy { font-size: 0.8125rem; }
    .hero__crm { font-size: 0.75rem; }
  }
  /* Tela estreita: com 40px de recuo lateral o rótulo do botão quebrava em
     duas linhas. Isso engorda o bloco de baixo em 28px e empurra o botão para
     cima, contra o queixo — o recuo menor devolve a linha única. */
  @media (max-width: 380px) {
    .hero__cta .btn { padding-inline: var(--s3); }
  }
}

@media (min-width: 900px) {
  .hero { padding-block: 0; }
  .hero__grid {
    /* o texto ocupa a coluna esquerda; a direita fica livre para o retrato */
    grid-template-columns: 1.05fr 0.95fr;
    gap: var(--s5); align-items: center;
    /* A primeira tela fecha cheia: o hero começa no topo (o margin-top negativo
       do .hero anula a altura do cabeçalho) e vai até a borda de baixo.
       Aqui havia um teto de 760px + cabeçalho dentro de um min(). Num monitor
       mais alto que isso o min() escolhia o teto, o hero parava antes do fim e
       a seção seguinte aparecia como uma faixa no rodapé da tela. O teto servia
       para o texto não se espalhar demais em tela alta, mas quem resolve isso é
       o align-items: center do grid, sem cortar a foto. */
    min-height: 100vh;
  }
  .hero__content { padding-block: var(--s6); }
}

/* ==================================================================== 2 · números */
.stats { border-top: 1px solid rgba(239,231,217,.10); }
.stats__grid { display: grid; gap: var(--s4); text-align: center; }
.stat { display: flex; flex-direction: column-reverse; gap: 6px; } /* número acima, label abaixo */
.stat__number {
  /* Elemento de assinatura 4 — número gigante */
  font-family: 'Newsreader', Georgia, serif;
  font-weight: 500;
  font-size: clamp(3.75rem, 2.2rem + 7vw, 7rem);   /* ~60 mobile → 112 desktop (80–120) */
  line-height: 1;
  color: var(--salvia);
  font-variant-numeric: lining-nums;
}
.stat__label {
  font: 600 0.75rem/1.5 'Manrope', sans-serif;
  text-transform: uppercase; letter-spacing: .16em;
  color: rgba(239,231,217,.65);
}
@media (min-width: 640px) {
  .stats__grid { grid-template-columns: repeat(3, 1fr); }
}

/* ==================================================================== 3 · sobre */
.about__grid { display: grid; gap: var(--s4); }
.about__photo {
  aspect-ratio: 4 / 5;
  border-radius: var(--r-img);
  box-shadow: var(--shadow);
  max-width: 480px;
}
.about__photo::after { background: linear-gradient(0deg, rgba(14,42,33,.55) 0%, rgba(14,42,33,0) 40%); }
.about__photo img { object-position: 50% 15%; }
.about__content h2 { margin-bottom: var(--s3); }
.about__content p { margin-bottom: var(--s2); max-width: 68ch; }

@media (min-width: 900px) {
  .about__grid { grid-template-columns: 5fr 7fr; gap: var(--s6); align-items: start; }
  .about__photo { position: sticky; top: calc(var(--header-h) + var(--s3)); }
}

/* ==================================================================== 4 · serviços */
.services__grid { position: relative; display: grid; gap: var(--s3); }

/* Linha de progresso: trilha tracejada + barra preenchida via GSAP (script.js
   §5). Tudo deriva de currentColor (grafite da seção) — nenhuma cor nova.
   Absolutas, fora do fluxo do grid; decorativas (aria-hidden) e transparentes
   ao mouse. No mobile (coluna única, sem gutter) a linha vira um trilho à
   esquerda dos cards, ligando as badges como nós de uma timeline; a partir de
   700px ela se move para o vão central entre as colunas. */
.services__grid { padding-left: 20px; }   /* abre espaço para o trilho no mobile */
.areas-track, .areas-fill {
  position: absolute; top: 0; bottom: 0;
  left: 7px;
  width: 2px;
  border-radius: var(--r-pill);
  pointer-events: none;
}
.areas-track {
  background: linear-gradient(to bottom, currentColor 0 7px, transparent 7px 16px);
  background-size: 100% 16px;
  opacity: .25;
}
@media (prefers-reduced-motion: no-preference) {
  /* tracejado "caminhando" devagar, como costura em movimento */
  .areas-track { animation: areas-dash 1.6s linear infinite; }
}
@keyframes areas-dash {
  to { background-position-y: 16px; }
}
.areas-fill {
  background: linear-gradient(to bottom, color-mix(in srgb, currentColor 55%, transparent), currentColor);
  transform: scaleY(0);        /* estado inicial; o GSAP leva a 1 com o scroll */
  transform-origin: top;
}
@media (min-width: 700px) {
  .services__grid { padding-left: 0; }
  /* no desktop a linha reta sai de cena: a trilha vira o zigue-zague em SVG
     gerado pelo script.js §5b, que serpenteia entre os cards */
  .areas-track, .areas-fill { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .areas-fill { display: none; }   /* sem o preenchimento animado, fica só a trilha estática */
}

/* Trilha zigue-zague (SVG injetado pelo script.js §5b, só ≥700px) */
.areas-zigzag {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
}
.areas-zigzag path {
  fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.areas-zigzag__track { stroke-dasharray: 8 7; opacity: .25; }
.areas-zigzag__fill { opacity: .8; }
@media (prefers-reduced-motion: no-preference) {
  /* tracejado "caminhando" devagar, como costura em movimento */
  .areas-zigzag__track { animation: zigzag-dash 1.6s linear infinite; }
}
@keyframes zigzag-dash {
  to { stroke-dashoffset: -15; }   /* múltiplo do padrão 8+7 — loop contínuo */
}

.card {
  display: flex; flex-direction: column; gap: var(--s2);
  background: var(--areia);
  border: 0; border-radius: var(--r-card);
  padding: 32px;
  transition: background .3s var(--ease), transform .3s var(--ease);
}
.card:hover { background: var(--creme); transform: translateY(-4px); }
.services .card:hover { box-shadow: var(--shadow); } /* areia→creme dentro de seção creme pede leve separação */
/* Badge do ícone ("nó"): anel + tinte derivados de currentColor (o terracota
   que o ícone já usava) — nenhuma cor nova. O gap de 16px do .card faz o papel
   da margem entre a badge e o título. */
.card__badge {
  width: 54px; height: 54px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  color: var(--terracota);
  border: 2px solid color-mix(in srgb, currentColor 35%, transparent);
  background: color-mix(in srgb, currentColor 10%, transparent);
  box-shadow: 0 2px 8px rgba(26,24,21,.08);   /* descola do areia sem virar sombra de card */
}
.card__icon { width: 22px; height: 22px; color: var(--terracota); }

@media (max-width: 767px) {
  .card__badge { width: 44px; height: 44px; }
}
.card__title {
  font-size: 1.375rem;   /* 22px */
  line-height: 1.25;
  margin: 0;
}
.card__text { font-size: 1rem; line-height: 1.65; margin: 0; }
.card__link { margin-top: auto; align-self: flex-end; }

/* Cards espalhados em zigue-zague (desktop): coluna da direita desce meio
   passo e cada card desloca um pouco para fora, com rotação alternada. A
   trilha tracejada (SVG gerado no script.js §5b) serpenteia entre eles. */
.services .card { position: relative; }
@media (min-width: 700px) {
  .services__grid { align-items: start; row-gap: var(--s4); }
  .services .card:nth-of-type(odd) {
    transform: rotate(-1.2deg) translateX(-14px);
  }
  .services .card:nth-of-type(even) {
    transform: rotate(1.2deg) translateX(14px);
    margin-top: 72px;             /* meio passo abaixo — cria o zigue-zague */
  }
  .services .card:nth-of-type(odd):hover  { transform: rotate(0deg) translateX(-14px) translateY(-4px); z-index: 2; }
  .services .card:nth-of-type(even):hover { transform: rotate(0deg) translateX(14px) translateY(-4px); z-index: 2; }
}

@media (min-width: 700px) {
  .services__grid { grid-template-columns: repeat(2, 1fr); }
}

/* ==================================================================== 5 · resultados & instagram */
/* minmax(0,1fr) e não a coluna `auto` implícita: `auto` não encolhe abaixo do
   conteúdo, e o card do perfil tem 345px de largura mínima — em telefone de
   até 390px isso esticava a grade além do container e a PÁGINA INTEIRA ganhava
   rolagem lateral. As duas variantes de desktop abaixo já usavam minmax(0,…);
   faltava aqui, que é justamente o caso do celular. */
.insta__grid { display: grid; gap: var(--s4); grid-template-columns: minmax(0, 1fr); }

/* Rótulo dos destaques — mesma voz do eyebrow, hierarquia de sub-bloco */
.insta__label {
  font: 600 0.75rem/1.4 'Manrope', sans-serif;
  text-transform: uppercase; letter-spacing: 0.16em;
  color: var(--pinho);
  margin: 0 0 var(--s3);
}
.insta__highlights { display: flex; flex-wrap: wrap; gap: var(--s3) var(--s4); }
.insta__hint { margin-top: var(--s3); font-size: 0.875rem; color: rgba(26,24,21,.62); }

/* Destaque no formato de story: anel segmentado (1 gomo por história, SVG
   montado no script.js §8) + capa circular. Sem JS o anel não aparece e o
   link leva ao perfil — nada quebra. */
.story {
  display: inline-flex; flex-direction: column; align-items: center; gap: 10px;
  text-decoration: none; color: var(--grafite);
}
.story__ring { position: relative; width: 96px; height: 96px; display: block; }
.story__segments { position: absolute; inset: 0; width: 100%; height: 100%; }
.story__seg {
  fill: none; stroke: var(--terracota);
  stroke-width: 5; stroke-linecap: round;
  transition: stroke .3s var(--ease);
}
.story__seg.is-viewed { stroke: rgba(26,24,21,.25); }
.story__avatar {
  position: absolute; inset: 8px;
  border-radius: 50%; overflow: hidden;
  background: var(--creme);
  box-shadow: inset 0 0 0 3px var(--areia);   /* respiro entre anel e capa */
}
.story__avatar img {
  width: 100%; height: 100%; object-fit: cover; border-radius: 50%;
  transition: transform .3s var(--ease);
}
.story:hover .story__avatar img { transform: scale(1.08); }
.story__name { font: 600 0.875rem/1.4 'Manrope', sans-serif; }

/* Cartão do perfil — demonstrativo do Instagram, no vocabulário do site */
.insta__profile {
  background: var(--creme);
  border-radius: var(--r-card);
  box-shadow: var(--shadow);
  padding: var(--s3);
  max-width: 462px;   /* 440 + 5%, a pedido do cliente */
}
.insta__head { display: flex; align-items: center; gap: 14px; margin-bottom: var(--s3); }
.insta__avatar { width: 56px; height: 56px; flex: none; border-radius: 50%; object-fit: cover; object-position: 50% 50%; }
.insta__id { display: flex; flex-direction: column; min-width: 0; }
.insta__user { font: 700 1rem/1.3 'Manrope', sans-serif; }
.insta__name { font-size: 0.8125rem; line-height: 1.4; color: rgba(26,24,21,.65); }
.insta__follow {
  margin-left: auto; flex: none;
  padding: 9px 18px; border-radius: var(--r-pill);
  background: var(--pinho); color: var(--creme);
  font: 600 0.8125rem/1.2 'Manrope', sans-serif; letter-spacing: .02em;
  text-decoration: none;
  transition: background .25s var(--ease), box-shadow .25s var(--ease);
}
.insta__follow:hover { background: var(--musgo); box-shadow: var(--shadow-cta); }
.insta__posts {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px;
  border-radius: 12px; overflow: hidden;
}
.insta__posts a { display: block; aspect-ratio: 1; }
.insta__posts img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: opacity .25s var(--ease), transform .3s var(--ease);
}
.insta__posts a:hover img { opacity: .88; transform: scale(1.03); }
.insta__link {
  display: inline-flex; align-items: center; gap: 8px;
  margin-top: var(--s2); padding-block: 6px;
  font: 600 0.875rem/1.4 'Manrope', sans-serif;
  color: var(--pinho); text-decoration: none;
  transition: color .25s var(--ease);
}
.insta__link:hover { color: var(--terracota); }
.insta__link .icon { width: 18px; height: 18px; }

/* Largura do texto de abertura da seção — espelha o max-width do
   .section-head. É a régua que posiciona o card no desktop. */
.insta { --intro-w: 720px; }

/* No celular os dois destaques ficam sozinhos numa faixa larga: alinhados à
   esquerda, sobrava um vazio de ~110px à direita que os deixava soltos na
   coluna. Centrados — com o rótulo acompanhando, senão ele ficaria pendurado
   fora do eixo do par —, o conjunto lê como um bloco só. A dica segue à
   esquerda: é frase corrida, e sozinha centrada viraria um terceiro eixo.
   No desktop nada muda: lá os destaques dividem a linha com o cartão do perfil
   e o alinhamento à esquerda é o que os prende à coluna de texto. */
@media (max-width: 899px) {
  .insta__highlights { justify-content: center; }
  .insta__label { text-align: center; }
}

@media (min-width: 900px) {
  /* piso de 240px na coluna esquerda: o suficiente para os dois destaques
     (2×96 + vão) não quebrarem em duas linhas */
  .insta__grid { grid-template-columns: minmax(240px, 1fr) minmax(0, 2.2fr); gap: var(--s5); align-items: center; }
  /* Só no desktop — no mobile o card segue o container. A subida de 5% vai em
     transform, não em margem: assim o bloco continua ocupando a mesma linha do
     grid e nada abaixo dele se desloca. Em porcentagem, o deslocamento
     acompanha a altura do card em qualquer largura de tela. */
  .insta__profile { justify-self: end; width: 100%; max-width: 508px; transform: translateY(-5%); }

  /* Miniaturas um pouco mais altas que a proporção nativa das fotos do perfil
     (1080×1350 = 4:5). A vertical é o único eixo livre do card: na horizontal
     ele está preso entre o fim do texto de abertura (--intro-w) e a borda do
     container. Em 5:7 o card fecha em 560px, 8% mais alto que os 519px de
     antes, ao custo de um corte lateral de cerca de 11% nas imagens. */
  .insta__posts a { aspect-ratio: 5 / 7; }
}

@media (min-width: 1200px) {
  /* Daqui para cima cabe ancorar o card no fim do texto de abertura: a
     coluna dele começa exatamente onde o parágrafo termina (--intro-w), de
     modo que o card não ocupa mais a faixa horizontal do texto. A borda
     direita acompanha o container, sem avançar sobre a margem da seção. */
  .insta__grid { grid-template-columns: calc(var(--intro-w) - var(--s5)) minmax(0, 1fr); }
  .insta__profile { max-width: none; }
}

/* Visualizador de stories (tela cheia, montado pelo script.js §8).
   Escuro de propósito — é o "modo Instagram", fora do ritmo areia/creme. */
.storyview {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(10,10,9,.96);
  display: grid; place-items: center;
}
.storyview[hidden] { display: none; }
.storyview__frame {
  position: relative; overflow: hidden;
  width: 100%; height: 100%;
  background: var(--fume);
}
@media (min-width: 700px) {
  .storyview__frame {
    width: min(430px, 92vw);
    height: min(88vh, 780px);
    border-radius: 18px;
  }
}
.storyview__top {
  position: absolute; top: 0; left: 0; right: 0; z-index: 3;
  padding: 10px 12px 18px;
  background: linear-gradient(180deg, rgba(10,10,9,.65), transparent);
}
.storyview__bars { display: flex; gap: 4px; }
.storyview__bar {
  flex: 1; height: 2px; border-radius: var(--r-pill);
  background: rgba(239,231,217,.3); overflow: hidden;
}
.storyview__bar-fill {
  display: block; width: 0; height: 100%;
  border-radius: inherit; background: var(--creme);
}
.storyview__head { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.storyview__avatar { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; object-position: 50% 50%; }
.storyview__id { display: flex; flex-direction: column; line-height: 1.25; }
.storyview__user { font: 600 0.875rem/1.3 'Manrope', sans-serif; color: var(--creme); }
.storyview__title { font-size: 0.75rem; color: rgba(239,231,217,.65); }
.storyview__close {
  margin-left: auto;
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  background: none; border: 0; cursor: pointer; color: var(--creme);
  transition: background .25s var(--ease);
}
.storyview__close:hover { background: rgba(239,231,217,.15); }
.storyview__close .icon { width: 20px; height: 20px; }
.storyview__stage {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  user-select: none; -webkit-user-select: none;
}
.storyview__img {
  max-width: 100%; max-height: 100%;
  object-fit: contain;
  opacity: 1; transition: opacity .2s var(--ease);
}
.storyview__img.is-loading { opacity: 0; }
/* Zonas de toque: terço esquerdo volta, o resto avança (como no Instagram).
   Sem tap-highlight: no toque, o realce padrão do navegador pintava a zona
   inteira como uma tarja escura por um instante. */
.storyview__nav {
  position: absolute; top: 64px; bottom: 0; z-index: 2;
  background: none; border: 0; cursor: pointer; padding: 0;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.storyview__nav--prev { left: 0; width: 33%; }
.storyview__nav--next { right: 0; width: 67%; }

/* Setas fora do quadro, como nos stories nativos do Instagram: círculos
   translúcidos no fundo escuro, centralizados na altura do quadro, a ~24px
   das bordas. No toque (telas pequenas) ficam de fora — as zonas de toque
   bastam e o quadro ocupa a tela toda. Na primeira história, a seta de
   voltar esmaece (dali ela só reinicia a própria história). */
.storyview__side {
  display: none;
  position: absolute; top: 50%; translate: 0 -50%; z-index: 4;
  width: 32px; height: 32px; border-radius: 50%;
  place-items: center;
  background: rgba(239,231,217,.16);
  border: 0; cursor: pointer; padding: 0;
  color: var(--creme);
  transition: background .25s var(--ease), opacity .25s var(--ease);
}
.storyview__side .icon { width: 18px; height: 18px; }
.storyview__side--prev { left: calc(50% - min(430px, 92vw) / 2 - 56px); }
.storyview__side--next { right: calc(50% - min(430px, 92vw) / 2 - 56px); }
.storyview__side:hover { background: rgba(239,231,217,.32); }
.storyview--first .storyview__side--prev { opacity: .35; }
@media (min-width: 700px) {
  .storyview__side { display: grid; }
}

/* ==================================================================== 6 · prova social */
.reviews__rating { margin-top: var(--s1); }
.reviews__stars { display: inline-flex; gap: 6px; }
.reviews__stars .icon--star { width: 22px; height: 22px; color: var(--dourado); }
.reviews__caption { margin: var(--s1) 0 0; color: rgba(239,231,217,.8); }

/* Estrelas das avaliações — mesma cor de assinatura, escala de legenda */
.reviews__stars--sm { gap: 3px; }
.reviews__stars--sm .icon--star { width: 15px; height: 15px; }

/* Atribuição: o nome é o link, e o ::after estende o clique ao card inteiro.
   O rótulo acessível continua sendo só "Nome, ver esta avaliação no Google",
   e não a avaliação toda, como aconteceria envolvendo o bloco num <a>. */
.reviews__link {
  font: 600 0.9375rem/1.4 'Manrope', sans-serif;
  color: var(--creme); text-decoration: none;
  transition: color .25s var(--ease);
}
.reviews__link::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.review:hover .reviews__link, .reviews__lead:hover .reviews__link { color: var(--salvia); }

/* Citação de abertura — o momento editorial da banda */
.reviews__lead { position: relative; margin: var(--s5) auto; text-align: center; }
.reviews__rule {
  display: block; width: 56px; height: 1px; margin: 0 auto var(--s3);
  background: var(--salvia); transform-origin: center;
}
.reviews__lead-quote { margin: 0; }
.reviews__lead-quote p {
  /* medida em em: a linha acompanha o corpo da citação em qualquer breakpoint */
  max-width: 21em; margin: 0 auto var(--s3);
  font: italic 400 clamp(1.5rem, 1.1rem + 1.7vw, 2rem)/1.34 'Newsreader', Georgia, serif;
  color: var(--creme); letter-spacing: -.01em;
  text-wrap: balance;
}
.reviews__lead-by { display: flex; flex-direction: column; align-items: center; gap: 6px; }

/* Pilha de avaliações ("stacking"): duas colunas de 6, cada .stack-item trava
   no topo (sticky) e o card seguinte sobe por baixo, cobrindo o anterior como
   baralho. O transform do efeito (scale/rotate, GSAP em script.js §6) fica no
   .review — NUNCA no .stack-item, porque transform em sticky quebra o sticky.
   Em coluna única (mobile) a pilha é travada em 620px de largura: sem isso,
   entre 700 e 900px a linha do card esticaria para ~90 caracteres.
   Ajustes: --stack-top = offset onde o card trava; escala/ângulo = script.js §6. */
.reviews__stacks {
  --stack-top: calc(var(--header-h) + var(--s3));
  display: grid; gap: var(--s3);
  max-width: 620px; margin-inline: auto;
}
.reviews__list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--s3);
}
.stack-item { position: sticky; top: var(--stack-top); }
.review {
  position: relative;
  display: flex; flex-direction: column;   /* permite empurrar o nome para o pé */
  background: var(--musgo);
  border: 1px solid rgba(239,231,217,.07);
  border-radius: var(--r-card);
  padding: var(--s3);
  will-change: transform;
  transform-origin: 50% 0;
  transition: border-color .3s var(--ease);   /* sem transição de transform: brigaria com o scrub */
}
.review:hover { border-color: rgba(163,194,168,.42); }
/* O card inteiro é clicável, então o foco de teclado cerca o card. Sem :has(),
   o anel padrão continua no link — por isso a regra fica dentro do @supports. */
@supports selector(:has(*)) {
  .review:has(.reviews__link:focus-visible),
  .reviews__lead:has(.reviews__link:focus-visible) {
    outline: 2px solid var(--creme); outline-offset: 3px; border-radius: var(--r-card);
  }
  .reviews__link:focus-visible { outline: none; }
}
.review__text { margin: var(--s2) 0 var(--s3); }
.review__text p {
  margin: 0 0 var(--s1); color: rgba(239,231,217,.92);
  font-size: 1.0625rem;   /* 17px: em duas colunas fecha a medida em ~55 caracteres */
}
.review__text p:last-child { margin-bottom: 0; }
/* o nome encosta no pé do card, então a linha de assinatura alinha entre todos */
.review__by { margin-top: auto; }

.reviews__more { text-align: center; margin-top: var(--s4); }
.reviews__source {
  margin: var(--s2) 0 0;
  font-size: 0.875rem; color: rgba(239,231,217,.72);
}

/* Duas colunas só a partir de 900px, junto com o resto do ritmo desktop: em
   768px a medida cairia para 26 caracteres por linha. `align-items: start`
   mantém a altura natural de cada coluna — esticá-las faria o último card da
   coluna mais curta ficar preso (sticky) por mais tempo que o conteúdo dela. */
@media (min-width: 900px) {
  .reviews__stacks {
    max-width: none;
    grid-template-columns: repeat(2, 1fr);
    align-items: start;
  }
}
@media (min-width: 1100px) {
  .review { padding: var(--s4); }
}
/* Em coluna única, 10 cards empilhados viram um trecho longo demais de rolagem
   no telefone: aqui a pilha mostra 6 (os dois últimos de cada lado saem). O
   corte acompanha o breakpoint das duas colunas — acima de 900px voltam os 10.
   O script ignora o que está oculto (script.js §6), então a pilha continua
   terminando no último card visível.

   O `display: contents` dissolve as duas <ul> e joga os seis <li> no mesmo
   container flex. É o que mantém o empilhamento contínuo: um sticky só se
   segura enquanto o bloco que o contém está na tela, então, com uma lista
   dentro da outra, a pilha soltava no fim da primeira e recomeçava do zero na
   segunda. Precisa ser flex, e não o grid do desktop: a área do grid vira o
   bloco contentor do item e prenderia cada card na própria linha. */
@media (max-width: 899px) {
  .reviews__stacks { display: flex; flex-direction: column; }
  .reviews__list { display: contents; }
  .reviews__list .stack-item:nth-child(n+4) { display: none; }
}
@media (max-width: 767px) {
  .reviews__stacks { --stack-top: calc(var(--header-h) + var(--s1)); }
}
/* Sem sticky nem transform com movimento reduzido: vira lista comum. */
@media (prefers-reduced-motion: reduce) {
  .reviews__stacks .stack-item { position: static; }
  .review { will-change: auto; transform: none !important; }
}

/* ==================================================================== 7 · FAQ */
.faq__list { border-top: 1px solid rgba(26,24,21,.12); }
.faq__item { border-bottom: 1px solid rgba(26,24,21,.12); }
.faq__q { margin: 0; font-size: inherit; }
.faq__q button {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  width: 100%; padding: var(--s3) 0;
  background: none; border: 0; cursor: pointer; text-align: left;
  font-family: 'Newsreader', Georgia, serif;
  font-size: 1.25rem; font-weight: 500; line-height: 1.35;
  color: var(--grafite);
}
.faq__icon { position: relative; width: 22px; height: 22px; flex: none; }
.faq__icon::before, .faq__icon::after {
  content: ""; position: absolute; inset: 0; margin: auto;
  background: var(--terracota);
  transition: transform .3s var(--ease), opacity .3s var(--ease);
}
.faq__icon::before { width: 14px; height: 1.5px; }
.faq__icon::after  { width: 1.5px; height: 14px; }
.faq__item.open .faq__icon::after { transform: rotate(90deg); opacity: 0; }

.faq__a {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .35s var(--ease);
}
.faq__item.open .faq__a { grid-template-rows: 1fr; }
.faq__a-inner { overflow: hidden; }
.faq__a-inner p { max-width: 65ch; padding-bottom: var(--s3); margin: 0; }

/* ==================================================================== 8 · localização */
.location__grid { display: grid; gap: var(--s4); }
.location__list { display: flex; flex-direction: column; gap: var(--s2); margin-top: var(--s3); }
.location__list li { display: flex; gap: var(--s2); align-items: flex-start; }
.location__icon { width: 22px; height: 22px; flex: none; color: var(--terracota); margin-top: 3px; }
/* padding-block em link inline expande a área de toque (~44px) sem mover as linhas */
.location__tel { font-weight: 600; text-underline-offset: 3px; padding-block: 10px; }
.location__tel:hover { color: var(--pinho); }
.location__actions { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s4); }

.location__map iframe {
  display: block; width: 100%; height: 380px;
  border-radius: var(--r-img);
  box-shadow: var(--shadow);
}

@media (min-width: 900px) {
  .location__grid { grid-template-columns: 1fr 1fr; gap: var(--s6); align-items: center; }
  .location__map iframe { height: 480px; }
}

/* ==================================================================== 9 · manifesto */
.manifesto {
  position: relative; overflow: hidden;
  background: var(--fume); color: var(--creme);
  text-align: center;
}
.manifesto__backdrop {
  /* FOTO sangrada de fundo — placeholder até a imagem real entrar */
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 90% at 72% 12%, rgba(169,118,74,.20), transparent 55%),
    radial-gradient(90% 80% at 18% 88%, rgba(27,58,46,.55), transparent 60%),
    var(--fume);
}
.manifesto__backdrop::after {
  content: ""; position: absolute; inset: 0;
  background: rgba(10,10,9,.45); /* overlay fumê para contraste do texto */
}
.manifesto__content { position: relative; z-index: 1; max-width: 880px; }
.manifesto__phrase {
  /* Caps editorial — só para frases-manifesto */
  font-family: 'Newsreader', Georgia, serif;
  font-weight: 500;
  font-size: clamp(1.5rem, 1.1rem + 2vw, 2.5rem);
  line-height: 1.4;
  text-transform: uppercase;
  letter-spacing: .14em;
  margin: 0 0 var(--s4);
}
.manifesto__chip { margin-bottom: var(--s4); }
.manifesto .signature { margin-top: var(--s5); }

/* ==================================================================== 10 · rodapé */
.site-footer { border-top: 1px solid rgba(239,231,217,.10); padding-block: var(--s5) var(--s4); }
.site-footer__grid { display: grid; gap: var(--s4); }
.site-footer__name {
  font-family: 'Newsreader', Georgia, serif;
  font-size: 1.25rem; font-weight: 500; line-height: 1.35;
  margin-bottom: var(--s1);
}
.site-footer__crm { font-size: 0.875rem; color: rgba(239,231,217,.7); margin-bottom: 4px; }

.site-footer__nav ul { display: flex; flex-direction: column; gap: 10px; }
.site-footer__nav a, .site-footer__social a {
  font: 500 0.9375rem/1.5 'Manrope', sans-serif;
  color: rgba(239,231,217,.8); text-decoration: none;
  /* área de toque ~44px; a margem negativa devolve quase todo o espaço visual */
  display: inline-block; padding-block: 11px; margin-block: -8px;
}
.site-footer__nav a:hover, .site-footer__social a:hover { color: var(--creme); text-decoration: underline; text-underline-offset: 3px; }
.site-footer__social { display: flex; flex-direction: column; gap: 10px; }

.site-footer__base {
  margin-top: var(--s5); padding-top: var(--s4);
  border-top: 1px solid rgba(239,231,217,.12);
  display: flex; flex-direction: column; gap: var(--s1);
  text-align: center;
}
.site-footer__signature {
  font-family: 'Newsreader', Georgia, serif; font-style: italic;
  font-size: 1.0625rem; letter-spacing: .06em;
  color: rgba(239,231,217,.6);
}
.site-footer__legal { font-size: 0.875rem; color: rgba(239,231,217,.65); }
.site-footer__copy { font-size: 0.8125rem; color: rgba(239,231,217,.55); } /* .45 media 3.66:1 — reprova AA */

@media (min-width: 900px) {
  .site-footer__grid { grid-template-columns: 1.4fr auto auto; gap: var(--s6); }
  .site-footer__nav ul { flex-direction: column; }
}

/* ============================================================ WhatsApp flutuante */
/* Único lugar do #25D366 em todo o site */
/* A doca carrega a posição; o botão, a aparência. A separação existe porque os
   dois estados têm naturezas opostas: o do scroll é preso ao dedo e não pode
   ter transição, o do menu é animado. Na mesma tag, um atrasaria o outro. */
.whatsapp-dock { position: fixed; right: 20px; bottom: 20px; z-index: 999; }
.whatsapp-float {
  width: 58px; height: 58px; border-radius: 50%;
  background: var(--whatsapp); color: #fff;
  display: grid; place-items: center;
  box-shadow: 0 8px 22px rgba(10,10,9,.30);
  transition: transform .26s var(--ease), opacity .26s var(--ease), visibility 0s;
  animation: wa-pulse 8s var(--ease) 4s infinite;
}
.whatsapp-float .icon { width: 30px; height: 30px; }
.whatsapp-float:hover { transform: scale(1.06); }

/* Com o menu aberto, o painel já traz o próprio CTA de WhatsApp: o flutuante
   cede o lugar em vez de pairar sobre o menu. Ele se recolhe para o canto
   onde mora (encolhe e desce) e volta pelo mesmo caminho, então o olho lê um
   objeto que sai e retorna, não dois cortes. A saída é mais rápida que a
   volta, que assenta na curva da casa. A visibilidade só desliga ao fim da
   saída: até lá o botão continua na tela, e depois dela sai do foco de
   teclado e do leitor de tela, em vez de virar um alvo invisível. O pulso
   pausa enquanto o botão está fora. Só no mobile, o único lugar onde existe
   menu para abrir.

   As duas curvas são diferentes de propósito. Na volta vale a da casa, que
   desacelera e assenta. Na saída ela não serve: por ser muito frontal, a
   opacidade zeraria nos primeiros 40ms e o encolhimento aconteceria com o
   botão já invisível. Com --ease-exit o botão segura a presença e só então
   acelera para fora, e o gesto é lido. */
@media (max-width: 899px) {
  body.menu-open .whatsapp-float {
    opacity: 0;
    transform: translateY(14px) scale(.72);
    visibility: hidden;
    pointer-events: none;
    animation-play-state: paused;
    transition: transform .16s var(--ease-exit), opacity .16s var(--ease-exit), visibility 0s linear .16s;
  }
}

@keyframes wa-pulse {
  0%   { box-shadow: 0 8px 22px rgba(10,10,9,.30), 0 0 0 0 rgba(37,211,102,.45); }
  7%   { box-shadow: 0 8px 22px rgba(10,10,9,.30), 0 0 0 16px rgba(37,211,102,0); }
  100% { box-shadow: 0 8px 22px rgba(10,10,9,.30), 0 0 0 0 rgba(37,211,102,0); }
}

/* ============================================== cromo que chega com o scroll */
/* No alto da página a barra é transparente sobre a foto do hero e a doca está
   vazia: a primeira tela é o retrato e a chamada, sem moldura em volta.
   Descendo, os dois chegam — em tempos diferentes de propósito, para a
   interface assentar em camadas em vez de piscar de uma vez.

   O progresso 0→1 vem do script.js §9 em custom properties, e a classe .cromo
   também: sem JS ou com movimento reduzido nada disso existe, o cabeçalho
   nasce sólido e o botão já está no lugar, como sempre foi. */

/* Em repouso a barra é transparente de verdade: só o verde entra, pelo
   background-color. Não há véu próprio aqui de propósito. Um véu protegeria a
   leitura do texto sobre a foto, mas ele terminaria exatamente na base da
   barra e essa borda apareceria como uma faixa escura sobre o retrato. E ele
   é dispensável: o scrim do próprio hero (.hero__bg::before) agora passa por
   baixo do cabeçalho e já entrega o contraste. Medido sobre os pixels reais da
   foto, o pior caso é 9,4:1 no desktop e 9,8:1 no mobile, contra o mínimo de
   4,5:1 — folga suficiente para a barra não precisar de fundo nenhum. */
.cromo .site-header {
  background-color: rgba(14, 42, 33, var(--cromo, 0));
  /* o fio da borda chega por último: é ele que diz que aquilo virou superfície */
  border-bottom-color: rgba(239, 231, 217, calc(.12 * var(--cromo-fio, 0)));
}

/* Com o menu aberto sobre o hero, a barra fecha em verde na hora: o painel do
   menu é pinho sólido e começa logo abaixo dela, então uma barra transparente
   deixaria a foto aparecendo acima de um painel opaco, como se fossem duas
   coisas. Fechado o menu, ela volta ao que a rolagem mandar.

   O verde entra numa camada própria, e não no background do cabeçalho, porque
   aquele fundo é preso ao scroll e não pode ter transição: aqui a transição é
   desejada, ali viraria atraso. Ela é curta de propósito — o painel do menu
   aparece de uma vez, e uma entrada longa deixaria a barra visivelmente
   atrasada em relação a ele. A borda fica de fora: barra e painel são o mesmo
   verde, e um fio entre os dois só inventaria uma divisão que não existe. */
@media (max-width: 899px) {
  .site-header::before {
    content: ""; position: absolute; inset: 0; z-index: -1;
    background: var(--pinho);
    opacity: 0;
    transition: opacity .16s var(--ease);
    pointer-events: none;
  }
  body.menu-open .site-header::before { opacity: 1; }
}

/* Preso ao scroll, sem transição: qualquer duração aqui viraria atraso em
   relação ao dedo. O botão cresce ao chegar, em vez de só aparecer. */
.cromo .whatsapp-dock {
  opacity: var(--flutuante, 0);
  transform: scale(calc(.82 + .18 * var(--flutuante, 0)));
  visibility: hidden;
  pointer-events: none;
}
.cromo.flutuante-dentro .whatsapp-dock { visibility: visible; pointer-events: auto; }
/* o pulso só começa depois que o botão assentou, nunca durante a chegada */
.cromo:not(.flutuante-firme) .whatsapp-float { animation-play-state: paused; }

/* ================================================================ abertura */
/* A capa: pinho sólido, a marca em Newsreader com o itálico da casa e a régua
   sálvia que risca — o mesmo gesto da prova social, reusado como assinatura de
   entrada em vez de um efeito novo. Sai como cortina que sobe (clip-path) e
   revela o hero, que também é escuro: a troca é tonal, nunca um flash.

   Tudo pende de html.abertura-ativa, aplicada por script inline no <head>:
   sem JS a capa não existe e a página nasce pronta. Os estados:
   .abertura-ativa mostra e trava a rolagem · .abertura-entra encena a chegada
   (fontes prontas, ver controlador no HTML) · .abertura-saida sobe a cortina.
   O controlador remove tudo ao fim, com teto de tempo. */
.abertura {
  position: fixed; inset: 0; z-index: 1200;   /* acima do menu (99) e da doca (999) */
  display: none;
  place-content: center; place-items: center;
  row-gap: var(--s2);
  padding: var(--s3);
  text-align: center;
  background: var(--pinho);
  color: var(--creme);
  clip-path: inset(0);
}
html.abertura-ativa .abertura { display: grid; }
/* nada rola por baixo da capa; solta assim que a cortina começa a subir */
html.abertura-ativa:not(.abertura-saida) { overflow: hidden; }

.abertura__area {
  margin: 0;
  font: 600 0.75rem/1 'Manrope', system-ui, sans-serif;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--salvia);
}

.abertura__marca {
  margin: 0;
  font: 500 clamp(1.875rem, 1.4rem + 2.4vw, 2.875rem)/1.15 'Newsreader', Georgia, serif;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.abertura__marca em { font-style: italic; color: var(--salvia); }

.abertura__regua {
  width: min(180px, 38vw);
  height: 2px;
  margin-top: var(--s1);
  background: var(--salvia);
  transform: scaleX(0);
  transform-origin: left center;
}

/* chegada: eyebrow, marca e régua em camadas, como a página assenta no scroll */
.abertura__area,
.abertura__marca {
  opacity: 0; translate: 0 14px;
  transition: opacity .51s var(--ease), translate .51s var(--ease);
}
.abertura__marca { transition-delay: .1s; }
html.abertura-entra .abertura__area,
html.abertura-entra .abertura__marca { opacity: 1; translate: 0 0; }

.abertura__regua { transition: transform .765s var(--ease) .32s; }
html.abertura-entra .abertura__regua { transform: scaleX(1); }

/* saída: o conteúdo despede primeiro, a cortina sobe logo atrás */
html.abertura-saida .abertura {
  clip-path: inset(0 0 100% 0);
  transition: clip-path .53s var(--ease-exit) .07s;
}
html.abertura-saida .abertura__area,
html.abertura-saida .abertura__marca,
html.abertura-saida .abertura__regua {
  opacity: 0; translate: 0 -12px;
  transition: opacity .26s var(--ease-exit), translate .26s var(--ease-exit);
}

/* ================================================================== motion */
/* Fade-up na entrada das seções (IntersectionObserver adiciona .is-visible).
   A classe .reveal é aplicada via JS — sem JS, tudo permanece visível. */
.reveal { opacity: 0; translate: 0 26px; transition: opacity .6s var(--ease), translate .6s var(--ease); }
.reveal.is-visible { opacity: 1; translate: 0 0; }

/* --- Prova social ---------------------------------------------------------
   Momento autoral da página: a régua sálvia risca, e a citação de abertura
   revela de cima para baixo por máscara, em vez do fade-up padrão. Tudo pende
   de .reveal, que só existe com JS — sem ele, o texto nasce visível. */
@property --wipe { syntax: '<percentage>'; inherits: false; initial-value: 0%; }

.reviews__lead.reveal { opacity: 1; translate: none; }
.reviews__lead.reveal .reviews__rule {
  transform: scaleX(0); transition: transform .55s var(--ease);
}
.reviews__lead.reveal.is-visible .reviews__rule { transform: scaleX(1); }

.reviews__lead.reveal .reviews__lead-quote {
  --wipe: -26%;
  -webkit-mask-image: linear-gradient(180deg, #000 var(--wipe), transparent calc(var(--wipe) + 26%));
          mask-image: linear-gradient(180deg, #000 var(--wipe), transparent calc(var(--wipe) + 26%));
  transition: --wipe 1.15s var(--ease) .16s;
}
.reviews__lead.reveal.is-visible .reviews__lead-quote { --wipe: 106%; }

/* As cinco estrelas do cabeçalho acendem em sequência — a nota é o argumento. */
.reviews__rating.is-visible .reviews__stars .icon--star {
  animation: star-in .5s var(--ease) both;
}
.reviews__rating.is-visible .icon--star:nth-child(1) { animation-delay: 240ms; }
.reviews__rating.is-visible .icon--star:nth-child(2) { animation-delay: 310ms; }
.reviews__rating.is-visible .icon--star:nth-child(3) { animation-delay: 380ms; }
.reviews__rating.is-visible .icon--star:nth-child(4) { animation-delay: 450ms; }
.reviews__rating.is-visible .icon--star:nth-child(5) { animation-delay: 520ms; }
@keyframes star-in {
  from { opacity: 0; transform: scale(.55) rotate(-14deg); }
  to   { opacity: 1; transform: none; }
}

/* ============================================================= desktop ≥900 */
@media (min-width: 900px) {
  body { font-size: 1.125rem; }               /* 18px */
  main > section, .site-footer { padding-block: 112px; }
  .site-footer { padding-block: var(--s6) var(--s4); }
  h3 { font-size: 1.75rem; }                  /* 28px */
  .card__title { font-size: 1.375rem; }
  .section-head { margin-bottom: var(--s5); }
}

/* ==================================================== prefers-reduced-motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* o script do <head> já não liga a capa; este é o cinto de segurança */
  .abertura { display: none !important; }
  html.abertura-ativa:not(.abertura-saida) { overflow: visible; overflow-x: clip; }
  .reveal { opacity: 1; translate: none; transition: none; }
  .reviews__lead.reveal .reviews__rule { transform: none; }
  .reviews__lead.reveal .reviews__lead-quote { -webkit-mask-image: none; mask-image: none; }
  .reviews__rating.is-visible .reviews__stars .icon--star { animation: none; }
  .whatsapp-float { animation: none; }
  /* sem movimento não há por que esperar: o atraso que segurava a
     visibilidade até o fim da saída também zera */
  body.menu-open .whatsapp-float { transition-delay: 0s; }
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
  }
}
