/* Página inicial pública do Be Visible Instagram — a landing comercial.

   Veio do desenho feito no Claude Design (projeto "Be Visible Instagram"). Ele é escuro
   no herói e cor de papel no resto: a marca acende (ouro sobre a noite) e
   depois assina (preto sobre o creme). O que foi acrescentado aqui é o que um
   desenho de tela larga não tem — respostas de tela, foco visível, contraste.

   Três ajustes de contraste, todos na mesma direção: o ouro claro é LUZ, não
   texto.
   1. #FFD697 só vive sobre o escuro. Sobre o creme ele some (1,4:1), então na
      parte clara o ouro que carrega texto é --ouro-forte (5,1:1) e o que é só
      grafismo — filete, ✓, numeral, seta — é --ouro.
   2. O cinza miúdo do desenho (#8A857B, 3,3:1) escureceu para #6A665D (5,2:1),
      o mesmo movimento que o painel já fazia.
   3. Sobre a noite, o texto apagado para em 58% de opacidade (6,4:1); abaixo
      disso o miúdo não passa AA.

   A exceção é o post do herói: lá dentro valem as cores do Instagram, não as
   nossas — ver o bloco "o post".

   O movimento tem um contrato só (ver o bloco "a luz"): o estado padrão de
   qualquer coisa animada é o estado FINAL, e o pré-estado (apagado, deslocado)
   só existe sob html[data-luz] — o atributo que o inline do <head> põe quando
   há JS e o visitante não pediu menos movimento. Sem JS ou com
   prefers-reduced-motion, nada daqui embaixo esconde conteúdo. Os dispositivos
   novos usam as mesmas quatro funções do ouro; nenhum texto novo fica abaixo
   de AA. */

:root {
  --noite: #141210;      /* o fundo da marca */
  --noite-2: #1D1915;    /* cartão sobre a noite */
  --papel: #FBF7F0;
  --branco: #FFFFFF;

  --tinta: #141210;
  --tinta-media: #2B2823;  /* o parágrafo-tese: preto que respira */
  --tinta-2: #55524B;
  --tinta-3: #6A665D;      /* miúdo; 5,2:1 sobre o papel */

  --linha: #EAE3D6;
  --linha-2: #F1EBDF;      /* divisória interna, mais fraca */
  --linha-3: #D9D2C6;      /* borda de pílula e trilho da linha do tempo */

  --ouro-claro: #FFD697;   /* só sobre a noite */
  --ouro: #B97E24;         /* grafismo sobre o papel */
  --ouro-forte: #8F5F14;   /* texto e link sobre o papel */
  --ouro-toque: #F3C271;   /* hover do botão de ouro */

  /* Texto sobre a noite, em três forças. */
  --claro: #FBF7F0;
  --claro-2: rgba(251, 247, 240, .72);
  --claro-3: rgba(251, 247, 240, .58);

  --e1: 4px;  --e2: 8px;  --e3: 12px; --e4: 16px; --e5: 20px;
  --e6: 24px; --e7: 32px; --e8: 40px; --e9: 64px; --e10: 96px;

  --r-p: 8px; --r-m: 12px; --r-g: 16px; --r-gg: 20px; --r-ggg: 24px;
  --r-redondo: 999px;

  --margem: var(--e5);
  --secao: var(--e9);   /* respiro entre seções; vira --e10 no desktop */

  --f-titulo: Lora, Georgia, 'Times New Roman', serif;
  --f-corpo: 'Hanken Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  /* As duas curvas do movimento: a da casa (a mesma da inclinação do post) e a
     do pulo, com overshoot, para as coisas que "pousam". */
  --curva: cubic-bezier(.2, .7, .3, 1);
  --curva-pulo: cubic-bezier(.34, 1.56, .64, 1);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--papel);
  color: var(--tinta);
  font-family: var(--f-corpo);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3 { font-family: var(--f-titulo); font-weight: 600; margin: 0; letter-spacing: -.02em; }
p { margin: 0; }
img { display: block; max-width: 100%; }
a { color: var(--ouro-forte); text-underline-offset: 3px; }
a:hover { color: var(--ouro); }
:focus-visible { outline: 2px solid var(--ouro-forte); outline-offset: 3px; border-radius: 2px; }
.capa :focus-visible { outline-color: var(--ouro-claro); }

/* ------------------------------------------------------------- estrutura */

.coluna { width: 100%; max-width: 1140px; margin: 0 auto; padding: 0 var(--margem); }
.secao { padding-top: var(--secao); }

.chapeu {
  font-size: 12px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ouro-forte);
}
.chapeu i { font-style: normal; color: var(--ouro); }   /* a faísca ✦ */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 56px; padding: 0 var(--e7);
  border: 0; border-radius: var(--r-redondo);
  background: var(--ouro-claro); color: var(--noite);
  font-family: var(--f-corpo); font-size: 17px; font-weight: 800;
  text-decoration: none; cursor: pointer; text-align: center;
}
.btn:hover { background: var(--ouro-toque); color: var(--noite); }
.btn:active { transform: translateY(1px); }
.btn-pequeno { min-height: 40px; padding: 0 var(--e5); font-size: 14px; font-weight: 700; }
.btn-tinta { background: var(--noite); color: var(--claro); }
.btn-tinta:hover { background: var(--tinta-media); color: var(--claro); }

.micro { font-size: 14px; color: var(--tinta-3); }

/* Legenda de figura sobre o papel (a .legenda vive na capa, em tom claro). */
.legenda-papel { margin-top: var(--e5); max-width: 46ch; margin-inline: auto; text-align: center; font-size: 13px; color: var(--tinta-3); }

/* ------------------------------------------------------------------ a luz */

/* O contrato da revelação: quem carrega [data-revela] acende sozinho ao entrar
   em cena; num [data-revela-filhos] quem acende são os filhos, em cascata (o
   JS escalona o transition-delay). O estado padrão é o final — o pré-estado só
   existe sob html[data-luz] e antes do [data-aceso] que o script põe. */
html[data-luz] [data-revela],
html[data-luz] [data-revela-filhos] > * {
  transition: opacity .55s var(--curva), transform .55s var(--curva);
}
html[data-luz] [data-revela]:not([data-aceso]),
html[data-luz] [data-revela-filhos]:not([data-aceso]) > * {
  opacity: 0; transform: translateY(14px);
}

/* A ilha escura acende um halo quando entra em cena — a mesma luz dos halos da
   capa, agora respondendo ao scroll. */
.preco-bloco { position: relative; overflow: hidden; }
.preco-bloco::after {
  content: ''; position: absolute; top: -160px; right: -120px;
  width: 440px; height: 440px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, rgba(255, 214, 151, .16) 0%, transparent 65%);
  opacity: .5; transition: opacity 1.2s var(--curva);
}
html[data-luz] .preco-bloco:not([data-aceso])::after { opacity: 0; }

/* Cartões respondem ao ponteiro com a gramática da casa: borda, não sombra. */
.passo, .frente, .combo {
  transition: transform .25s var(--curva), border-color .25s var(--curva);
}
.passo:hover, .combo:hover { transform: translateY(-2px); border-color: var(--ouro); }
.frente:hover { transform: translateY(-2px); border-color: rgba(255, 214, 151, .45); }

/* ------------------------------------------------------------------ capa */

/* A única faixa escura da página. Os dois halos são luz de fundo: ficam presos
   pelo overflow da faixa e nunca recebem clique. */
.capa { position: relative; overflow: hidden; background: var(--noite); color: var(--claro); }
.capa::before, .capa::after { content: ''; position: absolute; border-radius: 50%; pointer-events: none; }
.capa::before {
  top: -220px; right: -160px; width: 720px; height: 720px;
  background: radial-gradient(circle, rgba(255, 214, 151, .14) 0%, rgba(255, 214, 151, .05) 45%, transparent 70%);
}
.capa::after {
  bottom: -260px; left: -200px; width: 560px; height: 560px;
  background: radial-gradient(circle, rgba(185, 126, 36, .10) 0%, transparent 65%);
}
.capa .coluna { position: relative; }

.topo { min-height: 76px; display: flex; align-items: center; justify-content: space-between; gap: var(--e4); }
.topo-logo { height: 30px; width: auto; }
.topo-links { display: flex; align-items: center; gap: var(--e4); }
.topo-links a { color: var(--claro-2); text-decoration: none; font-size: 14px; font-weight: 600; }
.topo-links a:hover { color: var(--claro); }
/* O convite ao produto irmão é o primeiro a sair quando a tela aperta: ele
   volta inteiro, com preço, na tira de combo lá embaixo. */
.topo-irmao { display: none; }
/* "Preços" também espera a tela alargar: no celular o espaço do topo é do
   "Entrar", e a seção de preço chega rolando de qualquer jeito. */
.topo-precos { display: none; }
/* No celular o botão do topo também sai: o CTA grande do herói está logo
   abaixo, e o que precisa sobrar aqui em cima é o "Entrar" do cliente. */
.topo-cta { display: none; }
.topo-links .btn { color: var(--noite); }

/* O topo solto: quando a capa sai de vista, a barra volta flutuando — com o
   CTA junto, inclusive no celular. O padding-top na capa devolve a altura que
   a barra levou ao sair do fluxo; como isso só acontece com a capa já fora da
   tela, nada visível se move. */
body[data-topo-solto] .topo {
  position: fixed; inset: 0 0 auto; z-index: 10; min-height: 64px;
  padding-inline: max(var(--margem), calc((100% - 1140px) / 2 + var(--margem)));
  background: rgba(20, 18, 16, .94);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border-bottom: 1px solid rgba(255, 214, 151, .16);
  animation: descer .3s var(--curva);
}
body[data-topo-solto] .capa { padding-top: 76px; }
body[data-topo-solto] .topo-logo { height: 28px; }
body[data-topo-solto] .topo-cta { display: inline-flex; }
@keyframes descer { from { transform: translateY(-100%); } }

/* ----------------------------------------------------------------- herói */

.heroi { padding: var(--e8) 0 var(--e9); }
.heroi .chapeu { color: var(--ouro-claro); }
.heroi .chapeu i { color: var(--ouro-claro); }
.titulo {
  margin-top: var(--e5);
  font-size: clamp(34px, 8.6vw, 44px); line-height: 1.08; letter-spacing: -.02em;
  text-wrap: balance;
}
.titulo em { font-style: normal; color: var(--ouro-claro); }
.olho { margin-top: var(--e6); max-width: 46ch; font-size: 17px; color: var(--claro-2); }

.acoes { margin-top: var(--e7); display: flex; align-items: center; gap: var(--e6); flex-wrap: wrap; }
.acoes .preco { font-size: 14px; color: var(--claro-3); }

/* ------------------------------------------------------------- o post */

/* O produto na vitrine é um post de verdade, saído do editor: as cinco páginas
   do carrossel "Guia de bairro" da Ricardo Imob. A moldura imita o Instagram de
   propósito — fonte do sistema, ícones de contorno, barra de ações, os pontos
   azuis — porque é isso que se promete: o feed do corretor, não uma vitrine
   nossa. Daí as cores daqui de dentro serem as do Instagram e não as da marca.

   O recorte é a parte honesta: os templates desenham em 3:4 e é o navegador que
   corta para 4:5 na hora de publicar (ver o README). `aspect-ratio: 4/5` com
   `object-fit: cover` sobre a arte 3:4 refaz exatamente esse corte — 45px em
   cada borda —, então o que se vê aqui é o que vai ao ar. */
.produto { margin: 0; }

/* A caixa é o objeto sobre a mesa: ela carrega a inclinação e o adesivo, para
   que o cartão do Instagram lá dentro continue sendo só o Instagram. O torto
   fica pequeno de propósito — 2,5° dá vida sem borrar o texto da arte — e some
   quando o ponteiro chega: quem vai arrastar o carrossel recebe ele reto.
   No celular ele nasce reto; ali o post já está numa tela de telefone, e a
   diagonal só custaria as quinas, cortadas pela margem da coluna. */
.produto-caixa { position: relative; width: 100%; max-width: 340px; margin: 0 auto; }

.selo-auto {
  position: absolute; z-index: 2; top: -13px; right: -10px;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 15px; border-radius: var(--r-redondo);
  background: var(--ouro-claro); color: var(--noite);
  font-family: var(--f-corpo);
  font-size: 11.5px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  white-space: nowrap;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .5);
}
.selo-auto i { font-style: normal; font-size: 13px; line-height: 0; }

.ig {
  --ig-tinta: #262626;
  --ig-cinza: #737373;   /* o cinza do próprio Instagram; 4,7:1 no branco */
  --ig-linha: #DBDBDB;
  --ig-azul: #0095F6;

  width: 100%;
  background: #FFFFFF; color: var(--ig-tinta);
  border-radius: var(--r-m); overflow: hidden;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .5);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  font-size: 14px; line-height: 1.4;
}

.ig-topo { display: flex; align-items: center; gap: 10px; padding: 12px 14px; }
.ig-avatar {
  width: 32px; height: 32px; flex: none; border-radius: 50%;
  background: #16202A; color: #F6F1E9;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; letter-spacing: .06em;
}
.ig-quem { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.ig-quem b { font-size: 13px; font-weight: 600; }
.ig-quem span { font-size: 11px; color: var(--ig-cinza); }
.ig-menu { margin-left: auto; font-size: 15px; letter-spacing: 1px; color: var(--ig-tinta); }

/* --------------------------------------------------------------- a mídia */

.ig-media { position: relative; }
/* Sem JS o trilho continua deslizando no dedo; o script só acrescenta setas,
   pontos e contador vivos. */
.ig-trilho {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; -ms-overflow-style: none;
}
.ig-trilho::-webkit-scrollbar { display: none; }
/* `height: auto` é obrigatório: os atributos width//height do <img> entram como
   height:960px e ganhariam do aspect-ratio, esticando a página inteira. */
.ig-trilho img {
  width: 100%; height: auto; flex: none; scroll-snap-align: center;
  aspect-ratio: 4 / 5; object-fit: cover;   /* o recorte de publicação */
  background: #16202A;
}

.ig-seta {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 26px; height: 26px; padding: 0; border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .85); color: #262626;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; opacity: 0; transition: opacity .15s;
}
.ig-seta svg { width: 16px; height: 16px; }
.ig-seta[data-seta="-1"] { left: 10px; }
.ig-seta[data-seta="1"] { right: 10px; }
.ig-seta:disabled { display: none; }
/* Setas são coisa de ponteiro: no dedo, o gesto é arrastar. */
@media (hover: hover) {
  .ig-media:hover .ig-seta, .ig-seta:focus-visible { opacity: 1; }
}

/* As reações que pousam durante a passada automática. Invisíveis por padrão —
   só existem enquanto o keyframe roda, disparado pelo script no tick do
   autoplay (morrem junto com ele: gesto, aba oculta, menos movimento). Elas
   NUNCA mexem nos números do pé — é interface encenada, não engajamento. */
.ig-reacao {
  position: absolute; z-index: 2; pointer-events: none; opacity: 0;
}
.ig-reacao svg { width: 26px; height: 26px; display: block; }
.ig-reacao-coracao { left: 12px; bottom: -8px; color: #FF3040; }
.ig-reacao-coracao svg { filter: drop-shadow(0 4px 10px rgba(0, 0, 0, .35)); }
.ig-reacao-salvo {
  top: 12px; right: 12px;
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(20, 18, 16, .88); color: #FFFFFF;
  border-radius: var(--r-redondo); padding: 7px 12px;
  font-size: 11.5px; font-weight: 700;
}
.ig-reacao-salvo svg { width: 14px; height: 14px; }
.ig-reacao-salvo b { font-weight: 700; }
.ig-reacao[data-pousa] { animation: pousar 1.4s var(--curva-pulo); }
@keyframes pousar {
  0%       { opacity: 0; transform: translateY(8px) scale(.6); }
  18%      { opacity: 1; transform: none; }
  72%      { opacity: 1; transform: none; }
  100%     { opacity: 0; transform: translateY(-10px) scale(.9); }
}

/* ----------------------------------------------------------------- o pé */

.ig-pe { padding: 10px 14px 14px; }
.ig-acoes { position: relative; display: flex; align-items: center; gap: var(--e3); min-height: 28px; }
.ig-acoes svg { width: 23px; height: 23px; display: block; }
.ig-salvar { margin-left: auto; display: flex; }
.ig-icones { display: flex; gap: var(--e3); }
/* Os pontos ficam centrados na barra, como no Instagram da web — e centrados
   na largura do cartão, não no espaço que sobra entre os ícones. */
.ig-pontos {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: flex; gap: 4px;
}
.ig-pontos span { width: 6px; height: 6px; border-radius: 50%; background: #C7C7C7; transition: background .2s; }
.ig-pontos span[data-atual] { background: var(--ig-azul); }

.ig-curtidas { margin-top: 10px; font-size: 14px; font-weight: 600; }
.ig-legenda { margin-top: 4px; font-size: 14px; }
.ig-legenda b { font-weight: 600; }
.ig-legenda i { font-style: normal; color: var(--ig-cinza); }
.ig-comentarios { margin-top: 4px; font-size: 14px; color: var(--ig-cinza); }
.ig-tempo { margin-top: 6px; font-size: 10px; letter-spacing: .02em; text-transform: uppercase; color: var(--ig-cinza); }

.legenda { margin-top: var(--e5); max-width: 44ch; margin-inline: auto; text-align: center; font-size: 13px; color: var(--claro-3); }

/* --------------------------------------------------------- a constância */

.titulo-secao { font-size: clamp(28px, 6.6vw, 40px); line-height: 1.15; }
.chapeu + .titulo-secao { margin-top: var(--e4); }
/* 26ch quebra este título em três linhas — a medida foi ajustada quando ele
   deixou de ser a pergunta curta ("E no próximo?") e virou a frase inteira. */
.constancia .titulo-secao { max-width: 26ch; }
.subtitulo { margin-top: var(--e4); max-width: 60ch; font-size: 17px; color: var(--tinta-2); }

/* Quatro meses como uma régua: o filete de cima é o mês, e só o primeiro é
   preto — é o único em que alguma coisa aconteceu. */
.etapas { margin-top: var(--e8); display: grid; gap: var(--e6); }
.etapa { border-top: 2px solid var(--linha-3); padding-top: var(--e5); }
.etapa:first-child { border-top-color: var(--tinta); }
.etapa b { font-family: var(--f-titulo); font-size: 15px; color: var(--ouro-forte); }
.etapa h3 { margin-top: var(--e2); font-family: var(--f-corpo); font-size: 18px; font-weight: 700; letter-spacing: 0; }
.etapa p { margin-top: var(--e2); font-size: 15px; color: var(--tinta-2); }

/* ------------------------------------------- o perfil que se preenche */

/* A materialização da régua: um perfil de Instagram que começa com dois posts
   e se completa conforme a página anda (o script marca data-cheio célula a
   célula, sem nunca voltar). Sem luz, nasce cheio. Como no post do herói, a
   moldura usa fonte de sistema — é o Instagram do persona, não a nossa página. */
.perfil { margin: var(--e8) auto 0; max-width: 420px; }
.perfil-moldura {
  background: var(--branco); border: 1px solid var(--linha); border-radius: var(--r-m);
  overflow: hidden;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}
.perfil-topo { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--linha-2); }
.perfil-avatar {
  width: 36px; height: 36px; flex: none; border-radius: 50%;
  background: #16202A; color: #F6F1E9;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; letter-spacing: .06em;
}
.perfil-quem { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.perfil-quem b { font-size: 13.5px; font-weight: 600; color: #262626; }
.perfil-quem span { font-size: 11.5px; color: #737373; }

.perfil-grade { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2px; background: var(--branco); }
/* A célula vazia é a semana que ainda não chegou: papel com tracejado. O
   tracejado nasce invisível (estado final = grade cheia) e só aparece, sob a
   luz, enquanto a célula espera o data-cheio. */
.perfil-post { position: relative; background: #F4EFE6; box-shadow: inset 0 0 0 1px var(--linha-3); }
.perfil-post::after {
  content: ''; position: absolute; inset: 6px; border-radius: 4px;
  border: 1px dashed var(--linha-3); pointer-events: none;
  opacity: 0; transition: opacity .5s var(--curva);
}
html[data-luz] .perfil-post:not([data-cheio])::after { opacity: 1; }
.perfil-post img {
  position: relative; width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover;
  transition: opacity .5s var(--curva), transform .5s var(--curva);
}
html[data-luz] .perfil-post:not([data-cheio]) img { opacity: 0; transform: scale(.92); }

.tese { margin-top: var(--e8); max-width: 62ch; font-size: 18px; color: var(--tinta-media); }
.tese em { font-style: normal; border-bottom: 3px solid var(--ouro-claro); }

/* ------------------------------------------------------- o campo de luz */

/* A jornada da marca encenada: um céu de pontos (o mercado do corretor) que
   acende em quatro estágios, do "você é um ponto entre cento e tantos" até uma
   pessoa com nome te chamando. É a única faixa escura fora do herói — o lugar
   que era da conta da comissão, porque é o argumento que precisa de silêncio
   em volta.

   Três decisões seguram a cena inteira; mexer nelas é refazê-la:

   1. Não há moldura. A caixa é só a medida — quadrada, igual ao viewBox, para
      uma unidade do SVG valer sempre 1/120 dela. O céu se dissolve na noite por
      uma máscara radial: sem borda e sem cartão, o campo não tem fim visível.
      A medida quadrada é também o que deixa o recado da Marina (HTML, fora do
      SVG) pousar em cima do ponto dela, por --mx/--my.
   2. A luz tem uma causa. Uma onda sai de você a cada ciclo — é o post da
      semana — e cada ponto acende quando ela passa por cima, com o atraso do
      seu próprio --d. Os pontos não "aparecem": são alcançados. O estágio manda
      só em até onde a luz chega (anel 1, 2, 3); a onda manda no ritmo.
   3. Você é a marca da Be Visible desenhada em oito braços, e ela se monta ato a ato:
      no 1 você é do tamanho de qualquer outro ponto, no 4 está inteira. Os oito
      fios saem da ponta dos oito braços — a relação é a luz continuando.

   O contrato da luz vale inteiro aqui: o estado base de todo seletor abaixo é
   o ESTÁGIO 4. Os estágios 1 a 3 são regressões declaradas só sob
   html[data-luz] .campo-corpo[data-estagio="n"], e o landing.js só escreve o
   atributo quando há luz. As animações contínuas (a onda, a faísca, o eco do
   ato) são acréscimo pelo mesmo caminho: nascem desligadas e só existem sob
   html[data-luz]. Sem JS, sem data-luz ou com prefers-reduced-motion a cena
   nasce completa e parada, com o céu inteiro aceso e o recado na tela.

   Cuidado ao mexer: o palco é sticky, então nenhum ancestral dele pode ganhar
   overflow: hidden — o halo daqui é preso por ::before com inset, nunca
   cortando o pai.

   O nome é `campo-luz`, e não `campo`: `.campo` já é o par rótulo+input dos
   formulários (publico.css, painel.css) desde muito antes desta cena. Este
   arquivo é carregado JUNTO com o publico.css nas telas de /entrar e /assinar,
   as duas classes se encontrariam lá dentro, e a seção escura de página inteira
   vestiria cada campo do checkout. Nada aqui pode se chamar por um nome que os
   formulários já usam. */

.campo-luz {
  position: relative;
  margin-top: var(--secao);
  padding: var(--secao) 0;
  background: var(--noite);
  color: var(--claro);
}
.campo-luz::before {
  content: ''; position: absolute; inset: 0; overflow: hidden; pointer-events: none;
  background:
    radial-gradient(620px 420px at 78% 8%, rgba(255, 214, 151, .10) 0%, transparent 70%),
    radial-gradient(520px 380px at 12% 92%, rgba(185, 126, 36, .10) 0%, transparent 70%);
}
.campo-luz > .coluna { position: relative; }

/* ---- o céu de fundo: o campo não acaba na caixa

   Uma segunda camada de pontos, esparsa e fraca, ocupando a seção inteira. O
   palco vira o miolo aceso de uma coisa maior, e o quadrado some de vez.

   Dois cuidados que não são estilo, são mecânica:

   1. `overflow: clip`, nunca `hidden`. O hidden faria desta caixa um contêiner
      de rolagem, e a camada sticky lá dentro passaria a grudar NELA — ou seja,
      pararia de grudar. O clip recorta sem virar scroller.
   2. A camada de estrelas é sticky em 100vh: enquanto os atos passam, elas
      ficam paradas na tela, no mesmo compasso do palco. É esse descolamento
      entre o que anda (o texto) e o que fica (o céu) que dá a profundidade.

   Fica na camada de baixo, antes da .coluna na ordem do DOM, e não intercepta
   ponteiro nenhum. */
.campo-fundo {
  position: absolute; inset: 0; z-index: 0;
  overflow: clip; pointer-events: none;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 6%, #000 94%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 6%, #000 94%, transparent 100%);
}
.campo-estrelas { position: sticky; top: 0; height: 100vh; }
.campo-estrelas span {
  position: absolute; left: var(--x); top: var(--y);
  width: var(--r); height: var(--r); margin: calc(var(--r) / -2);
  border-radius: 50%; background: var(--ouro-claro); opacity: var(--o);
}
.campo-estrelas span[data-viva] { box-shadow: 0 0 9px 1px rgba(255, 214, 151, .3); }
/* Cada estrela respira no seu tempo (o atraso é negativo, para nenhuma esperar
   a primeira volta) — e o topo da respiração é o estado base, sem luz. */
@keyframes campo-cintila {
  from { opacity: calc(var(--o) * .4); }
  to   { opacity: var(--o); }
}

.campo-abre { max-width: 60ch; }
.campo-abre .chapeu { color: var(--ouro-claro); }
.campo-abre .chapeu i { color: var(--ouro-claro); }
.campo-abre h2 { margin-top: var(--e4); font-size: clamp(26px, 6.2vw, 36px); line-height: 1.18; }
.campo-abre > p { margin-top: var(--e5); font-size: 17px; color: var(--claro-2); }

.campo-corpo { margin-top: var(--e8); display: grid; gap: var(--e7); align-items: start; }

/* ---- o palco (sticky)

   No celular ele gruda no alto e os atos correm por baixo — daí o fundo opaco
   e o z-index, que o mantêm acima do texto que sobe. O 64px é a altura da
   barra do topo quando ela volta flutuando (z-index 10, sempre por cima). */

/* O fundo opaco sangra até a borda da tela (margem negativa devolvida em
   padding): sem isso ele para na coluna e sobram duas faixas de céu de fundo
   ao lado dele, que leem como emenda. No desktop nada disso existe — lá o
   palco não tem fundo. */
.campo-palco {
  margin: 0 calc(var(--margem) * -1); position: sticky; top: 64px; z-index: 2;
  padding: 0 var(--margem) var(--e4); background: var(--noite);
}
/* A saia do palco: sem ela o ato que sobe é decepado no fio da borda opaca.
   Aqui ele se apaga. No desktop nada corre por baixo e a saia some. */
.campo-palco::after {
  content: ''; position: absolute; left: 0; right: 0; top: 100%; height: var(--e8);
  background: linear-gradient(180deg, var(--noite) 0%, rgba(20, 18, 16, 0) 100%);
  pointer-events: none;
}
/* A caixa é quadrada porque o viewBox é: só assim 1 unidade do SVG = 1/120 da
   caixa, que é a régua que o recado da Marina usa. O `width` faz o quadrado
   (aspect-ratio + max-height não faria: a altura seria limitada e a largura
   não). Sem borda e sem fundo de cartão — o pouco de brilho é o do próprio
   campo, e a máscara dissolve as beiradas na noite. */
.campo-ceu {
  position: relative;
  width: min(100%, 46vh);
  aspect-ratio: 1 / 1;
  margin-inline: auto;
  background: radial-gradient(circle at 50% 50%, rgba(255, 214, 151, .055) 0%, transparent 62%);
  overflow: hidden;
}
.campo-ceu svg {
  width: 100%; height: 100%; display: block;
  -webkit-mask-image: radial-gradient(78% 78% at 50% 50%, #000 0 60%, rgba(0, 0, 0, .55) 82%, transparent 100%);
  mask-image: radial-gradient(78% 78% at 50% 50%, #000 0 60%, rgba(0, 0, 0, .55) 82%, transparent 100%);
}

/* ---- a onda: o post da semana saindo de você

   O raio é um scale() (o `r` não é animável em todo motor) sobre um círculo de
   raio 1, com vector-effect para o traço não engordar com ele. O ciclo e o
   alcance (scale 2 → 85, que é o canto do viewBox) conversam com o atraso de
   cada ponto, que é o --d dele vezes o ciclo: no instante em que a onda cruza o
   ponto, é ele que acende. Mexeu num, mexa no outro. */
.campo-corpo { --onda-ciclo: 6s; }
.ceu-onda circle {
  fill: none; stroke: var(--ouro-claro); stroke-width: 1.6;
  transform-origin: var(--centro); opacity: 0;
}
@keyframes campo-onda {
  0%   { transform: scale(2);  opacity: 0; }
  7%   { opacity: .20; }
  70%  { opacity: .09; }
  100% { transform: scale(85); opacity: 0; }
}

/* ---- o céu

   A opacidade do estágio mora no grupo do anel e o brilho da onda no ponto: as
   duas se multiplicam, em vez de a animação atropelar a transição. O atraso por
   anel é só cortesia — a luz chega antes perto e depois longe. */
.ceu-pontos g { transition: opacity .8s var(--curva); }
.ceu-pontos g[data-anel="1"] { opacity: .95; }
.ceu-pontos g[data-anel="2"] { opacity: .74; transition-delay: .12s; }
.ceu-pontos g[data-anel="3"] { opacity: .48; transition-delay: .26s; }
.ceu-pontos circle { fill: var(--ouro-claro); }

/* O ponto acende no clarão e volta para um ouro de brasa até a onda seguinte. */
@keyframes campo-acende {
  0%        { fill: #FFF6E6; }
  14%       { fill: var(--ouro-claro); }
  46%, 100% { fill: #BC9257; }
}

/* O traço se desenha por dashoffset, e os números são 1 porque o <line> carrega
   pathLength="1" — com ele o dash passa a falar em fração da linha, não em
   comprimento. Nada de vector-effect: non-scaling-stroke mede o dasharray em
   pixels de tela e briga com o pathLength, e o fio sai tracejado. Por isso a
   espessura também é em unidade de viewBox (1 unidade ≈ 4px na tela). */
.ceu-fios line, .marina-fio {
  stroke: var(--ouro-claro); stroke-width: .3; opacity: .45;
  stroke-dasharray: 1; stroke-dashoffset: 0;
  transition: stroke-dashoffset 1.1s var(--curva), opacity .7s var(--curva);
}
/* A ponta de cada fio é um conhecido: o ponto anônimo ganha um anel em volta. */
.ceu-conhecidos circle {
  fill: none; stroke: var(--ouro-claro); stroke-width: .26; opacity: .3;
  transition: opacity .7s var(--curva);
}

/* ---- a Marina: o único ponto do céu com nome */

.marina-fio { opacity: .8; stroke-width: .4; }
.marina-brilho { fill: url(#brilho-marina); }
.marina-anel { fill: none; stroke: var(--ouro-claro); stroke-width: .34; opacity: .6; }
/* O rabicho só existe onde o recado pende do ponto: no celular ele é uma tarja
   no pé do campo, e um fio apontando para o nada seria só sujeira. */
.marina-rabo { stroke: var(--ouro-claro); stroke-width: .38; opacity: 0; }
/* Até o ato 4 ela é um ponto como os outros — mesmo ouro, quase o mesmo raio.
   O que a distingue no fim não é o ponto: é o brilho, o anel e o fio. */
.marina-ponto { fill: var(--ouro-claro); }
.marina-brilho, .marina-anel, .marina-rabo, .marina-fio {
  transition: opacity .7s var(--curva), stroke-dashoffset 1.1s var(--curva);
}

/* A faísca corre no sentido contrário do fio — dela para você. Um dash de 10%
   da linha passeando pelo dashoffset; some no fim e espera a volta. */
.marina-faisca {
  stroke: #FFF6E6; stroke-width: .75; stroke-linecap: round;
  stroke-dasharray: .1 1; stroke-dashoffset: 0; opacity: 0;
}
@keyframes campo-faisca {
  0%        { stroke-dashoffset: 0;    opacity: 0; }
  8%        { opacity: 1; }
  44%       { stroke-dashoffset: -1.02; opacity: 1; }
  50%, 100% { stroke-dashoffset: -1.02; opacity: 0; }
}

/* ---- você: o halo, a marca em oito braços e o núcleo

   O brilho é um gradiente do <defs> (um círculo chapado em opacity vira um
   disco sujo). A marca usa transform-origin em unidades de viewBox, que é o
   default de transform-box em SVG — daí o --centro vir do markup. */
.voce-halo { fill: url(#brilho-voce); transition: opacity .8s var(--curva); }
.voce-marca {
  transform-origin: var(--centro);
  transition: transform .9s var(--curva-pulo), opacity .9s var(--curva);
}
.voce-marca path {
  fill: none; stroke: var(--ouro-claro); stroke-width: .55; stroke-linejoin: round;
  transition: opacity .7s var(--curva);
}
.voce-nucleo { fill: #FFF6E6; }
@keyframes campo-respira {
  0%, 100% { opacity: .74; }
  8%       { opacity: 1; }
}

/* ---- o recado: onde a cena abstrata vira uma pessoa

   Sem backdrop-filter de propósito: sobre a noite ele não acrescenta nada e
   custa uma camada composta a mais numa cena que já anima. */
.campo-recado {
  position: absolute; left: var(--e3); right: var(--e3); bottom: var(--e3);
  padding: var(--e4);
  border-radius: var(--r-g);
  background: linear-gradient(180deg, #251F19 0%, #1A1613 100%);
  border: 1px solid rgba(255, 214, 151, .26);
  box-shadow: 0 18px 44px rgba(0, 0, 0, .5);
  transition: opacity .6s var(--curva), transform .6s var(--curva-pulo);
}
.recado-quem { display: flex; align-items: center; gap: var(--e2); }
.recado-avatar {
  width: 26px; height: 26px; flex: none; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255, 214, 151, .14); color: var(--ouro-claro);
  box-shadow: inset 0 0 0 1px rgba(255, 214, 151, .38);
  font-size: 12px; font-weight: 800; letter-spacing: .04em;
}
.recado-quem b { font-size: 13.5px; font-weight: 700; color: var(--ouro-claro); }
.recado-quem i { font-style: normal; font-size: 11.5px; color: var(--claro-3); }
.recado-texto { display: block; margin-top: var(--e3); font-size: 14px; line-height: 1.45; color: var(--claro-2); }

.campo-palco .legenda { margin-top: var(--e5); }

/* ---- os quatro atos (texto de verdade: contam a história sem o céu) */

/* O min-height é o percurso: é ele que dá ao scroll o espaço para atravessar
   os quatro estágios enquanto o palco fica parado. Sem luz nada disso importa
   — os quatro atos continuam empilhados e legíveis. */
/* Sem fio ligando os atos, de propósito: uma linha vertical de ponta a ponta
   nesta altura da tela lê como divisória de coluna e briga com o palco. Quem
   dá a sequência são os pontos, que é o mesmo vocabulário do céu ao lado. */
.campo-atos {
  --recuo-topo: 0px; --recuo-pe: 0px;
  position: relative; margin: 0; list-style: none; display: grid;
  padding: var(--recuo-topo) 0 var(--recuo-pe);
}
.ato {
  position: relative; padding-left: var(--e6);
  min-height: 30vh; display: flex; flex-direction: column; justify-content: center;
  transition: color .45s var(--curva);
}
/* O numeral é o mesmo "01 — 05" que a arte dos carrosséis usa no canto: a
   sequência dita no vocabulário do próprio produto. Como o <li> é flex-column,
   o ::before já entra como primeira linha, acima do rótulo. */
.ato::before {
  content: '0' attr(data-n);
  font-size: 12px; font-weight: 700; letter-spacing: .2em;
  color: var(--claro-3); margin-bottom: var(--e3);
  transition: color .45s var(--curva);
}
/* O ato é um dos quatro tempos do argumento, não um item de lista: o corpo
   pede o mesmo peso do palco ao lado. Daí o rótulo em serifa grande e o
   parágrafo acima do miúdo — a coluna da direita não pode ler como legenda. */
.ato b {
  position: relative; display: block;
  font-family: var(--f-titulo); font-weight: 600;
  font-size: clamp(22px, 5.4vw, 26px); line-height: 1.2;
  letter-spacing: -.02em; color: var(--ouro-claro);
  transition: color .45s var(--curva);
}
/* O ponto do ato é o mesmo ponto do céu, do lado de fora: pendura no rótulo
   (não no <li>, que é flex e centra) para nascer sempre na linha do texto. */
.ato b::before {
  content: ''; position: absolute; left: calc(var(--e6) * -1); top: .55em;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--ouro-claro);
  box-shadow: 0 0 0 4px rgba(255, 214, 151, .14);
  transition: opacity .45s var(--curva), box-shadow .45s var(--curva);
}
/* O eco do ato da vez: um anel que sai do ponto no mesmo compasso da onda do
   céu, para as duas colunas baterem juntas. É um círculo transparente em cima
   do ponto de verdade — quem desenha o anel é o spread do box-shadow, e é por
   isso que ele precisa ter tamanho: o spread de uma caixa 0×0 sai quadrado. */
.ato b::after {
  content: ''; position: absolute; left: calc(var(--e6) * -1); top: .55em;
  width: 8px; height: 8px; border-radius: 50%; pointer-events: none;
}
@keyframes campo-eco {
  0%        { box-shadow: 0 0 0 0 rgba(255, 214, 151, .45); }
  70%, 100% { box-shadow: 0 0 0 11px rgba(255, 214, 151, 0); }
}
.ato p { margin-top: var(--e3); font-size: 16px; line-height: 1.55; color: var(--claro-2); }

/* ---- o fecho: valoriza o corretor, não dilui o preço */

.campo-fecho {
  margin-top: var(--e8); padding-top: var(--e7);
  border-top: 1px solid rgba(255, 214, 151, .16);
  max-width: 62ch;
}
.campo-fecho p { font-size: 17px; color: var(--claro-2); }
.campo-fecho strong { color: var(--claro); }
.campo-fecho .campo-pe { margin-top: var(--e3); font-size: 14px; color: var(--claro-3); }

/* ---- as regressões: só com luz, e só antes do estágio 4 */

/* O ato que não é o da vez recua, mas nunca abaixo de AA: o texto fica em
   --claro-3 (58%, 6,4:1), nunca em opacity que apagaria o parágrafo junto. */
html[data-luz] .campo-corpo[data-estagio] .ato:not([data-atual]) b { color: var(--claro-3); }
html[data-luz] .campo-corpo[data-estagio] .ato:not([data-atual]) b::before {
  opacity: .3; box-shadow: 0 0 0 4px rgba(255, 214, 151, 0);
}
html[data-luz] .campo-corpo[data-estagio] .ato[data-atual]::before { color: var(--ouro-claro); }
html[data-luz] .campo-corpo[data-estagio] .ato[data-atual] b::after {
  animation: campo-eco 2.6s var(--curva) infinite;
}

/* Estágio 1 — ser visto: só você, do tamanho de qualquer um, num campo apagado.
   A marca ainda não existe; o que se vê é o núcleo, que é um ponto como os
   outros. É esse o argumento do ato inteiro. */
html[data-luz] .campo-corpo[data-estagio="1"] .ceu-pontos g { opacity: .09; }
html[data-luz] .campo-corpo[data-estagio="1"] .voce-halo { opacity: 0; }
html[data-luz] .campo-corpo[data-estagio="1"] .voce-marca { transform: scale(.1); opacity: 0; }

/* Estágio 2 — ser lembrado: a onda começa a sair, o halo nasce, a marca se
   abre pela metade e o primeiro anel acende. */
html[data-luz] .campo-corpo[data-estagio="2"] .ceu-pontos g[data-anel="2"],
html[data-luz] .campo-corpo[data-estagio="2"] .ceu-pontos g[data-anel="3"] { opacity: .09; }
html[data-luz] .campo-corpo[data-estagio="2"] .voce-halo { opacity: .5; }
/* A marca não encolhe para se montar (encolher afina o traço junto e ela some
   dentro do halo): ela nasce pelos quatro braços retos e ganha os diagonais no
   ato seguinte. Meia marca é meia presença, e dá para ver. */
html[data-luz] .campo-corpo[data-estagio="2"] .voce-marca { transform: scale(.9); opacity: .85; }
html[data-luz] .campo-corpo[data-estagio="2"] .voce-marca path:nth-child(even) { opacity: 0; }

/* Estágio 3 — ser considerado: os fios se desenham, os conhecidos ganham anel,
   a borda do campo ainda não acendeu. */
html[data-luz] .campo-corpo[data-estagio="3"] .ceu-pontos g[data-anel="3"] { opacity: .11; }
html[data-luz] .campo-corpo[data-estagio="3"] .voce-marca { transform: scale(.97); opacity: .94; }

/* Os fios (e o da Marina junto) só existem a partir do estágio 3, e só brilham
   no 4. O dashoffset em 1 é a linha inteira ainda por desenhar. */
html[data-luz] .campo-corpo[data-estagio="1"] .ceu-fios line,
html[data-luz] .campo-corpo[data-estagio="2"] .ceu-fios line,
html[data-luz] .campo-corpo[data-estagio="1"] .marina-fio,
html[data-luz] .campo-corpo[data-estagio="2"] .marina-fio { stroke-dashoffset: 1; opacity: 0; }
html[data-luz] .campo-corpo[data-estagio="3"] .ceu-fios line { opacity: .26; }
html[data-luz] .campo-corpo[data-estagio="1"] .ceu-conhecidos circle,
html[data-luz] .campo-corpo[data-estagio="2"] .ceu-conhecidos circle { opacity: 0; }

/* A Marina é um ponto anônimo até o ato 4: aparece com o anel 1 e só ali ganha
   nome, brilho, anel e o rabicho que segura o recado. */
html[data-luz] .campo-corpo[data-estagio="1"] .marina-ponto { opacity: .09; }
html[data-luz] .campo-corpo[data-estagio="1"] .marina-brilho,
html[data-luz] .campo-corpo[data-estagio="2"] .marina-brilho,
html[data-luz] .campo-corpo[data-estagio="3"] .marina-brilho,
html[data-luz] .campo-corpo[data-estagio="1"] .marina-anel,
html[data-luz] .campo-corpo[data-estagio="2"] .marina-anel,
html[data-luz] .campo-corpo[data-estagio="3"] .marina-anel,
html[data-luz] .campo-corpo[data-estagio="1"] .marina-rabo,
html[data-luz] .campo-corpo[data-estagio="2"] .marina-rabo,
html[data-luz] .campo-corpo[data-estagio="3"] .marina-rabo { opacity: 0; }
html[data-luz] .campo-corpo[data-estagio="3"] .marina-fio { opacity: .3; }

/* O recado é o desfecho: pousa só no estágio 4. */
html[data-luz] .campo-corpo[data-estagio="1"] .campo-recado,
html[data-luz] .campo-corpo[data-estagio="2"] .campo-recado,
html[data-luz] .campo-corpo[data-estagio="3"] .campo-recado {
  opacity: 0; transform: translateY(12px);
}

/* ---- o que só existe com luz: a onda, o brilho dos pontos, a faísca

   Nada aqui tem estado base — sem data-luz a cena fica no estágio 4 parada, que
   é o contrato. A onda começa no ato 2 (antes dela não há post nenhum no ar) e
   o atraso de cada ponto é o tempo que ela leva para chegar até ele. */
html[data-luz] .campo-corpo[data-estagio="2"] .ceu-onda circle,
html[data-luz] .campo-corpo[data-estagio="3"] .ceu-onda circle,
html[data-luz] .campo-corpo[data-estagio="4"] .ceu-onda circle {
  animation: campo-onda var(--onda-ciclo) linear infinite;
}
html[data-luz] .campo-corpo[data-estagio="2"] .ceu-pontos circle,
html[data-luz] .campo-corpo[data-estagio="3"] .ceu-pontos circle,
html[data-luz] .campo-corpo[data-estagio="4"] .ceu-pontos circle,
html[data-luz] .campo-corpo[data-estagio="2"] .marina-ponto,
html[data-luz] .campo-corpo[data-estagio="3"] .marina-ponto,
html[data-luz] .campo-corpo[data-estagio="4"] .marina-ponto {
  animation: campo-acende var(--onda-ciclo) linear infinite;
  animation-delay: calc(var(--d) * var(--onda-ciclo));
}
html[data-luz] .campo-corpo[data-estagio="3"] .voce-halo,
html[data-luz] .campo-corpo[data-estagio="4"] .voce-halo {
  animation: campo-respira var(--onda-ciclo) var(--curva) infinite;
}
/* Linear de propósito: a faísca é um objeto atravessando o fio, e uma curva por
   trecho de keyframe a faria acelerar e frear no meio do caminho. */
html[data-luz] .campo-corpo[data-estagio="4"] .marina-faisca {
  animation: campo-faisca 4.2s linear infinite;
}

/* As estrelas do fundo não têm estágio: respiram enquanto a seção está na tela,
   e só isso. Ficam de fora do bloco de regressões de propósito — elas são o
   mundo, não a sua jornada. */
html[data-luz] .campo-luz[data-cena] .campo-estrelas span {
  animation: campo-cintila 7s var(--curva) infinite alternate;
  animation-delay: calc(var(--t) * -1);
}

/* E o interruptor: fora da tela, nada disso gira. O data-cena mora na seção e
   vem do mesmo observador que liga o medidor de estágio no landing.js.
   Especificidade igual à das regras acima, e vem depois — é o que faz este
   bloco vencer. */
html[data-luz] .campo-luz:not([data-cena]) .ceu-onda circle,
html[data-luz] .campo-luz:not([data-cena]) .ceu-pontos circle,
html[data-luz] .campo-luz:not([data-cena]) .marina-ponto,
html[data-luz] .campo-luz:not([data-cena]) .marina-faisca,
html[data-luz] .campo-luz:not([data-cena]) .voce-halo,
html[data-luz] .campo-luz:not([data-cena]) .ato[data-atual] b::after { animation: none; }

/* --------------------------------------------------------- como funciona */

.passos { margin-top: var(--e8); display: grid; gap: var(--e6); }
.passo { background: var(--branco); border: 1px solid var(--linha); border-radius: var(--r-g); padding: var(--e7); }
.passo b { font-family: var(--f-titulo); font-size: 40px; font-weight: 600; color: var(--ouro); line-height: 1; }
.passo h3 { margin-top: var(--e4); font-family: var(--f-corpo); font-size: 19px; font-weight: 700; letter-spacing: 0; }
.passo p { margin-top: var(--e3); font-size: 15px; color: var(--tinta-2); }

/* ---------------------------------------- a demonstração (celular + semana) */

/* O passo 3 em causa e efeito: a tela de aprovação do produto (o celular) e a
   agenda da semana (a tira). Com luz, a sequência roda uma vez quando o bloco
   acende: o anel de toque pulsa no botão, o botão comprime, o chip "agendado"
   surge, os três posts pousam nos dias. O estado final — chip visível, tira
   preenchida — é o padrão; o anel só existe dentro do keyframe. */
.demonstra { margin-top: var(--e8); display: grid; gap: var(--e7); align-items: start; }

.celular { margin: 0; }
.celular-moldura {
  max-width: 300px; margin: 0 auto;
  background: var(--branco); border: 1px solid var(--linha); border-radius: 26px;
  padding: var(--e5) var(--e5) var(--e6);
  box-shadow: 0 24px 60px rgba(20, 18, 16, .14);
  display: flex; flex-direction: column; gap: var(--e4);
}
.celular-titulo { font-size: 15px; font-weight: 700; text-align: center; }
.celular-post { position: relative; border-radius: var(--r-m); overflow: hidden; }
.celular-post img { width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; background: #16202A; }
.celular-paginas {
  position: absolute; top: 8px; right: 8px;
  background: rgba(20, 18, 16, .78); color: var(--claro);
  border-radius: var(--r-redondo); padding: 3px 10px;
  font-size: 10.5px; font-weight: 700;
}
/* O verde é o mesmo do botão real do painel (painel.css, --verde). */
.celular-aprovar {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 46px; border-radius: var(--r-redondo);
  background: #1f5c46; color: #FFFFFF;
  font-size: 14.5px; font-weight: 700;
}
.celular-aprovar i { font-style: normal; }
.celular-ajustes { text-align: center; font-size: 12.5px; color: var(--tinta-3); text-decoration: underline; text-underline-offset: 3px; }
.celular-chip {
  align-self: center;
  display: inline-flex; align-items: center; gap: 7px;
  background: rgba(31, 92, 70, .1); color: #1f5c46;
  border: 1px solid rgba(31, 92, 70, .3); border-radius: var(--r-redondo);
  padding: 7px 14px; font-size: 12px; font-weight: 700;
}
.celular-chip i { font-style: normal; }

.semana { margin: 0; align-self: center; }
.semana-tira { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--e2); max-width: 420px; margin: 0 auto; }
.dia { display: flex; flex-direction: column; align-items: center; gap: var(--e2); min-width: 0; }
.dia b { font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--tinta-3); }
.dia img { width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover; border-radius: var(--r-p); }
.dia i { width: 100%; aspect-ratio: 1 / 1; border-radius: var(--r-p); border: 1px dashed var(--linha-3); }

/* A coreografia, toda por delay a partir do [data-aceso] do .demonstra. */
html[data-luz] .demonstra[data-aceso] .celular-aprovar::after {
  content: ''; position: absolute; inset: -5px;
  border: 2px solid rgba(31, 92, 70, .55); border-radius: var(--r-redondo);
  opacity: 0;   /* o anel só existe dentro do keyframe — o estado final é sem ele */
  animation: tocar .9s var(--curva) .9s 2 backwards;
  pointer-events: none;
}
html[data-luz] .demonstra[data-aceso] .celular-aprovar { animation: comprimir .35s var(--curva) 1.5s; }
@keyframes tocar {
  from { opacity: 0; transform: scale(.96); }
  40%  { opacity: 1; }
  to   { opacity: 0; transform: scale(1.06); }
}
@keyframes comprimir {
  50% { transform: scale(.96); }
}
.celular-chip { transition: opacity .4s var(--curva-pulo), transform .4s var(--curva-pulo); }
html[data-luz] .demonstra:not([data-aceso]) .celular-chip { opacity: 0; transform: translateY(6px) scale(.9); }
.demonstra[data-aceso] .celular-chip { transition-delay: 1.9s; }
.dia img { transition: opacity .45s var(--curva-pulo), transform .45s var(--curva-pulo); }
html[data-luz] .demonstra:not([data-aceso]) .dia img { opacity: 0; transform: translateY(-10px); }
.demonstra[data-aceso] .dia-cheio:nth-child(1) img { transition-delay: 2.2s; }
.demonstra[data-aceso] .dia-cheio:nth-child(3) img { transition-delay: 2.4s; }
.demonstra[data-aceso] .dia-cheio:nth-child(5) img { transition-delay: 2.6s; }

/* ----------------------------------------------------------- as frentes */

.frentes { margin-top: var(--e8); display: grid; gap: var(--e6); }
.frente {
  border-radius: var(--r-g); padding: var(--e6);
  background: linear-gradient(170deg, #1E1913, var(--noite));
  border: 1px solid rgba(255, 214, 151, .18);
  color: var(--claro);
  display: flex; flex-direction: column;
}
.frente b { font-size: 11px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase; color: var(--ouro-claro); }
.frente h3 { margin-top: var(--e3); font-size: 19px; line-height: 1.3; }
.frente p { margin-top: var(--e3); font-size: 14px; color: var(--claro-3); }

/* -------------------------------------------------- incluído e comparação */

.oferta { display: grid; gap: var(--e9); align-items: start; }
.oferta h2 { font-size: clamp(24px, 5.6vw, 32px); }

.inclui { margin-top: var(--e7); list-style: none; padding: 0; }
.inclui li {
  display: flex; gap: var(--e4); align-items: baseline;
  padding: var(--e4) 0; border-bottom: 1px solid var(--linha);
  font-size: 16px;
}
.inclui li i { font-style: normal; color: var(--ouro); font-weight: 800; }

/* A tabela é uma grade, não um <table>: no celular cada linha vira um bloco e
   cada célula passa a dizer de que coluna veio (o data-col vira rótulo). */
.compara { margin-top: var(--e7); background: var(--branco); border: 1px solid var(--linha); border-radius: var(--r-g); overflow: hidden; }
.compara-cabeca { display: none; }
.compara-linha { padding: var(--e4) var(--e5); }
.compara-linha + .compara-linha { border-top: 1px solid var(--linha-2); }
.compara-linha b { display: block; font-size: 15px; font-weight: 700; }
.compara-linha span { display: flex; justify-content: space-between; gap: var(--e4); margin-top: 6px; font-size: 14px; color: var(--tinta-2); }
.compara-linha span::before { content: attr(data-col); color: var(--tinta-3); }
.compara-linha .marca { font-weight: 700; color: var(--ouro-forte); }

/* ------------------------------------------------------------- o preço */

.preco-bloco {
  background: var(--noite); color: var(--claro); border-radius: var(--r-ggg);
  padding: var(--e8) var(--e6);
  display: grid; gap: var(--e8); align-items: center;
}
.preco-bloco .chapeu { color: var(--ouro-claro); }
.preco-bloco h2 { margin-top: var(--e4); font-size: clamp(26px, 6.2vw, 36px); line-height: 1.2; }
.preco-texto > p { margin-top: var(--e4); max-width: 52ch; font-size: 16px; color: var(--claro-2); }

.preco-cartao {
  position: relative;
  text-align: center;
  background: rgba(255, 214, 151, .08); border: 1px solid rgba(255, 214, 151, .3);
  border-radius: var(--r-gg); padding: var(--e8) var(--e6);
}
/* O adesivo do desconto — o mesmo dispositivo do "Post automático" da vitrine. */
.selo-ano {
  position: absolute; z-index: 2; top: -13px; right: -10px;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 15px; border-radius: var(--r-redondo);
  background: var(--ouro-claro); color: var(--noite);
  font-family: var(--f-corpo);
  font-size: 11.5px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  white-space: nowrap; transform: rotate(-3deg);
  box-shadow: 0 10px 26px rgba(0, 0, 0, .5);
}
.selo-ano i { font-style: normal; font-size: 13px; line-height: 0; }
.preco-cartao .plano { font-size: 14px; color: var(--claro-3); }
.preco-cartao .valor { margin-top: var(--e2); font-family: var(--f-titulo); color: var(--ouro-claro); white-space: nowrap; }
.preco-cartao .cifrao { font-size: 22px; vertical-align: 22px; }
.preco-cartao .inteiro { font-size: 64px; font-weight: 600; letter-spacing: -.03em; }
.preco-cartao .centavos { font-size: 26px; }
.preco-cartao .mes { font-size: 16px; color: var(--claro-3); }
.preco-cartao .preco-parcela { margin-top: var(--e2); font-size: 14px; color: var(--claro-2); }
.preco-cartao .btn { margin-top: var(--e6); }
.preco-cartao .micro { margin-top: var(--e4); font-size: 13px; color: var(--claro-3); }
/* A alternativa sem compromisso: presente, e menor que o plano que queremos
   vender. Quem só quer o mês avulso encontra; quem não procurava, não tropeça. */
.preco-cartao .preco-alt {
  margin-top: var(--e5); padding-top: var(--e5);
  border-top: 1px solid rgba(255, 214, 151, .22);
  font-size: 13.5px; line-height: 1.6; color: var(--claro-3);
}
.preco-cartao .preco-alt b { color: var(--claro-2); font-weight: 700; }
.preco-cartao .preco-alt a { color: inherit; }

/* --------------------------------------------------------------- o faq */

.faq { max-width: 820px; }
.faq h2 { font-size: clamp(26px, 6.2vw, 36px); }
.faq-lista { margin-top: var(--e7); }
.faq details { border-bottom: 1px solid var(--linha); }
.faq summary {
  display: flex; justify-content: space-between; align-items: center; gap: var(--e4);
  padding: var(--e5) 0; font-size: 17px; font-weight: 700;
  list-style: none; cursor: pointer;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary i {
  flex: none; font-style: normal; font-size: 20px; font-weight: 400; color: var(--ouro);
  transition: transform .2s;
}
.faq details[open] summary i { transform: rotate(45deg); }
.faq details p { padding: 0 0 var(--e5); max-width: 64ch; font-size: 15.5px; color: var(--tinta-2); }

/* ------------------------------------------------------------- o fecho */

.fecho { display: grid; gap: var(--e9); align-items: center; }
.fecho h2 { font-size: clamp(30px, 7.4vw, 44px); line-height: 1.12; max-width: 24ch; }
.fecho .acoes { margin-top: var(--e7); }
.fecho .acoes .micro { max-width: 34ch; }

/* O retrato do fecho é a promessa em objeto: a foto do imóvel, e por cima dela
   a etiqueta que diz de quem é o nome que fica. */
.retrato { position: relative; justify-self: center; max-width: 100%; }
.retrato > img { width: 300px; max-width: 100%; aspect-ratio: 5 / 6; object-fit: cover; border-radius: 18px; box-shadow: 0 24px 60px rgba(20, 18, 16, .18); }
.retrato-nome {
  position: absolute; left: -16px; bottom: var(--e6);
  background: var(--noite); color: var(--claro);
  border-radius: var(--r-m); padding: var(--e3) var(--e5);
  box-shadow: 0 12px 32px rgba(20, 18, 16, .3);
}
.retrato-nome b { font-family: var(--f-titulo); font-size: 15px; font-weight: 600; color: var(--ouro-claro); }
.retrato-nome p { margin-top: 2px; font-size: 11.5px; color: var(--claro-3); }
.retrato-faisca {
  position: absolute; top: -14px; right: -14px;
  width: 52px; height: 52px; border-radius: 50%; background: var(--ouro-claro);
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; color: var(--noite);
}

.combo {
  margin-top: var(--e9);
  border: 1px solid var(--linha); background: var(--branco); border-radius: var(--r-g);
  padding: var(--e6);
  display: flex; justify-content: space-between; align-items: center; gap: var(--e6); flex-wrap: wrap;
}
.combo p { font-size: 15.5px; color: var(--tinta-2); max-width: 58ch; }
.combo strong { color: var(--tinta); }
.combo em { font-style: normal; font-weight: 700; color: var(--ouro-forte); }
.combo a { flex: none; font-size: 15px; font-weight: 700; color: var(--tinta); text-decoration: none; }
.combo a:hover { color: var(--ouro-forte); text-decoration: underline; }

/* ------------------------------------------------------------- conhecer */

/* A saída de quem não quer assinar sem falar com alguém. O estado padrão aqui
   é o final, como no resto da página — a revelação por scroll é [data-revela],
   e o pré-estado dela só existe sob html[data-luz]. */
.conhecer {
  border: 1px solid var(--linha); background: var(--branco); border-radius: var(--r-gg);
  padding: var(--e7); display: grid; gap: var(--e6);
}
.conhecer-texto h2 { margin-top: var(--e3); font-size: clamp(24px, 5.6vw, 32px); line-height: 1.18; max-width: 20ch; }
.conhecer-texto p { margin-top: var(--e4); font-size: 15.5px; color: var(--tinta-2); max-width: 52ch; }

.conhecer-form { display: grid; gap: var(--e3); align-content: start; }
.conhecer-linha { display: grid; gap: var(--e3); }
.conhecer input[type="text"],
.conhecer input[type="email"],
.conhecer input[type="tel"] {
  width: 100%; font: inherit; font-size: 15px; color: var(--tinta);
  background: var(--papel, #FFF); border: 1px solid var(--linha); border-radius: var(--r-m);
  padding: 12px var(--e4); transition: border-color .15s var(--curva);
}
.conhecer input::placeholder { color: var(--tinta-3); }
.conhecer input:focus { outline: none; border-color: var(--ouro); }
.conhecer .btn { justify-self: start; margin-top: var(--e2); }
.conhecer .micro { color: var(--tinta-3); }

.conhecer-pronto {
  border: 1px solid var(--linha); border-radius: var(--r-g); padding: var(--e5) var(--e6);
  background: rgba(185, 126, 36, .06); align-self: start;
}
.conhecer-pronto strong { font-size: 16px; }
.conhecer-pronto p { margin-top: var(--e2); font-size: 14.5px; color: var(--tinta-2); }

/* Isca de robô e rótulos para leitor de tela: fora da vista, nunca do DOM
   (display:none tiraria o campo do envio e o rótulo do leitor). */
.fora-de-vista { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.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;
}

/* Link discreto ao lado do botão: o caminho principal segue sendo assinar.
   O padrão é o do papel — é onde ele aparece no fecho. Dentro da capa a única
   faixa escura da página inverte as duas cores: o repouso é o creme fraco e o
   hover é o creme cheio, senão o hover cairia no --tinta, que é o mesmo tom do
   --noite do fundo, e o link sumiria debaixo do cursor. */
.link-conversa {
  font-size: 15px; font-weight: 600; color: var(--tinta-2);
  text-decoration: underline; text-underline-offset: 4px; text-decoration-color: var(--linha);
}
.link-conversa:hover { color: var(--tinta); text-decoration-color: currentColor; }
.capa .link-conversa { color: var(--claro-2); text-decoration-color: rgba(251, 247, 240, .3); }
.capa .link-conversa:hover { color: var(--claro); text-decoration-color: currentColor; }

.rodape {
  margin-top: var(--e9); padding: var(--e7) 0 var(--e9);
  border-top: 1px solid var(--linha);
  display: flex; justify-content: space-between; align-items: center; gap: var(--e4) var(--e6); flex-wrap: wrap;
}
/* A versão "preto" do logo: a palavra BE VISIBLE é preta e o cone é o
   ouro da marca — sobre o creme ele quase some em tamanho pequeno, daí
   os 34px do desenho em vez de menos. */
.rodape-logo { height: 34px; width: auto; }
.rodape p { font-size: 13px; color: var(--tinta-3); }
/* A linha dos documentos ocupa a largura inteira e fecha o rodapé embaixo, em
   vez de disputar espaço com o logo e os links do produto. */
.rodape-legais { flex-basis: 100%; }
.rodape a { color: var(--tinta-2); text-decoration: none; }
.rodape a:hover { color: var(--ouro-forte); text-decoration: underline; }

/* -------------------------------------------------------------- respostas */

@media (min-width: 600px) {
  :root { --margem: var(--e7); }

  /* A costura: com largura, a noite vira objeto sobre o papel. */
  .capa { border-radius: 0 0 var(--r-ggg) var(--r-ggg); }

  .topo-logo { height: 38px; }
  .topo-cta { display: inline-flex; }
  .topo-precos { display: inline; }
  .titulo { font-size: 48px; }
  .subtitulo { font-size: 18px; }

  .produto-caixa {
    max-width: 360px;
    transform: rotate(-2.5deg);
    transition: transform .35s var(--curva);
  }
  .produto-caixa:hover, .produto-caixa:focus-within { transform: rotate(0); }

  .etapas { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .demonstra { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: center; }
  .passos { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .frentes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .frente { min-height: 200px; }

  /* Com largura para as quatro colunas, a tabela volta a ser tabela. */
  .compara-cabeca, .compara-linha { display: grid; grid-template-columns: 1.3fr 1fr 1fr 1fr; }
  .compara-cabeca { background: var(--noite); color: var(--claro); font-size: 13px; font-weight: 700; }
  .compara-cabeca span { padding: var(--e4) var(--e3); }
  .compara-cabeca .marca { color: var(--ouro-claro); }
  .compara-linha { padding: 0; }
  .compara-linha b { padding: var(--e4) var(--e5); }
  .compara-linha span { display: block; margin: 0; padding: var(--e4) var(--e3); }
  .compara-linha span::before { display: none; }

  .preco-bloco { padding: var(--e9) var(--e8); }
  .retrato-nome { left: -28px; }
}

@media (min-width: 1040px) {
  :root { --margem: var(--e8); --secao: var(--e10); }

  .topo-logo { height: 44px; }
  .topo-links { gap: var(--e6); }
  .topo-irmao { display: inline; }

  .heroi { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--e9); align-items: center; padding: var(--e9) 0 var(--e10); }
  .titulo { font-size: 52px; }

  .etapas { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--e6); }

  /* Só onde as quatro etapas são uma linha única: a linha de ouro se desenha
     por cima dos filetes quando a régua acende. Os filetes ficam — eles dizem
     "só no primeiro aconteceu algo"; a Be Visible acende os quatro. */
  .constancia .etapas { position: relative; }
  .constancia .etapas::after {
    content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px;
    background: linear-gradient(90deg, var(--ouro), var(--ouro-claro));
    transform-origin: left; pointer-events: none;
    transition: transform 1.6s var(--curva);
  }
  html[data-luz] .constancia .etapas:not([data-aceso])::after { transform: scaleX(0); }

  .tese { font-size: 19px; }

  /* Com duas colunas o palco deixa de tapar o texto: ele fica de um lado,
     parado, e os quatro atos passam do outro. O fundo opaco e o z-index do
     celular saem — aqui nada corre por baixo dele. */
  .campo-corpo {
    grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
    gap: var(--e9); align-items: start;
  }
  /* O palco fica alto e quase quadrado, e gruda a 13vh — na prática centrado
     na tela enquanto os atos passam. */
  .campo-palco { top: 13vh; z-index: auto; background: none; margin: 0; padding: 0; }
  .campo-palco::after { display: none; }
  .campo-ceu { width: min(100%, 60vh); }
  .marina-rabo { opacity: .7; }

  /* Aqui o recado deixa de ser uma tarja no pé e passa a pender do ponto da
     Marina: --mx/--my são a posição dele em porcentagem da caixa (o viewBox é
     quadrado como a caixa, por isso a conta fecha) e --mr é o rabicho que desce
     dali. Os 22px são o quanto do recado fica à esquerda do fio — sempre em px,
     para o rabicho cair no mesmo lugar da bolha em qualquer tamanho de tela. */
  .campo-recado {
    left: calc(var(--mx) - 22px); right: auto;
    top: calc(var(--my) + var(--mr)); bottom: auto;
    width: min(272px, 60%);
    border-top-left-radius: var(--r-p);
  }

  /* Os dois recuos são o que reparte o scroll entre os quatro atos. O de cima
     nasce o primeiro ato na altura do núcleo do campo e impede que o segundo
     já comece acima da linha de leitura (a cena abriria no estágio 2); o de
     baixo dá ao quarto o mesmo tempo de tela que os do meio, em vez de deixá-lo
     durar só o último quadro. Mexer num deles desequilibra a cena inteira. */
  .campo-atos { --recuo-topo: 24vh; --recuo-pe: 50vh; }
  .ato { min-height: 30vh; }
  .ato b { font-size: clamp(26px, 2.2vw, 31px); }
  .ato p { font-size: 18px; max-width: 40ch; }

  .frentes { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--e6); }

  .oferta { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }

  .preco-bloco { grid-template-columns: minmax(0, 1fr) auto; gap: var(--e8); padding: var(--e9); }
  .preco-cartao { padding: var(--e8); }

  .conhecer { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: var(--e8); padding: var(--e8); align-items: center; }
  .conhecer-linha { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .fecho { grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); }
  .fecho .acoes { gap: var(--e7); }
}

/* A trava dupla: o inline do <head> já não põe data-luz com esta preferência,
   e aqui qualquer transição ou animação que sobre é desligada na marra. */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
