/* =============================================================================
   O Estudo Devolve — folha de estilo AUTORADA.
   Não é gerada. `tokens.css` é gerado de src/ui/marca.ts; este arquivo é design.

   A pilha de profundidade, de baixo para cima, é o que faz o vidro existir:
     1. base escura              2. malha de gradiente animada
     3. granulado                4. painéis de vidro
     5. conteúdo
   Vidro sobre cor plana não tem nada para desfocar e vira um quadrado cinza —
   é assim que a maioria dos sites erra glassmorphism.
   ========================================================================== */

@import url('tokens.css');

/* -----------------------------------------------------------------------------
   Sistema de movimento: DUAS velocidades, nunca misturadas.
   Ambiente é lento e de baixo contraste; resposta é rápida e precisa. Trocar
   as duas de lugar é o que faz site parecer barato.
   -------------------------------------------------------------------------- */
:root {
  --t-micro: 150ms;
  --t-transicao: 300ms;
  --t-entrada: 500ms;
  --t-ambiente: 40s;

  --e-micro: cubic-bezier(0.2, 0, 0.4, 1);
  --e-transicao: cubic-bezier(0.32, 0.72, 0, 1);
  /* Desaceleração longa: arranca rápido e assenta devagar. O olho lê como massa. */
  --e-entrada: cubic-bezier(0.16, 1, 0.3, 1);
  /* Ultrapassagem curta. Só para conquista — nada mais usa esta. */
  --e-mola: cubic-bezier(0.34, 1.56, 0.64, 1);

  --raio: 18px;
  --faixa: 1080px;

  /* Vidro. 58% de opacidade é PISO de legibilidade, não gosto: abaixo disso o
     texto perde 4.5:1 sobre a parte clara da malha. */
  --vidro: color-mix(in oklab, var(--fundo) 58%, transparent);
  --vidro-borda: rgba(255, 255, 255, 0.09);
  --vidro-borda-viva: rgba(255, 255, 255, 0.2);
  --vidro-blur: 28px;

  /* Três camadas: perto e opaca, média, larga e difusa. Uma sombra só faz o
     cartão parecer adesivo colado na tela. */
  --elev: 0 1px 2px rgba(3, 6, 22, 0.5), 0 8px 24px rgba(3, 6, 22, 0.38),
    0 32px 64px -16px rgba(3, 6, 22, 0.6);
  --elev-alta: 0 2px 4px rgba(3, 6, 22, 0.5), 0 14px 32px rgba(3, 6, 22, 0.44),
    0 44px 88px -20px rgba(3, 6, 22, 0.66);
}

/* Ângulos e posições da malha precisam ser @property para INTERPOLAR.
   Sem o tipo declarado, o navegador trata como string e a animação salta. */
@property --malha-x1 { syntax: '<percentage>'; inherits: false; initial-value: 12%; }
@property --malha-y1 { syntax: '<percentage>'; inherits: false; initial-value: 4%; }
@property --malha-x2 { syntax: '<percentage>'; inherits: false; initial-value: 88%; }
@property --malha-y2 { syntax: '<percentage>'; inherits: false; initial-value: 12%; }
@property --malha-x3 { syntax: '<percentage>'; inherits: false; initial-value: 68%; }
@property --malha-y3 { syntax: '<percentage>'; inherits: false; initial-value: 82%; }

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Permite transicionar até `auto` — é o que torna o FAQ animável. */
  interpolate-size: allow-keywords;
}

body {
  margin: 0;
  background: var(--fundo);
  color: var(--texto-suave);
  font-family: Outfit, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  font-size: 17px;
  line-height: 1.62;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

@font-face {
  font-family: Outfit;
  src: url('fontes/Outfit-Regular.ttf') format('truetype');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: Outfit;
  src: url('fontes/Outfit-SemiBold.ttf') format('truetype');
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: Outfit;
  src: url('fontes/Outfit-Bold.ttf') format('truetype');
  font-weight: 700;
  font-display: swap;
}

img { max-width: 100%; height: auto; display: block; }

::selection { background: var(--roxo); color: #fff; }

/* Anel de foco próprio: o padrão do navegador desaparece sobre vidro escuro. */
:focus-visible {
  outline: 3px solid var(--magenta-claro);
  outline-offset: 3px;
  border-radius: 6px;
}

/* -----------------------------------------------------------------------------
   Camadas 2 e 3: a malha animada e o granulado
   -------------------------------------------------------------------------- */
.fundo {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

.fundo::before {
  content: '';
  position: absolute;
  inset: -20%;
  background:
    radial-gradient(42rem 34rem at var(--malha-x1) var(--malha-y1),
      oklch(65% 0.13 195 / 0.34), transparent 68%),
    radial-gradient(38rem 30rem at var(--malha-x2) var(--malha-y2),
      oklch(58% 0.2 300 / 0.32), transparent 66%),
    radial-gradient(46rem 32rem at var(--malha-x3) var(--malha-y3),
      oklch(60% 0.19 340 / 0.26), transparent 70%);
  animation: deriva var(--t-ambiente) linear infinite alternate;
  will-change: --malha-x1, --malha-y1, --malha-x2, --malha-y2;
}

/* oklch e não sRGB: gradiente de ciano a magenta em sRGB passa por um cinza
   sujo no meio do caminho. Em oklch a interpolação é perceptualmente reta. */
@keyframes deriva {
  to {
    --malha-x1: 26%;
    --malha-y1: 18%;
    --malha-x2: 72%;
    --malha-y2: 2%;
    --malha-x3: 54%;
    --malha-y3: 70%;
  }
}

/* Granulado: mata o banding do gradiente e é o que separa "premium" de
   "chapado". 400 bytes, sem requisição. */
.fundo::after {
  content: '';
  position: absolute;
  inset: 0;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Fio de progresso da leitura. Puro CSS, ligado ao scroll da raiz. */
.progresso {
  position: fixed;
  top: 0;
  left: 0;
  height: 2px;
  width: 100%;
  transform-origin: 0 50%;
  transform: scaleX(0);
  background: var(--rampa);
  z-index: 10;
}

/* -----------------------------------------------------------------------------
   Tipografia e estrutura
   -------------------------------------------------------------------------- */
.faixa { width: 100%; max-width: var(--faixa); margin: 0 auto; padding: 0 24px; }

section { padding: clamp(72px, 11vh, 132px) 0; position: relative; }

h1, h2, h3 {
  color: var(--texto);
  margin: 0 0 18px;
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.025em;
  text-wrap: balance;
}
h1 { font-size: clamp(2.5rem, 7.5vw, 4.6rem); font-weight: 700; letter-spacing: -0.035em; }
h2 { font-size: clamp(1.7rem, 4.4vw, 2.7rem); margin-bottom: 14px; }
h3 { font-size: 1.16rem; letter-spacing: -0.015em; margin-bottom: 8px; }

p { margin: 0 0 14px; }
.chamada { font-size: clamp(1.06rem, 2.3vw, 1.3rem); max-width: 58ch; color: var(--texto-suave); }
.nota { font-size: 0.935rem; color: var(--texto-fraco); }
.secao-topo { margin-bottom: 44px; }

/* Fecho de seção: a frase que pede reflexão, e não descreve recurso.
   Sem vidro de propósito — um painel a mais aqui competiria com os cartões
   logo acima, e o peso do texto é justamente ele estar solto na página. */
.fecho {
  margin: 40px 0 0;
  padding-left: 22px;
  max-width: 66ch;
  font-size: clamp(1.02rem, 2.1vw, 1.2rem);
  line-height: 1.6;
  color: var(--texto-suave);
  text-wrap: pretty;
  border-left: 2px solid transparent;
  /* Duas camadas: a borda recebe a rampa, o resto fica transparente. */
  border-image: var(--rampa) 1;
  border-width: 0 0 0 2px;
  border-style: solid;
}
.fecho strong { color: var(--texto); }

strong { color: var(--texto); font-weight: 600; }
code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.88em;
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid var(--vidro-borda);
  padding: 0.12em 0.42em;
  border-radius: 6px;
  white-space: nowrap;
}
.destaque {
  background: var(--rampa);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* -----------------------------------------------------------------------------
   Camada 4: vidro
   -------------------------------------------------------------------------- */
.vidro {
  background: var(--vidro);
  backdrop-filter: blur(var(--vidro-blur)) saturate(160%);
  -webkit-backdrop-filter: blur(var(--vidro-blur)) saturate(160%);
  border: 1px solid var(--vidro-borda);
  border-radius: var(--raio);
  box-shadow: var(--elev), inset 0 1px 0 rgba(255, 255, 255, 0.08);
}

/* -----------------------------------------------------------------------------
   Abertura
   -------------------------------------------------------------------------- */
header { padding: clamp(28px, 5vh, 44px) 0 clamp(64px, 9vh, 108px); }

.marca { display: flex; align-items: center; gap: 12px; margin-bottom: clamp(48px, 9vh, 92px); }
/* 22,5% é o raio do PRÓPRIO desenho, medido no arquivo. Estava 11px, que a 38px
   dá 29% e cortava os cantos da arte; e agora que o PNG já vem recortado com
   fundo transparente, é isto que faz a sombra seguir a silhueta em vez de um
   quadrado em volta dela. */
.marca img { width: 38px; height: 38px; border-radius: 22.5%; box-shadow: var(--elev); }
.marca span { font-weight: 600; color: var(--texto); letter-spacing: -0.01em; }

.abertura { display: grid; gap: clamp(40px, 6vw, 64px); align-items: center; }
@media (min-width: 940px) { .abertura { grid-template-columns: 1.05fr 0.95fr; } }

.abertura h1 { max-width: 16ch; }
.abertura .chamada { margin-bottom: 30px; }

/* Cada linha do título é revelada por máscara: sobe por trás de um recorte que
   se abre, em vez de só aparecer. É o gesto das páginas da Apple. */
.linha { display: block; overflow: hidden; padding-bottom: 0.06em; }
.linha > span { display: block; }

/* -----------------------------------------------------------------------------
   O contador vivo — a peça que demonstra o produto em vez de descrevê-lo
   -------------------------------------------------------------------------- */
.painel { padding: 24px; }
.painel-topo {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 16px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--vidro-borda);
}
.painel-topo strong { font-size: 0.97rem; }
.pulso {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ok);
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--ok) 22%, transparent);
  animation: pulsar 2.4s var(--e-transicao) infinite;
  flex: 0 0 auto;
}
@keyframes pulsar {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.55; transform: scale(0.86); }
}
.painel-topo .nota { margin: 0 0 0 auto; font-size: 0.85rem; }

.relogio {
  font-size: clamp(2.6rem, 8vw, 3.9rem);
  font-weight: 700;
  color: var(--texto);
  letter-spacing: -0.03em;
  /* Sem largura fixa de dígito o número tremula a cada segundo, e isso é o que
     denuncia amadorismo num contador. */
  font-variant-numeric: tabular-nums;
  display: flex;
  /* `flex-start`, e a escolha é o ponto todo desta construção.
     NÃO pode ser `baseline`: a linha de base de uma caixa com `overflow`
     recortado não é a do texto dela, é a BORDA INFERIOR da caixa. Então
     `baseline` alinhava o texto dos dois-pontos contra o FUNDO da janela dos
     dígitos, e jogava os dois-pontos 8px acima da linha dos números.
     Com todas as peças do mesmo tamanho e o mesmo topo, a linha de base sai
     igual por construção — sem depender de nenhuma regra de sintetização. */
  align-items: flex-start;
  line-height: 1;
}

/**
 * Cada dígito é uma JANELA que recorta uma linha, e o valor entra por baixo.
 *
 * `1em` exato, medido e não estimado: na Outfit a tinta do `0` ocupa de 9,2px a
 * 55,2px dentro da linha de 62,4px, então a janela do tamanho da linha não
 * corta nada. O que cortava antes era o rolo, não a altura.
 *
 * `.separador` recebe a MESMA altura de propósito: é o que faz os dois-pontos
 * e os números compartilharem a linha de base.
 */
.digito,
.separador {
  display: block;
  height: 1em;
}
/**
 * `overflow: hidden` recorta nos DOIS eixos, e é isso que estragava o número.
 *
 * O `letter-spacing` negativo encolhe a caixa de cada dígito para 34,95px,
 * enquanto a tinta do algarismo tabular vai até 37px — então o recorte comia
 * 2px da direita de todo numeral, achatando a curva do zero.
 *
 * `overflow-x: visible` com `overflow-y: hidden` não resolve: o CSS promove o
 * outro eixo para `auto`. A saída é alargar a caixa de RECORTE com padding
 * (o recorte acontece na borda do padding) e devolver a largura ao layout com
 * margem negativa do mesmo tamanho — o relógio não muda de tamanho nem de
 * espaçamento, e a janela deixa de tocar a tinta.
 */
.digito {
  overflow: hidden;
  padding-inline: 6px;
  margin-inline: -6px;
}
.digito > span { display: block; }

.digito.rolando > span { animation: rolar var(--t-transicao) var(--e-transicao); }

/* 100% do vão é exatamente a altura da janela, porque as duas medem 1em: o
   dígito nasce inteiro abaixo do recorte, invisível, e sobe. Partindo de uma
   fração ele começaria DENTRO da janela, e é isso que parecia um número
   montado sobre o outro. */
@keyframes rolar {
  from { transform: translateY(100%); }
  to { transform: translateY(0); }
}

.medidas { display: flex; gap: 26px; margin-top: 20px; }
.medida .rotulo { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.09em; color: var(--texto-fraco); }
.medida .valor { font-size: 1.32rem; font-weight: 600; color: var(--texto); font-variant-numeric: tabular-nums; }

.revelacao { margin-top: 22px; font-size: 0.95rem; color: var(--texto-fraco); max-width: 42ch; }

/* -----------------------------------------------------------------------------
   Botão
   -------------------------------------------------------------------------- */
.botao {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 52px; /* alvo de toque confortável, acima dos 44px mínimos */
  padding: 0 30px;
  background: var(--rampa);
  color: #06102a;
  font: inherit;
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  text-decoration: none;
  border: 0;
  border-radius: 14px;
  overflow: hidden;
  box-shadow: var(--elev);
  transition: transform var(--t-micro) var(--e-micro), box-shadow var(--t-micro) var(--e-micro);
}
.botao:hover { transform: translateY(-2px); box-shadow: var(--elev-alta); }
/* Confirma o clique antes de a página reagir. */
.botao:active { transform: translateY(0) scale(0.985); }

/* Varredura de brilho: um gradiente extra e transform, sem sombra animada. */
.botao::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 32%, rgba(255, 255, 255, 0.42) 50%, transparent 68%);
  transform: translateX(-100%);
}
.botao:hover::after { animation: varrer 900ms var(--e-transicao); }
@keyframes varrer { to { transform: translateX(100%); } }

.sob-botao { margin-top: 14px; font-size: 0.9rem; color: var(--texto-fraco); }

/* -----------------------------------------------------------------------------
   Grades e cartões
   -------------------------------------------------------------------------- */
.grade { display: grid; gap: 18px; }
@media (min-width: 720px) {
  .grade-3 { grid-template-columns: repeat(3, 1fr); }
  .grade-2 { grid-template-columns: repeat(2, 1fr); }
}

.cartao { padding: 26px; position: relative; overflow: hidden; }
.cartao h3 { margin-bottom: 6px; }
.cartao p:last-child { margin-bottom: 0; }

/* Spotlight: brilho radial seguindo o ponteiro. As coordenadas chegam por
   custom property, atualizada num único pointermove com rAF. */
.foco::before {
  content: '';
  position: absolute;
  inset: 0;
  opacity: 0;
  background: radial-gradient(
    22rem 22rem at var(--px, 50%) var(--py, 50%),
    rgba(255, 255, 255, 0.09),
    transparent 62%
  );
  transition: opacity var(--t-transicao) var(--e-micro);
  pointer-events: none;
}
.foco:hover::before { opacity: 1; }
.foco {
  transition: transform var(--t-micro) var(--e-micro), border-color var(--t-micro) var(--e-micro),
    box-shadow var(--t-micro) var(--e-micro);
}
.foco:hover { transform: translateY(-3px); border-color: var(--vidro-borda-viva); box-shadow: var(--elev-alta); }

.passo .numero {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 11px;
  background: var(--rampa);
  color: #06102a;
  font-weight: 700;
  margin-bottom: 14px;
  box-shadow: var(--elev);
}

/* -----------------------------------------------------------------------------
   A escada de níveis — progressão demonstrada por progressão
   -------------------------------------------------------------------------- */
/**
 * `isolation` cria um contexto de empilhamento próprio, para os z-index daqui
 * não disputarem com o resto da página.
 *
 * Toda a geometria da escada sai destas três medidas. Elas existem como
 * variáveis porque o breakpoint estreito encolhe o ícone, e antes o halo e o
 * trilho ficavam para trás: o ícone ia para 36px e -48px, o halo continuava com
 * 44px em -56px, e os dois se descolavam. Derivando tudo, o breakpoint troca
 * duas linhas e o resto acompanha.
 */
.escada {
  position: relative;
  padding-left: 56px;
  isolation: isolate;
  --icone-x: -56px;
  --icone-tam: 44px;
  --icone-topo: 14px;
  /* Onde o centro do ícone cai dentro do degrau — é o que ancora o trilho. */
  --centro-icone: calc(var(--icone-topo) + var(--icone-tam) / 2);
  /* Trilho de 2px centralizado no ícone. */
  --fio-x: calc(var(--icone-x) + var(--icone-tam) / 2 - 1px);
}

.degrau { position: relative; padding: 16px 0; }

/**
 * O trilho é um SEGMENTO por degrau, e não uma linha única na escada.
 *
 * Antes era um só, do topo ao rodapé da escada, e passava 34px por baixo do
 * ícone do último nível — a escada parecia continuar para um sexto nível que não
 * existe. Agora cada segmento vai do centro do próprio ícone até o centro do
 * ícone de baixo: os dois ficam a `--centro-icone` do topo dos seus degraus, e
 * os degraus se empilham sem espaço, então `height: 100%` cobre exatamente a
 * distância entre eles — qualquer que seja a altura do degrau. O último nível
 * não tem fio, e a linha termina nele.
 */
.fio {
  position: absolute;
  left: var(--fio-x);
  top: var(--centro-icone);
  width: 2px;
  height: 100%;
  border-radius: 2px;
  overflow: hidden;
  background: var(--vidro-borda);
  z-index: 0;
}
/**
 * O preenchimento colorido, e ele nasce CHEIO.
 *
 * Estado base = aceso, aqui e nos dois de baixo. Quem não implementa
 * `animation-timeline` (Firefox hoje) via uma escada permanentemente apagada e
 * cinza, esperando um gatilho que nunca chega — o oposto do que o comentário do
 * `@supports` promete. Quem tem suporte recebe o estado inicial pelos
 * `@keyframes`, que declaram só o `from`: assim os valores finais têm UMA fonte,
 * que é esta regra.
 */
.fio::before {
  content: '';
  position: absolute;
  inset: 0;
  transform-origin: 50% 0;
  background: linear-gradient(180deg, var(--de), var(--para));
}

/**
 * O halo que cresce a cada degrau.
 *
 * O brilho fica mais largo e mais difuso conforme se sobe: o primeiro nível é
 * uma brasa, o último é uma auréola. É a progressão dita pela LUZ, e não por
 * número — quem rola até o fim sente que chegou a algum lugar antes de ler o
 * nome do nível.
 *
 * `--n` vem do HTML, de 0 a 4.
 */
.degrau::before {
  content: '';
  position: absolute;
  border-radius: 50%;
  /* A cor do PRÓPRIO nível, e não a rampa inteira: com a rampa, os cinco halos
     eram a mesma mistura, e agora que o ícone e o trilho falam a cor daquele
     degrau um brilho genérico discordaria dos dois que ele envolve. */
  background: var(--cor, var(--rampa));
  z-index: 1;
  opacity: calc(0.14 + var(--n, 0) * 0.075);
  filter: blur(calc(7px + var(--n, 0) * 6px));
  transform: scale(calc(1 + var(--n, 0) * 0.26));
}

/* Acima do trilho E acima do halo. */
.degrau img { z-index: 2; }

.degrau::before,
.degrau img {
  position: absolute;
  left: var(--icone-x);
  top: var(--icone-topo);
  width: var(--icone-tam);
  height: var(--icone-tam);
}
.degrau h3 { margin-bottom: 2px; position: relative; z-index: 2; }
.degrau p { margin: 0; position: relative; z-index: 2; }

/* -----------------------------------------------------------------------------
   O mês que zera e o total que não
   -------------------------------------------------------------------------- */
.barras { display: grid; gap: 22px; }
@media (min-width: 640px) { .barras { grid-template-columns: 1fr 1fr; } }
.barra-caixa { padding: 24px; }
.barra-titulo { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 14px; }
.barra-titulo strong { font-size: 1.02rem; }
.trilho { height: 10px; border-radius: 99px; background: rgba(255, 255, 255, 0.07); overflow: hidden; }
/* Repouso CHEIO, pelo mesmo motivo da escada: sem `animation-timeline`, duas
   barras paradas em 8% não contrastam nada — e a que diz "só sobe" ficaria
   afirmando 8% ao lado do próprio rótulo. */
.enche { height: 100%; border-radius: 99px; background: var(--rampa); transform-origin: 0 50%; }

/* O laço do mês NÃO depende de rolagem (`animation-timeline: auto`), então vive
   fora do @supports: é a única parte da seção que o Firefox também ganha. */
.enche.zera { animation: encher-e-zerar 2.6s var(--e-entrada) infinite; }
@keyframes encher-e-zerar {
  0% { transform: scaleX(0.08); }
  55% { transform: scaleX(1); }
  72% { transform: scaleX(1); }
  78% { transform: scaleX(0.08); }
  100% { transform: scaleX(0.08); }
}

/* -----------------------------------------------------------------------------
   Áreas
   -------------------------------------------------------------------------- */
.areas { display: grid; gap: 14px; }
@media (min-width: 680px) {
  .areas { grid-template-columns: 1fr 1fr; }
  /* São cinco áreas: em duas colunas a última sobraria sozinha à esquerda,
     com um buraco do lado. Atravessando as duas, a grade fecha. */
  .areas .area:last-child { grid-column: 1 / -1; }
}
.area { display: flex; gap: 15px; align-items: flex-start; padding: 20px 22px; }
.area img { width: 32px; height: 32px; flex: 0 0 32px; margin-top: 2px; }
.area h3 { font-size: 1.04rem; margin-bottom: 1px; }
.area p { margin: 0; font-size: 0.92rem; color: var(--texto-fraco); }

/* -----------------------------------------------------------------------------
   FAQ
   -------------------------------------------------------------------------- */
.faq { display: grid; gap: 10px; }
details { padding: 0 22px; }
summary {
  cursor: pointer;
  list-style: none;
  color: var(--texto);
  font-weight: 600;
  font-size: 1.06rem;
  letter-spacing: -0.012em;
  padding: 19px 0;
  display: flex;
  align-items: center;
  gap: 14px;
}
summary::-webkit-details-marker { display: none; }
summary::after {
  content: '';
  width: 9px;
  height: 9px;
  margin-left: auto;
  flex: 0 0 auto;
  border-right: 2px solid var(--roxo);
  border-bottom: 2px solid var(--roxo);
  transform: rotate(45deg);
  transition: transform var(--t-transicao) var(--e-transicao);
}
details[open] summary::after { transform: rotate(-135deg); }
.resposta { padding-bottom: 20px; }
.resposta p:last-child { margin-bottom: 0; }

/* Transição de altura até `auto`, possível por `interpolate-size`. Onde não há
   suporte, o details abre instantâneo — comportamento nativo, e correto. */
@supports selector(::details-content) {
  ::details-content {
    block-size: 0;
    overflow: clip;
    transition: block-size var(--t-transicao) var(--e-transicao), content-visibility var(--t-transicao) allow-discrete;
  }
  details[open]::details-content { block-size: auto; }
}

/* -----------------------------------------------------------------------------
   Fechamento e rodapé
   -------------------------------------------------------------------------- */
.fechamento { text-align: center; }
.fechamento .chamada { margin: 0 auto 30px; }

footer { border-top: 1px solid var(--vidro-borda); padding: 34px 0 60px; font-size: 0.9rem; color: var(--texto-fraco); }
footer a { color: var(--texto-suave); text-decoration-color: var(--vidro-borda-viva); }
footer a:hover { color: var(--texto); }

/* =============================================================================
   MOVIMENTO LIGADO AO SCROLL

   Tudo aqui dentro de @supports, e o estado FORA dele é "visível". Esconder
   por padrão e revelar por animação é o que deixa páginas em branco em
   navegador sem suporte — o Firefox ainda não implementou animation-timeline.
   ========================================================================== */
@supports (animation-timeline: view()) {
  .revela {
    animation: revelar var(--t-entrada) var(--e-entrada) both;
    animation-timeline: view();
    animation-range: entry 8% cover 26%;
  }
  @keyframes revelar {
    from { opacity: 0; transform: translateY(26px) scale(0.985); }
    to { opacity: 1; transform: none; }
  }

  /* Cascata: 60ms é o bastante para ler como ordem, não como lentidão. */
  .cascata > * { animation-delay: calc(var(--i, 0) * 60ms); }

  /* Cabeçalho que assenta: entra 4% maior. Quase imperceptível, e é o que dá
     sensação de câmera. */
  .secao-topo {
    animation: assentar var(--t-entrada) var(--e-entrada) both;
    animation-timeline: view();
    animation-range: entry 10% cover 34%;
  }
  @keyframes assentar {
    from { opacity: 0; transform: scale(1.04) translateY(18px); }
    to { opacity: 1; transform: none; }
  }

  .progresso {
    animation: encher-x linear both;
    animation-timeline: scroll(root);
  }
  @keyframes encher-x { to { transform: scaleX(1); } }

  /* Parallax: o fundo desloca menos que o conteúdo. Sem background-attachment,
     que trava em iOS. */
  .fundo::before {
    animation: deriva var(--t-ambiente) linear infinite alternate,
      flutuar linear both;
    animation-timeline: auto, scroll(root);
  }
  @keyframes flutuar { to { transform: translateY(-9%); } }

  /* ---------------------------------------------------------------------------
     A escada: a linha sobe e a luz acende ONDE ela chega

     UMA timeline para as nove animações, e ela é da escada inteira — não uma
     `view()` por degrau. A diferença decide se o gesto é visível.

     `entry` é ancorado na borda de BAIXO da janela: o alcance começa quando o
     topo do sujeito cruza o rodapé da tela e termina quando o rodapé dele cruza.
     Com um degrau de 78px como sujeito, `entry 16%…128%` inteiro acontece nos
     primeiros ~90px de rolagem depois de o degrau espiar no rodapé — quando a
     escada chega ao meio do visor já acabou tudo, e ela aparece pronta e parada.
     Foi exatamente o que se viu.

     `cover` da escada dura a altura dela MAIS uma tela (391 + 860 = 1251px), e
     acompanha a seção atravessando o visor, em qualquer altura de janela. É o
     alcance certo para um gesto que a pessoa precisa ver acontecer.

     A sincronia vira aritmética sobre esse alcance comum, com `--n` de 0 a 4:

       ícone e halo do degrau n   acendem  de `cover 19%+12n`  a `cover 26%+12n`
       segmento abaixo do degrau n é traçado de `cover 26%+12n` a `cover 38%+12n`

     e `38 + 12n` é `26 + 12(n+1)` — o instante em que o ícone de baixo termina
     de acender. A linha não chega antes nem depois: ela encosta no ícone
     exatamente quando ele acaba de acender, e o último fecha em `cover 74%`.
     -------------------------------------------------------------------------- */
  .escada { view-timeline-name: --escada; }

  .degrau img,
  .degrau::before {
    animation: acender auto var(--e-entrada) both;
    animation-timeline: --escada;
    animation-range: cover calc(19% + var(--n) * 12%) cover calc(26% + var(--n) * 12%);
  }
  /* O halo acompanha o ícone com sua própria curva, e nunca chega a competir
     com ele. O `--n` decide a intensidade final na regra base; aqui só se
     declara de ONDE ele vem — e o desfoque vem junto, de uma brasa fechada até a
     auréola larga do último nível. É o desfoque abrindo conforme a linha sobe,
     e não um valor fixo que aparece de uma vez. */
  .degrau::before { animation-name: acender-halo; }
  @keyframes acender-halo {
    from { opacity: 0; filter: blur(3px); transform: scale(0.55); }
  }
  /* A ultrapassagem existe porque conquista pede comemoração. É a única
     exceção à curva de entrada em toda a folha, e ela ASSENTA: o `to` tem de
     bater com o estado base, senão `both` deixa todo ícone 6% maior para
     sempre. */
  @keyframes acender {
    from { opacity: 0.28; filter: grayscale(1); transform: scale(0.94); }
    70% { transform: scale(1.07); }
    to { opacity: 1; filter: grayscale(0); transform: scale(1); }
  }

  .fio::before {
    animation: tracar-fio auto linear both;
    animation-timeline: --escada;
    animation-range: cover calc(26% + var(--n) * 12%) cover calc(38% + var(--n) * 12%);
  }
  @keyframes tracar-fio { from { transform: scaleY(0); } }

  /* Keyframe PRÓPRIO, com `from` explícito. Não dá para reusar `encher-x`: ele é
     `to`-only de propósito, porque a barra de leitura (`.progresso`) parte do
     `scaleX(0)` do repouso dela — dar um `from` ali faria o fio do topo nascer
     em 8% em toda carga da página. */
  .enche { animation: encher-barra auto var(--e-entrada) both; animation-timeline: view(); animation-range: entry 26% cover 54%; }
  @keyframes encher-barra { from { transform: scaleX(0.08); } }
}

/* -----------------------------------------------------------------------------
   Entrada em cascata na carga.

   KEYFRAME, e não `@starting-style` com transição — que foi a primeira
   tentativa e deixou o herói INTEIRO com opacidade 0. `@starting-style` só
   fornece o valor de partida; se a transição não dispara, o elemento fica
   parado no estado inicial, e o estado inicial é invisível. Numa abertura, isso
   é a página não existir.

   `animation` com `both` não tem esse risco: ela roda no carregamento sem
   depender de gatilho nenhum, e o `both` sustenta o ÚLTIMO quadro — que é o
   estado visível. Com movimento reduzido, a duração vai a 0.001ms e o elemento
   simplesmente aparece.

   Regra que vale para o resto da folha: o estado de repouso de qualquer
   elemento é sempre "visível". Nada fica escondido esperando permissão.
   -------------------------------------------------------------------------- */
.entra {
  animation: entrar var(--t-entrada) var(--e-entrada) both;
  animation-delay: calc(var(--i, 0) * 70ms + 120ms);
}
@keyframes entrar {
  from { opacity: 0; transform: translateY(18px); }
  to { opacity: 1; transform: none; }
}

/* Título por máscara: só depois de a fonte assentar, senão o gesto acontece
   com a fonte de sistema e reflui no meio. O JS marca <html class="pronto">. */
.pronto .linha > span { animation: subir 700ms var(--e-entrada) both; animation-delay: calc(var(--i, 0) * 70ms); }
@keyframes subir { from { transform: translateY(105%); } to { transform: translateY(0); } }

/* =============================================================================
   Telas pequenas: menos manchas e menos blur. backdrop-filter é o que dói em
   celular intermediário.
   ========================================================================== */
@media (max-width: 640px) {
  :root { --vidro-blur: 16px; }
  .fundo::before { background:
      radial-gradient(30rem 26rem at var(--malha-x1) var(--malha-y1), oklch(65% 0.13 195 / 0.3), transparent 68%),
      radial-gradient(30rem 26rem at var(--malha-x3) var(--malha-y3), oklch(60% 0.19 340 / 0.26), transparent 70%); }
  .medidas { gap: 18px; }
  /* Duas medidas, e o halo, o trilho e o centro do ícone acompanham por cálculo. */
  .escada { padding-left: 48px; --icone-x: -48px; --icone-tam: 36px; }
}

/* =============================================================================
   Movimento reduzido: desliga TUDO menos o contador — ele é a mensagem, não o
   enfeite. Sobra uma página estática, completa e legível.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    /* O atraso PRECISA ir junto. Sem ele, a duração some mas o atraso fica, e o
       preenchimento para trás segura o quadro inicial durante toda a espera —
       a entrada em cascata vira um piscar tardio em vez de não acontecer. */
    animation-delay: 0s !important;
    transition-duration: 0.001ms !important;
  }

  /**
   * `animation: none`, e nunca "declarar o valor final aqui".
   *
   * São duas razões, e as duas custaram um defeito real nesta folha:
   *
   * 1. Zerar `animation-duration` NÃO para animação de rolagem. Numa timeline de
   *    progresso a duração vem do alcance, então tudo que é dirigido por scroll
   *    continuava correndo com movimento reduzido ligado — exatamente o que a
   *    preferência pede para não acontecer.
   * 2. Declaração de autor PERDE para o preenchimento de uma animação: origem de
   *    animação ganha de autor-normal na cascata. Então `transform: scaleX(1)`
   *    escrito aqui era simplesmente ignorado enquanto a animação existisse.
   *
   * Desligada a animação, vale o estado de repouso — que nesta folha é o estado
   * visível. Uma fonte da verdade, e não duas.
   */
  .fundo::before,
  .revela,
  .cascata > *,
  .secao-topo,
  .progresso,
  .fio::before,
  .degrau img,
  .degrau::before,
  .enche,
  .enche.zera,
  .botao:hover::after { animation: none !important; }

  /* O mês zerando é a única coisa que precisa de um valor próprio: parado, a
     barra do mês tem de ficar diferente da do total, senão a seção inteira passa
     a dizer que as duas contagens são iguais. */
  .enche.zera { transform: scaleX(0.55); }
}
