/* ==========================================================================
   albuns.online - site.css
   Biblioteca de temas de álbum para o fotógrafo profissional. Marca fechada
   em _knowledge/branding/albuns-online.md. Fala com o fotógrafo, nunca com
   quem faz a festa. O mascote se chama Chapa.
   ========================================================================== */

/* ---------- Fonte, self-hosted, sem CDN ----------
   Public Sans só existe em peso 800 estático neste arquivo (escolha da
   marca: "algo tipo Helvetica Neue Bold" que fica quieta perto de um
   mascote cheio de personalidade). Ela é a fonte de destaque: wordmark,
   H1, H2, números grandes. O corpo do texto usa a pilha do sistema, que
   também é self-hosted por definição (não existe download nenhum). */
@font-face {
  font-family: 'Public Sans';
  src: url('/assets/fonts/publicsans.woff2') format('woff2');
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}

/* ---------- Reset mínimo ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body, h1, h2, h3, p, figure, ul, ol, dialog, figcaption { margin: 0; padding: 0; }
ul { list-style: none; }
/* height:auto no reset e obrigatorio, nao enfeite. Toda <img> aqui carrega
   width/height reais no HTML (defesa contra CLS), e o atributo height vence
   qualquer largura definida via CSS no elemento PAI: sem esta linha, uma pose
   de 900x900 limitada a 112px de largura pelo container continua com 900px de
   altura e sai esmagada numa tira vertical. Foi assim que o Chapa apareceu
   gigante e cortado dentro do bloco de apresentacao dele. Quem precisa de
   altura fixa (as capas com object-fit) declara height depois e vence por
   ordem. */
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
input, select { font: inherit; color: inherit; }
summary::-webkit-details-marker { display: none; }

/* ---------- Tokens ---------- */
:root {
  /* Paleta oficial da marca, travada, não re-decidir */
  --esc:   #1B1410; /* fundo padrão */
  --creme: #F7EFE2; /* texto sobre escuro, fundo claro */
  --cobre: #E8871A; /* acento único: botão, destaque, link ativo */
  --m2:    #A85E18; /* sombra média do mascote */
  --m3:    #6A3C15; /* sombra profunda do mascote */

  /* Fundos derivados, para o ritmo de cor entre seções. São o mesmo
     território do --esc, movidos só em luminosidade: sem cor nova. */
  --esc-fundo:  #150F0C; /* mais fundo que o padrão, para a seção do problema */
  --carvao:     #241B16; /* um degrau acima, para o FAQ */

  /* Derivados de opacidade sobre a paleta acima, nunca cor nova */
  --creme-70:  rgba(247, 239, 226, .72);
  /* .53 e nao .46: em .46 este token dava #807870 sobre o fundo escuro,
     ou seja 4,19:1, abaixo do minimo de 4,5 exigido pra texto. Ele veste
     os metadados do hero e as duas linhas do rodape. Medido no Lighthouse,
     nao estimado. */
  --creme-45:  rgba(247, 239, 226, .53);
  --creme-24:  rgba(247, 239, 226, .24);
  --creme-14:  rgba(247, 239, 226, .14);
  --esc-70:    rgba(27, 20, 16, .72);
  --esc-45:    rgba(27, 20, 16, .46);
  --esc-14:    rgba(27, 20, 16, .14);

  --erro:      #C1432B; /* terroso, não é o vermelho de proposta comercial */
  --erro-bg:   rgba(193, 67, 43, .12);

  --radius:    22px;
  --radius-sm: 12px;
  --shadow-pop:  0 24px 56px -20px rgba(10, 7, 5, .55);
  --shadow-card: 0 1px 2px rgba(10, 7, 5, .08), 0 16px 34px -16px rgba(10, 7, 5, .40);
  --container: 1200px;

  --font-display: 'Public Sans', 'Helvetica Neue', Arial, sans-serif; /* peso 800 só */
  --font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, 'Helvetica Neue', Arial, sans-serif;
  --font-mono: ui-monospace, 'SF Mono', 'Cascadia Code', 'Roboto Mono', Menlo, Consolas, monospace;

  --ease-out-strong: cubic-bezier(.16, 1, .3, 1);
  --ease-inout:      cubic-bezier(.65, 0, .35, 1);

  --header-h: 78px; /* fallback antes do JS medir a altura real */

  /* Fundo/texto do palco de temas: o JS troca estes três conforme o tema
     ativo (técnica do Project Aperture). Sem JS ficam no padrão da marca. */
  --palco-bg: var(--esc);
  --palco-fg: var(--creme);
  --palco-luz: rgba(232, 135, 26, .16);
}

html {
  scroll-behavior: smooth;
  /* clip, nunca hidden: overflow-x:hidden cria container de scroll próprio
     no html, quebra `position: sticky` em todo descendente e briga com o
     Lenis. clip corta o transbordo sem criar esse container. */
  overflow-x: clip;
}

/* html.js, NUNCA `.js html`. A classe js mora no próprio <html> (é
   adicionada por um script síncrono no <head>, antes do primeiro paint).
   `.js html` procura um <html> dentro de um elemento .js e nunca casa com
   nada: com a regra morta, o scroll-behavior:smooth nativo continua ligado
   ao mesmo tempo que o Lenis, e os dois motores de scroll brigam pela
   mesma rolagem. */
html.js { scroll-behavior: auto; }

body {
  background: var(--esc);
  color: var(--creme);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4vw, 4rem);
}

.somente-leitor {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Link de pulo: existe fora da tela e só aparece ao receber foco pelo
   teclado. É a saída de quem navega sem mouse e não quer ouvir o header
   em toda página. */
.pular {
  position: absolute;
  left: -9999px;
  z-index: 200;
  background: var(--cobre);
  color: var(--esc);
  padding: .8em 1.4em;
  border-radius: 0 0 var(--radius-sm) 0;
  font-weight: 700;
}
.pular:focus { left: 0; top: 0; }

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

/* ---------- Tipografia utilitária ---------- */
h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -0.028em;
  line-height: 1.02;
  color: var(--creme);
}

/* Uma palavra da headline em cor no meio da frase (gramática da Broud).
   É letra colorida, não bloco atrás, e por isso só funciona sobre fundo
   escuro. Nas seções claras a regra mais abaixo troca pelo cobre escuro,
   porque o cobre puro sobre creme dá 2,22:1 e reprova como texto. */
h1 em, h2 em {
  font-style: normal;
  color: var(--cobre);
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .55em;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: .74rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--cobre);
}
.eyebrow::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--cobre);
  flex: none;
}
.eyebrow--claro { color: var(--esc); }
.eyebrow--claro::before { background: var(--esc); }

/* Pill outline com ícone como rótulo de seção (gramática da Broud). */
.pill {
  display: inline-flex;
  align-items: center;
  gap: .6em;
  border: 1px solid var(--creme-24);
  border-radius: 999px;
  padding: .5em 1em .5em .5em;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: .74rem;
  letter-spacing: .08em;
  color: var(--creme-70);
  margin-block-end: 1.1rem;
}
.pill-ico {
  width: 1.55em;
  height: 1.55em;
  border-radius: 999px;
  background: var(--cobre);
  color: var(--esc);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: .82em;
  font-weight: 700;
  flex: none;
}
.pill-ico svg { width: .74em; height: .74em; }
.pill--escuro {
  border-color: var(--esc-14);
  color: var(--esc-70);
}

.lead {
  font-size: clamp(1rem, .94rem + .3vw, 1.15rem);
  line-height: 1.55;
  color: var(--creme-70);
  max-width: 46ch;
}

/* ---------- Lockup: mascote + "álbuns.online" ----------
   Proporção travada pela marca: o texto tem 0,62x a altura do mascote, com
   0,24x de espaço entre os dois. --lockup-h é a altura do mascote; o resto
   é derivado dela, então o mesmo componente serve pro header e pro rodapé
   só mudando uma variável. */
.lockup {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--lockup-h, 34px) * .24);
  --lockup-h: 34px;
}
.lockup-mascote {
  height: var(--lockup-h);
  width: auto;
  flex: none;
}
.lockup-texto {
  display: inline-flex;
  align-items: baseline;
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -0.028em;
  font-size: calc(var(--lockup-h, 34px) * .62);
  line-height: 1;
  color: var(--creme);
  white-space: nowrap;
}

/* O acento do "á" é desenhado, não vem da fonte: uma fotinha inclinada
   (retângulo cobre + sol + horizonte), 0,62 da largura do glifo, rotação
   -16deg.

   A versão anterior media o glifo com canvas.measureText no JS e escrevia
   top/left em `em`. Aquilo errava por dois motivos ao mesmo tempo: media a
   ascendente da fonte (que na Public Sans é a altura do "d", não a do "a"),
   e escrevia num elemento cuja caixa de referência é a linha inteira. O
   acento saía boiando acima e à direita da letra, que é o "acento voando"
   reclamado.

   Agora não tem JS nenhum, e os três números abaixo foram MEDIDOS no glifo
   real da Public Sans 800, com uma sonda de altura zero pra achar a linha de
   base e canvas.measureText('a') pra achar o topo do glifo:

     topo do "a", medido do fundo da caixa .... 0,673em
     largura do glifo "a" ..................... 0,5725em
     largura do acento (0,62x, é da marca) .... 0,355em
     centragem = (0,5725 - 0,355) / 2 ......... 0,109em

   Por isso `bottom: .70em` (o topo do glifo mais um respiro) e
   `left: .109em`. Ao trocar a fonte ou o peso, medir de novo: esses valores
   não valem pra outra fonte. As cores do SVG estão em hexadecimal fixo, não
   var(), porque o WebView do WhatsApp que abre este link às vezes não resolve
   custom property dentro de atributo de apresentação SVG. */
.lockup-letra-a {
  position: relative;
  display: inline-block;
  line-height: 1;
}
.lockup-acento {
  position: absolute;
  width: .355em;
  height: .231em;
  bottom: .70em;
  left: .109em;
  transform: rotate(-16deg);
  transform-origin: 50% 100%;
  pointer-events: none;
}
.lockup-online {
  font-weight: 500;
  /* .58 e nao .42: o ".online" e endereco e nao marca, entao pede menos peso
     que o nome, mas em .42 ele dava 3,69:1 sobre o fundo escuro e reprovava
     em contraste. Em .58 da 5,9:1 e continua visivelmente mais apagado que o
     "albuns". Medido, nao estimado. */
  opacity: .58;
}

/* ---------- Botões ---------- */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6em;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: .95rem;
  padding: .95em 1.7em;
  border-radius: 999px;
  border: 1px solid transparent;
  transition: transform .18s ease-out, box-shadow .18s ease-out, background-color .18s ease-out, border-color .18s ease-out;
  white-space: nowrap;
  overflow: hidden;
  isolation: isolate;
}
.btn-primary {
  background: var(--cobre);
  color: var(--esc);
}
.btn-primary:active { background: var(--m2); }

/* O brilho que atravessa o botão no hover (gramática da Broud). Fica fora
   da caixa por padrão e só entra durante a transição, então não pinta nada
   enquanto ninguém interage. */
.btn-primary::after {
  content: '';
  position: absolute;
  inset-block: 0;
  inset-inline-start: -60%;
  width: 40%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .42), transparent);
  transform: skewX(-18deg);
  pointer-events: none;
  z-index: -1;
}

.btn-outline {
  background: transparent;
  border-color: var(--creme-24);
  color: var(--creme);
}
.btn-outline:active { border-color: var(--creme-45); }

.btn-whatsapp {
  background: var(--cobre);
  color: var(--esc);
}

.btn-block { width: 100%; }
.btn-sm { padding: .7em 1.35em; font-size: .85rem; }

@media (hover: hover) {
  .btn:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-pop);
  }
  .btn-primary:hover::after {
    transition: left .62s var(--ease-inout);
    inset-inline-start: 120%;
  }
  .btn-outline:hover { border-color: var(--creme-45); }
}

/* ==========================================================================
   Cursor customizado (gramática da Broud)
   Só liga em ponteiro fino, e o JS é quem adiciona .tem-cursor no html.
   No celular o bloco inteiro nunca é ativado.
   ========================================================================== */
.cursor { display: none; }
@media (hover: hover) and (pointer: fine) {
  html.tem-cursor .cursor {
    display: block;
    position: fixed;
    inset-block-start: 0;
    inset-inline-start: 0;
    z-index: 300;
    pointer-events: none;
    will-change: transform;
  }
  html.tem-cursor .cursor-ponto {
    position: absolute;
    inset-block-start: -5px;
    inset-inline-start: -5px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--cobre);
    transition: width .22s var(--ease-out-strong), height .22s var(--ease-out-strong),
                top .22s var(--ease-out-strong), left .22s var(--ease-out-strong),
                opacity .22s ease-out;
  }
  html.tem-cursor .cursor-rotulo {
    position: absolute;
    inset-block-start: 14px;
    inset-inline-start: 14px;
    background: var(--cobre);
    color: var(--esc);
    font-family: var(--font-mono);
    font-weight: 600;
    font-size: .68rem;
    letter-spacing: .06em;
    padding: .45em .85em;
    border-radius: 999px;
    white-space: nowrap;
    opacity: 0;
    transform: scale(.82);
    transform-origin: 0 0;
    transition: opacity .2s ease-out, transform .2s var(--ease-out-strong);
  }
  html.tem-cursor .cursor.is-ativo .cursor-ponto {
    inset-block-start: -3px;
    inset-inline-start: -3px;
    width: 6px;
    height: 6px;
  }
  html.tem-cursor .cursor.is-ativo .cursor-rotulo {
    opacity: 1;
    transform: scale(1);
  }
}

/* ==========================================================================
   Fundo de seda: o degradê
   Três manchas de luz com blur pesado, girando devagar, mais uma camada de
   grão por cima pra não virar aquele borrão liso de gerador de gradiente.
   É CSS puro: sem canvas, sem WebGL, sem custo de JS no caminho do LCP.
   ========================================================================== */
.seda {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}
.seda-mancha {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: .55;
  will-change: transform;
}
.seda-mancha--1 {
  width: 46vw; height: 46vw;
  inset-block-start: -12vw; inset-inline-end: -6vw;
  background: radial-gradient(circle, rgba(232, 135, 26, .55), transparent 68%);
  animation: sedaGira1 26s ease-in-out infinite;
}
.seda-mancha--2 {
  width: 38vw; height: 38vw;
  inset-block-end: -14vw; inset-inline-start: -8vw;
  background: radial-gradient(circle, rgba(168, 94, 24, .5), transparent 68%);
  animation: sedaGira2 32s ease-in-out infinite;
}
.seda-mancha--3 {
  width: 30vw; height: 30vw;
  inset-block-start: 32%; inset-inline-start: 42%;
  background: radial-gradient(circle, rgba(106, 60, 21, .55), transparent 70%);
  animation: sedaGira3 38s ease-in-out infinite;
}
/* O grão é um SVG de ruído embutido em data URI, não uma imagem baixada.
   Sem ele o degradê fica com aquela aparência de fundo de template. */
.seda-grao {
  position: absolute;
  inset: 0;
  opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}
@keyframes sedaGira1 {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  50%      { transform: translate3d(-6%, 8%, 0) scale(1.12); }
}
@keyframes sedaGira2 {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1.06); }
  50%      { transform: translate3d(9%, -7%, 0) scale(.94); }
}
@keyframes sedaGira3 {
  0%, 100% { transform: translate3d(0, 0, 0) scale(.96); }
  50%      { transform: translate3d(-10%, -6%, 0) scale(1.14); }
}

/* ==========================================================================
   Sistema de reveal
   Estado padrão (sem JS): tudo visível, sem transform. A classe .js só
   existe porque um script síncrono no <head> a adiciona no <html> antes do
   primeiro paint. Se o JS falhar em carregar, a página inteira aparece.
   ========================================================================== */
.reveal,
.reveal-num,
.reveal-card,
.hero-h1 .palavra,
.hero-reveal {
  opacity: 1;
  transform: none;
  filter: none;
}

.js .secao .reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity .64s var(--ease-out-strong), transform .64s var(--ease-out-strong);
}
.js .secao.is-visible .reveal { opacity: 1; transform: translateY(0); }

.js .secao .reveal-num {
  opacity: 0;
  transition: opacity .64s var(--ease-out-strong);
}
.js .secao.is-visible .reveal-num { opacity: 1; }

@media (max-width: 640px) {
  .js .secao .reveal { transform: translateY(14px); }
}

.js .reveal-card {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .7s var(--ease-out-strong), transform .7s var(--ease-out-strong);
}
.js .reveal-card.is-visible { opacity: 1; transform: translateY(0); }
@media (max-width: 640px) {
  .js .reveal-card { transform: translateY(16px); }
}

/* Hero: linhas do H1. Animação CSS pura, disparada assim que a folha de
   estilo é aplicada, não espera o site.js baixar. O H1 é o elemento de LCP
   da página: numa versão anterior, quando a revelação dependia do JS rodar
   no evento load, o Render Delay sozinho custava ~2,7s do LCP. Não mover
   essa animação pro JS. */
/* SEM overflow:hidden nesta linha, e é decisão. A máscara de recorte era o
   que a versão anterior usava, mas o reveal agora é por desfoque, e desfoque
   sangra para fora da caixa: cortado, cada palavra ganha uma borda dura que
   denuncia o truque. Neste mesmo projeto um overflow de máscara já comeu o
   sublinhado de marca uma vez. */
.hero-h1 .line { display: block; }

.hero-h1 .palavra {
  display: inline-block;
  will-change: filter, opacity, transform;
}

/* A revelação: de desfocado e subexposto para nítido e no ponto. O
   `brightness` no filtro em vez de animar `color` é o que deixa a palavra em
   cobre (o <em>) revelar junto, com a cor dela, sem precisar de regra à parte. */
@keyframes revela {
  from {
    opacity: 0;
    filter: blur(13px) brightness(.35);
    transform: translateY(15px);
  }
  to {
    opacity: 1;
    filter: blur(0) brightness(1);
    transform: translateY(0);
  }
}
@keyframes heroSobeCurto {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* 40ms de passo com 14 palavras fecha em 1,2s: rápido o bastante pra não
   atrasar a leitura e lento o bastante pra ler como revelação. */
.js .hero-h1 .palavra {
  animation: revela .62s var(--ease-out-strong) both;
  animation-delay: calc(var(--i, 0) * 40ms);
}
@media (max-width: 640px) {
  .js .hero-h1 .palavra { animation-delay: calc(var(--i, 0) * 28ms); }
}

/* ---------- O slot que troca o tipo de evento ----------
   A ideia é o quadro de um filme avançando: a palavra atual sai por cima
   queimada de luz (brightness alto e desfoque, como negativo superexposto) e
   a nova entra por baixo revelando do escuro. É o mesmo vocabulário do reveal
   das outras palavras, aplicado a uma troca em ciclo.

   O slot é `inline-grid` com uma célula só: a palavra que sai e a que entra
   ocupam a MESMA célula, então uma não empurra a outra durante a troca. A
   largura anima entre uma palavra e a outra porque o JS mede e escreve
   `--slot-w`; sem isso o resto da linha dá um salto seco a cada 3 segundos. */
.hero-h1 .slot {
  display: inline-grid;
  grid-template-columns: 1fr;
  vertical-align: baseline;
  overflow: clip;
  overflow-clip-margin: .28em; /* deixa o desfoque sangrar sem cortar */
  padding-inline-end: .06em;
  margin-inline-end: -.06em;
}
.js .hero-h1 .slot {
  width: var(--slot-w, auto);
  transition: width .5s var(--ease-out-strong);
}
.hero-h1 .slot-quadro {
  grid-area: 1 / 1;
  white-space: nowrap;
  color: var(--cobre);
}
/* A que está saindo é clonada pelo JS e recebe esta classe. */
.hero-h1 .slot-quadro--sai {
  animation: quadroSai .46s var(--ease-inout) both;
  pointer-events: none;
}
.js .hero-h1 .slot-quadro--entra {
  animation: quadroEntra .58s var(--ease-out-strong) both;
}
@keyframes quadroSai {
  to {
    opacity: 0;
    filter: blur(9px) brightness(2.6);
    transform: translateY(-.52em);
  }
}
@keyframes quadroEntra {
  from {
    opacity: 0;
    filter: blur(11px) brightness(.3);
    transform: translateY(.5em);
  }
}
/* O traço embaixo do slot é o que amarra a troca na marca: ele encolhe e
   volta a crescer a cada quadro, como o filme sendo puxado. */
.hero-h1 .slot::after {
  content: '';
  position: absolute;
  inset-block-end: .06em;
  inset-inline: 0;
  height: .055em;
  background: var(--cobre);
  opacity: .42;
  transform-origin: 0 50%;
}
.hero-h1 .slot { position: relative; }
.js .hero-h1 .slot.is-trocando::after { animation: tracoPuxa .82s var(--ease-inout); }
@keyframes tracoPuxa {
  0%   { transform: scaleX(1); }
  38%  { transform: scaleX(0); transform-origin: 100% 50%; }
  39%  { transform: scaleX(0); transform-origin: 0 50%; }
  100% { transform: scaleX(1); transform-origin: 0 50%; }
}

.js .hero-reveal {
  animation: heroSobeCurto .6s var(--ease-inout) 460ms both;
}

/* Reduced motion: tudo no estado final, sem transição nem animação */
@media (prefers-reduced-motion: reduce) {
  .js .secao .reveal,
  .js .secao .reveal-num,
  .js .reveal-card,
  .js .hero-h1 .palavra,
  .js .hero-reveal {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    animation: none !important;
  }
  .seda-mancha,
  .faixa-trilho,
  .prova-tira,
  .hero-h1 .palavra,
  .hero-foto { animation: none !important; filter: none !important; }
  html { scroll-behavior: auto !important; }
}

/* ==========================================================================
   00 - Header
   ========================================================================== */
.header {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 60;
  background: transparent;
  backdrop-filter: none;
  transition: background-color .24s ease-out, backdrop-filter .24s ease-out, box-shadow .24s ease-out;
}
.header-inner {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding-block: 1.3rem;
}
.header .lockup { margin-inline-end: auto; }
.header.is-scrolled {
  background: rgba(27, 20, 16, .86);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 1px 0 var(--creme-14);
}

.nav {
  display: flex;
  align-items: center;
  gap: 2rem;
}
.nav-link {
  position: relative;
  font-size: .92rem;
  color: var(--creme-70);
  padding-block: .3em;
  transition: color .18s ease-out;
}
/* O sublinhado nasce com largura zero e cresce a partir da esquerda. Fica
   fora de qualquer elemento com overflow:hidden de propósito: foi um
   overflow de máscara de animação que já comeu um sublinhado de marca
   neste projeto antes. */
.nav-link::after {
  content: '';
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  height: 2px;
  width: 0;
  background: var(--cobre);
  transition: width .28s var(--ease-out-strong);
}
.nav-link:hover,
.nav-link.is-ativo { color: var(--creme); }
.nav-link:hover::after,
.nav-link.is-ativo::after { width: 100%; }

/* Botão de menu do celular: dois traços que viram X. */
.menu-btn {
  display: none;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid var(--creme-24);
  position: relative;
  flex: none;
}
.menu-btn span {
  position: absolute;
  inset-inline: 11px;
  height: 2px;
  background: var(--creme);
  transition: transform .26s var(--ease-out-strong), opacity .18s ease-out;
}
.menu-btn span:nth-child(1) { inset-block-start: 16px; }
.menu-btn span:nth-child(2) { inset-block-start: 24px; }
.menu-btn[aria-expanded="true"] span:nth-child(1) { transform: translateY(4px) rotate(45deg); }
.menu-btn[aria-expanded="true"] span:nth-child(2) { transform: translateY(-4px) rotate(-45deg); }

.menu-mobile {
  display: none;
  flex-direction: column;
  gap: .35rem;
  padding: .5rem clamp(1.25rem, 4vw, 4rem) 1.5rem;
  background: rgba(27, 20, 16, .97);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-block-start: 1px solid var(--creme-14);
}
.menu-mobile[hidden] { display: none; }
.menu-mobile a:not(.btn) {
  padding-block: .85rem;
  font-size: 1.05rem;
  color: var(--creme);
  border-block-end: 1px solid var(--creme-14);
}
.menu-mobile .btn { margin-block-start: 1rem; }

@media (max-width: 900px) {
  .nav { display: none; }
  .header .btn-sm { display: none; }
  .menu-btn { display: block; }
  .menu-mobile:not([hidden]) { display: flex; }
}

/* ==========================================================================
   01 - Hero
   ========================================================================== */
.hero {
  position: relative;
  background: var(--esc);
  color: var(--creme);
  min-height: calc(100svh - var(--header-h));
  display: flex;
  align-items: center;
  padding-block: clamp(2rem, 5vw, 3rem);
  overflow: clip;
}
.hero-inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.24fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(2rem, 4vw, 3.4rem);
  padding-block-start: var(--header-h);
}
/* O teto de 3,1rem nao e gosto: acima disso a linha mais longa do H1 nao cabe
   na coluna e quebra no meio, o que arruina o reveal palavra a palavra. A
   linha mais longa agora e "O album de aniversario" (24 caracteres), porque a
   palavra do slot troca em ciclo e a MAIS LONGA e quem manda.

   Medir contando linhas VISUAIS (altura da .line dividida pelo line-height),
   nao `getClientRects().length`: a .line e `display:block` e devolve sempre um
   rect, mesmo quebrada em duas linhas. Esse detalhe fez um teste passar verde
   com o H1 quebrado na tela. Ao mexer na fonte, na copy, na largura da coluna
   ou nas palavras do ciclo, medir de novo em 1440, 1280, 1024 e 900. */
.hero-h1 {
  font-size: clamp(1.9rem, 1.45rem + 2.13vw, 3.1rem);
  margin-block: 1.1rem 1.3rem;
}
.hero-lead { max-width: 44ch; }
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: .8rem;
  margin-block-start: 1.9rem;
}
.hero-meta {
  margin-block-start: 2.2rem;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: .7rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--creme-45);
}
.hero-meta span:not(:last-child)::after {
  content: '/';
  margin-inline: .9em;
  color: var(--creme-14);
}

/* ---------- O palco do hero: Chapa + o leque de capas ----------
   Regra que não pode ser quebrada de novo: as capas nascem VISÍVEIS. Na
   versão anterior elas nasciam com opacity 0 e scale .32 atrás do mascote,
   e só abriam depois de 100% de scroll dentro de um hero de 817px, ou seja
   quase nunca dentro do campo de visão. Quem chegava via um texto e um
   boneco, e não entendia o que o site vende. O scroll agora só afasta as
   capas um pouco; ele nunca decide se elas existem. */
.hero-palco {
  position: relative;
  aspect-ratio: 1 / 1;
  width: 100%;
  max-width: 480px;
  margin-inline: auto;
  /* width:100% é o que evita este bug: .hero-palco é item de grid e todos
     os filhos são position:absolute. Sem um filho em fluxo normal, o
     tamanho intrínseco do item de grid é 0, e o quadrado inteiro colapsa
     pra 0x0 levando as capas junto. */
}
.hero-chapa {
  position: absolute;
  inset-block-start: 30%;
  inset-inline-start: 27%;
  width: 46%;
  height: auto;
  z-index: 5;
  filter: drop-shadow(0 18px 34px rgba(10, 7, 5, .5));
}
.hero-foto {
  position: absolute;
  width: 37%;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: var(--shadow-pop);
  border: 3px solid var(--esc);
  background: var(--esc);
  will-change: transform;
}
.hero-foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  aspect-ratio: 3 / 2;
}
.hero-foto figcaption {
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  padding: 1.4em .7em .5em;
  background: linear-gradient(to top, rgba(10, 7, 5, .82), transparent);
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: .56rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--creme);
}
.hero-foto[data-hero-foto="1"] { inset-block-start: 0%;  inset-inline-start: 0%;  transform: rotate(-9deg); }
.hero-foto[data-hero-foto="2"] { inset-block-start: 6%;  inset-inline-end: 0%;    transform: rotate(7deg); }
.hero-foto[data-hero-foto="3"] { inset-block-end: 2%;    inset-inline-start: 4%;  transform: rotate(6deg); }
.hero-foto[data-hero-foto="4"] { inset-block-end: 0%;    inset-inline-end: 2%;    transform: rotate(-8deg); }

/* A entrada das capas é CSS puro e curta, pelo mesmo motivo do H1: elas
   estão acima da dobra e qualquer coisa que dependa do JS pra aparecer
   entra na conta do LCP. */
@keyframes capaEntra {
  from { opacity: 0; transform: translate3d(0, 22px, 0) scale(.9) rotate(0deg); }
}
.js .hero-foto { animation: capaEntra .78s var(--ease-out-strong) both; }
.js .hero-foto[data-hero-foto="1"] { animation-delay: 260ms; }
.js .hero-foto[data-hero-foto="2"] { animation-delay: 360ms; }
.js .hero-foto[data-hero-foto="3"] { animation-delay: 460ms; }
.js .hero-foto[data-hero-foto="4"] { animation-delay: 560ms; }

/* 1000px, e não os 900 do resto do arquivo. Entre 900 e 1000 o hero ainda
   estava em duas colunas e a coluna de texto ficava estreita demais para
   "O álbum de chá de bebê", a mais longa do ciclo. Medido nas 13 larguras. */
@media (max-width: 1000px) {
  .hero-inner { grid-template-columns: 1fr; }
  .hero-palco { order: -1; max-width: 330px; margin-block-end: 1rem; }
  /* Em coluna única a largura útil cai pra ~350px no celular, e a linha mais
     longa continua sendo a do slot ("O álbum de aniversário"). Esta escala foi
     medida com as seis palavras do ciclo, não estimada. */
  .hero-h1 { font-size: clamp(1.85rem, 1.15rem + 3.1vw, 3rem); }
}

/* ==========================================================================
   Faixa correndo
   ========================================================================== */
.faixa {
  background: var(--cobre);
  color: var(--esc);
  overflow: hidden;
  padding-block: .85rem;
  border-block: 1px solid rgba(27, 20, 16, .16);
}
.faixa-trilho {
  display: flex;
  width: max-content;
  animation: faixaCorre 34s linear infinite;
}
.faixa-grupo {
  display: flex;
  align-items: center;
  flex: none;
}
.faixa-grupo span {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1rem, .9rem + .5vw, 1.35rem);
  letter-spacing: -0.028em;
  padding-inline: .55em;
}
.faixa-p {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--esc);
  padding: 0 !important;
  margin-inline: .7em;
  flex: none;
}
/* -50% exatamente, com dois grupos idênticos: qualquer outro valor deixa a
   emenda visível a cada volta. */
@keyframes faixaCorre {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

/* ==========================================================================
   Seções gerais
   ========================================================================== */
.secao {
  padding-block: clamp(4rem, 7vw, 7.5rem);
  position: relative;
  background: var(--esc);
  color: var(--creme);
}
.secao-head { margin-block-end: clamp(2.2rem, 4vw, 3.2rem); }
.secao-titulo {
  font-size: clamp(1.95rem, 1.4rem + 2.4vw, 3.1rem);
  max-width: 20ch;
}

/* Curva orgânica separando duas seções (assinatura estrutural da Broud).
   É um pseudo-elemento com border-radius exagerado, não um SVG: assim ela
   acompanha a cor da própria seção e não precisa de um arquivo por combinação
   de cores.

   A primeira versão sangrava `inset-inline: -12%` pra esconder o encontro das
   pontas com a borda, e isso criou **437px de largura numa tela de 390**: a
   seção não tem recorte horizontal, então a sangria virou transbordo e barra
   de rolagem lateral no celular. Pego pela checagem de
   `scrollWidth != clientWidth`, que faz parte da bateria de testes deste site.

   A sangria voltou pra 0 e o encontro das pontas se resolve pelo raio: com
   `50% 100%` o arco chega na borda com tangente horizontal, então não existe
   dentinho pra esconder. */
.curva-topo::before {
  content: '';
  position: absolute;
  inset-block-start: -2.6vw;
  inset-inline: 0;
  height: 5.2vw;
  background: inherit;
  border-start-start-radius: 50% 100%;
  border-start-end-radius: 50% 100%;
  pointer-events: none;
  z-index: 0;
}
/* O conteúdo precisa ficar acima da curva, senão a curva da seção seguinte
   passa por cima do último parágrafo da anterior. */
.curva-topo > .container { position: relative; z-index: 1; }

/* ---------- 02: O que trava hoje ---------- */
.secao-problema {
  background: var(--esc-fundo);
  position: relative;
}
.problemas-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.75rem, 3vw, 2.5rem);
}
.problema-num {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: clamp(2rem, 1.6rem + 1.6vw, 2.8rem);
  color: var(--creme-24);
  margin-block-end: .5rem;
  display: block;
}
.problema-item p { color: var(--creme-70); max-width: 32ch; }

.problema-link {
  margin-block-start: clamp(2rem, 4vw, 3rem);
  padding-block-start: 1.6rem;
  border-block-start: 1px solid var(--creme-14);
  max-width: 60ch;
}
.problema-link a {
  color: var(--cobre);
  font-size: .98rem;
  border-block-end: 1px solid color-mix(in srgb, var(--cobre) 40%, transparent);
  padding-block-end: 2px;
  transition: border-color .2s ease-out;
}
.problema-link a::after { content: ' \2192'; }
.problema-link a:hover { border-block-end-color: var(--cobre); }

.problema-mascote {
  position: absolute;
  inset-block-end: 0;
  inset-inline-end: clamp(1rem, 4vw, 3rem);
  width: clamp(70px, 8vw, 110px);
  height: auto;
  opacity: .9;
  pointer-events: none;
}

/* ==========================================================================
   03 - A vitrine de temas, em palco (o coração da página)
   O fundo da seção assume a cor do tema ativo (técnica do Project Aperture).
   ========================================================================== */
.secao-vitrine {
  background: var(--palco-bg);
  color: var(--palco-fg);
  transition: background-color .7s var(--ease-inout), color .7s var(--ease-inout);
  overflow: clip;
}
.secao-vitrine::before {
  content: '';
  position: absolute;
  inset-block-start: -10%;
  inset-inline-end: -10%;
  width: 55%;
  height: 70%;
  background: radial-gradient(circle at 60% 40%, var(--palco-luz), transparent 68%);
  filter: blur(40px);
  pointer-events: none;
  transition: background .7s var(--ease-inout);
}
.secao-vitrine .container { position: relative; z-index: 1; }
.secao-vitrine .secao-titulo,
.secao-vitrine .pill { color: inherit; }
.secao-vitrine .lead { color: inherit; opacity: .72; }
.secao-vitrine .pill { border-color: color-mix(in srgb, currentColor 24%, transparent); }
.vitrine-lead { margin-block-start: 1rem; }

/* Palco: um painel por tema. Todos existem no HTML desde o load; sem JS
   eles ficam empilhados e legíveis, e o JS só decide qual está visível.
   Nenhum conteúdo real depende de JS pra existir. */
.palco { position: relative; }
.palco-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.12fr);
  align-items: center;
  gap: clamp(2rem, 4vw, 4rem);
}
.js .palco { display: grid; }
/* Os painéis se empilham na mesma célula do grid, então a altura do palco é
   a do painel mais alto e não pula ao trocar de tema. */
.js .palco-item {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transform: translateY(16px);
  transition: opacity .5s var(--ease-out-strong), transform .5s var(--ease-out-strong), visibility .5s;
  pointer-events: none;
}
.js .palco-item.is-ativo {
  opacity: 1;
  visibility: visible;
  transform: none;
  pointer-events: auto;
}

.palco-conta {
  display: flex;
  align-items: center;
  gap: .7em;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: .74rem;
  letter-spacing: .14em;
  opacity: .6;
  margin-block-end: 1rem;
}
.palco-sep {
  width: 22px;
  height: 1px;
  background: currentColor;
  opacity: .4;
}
.palco-status {
  border: 1px solid color-mix(in srgb, currentColor 34%, transparent);
  border-radius: 999px;
  padding: .3em .8em;
  letter-spacing: .1em;
}
.palco-status--no-ar {
  background: var(--cobre);
  border-color: var(--cobre);
  color: var(--esc);
  opacity: 1;
}
.palco-nome {
  font-size: clamp(2.6rem, 1.8rem + 3.6vw, 4.6rem);
  line-height: .95;
  color: inherit;
  margin-block-end: .5rem;
}
.palco-tipo {
  font-size: clamp(1.02rem, .95rem + .35vw, 1.2rem);
  opacity: .68;
  margin-block-end: 1.9rem;
}
.palco-lista {
  display: flex;
  flex-direction: column;
  gap: .95rem;
  margin-block-end: 2.2rem;
  max-width: 46ch;
}
.palco-lista li {
  position: relative;
  padding-inline-start: 1.3em;
  font-size: .98rem;
  line-height: 1.55;
  opacity: .82;
}
.palco-lista li::before {
  content: '';
  position: absolute;
  inset-block-start: .58em;
  inset-inline-start: 0;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--cobre);
}
.palco-lista b { font-weight: 700; opacity: 1; }
.palco-capa {
  border-radius: var(--radius);
  overflow: hidden;
  aspect-ratio: 3 / 2;
  box-shadow: 0 40px 90px -30px rgba(10, 7, 5, .7);
}
.palco-capa img { width: 100%; height: 100%; object-fit: cover; }
.palco-item .btn-outline { border-color: color-mix(in srgb, currentColor 30%, transparent); color: inherit; }

/* A tira de navegação do palco */
.tira {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(.7rem, 1.4vw, 1.1rem);
  margin-block-start: clamp(2.5rem, 4vw, 3.5rem);
}
.tira-item {
  position: relative;
  border-radius: var(--radius-sm);
  overflow: hidden;
  aspect-ratio: 16 / 10;
  opacity: .42;
  border: 2px solid transparent;
  transition: opacity .3s ease-out, border-color .3s ease-out, transform .3s var(--ease-out-strong);
  padding: 0;
}
.tira-item img { width: 100%; height: 100%; object-fit: cover; }
.tira-nome {
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  padding: 1.6em .6em .5em;
  background: linear-gradient(to top, rgba(10, 7, 5, .85), transparent);
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: .64rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #F7EFE2;
}
.tira-item.is-ativo {
  opacity: 1;
  border-color: var(--cobre);
}
@media (hover: hover) {
  .tira-item:hover { opacity: .85; transform: translateY(-3px); }
  .tira-item.is-ativo:hover { opacity: 1; }
}

.vitrine-nota {
  margin-block-start: clamp(2rem, 3vw, 2.8rem);
  padding-block-start: 1.6rem;
  border-block-start: 1px solid color-mix(in srgb, currentColor 16%, transparent);
  max-width: 56ch;
  opacity: .68;
  font-size: .95rem;
}

@media (max-width: 900px) {
  .palco-item { grid-template-columns: 1fr; gap: 1.8rem; }
  .palco-item .palco-capa { order: -1; }
  .palco-nome { font-size: clamp(2.4rem, 1.8rem + 4vw, 3.2rem); }
}
@media (max-width: 560px) {
  .tira { grid-template-columns: repeat(2, 1fr); }
}

/* ==========================================================================
   04 - Como funciona. Seção CLARA: o contraste entre seções é o ritmo.
   ========================================================================== */
.secao-como {
  background: var(--creme);
  color: var(--esc);
}
.secao-como .secao-titulo { color: var(--esc); }
/* O cobre puro sobre creme dá 2,22:1 e reprova como texto. Sobre claro a
   palavra colorida da headline usa a sombra profunda do mascote, que é a
   mesma família de cor e dá 7,9:1. */
.secao-como h2 em { color: var(--m3); }

.passos-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.75rem, 3vw, 2.75rem);
  position: relative;
}

/* ---------- Trilho com ponto (gramática da Broud) ----------
   Corre na altura do centro dos selos, ligando os três. A fita em cobre
   cresce conforme a seção rola, e o ponto anda com ela. Fica ATRÁS dos selos
   (z-index 0 contra o 1 deles), senão a linha cruza por cima do mascote. */
.trilho {
  position: absolute;
  z-index: 0;
  inset-block-start: 37px;   /* metade dos 74px do selo */
  inset-inline: 37px;
  height: 2px;
  pointer-events: none;
}
.trilho-base,
.trilho-fita {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  border-radius: 2px;
}
.trilho-base { inset-inline-end: 0; background: var(--esc-14); }
.trilho-fita {
  width: 0;
  background: var(--cobre);
  transform-origin: 0 50%;
}
.trilho-ponto {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 0;
  width: 13px;
  height: 13px;
  margin: -6.5px 0 0 -6.5px;
  border-radius: 50%;
  background: var(--cobre);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--cobre) 22%, transparent);
}
/* Sem JS o trilho nasce completo: o estado padrão é o final, nunca o vazio. */
.js .trilho-fita { width: 0; }
.js .trilho-ponto { inset-inline-start: 0; }
.trilho-fita { width: 100%; }
.trilho-ponto { inset-inline-start: 100%; }

.passo-item { position: relative; z-index: 1; }
/* As poses do mascote só funcionam sobre fundo escuro: mãos e pés são
   creme e desaparecem no claro, deixando o bicho com cara de amputado.
   Por isso cada pose ganha um selo escuro atrás dela nesta seção. */
.passo-selo {
  width: 74px;
  height: 74px;
  border-radius: 50%;
  background: var(--esc);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-block-end: 1.2rem;
}
.passo-selo img { width: 56px; height: 56px; }
.passo-num {
  display: block;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: .74rem;
  letter-spacing: .16em;
  color: var(--m2);
  margin-block-end: .5rem;
}
.passo-titulo {
  color: var(--esc);
  font-size: 1.35rem;
  margin-block-end: .5rem;
}
.passo-item p { color: var(--esc-70); max-width: 34ch; }

.chapa-card {
  display: flex;
  align-items: center;
  gap: clamp(1.2rem, 3vw, 2.2rem);
  margin-block-start: clamp(2.5rem, 5vw, 4rem);
  background: var(--esc);
  color: var(--creme);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 3vw, 2.2rem);
  box-shadow: var(--shadow-card);
}
.chapa-foto {
  width: clamp(78px, 10vw, 112px);
  flex: none;
}
.chapa-nome {
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -0.028em;
  font-size: clamp(1.3rem, 1.1rem + .8vw, 1.7rem);
  margin-block-end: .45rem;
}
.chapa-texto { color: var(--creme-70); max-width: 56ch; font-size: .98rem; }

@media (max-width: 560px) {
  .chapa-card { flex-direction: column; align-items: flex-start; }
}

/* ==========================================================================
   05 - A prova real
   ========================================================================== */
.secao-prova { background: var(--esc); }
.prova-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .78fr);
  align-items: center;
  gap: clamp(2rem, 5vw, 4.5rem);
}
.prova-inner .secao-titulo { margin-block: 1rem .1rem; }
.prova-inner .lead { margin-block: 1.1rem 2rem; }
.prova-tela { display: flex; flex-direction: column; align-items: center; }
/* Moldura de celular desenhada em CSS, sem imagem de mockup baixada. */
.prova-fone {
  position: relative;
  width: min(280px, 74vw);
  aspect-ratio: 9 / 19;
  border-radius: 38px;
  padding: 10px;
  background: linear-gradient(160deg, #3a2c22, #15100c);
  box-shadow: 0 40px 80px -26px rgba(10, 7, 5, .75);
}
/* A janela é o recorte da tela do celular, e é ela que tem o overflow.
   Nunca pôr o overflow no .prova-fone: a moldura tem borda arredondada e
   sombra, e cortar ali comeria a sombra junto.

   `position: absolute` é obrigatório aqui, não é estilo. O .prova-fone define
   a altura por `aspect-ratio: 9/19`, e **aspect-ratio cede quando o conteúdo
   em fluxo é mais alto**: a tira do álbum tem 1286px renderizados dentro de um
   celular de 590px, e com a janela em fluxo normal ela esticava a moldura
   inteira para mais de 1100px, vazando por cima e por baixo da seção. Tirando
   a janela do fluxo, o aspect-ratio volta a mandar e o overflow corta. */
.prova-janela {
  position: absolute;
  inset: 10px;
  overflow: hidden;
  border-radius: 28px;
  background: #FBF3EE; /* o creme da capa do álbum, pra não piscar branco */
}
/* A tira é o álbum inteiro numa imagem só. `height:auto` com a largura em
   100% mantém a proporção 520x2572, e o translate negativo é o que rola.
   O valor de -55% não é chute: a tira renderizada tem cerca de 1286px de
   altura numa janela de 570px, então 55% dela é o que sobra pra correr. */
.prova-tira {
  width: 100%;
  height: auto;
  display: block;
  will-change: transform;
}
.js .prova-tira {
  animation: provaRola 26s ease-in-out infinite alternate;
  animation-play-state: paused;
}
/* Só roda enquanto a seção está na tela. Animação infinita rodando fora do
   campo de visão é CPU queimada à toa, e este site já paga o custo das três
   manchas do fundo de seda. */
.js [data-prova].is-rodando .prova-tira { animation-play-state: running; }
@keyframes provaRola {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(0, -55%, 0); }
}
.prova-legenda {
  margin-block-start: 1.1rem;
  text-align: center;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--creme-45);
}
.prova-notch {
  position: absolute;
  inset-block-start: 22px;
  inset-inline-start: 50%;
  transform: translateX(-50%);
  width: 34%;
  height: 17px;
  border-radius: 999px;
  background: #15100c;
  z-index: 2;
}
@media (max-width: 900px) {
  .prova-inner { grid-template-columns: 1fr; }
  .prova-tela { order: -1; }
}

/* ==========================================================================
   06 - Dúvidas
   ========================================================================== */
.secao-faq { background: var(--carvao); }
.faq-inner {
  display: grid;
  grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
.faq-head .secao-titulo { margin-block: .2rem 1rem; }
.faq-btn { margin-block-start: 1.6rem; }
/* A coluna da esquerda do FAQ é curta de propósito (é a gramática da Broud),
   mas sem nada embaixo ela vira um buraco de meia tela. O mascote com cara de
   dúvida ocupa esse espaço e é justamente onde ele deve aparecer: reagindo ao
   conteúdo da seção. */
.faq-chapa {
  width: clamp(96px, 12vw, 148px);
  margin-block-start: clamp(2rem, 4vw, 3.5rem);
  opacity: .92;
}
.faq-lista { display: flex; flex-direction: column; gap: .7rem; }

/* <details> nativo: abre e fecha sem uma linha de JS, funciona com teclado
   e com leitor de tela por padrão, e o conteúdo da resposta está no HTML
   desde o load (conta pro SEO e pro rich result de FAQ). O JS só entra
   pra fechar as outras quando uma abre. */
.faq-item {
  background: rgba(247, 239, 226, .04);
  border: 1px solid var(--creme-14);
  border-radius: var(--radius-sm);
  transition: border-color .24s ease-out, background-color .24s ease-out;
}
.faq-item[open] {
  border-color: color-mix(in srgb, var(--cobre) 46%, transparent);
  background: rgba(247, 239, 226, .06);
}
.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.2rem;
  cursor: pointer;
  padding: 1.15rem 1.35rem;
  font-weight: 600;
  font-size: 1.02rem;
  list-style: none;
  color: var(--creme);
}
.faq-mais {
  position: relative;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1px solid var(--creme-24);
  flex: none;
  transition: background-color .24s ease-out, border-color .24s ease-out, transform .3s var(--ease-out-strong);
}
.faq-mais::before,
.faq-mais::after {
  content: '';
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  background: currentColor;
  transform: translate(-50%, -50%);
  transition: opacity .24s ease-out;
}
.faq-mais::before { width: 11px; height: 1.5px; }
.faq-mais::after  { width: 1.5px; height: 11px; }
.faq-item[open] .faq-mais {
  background: var(--cobre);
  border-color: var(--cobre);
  color: var(--esc);
  transform: rotate(180deg);
}
.faq-item[open] .faq-mais::after { opacity: 0; }
.faq-resp {
  padding: 0 1.35rem 1.3rem;
  color: var(--creme-70);
  font-size: .96rem;
  line-height: 1.6;
  max-width: 62ch;
}
/* A abertura anima a altura por grid-template-rows, que é interpolável, em
   vez de height:auto, que não é. */
@media (prefers-reduced-motion: no-preference) {
  .js .faq-item > .faq-resp {
    display: grid;
    grid-template-rows: 1fr;
    animation: faqAbre .34s var(--ease-out-strong);
  }
  @keyframes faqAbre {
    from { grid-template-rows: 0fr; opacity: 0; }
    to   { grid-template-rows: 1fr; opacity: 1; }
  }
  .js .faq-item > .faq-resp > p { min-height: 0; }
}

@media (max-width: 900px) {
  .faq-inner { grid-template-columns: 1fr; }
  /* Em coluna única o mascote cairia entre o texto e as perguntas, empurrando
     a primeira pergunta pra fora da tela. */
  .faq-chapa { display: none; }
}

/* ==========================================================================
   07 - Lista de espera
   ========================================================================== */
.secao-lista {
  display: flex;
  justify-content: center;
  background: var(--esc-fundo);
  position: relative;
  overflow: clip;
}
.seda--lista { opacity: .42; }
.secao-lista .container { position: relative; z-index: 1; display: flex; justify-content: center; }
.card-lista {
  width: 100%;
  max-width: 620px;
  background: var(--creme);
  color: var(--esc);
  border-radius: 24px;
  box-shadow: var(--shadow-card);
  padding: clamp(1.75rem, 4vw, 3rem);
}
.card-lista .secao-titulo {
  color: var(--esc);
  font-size: clamp(1.55rem, 1.3rem + 1.3vw, 2.1rem);
  margin-block-start: .8rem;
  max-width: none;
}
.card-lista .lead { color: var(--esc-70); margin-block-start: .5rem; margin-block-end: 1.75rem; }

.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}
.form-field { display: flex; flex-direction: column; gap: .4rem; margin-block-end: 1rem; }
.form-field--full { grid-column: 1 / -1; }
.form-field[hidden] { display: none; }

.form-field label {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--esc-70);
}

.form-field input,
.form-field select {
  border: 1px solid var(--esc-14);
  border-radius: var(--radius-sm);
  padding: .85em 1em;
  background: #fff;
  color: var(--esc);
  font-size: 1rem;
  transition: border-color .15s ease-out, box-shadow .15s ease-out;
}
.form-field input:focus,
.form-field select:focus {
  outline: none;
  border-color: var(--cobre);
  box-shadow: 0 0 0 3px rgba(232, 135, 26, .18);
}
.form-field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='M5.5 7.5l4.5 4.5 4.5-4.5' stroke='%236A3C15' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1em center;
}

/* Honeypot: nunca display:none. Campo escondido por display:none às vezes é
   ignorado pelo preenchedor automático junto com o robô, e a armadilha deixa
   de funcionar. left:-9999px some visualmente sem sair do fluxo. */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-nota {
  font-size: .82rem;
  color: var(--esc-70);
  margin-block-start: 1rem;
}

.form-erro-wrap {
  display: flex;
  align-items: center;
  gap: .75rem;
  margin-block-start: .9rem;
}
.form-erro { color: var(--erro); font-size: .88rem; }
/* A pose só funciona sobre fundo escuro (mãos e pés são creme, somem no
   claro), e o card da lista é creme, então a pose de erro ganha um selo
   escuro atrás dela aqui dentro. */
.form-erro-mascote-selo {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--esc);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
/* [hidden] tem a mesma especificidade (0,1,0) que a classe acima, e em
   empate quem vem depois no CSS de autor vence a folha do agente do
   usuário. Sem esta regra o display:inline-flex ganhava do display:none
   nativo e o selo aparecia mesmo com o atributo hidden no HTML. */
.form-erro-mascote-selo[hidden] { display: none; }
.form-erro-mascote-selo img { width: 30px; height: 30px; }

.sucesso-selo {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--esc);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-block-end: 1rem;
}
.sucesso-selo img { width: 42px; height: 42px; }
.sucesso-titulo {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.45rem, 1.2rem + 1.2vw, 1.9rem);
  letter-spacing: -0.028em;
  line-height: 1.08;
  margin-block-end: .6rem;
  color: var(--esc);
}
.sucesso-texto { color: var(--esc-70); margin-block-end: 1.75rem; }

/* ==========================================================================
   Artigo (páginas de conteúdo)
   Medida de leitura em 68ch: acima disso o olho perde a linha ao voltar.
   ========================================================================== */
.artigo { padding-block-start: calc(var(--header-h) + clamp(2rem, 5vw, 4rem)); }
.artigo-corpo { max-width: 74ch; }

.migalhas {
  display: flex;
  gap: .6em;
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .08em;
  color: var(--creme-45);
  margin-block-end: 1.6rem;
}
.migalhas a { color: var(--cobre); }
.migalhas a:hover { text-decoration: underline; }

.artigo-titulo {
  font-size: clamp(1.9rem, 1.3rem + 2.4vw, 3rem);
  max-width: 22ch;
  margin-block-end: 1.4rem;
}
.artigo-linha-fina {
  font-size: clamp(1.05rem, 1rem + .35vw, 1.25rem);
  line-height: 1.55;
  color: var(--creme-70);
  max-width: 62ch;
}
.artigo-meta {
  font-family: var(--font-mono);
  font-size: .74rem;
  letter-spacing: .08em;
  color: var(--creme-45);
  margin-block: 1.4rem 2.6rem;
  padding-block-end: 1.6rem;
  border-block-end: 1px solid var(--creme-14);
}

.artigo-corpo h2 {
  font-size: clamp(1.4rem, 1.2rem + .9vw, 1.9rem);
  margin-block: 2.8rem 1rem;
  max-width: 26ch;
}
.artigo-corpo h3 {
  font-size: clamp(1.12rem, 1.05rem + .4vw, 1.32rem);
  color: var(--cobre);
  margin-block: 2rem .7rem;
}
.artigo-corpo p {
  color: var(--creme-70);
  line-height: 1.68;
  margin-block-end: 1.1rem;
  max-width: 68ch;
}
.artigo-corpo strong { color: var(--creme); font-weight: 700; }

/* A nota fecha cada bloco com o veredito, e o traço em cobre à esquerda é o
   que faz o olho achar ela na varredura. */
.artigo-nota {
  border-inline-start: 2px solid var(--cobre);
  padding-inline-start: 1.1rem;
  margin-block: 1.2rem 2rem !important;
  font-size: .96rem;
}

.artigo-lista {
  display: flex;
  flex-direction: column;
  gap: .9rem;
  margin-block: 1.2rem 1.8rem;
  max-width: 68ch;
}
.artigo-lista li {
  position: relative;
  padding-inline-start: 1.4em;
  color: var(--creme-70);
  line-height: 1.6;
}
.artigo-lista li::before {
  content: '';
  position: absolute;
  inset-block-start: .62em;
  inset-inline-start: 0;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--cobre);
}
.artigo-lista strong { color: var(--creme); }

.artigo-cta {
  display: flex;
  gap: clamp(1.2rem, 3vw, 2rem);
  align-items: flex-start;
  margin-block-start: 3.5rem;
  padding: clamp(1.5rem, 3vw, 2.2rem);
  border-radius: var(--radius);
  background: rgba(232, 135, 26, .09);
  border: 1px solid color-mix(in srgb, var(--cobre) 34%, transparent);
}
.artigo-cta-selo {
  width: clamp(70px, 9vw, 100px);
  flex: none;
  border-radius: 50%;
  background: var(--esc);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: .5rem;
}
.artigo-cta-titulo { font-size: 1.3rem; margin-block: 0 .7rem !important; max-width: none; }
.artigo-cta-acoes {
  display: flex;
  flex-wrap: wrap;
  gap: .7rem;
  margin-block-start: 1.4rem;
}
@media (max-width: 560px) {
  .artigo-cta { flex-direction: column; }
  .artigo-cta-acoes .btn { width: 100%; }
}

/* ==========================================================================
   Blog: índice e lista de posts
   ========================================================================== */
.blog-topo {
  padding-block: calc(var(--header-h) + clamp(2.5rem, 6vw, 4.5rem)) clamp(1rem, 2vw, 2rem);
}
.blog-topo .secao-titulo { margin-block: .4rem 1.2rem; max-width: 18ch; }
.secao-blog-lista { padding-block-start: 0; }

.post-grupo { margin-block-end: clamp(3rem, 6vw, 4.5rem); }
.post-grupo-titulo {
  font-size: clamp(1.15rem, 1.05rem + .4vw, 1.4rem);
  color: var(--cobre);
  padding-block-end: .9rem;
  margin-block-end: 1.8rem;
  border-block-end: 1px solid var(--creme-14);
}

.posts {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
}
/* O card inteiro é o link, não só o título: alvo de toque maior no celular e
   uma parada só por card na navegação por teclado. */
.post a {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: clamp(1.2rem, 2.2vw, 1.6rem);
  border: 1px solid var(--creme-14);
  border-radius: var(--radius-sm);
  background: rgba(247, 239, 226, .03);
  transition: border-color .24s ease-out, background-color .24s ease-out, transform .24s var(--ease-out-strong);
}
.post-meta {
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--creme-45);
}
.post-titulo {
  font-size: 1.16rem;
  line-height: 1.18;
  margin-block: .7rem .6rem;
  color: var(--creme);
}
.post-resumo {
  font-size: .92rem;
  line-height: 1.55;
  color: var(--creme-70);
  flex: 1;
}
.post-ler {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  margin-block-start: 1.1rem;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: .7rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--cobre);
}
.post-ler::after { content: '\2192'; transition: transform .24s var(--ease-out-strong); }
@media (hover: hover) {
  .post a:hover {
    border-color: color-mix(in srgb, var(--cobre) 50%, transparent);
    background: rgba(232, 135, 26, .07);
    transform: translateY(-3px);
  }
  .post a:hover .post-ler::after { transform: translateX(4px); }
}

/* ---------- "Leia também" no fim do artigo ---------- */
.relacionados {
  margin-block-start: clamp(2.5rem, 5vw, 3.5rem);
  padding-block-start: 1.8rem;
  border-block-start: 1px solid var(--creme-14);
}
.relacionados-titulo {
  font-size: 1.1rem;
  margin-block-end: 1.2rem !important;
  max-width: none;
}
.relacionados ul {
  display: grid;
  gap: .6rem;
}
.relacionados a {
  display: block;
  padding: .95rem 1.1rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--creme-14);
  transition: border-color .22s ease-out, background-color .22s ease-out;
}
.rel-cluster {
  display: block;
  font-family: var(--font-mono);
  font-size: .64rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--cobre);
  margin-block-end: .3rem;
}
.rel-titulo { color: var(--creme); font-size: .98rem; line-height: 1.35; }
@media (hover: hover) {
  .relacionados a:hover {
    border-color: color-mix(in srgb, var(--cobre) 46%, transparent);
    background: rgba(232, 135, 26, .06);
  }
}

/* ==========================================================================
   08 - Rodapé
   ========================================================================== */
.footer {
  background: var(--esc);
  color: var(--creme-45);
  padding-block: clamp(2.5rem, 5vw, 4rem);
  position: relative;
  overflow: clip;
}
.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}
.footer-lockup { --lockup-h: 30px; }
.footer-desc {
  font-size: .9rem;
  max-width: 40ch;
  color: var(--creme-45);
  margin-block-start: .6rem;
}
.footer-copy {
  font-size: .78rem;
  margin-block-start: 2rem;
  color: var(--creme-45);
}
.footer-espia {
  position: absolute;
  inset-block-end: -6px;
  inset-inline-end: clamp(1rem, 6vw, 5rem);
  width: clamp(64px, 7vw, 96px);
  height: auto;
  pointer-events: none;
}

/* ==========================================================================
   Responsivo geral
   ========================================================================== */
@media (max-width: 900px) {
  .problemas-grid,
  .passos-grid { grid-template-columns: 1fr; gap: 2.25rem; }
  /* Em coluna única o trilho vira vertical, correndo pela esquerda na altura
     do centro dos selos. */
  .trilho {
    inset-block: 37px 37px;
    inset-inline: 37px auto;
    width: 2px;
    height: auto;
  }
  .trilho-base,
  .trilho-fita {
    inset-inline: 0;
    inset-block-start: 0;
  }
  .trilho-base { inset-block-end: 0; }
  .trilho-fita { width: auto; height: 0; }
  .js .trilho-fita { height: 0; width: auto; }
  .trilho-fita { height: 100%; }
  .trilho-ponto {
    inset-inline-start: 50%;
    inset-block-start: 0;
  }
  .js .trilho-ponto { inset-block-start: 0; inset-inline-start: 50%; }
  .trilho-ponto { inset-block-start: 100%; }
}

@media (max-width: 640px) {
  .header-inner { padding-block: 1.05rem; }
  .hero-actions { flex-direction: column; align-items: stretch; }
  .form-grid { grid-template-columns: 1fr; }
  .footer-espia { width: 56px; }
}
