/* ============================================================
   PRANCHA
   Sistema visual do Professor Rogério.

   O conceito não é "tema escuro com azul". É uma prancha de desenho
   técnico: margem cotada, pranchas numeradas, linha de cota, selo no
   rodapé. Sai da frase que o próprio professor assina, que redação é
   engenharia e não inspiração.

   Três regras que não se quebram:

   1. O azul é linha de construção. Nunca preenche bloco inteiro, nunca
      é fundo. No dia em que virar fundo, deixa de significar.
   2. Três famílias, três funções. Bricolage no display, Source Serif no
      corpo porque o assunto é texto escrito, Plex Mono na camada
      técnica. Nenhuma invade a função da outra.
   3. Existe UM bloco claro no site inteiro, e é onde o pedido acontece.
   ============================================================ */

:root {
  color-scheme: dark;

  /* Chapa. O breu é o mesmo ponto de sombra para onde as fotos foram
     graduadas, então o retrato dissolve sem emenda. */
  --breu:   #060f1a;
  --chapa:  #0c1826;
  --chapa2: #12233a;

  /* Giz */
  --giz:  #eaf2fb;
  --giz2: #93aec9;
  --giz3: #55708c;

  /* Risco. O único acento. */
  --risco:   #67b6f7;
  --risco-q: #a5d6ff;
  --risco-f: #2c5f8a;

  /* Semântico. Só correção, só falta. */
  --erro: #ff6b5c;

  --fio:  rgba(103, 182, 247, .22);
  --fio2: rgba(103, 182, 247, .09);

  --display: 'Bricolage Grotesque', 'Segoe UI', system-ui, sans-serif;
  --corpo:   'Source Serif 4', Georgia, 'Times New Roman', serif;
  --tec:     'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

  --larg:    1180px;
  --meia:    590px;
  --leitura: 640px;
  --rail:    72px;   /* a margem cotada da prancha */
  --pauta:   34px;   /* o ritmo da folha de redação */

  --ease: cubic-bezier(.22, .68, .28, 1);
}

/* O container só cresce a partir de 1200px.

   Em 1180px fixo, num monitor de 2000, sobravam 820px de margem morta,
   41% da tela: era a causa raiz da sensação de vazio, e não falta de
   elemento. Mas a conta em vw não pode valer no celular, onde 88vw de
   375 dá 330 e o conteúdo ENCOLHE 45px em vez de crescer. Por isso a
   regra é escalonada e não uma expressão só.

   --meia é metade de --larg, e existe para a grade de construção e as
   cruzetas se posicionarem sem repetir a conta. */
@media (min-width: 1200px) {
  :root { --larg: min(1560px, 88vw); --meia: min(780px, 44vw); }
}

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 90px;
}

body {
  margin: 0;
  background: var(--breu);
  color: var(--giz);
  font-family: var(--corpo);
  font-size: 19px;
  line-height: 1.68;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Grão. Quebra a chapa lisa e dá matéria ao fundo. Fica por cima de tudo
   e não intercepta clique. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}

img, svg { max-width: 100%; height: auto; display: block; }

::selection { background: var(--risco); color: var(--breu); }

/* ------------------------------------------------------------ */
/* Tipografia                                                     */
/* ------------------------------------------------------------ */

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -.03em;
  margin: 0 0 .5em;
  text-wrap: balance;
}

/* Teto em 4.5rem: acima disso a linha "do ENEM não é" quebra dentro da
   coluna do herói, e quebra de linha forçada só funciona se ela couber. */
h1 { font-size: clamp(2.4rem, 6vw, 4.5rem); }
/* Escala com contraste maior. Escala tímida é a causa mais comum de uma
   página parecer simples: não é falta de elemento, é falta de diferença
   entre o maior e o menor corpo da página. */
h2 { font-size: clamp(2.1rem, 5.4vw, 3.7rem); }
h3 { font-size: clamp(1.16rem, 2.4vw, 1.4rem); font-weight: 700; letter-spacing: -.02em; }
h4 { font-size: 1.02rem; font-weight: 700; letter-spacing: -.012em; }

p { margin: 0 0 1.15em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

a { color: var(--risco); text-underline-offset: 3px; }
a:hover { color: var(--risco-q); }

.dim  { color: var(--giz2); }
.mini { font-size: .93rem; }
.leitura { max-width: var(--leitura); }

/* A camada técnica. Tudo que é dado, medida ou rótulo vive aqui. */
.tec {
  font-family: var(--tec);
  font-weight: 500;
  font-size: .7rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--giz3);
  font-variant-numeric: tabular-nums;
}
.tec-risco { color: var(--risco); }

.num {
  font-family: var(--display);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.05em;
  line-height: .9;
}

/* Grifo: linha de construção sob a palavra. Desenha sozinha no load. */
.grifo { position: relative; white-space: nowrap; }
.grifo::after {
  content: '';
  position: absolute;
  left: 0; bottom: .06em;
  width: 100%; height: 5px;
  background: var(--risco);
  transform: scaleX(0);
  transform-origin: left;
  animation: risca 1s var(--ease) 1.1s forwards;
}
@keyframes risca { to { transform: scaleX(1); } }

/* Falta informação. Marcado como professor marca texto. */
/* .falta MARCA PENDENCIA PARA QUEM CONSTROI, E NAO DESENHA NADA.
   
   Ela desenhava sublinhado pontilhado vermelho, e dez dos onze usos
   estao nos BOTOES DE CHECKOUT das paginas de venda: a principal
   chamada de cada pagina saia com uma marca de defeito embaixo. O
   elemento que precisa parecer o mais seguro da pagina era o unico
   marcado como quebrado.
   
   O inventario de pendencias virou comando, `npm run pendencias`, que
   le do codigo. Marca visivel nao pode depender de alguem lembrar de
   tirar antes do deploy: ja escapou duas notas de producao para o ar
   por esse caminho. */
.falta { }

/* ------------------------------------------------------------ */
/* A prancha                                                      */
/* ------------------------------------------------------------ */

.env {
  width: 100%;
  max-width: var(--larg);
  margin: 0 auto;
  padding: 0 24px;
}
@media (min-width: 1000px) { .env { padding: 0 24px 0 calc(var(--rail) + 24px); } }

/* Margem cotada: fica na lateral esquerda, fixa, com as marcas de prancha.
   Some no mobile, onde não há largura para ela. */
.margem {
  position: fixed;
  left: 0; top: 0; bottom: 0;
  width: var(--rail);
  z-index: 40;
  display: none;
  border-right: 1px solid var(--fio2);
  pointer-events: none;
}
@media (min-width: 1000px) { .margem { display: block; } }

.margem-marcas {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 18px;
  align-items: center;
  pointer-events: auto;
}
.margem-marca {
  font-family: var(--tec);
  font-size: .64rem;
  font-weight: 600;
  letter-spacing: .1em;
  color: var(--giz3);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 7px;
  opacity: .45;
  transition: opacity .3s var(--ease), color .3s var(--ease);
}
.margem-marca::before {
  content: '';
  width: 9px; height: 1px;
  background: currentColor;
  transition: width .3s var(--ease);
}
.margem-marca:hover { opacity: 1; }
.margem-marca[aria-current="true"] { opacity: 1; color: var(--risco); }
.margem-marca[aria-current="true"]::before { width: 20px; }

/* Pauta: a linha da folha de redação virando linha de construção. */
.pauta {
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent calc(var(--pauta) - 1px),
    var(--fio2) calc(var(--pauta) - 1px),
    var(--fio2) var(--pauta)
  );
}

/* ------------------------------------------------------------ */
/* Pranchas (seções)                                              */
/* ------------------------------------------------------------ */

/* ============================================================ */
/* A CORTINA                                                    */
/*                                                              */
/* Cada prancha gruda no topo e a seguinte sobe POR CIMA dela.  */
/* A que fica embaixo encolhe e escurece: lê como "foi para     */
/* baixo da pilha", não como "sumiu".                           */
/*                                                              */
/* ARMADILHA: sticky quebra EM SILÊNCIO se qualquer ancestral   */
/* tiver overflow:hidden, transform, filter ou will-change.     */
/* Não dá erro, só não gruda. Por isso o .heroi usa clip e não  */
/* hidden, e por isso nenhum pai de .prancha pode ganhar        */
/* transform. Se alguém "limpar" isso, a página degrada para    */
/* empilhamento normal sem avisar.                              */
/* ============================================================ */

.prancha {
  padding: 84px 0;
  position: relative;
  background: var(--breu);   /* opaca, senão a de baixo vaza pela cortina */
}
/* 120px sobrava. Com esse respiro cada prancha virava uma ilha e a
   página lia como seis documentos empilhados em vez de uma coisa só.
   Foi essa a reclamação de "as coisas estão longe e desconexas". */
@media (min-width: 900px) { .prancha { padding: 78px 0; } }

/* NÃO reintroduzir empilhamento sticky aqui.
   Uma versão anterior grudava cada prancha no topo e fazia a seguinte
   escalar por cima, com a de baixo encolhendo e perdendo opacidade.
   Falhou por dois motivos, e os dois são estruturais:

   1. Seção com parágrafo longo é mais alta que a tela, então nunca gruda
      direito. A técnica serve para cartão curto, não para conteúdo.
   2. O encolhimento acontecia ENQUANTO a pessoa lia. Texto que escala e
      apaga no meio da leitura não é efeito, é obstáculo.

   A invasão agora é feita por UM ELEMENTO atravessando a fronteira, não
   pela seção inteira escalando por cima da outra. */

.empilha { overflow-x: clip; }

/* O número da próxima prancha nasce dentro da anterior, gigante e só de
   contorno, e a seção chega por baixo dele. Um elemento cruzando a borda
   costura as duas sem tocar na legibilidade de nenhuma. */
.prancha { --marca: ''; }

@media (min-width: 900px) {
  .prancha + .prancha,
  .prancha + .rodape { margin-top: -1px; }

  .prancha[data-marca-n]::before {
    content: attr(data-marca-n);
    position: absolute;
    right: 3vw;
    top: -3.2em;
    font-family: var(--display);
    font-weight: 800;
    font-size: clamp(7rem, 15vw, 15rem);
    line-height: .78;
    letter-spacing: -.06em;
    color: transparent;
    -webkit-text-stroke: 1px rgba(103, 182, 247, .12);
    font-variant-numeric: tabular-nums;
    pointer-events: none;
    z-index: 0;
    user-select: none;
  }
  .prancha-clara[data-marca-n]::before { -webkit-text-stroke-color: rgba(6, 15, 26, .10); }

  /* SEM diagonal. Uma versão anterior cortava a borda de cima de cinco
     pranchas em diagonal alternada. Repetido cinco vezes, o corte deixa de
     ser gesto e vira maneirismo, que é o que faz um site parecer template.
     A costura entre pranchas agora é o número atravessando e a coluna
     vertical que percorre a página inteira. */
  .prancha[data-corte],
  .prancha[data-corte-inv] { clip-path: none; margin-top: 0; }
}

/* ============================================================ */
/* A COLUNA                                                     */
/* Uma linha de construção única percorre a página do topo ao    */
/* rodapé, e as pranchas são estações nela. É o que dá unidade   */
/* sem repetir gesto: um elemento contínuo em vez de cinco       */
/* cortes iguais.                                                */
/* ============================================================ */

.empilha { position: relative; }

@media (min-width: 1000px) {
  .empilha::before {
    content: '';
    position: absolute;
    left: calc(var(--rail) / 2);
    top: 0; bottom: 0;
    width: 1px;
    background: linear-gradient(to bottom,
      transparent 0, var(--fio2) 4%, var(--fio2) 96%, transparent 100%);
    pointer-events: none;
    z-index: 1;
  }

  /* A estação: um nó na coluna, na altura em que cada prancha começa. */
  .prancha[data-marca-n]::after,
  .heroi::after {
    content: '';
    position: absolute;
    left: calc(var(--rail) / 2);
    top: 0;
    width: 7px; height: 7px;
    margin: -3px 0 0 -3px;
    border: 1px solid var(--risco);
    background: var(--breu);
    transform: rotate(45deg);
    z-index: 2;
    pointer-events: none;
  }
  .prancha-clara[data-marca-n]::after { background: var(--giz); }
}

/* ============================================================ */
/* TEXTURA                                                      */
/* Varredura horizontal fina por cima de tudo. Vem de monitor    */
/* de traço e de folha reprografada, e é o que tira a chapa      */
/* lisa sem introduzir cor nova.                                 */
/* ============================================================ */

body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 89;
  pointer-events: none;
  opacity: .5;
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0 2px,
    rgba(103, 182, 247, .022) 2px 3px);
}
@media (prefers-reduced-motion: reduce) { body::before { display: none; } }

/* O conteúdo fica acima do número que atravessa. */
.prancha > .env { position: relative; z-index: 1; }

/* ============================================================ */
/* SINAIS DE PRANCHA                                            */
/* Cantoneira, tique de cota e cruz de registro. São as marcas   */
/* que existem numa folha técnica de verdade e que faltavam:     */
/* o site tinha o conceito e não tinha o vocabulário.            */
/* Tudo em CSS, zero requisição.                                 */
/* ============================================================ */

/* Cantoneira: o L que marca o canto útil da folha. */
.cantos { position: absolute; inset: 26px; pointer-events: none; z-index: 0; }
.cantos i {
  position: absolute;
  width: 18px; height: 18px;
  border: 1px solid var(--fio);
  opacity: .6;
}
.cantos i:nth-child(1) { top: 0; left: 0; border-right: 0; border-bottom: 0; }
.cantos i:nth-child(2) { top: 0; right: 0; border-left: 0; border-bottom: 0; }
.cantos i:nth-child(3) { bottom: 0; left: 0; border-right: 0; border-top: 0; }
.cantos i:nth-child(4) { bottom: 0; right: 0; border-left: 0; border-top: 0; }
.prancha-clara .cantos i { border-color: rgba(6, 15, 26, .22); }

/* Régua de tiques na lateral, como a graduação de uma folha cotada. */
.tiques {
  position: absolute;
  left: 0; top: 12%; bottom: 12%;
  width: 10px;
  pointer-events: none;
  background-image: repeating-linear-gradient(
    to bottom, var(--fio) 0 1px, transparent 1px 22px);
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
  opacity: .7;
}
@media (max-width: 899px) { .tiques, .cantos { display: none; } }

/* Cruz de registro. Marca de alinhamento de impressão. */
.cruz {
  position: absolute;
  width: 16px; height: 16px;
  pointer-events: none;
  opacity: .5;
}
.cruz::before, .cruz::after {
  content: '';
  position: absolute;
  background: var(--risco);
}
.cruz::before { left: 50%; top: 0; bottom: 0; width: 1px; transform: translateX(-.5px); }
.cruz::after  { top: 50%; left: 0; right: 0; height: 1px; transform: translateY(-.5px); }

/* ============================================================ */
/* CHÃO EM PERSPECTIVA                                          */
/* A grade se inclina e foge para o horizonte. É o 3D que cabe   */
/* aqui: um gradiente repetido dentro de um rotateX, composto na */
/* GPU, sem WebGL, sem malha, sem uma requisição.                */
/* ============================================================ */

.chao {
  position: absolute;
  left: -30%; right: -30%; bottom: 0;
  height: 46%;
  pointer-events: none;
  z-index: 0;
  perspective: 300px;
  perspective-origin: 50% 0%;
  overflow: hidden;
}
.chao i {
  position: absolute;
  inset: -60% 0 -10%;
  transform: rotateX(72deg);
  transform-origin: 50% 0%;
  background-image:
    repeating-linear-gradient(to right, rgba(103,182,247,.14) 0 1px, transparent 1px 70px),
    repeating-linear-gradient(to bottom, rgba(103,182,247,.10) 0 1px, transparent 1px 70px);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 55%, transparent 92%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 55%, transparent 92%);
}
@media (max-width: 899px) { .chao { display: none; } }

.prancha-chapa { background: var(--chapa); }

/* O único bloco claro do site. É onde o pedido acontece.

   A virada de escuro para claro acontece DURANTE a rolagem, não numa linha
   reta: uma faixa de 42svh acima da seção gradua de um para o outro, e o
   fundo claro entra por baixo. Antes o corte era seco e a seção parecia
   outro site colado no meio. */
.prancha-clara {
  background: var(--giz);
  color: var(--breu);
  position: relative;
}
/* A transição fica DENTRO da própria seção clara, não acima dela.
   A versão anterior usava top:-42svh com z-index:-1 para invadir a prancha
   anterior. Não funcionou: .prancha só tem position:relative, sem z-index,
   então não cria contexto de empilhamento, e o z-index negativo não ia para
   trás da seção de cima. O resultado era um clarão vazando pelas laterais
   da prancha 04. */
/* Corte LIMPO, não esfumado. Prancha técnica não tem degradê: tem linha.
   O borrão de 40svh que existia aqui brigava com o conceito inteiro e
   ainda lavava a base da prancha anterior.

   O que costura as duas agora é o que atravessa o corte: a coluna, o
   número da prancha e uma régua de tiques que muda de cor no meio. */
.prancha-clara {
  background: var(--giz);
  padding-top: 96px;
  border-top: 1px solid var(--risco);
}
@media (min-width: 900px) { .prancha-clara { padding-top: 128px; } }

/* A régua atravessa o corte: metade de cima em azul sobre o escuro,
   metade de baixo em escuro sobre o claro. Um objeto só, dois fundos. */
.emenda {
  position: absolute;
  left: 0; right: 0;
  top: -34px;
  height: 68px;
  pointer-events: none;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
  padding-right: 4vw;
}
.emenda span {
  font-family: var(--tec);
  font-size: .62rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--risco);
  background: var(--breu);
  padding: 5px 12px;
}
.emenda i {
  width: 108px;
  height: 34px;
  background-image: repeating-linear-gradient(
    to right, var(--risco) 0 1px, transparent 1px 9px);
  -webkit-mask-image: linear-gradient(to right, transparent, #000 40%);
  mask-image: linear-gradient(to right, transparent, #000 40%);
  opacity: .8;
}
@media (max-width: 899px) { .emenda { display: none; } }
.prancha-clara .tec { color: var(--risco-f); }
.prancha-clara .dim { color: #40607f; }

/* Cabeçalho de prancha: número, título e o fio que desenha na entrada. */
.prancha-topo {
  display: flex;
  align-items: baseline;
  gap: 16px;
  margin-bottom: 34px;
  position: relative;
  padding-top: 18px;
}
.prancha-topo::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 1px;
  background: var(--fio);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 1.1s var(--ease);
}
.revelado .prancha-topo::before { transform: scaleX(1); }

/* Prancha centralizada. Existe para a dobra que vem logo abaixo de outra
   dobra centralizada: com o eixo pulando de lado a cada seção, a segunda
   lê como um recomeço em vez de continuação. */
.prancha-centro { text-align: center; }
.prancha-centro .prancha-topo { justify-content: center; }
.prancha-centro .quem-texto { max-width: 34em; margin-inline: auto; }
.prancha-centro .frase { margin-inline: auto; }
/* Os cartões de comparação continuam alinhados à esquerda por dentro.
   Rótulo e frase centralizados dentro de caixa pequena lê como legenda
   de foto, não como par de comparação. */
.prancha-centro .par { margin-inline: auto; text-align: left; }

/* Junta entre duas dobras.

   Uma linha vertical curta atravessando a borda da seção, com um nó no
   meio dela. Duas seções centralizadas coladas leem como uma seção só,
   partida no meio por acidente. A junta diz o contrário: a de baixo
   continua a de cima, e a emenda é de propósito.

   Chama junta e não costura porque `.costura` já existe mais adiante
   neste arquivo, com outro papel. Nome repetido em CSS não dá erro, só
   faz a regra de baixo vencer em silêncio. */
.junta {
  position: absolute;
  top: -47px;
  left: 50%;
  width: 1px;
  height: 94px;
  transform: translateX(-50%);
  background: linear-gradient(to bottom,
    transparent, var(--risco-f) 26%, var(--risco) 50%, var(--risco-f) 74%, transparent);
  z-index: 4;
  pointer-events: none;
}
/* A partir de 1000px o .env ganha 96px de recuo à esquerda contra 24px à
   direita, por causa da margem cotada. O conteúdo centralizado dentro
   dele fica 36px à direita do meio da página, então a junta precisa do
   mesmo desvio, senão ela aponta para um eixo que o texto não usa.
   36px é metade do rail, e está escrito assim para acompanhar a variável. */
@media (min-width: 1000px) { .junta { left: calc(50% + var(--rail) / 2); } }
/* Losango cheio no acento. Cheio e não vazado de propósito: vazado
   precisaria casar o fundo com os dois lados da emenda, que são cores
   diferentes, e um dos dois ficaria errado. */
.junta::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 9px;
  height: 9px;
  transform: translate(-50%, -50%) rotate(45deg);
  background: var(--risco);
}

.prancha-clara .prancha-topo::before { background: rgba(6, 15, 26, .18); }

.fio { height: 1px; background: var(--fio); border: 0; margin: 0; }

/* ------------------------------------------------------------ */
/* Revelação no scroll                                            */
/* ------------------------------------------------------------ */

/* O esconder só vale se o JS assumiu o controle.

   Antes era `.sobe { opacity: 0 }` puro, e isso é frágil de um jeito que
   já custou caro: se o observador não dispara, por erro de script, por
   seletor que não pega a seção, ou por uma faixa nova que não é .prancha,
   o conteúdo fica invisível PARA SEMPRE e a pessoa vê uma área em branco.
   Foi exatamente o que aconteceu com a faixa clara da recusa: 16 blocos
   da página estavam em opacity 0 sem nunca voltar.

   Agora o padrão é visível. O JS marca html.js-anima quando está pronto
   para animar, e só aí o esconder passa a valer. Falhou o JS, a página
   continua legível: o pior caso vira perder a animação, não perder o
   texto. */
/* .sobe NAO esconde mais nada. Só carrega a transição.

   A versão anterior era `opacity: 0` até um observador adicionar
   .revelado numa seção ancestral, e isso quebrou a página de um jeito
   caro: 16 blocos ficaram invisíveis, incluindo a faixa clara inteira da
   recusa, que aparecia como uma área em branco com só o rótulo.

   Foram duas falhas somadas. A primeira: as três faixas de sangria não
   são .prancha, e o observador só olhava .prancha, então elas nunca
   ganhavam .revelado. A segunda: .faixa-fala tem .sobe NELA MESMA, e
   `.revelado .sobe` é seletor de descendente, que nunca casa com o
   próprio elemento.

   Conteúdo que só aparece se um observador acertar é frágil demais para
   uma página institucional. O padrão agora é visível. A entrada animada
   do herói continua funcionando: ela é a .entra, que é animation e não
   depende de classe nenhuma chegar depois. */
.sobe {
  transition: opacity .8s var(--ease), transform .8s var(--ease);
}
.revelado .sobe { opacity: 1; transform: none; }
.revelado .sobe:nth-child(2) { transition-delay: .08s; }
.revelado .sobe:nth-child(3) { transition-delay: .16s; }
.revelado .sobe:nth-child(4) { transition-delay: .24s; }

/* ------------------------------------------------------------ */
/* Topo                                                          */
/* ------------------------------------------------------------ */

.topo {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(6, 15, 26, .78);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--fio2);
}
.topo-in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  min-height: 70px;
}
.assinatura {
  font-family: var(--display);
  font-weight: 800;
  font-size: 1.02rem;
  letter-spacing: -.035em;
  color: var(--giz);
  text-decoration: none;
}
.assinatura span { color: var(--risco); }

.menu { display: none; gap: 28px; }
@media (min-width: 940px) { .menu { display: flex; } }
.menu a {
  font-family: var(--tec);
  font-size: .68rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--giz2);
  text-decoration: none;
  position: relative;
  padding-bottom: 3px;
}
.menu a::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0; right: 0;
  height: 1px;
  background: var(--risco);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .3s var(--ease);
}
.menu a:hover { color: var(--giz); }
.menu a:hover::after { transform: scaleX(1); transform-origin: left; }

/* ------------------------------------------------------------ */
/* Botão                                                         */
/* ------------------------------------------------------------ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .7em;
  padding: 15px 26px;
  background: var(--risco);
  color: var(--breu);
  border: 1px solid var(--risco);
  border-radius: 2px;
  font-family: var(--tec);
  font-size: .74rem;
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: background .2s var(--ease), color .2s var(--ease);
}
/* A varredura: uma linha de construção passando por baixo do rótulo. */
.btn::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--breu);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .32s var(--ease);
}
.btn > * { position: relative; z-index: 1; }
.btn:hover::before { transform: scaleX(1); transform-origin: left; }
.btn:hover { color: var(--risco); }
.btn:focus-visible { outline: 2px solid var(--giz); outline-offset: 3px; }

.btn-linha { background: transparent; color: var(--giz); border-color: var(--fio); }
.btn-linha::before { background: var(--giz); }
.btn-linha:hover { color: var(--breu); border-color: var(--giz); }

.prancha-clara .btn { background: var(--breu); border-color: var(--breu); color: var(--giz); }
.prancha-clara .btn::before { background: var(--risco); }
.prancha-clara .btn:hover { color: var(--breu); }

/* ------------------------------------------------------------ */
/* Herói                                                         */
/* ------------------------------------------------------------ */

/* clip, NUNCA hidden: hidden vira containing block e mata o sticky das
   pranchas seguintes sem dar erro nenhum. */
.heroi { position: relative; border-bottom: 1px solid var(--fio2); overflow-x: clip; }

/* ------------------------------------------------------------ */
/* Fundo do herói: três camadas atrás de tudo                    */
/*                                                               */
/* O campo escuro chapado era o motivo de a dobra parecer sem    */
/* graça. Aqui entram profundidade e matéria, sem uma linha de   */
/* JavaScript e sem custo de carregamento: um numeral fantasma,  */
/* a pauta, e um clarão que assenta a figura.                    */
/* ------------------------------------------------------------ */

.heroi-fundo {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}

/* O ano em corpo gigante, quase invisível. É o assunto da dobra virando
   textura, e é o que dá escala ao vazio. */
.heroi-fundo b {
  position: absolute;
  right: -.06em;
  bottom: -.28em;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(14rem, 34vw, 34rem);
  line-height: .8;
  letter-spacing: -.06em;
  color: transparent;
  /* Era 1px em 7% de opacidade: educado demais, e o efeito mais barato
     de impacto da página estava sendo desperdiçado. Em 2px e 17% o
     numeral vira estrutura visível, e o recorte do Rogério passa na
     frente dele. Metade do número aparece de cada lado da figura, que é
     o que faz a foto e o tipo se cruzarem em vez de conviverem. */
  -webkit-text-stroke: 2px rgba(103, 182, 247, .17);
  font-variant-numeric: tabular-nums;
  user-select: none;
}
/* No celular o numeral fica atrás de texto corrido, e aí 17% já é
   ruído em cima da leitura. */
@media (max-width: 919px) { .heroi-fundo b { -webkit-text-stroke-width: 1.5px; opacity: .55; } }

/* A pauta, agora no fundo do herói, com desbotamento nas pontas para não
   virar papel quadriculado. */
.heroi-fundo i {
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    to bottom, transparent 0, transparent 33px,
    rgba(103,182,247,.028) 33px, rgba(103,182,247,.028) 34px);
  -webkit-mask-image: radial-gradient(ellipse 70% 62% at 58% 52%, #000 8%, transparent 72%);
  mask-image: radial-gradient(ellipse 70% 62% at 58% 52%, #000 8%, transparent 72%);
}

/* Clarão atrás do ombro. Assenta a figura sem inventar chão. */
.heroi-fundo u {
  position: absolute;
  right: 4%; top: 30%;
  width: 46vw; aspect-ratio: 1;
  transform: translateY(-30%);
  background: radial-gradient(circle, rgba(103,182,247,.10) 0%, transparent 64%);
}

/* A régua horizontal que cruza POR TRÁS do retrato, na altura do olhar.
   É o que prende a figura ao layout: sem ela o retrato flutua. */
.heroi-regua {
  position: absolute;
  left: 0; right: 0;
  top: 42%;
  height: 1px;
  background: linear-gradient(to right, transparent, var(--fio) 12%, var(--fio) 74%, transparent);
  z-index: 1;
  transform: scaleX(0);
  transform-origin: left;
  animation: estica 1.4s var(--ease) .9s forwards;
}
@keyframes estica { to { transform: scaleX(1); } }

/* position: static, e não relative.

   Com relative, a grade virava o bloco de referência do retrato absoluto,
   e o `right: 0` dele passava a valer contra a largura da grade, que está
   dentro do container de 1420px. A foto parava a 126px da borda da janela
   num monitor de 1400 e a sangria não acontecia. Static devolve a
   referência para a .heroi, que ocupa a tela inteira. */
.heroi-grade { display: grid; gap: 44px; padding: 34px 0 0; align-items: end; position: static; }

/* Acima de 920px o retrato SAI da grade e encosta na borda direita da
   janela, muito maior, com o título passando por cima.

   O motivo é composição, não capricho: retrato dentro de coluna vira
   retângulo colado, por maior que fique. Quebrando a grade ele deixa de
   ser um elemento na página e passa a ser o fundo dela. Foi o caminho
   escolhido depois de o recorte de fundo falhar: o terno azul-marinho e o
   fundo azul-marinho ocupam a mesma faixa de cor, e nenhum método por cor
   separa os dois. */
/* ------------------------------------------------------------ */
/* A dobra no celular                                            */
/*                                                               */
/* Abaixo de 920px o retrato era um bloco no fluxo, embaixo do   */
/* texto, então na primeira tela aparecia só o alto da cabeça    */
/* cortado pela borda. A pessoa via um site sem professor.       */
/*                                                               */
/* Agora ele é absoluto no pé da dobra, sangrando pela direita,  */
/* com o texto por cima. A mistura entre os dois é feita NA      */
/* PRÓPRIA IMAGEM, com duas máscaras cruzadas, e não com um véu  */
/* escuro por cima: véu retangular apaga a pauta e o chão dentro */
/* do próprio retângulo e denuncia as bordas dele. Isso já foi   */
/* tentado antes e é o motivo de estar escrito aqui.             */
/* ------------------------------------------------------------ */
@media (max-width: 919px) {
  .heroi { min-height: 100svh; display: flex; align-items: flex-start; }

  /* position: static, e é isto que estava quebrando a composição.
     A .heroi-grade declara position: relative para o desktop, então ela
     virava o bloco de referência do retrato absoluto. Como a altura dela
     é a altura do texto, o `bottom: 0` do retrato colava no fim do TEXTO
     e não no pé da dobra: a foto subia junto com a coluna e o rosto
     parava atrás dos parágrafos. Static devolve a referência para a
     .heroi, que é quem tem a altura da tela. */
  .heroi-grade { position: static; width: 100%; padding: 92px 0 0; gap: 0; }

  .heroi-texto {
    position: relative;
    z-index: 2;
    padding-bottom: 30px;
    text-shadow: 0 2px 26px rgba(6, 15, 26, .92), 0 1px 5px rgba(6, 15, 26, .8);
  }

  /* Mesmo defeito que ja foi corrigido acima de 920px, e que eu deixei
     passar aqui embaixo: a sombra acima e herdada por TUDO dentro do
     heroi, e ela e um borrao escuro. Em texto claro sobre fundo escuro
     ela assenta a letra. Em texto ESCURO dentro de caixa CLARA ela pinta
     um halo em volta das letras que vaza para fora da caixa, porque
     text-shadow nao e recortada pelo fundo do elemento.

     Era isso o brilho bugado na palavra em destaque da promessa, no
     celular, em todas as paginas. */
  .heroi-texto .grifo-caixa,
  .heroi-texto .marca-forte,
  .heroi-texto .preco-economia,
  .heroi-texto .btn-bloco,
  .heroi-texto .marca-erro-forte { text-shadow: none; }

  /* A conta que decide o tamanho.

     O retrato é 1000 por 1249, e nesse enquadramento o rosto ocupa mais
     ou menos os 30% de cima. Com a base grudada no pé da dobra, o topo da
     cabeça cai em (pé - 0,95 da altura) e a linha dos olhos em
     (pé - 0,85 da altura).

     A primeira versão tinha 470px de altura numa tela de 812: os olhos
     caíam em 415px, no meio do segundo parágrafo. Por isso o texto passava
     pela cara dele.

     Com 330px de teto e um parágrafo só, a linha dos olhos desce para
     cerca de 530px, abaixo do último texto. A sobreposição fica no ombro
     e no braço, que é onde ela compõe em vez de atrapalhar.

     A REGRA DE OURO continua valendo e agora está escrita como conta.

     Só aumentar a largura come a folga, e come rápido: de 218 para 278 de
     largura a cabeça sobe 71px e passa a ficar 29px ACIMA do fim do botão,
     com a testa dele atrás do texto. Medido antes de trocar de abordagem.

     Por isso a foto não fica mais presa pela base: a base afunda e o topo
     da cabeça vira o ponto fixo, a 186px da base da dobra.

     186 é medido, não redondo, e sai de duas leituras em 375x812: o botão
     "Quem eu sou" termina em 584 e a dobra termina em 811. 811 menos 584
     menos 41 de folga dá 186. QUEM MUDAR A COPY DA DOBRA MEXE NESTE NÚMERO:
     manchete mais comprida empurra o botão para baixo e come a folga. Era
     258 quando o botão terminava em 511.

     O que passa da base entra por trás da faixa azul dos números, que tem
     158px, é opaca e vem colada aqui embaixo.

     vw e não %: a mesma medida é usada no `bottom`, e lá a porcentagem
     valeria contra a ALTURA da dobra em vez da largura. */
  /* A FOTO OCUPA O QUE SOBRA, E NAO UMA POSICAO CALCULADA.

     A versao anterior prendia o topo da cabeca a 186px da base da dobra.
     O 186 era medido de verdade, de uma leitura em 375x812 em que o
     botao "Quem eu sou" terminava em 584. E o comentario dizia, com
     todas as letras, que quem mudasse a copy teria de mexer no numero.

     A copy mudou. A manchete virou cinco linhas, o botao desceu, e o
     rosto do professor foi parar embaixo dele.

     Numero medido contra um layout que muda envelhece sempre. Ele nao
     envelhece devagar: envelhece na primeira troca de titulo, e sem
     avisar, porque nada quebra e nada fica vermelho.

     Agora a dobra e uma grade de duas fileiras. A primeira toma a altura
     que o texto precisar, seja ela qual for. A segunda fica com o resto,
     e e nela que a foto vive. Texto e figura deixam de disputar o mesmo
     espaco, e por construcao: nao ha conta para errar, nao ha copy que
     quebre, e nao ha aparelho de altura diferente que desalinhe.

     O piso de 200px existe para o professor nao virar uma tira. Se a
     manchete crescer tanto que nem isso caiba, a dobra passa de 100svh,
     o que e melhor que a foto sumir ou cobrir a leitura. */
  .heroi-grade {
    display: grid;
    grid-template-rows: auto minmax(200px, 1fr);
    min-height: calc(100svh - 92px);
    /* A regra base da grade traz align-items: end, para o desktop. Aqui
       ela colapsava a caixa do retrato para zero de altura, porque o
       filho dela e absoluto e nao tem altura propria com que se
       alinhar. A caixa precisa ESTICAR ate a fileira toda. */
    align-items: stretch;
  }

  .heroi .heroi-retrato {
    position: relative;
    grid-row: 2;
    /* min-height: 0 nao basta. A imagem em fluxo tem altura INTRINSECA,
       e `height: 100%` contra um pai sem altura definida cai para auto:
       327px de largura viravam 409px de altura e a fileira 1fr obedecia
       a imagem em vez de mandar nela. A dobra passava 259px da tela.
       Tirando a imagem do fluxo, quem manda na altura e a grade. */
    overflow: hidden;
    min-height: 0;
    width: 100%;
    margin: 0;
    z-index: 1;
    pointer-events: none;
  }

  /* cover com o topo ancorado, e nao contain.
     `contain` numa faixa larga e baixa escala pela ALTURA e devolve um
     professor de 160px de largura no meio do nada. `cover` preenche a
     faixa, e com object-position no topo ele corta o TORSO, e nunca a
     cabeca, que e a unica parte que precisa aparecer. */
  .heroi .heroi-retrato img {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    max-width: none;
    object-fit: cover;
    object-position: center top;
  }

  .heroi .heroi-retrato .cota { display: none; }

  /* A mascara lateral SAIU quando o retrato foi para o centro.

     Ela desbotava o lado esquerdo, e existia porque a figura ficava
     encostada na direita com o texto entrando por aquele lado. Centrado,
     ela come metade do rosto e da ombro sem par: o desbotamento passa a
     cair no meio da figura em vez de cair na emenda com o texto.

     Sobra a de baixo, que desbota o pe, onde o torso e cortado pelo
     proprio enquadramento da foto. Essa continua necessaria. */
  .heroi .heroi-retrato img {
    -webkit-mask-image:
      linear-gradient(to bottom, #000 0%, #000 74%, rgba(0, 0, 0, .5) 90%, transparent 100%);
    mask-image:
      linear-gradient(to bottom, #000 0%, #000 74%, rgba(0, 0, 0, .5) 90%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-composite: intersect;
  }
}

/* A folga que o texto deixa para o retrato absoluto. Estava embutida no
   HTML, e por isso nenhuma regra de CSS conseguia desliga-la no
   telefone: 78px de espaco morto empurrando a dobra para fora da tela
   num aparelho onde o retrato nem e absoluto. */
@media (min-width: 920px) {
  .heroi-texto-largo { padding-bottom: 78px; }
}

@media (min-width: 920px) {
  .heroi { min-height: 84vh; display: flex; align-items: center; }
  .heroi-grade { display: block; padding: 24px 0 64px; width: 100%; }

  .heroi-texto { position: relative; z-index: 2; max-width: 520px; }

  /* Dois nomes de classe de propósito. `.retrato` declara position:relative
     mais adiante no arquivo, com a mesma especificidade, e venceria por
     ordem de origem. Subir para .heroi .heroi-retrato resolve sem depender
     de onde a regra está no arquivo. */
  .heroi .heroi-retrato {
    /* A largura mora numa variável porque o `bottom` depende dela. O recorte
       é 1000 por 1249, então a altura é 1,25 da largura, o topo da cabeça
       fica a 4% do alto da imagem e a linha dos olhos a 15%. As três contas
       abaixo saem daí. */
    --retrato-larg: min(46vw, 680px);  /* TRAVADO PELO CLIENTE. Nao aumentar. */

    position: absolute;
    right: 0;
    width: var(--retrato-larg);

    /* bottom: 0 NÃO sobreviveu ao aumento, e a conta é esta.

       Em 1400x900 a dobra tem 755px de altura. Com 58vw a foto passa a ter
       812 de largura por 1015 de altura. Presa pela base, ela sobe 260px
       acima do topo da página: a coroa cai em -219 e a linha dos olhos em
       -108. O rosto sai da tela inteiro. Medido antes de trocar de
       abordagem, com o retrato em 46vw a coroa já era cortada em 18px.

       Agora quem fica fixo é o TOPO DA CABEÇA, a 60px do alto da dobra: a
       base afunda exatamente o tanto que a foto cresceu. Em 1400x900 a
       coroa passa a cair em +59px e para de ser cortada.

       84vh é a altura da própria dobra, declarada no min-height quatro
       linhas acima. Mexer num dos dois sem mexer no outro descola a conta.
       A primeira versão usava uma constante de 730px no lugar dela e falhou
       em janela baixa: em 1200x800 a dobra tem 672 e não 756, e a coroa
       voltava a ser cortada em 19px. Medido.

       Os 60px do fim não são folga de segurança: é onde cabe a linha de
       cota "ESC 1:1", que fica 31px acima da coroa e estava sendo cortada
       pela borda de cima da janela.

       O min(0px, ...) existe para tela estreita: abaixo de 1000px a foto já
       cabe inteira na dobra e não tem nada para afundar.

       O que afunda passa por trás da faixa azul dos números, que é opaca,
       tem sangria total e começa colada na base da dobra. Não sobra aresta
       solta em lugar nenhum. */
    bottom: min(0px, calc(84vh - 1.2 * var(--retrato-larg) - 60px));

    /* ATRÁS do texto. É a mudança que tira a dobra do óbvio: o recorte com
       alfa foi conquistado justamente para o título poder passar na frente
       do ombro. Em colunas separadas, o alfa não serve para nada. */
    z-index: 1;
    padding-top: 0;
  }

  /* O texto avança sobre o retrato. A sombra existe para o branco continuar
     legível quando cruzar o ombro, que é a única parte clara da figura. */
  .heroi-texto {
    max-width: 640px;
    z-index: 2;
    text-shadow: 0 2px 30px rgba(6, 15, 26, .85), 0 1px 6px rgba(6, 15, 26, .6);
  }

  /* A sombra acima é herdada por TUDO que está dentro do herói, e ela é
     um borrão escuro. Em texto claro sobre fundo escuro ela assenta a
     letra, que é para o que foi feita. Em texto escuro dentro de caixa
     clara ela faz o contrário: pinta um halo escuro em volta das letras
     que vaza para fora da caixa, porque text-shadow não é recortada pelo
     fundo do elemento. Era isso o borrão cinza em volta do GABARITAR, e
     só aparecia no desktop porque a sombra só existe a partir de 920px. */
  .heroi-texto .grifo-caixa,
  .heroi-texto .marca-forte,
  .heroi-texto .preco-economia,
  .heroi-texto .btn-bloco { text-shadow: none; }
  .heroi-texto .heroi-frase { max-width: 30em; }
}
/* Em tela larga o texto acabava em 949 e a foto só começava em 1305:
   356px de buraco no meio da dobra. A coluna sobe para 780 e o vão cai
   para pouco mais de 170, que é respiro e não falta. A frase de apoio
   continua travada em 30em, porque linha longa demais não se lê. */
@media (min-width: 1400px) { .heroi-texto { max-width: 780px; } }

/* Coluna larga e centrada, para a dobra que tem manchete comprida e muito
   vazio entre o texto e a figura.

   O teto de 1120px existe para o retrato: ele sangra na borda direita e
   ocupa cerca de 40% da janela. Texto centrado atravessando essa faixa
   passaria por baixo da figura, e texto por baixo de foto e pior do que o
   vazio que ele veio resolver. */
/* O teto sai de uma conta, não de um chute.

   O retrato sangra na direita ocupando --retrato-w da janela. A faixa
   livre para o texto é o que sobra à esquerda dele, menos o recuo do
   container e menos uma folga. Se eu deixasse 1120px fixo, como estava,
   o texto entrava 374px por baixo da figura numa janela de 1885.

   Os dois pedidos do cliente brigam pelo mesmo espaço: retrato maior e
   texto ocupando a faixa toda. A conta abaixo divide sem que nenhum dos
   dois invada o outro. */
@media (min-width: 920px) {
  .heroi-texto-largo {
    /* min(46vw, 680px) é o --retrato-larg da regra do retrato aqui embaixo.
       Se aquele número mudar, este muda junto.

       0,695 e não 1: o retrato é um recorte com alfa, e a caixa dele não é
       a figura. Medi o alfa da rogerio-recorte.webp linha a linha: o rosto
       só começa a 30,5% da largura da imagem, e à esquerda disso é
       transparente. Descontar a caixa inteira jogava fora 248px de espaço
       que não tem nada dentro.

       250px é o recuo real da coluna à esquerda: 172px de container mais a
       margem cotada, numa janela de 1400, mais folga.

       Esta conta foi refeita porque o retrato cresceu de 46vw para 58vw. Com
       o desconto antigo, em 1400 a coluna caía para 456px e a manchete de
       72px estourava em ONZE linhas em vez de três. Medido. Agora dá 586px,
       e a linha mais longa da manchete, "desde 2002." em 383px, termina em
       656, contra o rosto que começa em 821: 165px de folga. */
    max-width: min(880px, calc(100vw - 0.695 * min(46vw, 680px) - 250px));
    text-align: center;

    /* Respiro para a marca, que agora tem 52px de símbolo e termina em 70.

       Com a manchete comprida, o conteúdo da dobra passa de 84vh e a dobra
       deixa de ser centrada: o texto encosta no topo e a primeira linha da
       manchete começava em 54, dezesseis pixels ACIMA da base da marca, com
       88px de sobreposição horizontal. Medido em 1400x900, e já acontecia
       com o símbolo de 36px: a base dele caía em 68 contra os mesmos 54.

       62px empurram a manchete para 135. Foram 46 na primeira tentativa, e em
       1200x800 sobravam 2px entre a marca e a linha tecnica: a dobra fica
       mais alta ali e o texto sobe. Não é
       margem no .heroi-grade porque essa classe é das sete páginas, e só
       esta tem marca em cima da dobra. */
    padding-top: 62px;
  }
  .heroi-texto-largo .heroi-frase { margin-inline: auto; }
  .heroi-texto-largo .heroi-acoes { justify-content: center; }
}
/* No celular nao existe figura ao lado disputando espaco, entao a coluna e
   a largura toda e o centrado vale sem teto. */
@media (max-width: 919px) {
  .heroi-texto-largo { text-align: center; }
  .heroi-texto-largo .heroi-frase { margin-inline: auto; }
  .heroi-texto-largo .heroi-acoes { justify-content: center; }
}
/* NAO reintroduzir um `right` calculado aqui. A versao anterior usava
   calc((100vw - 1420px) / 2) para alinhar a foto com a borda do container,
   e em tela larga isso empurrava a figura 255px para dentro, direto em cima
   da coluna de texto. A foto sangra na borda da janela, e ponto. */

/* Entrada orquestrada: cada linha do título sobe atrasada da anterior. */
.entra { opacity: 0; transform: translateY(26px); animation: entrar .9s var(--ease) forwards; }
@keyframes entrar { to { opacity: 1; transform: none; } }
.d1 { animation-delay: .05s } .d2 { animation-delay: .18s }
.d3 { animation-delay: .31s } .d4 { animation-delay: .44s }
.d5 { animation-delay: .57s } .d6 { animation-delay: .7s }
.d7 { animation-delay: .83s }

.heroi-frase { font-size: clamp(1.04rem, 2vw, 1.2rem); color: var(--giz2); max-width: 33em; }
.heroi-acoes { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; }

/* ------------------------------------------------------------ */
/* Herói centrado                                                */
/*                                                               */
/* Variante para a dobra que não tem retrato. Sem figura à       */
/* direita, a composição fora de eixo perde o motivo de existir  */
/* e o texto volta para o meio.                                  */
/*                                                               */
/* As três camadas de fundo vêm junto, e isso não é detalhe: o   */
/* numeral, a pauta e o clarão foram posicionados para apontar   */
/* para uma figura à direita. Deixados onde estavam, ficam       */
/* apontando para um lugar vazio, e a dobra fica torta sem que   */
/* dê para dizer por quê.                                        */
/* ------------------------------------------------------------ */
.heroi-centro { text-align: center; }
.heroi-centro .heroi-texto { margin-inline: auto; }
/* Abaixo de 700px as linhas da manchete voltam a ser inline. Quebradas
   em bloco num celular de 375px, cada bloco quebrava de novo por dentro
   e a manchete virava seis linhas soltas, com "a prova" sozinha numa
   delas. Inline, o texto reflui e quebra onde couber. */
@media (max-width: 699px) {
  .heroi-centro h1 > span[style*="block"] { display: inline !important; }
}
.heroi-centro .heroi-frase { margin-inline: auto; }
.heroi-centro .heroi-fundo b {
  right: auto;
  left: 50%;
  bottom: -.24em;
  transform: translateX(-50%);
}
.heroi-centro .heroi-fundo i {
  -webkit-mask-image: radial-gradient(ellipse 68% 60% at 50% 48%, #000 8%, transparent 72%);
  mask-image: radial-gradient(ellipse 68% 60% at 50% 48%, #000 8%, transparent 72%);
}
.heroi-centro .heroi-fundo u {
  right: auto;
  left: 50%;
  top: 28%;
  transform: translate(-50%, -30%);
}

/* Os bizus entregues na própria dobra.

   Primeira versão: sem caixa, só uma régua curta em cima, para não ler
   como anúncio. Errado. Sem caixa e sobre o mesmo fundo do resto, o
   bizu virava mais um parágrafo da dobra e a entrega mais valiosa da
   página passava despercebida.

   Agora é painel: chapa mais clara que o breu da dobra, sombra funda o
   bastante para descolar do fundo, e a regra do bizu em azul claro. São
   os três únicos elementos da página com essa combinação, então o olho
   vai neles antes de ler qualquer outra coisa. */
.amostra { display: grid; gap: 20px; margin-top: 52px; }
@media (min-width: 860px) { .amostra { grid-template-columns: 1fr 1fr; gap: 26px; } }
.amostra > article {
  position: relative;
  background: var(--chapa2);
  border: 1px solid var(--fio);
  border-top: 3px solid var(--risco);
  padding: 26px 24px 24px;
  box-shadow: 0 26px 54px rgba(0, 0, 0, .55), 0 6px 16px rgba(0, 0, 0, .3);
}
/* O halo. É o que faz o painel parecer suspenso em vez de colado: uma
   mancha do acento por baixo, maior que o cartão e desfocada. */
.amostra > article::after {
  content: '';
  position: absolute;
  inset: 12% 6% -14% 6%;
  z-index: -1;
  background: rgba(103, 182, 247, .13);
  filter: blur(30px);
  pointer-events: none;
}
.amostra .bizu-n { color: var(--risco); margin-bottom: .9em; }
.amostra h3 {
  font-size: clamp(1.3rem, 2.5vw, 1.66rem);
  line-height: 1.13;
  margin-bottom: .6em;
  color: var(--risco-q);
}
.amostra p { color: var(--giz2); font-size: .97rem; margin-bottom: 0; }
.amostra p strong { color: var(--giz); }

/* O que tem dentro, em números, ainda na primeira dobra. A pergunta
   "o que eu levo" não pode esperar seis pranchas para ser respondida. */
.regua-itens {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px 36px;
  margin: 46px 0 0;
  padding: 0;
}
.regua-itens li {
  list-style: none;
  font-family: var(--tec);
  font-size: .76rem;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--giz3);
}
.regua-itens b { color: var(--giz); font-weight: 600; }

/* ------------------------------------------------------------ */
/* Faixa em loop                                                 */
/*                                                               */
/* Movimento contínuo na dobra sem requisição e sem script: uma  */
/* fita duplicada deslizando por transform, que é a propriedade  */
/* que anima sem forçar recálculo de layout a cada quadro.       */
/*                                                               */
/* O conteúdo é duplicado no HTML de propósito, e as duas metades*/
/* têm que ser idênticas. O laço anda até -50%, que é exatamente */
/* o começo da segunda cópia, então o ponto de reinício cai onde */
/* o olho já estava vendo a mesma coisa e não existe emenda.     */
/* Sem a cópia, a fita dá um salto visível a cada volta.         */
/* ------------------------------------------------------------ */
.faixa {
  position: relative;
  overflow: hidden;
  padding: 15px 0;
  /* Fundo no acento e texto escuro em cima. A primeira versão era texto
     apagado sobre chapa escura: bonito e ilegível, que é o pior par
     possível para o primeiro elemento da página. Aqui a faixa é a coisa
     de maior contraste do site inteiro, e é de propósito. */
  background: var(--risco);
}
.faixa-fita {
  display: flex;
  width: max-content;
  animation: correfita 38s linear infinite;
  /* A máscara fica na fita, não na faixa. Na faixa ela desbotava a barra
     inteira nas pontas e a barra deixava de ser barra. Aqui só o texto
     some na borda, e o bloco de cor continua de ponta a ponta. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent);
}
.faixa-fita > span {
  font-family: var(--tec);
  font-size: clamp(.84rem, 1.5vw, .96rem);
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  /* .72 e não .66. Em .66 o contraste com o azul dá 4.38:1, abaixo do
     mínimo de 4.5 para texto normal. Em .72 dá 5.09:1. */
  color: rgba(6, 15, 26, .72);
  white-space: nowrap;
  padding-right: 44px;
}
.faixa-fita b { color: var(--breu); font-weight: 700; }
@keyframes correfita { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .faixa-fita { animation: none; } }

/* ------------------------------------------------------------ */
/* Hierarquia: o degrau que faltava                              */
/*                                                               */
/* A página tinha dois tamanhos, o título e o resto. Sem degrau  */
/* no meio, tudo que não era h2 virava o mesmo cinza e a pessoa  */
/* lia parágrafo atrás de parágrafo sem nenhum ponto de parada.  */
/*                                                               */
/* A escala fica assim, e são cinco degraus:                     */
/* h2 3.7  ·  frase 2.0  ·  h3 1.5  ·  corpo 1.05  ·  tec 0.76   */
/* ------------------------------------------------------------ */
.frase {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.5rem, 3.2vw, 2.3rem);
  line-height: 1.16;
  letter-spacing: -.02em;
  color: var(--giz);
  max-width: 21em;
  margin-bottom: .5em;
}
.fecho-central .frase { margin-left: auto; margin-right: auto; }

/* Marca-texto.

   Pinta só os 42% de baixo da linha, que é onde o traço de um marcador
   de verdade cai. Pintar a caixa inteira dá etiqueta, não marcação, e
   etiqueta em cima de frase longa fica ilegível. */
.marca {
  background-image: linear-gradient(to top,
    rgba(103, 182, 247, .32) 0, rgba(103, 182, 247, .32) 42%, transparent 42%);
  padding: 0 .1em;
  color: var(--giz);
  font-weight: 600;
}
/* Uma por seção, no máximo. Fundo cheio e texto escuro, para a única
   frase que a pessoa tem que levar embora se ler só ela. */
.marca-forte {
  background: var(--risco);
  color: var(--breu);
  padding: .05em .3em;
  font-weight: 600;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
/* Caixa cheia no lugar do sublinhado, para a palavra que carrega a
   promessa. O .grifo risca por baixo com 5px de acento, que some quando
   a manchete tem 60px: o traço vira detalhe embaixo de uma palavra
   grande. A caixa inverte o par inteiro e é vista antes de ser lida. */
.grifo-caixa {
  background: var(--giz);
  color: var(--breu);
  padding: 0 .14em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* A segunda palavra em ênfase da manchete. Duas caixas cheias na mesma
   frase brigam entre si e nenhuma das duas ganha, então esta fica só na
   cor do acento: a hierarquia entre as duas ênfases é PRECISA em azul,
   GABARITAR em caixa, e a promessa é a que leva a caixa. */
.palavra-forte { color: var(--risco); }

/* Chamada para descer. Seta e três palavras. Fica logo acima dos bizus
   porque o que ela anuncia está ali, e não seis pranchas abaixo. */
.desce {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  margin-top: 40px;
}
.desce span {
  font-family: var(--tec);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--risco);
}
/* Seta em borda, não em glifo: fonte de ícone seria uma requisição a
   mais e um caractere que pode não existir na família carregada. */
.desce i {
  width: 12px;
  height: 12px;
  border-right: 2px solid var(--risco);
  border-bottom: 2px solid var(--risco);
  transform: rotate(45deg);
  animation: pula 1.7s var(--ease) infinite;
}
@keyframes pula {
  0%, 100% { transform: rotate(45deg) translate(0, 0); }
  50%      { transform: rotate(45deg) translate(4px, 4px); }
}
@media (prefers-reduced-motion: reduce) { .desce i { animation: none; } }

/* ------------------------------------------------------------ */
/* Preço e chamada na própria dobra                              */
/*                                                               */
/* A dobra tinha manchete, subtítulo e prova, e nenhum preço.    */
/* Quem chega por anúncio pergunta quanto custa antes de         */
/* perguntar o que é, e a resposta estava a seis pranchas de     */
/* distância.                                                     */
/* ------------------------------------------------------------ */
.preco-dobra { margin-top: 40px; }
.preco-linha {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 6px 14px;
}
.preco-de {
  font-family: var(--tec);
  font-size: 1rem;
  color: var(--giz3);
  text-decoration: line-through;
}
.preco-por { font-family: var(--tec); font-size: .82rem; color: var(--giz2); }
.preco-valor {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(2.7rem, 7.4vw, 3.7rem);
  line-height: 1;
  letter-spacing: -.035em;
  color: var(--giz);
}
/* Selo de economia no acento, não em vermelho. Vermelho num selo de
   desconto é convenção de varejo, e essa página não é varejo: a marca
   tem uma cor só, e usar uma segunda só no selo faz ele parecer colado
   de outro site. */
.preco-economia {
  font-family: var(--tec);
  font-size: .74rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  background: var(--risco);
  color: var(--breu);
  padding: .55em .85em;
  align-self: center;
}

/* O que vai dentro, entre o preço e o botão.

   Cada linha tem duas partes e as duas são obrigatórias: o entregável,
   que é o que a pessoa recebe, e a promessa, que é o que ela passa a
   conseguir fazer. Lista só com o entregável vira índice de sumário, e
   índice de sumário não vende. */
.entrega {
  display: grid;
  gap: 13px;
  max-width: 720px;
  margin: 30px auto 0;
  padding: 0;
  text-align: left;
}
@media (min-width: 820px) { .entrega { grid-template-columns: 1fr 1fr; gap: 16px 34px; } }
.entrega li { list-style: none; display: flex; align-items: flex-start; gap: 13px; }
/* Marca de conferido desenhada em borda, como a seta do "veja os bizus".
   Sem fonte de ícone e sem uma requisição a mais. */
.entrega li::before {
  content: '';
  flex: 0 0 auto;
  width: 6px;
  height: 11px;
  margin-top: 5px;
  border-right: 2px solid var(--risco);
  border-bottom: 2px solid var(--risco);
  transform: rotate(45deg);
}
.entrega b { display: block; color: var(--giz); font-weight: 600; font-size: .98rem; line-height: 1.25; }
.entrega span { display: block; color: var(--giz2); font-size: .87rem; line-height: 1.35; margin-top: 2px; }

/* O botão da dobra é branco, não azul. Na página inteira o acento é
   azul, então azul virou a cor do sistema e deixou de ser a cor do
   clique. Branco é a única coisa dessa cor na dobra. */
.btn-bloco {
  position: relative;
  display: block;
  width: 100%;
  max-width: 460px;
  margin: 26px auto 0;
  background: var(--giz);
  color: var(--breu);
  border: 0;
  padding: 22px 28px;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.05rem, 2.4vw, 1.24rem);
  text-align: center;
  text-decoration: none;
  overflow: hidden;
  isolation: isolate;
  cursor: pointer;
  transition: transform .18s var(--ease), box-shadow .18s var(--ease);
  box-shadow: 0 14px 34px rgba(0, 0, 0, .45);
}
/* Tres camadas, e cada uma responde a uma coisa diferente.

   ::before e a passada de luz. Ela nasce fora do botao pela esquerda e
   atravessa no hover. Fica embaixo do texto por z-index negativo, entao
   nao lava a palavra enquanto passa.

   ::after e o fio de acento que cresce da esquerda. Ele e o unico
   elemento que sobra depois do hover terminar, e serve de rastro: o
   botao lido de relance parece que carregou alguma coisa.

   O :active encolhe. Botao que nao afunda no toque le como imagem, e
   foi essa a reclamacao. */
.btn-bloco::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 -60%;
  z-index: -1;
  width: 55%;
  background: linear-gradient(100deg, transparent, rgba(103, 182, 247, .55), transparent);
  transform: skewX(-18deg);
  transition: left .55s var(--ease);
}
.btn-bloco::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 3px;
  background: var(--risco);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .34s var(--ease);
}
.btn-bloco:hover, .btn-bloco:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 20px 44px rgba(0, 0, 0, .55);
}
.btn-bloco:hover::before, .btn-bloco:focus-visible::before { left: 105%; }
.btn-bloco:hover::after, .btn-bloco:focus-visible::after { transform: scaleX(1); }
.btn-bloco:active { transform: translateY(0) scale(.985); box-shadow: 0 8px 20px rgba(0, 0, 0, .5); }

/* A seta. Entra por markup, nao por ::after global: botao com texto de
   duas linhas em pagina de preco nao quer seta, e um ::after em
   .btn-bloco colocaria seta em todos os quinze botoes do projeto. */
.btn-seta { display: inline-flex; align-items: center; gap: .6em; }
.btn-seta i {
  font-style: normal;
  display: inline-block;
  transition: transform .28s var(--ease);
}
.btn-bloco:hover .btn-seta i { transform: translateX(6px); }

@media (prefers-reduced-motion: reduce) {
  .btn-bloco, .btn-bloco::before, .btn-bloco::after, .btn-seta i { transition: none; }
  .btn-bloco:hover { transform: none; }
}

/* Os três selos.

   Antes eram três itens de peso diferente, dois com <b> e um sem, com
   espaçamento só por gap. Quebravam em 2 mais 1 e a terceira linha ficava
   órfã, parecendo que faltou alguma coisa.

   Agora têm peso igual e losango de separação entre eles. O losango é o
   mesmo sinal do nó da junta, então quando a linha quebra ela quebra
   depois de um separador e a quebra lê como decisão, não como sobra. */
.preco-selos {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 6px 0;
  margin: 20px 0 0;
  padding: 0;
}
.preco-selos li {
  list-style: none;
  display: flex;
  align-items: center;
  font-family: var(--tec);
  font-size: .74rem;
  font-weight: 500;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--giz2);
}
.preco-selos li:not(:last-child)::after {
  content: '';
  width: 4px;
  height: 4px;
  margin: 0 15px;
  background: var(--risco);
  transform: rotate(45deg);
}
/* Abaixo de 560px os três não cabem numa linha de jeito nenhum: são 48
   caracteres mais dois separadores, contra 327px de largura útil. Em vez
   de deixar quebrar em 2 mais 1, com a primeira linha terminando num
   losango solto, eles empilham. Três linhas centradas leem como lista;
   duas linhas desiguais leem como sobra. */
@media (max-width: 559px) {
  .preco-selos { flex-direction: column; gap: 9px; }
  .preco-selos li:not(:last-child)::after { display: none; }
}

/* Subtítulo do herói em destaque.

   Era vermelho. Saiu: o vermelho deste sistema significa errado, e ele
   está reservado para .par-erro e .bizu-erro, onde a cor carrega
   sentido. Usado no subtítulo virava uma segunda cor de marca competindo
   com o azul, e a dobra passava a ter duas.

   O destaque agora vem do corpo e do contraste dentro da própria frase:
   texto claro, o número no acento, e o fecho em caixa cheia. */
.heroi-frase-forte {
  color: var(--giz);
  font-size: clamp(1.16rem, 2.4vw, 1.56rem);
  line-height: 1.32;
  max-width: 26em;
}
.heroi-frase-forte b { color: var(--risco); font-weight: 700; }

/* No bloco claro o traço precisa de mais carga, senão some no papel. */
.prancha-clara .marca {
  background-image: linear-gradient(to top,
    rgba(103, 182, 247, .58) 0, rgba(103, 182, 247, .58) 42%, transparent 42%);
  color: var(--breu);
}

/* Escada de ancoragem.

   Três linhas em ordem decrescente de preço, e a última é a nossa. A
   ordem importa: o olho lê o R$70 primeiro e chega no R$37 já com uma
   régua na cabeça. Invertido, o R$37 seria o primeiro número visto e não
   teria contra o que ser barato.

   A terceira linha ganha fio no acento e fundo, para o olho saber onde a
   escada termina sem precisar de seta. */
.ancora { display: grid; gap: 0; margin: 0; padding: 0; }
.ancora li {
  list-style: none;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 2px 16px;
  padding: 15px 0;
  border-top: 1px solid var(--fio2);
}
.ancora li:last-child { border-bottom: 1px solid var(--fio2); }
.ancora-que { color: var(--giz2); font-size: 1rem; }
.ancora-valor {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.5rem;
  letter-spacing: -.02em;
  color: var(--giz3);
  justify-self: end;
}
.ancora-oque {
  grid-column: 1 / -1;
  font-family: var(--tec);
  font-style: normal;
  font-size: .74rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--giz3);
}
.ancora-nossa {
  border-left: 3px solid var(--risco);
  padding-left: 16px;
  background: linear-gradient(to right, rgba(103, 182, 247, .09), transparent 70%);
}
.ancora-nossa .ancora-que { color: var(--giz); }
.ancora-nossa .ancora-valor { color: var(--risco); font-size: 1.9rem; }
.ancora-nossa .ancora-oque { color: var(--giz2); }

/* De muitas regras para um teste. É a tese do produto, então ela aparece
   como par de colunas e não como frase enterrada num parágrafo. */
.vira { display: grid; gap: 0; margin: 30px 0 0; padding: 0; max-width: 36em; }
.vira li {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 12px;
  border-top: 1px solid var(--fio2);
  padding: 12px 0;
}
.vira li:last-child { border-bottom: 1px solid var(--fio2); }
.vira span { color: var(--giz2); font-size: 1rem; }
.vira i {
  font-family: var(--tec);
  font-style: normal;
  font-size: .72rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--risco);
}
.vira b { font-weight: 600; color: var(--giz); font-size: 1rem; }

/* Retrato. O fundo da foto foi graduado para o mesmo breu da página, então
   ela dissolve sem moldura. Só use com foto de fundo escuro: em fundo claro
   isso vira um retângulo pousado no nada. */
.retrato { position: relative; }

/* No herói a foto encosta na borda direita da página, então só a esquerda e
   a base precisam dissolver. Vale para foto COM fundo. */
.retrato img {
  width: 100%;
  -webkit-mask-image:
    linear-gradient(to bottom, transparent 0%, #000 6%, #000 66%, transparent 100%),
    linear-gradient(to left, #000 76%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to bottom, transparent 0%, #000 6%, #000 66%, transparent 100%),
    linear-gradient(to left, #000 76%, transparent 100%);
  mask-composite: intersect;
}

/* Recorte com alfa: nada de máscara. A máscara existia só para disfarçar a
   emenda entre foto e fundo, e com transparência essa emenda não existe.
   Aqui a foto entra inteira, nítida até a borda.

   O brilho por trás é sombra invertida: em vez de escurecer o chão, ele
   acende o ar atrás do ombro. Assenta a figura sem inventar um chão que
   não existe numa página. */
.retrato-alfa { position: relative; }
.retrato-alfa::before {
  content: '';
  position: absolute;
  left: 50%; top: 42%;
  width: 78%; aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, rgba(103,182,247,.13) 0%, transparent 68%);
  z-index: 0;
  pointer-events: none;
}
/* A LATERAL não leva máscara: o alfa já resolve, e mascarar de lado
   comeria o contorno de luz do ombro.

   A BASE leva, e é obrigatório: a foto foi cortada no torso, então com
   fundo transparente esse corte vira uma linha reta suspensa no ar. O
   desbotamento começa em 58% e só termina no fim, o que é longo de
   propósito: dissolução curta lê como borrão, longa lê como o corpo
   entrando na escuridão. */
.retrato-alfa img {
  position: relative;
  z-index: 1;
  -webkit-mask-image: linear-gradient(to bottom,
    #000 0%, #000 58%, rgba(0,0,0,.82) 74%, rgba(0,0,0,.4) 88%, transparent 100%);
  mask-image: linear-gradient(to bottom,
    #000 0%, #000 58%, rgba(0,0,0,.82) 74%, rgba(0,0,0,.4) 88%, transparent 100%);
  filter: drop-shadow(0 24px 48px rgba(0, 0, 0, .5));
}

/* NÃO reintroduzir véu escuro aqui.
   Uma tentativa anterior pintava um gradiente opaco sobre a base do
   retrato para "trazer o fundo por cima". O gradiente apagava as linhas
   da pauta dentro do próprio retângulo, e o retângulo ficava visível:
   uma borda vertical na direita e uma horizontal embaixo, exatamente o
   corte reto que se queria eliminar.

   A máscara na base do <img> resolve sozinha, porque ela remove pixel em
   vez de pintar por cima. */

/* A foto da prancha 03 sangra pela esquerda e encosta no texto pela direita.
   A esquerda fica intacta, porque ali ela sai da tela e não tem borda para
   esconder. Direita e base dissolvem longo, e o topo desbota de leve.

   Sem isso a imagem vira um retângulo de aresta viva no meio do escuro, que
   foi exatamente o defeito visto na captura. */
.retrato-meio img {
  -webkit-mask-image:
    linear-gradient(to bottom, transparent 0%, #000 7%, #000 62%, transparent 100%),
    linear-gradient(to right, #000 0%, #000 54%, rgba(0,0,0,.5) 82%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to bottom, transparent 0%, #000 7%, #000 62%, transparent 100%),
    linear-gradient(to right, #000 0%, #000 54%, rgba(0,0,0,.5) 82%, transparent 100%);
  mask-composite: intersect;
}

/* Linha de cota, como numa prancha de verdade: dois traços e a medida no
   meio. Mede o retrato, e é o detalhe que denuncia o conceito. */
.cota {
  position: absolute;
  right: 0;
  display: none;
  align-items: center;
  gap: 8px;
  font-family: var(--tec);
  font-size: .6rem;
  letter-spacing: .14em;
  color: var(--risco-f);
  opacity: 0;
  animation: entrar .8s var(--ease) 1.4s forwards;
}
@media (min-width: 920px) { .cota { display: flex; } }
.cota::before, .cota::after { content: ''; height: 1px; background: currentColor; flex: 1; min-width: 26px; }
.cota-topo { top: 10px; left: 0; }
.cota-base { bottom: 46px; left: 0; }

/* ============================================================ */
/* A LINHA DO TEMPO                                             */
/*                                                              */
/* A pauta do sistema deixa de ser textura e vira régua de 24    */
/* anos. UMA linha vertical desce do herói, atravessa a borda    */
/* entre as dobras e organiza a segunda inteira.                 */
/*                                                              */
/* Isso resolve três problemas com um elemento: costura as       */
/* dobras, conta a autoridade como distância percorrida, e dá o  */
/* movimento sem precisar de efeito decorativo.                  */
/* ============================================================ */

/* A costura: o pedaço de linha que sai do herói e entra na dobra
   seguinte. Ela nasce no fim do texto e desce atravessando a borda. */
.costura {
  position: absolute;
  left: 0;
  bottom: -60px;
  width: 1px;
  height: 120px;
  background: linear-gradient(to bottom, var(--risco), var(--fio));
  transform-origin: top;
  transform: scaleY(0);
  animation: desce 1.1s var(--ease) 1.5s forwards;
  z-index: 3;
}
@keyframes desce { to { transform: scaleY(1); } }

/* A linha do tempo INVADE o herói em vez de começar depois dele. Bloco que
   encosta em bloco é empilhamento; bloco que invade é composição. */
.tempo {
  position: relative;
  z-index: 3;
  margin-top: -72px;
  background: linear-gradient(to bottom, transparent, var(--breu) 90px);
}
@media (min-width: 900px) { .tempo { margin-top: -110px; } }

/* A espinha. Fica atrás dos marcos e cresce conforme a pessoa rola.
   O --avanco é escrito pelo JS, de 0 a 1. */
/* A espinha fica ENTRE a coluna do ano e a do texto, nunca por baixo do ano.
   A coluna do ano tem 200px e o vao 44px, então 222px cai no meio do vao.
   Em 95px ela cortava os numerais ao meio, que era o defeito relatado. */
.espinha {
  position: absolute;
  top: 0; bottom: 0;
  left: 11px;
  width: 1px;
  background: var(--fio2);
  z-index: 0;
}
@media (min-width: 780px) { .espinha { left: 222px; } }

.espinha::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, var(--risco) 0%, var(--risco) 82%, transparent 100%);
  transform-origin: top;
  transform: scaleY(var(--avanco, 0));
  transition: transform .12s linear;
}

/* Profundidade em Z. É o 3D que cabe aqui: sem WebGL, sem biblioteca, e
   composto na GPU. O tráfego chega por webview do Instagram em celular
   médio, e cena em tempo real custaria segundos de carregamento.

   Só acima de 900px: no celular perspectiva em lista longa provoca
   repaint e engasga a rolagem. */
.marcos { position: relative; display: grid; gap: 0; }

@media (min-width: 900px) {
  .marcos { perspective: 900px; perspective-origin: 20% 50%; }
  .marco {
    transform: translateZ(-140px) translateY(30px) rotateX(6deg);
    opacity: .35;
    transition: transform 1s var(--ease), opacity .8s var(--ease);
  }
  .marco.aceso { transform: none; opacity: 1; }
}

.marco {
  position: relative;
  display: grid;
  gap: 10px;
  padding: 40px 0 40px 40px;
}
@media (min-width: 780px) {
  .marco { grid-template-columns: 200px 1fr; gap: 0 44px; padding: 52px 0 52px 0; }
}

/* O ponto na linha. Apagado até o marco entrar, e aí acende. */
.marco::before {
  content: '';
  position: absolute;
  left: 6px;
  top: 48px;
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--breu);
  border: 1px solid var(--fio);
  transition: border-color .5s var(--ease), box-shadow .5s var(--ease), background .5s var(--ease);
  z-index: 2;
}
@media (min-width: 780px) { .marco::before { left: 217px; top: 60px; } }

/* O ano fica ACIMA da espinha, com um respiro de fundo em volta, para o fio
   nunca cruzar o numeral. */
.marco-ano { position: relative; z-index: 1; padding-right: 18px; }

.marco.aceso::before {
  background: var(--risco);
  border-color: var(--risco);
  box-shadow: 0 0 0 4px rgba(103, 182, 247, .16), 0 0 18px rgba(103, 182, 247, .5);
}

.marco-ano {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(2.2rem, 6vw, 3.4rem);
  letter-spacing: -.05em;
  line-height: .92;
  color: var(--giz3);
  font-variant-numeric: tabular-nums;
  transition: color .6s var(--ease);
}
@media (min-width: 780px) { .marco-ano { text-align: right; } }
.marco.aceso .marco-ano { color: var(--risco); }

.marco-rotulo {
  display: block;
  font-family: var(--tec);
  font-size: .64rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--giz3);
  margin-top: .7em;
}

.marco h3 { margin-bottom: .4em; }
.marco p { color: var(--giz2); max-width: 54ch; }

/* A revelação é por cortina, não por opacidade. Fade todo mundo faz;
   cortina lê como algo sendo escrito na folha. */
.cortina {
  clip-path: inset(0 100% 0 0);
  transition: clip-path 1s var(--ease);
}
.marco.aceso .cortina { clip-path: inset(0 0 0 0); }
.marco.aceso .cortina:nth-of-type(2) { transition-delay: .1s; }

/* A frase que fecha a linha do tempo, alinhada com a espinha. */
.tempo-fecho {
  position: relative;
  padding: 46px 0 0 40px;
  border-top: 1px solid var(--fio2);
  margin-top: 20px;
}
@media (min-width: 780px) { .tempo-fecho { padding-left: 244px; } }

/* ------------------------------------------------------------ */
/* Faixa de dados                                                */
/* ------------------------------------------------------------ */

.dados {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  border-top: 1px solid var(--fio);
  border-left: 1px solid var(--fio);
}
@media (min-width: 780px) {
  .dados { grid-template-columns: repeat(4, 1fr); }
  .dados-3 { grid-template-columns: repeat(3, 1fr); }
}

/* Três cartões numa grade de duas colunas deixam o quarto quadrante vazio,
   e o buraco lê como erro de montagem: falta um número.

   Escolhi UMA COLUNA no celular em vez de mandar o terceiro atravessar as
   duas. Atravessando, o cartão do Instagram ficaria com o dobro da área dos
   outros dois e passaria a valer mais que os 24 anos e os 4.000 alunos, e
   a página não afirma isso em lugar nenhum. Hierarquia inventada é o mesmo
   defeito de número inventado.

   E a coluna única conserta uma segunda medida, que era o defeito de
   verdade: em 375px cada célula da grade de dois tem 114px de texto útil,
   e "200 mil+" em 33,6px pede 155. O número quebrava em DUAS LINHAS dentro
   do quadrado. Com uma coluna são 279px e os três cabem numa linha só.

   Só .dados-3. A .dados de quatro itens fecha a grade de dois sozinha e
   continua como está, aqui e na redacao-aula. */
@media (max-width: 779px) {
  .dados-3 { grid-template-columns: 1fr; }
}

.dado {
  padding: 30px 24px;
  border-right: 1px solid var(--fio);
  border-bottom: 1px solid var(--fio);
  position: relative;
  transition: background .35s var(--ease);
}
.dado:hover { background: var(--chapa); }
.dado .num { font-size: clamp(2.1rem, 5vw, 3rem); color: var(--risco); }
.dado p { margin: 12px 0 0; font-size: .88rem; color: var(--giz2); line-height: 1.42; }

/* ============================================================ */
/* PRANCHA 03 · QUEM É                                          */
/* Duas colunas DESIGUAIS, retrato sangrando pela borda         */
/* esquerda. Era coluna única com foto solta embaixo, o que      */
/* deixava buraco e repetia a composição das outras cinco.       */
/* ============================================================ */

.quem { position: relative; }

.quem-grade { display: grid; gap: 34px; }
@media (min-width: 920px) {
  .quem-grade { grid-template-columns: 44% 1fr; gap: 0 56px; align-items: center; }
  /* Sangra pela esquerda: sai do container e encosta na borda da janela. */
  .quem-foto { margin-left: calc(-1 * (var(--rail) + 100px)); }
}

/* A foto desta prancha é horizontal 4:3 e já vem com alfa, então entra
   inteira, sem janela recortando e sem máscara disfarçando emenda.
   O único desbotamento é na base, onde o torso é cortado pelo enquadramento
   original. */
.quem-foto { position: relative; }
.quem-foto img {
  width: 100%;
  display: block;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 76%, rgba(0,0,0,.6) 90%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 76%, rgba(0,0,0,.6) 90%, transparent 100%);
  filter: drop-shadow(0 22px 46px rgba(0, 0, 0, .52));
}
.quem-texto { max-width: 440px; }

/* A prova de didática: uma frase em corpo de manchete atravessando a
   largura inteira. Não é parágrafo com aspas, é citação de revista, e é o
   único lugar da página onde o texto vira elemento gráfico. */
.didatica {
  margin-top: 72px;
  padding-top: 44px;
  border-top: 1px solid var(--fio);
  position: relative;
}
.didatica p {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(1.7rem, 4.4vw, 3.1rem);
  line-height: 1.06;
  letter-spacing: -.035em;
  color: var(--giz);
  max-width: 17em;
  text-wrap: balance;
}
.didatica p em { font-style: normal; color: var(--risco); }
.didatica footer {
  margin-top: 1.4em;
  font-family: var(--tec);
  font-size: .68rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--giz3);
}

/* ============================================================ */
/* PRANCHA 04 · COMO ENSINA                                     */
/* Grade 2 por 2, não lista vertical. Densa, logo depois de uma  */
/* prancha arejada: é o ritmo que faltava.                       */
/* ============================================================ */

.quadros { display: grid; gap: 1px; background: var(--fio2); margin-top: 44px; }
@media (min-width: 760px) { .quadros { grid-template-columns: 1fr 1fr; } }

.quadro {
  position: relative;
  background: var(--breu);
  padding: 40px 34px 44px;
  overflow: hidden;
  transition: background .4s var(--ease);
}
.quadro:hover { background: var(--chapa); }

/* O número em corpo gigantesco como textura do próprio quadrante. */
.quadro b {
  position: absolute;
  right: -.04em; bottom: -.34em;
  font-family: var(--display);
  font-weight: 800;
  font-size: 11rem;
  line-height: .8;
  letter-spacing: -.06em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(103, 182, 247, .10);
  font-variant-numeric: tabular-nums;
  pointer-events: none;
  transition: -webkit-text-stroke-color .4s var(--ease);
}
.quadro:hover b { -webkit-text-stroke-color: rgba(103, 182, 247, .2); }
.quadro h3, .quadro p { position: relative; z-index: 1; }
.quadro h3 { margin-bottom: .5em; }
.quadro p { color: var(--giz2); font-size: .97rem; max-width: 34ch; }

/* ------------------------------------------------------------ */
/* Posições                                                      */
/* ------------------------------------------------------------ */

.posicoes { border-top: 1px solid var(--fio); }

.posicao {
  display: grid;
  gap: 8px 30px;
  padding: 32px 0;
  border-bottom: 1px solid var(--fio2);
  transition: padding-left .4s var(--ease);
}
@media (min-width: 780px) { .posicao { grid-template-columns: 84px 1fr; gap: 0 34px; } }
.posicao:hover { padding-left: 10px; }

.posicao-n {
  font-family: var(--tec);
  font-weight: 600;
  font-size: .74rem;
  letter-spacing: .16em;
  color: var(--risco-f);
  padding-top: .5em;
  transition: color .3s var(--ease);
}
.posicao:hover .posicao-n { color: var(--risco); }
.posicao h3 { margin-bottom: .35em; }
.posicao p { color: var(--giz2); max-width: 58ch; }

/* ------------------------------------------------------------ */
/* Ficha de material                                             */
/* ------------------------------------------------------------ */

.fichas { display: grid; gap: 0; border-top: 1px solid rgba(6,15,26,.18); }

.ficha {
  display: grid;
  gap: 10px 30px;
  padding: 34px 0;
  border-bottom: 1px solid rgba(6, 15, 26, .18);
  text-decoration: none;
  color: inherit;
  position: relative;
  transition: padding-left .4s var(--ease);
}
@media (min-width: 820px) { .ficha { grid-template-columns: 168px 1fr auto; gap: 0 34px; align-items: start; } }
.ficha:hover { padding-left: 12px; }

.ficha-selo { font-family: var(--tec); font-size: .68rem; letter-spacing: .14em; text-transform: uppercase; color: var(--risco-f); padding-top: .35em; }
.ficha h3 { margin-bottom: .3em; }
.ficha p { margin: 0; color: #40607f; font-size: .96rem; max-width: 56ch; }

.ficha-preco {
  font-family: var(--display);
  font-weight: 800;
  font-size: 1.7rem;
  letter-spacing: -.04em;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 12px;
}
/* A seta é VISÍVEL sem hover. No celular hover não existe, e ela estava em
   opacity 0: para a maior parte do tráfego, que vem de webview, o único
   sinal de que a ficha é clicável simplesmente não aparecia. */
.ficha-preco::after {
  content: '→';
  font-family: var(--tec);
  font-size: 1rem;
  color: var(--risco-f);
  opacity: .55;
  transition: transform .35s var(--ease), opacity .35s var(--ease);
}
.ficha:hover .ficha-preco::after { transform: translateX(5px); opacity: 1; }

/* ============================================================ */
/* PRANCHA 05 · MATERIAIS                                       */
/* Duas metades verticais em vez de lista. Era a única prancha   */
/* que ainda abria como rótulo, título e lista, igual às outras. */
/* ============================================================ */

.vitrine { display: grid; gap: 1px; background: rgba(6,15,26,.14); margin-top: 48px; }
@media (min-width: 860px) { .vitrine { grid-template-columns: 1fr 1fr; } }

.vitrine a {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 46px 38px 52px;
  background: var(--giz);
  text-decoration: none;
  color: var(--breu);
  overflow: hidden;
  transition: background .35s var(--ease);
}
.vitrine a:hover { background: #dfe9f4; }

/* O preço em corpo de manchete, não em linha de tabela. É o número que
   decide, então ele é o maior elemento do bloco. */
.vitrine .preco {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(3.4rem, 8vw, 5.4rem);
  line-height: .88;
  letter-spacing: -.05em;
  color: var(--breu);
}
.vitrine .selo-lado {
  font-family: var(--tec);
  font-size: .66rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--risco-f);
}
.vitrine h3 { font-size: clamp(1.2rem, 2.6vw, 1.5rem); margin: 0; max-width: 14em; }
.vitrine p { margin: 0; color: #3d566f; font-size: .95rem; max-width: 32ch; }
/* O diferencial de cada produto, em três linhas. É o que separa isto de um
   link: produto tem especificação, link não tem. */
.vitrine ul {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  border-top: 1px solid rgba(6,15,26,.14);
}
.vitrine li {
  display: flex;
  justify-content: space-between;
  gap: 18px;
  padding: 10px 0;
  border-bottom: 1px solid rgba(6,15,26,.09);
  font-size: .88rem;
  color: #3d566f;
}
.vitrine li b {
  font-family: var(--tec);
  font-weight: 600;
  font-size: .78rem;
  color: var(--breu);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Botão de verdade, com fundo e contraste. Era texto com seta, que em
   bloco de produto lê como link e não como ação. */
.vitrine .leva {
  margin-top: auto;
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: .8em;
  padding: 15px 26px;
  background: var(--breu);
  color: var(--giz);
  border-radius: 2px;
  font-family: var(--tec);
  font-size: .74rem;
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  transition: background .25s var(--ease), gap .25s var(--ease);
}
.vitrine a:hover .leva { background: var(--risco-f); gap: 1.3em; }

/* A etiqueta que marca o produto de entrada. Um selo só na página: dois
   selos e nenhum significa nada. */
.vitrine .etiqueta {
  position: absolute;
  top: 0; right: 0;
  padding: 8px 16px;
  background: var(--breu);
  color: var(--risco);
  font-family: var(--tec);
  font-size: .62rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
}

/* ============================================================ */
/* PRANCHA 06 · FECHO                                           */
/* Centralizada e sem grade. É a única composição que a página   */
/* ainda não tinha usado, e serve para fechar.                   */
/* ============================================================ */

.fecho-central { text-align: center; max-width: 780px; margin: 0 auto; }
.fecho-central h2 { font-size: clamp(2rem, 6vw, 3.6rem); margin-bottom: .5em; }
.fecho-central .canal { margin: 34px auto 0; }
.fecho-central .selo { text-align: left; margin-top: 64px; }

/* ------------------------------------------------------------ */
/* Canal                                                         */
/* ------------------------------------------------------------ */

/* O @ tem 27 caracteres em mono. Em linha única, dentro de uma caixa com
   rótulo do lado, ele estourava a borda direita no celular e o fim do
   nome era cortado. Agora o rótulo e o @ podem quebrar em duas linhas, e
   o corpo do @ acompanha a largura da tela. */
.canal {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 6px 16px;
  max-width: 100%;
  padding: 22px 26px;
  border: 1px solid var(--fio);
  text-decoration: none;
  color: var(--giz);
  transition: border-color .3s var(--ease), background .3s var(--ease);
}
.canal-arroba {
  font-family: var(--tec);
  font-size: clamp(.78rem, 3.2vw, .95rem);
  overflow-wrap: anywhere;
}
.canal:hover { border-color: var(--risco); background: var(--chapa); color: var(--giz); }
.canal .tec { transition: color .3s var(--ease); }
.canal:hover .tec { color: var(--risco); }

/* ------------------------------------------------------------ */
/* Faixa de números, sangria total                               */
/*                                                               */
/* A página inteira vivia dentro de um container de 1420px, e em */
/* monitor de 1920 sobravam 500px de nada dos dois lados, 26% da */
/* tela. Esta faixa é a primeira coisa que atravessa de ponta a  */
/* ponta, e ela vem logo depois da dobra de propósito: é onde as */
/* credenciais param de ser prosa e viram número.                */
/* ------------------------------------------------------------ */
.faixa-numeros {
  position: relative;
  z-index: 3;
  background: var(--risco);
  color: var(--breu);
  padding: 24px 0;
}
.faixa-numeros ul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 14px 0;
  margin: 0;
  padding: 0;
}
.faixa-numeros li {
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 2px clamp(16px, 2.8vw, 42px);
}
/* Fio separando, e só entre os itens. Some quando a linha quebra
   porque aí ele viraria um traço solto no começo da segunda linha. */
@media (min-width: 720px) { .faixa-numeros li + li { border-left: 1px solid rgba(6, 15, 26, .28); } }
/* Abaixo de 720px os quatro não cabem numa linha e quebravam em 3, com a
   última sozinha. Grade 2 por 2: duas linhas iguais, sem órfã. */
@media (max-width: 719px) {
  .faixa-numeros ul { display: grid; grid-template-columns: 1fr 1fr; gap: 18px 0; }
  .faixa-numeros li { flex-direction: column; align-items: center; gap: 3px; text-align: center; padding: 0 8px; }
  .faixa-numeros li:nth-child(2n) { border-left: 1px solid rgba(6, 15, 26, .28); }
}
.faixa-numeros b {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(1.45rem, 3.3vw, 2.35rem);
  line-height: 1;
  letter-spacing: -.035em;
}
.faixa-numeros span {
  font-family: var(--tec);
  font-size: .74rem;
  font-weight: 500;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: rgba(6, 15, 26, .74);
}

/* ------------------------------------------------------------ */
/* Faixa de fala, sangria total                                  */
/*                                                               */
/* A segunda das três sangrias que o plano prometia. A frase de   */
/* didática estava presa dentro da prancha 03, do tamanho de um  */
/* parágrafo qualquer. Ela é a única frase do site que é posição */
/* e não informação, então ela sai da coluna e vira faixa.        */
/* ------------------------------------------------------------ */
.faixa-fala {
  position: relative;
  z-index: 2;
  background: var(--chapa);
  border-top: 1px solid var(--risco-f);
  border-bottom: 1px solid var(--risco-f);
  padding: clamp(52px, 7vw, 88px) 0;
  margin: 0;
  overflow: hidden;
}
/* Aspas em corpo absurdo, cortadas pela borda. É o único ornamento
   tipográfico do site e ele existe para a faixa não ser um retângulo
   com texto dentro. */
.faixa-fala::before {
  content: '\201C';
  position: absolute;
  left: 2vw;
  top: -.16em;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(14rem, 26vw, 30rem);
  line-height: .8;
  color: var(--risco);
  opacity: .07;
  pointer-events: none;
}
.faixa-fala .env { position: relative; z-index: 1; }
.faixa-fala p {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.6rem, 4.2vw, 3.1rem);
  line-height: 1.1;
  letter-spacing: -.025em;
  color: var(--giz);
  max-width: 22em;
  margin: 0;
}
.faixa-fala em { font-style: normal; color: var(--risco); }
.faixa-fala footer {
  margin-top: 22px;
  font-family: var(--tec);
  font-size: .74rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--giz3);
}

/* A virada. Faixa de sangria total com a foto colada na borda esquerda e
   a história do lado. É a batida que faltava na narrativa de autoridade:
   sem ela ele é um professor com muitos anos, com ela ele é um professor
   que descobriu alguma coisa. */
/* O fundo da seção segue o gradiente da própria foto.

   Medi a rogerio-perfil.jpg pixel a pixel: o fundo dela vai de #010206 na
   borda esquerda a #02050e atrás da cabeça, à direita. É praticamente
   preto. A faixa estava chapada em --chapa2, #12233a, que é 33 pontos de
   azul mais clara: a foto quase preta encostava num campo bem mais claro e
   a emenda entre as duas era uma linha vertical visível. Era esse o defeito
   relatado, e ele não estava na máscara, estava na cor de trás.

   Agora o campo começa em #04070c à esquerda, fica quase preto até 32%, que
   é onde a foto termina no desktop, e só então abre para --chapa2 e fecha
   em --breu. É o clarão de trás da cabeça continuando para dentro da
   página em vez de parar na borda da imagem.

   As bordas de 1px saíram junto: elas eram exatamente o retângulo que este
   ajuste existe para dissolver. */
.faixa-virada {
  position: relative;
  /* 3 e não 2. A .faixa-fala logo abaixo também é 2, e com empate quem
     vence é quem vem depois no HTML: a faixa de baixo passaria por cima da
     invasão em vez de receber ela. */
  z-index: 3;
  background: linear-gradient(to right,
    #04070c 0%,
    #05090f 32%,
    var(--chapa2) 68%,
    var(--breu) 100%);
  overflow: hidden;

  /* A invasão. 48px de margem negativa em cima e embaixo, e é margem
     VERTICAL de propósito: no eixo horizontal a faixa já é de sangria
     total e margem negativa ali seria a única das duas capaz de criar
     barra de rolagem, sem ganhar nada em troca.

     Margem negativa sozinha não bastava: ela só MUDA DE LUGAR a linha
     onde o fundo troca de cor, não apaga a linha. Por isso a máscara
     abaixo dissolve os mesmos 48px nas duas pontas. Uma faz a faixa
     avançar, a outra faz o avanço não ter aresta. */
  margin-top: -48px;
  margin-bottom: -48px;
  -webkit-mask-image: linear-gradient(to bottom,
    transparent 0, #000 48px, #000 calc(100% - 48px), transparent 100%);
  mask-image: linear-gradient(to bottom,
    transparent 0, #000 48px, #000 calc(100% - 48px), transparent 100%);
}
.faixa-virada-grade { display: grid; align-items: center; }
@media (min-width: 900px) { .faixa-virada-grade { grid-template-columns: 40% 1fr; } }
/* A foto encosta na borda esquerda da janela, fora do container. É o que
   faz a faixa ler como faixa e não como cartão largo. */
.faixa-virada figure { margin: 0; position: relative; }
.faixa-virada img {
  display: block;
  width: 100%;
  height: 100%;
  max-height: 560px;
  object-fit: cover;
  object-position: 50% 22%;
  /* O corte saiu de 62% e virou uma curva de quatro paradas.

     Medi a silhueta: a nuca dele termina em 76% da largura da imagem, e
     tudo à direita disso é fundo. Cortando em 62% a máscara já comia a
     cabeça: em 76% a opacidade estava em 63%, e a nuca desbotava contra o
     campo. Agora em 76% ela está em 91% e o desbotamento inteiro acontece
     nos 24% de fundo puro que sobram.

     Três paradas em vez de uma reta porque reta tem cotovelo: no ponto onde
     ela começa, a taxa de queda muda de zero para constante de uma vez, e é
     esse cotovelo que o olho lê como borda. */
  -webkit-mask-image: linear-gradient(to right,
    #000 0%, #000 70%, rgba(0, 0, 0, .82) 82%, rgba(0, 0, 0, .34) 92%, transparent 100%);
  mask-image: linear-gradient(to right,
    #000 0%, #000 70%, rgba(0, 0, 0, .82) 82%, rgba(0, 0, 0, .34) 92%, transparent 100%);
}
/* No celular a faixa empilha, e aí a máscara da direita não serve para
   nada: quem entra por aquele lado é o texto, e no empilhado o texto entra
   por BAIXO. Sem trocar o eixo, a foto terminava num corte reto e o olho
   lia uma linha horizontal atravessando a seção.

   As paradas são as mesmas do desktop, só que no eixo vertical, e o
   desbotamento começa em 70% porque abaixo disso já é ombro e paletó. */
@media (max-width: 899px) {
  .faixa-virada img {
    max-height: 300px;
    object-position: 50% 18%;
    -webkit-mask-image: linear-gradient(to bottom,
      #000 0%, #000 70%, rgba(0, 0, 0, .82) 82%, rgba(0, 0, 0, .34) 92%, transparent 100%);
    mask-image: linear-gradient(to bottom,
      #000 0%, #000 70%, rgba(0, 0, 0, .82) 82%, rgba(0, 0, 0, .34) 92%, transparent 100%);
  }
}
/* Os respiros subiram porque a máscara da faixa dissolve 48px em cada
   ponta: texto dentro dessa faixa sairia desbotado. O piso passa a ser
   64px, 16 a mais que a dissolução, e no celular a base vai a 72 porque é
   ali que a assinatura termina. */
.faixa-virada-texto { padding: clamp(64px, 6vw, 88px) 24px clamp(64px, 6vw, 88px) 0; }
@media (max-width: 899px) { .faixa-virada-texto { padding: 62px 24px 72px; } }
.faixa-virada blockquote {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.3rem, 2.6vw, 2rem);
  line-height: 1.16;
  letter-spacing: -.02em;
  color: var(--giz);
  max-width: 22em;
}
.faixa-virada blockquote em { font-style: normal; color: var(--risco); }
.faixa-virada figcaption,
.faixa-virada .assina {
  margin-top: 20px;
  font-family: var(--tec);
  font-size: .74rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--giz3);
}

/* A silhueta contra a luz, na faixa clara da recusa.

   NAO usar float aqui. A primeira versão flutuava a figura à direita, e
   float ao lado de uma grade não empurra o conteúdo: encolhe a caixa da
   grade inteira. As três recusas caíram para 220px de coluna e a lista
   perdeu 363px de largura. Foi isso que quebrou a prancha.

   A figura agora divide a PRIMEIRA linha com o título, e as três recusas
   ficam embaixo ocupando a largura toda. */
.recusa-topo { display: grid; gap: 24px; align-items: end; margin-bottom: 8px; }
@media (min-width: 900px) { .recusa-topo { grid-template-columns: 1fr 290px; gap: 0 48px; } }
.recusa-figura { margin: 0; align-self: end; }
.recusa-figura img {
  display: block;
  width: 100%;
  -webkit-mask-image: linear-gradient(to bottom, #000 74%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 74%, transparent 100%);
}
@media (max-width: 899px) { .recusa-figura { display: none; } }

/* A terceira sangria: a recusa, em fundo claro.

   É a única inversão de cor da página fora da prancha de materiais, e
   ela existe para parar o olho. Anti-posicionamento é o atalho mais
   rápido para credibilidade porque ninguém que está vendendo abre mão
   de nada. */
.faixa-recusa {
  position: relative;
  z-index: 2;
  background: var(--giz);
  color: var(--breu);
  padding: clamp(54px, 7vw, 92px) 0;
  border-top: 3px solid var(--risco);
}
.faixa-recusa .tec { color: var(--risco-f); }
.faixa-recusa h2 { color: var(--breu); margin-bottom: .7em; }
.faixa-recusa ul { display: grid; gap: 0; margin: 0; padding: 0; }
@media (min-width: 900px) { .faixa-recusa ul { grid-template-columns: repeat(3, 1fr); gap: 0 34px; } }
.faixa-recusa li {
  list-style: none;
  border-top: 1px solid rgba(6, 15, 26, .16);
  padding: 20px 0 22px;
}
.faixa-recusa b {
  display: block;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.15rem, 2.2vw, 1.45rem);
  line-height: 1.14;
  margin-bottom: .45em;
}
.faixa-recusa span { display: block; color: #3d5772; font-size: .97rem; line-height: 1.45; }

/* ------------------------------------------------------------ */
/* Camadas de fundo para as pranchas do meio                     */
/*                                                               */
/* Só o herói tinha profundidade. As outras cinco eram campo     */
/* chapado, e é por isso que a página perdia força depois da     */
/* primeira tela. Estas duas camadas custam zero requisição:     */
/* a pauta é gradiente repetido, o clarão é um radial.           */
/* ------------------------------------------------------------ */
.camadas {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}
/* A pauta. Estava em 2,2% de opacidade e mascarada num elipse pequeno:
   invisível na prática. Em 4,5%, com a máscara aberta, ela vira a
   textura de folha que o resto do sistema promete. */
.camadas i {
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    to bottom, transparent 0, transparent 33px,
    rgba(103, 182, 247, .045) 33px, rgba(103, 182, 247, .045) 34px);
  -webkit-mask-image: radial-gradient(ellipse 96% 78% at 50% 46%, #000 24%, transparent 88%);
  mask-image: radial-gradient(ellipse 96% 78% at 50% 46%, #000 24%, transparent 88%);
}

/* ------------------------------------------------------------ */
/* A grade de construção                                         */
/*                                                               */
/* Isto é o que estava faltando de verdade. As laterais não      */
/* estavam vazias por falta de conteúdo, estavam vazias por      */
/* falta de ESTRUTURA: numa prancha de desenho o papel em volta  */
/* da peça não é branco, é gradeado e cotado.                    */
/*                                                               */
/* Fica no .empilha, então vale para a página inteira de uma vez */
/* só, e é toda em gradiente: zero requisição, zero elemento.    */
/* ------------------------------------------------------------ */
.empilha::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    /* verticais nas bordas do container e nos terços dele */
    linear-gradient(to right, transparent calc(50% - var(--meia)),
      rgba(103, 182, 247, .085) calc(50% - var(--meia)),
      rgba(103, 182, 247, .085) calc(50% - var(--meia) + 1px), transparent calc(50% - var(--meia) + 1px)),
    linear-gradient(to right, transparent calc(50% + var(--meia)),
      rgba(103, 182, 247, .085) calc(50% + var(--meia)),
      rgba(103, 182, 247, .085) calc(50% + var(--meia) + 1px), transparent calc(50% + var(--meia) + 1px)),
    /* grade fina de 120px, que só aparece de perto */
    repeating-linear-gradient(to right, transparent 0, transparent 119px,
      rgba(103, 182, 247, .022) 119px, rgba(103, 182, 247, .022) 120px);
}
@media (max-width: 999px) { .empilha::before { display: none; } }

/* As cruzetas de registro nas duas margens.

   Numa prancha de verdade elas servem para alinhar a folha na mesa. Aqui
   servem para o mesmo que serviam lá: dizer que aquele espaço é papel, e
   não buraco. Ficam exatamente onde estava o vazio.

   O ladrilho é um SVG de 16 por 260: a cruzeta ocupa os 16px de cima e o
   resto é o intervalo, então repeat-y desenha uma a cada 260px. Vai como
   data URI, que o CSP já libera em img-src. */
.empilha::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='260'%3E%3Cpath d='M8 1v14M1 8h14' stroke='%232c5f8a' stroke-width='1'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='260'%3E%3Cpath d='M8 1v14M1 8h14' stroke='%232c5f8a' stroke-width='1'/%3E%3C/svg%3E");
  background-repeat: repeat-y, repeat-y;
  background-position:
    calc(50% - var(--meia) - 38px) 150px,
    calc(50% + var(--meia) + 22px) 280px;
  opacity: .6;
}
@media (max-width: 999px) { .empilha::after { display: none; } }
/* O clarão vai para o lado onde está a figura da prancha, então
   ele é posicionável em vez de fixo no centro. */
.camadas u {
  position: absolute;
  top: 22%;
  left: var(--clarao-x, 50%);
  width: 46vw;
  aspect-ratio: 1;
  transform: translate(-50%, -22%);
  background: radial-gradient(circle, rgba(103, 182, 247, .09) 0%, transparent 64%);
}

/* ------------------------------------------------------------ */
/* Chamadas apontando para dentro da foto                        */
/*                                                               */
/* Não é importado de referência nenhuma: prancha de desenho     */
/* técnico vive de cota apontando para a peça, e o site já tinha */
/* a classe .cota usada uma vez só e escondida. Aqui a linha sai */
/* de um ponto da imagem e termina num rótulo do lado de fora.   */
/*                                                               */
/* Cada chamada é posicionada por duas variáveis, --x e --y, em  */
/* porcentagem da própria foto, então mexer nelas não exige      */
/* recalcular mais nada.                                         */
/* ------------------------------------------------------------ */
.com-chamadas { position: relative; }
.chamada {
  position: absolute;
  left: var(--x);
  top: var(--y);
  z-index: 3;
  display: none;
  align-items: center;
  gap: 10px;
  pointer-events: none;
}
/* Só a partir de 900px. Em celular a foto tem 300px de largura e
   rótulo em cima dela vira sujeira, não informação. */
@media (min-width: 900px) { .chamada { display: flex; } }

/* O ponto que fica em cima da peça. */
.chamada::before {
  content: '';
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  background: var(--risco);
  transform: rotate(45deg);
  box-shadow: 0 0 0 4px rgba(103, 182, 247, .18);
}
/* A linha que liga o ponto ao rótulo. */
.chamada i {
  display: block;
  width: var(--fio-len, 54px);
  height: 1px;
  background: var(--risco);
  opacity: .7;
}
.chamada b {
  font-family: var(--tec);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--giz);
  white-space: nowrap;
  background: rgba(6, 15, 26, .82);
  padding: 5px 9px;
  border: 1px solid var(--fio2);
}
/* Chamada que sai para a esquerda: inverte a ordem dos três pedaços
   e ancora pela direita, senão ela empurraria a si mesma para fora. */
.chamada-esq { flex-direction: row-reverse; left: auto; right: var(--x); }

/* ------------------------------------------------------------ */
/* A marca, solta no topo                                        */
/*                                                               */
/* Sem barra atrás. A barra existia para segurar menu e botão,   */
/* e os dois saíram: menu em página institucional de uma pessoa  */
/* só é navegação para lugar nenhum, e o botão repetia o que a   */
/* dobra já pede.                                                */
/*                                                               */
/* É absoluta e não fixa. Fixa, ela atravessaria a prancha clara */
/* mais adiante e o texto claro sumiria no papel. Absoluta, ela  */
/* sobe com a rolagem e o problema não existe.                   */
/* ------------------------------------------------------------ */
.marca-topo {
  position: absolute;
  top: 26px;
  left: 24px;
  z-index: 30;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  color: var(--giz);
}
/* 18px e não 32. O símbolo cresceu 16px e a marca cresce para BAIXO, e o
   nome dela divide a mesma coluna que a linha técnica da dobra, que começa
   em x=173. Com 32 a tinta do nome terminava em 82 e a da linha técnica
   começa em 83: um pixel entre as duas. Subindo 14px sobram 15px de tinta,
   que é a folga que existia antes de o símbolo crescer. */
@media (min-width: 1000px) { .marca-topo { left: calc(var(--rail) + 24px); top: 18px; } }

/* O símbolo. Uma prancha em miniatura: o quadrado da folha, a
   cantoneira no canto que o site inteiro usa, e o R no lugar onde vai a
   identificação do desenho.

   52px e não 36. Em 36 ele media 3,6% da altura de uma tela de 812 e
   sumia: a marca lia como o nome escrito ao lado de um selo, não como
   marca. O traço, a cantoneira e o R são medidos em unidades da viewBox
   de 40, então os três crescem junto sem uma linha a mais. */
.marca-simbolo { flex: 0 0 auto; display: block; width: 52px; height: 52px; }
.marca-simbolo .folha { fill: none; stroke: var(--fio); stroke-width: 1.5; }
.marca-simbolo .canto { fill: none; stroke: var(--risco); stroke-width: 2.5; }
.marca-simbolo .letra {
  font-family: var(--display);
  font-weight: 800;
  font-size: 23px;
  fill: var(--giz);
}
.marca-topo:hover .folha { stroke: var(--risco); }

/* O nome acompanha o símbolo pela ALTURA do bloco, não pela porcentagem.
   Em .96rem as duas linhas somavam 32px contra um símbolo de 36, 89% dele.
   Em 1.35rem somam 45px contra 52, 87%: a proporção que já estava certa
   continua igual, e o par cresce como uma peça só em vez de o nome ficar
   pequeno do lado de um selo grande. */
.marca-nome {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.35rem;
  line-height: 1.05;
  letter-spacing: -.01em;
}
/* O nome fica em duas linhas ao lado do símbolo, e não some no celular:
   símbolo mais nome dá 138px numa tela de 375, sobra folga. Marca só com
   sigla obriga a pessoa a já saber de quem é. */
.marca-nome i { display: block; font-style: normal; color: var(--risco); }

/* ------------------------------------------------------------ */
/* Selo (o bloco de identificação do rodapé de uma prancha)      */
/* ------------------------------------------------------------ */

.rodape { background: var(--chapa); border-top: 1px solid var(--fio); padding: 70px 0 0; }

.selo {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  border-top: 1px solid var(--fio);
  border-left: 1px solid var(--fio);
  margin-top: 56px;
}
@media (min-width: 720px) { .selo { grid-template-columns: repeat(4, 1fr); } }
.selo-cel {
  padding: 16px 18px;
  border-right: 1px solid var(--fio);
  border-bottom: 1px solid var(--fio);
}
.selo-cel dt { font-family: var(--tec); font-size: .58rem; letter-spacing: .16em; text-transform: uppercase; color: var(--giz3); margin-bottom: 6px; }
.selo-cel dd { margin: 0; font-family: var(--tec); font-size: .8rem; color: var(--giz2); }

/* ============================================================ */
/* PÁGINA DE VENDA                                              */
/* Componentes que só existem nas seis páginas de oferta.       */
/* ============================================================ */

/* Bizu demonstrado, de graça, dentro da página de venda.
   O mercado inteiro mostra mockup de tablet flutuando. Mostrar o produto
   funcionando é o que só quem tem produto pode fazer. */
.bizu {
  border: 1px solid var(--fio);
  border-left: 3px solid var(--risco);
  padding: 24px 26px;
  background: var(--chapa);
  margin-bottom: 14px;
}
.bizu-n {
  font-family: var(--tec);
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--risco);
  margin: 0 0 .7em;
}
.bizu h3 { margin-bottom: .45em; }
.bizu p { color: var(--giz2); font-size: .97rem; }
.bizu p:last-child { margin-bottom: 0; }

/* Par errado e certo, lado a lado. */
.par { display: grid; gap: 10px; margin: 18px 0 0; }
@media (min-width: 640px) { .par { grid-template-columns: 1fr 1fr; gap: 14px; } }
.par > div { padding: 14px 16px; border: 1px solid var(--fio2); }
.par-erro { border-left: 2px solid var(--erro) !important; }
.par-ok   { border-left: 2px solid var(--risco) !important; }
.par .tec { margin-bottom: .6em; }
.par p { margin: 0; font-size: .92rem; color: var(--giz); font-family: var(--corpo); }

/* Serve e não serve. A coluna do "não serve" custa venda de propósito:
   quem desqualifica em público ganha crédito no que qualifica. */
.serve { display: grid; gap: 28px; margin-top: 34px; }
@media (min-width: 760px) { .serve { grid-template-columns: 1fr 1fr; gap: 44px; } }
.serve ul { list-style: none; margin: 0; padding: 0; }
.serve li {
  padding: 12px 0 12px 30px;
  border-bottom: 1px solid var(--fio2);
  position: relative;
  color: var(--giz2);
  font-size: .97rem;
}
.serve li::before {
  position: absolute; left: 0; top: 12px;
  font-family: var(--tec); font-size: .9rem;
}
.serve-sim li::before { content: '+'; color: var(--risco); }
.serve-nao li::before { content: '−'; color: var(--erro); }

/* Bloco de oferta */
.oferta {
  border: 1px solid var(--risco);
  padding: 34px 30px;
  background: var(--chapa);
  max-width: 620px;
}
.oferta-linha {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  padding: 11px 0;
  border-bottom: 1px solid var(--fio2);
  font-size: .95rem;
}
.oferta-linha span:last-child { font-family: var(--tec); color: var(--giz3); white-space: nowrap; }
.oferta-preco {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(3rem, 9vw, 4.6rem);
  letter-spacing: -.05em;
  line-height: .95;
  color: var(--risco);
  margin: 26px 0 0;
}
.oferta .btn { width: 100%; margin-top: 22px; padding: 19px 26px; font-size: .82rem; }

/* Perguntas */
.faq { border-top: 1px solid var(--fio); margin-top: 34px; }
.faq details { border-bottom: 1px solid var(--fio2); }
.faq summary {
  padding: 22px 40px 22px 0;
  cursor: pointer;
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.06rem;
  letter-spacing: -.02em;
  list-style: none;
  position: relative;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '+';
  position: absolute; right: 4px; top: 22px;
  font-family: var(--tec); color: var(--risco);
  transition: transform .3s var(--ease);
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq details > div { padding: 0 0 24px; color: var(--giz2); max-width: 62ch; }

/* Fechamento binário */
.fecho { display: grid; gap: 14px; margin-top: 34px; }
@media (min-width: 700px) { .fecho { grid-template-columns: 1fr 1fr; gap: 20px; } }
.fecho > div { padding: 26px; border: 1px solid var(--fio2); }
.fecho > div:last-child { border-color: var(--risco); }
.fecho h4 { margin-bottom: .5em; }
.fecho p { margin: 0; color: var(--giz2); font-size: .95rem; }

/* ------------------------------------------------------------ */
/* QUIZ                                                          */
/* Usado por bizus-quiz.html e redacao-quiz.html.                */
/*                                                               */
/* Subiu para cá porque as duas páginas escreveram este mesmo    */
/* componente por conta e já tinham divergido: dois nomes para a */
/* barra de progresso, duas alturas de alternativa, dois jeitos  */
/* de marcar o rótulo. É exatamente assim que os dez blocos do   */
/* projeto de matemática divergiram. Componente usado por duas   */
/* páginas mora aqui, sem exceção.                               */
/* ------------------------------------------------------------ */

/* Régua de progresso. Fina de propósito: é medida, não enfeite. */
.prog { height: 2px; background: var(--fio2); margin-bottom: 26px; }
.prog > i {
  display: block; height: 100%; width: 0;
  background: var(--risco);
  transition: width .5s var(--ease);
}

/* O texto base da questão. Serifado, com fio à esquerda, como citação na
   prancha. Nunca em caixa: caixa dentro de caixa vira ruído. */
.excerto {
  margin: 0 0 24px;
  padding: 4px 0 4px 18px;
  border-left: 2px solid var(--fio);
  color: var(--giz2);
  font-size: 1rem;
  max-width: var(--leitura);
  overflow-wrap: anywhere;
}

/* Alternativa. É botão de LEITURA, não de ação: por isso serifada, caixa
   baixa e alinhada à esquerda. O .btn do sistema é mono e caixa alta, e
   alternativa em caixa alta ninguém lê.

   60px de altura mínima porque a maior parte do tráfego chega pelo webview
   do Instagram, no celular, com o polegar. */
/* O atributo hidden precisa ganhar de qualquer display do autor.

   O navegador aplica hidden por display:none na folha DELE, que perde
   para qualquer regra nossa. .quiz-ponte e display:flex e .btn-bloco e
   display:block, entao os dois ignoravam o hidden: a ponte vazia e o
   botao Proxima ficavam na tela desde a primeira pergunta, e dava para
   avancar o quiz inteiro sem responder nada. */
[hidden] { display: none !important; }

/* O alvo de foco programatico nao desenha anel.

   As telas dos funis dao focus() no titulo a cada troca, so para o leitor
   de tela anunciar a tela nova. Elemento com tabindex="-1" nao e
   alcancavel por Tab, entao nenhum usuario de teclado pousa nele por
   conta propria: o anel so aparecia como um retangulo em volta da
   manchete, que foi o que o cliente viu no print. Botao e link seguem
   com o anel deles, intocados. */
[tabindex="-1"]:focus { outline: none; }

.opcao {
  display: flex;
  gap: 14px;
  width: 100%;
  min-height: 60px;
  text-align: left;
  margin: 0 0 10px;
  padding: 16px 18px;
  background: var(--chapa);
  color: var(--giz);
  border: 1px solid var(--fio2);
  border-left: 3px solid var(--risco-f);
  border-radius: 2px;
  font-family: var(--corpo);
  font-size: 1rem;
  line-height: 1.5;
  cursor: pointer;
  overflow-wrap: anywhere;
  transition: border-left-color .25s var(--ease), background .25s var(--ease);
}
.opcao:hover:not(:disabled) { border-left-color: var(--risco); background: var(--chapa2); }
.opcao:focus-visible { outline: 2px solid var(--giz); outline-offset: 3px; }
.opcao:disabled { cursor: default; color: var(--giz3); }

/* O rótulo da alternativa. Classe explícita em vez de seletor de span:
   uma das duas páginas usava `.opcao span` e quebraria ao ganhar
   qualquer outro span dentro. */
.opcao-marca,
.opcao > span:first-child {
  font-family: var(--tec);
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--risco);
  padding-top: .2em;
  flex: 0 0 auto;
}

/* Depois da resposta: a certa em linha de construção, a marcada em
   vermelho de correção. As duas voltam a 100%, o resto some no cinza. */
.opcao-certa  { border-left-color: var(--risco) !important; color: var(--giz) !important; opacity: 1 !important; }
.opcao-errada { border-left-color: var(--erro)  !important; opacity: 1 !important; }
.opcao-certa  .opcao-marca, .opcao-certa  > span:first-child { color: var(--risco); }
.opcao-errada .opcao-marca, .opcao-errada > span:first-child { color: var(--erro); }

/* A explicação reusa o .bizu. Só o caso de erro troca a cor da lateral:
   acertar e errar precisam ler diferente. */
.bizu-erro { border-left-color: var(--erro); }
.bizu-erro .bizu-n { color: var(--erro); }

/* Medida por etapa, no resultado. */
.medida { height: 3px; max-width: 220px; margin-top: 14px; background: var(--fio2); }
.medida > i { display: block; height: 100%; background: var(--risco); }
.medida-fraca > i { background: var(--erro); }

/* Barra fixa de compra, só no mobile. No desktop o botão do topo basta. */
.barra {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  background: rgba(6, 15, 26, .94);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--fio);
  transform: translateY(110%);
  transition: transform .4s var(--ease);
}
.barra.visivel { transform: none; }
.barra .btn { flex: 1; }
@media (min-width: 900px) { .barra { display: none; } }
/* Havia aqui um .barra-sempre, que soltava a barra fixa também no
   desktop. Existia por um motivo que deixou de valer: a página dos bizus
   tinha tirado o topo fixo e ficava sem botão nenhum depois da dobra.
   Hoje ela tem preço e botão na primeira dobra, a barra saiu, e a regra
   ficou sem nenhum usuário. Removida em vez de deixada como CSS morto. */

/* ------------------------------------------------------------ */
/* QUIZ EM TELAS                                                 */
/*                                                               */
/* Tudo aqui leva prefixo quiz-. O prefixo não é enfeite: o      */
/* bloco QUIZ acima já é compartilhado por duas páginas, e sem   */
/* separação a terceira página que precisar de um "selo" ou de   */
/* um "passo" ia achar que estes nomes são do sistema e         */
/* herdar decisões que só valem para uma isca de tela cheia.     */
/*                                                               */
/* Por que tela e não rolagem. A versão anterior da isca abria   */
/* as seções com .oculto e rolava até elas. Duas coisas          */
/* quebravam: a barra de rolagem encolhia a cada resposta e      */
/* entregava que faltava página, e no celular a pergunta         */
/* anterior continuava visível acima da atual, então a pessoa    */
/* relia a resposta que já tinha dado em vez de olhar a nova.    */
/* Aqui existe uma tela por vez e o resto não está na página.    */
/* ------------------------------------------------------------ */

/* A troca de tela. display none e não visibility: elemento escondido por
   visibility continua ocupando altura, e a página ficava com 5 telas de
   espaço em branco embaixo da ativa. */
.quiz-tela { display: none; }
/* SEM fill-mode "both" nas tres animacoes de entrada abaixo.

   As tres tem so um bloco from, com opacity 0. Com "both" o elemento
   fica preso nesse from ate a animacao rodar, e se ela nao rodar o
   conteudo nunca aparece. Sem fill-mode o estado parado e o normal,
   visivel, e a animacao so interpola enquanto roda. O destino ja e o
   estilo natural do elemento, entao nada se perde.

   Isso nao e hipotese: e o mesmo defeito que deixou 16 blocos
   invisiveis na pagina inicial deste projeto. */
.quiz-tela-ativa { display: block; animation: quiz-entra .42s var(--ease); }
@keyframes quiz-entra { from { opacity: 0; transform: translateY(14px); } }

/* Tela travada na altura da janela.

   svh e não vh, com vh de piso para quem não conhece a unidade. No Safari
   do iPhone o vh conta a tela com a barra de endereço recolhida, e a
   última alternativa da pergunta ficava escondida atrás dela justamente
   no aparelho de onde vem a maior parte do tráfego. */
.quiz-palco {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* Os 84px de respiro da .prancha valem numa página que rola, onde eles
     separam uma seção da outra. Aqui não existe seção seguinte, e os 168
     px somados empurravam a quarta alternativa para fora da tela em
     375x812, que é o aparelho mais comum do tráfego. Medido: 868px de
     conteúdo contra 812 de janela antes de cortar, 796 depois. */
  padding: 48px 0;
}

/* Botão que é <button> e não <a>. Iniciar o teste não leva a lugar
   nenhum, então âncora com href falso seria mentira para o leitor de
   tela. O .btn-bloco foi escrito para <a> e não traz cursor nem reset de
   aparência, que é o que esta classe completa. */
.quiz-botao {
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
  line-height: 1.2;
}

/* ---------- O 5 e o 3 da primeira tela ---------- */

/* Os dois algarismos em corpo gigante ao lado da frase.

   O 5 é só contorno e o 3 é cheio. A pessoa vê três de cinco antes de
   ler qualquer palavra, que é exatamente o que a frase diz.

   Foram três tentativas. A primeira era os dois números em azul cheio, e
   dois números iguais lado a lado não dizem nada sozinhos. A segunda era
   um 5 com três traços acesos dentro dele, que virou desenho e exigia
   legenda. Contorno contra cheio resolve sem nenhum texto de apoio. */
.quiz-sabia {
  display: grid;
  gap: 16px 28px;
  align-items: center;
  max-width: 760px;
  margin: 34px auto 0;
  padding: 26px 0 0;
  border-top: 1px solid var(--fio);
  /* A dobra é centralizada pelo .heroi-centro. Texto de citação
     centralizado ninguém lê, então o bloco volta para a esquerda e é a
     margem automática que o mantém no eixo. Mesma solução da .entrega. */
  text-align: left;
}
@media (min-width: 760px) { .quiz-sabia { grid-template-columns: auto 1fr; } }

.quiz-cifras { display: flex; align-items: flex-end; gap: 12px; }
.quiz-cifra {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(3.4rem, 12vw, 6rem);
  line-height: .76;
  letter-spacing: -.05em;
  color: transparent;
  -webkit-text-stroke: 2px var(--risco-f);
}
.quiz-cifra-cheia { color: var(--risco); -webkit-text-stroke: 0; }

.quiz-sabia-fala {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.2rem, 2.5vw, 1.66rem);
  line-height: 1.2;
  letter-spacing: -.02em;
  color: var(--giz);
}
.quiz-sabia-fala b { color: var(--risco); font-weight: 700; }

/* ---------- Cabeça do quiz: régua, contador e selo ---------- */

/* flex-start e não center: a .prog carrega 26px de margem embaixo, e
   centralizar empurrava o selo 13px para baixo do contador. */
.quiz-topo { display: flex; align-items: flex-start; gap: 20px; }
.quiz-marcha { flex: 1 1 auto; min-width: 0; }

/* O selo que enche.

   É um anel em conic-gradient preso a --enche, que o JavaScript escreve
   de 0 a 1. Anel e não uma segunda barra: a régua linear já está do lado
   dele, e é a diferença entre as duas formas que faz o par ler como
   instrumento de medida em vez de dois enfeites iguais. */
@property --enche {
  syntax: '<number>';
  inherits: false;
  initial-value: 0;
}
.quiz-selo {
  --enche: 0;
  flex: 0 0 auto;
  position: relative;
  width: 58px;
  height: 58px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: conic-gradient(var(--risco) calc(var(--enche) * 360deg), var(--fio2) 0);
  /* Sem @property o navegador não sabe interpolar um número dentro de um
     gradiente, e a transição é ignorada em silêncio: o anel salta de uma
     fatia para a outra. Salto é aceitável, o anel continua medindo. */
  transition: --enche .55s var(--ease);
}
.quiz-selo::before {
  content: '';
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  background: var(--breu);
}
.quiz-selo-n {
  position: relative;
  font-family: var(--tec);
  font-size: .78rem;
  font-weight: 600;
  color: var(--risco);
}

/* ---------- Uma pergunta por vez ---------- */

/* translateY e nunca translateX. A primeira versão entrava pela direita,
   e durante os 380ms da transição o passo empurrava a página para fora
   em 18px: em 375px isso é barra de rolagem horizontal piscando a cada
   resposta. O .empilha corta o vazamento, mas contar com o clip do pai
   para consertar a própria animação é dívida. */
.quiz-passo { display: none; }
.quiz-passo-ativo { display: block; animation: quiz-passa .38s var(--ease); }
@keyframes quiz-passa { from { opacity: 0; transform: translateY(16px); } }

/* A alternativa marcada, e as outras três.

   As classes .opcao-certa e .opcao-errada do bloco QUIZ ficam de fora
   desta página. Elas pintam de azul e de vermelho, e aqui não existe
   acerto: a pergunta é sobre como você resolve a prova. Pintar de
   vermelho um jeito de estudar culpa a pessoa antes de ela ver o
   diagnóstico, e a postura do projeto é culpar o método.

   O seletor é composto, .opcao.quiz-escolhida, e não .quiz-escolhida
   sozinho. Precisa empatar em especificidade com o .opcao:disabled do
   bloco acima, que pinta o texto de --giz3: sem o empate, a alternativa
   marcada apagava junto com as outras três e a pessoa perdia de vista o
   que ela mesma tinha acabado de escolher. */
.opcao.quiz-escolhida {
  border-left-color: var(--risco);
  background: var(--chapa2);
  color: var(--giz);
}
.quiz-apagada { opacity: .45; }

/* A ponte para o bizu numerado.

   Linha e não cartão. Como cartão, ela competia com a alternativa que a
   pessoa acabou de marcar: os dois blocos tinham o mesmo peso e o olho ia
   para o de baixo, então a pessoa lia a explicação sem nunca olhar a
   própria escolha acesa. */
.quiz-ponte {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  max-width: var(--leitura);
  margin-top: 22px;
  padding: 14px 16px;
  background: var(--chapa);
  border-left: 2px solid var(--risco);
  animation: quiz-entra .4s var(--ease);
}
.quiz-ponte-n {
  flex: 0 0 auto;
  padding-top: .3em;
  font-family: var(--tec);
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--risco);
}
.quiz-ponte p { margin: 0; font-size: .97rem; color: var(--giz2); }

/* ---------- Tela de cálculo ---------- */

/* As linhas de status entram uma a uma. O cálculo acontece de verdade e
   leva menos de um milissegundo: o que está encenado é a espera, e ela
   existe porque resultado instantâneo depois de 8 respostas lê como
   resultado pronto de antemão, igual para todo mundo. */
.quiz-status { list-style: none; max-width: 560px; margin: 30px 0 0; padding: 0; }
.quiz-status li {
  display: flex;
  gap: 12px;
  align-items: baseline;
  padding: 12px 0;
  border-bottom: 1px solid var(--fio2);
  font-family: var(--tec);
  font-size: .78rem;
  line-height: 1.5;
  color: var(--giz3);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .32s var(--ease), transform .32s var(--ease), color .32s var(--ease);
}
.quiz-status li::before { content: '+'; color: var(--risco-f); }
.quiz-status li.quiz-status-visivel { opacity: 1; transform: none; color: var(--giz2); }
.quiz-status li.quiz-status-visivel::before { color: var(--risco); }

/* ---------- Email e telefone ---------- */

.quiz-forma { max-width: 470px; margin-top: 30px; }
.quiz-campo { display: block; margin-bottom: 16px; }
.quiz-campo > span {
  display: block;
  margin-bottom: 8px;
  font-family: var(--tec);
  font-size: .7rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--giz3);
}
/* 54px de altura mínima pelo mesmo motivo da .opcao: polegar em webview
   de Instagram é a mão que preenche este formulário. */
.quiz-campo input {
  width: 100%;
  min-height: 54px;
  padding: 15px 16px;
  background: var(--chapa);
  color: var(--giz);
  border: 1px solid var(--fio2);
  border-left: 3px solid var(--risco-f);
  border-radius: 2px;
  font-family: var(--corpo);
  font-size: 1rem;
}
.quiz-campo input:focus {
  outline: 2px solid var(--giz);
  outline-offset: 2px;
  border-left-color: var(--risco);
}
/* :user-invalid e não :invalid. O :invalid pinta o campo de vermelho no
   primeiro caractere digitado, quando o email ainda está pela metade e a
   pessoa não errou nada. */
.quiz-campo input:user-invalid { border-left-color: var(--erro); }

.quiz-aviso {
  margin-top: 14px;
  font-family: var(--tec);
  font-size: .72rem;
  line-height: 1.55;
  color: var(--giz3);
}
.quiz-aviso-erro { color: var(--erro); }

/* ---------- Diagnóstico ---------- */

.quiz-nivel { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 14px; }
.quiz-nivel-n {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(3.2rem, 12vw, 5.2rem);
  line-height: .85;
  letter-spacing: -.05em;
  color: var(--risco);
}
.quiz-nivel-de { font-family: var(--tec); font-size: .8rem; color: var(--giz3); }

/* O carimbo de desbloqueado. Entra grande e assenta, que é o movimento
   de um carimbo de verdade. Fica torto em 3 graus de propósito: carimbo
   no eixo perfeito lê como etiqueta impressa junto com a página, e a
   página inteira é uma prancha, onde nada é impresso torto sem querer. */
.quiz-carimbo {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 22px;
  padding: 9px 16px;
  border: 1px solid var(--risco);
  color: var(--risco);
  font-family: var(--tec);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  opacity: 0;
  transform: scale(1.6) rotate(-8deg);
}
.quiz-carimbo-visivel { animation: quiz-carimba .5s var(--ease) forwards; }
@keyframes quiz-carimba { to { opacity: 1; transform: scale(1) rotate(-3deg); } }

/* O pulso do botão de desbloquear. É o único elemento que se mexe
   sozinho depois da primeira tela, e ele está sozinho na tela: qualquer
   coisa ao lado dividiria o clique.

   A animação sobrescreve o translateY do :hover do .btn-bloco enquanto
   roda. Aceito: o pulso já entrega o retorno que o hover daria, e hover
   não existe no aparelho de onde vem o tráfego. */
.quiz-pulso { animation: quiz-pulsa 2.4s var(--ease) infinite; }
@keyframes quiz-pulsa {
  0%, 100% { transform: none; box-shadow: 0 14px 34px rgba(0, 0, 0, .45); }
  50% { transform: translateY(-3px); box-shadow: 0 24px 50px rgba(103, 182, 247, .3); }
}

/* ---------- A conta da solução ---------- */

.quiz-conta { max-width: var(--leitura); margin-top: 26px; border-top: 1px solid var(--fio); }
.quiz-conta > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
  padding: 13px 0;
  border-bottom: 1px solid var(--fio2);
  font-family: var(--tec);
  font-size: .78rem;
  line-height: 1.4;
  color: var(--giz2);
}
.quiz-conta b {
  flex: 0 0 auto;
  font-family: var(--display);
  font-size: 1.16rem;
  font-weight: 800;
  letter-spacing: -.02em;
  color: var(--giz);
  text-align: right;
}
/* Vermelho só no número que é custo. O sistema reserva o --erro para o
   que está errado, e questão perdida é exatamente isso. */
.quiz-conta-alta b { color: var(--erro); }

/* A lista dos padrões que pegam a pessoa. Grade de duas colunas com o
   número do bizu na estreita, igual à .posicao, mas com o nome e a dor
   na mesma célula: aqui a linha precisa ser lida inteira de uma vez. */
.quiz-pegou {
  list-style: none;
  max-width: var(--leitura);
  margin: 24px 0 0;
  padding: 0;
  border-top: 1px solid var(--fio);
}
.quiz-pegou li {
  display: grid;
  grid-template-columns: 62px 1fr;
  gap: 0 16px;
  align-items: start;
  padding: 16px 0;
  border-bottom: 1px solid var(--fio2);
}
.quiz-pegou-n {
  padding-top: .3em;
  font-family: var(--tec);
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .12em;
  color: var(--risco);
}
.quiz-pegou b {
  display: block;
  font-family: var(--display);
  font-size: 1.06rem;
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--giz);
}
.quiz-pegou span {
  display: block;
  margin-top: 4px;
  font-size: .93rem;
  line-height: 1.45;
  color: var(--giz2);
}
/* O dominante ganha o fio vermelho na borda, e é o único da lista que
   tem. Ordenar por gravidade sem marcar o primeiro não adianta: ninguém
   sabe que a lista está ordenada. */
.quiz-pegou-forte { border-left: 2px solid var(--erro); padding-left: 14px; }

@media (prefers-reduced-motion: reduce) {
  .quiz-tela-ativa, .quiz-passo-ativo, .quiz-ponte, .quiz-pulso { animation: none; }
  .quiz-status li { transition: none; }
  /* O carimbo nasce em opacity 0 e só a animação o traz. Sem estas duas
     linhas, quem pede menos movimento clica em desbloquear e não vê
     carimbo nenhum. */
  .quiz-carimbo-visivel { animation: none; opacity: 1; transform: rotate(-3deg); }
}

/* ------------------------------------------------------------ */
/* Utilidades                                                    */
/* ------------------------------------------------------------ */

.mt-p { margin-top: 12px; }
.mt-m { margin-top: 28px; }
.mt-g { margin-top: 52px; }
.oculto { display: none !important; }

/* Fora da primeira dobra, o navegador só desenha o que entra na tela.
   Uma linha, e ela é o que segura a rolagem lisa em celular fraco agora
   que existe perspectiva e paralaxe. */
@media (max-width: 899px) {
  .prancha, .rodape { content-visibility: auto; contain-intrinsic-size: auto 700px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-delay: 0ms !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .entra, .sobe { opacity: 1 !important; transform: none !important; }
  .grifo::after, .prancha-topo::before, .heroi-regua { transform: scaleX(1) !important; }
  .marco { transform: none !important; opacity: 1 !important; }
  .heroi-texto, .heroi-retrato, .heroi-fundo b { transform: none !important; opacity: 1 !important; }
}

/* ------------------------------------------------------------ */
/* TELA TRAVADA                                                  */
/*                                                               */
/* A página inteira dentro da altura da janela, sem barra de     */
/* rolagem vertical. Vale só onde a classe .quiz-trava está no   */
/* <html>, e hoje isso é uma página só, a bizus-quiz.html.       */
/* Nenhuma outra página muda por causa deste bloco.              */
/*                                                               */
/* Por que a trava está no <html> E no <body>: overflow só no    */
/* body não segura nada. Quando o html não declara overflow, o   */
/* navegador PROPAGA a rolagem do body para o viewport e a barra */
/* continua lá. Travar os dois é o que faz o                     */
/* document.documentElement.scrollHeight parar de crescer.       */
/*                                                               */
/* A regra da rolagem, e ela não tem exceção: a PÁGINA nunca     */
/* rola. Se um painel não couber na janela, quem rola é o        */
/* painel, por dentro, e para isso ele precisa ter .quiz-palco   */
/* ou .quiz-rolo. Hoje só a tela da conta final usa .quiz-rolo:  */
/* lista de até nove armadilhas mais oferta mais preço não cabe  */
/* em 812px de altura, e cortar a lista seria esconder metade do */
/* diagnóstico.                                                  */
/* ------------------------------------------------------------ */

html.quiz-trava,
html.quiz-trava body {
  height: 100%;
  max-height: 100%;
  overflow: hidden;
  /* Sem esta linha o celular ainda arrasta a página inteira e mostra a
     faixa de fundo do navegador, mesmo com overflow hidden. */
  overscroll-behavior: none;
}

.quiz-trava .empilha { height: 100%; }

/* A tela ativa vira a coluna que ocupa a janela: a faixa em cima com a
   altura dela, o painel embaixo com tudo que sobrar. */
.quiz-trava .quiz-tela-ativa {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.quiz-trava .quiz-tela-ativa > .faixa { flex: 0 0 auto; }

/* min-height: 0 é a linha que faz a trava funcionar, e é a primeira que
   alguém apaga por parecer inútil. Item de flex não encolhe abaixo do
   próprio conteúdo por padrão: sem ela o painel cresce, empurra a
   coluna para fora da janela e a barra de rolagem volta pela porta dos
   fundos, sem erro nenhum no console. */
.quiz-trava .quiz-tela-ativa > .prancha,
.quiz-trava .quiz-tela-ativa > .heroi {
  flex: 1 1 auto;
  min-height: 0;
}

/* Os 84px de respiro da prancha separam uma seção da outra numa página
   que rola. Aqui não existe seção seguinte, e os 168px somados são a
   diferença entre caber e não caber em 375x812. */
.quiz-trava .prancha { padding: 22px 0; }

/* content-visibility: auto pula o desenho do que está fora da tela.
   Numa página travada ele não economiza nada, porque existe uma tela
   por vez e as outras estão em display none, e atrapalha a medida da
   caixa que rola por dentro. */
@media (max-width: 899px) {
  .quiz-trava .prancha { content-visibility: visible; }
}

.quiz-trava .quiz-palco {
  min-height: 0;
  padding: 22px 0;
  /* safe center: centraliza enquanto couber, e volta a alinhar pelo topo
     quando não couber. Sem o safe, conteúdo mais alto que a caixa é
     cortado pela borda DE CIMA, e a parte cortada fica inalcançável:
     flex centralizado não deixa rolar para trás do começo. Navegador
     que não conhece a palavra ignora a declaração e fica no center, que
     é o comportamento de hoje. */
  justify-content: safe center;
}

/* As duas caixas que podem rolar por dentro. overscroll-behavior:
   contain impede que o fim da rolagem interna vire rolagem da página no
   celular, que é o vazamento clássico deste padrão. */
.quiz-trava .quiz-palco,
.quiz-trava .quiz-rolo {
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
.quiz-trava .quiz-rolo { padding: 22px 0; }

/* A dobra. O min-height 100svh do bloco do herói brigava com a altura
   que o pai já travou, e o resultado era uma tela de altura dupla. */
.quiz-trava .heroi { min-height: 0; display: block; overflow-y: auto; }
.quiz-trava .heroi-grade { padding: 14px 0 0; gap: 0; }
.quiz-trava .heroi-texto { padding-bottom: 0; max-width: 1240px; }

/* A manchete cai de 4.5rem para 3.4rem no teto e de 6vw para 7.4vw no
   meio da escala. Medido em 375x812: com o corpo do sistema a manchete
   sozinha comia 273px de 812, e a lista do que o teste devolve ficava
   fora da janela. */
.quiz-trava .heroi h1 { font-size: clamp(1.95rem, 7.4vw, 3.4rem); }

/* ---------- Espaçamentos que saíram de style inline ---------- */

/* A linha técnica que rotula um bloco. Existe para o rótulo não
   depender de style no atributo, que é onde essas medidas estavam. */
.quiz-linha-tec { margin: 20px 0 10px; }
.heroi-texto > .quiz-linha-tec:first-child { margin: 0 0 1.4em; }
.quiz-topo .quiz-linha-tec { margin: 0 0 .9em; }

.quiz-titulo-curto { max-width: 12em; }
/* O h2 do sistema vai a 3.7rem. Nas telas de resultado o título divide
   a janela com a conta inteira, e 3.7rem sozinho tomava um terço da
   altura útil. */
.quiz-titulo-medio { font-size: clamp(1.6rem, 3.6vw, 2.5rem); max-width: 17em; }

.quiz-pergunta { font-size: clamp(1.28rem, 4.4vw, 1.95rem); margin-bottom: .5em; }
.quiz-alternativas { margin-top: 20px; max-width: var(--leitura); }
.quiz-conta-leitura { margin-top: 1.3em; }
.quiz-entrega-esq { margin-left: 0; }
.quiz-carimbo-centro { text-align: center; }

/* ---------- As telas de mensagem do quiz ----------

   .quiz-abertura estava no HTML das quatro telas de coluna unica e nao
   existia no CSS: o texto ficava alinhado a esquerda dentro de um bloco
   de 1126px e as linhas curtas boiavam no canto. Centraliza o texto e
   segura a largura de leitura.

   Lista e formulario voltam para a esquerda por dentro: item de lista
   com texto centralizado nao tem borda de leitura, e campo de formulario
   com rotulo centralizado esconde onde comeca o campo. */
.quiz-abertura { text-align: center; }
.quiz-abertura > h1,
.quiz-abertura > h2 { margin-inline: auto; }
.quiz-abertura .entrega,
.quiz-abertura .quiz-forma { text-align: left; }
.quiz-abertura .quiz-linha-tec { text-align: center; }
.quiz-abertura .leitura { margin-inline: auto; }
.quiz-rodape-linha { margin: 40px 0 0; color: var(--giz3); }

/* ---------- Aperto fino, só na página travada ---------- */

/* A alternativa continua com alvo de dedo, 54px, que é o mínimo
   confortável em webview de Instagram. Os 60px do sistema valem numa
   página que rola: aqui os 6px vezes 4 alternativas são 24px, e 24px é
   a diferença entre a ponte caber e não caber depois da resposta. */
.quiz-trava .opcao {
  min-height: 54px;
  margin-bottom: 8px;
  padding: 13px 16px;
  font-size: .97rem;
}
.quiz-trava .quiz-ponte { margin-top: 16px; padding: 12px 15px; }
.quiz-trava .quiz-ponte p { font-size: .93rem; }
.quiz-trava .quiz-passo .mt-m { margin-top: 18px; }
.quiz-trava .quiz-status { margin-top: 22px; }
.quiz-trava .quiz-status li { padding: 10px 0; }
.quiz-trava .quiz-forma { margin-top: 22px; }
.quiz-trava .btn-bloco { margin-top: 20px; }
.quiz-trava .entrega { margin-top: 14px; }

/* A dobra travada centraliza pelo eixo vertical.

   Com display block ela ficava colada no topo e sobravam 201px de nada
   embaixo, em 375x812. Coluna de flex com safe center resolve, e o safe
   é o mesmo cuidado do .quiz-palco: se um dia o conteúdo passar da
   altura da janela, o alinhamento volta para o topo em vez de cortar a
   manchete pela borda de cima. */
.quiz-trava .heroi {
  display: flex;
  flex-direction: column;
  justify-content: safe center;
}

/* A frase do mecanismo, na dobra centralizada. O .frase do sistema tem
   max-width em em e alinhamento à esquerda por herança: sem a margem
   automática ele encosta na borda esquerda dentro de uma dobra
   centralizada. */
.quiz-frase-dobra { margin: 20px auto 0; max-width: 20em; }

/* A faixa perde 4px de respiro na página travada. Sozinhos eles não
   valem nada, mas em 375x812 a dobra fecha com 28px de folga, e 8px são
   quase um terço dessa margem. */
.quiz-trava .faixa { padding: 11px 0; }

/* ------------------------------------------------------------ */
/* CRONOGRAMA                                                    */
/*                                                               */
/* O que é só da bizus-cronograma.html. Um seletor, prefixo cron,*/
/* conferido antes de escrever: nenhuma outra página usa esta    */
/* classe, e nada acima deste ponto muda por causa dela.         */
/* ------------------------------------------------------------ */

/* A manchete do cronograma é travada pelo cliente, palavra por
   palavra, e tem 62 caracteres contra 47 da manchete do quiz.

   Com a escala travada do quiz, clamp(1.95rem, 7.4vw, 3.4rem), medi em
   375x812: a fonte dava 31,2px, a manchete ocupava 159px e a dobra
   estourava a janela em 14px, porque "pra prova de Linguagens do ENEM"
   quebrava sozinha e virava a quinta linha.

   Com esta escala a fonte dá 25,92px em 375px e 46,4px em 1280px, e a
   manchete fecha em 4 linhas nos dois tamanhos: em 1280px pelos quatro
   <span> do HTML, em 375px pela quebra natural, porque acima já existe
   a regra que devolve display inline para esses span abaixo de 700px.
   A manchete ocupa 106px em 375px, e a dobra sobra 63px em 375x812 e
   116px em 1280x800. Mexer no texto da manchete pede medir de novo.

   O seletor tem os dois níveis de propósito. A primeira versão era só
   .cron-manchete, e ela não pintou nada: .quiz-trava .heroi h1 tem
   duas classes e um elemento, e uma classe sozinha perde para isso. A
   fonte continuou em 31,2px e a medida na tela não mudou nem um pixel,
   sem erro nenhum no console. */
.heroi h1.cron-manchete,
.quiz-trava .heroi h1.cron-manchete { font-size: clamp(1.62rem, 6.05vw, 2.9rem); }

/* ------------------------------------------------------------ */
/* A tela de resultado do quiz, em duas colunas                  */
/*                                                               */
/* Ela era uma coluna so, encostada na esquerda, e num monitor   */
/* de 2000px a metade direita ficava vazia enquanto o bloco de   */
/* preco aparecia centrado la embaixo. Dois eixos de leitura na  */
/* mesma tela, e o olho nao sabe qual seguir.                    */
/*                                                               */
/* Agora sao dois blocos lado a lado com papeis opostos:         */
/* a esquerda diagnostica, a direita vende. O diagnostico ganha  */
/* mais largura porque ele tem lista; a oferta e mais estreita   */
/* porque coluna estreita empurra o olho para baixo, ate o       */
/* botao.                                                        */
/* ------------------------------------------------------------ */
.quiz-solucao { display: grid; gap: 30px; }
@media (min-width: 1000px) {
  .quiz-solucao { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: 0 clamp(40px, 5vw, 88px); }
}

/* A oferta ganha fio e recuo, para ler como bloco separado e nao como
   continuacao da lista de armadilhas. */
@media (min-width: 1000px) {
  .quiz-oferta-lado {
    border-left: 1px solid var(--fio2);
    padding-left: clamp(28px, 3.4vw, 52px);
  }
  /* Dentro da coluna estreita a lista de entregaveis nao cabe em duas
     colunas: uma so, com a promessa embaixo do entregavel. */
  .quiz-oferta-lado .entrega { grid-template-columns: 1fr; gap: 14px; margin-top: 18px; }
  /* O botao para de ter largura de dobra e passa a ocupar a coluna. */
  .quiz-oferta-lado .btn-bloco { max-width: none; }
  .quiz-oferta-lado .preco-linha { justify-content: flex-start; }
  .quiz-oferta-lado .preco-selos { justify-content: flex-start; }
  .quiz-oferta-lado .preco-selos li:not(:last-child)::after { margin: 0 11px; }
}

/* Paragrafo que so existe quando o JS escreve nele. Vazio, ele deixava um
   respiro de 1.4em no meio da coluna sem nada dentro. */
.quiz-so-vazio:empty { display: none; }


/* ============================================================ */
/* A AULA DA ENGENHARIA · redacao-aula.html                     */
/*                                                              */
/* Cinco telas, uma por vez. A pessoa nunca rola a pagina: ela  */
/* avanca. Mesma mecanica das duas iscas do R$37, com prefixo   */
/* proprio para nao amarrar as duas paginas uma na outra: se    */
/* uma mudar, a outra nao quebra junto.                         */
/*                                                              */
/* A v1 tinha sete telas e uma delas era uma redacao inteira de */
/* 30 linhas: no celular virava parede. Sairam daqui junto com  */
/* ela .aula-folha, .aula-texto, .aula-cota, .aula-trecho,      */
/* .aula-nome, .aula-faz, .aula-borrado e .aula-cadeado. Se     */
/* voltarem, voltam com a parede.                               */
/* ============================================================ */
.aula-trava, .aula-trava body { height: 100%; overflow: hidden; }

.aula-tela { display: none; }
.aula-tela-ativa { display: block; }

.aula-palco {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  position: relative;
  overflow: hidden;
  background: var(--breu);
  padding: 40px 0;
}
/* A tela que nao cabe rola POR DENTRO, nunca a pagina.
   height, NAO min-height: com min-height o elemento cresce em vez de
   rolar, e como o html esta com overflow hidden o que passa do fundo
   da tela fica inalcancavel. */
.aula-rolo {
  justify-content: flex-start;
  height: 100vh;
  height: 100svh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
/* Centraliza quando sobra espaco, encosta no topo quando falta. Margem
   auto faz as duas coisas sozinha: com espaco livre positivo ela divide
   a sobra, com espaco negativo ela vale zero. justify-content: center
   nao serve porque corta o topo e o que fica acima do zero do scroll
   nao tem como ser alcancado. */
.aula-rolo > .env { margin-block: auto; }

.aula-centro { text-align: center; }
.aula-centro .btn-bloco { margin-top: 34px; }
.aula-centro .preco-selos { justify-content: center; }
.aula-tela .btn-bloco { margin-inline: auto; }

/* ------------------------------------------------------------ */
/* A manchete palavra por palavra                                */
/*                                                              */
/* Cada palavra e um span com overflow escondido e a palavra     */
/* subindo de baixo. Mesmo mecanismo do .entra do sistema, mas   */
/* por palavra em vez de por linha.                              */
/* ------------------------------------------------------------ */
/* Treze palavras, nao seis: o tamanho caiu junto. No tamanho antigo a
   frase ocupava seis linhas no celular e virava parede.
   Sem realce de cor por dentro, a pedido do cliente: fonte, tamanho e
   cor iguais do comeco ao fim. */
.aula-h1 {
  font-size: clamp(2rem, 8.2vw, 4.6rem);
  line-height: 1.02;
  letter-spacing: -.035em;
  margin: 0;
  max-width: 15em;
  margin-inline: auto;
}
.aula-h2 em { font-style: normal; color: var(--risco); }

.aula-p {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  padding-bottom: .06em;
}
.aula-anima .aula-p { animation: sobePalavra .72s var(--ease) both; }
.aula-anima .aula-p:nth-child(1)  { animation-delay: .04s }
.aula-anima .aula-p:nth-child(2)  { animation-delay: .11s }
.aula-anima .aula-p:nth-child(3)  { animation-delay: .18s }
.aula-anima .aula-p:nth-child(4)  { animation-delay: .25s }
.aula-anima .aula-p:nth-child(5)  { animation-delay: .32s }
.aula-anima .aula-p:nth-child(6)  { animation-delay: .39s }
.aula-anima .aula-p:nth-child(7)  { animation-delay: .46s }
.aula-anima .aula-p:nth-child(8)  { animation-delay: .53s }
.aula-anima .aula-p:nth-child(9)  { animation-delay: .60s }
.aula-anima .aula-p:nth-child(10) { animation-delay: .67s }
.aula-anima .aula-p:nth-child(11) { animation-delay: .74s }
.aula-anima .aula-p:nth-child(12) { animation-delay: .81s }
.aula-anima .aula-p:nth-child(13) { animation-delay: .88s }
.aula-anima .aula-p:nth-child(14) { animation-delay: .95s }
.aula-anima .aula-p:nth-child(15) { animation-delay: 1.02s }
.aula-anima .aula-p:nth-child(n+16) { animation-delay: 1.09s }
@keyframes sobePalavra {
  from { transform: translateY(102%); opacity: 0 }
  to   { transform: none; opacity: 1 }
}
/* Sem animacao a manchete tem que nascer visivel. Palavra escondida
   esperando um efeito que nao vai rodar e texto perdido. */
@media (prefers-reduced-motion: reduce) {
  .aula-anima .aula-p { animation: none; transform: none; opacity: 1; }
}

.aula-h2 {
  font-size: clamp(1.75rem, 6vw, 3.2rem);
  line-height: 1.05;
  letter-spacing: -.03em;
  margin: 0 0 .6em;
}
.aula-h2-grande { font-size: clamp(1.9rem, 7vw, 3.9rem); line-height: .98; }

.aula-riscado { position: relative; color: var(--giz3); }
.aula-riscado::after {
  content: '';
  position: absolute;
  left: -.04em; right: -.04em; top: 52%;
  height: 4px;
  background: var(--erro);
  transform: rotate(-2deg);
}

.aula-selo { margin-bottom: 1.4em; }
.aula-sub {
  font-family: var(--corpo);
  font-size: clamp(1.02rem, 2.4vw, 1.25rem);
  color: var(--giz2);
  margin: 1.2em auto 0;
  max-width: 28em;
}
.aula-frase {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.1rem, 2.6vw, 1.55rem);
  line-height: 1.28;
  color: var(--giz);
  max-width: 25em;
  margin: 30px auto 0;
}
.aula-frase b { color: var(--risco-q); }
.aula-frase-dor { max-width: none; margin: 26px 0 0; }

/* Os dois cartoes da tela 2. Template contra estrutura movel, lado a
   lado, porque definicao por contraste dispensa paragrafo. */
.aula-cartoes { display: grid; gap: 14px; max-width: 660px; margin: 0 auto; text-align: left; }
@media (min-width: 680px) { .aula-cartoes { grid-template-columns: 1fr 1fr; } }
.aula-cartoes article {
  border: 1px solid var(--fio);
  border-top: 3px solid var(--giz3);
  background: var(--chapa);
  padding: 20px 22px;
}
.aula-cartao-forte { border-top-color: var(--risco); background: var(--chapa2); }
.aula-cartoes b {
  display: block;
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.12rem;
  color: var(--giz);
  margin-bottom: .4em;
}
.aula-cartao-forte b { color: var(--risco-q); }
.aula-cartoes span { color: var(--giz2); font-size: .94rem; line-height: 1.45; }

/* Os tres trechos. Sao a prova da pagina, e por isso ficam em fonte de
   corpo, nao de display: tem que ler como redacao de aluno. */
.aula-trios { display: grid; gap: 14px; margin: 26px auto 0; max-width: 1040px; text-align: left; }
@media (min-width: 900px) { .aula-trios { grid-template-columns: repeat(3, 1fr); } }
.aula-trios article {
  border-left: 3px solid var(--risco);
  background: var(--chapa);
  padding: 18px 20px;
}
.aula-trios .tec { margin-bottom: .8em; }
.aula-trios article > p:not(.tec) {
  font-family: var(--corpo);
  font-size: .95rem;
  line-height: 1.5;
  color: var(--giz2);
  margin: 0;
}
.aula-trios b { color: var(--risco-q); font-weight: 600; }
.aula-trios cite {
  display: block;
  font-family: var(--tec);
  font-style: normal;
  font-size: .68rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--giz3);
  margin-top: 1em;
}

/* Os quatro numeros do trabalho. */
.aula-numeros {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px 12px;
  margin: 0 auto;
  padding: 0;
  max-width: 660px;
}
@media (min-width: 760px) { .aula-numeros { grid-template-columns: repeat(4, 1fr); } }
.aula-numeros li { list-style: none; }
.aula-numeros b {
  display: block;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(2rem, 6vw, 3rem);
  line-height: 1;
  letter-spacing: -.04em;
  color: var(--risco);
}
.aula-numeros span {
  display: block;
  font-family: var(--tec);
  font-size: .7rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--giz2);
  margin-top: .5em;
}

/* As dores. Uma por linha, curtas, com marca de corte no lugar do
   marcador de lista: bolinha le como item de menu, corte le como
   problema. */
.aula-dores { margin: 0; padding: 0; display: grid; gap: 11px; }
.aula-dores li {
  list-style: none;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  color: var(--giz2);
  font-size: 1rem;
  line-height: 1.4;
}
.aula-dores li::before {
  content: '';
  flex: 0 0 auto;
  width: 11px;
  height: 2px;
  margin-top: .62em;
  background: var(--erro);
}

/* ------------------------------------------------------------ */
/* AULA · a entrada escalonada, o trilho e a troca               */
/*                                                              */
/* A reclamacao foi "faltou animacao mais complexa no botao e na */
/* pagina". O botao subiu no .btn-bloco, que e compartilhado. A  */
/* pagina ganha duas camadas de movimento: os blocos da tela     */
/* entram em cascata e a manchete se separa palavra por palavra  */
/* depois que a cascata passa.                                   */
/*                                                              */
/* .aula-passo e classe que o JS COLOCA e TIRA. Sem ela o estado */
/* e o normal, visivel. Animacao que esconde por padrao ja custou */
/* 16 blocos invisiveis na pagina inicial deste projeto.         */
/* ------------------------------------------------------------ */
.aula-passo > * { animation: aulaEntra .62s var(--ease) both; }
.aula-passo > *:nth-child(1) { animation-delay: .02s }
.aula-passo > *:nth-child(2) { animation-delay: .10s }
.aula-passo > *:nth-child(3) { animation-delay: .18s }
.aula-passo > *:nth-child(4) { animation-delay: .26s }
.aula-passo > *:nth-child(5) { animation-delay: .34s }
.aula-passo > *:nth-child(6) { animation-delay: .42s }
.aula-passo > *:nth-child(n+7) { animation-delay: .50s }
@keyframes aulaEntra {
  from { opacity: 0; transform: translateY(22px); filter: blur(6px); }
  to   { opacity: 1; transform: none; filter: none; }
}

/* O trilho. Seis tracos no rodape, o da vez aceso e alargado, os
   ja vistos em azul apagado. Fixo, porque tela que troca sem aviso
   nao deixa a pessoa medir quanto falta. */
.aula-trilho {
  position: fixed;
  z-index: 6;
  left: 0; right: 0; bottom: 0;
  display: flex;
  gap: 4px;
  padding: 0 16px 14px;
  justify-content: center;
  pointer-events: none;
}
.aula-trilho i {
  display: block;
  width: 26px;
  height: 3px;
  background: var(--fio2);
  transition: width .4s var(--ease), background .4s var(--ease);
}
.aula-trilho i.feito { background: var(--risco-f); }
.aula-trilho i.agora { width: 52px; background: var(--risco); }

/* A linha tecnica embaixo do botao da tela 1. Fecha a dobra sem
   pedir nada: e a ultima coisa lida antes do clique. */
.aula-rodape-tec {
  font-family: var(--tec);
  font-size: .72rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--giz3);
  margin: 26px 0 0;
}

/* A troca. Herda .quiz-forma do quiz para os dois funis terem o
   mesmo formulario, e so recentraliza o bloco. */
.aula-forma { max-width: 460px; margin-inline: auto; text-align: left; }

/* Os cinco entregues. Numero grande em coluna propria, porque a
   promessa da tela 1 era "cinco" e o numero e que fecha o laco. */
.aula-cinco {
  counter-reset: cinco;
  list-style: none;
  margin: 30px auto 0;
  padding: 0;
  max-width: 780px;
  display: grid;
  gap: 2px;
  text-align: left;
}
.aula-cinco li {
  counter-increment: cinco;
  display: grid;
  grid-template-columns: 46px 1fr;
  gap: 0 14px;
  align-items: start;
  padding: 16px 18px;
  background: var(--chapa);
  border-left: 3px solid var(--risco);
}
.aula-cinco li::before {
  content: counter(cinco, decimal-leading-zero);
  font-family: var(--tec);
  font-size: 1.02rem;
  font-weight: 600;
  color: var(--risco);
  line-height: 1.2;
}
.aula-cinco b {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.04rem;
  line-height: 1.2;
  color: var(--giz);
}
.aula-cinco span {
  display: block;
  grid-column: 2;
  color: var(--giz2);
  font-size: .92rem;
  line-height: 1.42;
  margin-top: .35em;
}
@media (max-width: 559px) {
  .aula-cinco li { grid-template-columns: 34px 1fr; padding: 14px 14px; }
}

.aula-entrega-topo { margin-bottom: 6px; }
.aula-centro-frase { text-align: center; margin-inline: auto; }
/* A oferta comeca depois de uma pausa larga: os cinco sao entrega,
   o que vem embaixo e venda, e a distancia entre as duas coisas
   tem que ser visivel. */
.aula-oferta { margin-top: clamp(48px, 7vw, 96px); padding-top: clamp(32px, 4vw, 56px); border-top: 1px solid var(--fio2); }

@media (prefers-reduced-motion: reduce) {
  .aula-passo > * { animation: none; }
  .aula-trilho i { transition: none; }
}
