/* ═══════════════════════════════════════════════════════════════════════════
   HERÓI 3D — estilos
   O contexto completo (por que três camadas, o que já foi tentado e rejeitado)
   está no cabeçalho de js/hero-3d.js e em docs/hero-3d.md.

   Identidade: a mesma do site. #F9F9F9 de fundo, #2846c9 da marca, #111827 de
   texto, Manrope. Nada aqui muda a identidade — só a forma de apresentá-la.
   ═══════════════════════════════════════════════════════════════════════════ */

.hero3d {
  --h3d-ground: #F9F9F9;
  --h3d-ink: #111827;
  --h3d-muted: #4A5468;
  --h3d-faint: #8A93AC;
  --h3d-brand: #2846c9;
  --h3d-rule: rgba(17, 24, 39, .12);
  --h3d-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
  /* calha lateral do herói, em um lugar só: a chamada, as legendas e o HUD
     usam a mesma, e o CTA de celular precisa cancelá-la exatamente */
  --h3d-calha: clamp(20px, 5vw, 76px);

  position: relative;
  /* A altura da seção é a DURAÇÃO da animação. Menos que isto e os atos
     ficam curtos demais para serem lidos — foi o erro repetido no protótipo. */
  height: 620vh;
}

/* ── reserva de último caso ───────────────────────────────────────────────
   A sala em arame, em CSS, no palco. É o que sobra na tela quando NADA mais
   funciona: script bloqueado, WebP não suportado, extensão barrando o
   diretório dos quadros, imagem que não chega.

   Ela é o padrão e some assim que o JS entra (`[data-js]`) — por isso não
   pisca no caminho bom nem muda o herói animado. Volta se, no fim do
   carregamento, nenhum quadro tiver sido desenhado (`[data-cena="vazia"]`).

   A alternativa seria detectar a falha em JS, mas o pior dos casos é
   justamente aquele em que o JS não roda: quem detecta tem que ser o CSS.

   O arquivo é o quadro zero da camada de linhas, que o site já carrega — nada
   novo entra por causa disto. */
.hero3d__stage {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  background:
    url("../hero/desktop/linhas/f000.webp") center / cover no-repeat,
    radial-gradient(120% 92% at 22% 44%, #FFFFFF 0%, #F4F6FB 46%, #E8EDF7 100%),
    var(--h3d-ground);
}
@media (max-width: 767px) {
  .hero3d__stage { background-image: url("../hero/mobile/linhas/f000.webp") }
}
.hero3d[data-js] .hero3d__stage { background-image: none }
/* Aqui o `background` volta INTEIRO, e não só a imagem: sem o gradiente por
   baixo, o arame ficaria sobre a cor chapada — e é justamente neste caso que
   nada mais vai pintar por cima. */
.hero3d[data-js][data-cena="vazia"] .hero3d__stage {
  background:
    url("../hero/desktop/linhas/f000.webp") center / cover no-repeat,
    radial-gradient(120% 92% at 22% 44%, #FFFFFF 0%, #F4F6FB 46%, #E8EDF7 100%),
    var(--h3d-ground);
}
@media (max-width: 767px) {
  .hero3d[data-js][data-cena="vazia"] .hero3d__stage {
    background-image:
      url("../hero/mobile/linhas/f000.webp"),
      radial-gradient(120% 92% at 22% 44%, #FFFFFF 0%, #F4F6FB 46%, #E8EDF7 100%);
  }
}
/* E o véu da chamada vale aqui também: sem quadro desenhado, o texto passa a
   morar sobre o arame. */
.hero3d[data-cena="vazia"] .hero3d__stage::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(to right,
    rgba(252, 253, 255, .93) 0%,
    rgba(252, 253, 255, .80) 30%,
    rgba(252, 253, 255, 0) 62%);
}
.hero3d[data-cena="vazia"] .hero3d__claim { z-index: 2 }

/* CAMADA 1 — campo: o fundo do primeiro ato, feito para segurar o texto */
.hero3d__ground {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 92% at 22% 44%, #FFFFFF 0%, #F4F6FB 46%, #E8EDF7 100%),
    var(--h3d-ground);
}
.hero3d__ground canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block }

/* CAMADAS 2 e 3 — linhas e sólido. `cover` porque com height:auto sobram
   tarjas brancas em cima e embaixo. */
.hero3d__layer { position: absolute; inset: 0; opacity: 0 }
.hero3d__layer canvas {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block;
}

/* véu SÓ embaixo, e só quando há legenda; nunca cobrindo a cena inteira */
.hero3d__scrim {
  position: absolute; inset: auto 0 0; height: 54%; pointer-events: none; opacity: 0;
  transition: opacity .4s ease;
  background: linear-gradient(to top,
    rgba(249, 249, 251, .94) 0%, rgba(249, 249, 251, .55) 46%, rgba(249, 249, 251, 0) 100%);
}

/* ── a chamada ───────────────────────────────────────────────────────────── */
.hero3d__claim {
  position: absolute; left: var(--h3d-calha); top: 50%; transform: translateY(-50%);
  width: min(660px, 48vw);
}
.hero3d__claim h1 {
  font-size: clamp(28px, 3.1vw, 50px); font-weight: 800; letter-spacing: -.04em;
  line-height: 1.02; margin: 0; color: var(--h3d-ink); text-wrap: balance;
}
.hero3d__sub {
  margin: 20px 0 0; width: min(420px, 34vw);
  font-size: clamp(15px, 1.35vw, 18px); line-height: 1.5;
  color: var(--h3d-muted); font-weight: 500;
}
.hero3d__cta { margin-top: 28px; display: inline-block }
/* ── aviso de animação desligada ──────────────────────────────────────────
   Uma pílula solta com "ver mesmo assim" não se lia como nada: nem como
   botão, nem como explicação. Quem chega numa página parada não sabe que ela
   deveria se mexer — então o texto vem antes do botão e diz POR QUE, e que a
   decisão foi do computador da pessoa, não do site.

   Nasce escondido no HTML: só o script o revela, e só quando a cena parou por
   preferência de movimento. */
.hero3d__aviso {
  margin-top: 26px; max-width: 420px;
  padding: 18px 20px; border-radius: 14px;
  border: 1px solid var(--h3d-rule);
  background: rgba(255, 255, 255, .86);
  backdrop-filter: blur(3px);
  box-shadow: 0 16px 34px -26px rgba(17, 24, 39, .5);
}
.hero3d__aviso[hidden] { display: none }
.hero3d__aviso-olho {
  margin: 0 0 8px; font-family: var(--h3d-mono);
  font-size: 10.5px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--h3d-brand);
}
.hero3d__aviso-texto {
  margin: 0 0 14px; font-size: 14.5px; line-height: 1.5; color: var(--h3d-muted);
}
.hero3d__aviso-texto strong { color: var(--h3d-ink); font-weight: 600 }
.hero3d__aviso-botao {
  display: inline-block; padding: 11px 20px; border-radius: 999px; border: 0;
  background: var(--h3d-brand); color: #fff; cursor: pointer;
  font-family: inherit; font-size: 14.5px; font-weight: 700; letter-spacing: -.01em;
  transition: background .2s ease, transform .2s ease;
}
.hero3d__aviso-botao:hover { background: #1e37a6; transform: translateY(-1px) }
@media (max-width: 767px) {
  .hero3d__aviso { max-width: none; margin-top: 20px; padding: 16px 18px }
}

/* ── legendas: parte da composição, não rodapé ───────────────────────────── */
.hero3d {
  /* Espaço da pílula de rolagem: 10px do rodapé + 40px dela + folga. A
     legenda e, no celular, a chamada ficam acima disso. O número foi
     escolhido para que o 8vh e o 13vh originais continuem valendo: a legenda
     só sobe em janela com menos de 700px de altura, e a chamada com menos de
     430px — e ali, sem subir, elas passariam por baixo da pílula. */
  --h3d-pilula: 56px;
  /* Quanto a barra de cookies empurra. Só no desktop com altura para isso;
     no celular e em tela baixa a pílula espera a barra fechar, porque subir a
     chamada inteira escondia o título atrás do cabeçalho. */
  --h3d-sobe: 0px;
}
@media (min-width: 901px) and (min-height: 560px) {
  .hero3d { --h3d-sobe: var(--h3d-rodape, 0px) }
}
.hero3d__caps {
  position: absolute; left: 0; right: 0; bottom: max(8vh, calc(var(--h3d-pilula) + var(--h3d-sobe)));
  display: grid; justify-items: center; pointer-events: none;
  padding-inline: var(--h3d-calha); text-align: center;
}
.hero3d__cap {
  grid-area: 1/1; opacity: 0; transform: translateY(18px);
  transition: opacity .5s ease, transform .5s ease; max-width: min(880px, 86vw);
}
.hero3d__cap.is-on { opacity: 1; transform: none }
.hero3d__cap b {
  display: block; font-size: clamp(28px, 4vw, 62px); font-weight: 800;
  letter-spacing: -.045em; line-height: 1.02; color: var(--h3d-ink); text-wrap: balance;
}
.hero3d__cap span {
  display: block; margin-top: 14px; font-size: clamp(15px, 1.5vw, 20px);
  color: var(--h3d-muted); line-height: 1.5; font-weight: 500;
  max-width: 52ch; margin-inline: auto; text-wrap: balance;
}

/* ── fecho ───────────────────────────────────────────────────────────────── */
.hero3d__closer {
  position: absolute; inset: 0; display: grid; align-content: center; justify-items: center;
  opacity: 0; pointer-events: none; text-align: center;
  /* transparente nas bordas para as partículas aparecerem em volta da marca —
     sólido aqui deixava o final chapado */
  background: radial-gradient(46% 42% at 50% 48%,
    rgba(249, 249, 251, .92) 0%, rgba(249, 249, 251, .72) 55%, rgba(249, 249, 251, .28) 100%);
}
.hero3d__closer img { width: clamp(60px, 7.5vw, 104px); height: auto; display: block }
.hero3d__closer b {
  margin-top: 18px; font-size: clamp(26px, 3vw, 40px); font-weight: 800;
  letter-spacing: -.03em; color: var(--h3d-ink);
}
.hero3d__closer p {
  margin: 14px 0 0; font-size: clamp(17px, 1.8vw, 24px); color: var(--h3d-muted);
  font-weight: 500; max-width: 22ch; line-height: 1.35;
}
.hero3d__closer .hero3d__cta { margin-top: 32px; pointer-events: auto }

/* ── orientação da rolagem ────────────────────────────────────────────────
   A seção prende a tela por seis alturas. Sem orientação, quem chega vê o
   título sumir, a cena mudar devagar e conclui que "o site não rola" — foi o
   relato de um lead, com print parado no segundo ato. A barra "SEQUÊNCIA" que
   ficava aqui não dizia nada a quem não sabia o que ela era.

   Duas peças, com papéis diferentes:
     · o TRILHO diz onde a pessoa está (quatro atos, qual é o atual);
     · a PÍLULA diz o que fazer (rolar, e que ainda tem mais) e dá a saída
       ("Pular demonstração").
   As duas respondem à rolagem na hora, mesmo quando os quadros ainda estão
   chegando — que é justamente quando a cena parece travada.

   O movimento é contido de propósito: o ícone só se mexe quando a pessoa PARA
   de rolar (`data-parado`). */

/* A dica de rolagem que morava na chamada virou a pílula. O ESPAÇO dela fica:
   a chamada é centralizada no desktop e ancorada embaixo no celular, então
   tirar a linha descia o título ~17px e ~34px. E um HTML antigo ainda em
   cache (até 1h) com este CSS continua certo: a dica some, o espaço é igual. */
.hero3d__hint {
  margin: 18px 0 0; font-size: 10.5px; line-height: 1.5; height: 1.5em;
  visibility: hidden;
}
/* HTML antigo em cache: a barra "SEQUÊNCIA" deu lugar ao trilho. */
.hero3d__hud { display: none }

/* trilho — desktop */
.hero3d__guia {
  position: absolute; right: clamp(20px, 4vw, 64px); top: 46%; transform: translateY(-50%);
  z-index: 4;
}
.hero3d__guia ol {
  list-style: none; margin: 0; padding: 0; position: relative;
  display: grid; gap: clamp(26px, 5.2vh, 48px);
}
/* a linha passa pelo centro dos pontos; o preenchimento anda com --guia */
.hero3d__guia ol::before,
.hero3d__guia ol::after {
  content: ""; position: absolute; right: 6px; top: 6px; bottom: 6px; width: 1px;
}
.hero3d__guia ol::before { background: rgba(17, 24, 39, .16) }
.hero3d__guia ol::after {
  background: var(--h3d-brand);
  transform-origin: top; transform: scaleY(var(--guia, 0));
}
.hero3d__guia button {
  all: unset; box-sizing: border-box; cursor: pointer;
  /* largura cheia: encolhido para o próprio texto, cada ponto ficava numa
     coluna diferente e o trilho saía em zigue-zague */
  width: 100%; height: 13px;
  display: flex; align-items: center; justify-content: flex-end; gap: 14px;
  position: relative;
  font-family: var(--h3d-mono); font-size: 10.5px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--h3d-muted); white-space: nowrap;
}
.hero3d__guia button::after {
  content: ""; width: 7px; height: 7px; margin-right: 3px; border-radius: 50%;
  background: #FFFFFF; box-shadow: inset 0 0 0 1.5px rgba(17, 24, 39, .28);
  position: relative; z-index: 1; flex: none;
  transition: transform .3s ease, background .3s ease, box-shadow .3s ease;
}
/* O nome só aparece no ato atual — e em todos quando a pessoa aponta para o
   trilho, que é quando ela está procurando para onde ir. Escondido por
   opacidade, não por display: o leitor de tela lê os quatro. */
.hero3d__guia button span {
  opacity: 0; transform: translateX(6px);
  /* o nome cai sobre a cena, que tem áreas escuras (a cadeira, a parede) */
  text-shadow: 0 0 2px rgba(255, 255, 255, .95), 0 0 10px rgba(255, 255, 255, .95);
  transition: opacity .3s ease, transform .3s ease, color .3s ease;
}
.hero3d__guia:hover button span,
.hero3d__guia:focus-within button span { opacity: 1; transform: none }
.hero3d__guia [data-feito]::after { background: var(--h3d-brand); box-shadow: none }
.hero3d__guia [aria-current="step"] { color: var(--h3d-ink) }
.hero3d__guia [aria-current="step"] span { opacity: 1; transform: none; font-weight: 600 }
.hero3d__guia [aria-current="step"]::after {
  background: var(--h3d-brand);
  box-shadow: 0 0 0 4px rgba(40, 70, 201, .16);
  transform: scale(1.35);
}
.hero3d__guia button:hover { color: var(--h3d-ink) }

/* pílula — todos os tamanhos */
.hero3d__rolar {
  position: absolute; left: 50%; bottom: calc(10px + var(--h3d-sobe)); z-index: 4;
  transform: translateX(-50%);
  display: flex; align-items: center;
  padding: 4px; border-radius: 999px;
  background: rgba(255, 255, 255, .86);
  border: 1px solid rgba(17, 24, 39, .08);
  box-shadow: 0 10px 28px -18px rgba(17, 24, 39, .45);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  white-space: nowrap;
  transition: opacity .3s ease, visibility .3s;
}
/* Até o script escrever o texto certo (toque, largura), a pílula não
   aparece — senão ela nascia com a frase do desktop e trocava de largura na
   frente da pessoa. Sem script ela fica, com o texto do HTML. */
.hero3d[data-js]:not([data-guia-pronta]) .hero3d__rolar { opacity: 0 }
.hero3d__rolar-acao {
  all: unset; box-sizing: border-box; cursor: pointer;
  display: inline-flex; align-items: center; gap: 9px;
  height: 30px; padding: 0 13px 0 7px; border-radius: 999px;
  font-size: 13px; font-weight: 600; line-height: 1; letter-spacing: -.005em;
  color: var(--h3d-ink); font-variant-numeric: tabular-nums;
  transition: background .2s ease;
}
.hero3d__rolar-acao b { color: var(--h3d-brand); font-weight: 700 }
.hero3d__rolar-acao:hover { background: rgba(40, 70, 201, .07) }
.hero3d__pular {
  display: inline-flex; align-items: center;
  height: 30px; padding: 0 12px; margin-left: 2px;
  border-left: 1px solid rgba(17, 24, 39, .1); border-radius: 0 999px 999px 0;
  font-size: 13px; font-weight: 500; line-height: 1; letter-spacing: -.005em;
  color: var(--h3d-muted); text-decoration: none;
  transition: color .2s ease;
}
.hero3d__pular:hover { color: var(--h3d-brand) }

/* Foco visível. O `all: unset` apaga o anel padrão do navegador, então ele
   volta aqui; `:focus` é a rede para navegador sem `:focus-visible`. */
.hero3d__rolar-acao:focus,
.hero3d__pular:focus,
.hero3d__guia button:focus { outline: 2px solid var(--h3d-brand); outline-offset: 2px; border-radius: 6px }
.hero3d__rolar-acao:focus:not(:focus-visible),
.hero3d__pular:focus:not(:focus-visible),
.hero3d__guia button:focus:not(:focus-visible) { outline: none }

/* ícone: mouse no desktop, seta no toque */
.hero3d__rolar-icone {
  width: 15px; height: 21px; border-radius: 8px; flex: none; position: relative;
  box-shadow: inset 0 0 0 1.5px var(--h3d-brand);
}
.hero3d__rolar-icone i {
  position: absolute; left: 50%; top: 5px; width: 2px; height: 5px; margin-left: -1px;
  border-radius: 1px; background: var(--h3d-brand);
}
.hero3d[data-parado] .hero3d__rolar-icone i { animation: h3d-roda 1.6s cubic-bezier(.5, 0, .3, 1) infinite }
@keyframes h3d-roda {
  0%   { transform: translateY(0);   opacity: 1 }
  60%  { transform: translateY(7px); opacity: 0 }
  61%  { transform: translateY(0);   opacity: 0 }
  100% { transform: translateY(0);   opacity: 1 }
}
@media (hover: none), (pointer: coarse) {
  .hero3d__rolar-icone { width: 18px; height: 18px; border-radius: 50%; background: var(--h3d-brand); box-shadow: none }
  .hero3d__rolar-icone i {
    top: 4px; width: 6px; height: 6px; margin-left: -3px; border-radius: 0; background: none;
    border-right: 2px solid #fff; border-bottom: 2px solid #fff; transform: rotate(45deg);
  }
  .hero3d[data-parado] .hero3d__rolar-icone i { animation: h3d-seta 1.4s ease-in-out infinite }
}
@keyframes h3d-seta {
  0%, 100% { transform: translateY(0) rotate(45deg) }
  50%      { transform: translateY(3px) rotate(45deg) }
}
@media (prefers-reduced-motion: reduce) {
  .hero3d .hero3d__rolar-icone i { animation: none !important }
}

/* No fecho não há mais o que pular; e com o herói de uma tela só (movimento
   reduzido) não há trilho a percorrer. Sem script o trilho não teria o que
   marcar; a pílula fica, porque a rolagem vale e "Pular" é um link comum. */
.hero3d:not([data-js]) .hero3d__guia,
.hero3d[data-fecho] .hero3d__pular,
.hero3d[data-curto] .hero3d__pular,
.hero3d[data-curto] .hero3d__guia { display: none }

/* Onde não há altura para a pílula subir acima da barra de cookies, ela
   espera a barra fechar. E em celular deitado o botão do fecho desce até o
   rodapé: ali a pílula sai de cena no fecho. */
@media (max-width: 900px), (max-height: 559px) {
  .hero3d[data-cookies] .hero3d__rolar { opacity: 0; visibility: hidden }
}
@media (max-height: 480px) {
  .hero3d[data-fecho] .hero3d__rolar { opacity: 0; visibility: hidden }
}

/* Destino do "Pular". No celular o cabeçalho fixo (até ~90px) cobria o
   começo da seção de clientes; no desktop o respiro da própria seção basta. */
@media (max-width: 900px) {
  #clientes { scroll-margin-top: 48px }
}

/* ── carregamento ────────────────────────────────────────────────────────── */

/* O carregamento é parte da cena, não um spinner por cima dela. Fica junto da
   dica de rolagem, some sozinho e NUNCA impede o uso. */
.hero3d__load {
  position: absolute; left: var(--h3d-calha); bottom: 5vh; z-index: 5;
  display: flex; align-items: center; gap: 12px;
  font-family: var(--h3d-mono); font-size: 10px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--h3d-faint); transition: opacity .6s ease;
}
.hero3d__load[data-pronto="true"] { opacity: 0 }
/* Até ~1100px o carregamento (à esquerda) e a pílula (centro, ou esquerda no
   celular) se cruzam — e é justamente enquanto carrega que a cena parece
   travada. Ali o carregamento sobe para cima da pílula. */
@media (max-width: 1100px) {
  .hero3d__load { bottom: max(5vh, calc(var(--h3d-pilula) + var(--h3d-sobe) + 8px)) }
}
.hero3d__load .trilho { width: clamp(90px, 12vw, 168px); height: 1px; background: rgba(17, 24, 39, .14); overflow: hidden }
.hero3d__load .trilho i {
  display: block; height: 100%; background: var(--h3d-brand);
  transform: scaleX(0); transform-origin: left; transition: transform .35s cubic-bezier(.2, .8, .2, 1);
}
.hero3d__load b { font-weight: 500; font-variant-numeric: tabular-nums; color: var(--h3d-muted) }

/* Cena parada: entra a sala em ARAME, a mesma da capa de apresentação.
   Não é o render sólido. Uma versão anterior fixava um quadro fotográfico da
   sequência, e foi o que apareceu em produção: parado e em tela cheia, o
   render denuncia que é render — mesma razão pela qual os planos abertos da
   sala saíram das peças de rede. O desenho em linha é o que o site usa como
   identidade quando não há movimento. */
.hero3d[data-modo="estatico"] .hero3d__stage {
  background:
    url("../hero/desktop/linhas/f000.webp") center / cover no-repeat,
    radial-gradient(120% 92% at 22% 44%, #FFFFFF 0%, #F4F6FB 46%, #E8EDF7 100%),
    var(--h3d-ground);
}
@media (max-width: 767px) {
  .hero3d[data-modo="estatico"] .hero3d__stage {
    background-image:
      url("../hero/mobile/linhas/f000.webp"),
      radial-gradient(120% 92% at 22% 44%, #FFFFFF 0%, #F4F6FB 46%, #E8EDF7 100%);
  }
}

/* E o `ground` perde o fundo PRÓPRIO: ele é opaco e cobria o palco inteiro,
   então o arame ficava desenhado embaixo e invisível. Aqui ele passa a ser só
   o suporte das partículas — que continuam sumindo com a rolagem, enquanto o
   arame fica, porque agora mora na camada de baixo, que ninguém apaga. */
.hero3d[data-modo="estatico"] .hero3d__ground { background: none }

/* ── véu do modo parado ───────────────────────────────────────────────────
   Com a cena congelada, o quadro fica à vista o herói inteiro — e a chamada
   passa a morar em cima dele. No modo animado isso não acontece: o primeiro
   ato é só gradiente, e o 3D só entra quando o texto já saiu.

   O degradê morre antes da metade do quadro, então a cena continua inteira do
   lado direito. Na tela estreita ele vira vertical, que é onde o texto cai
   nesse formato. */
.hero3d[data-modo="estatico"] .hero3d__stage::after {
  /* z-index 1 põe o véu acima das camadas da cena, que ficam em `auto`; a
     chamada sobe para 2 logo abaixo. Em 3 ele passava por cima do texto
     também, e a peça inteira saía lavada. */
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(to right,
    rgba(252, 253, 255, .93) 0%,
    rgba(252, 253, 255, .80) 30%,
    rgba(252, 253, 255, 0) 62%);
}
.hero3d[data-modo="estatico"] .hero3d__claim,
.hero3d[data-modo="estatico"] .hero3d__caps,
.hero3d[data-modo="estatico"] .hero3d__closer { z-index: 2 }
@media (max-width: 900px) {
  .hero3d[data-modo="estatico"] .hero3d__stage::after {
    background: linear-gradient(to bottom,
      rgba(252, 253, 255, 0) 0%,
      rgba(252, 253, 255, .62) 34%,
      rgba(252, 253, 255, .93) 62%);
  }
}

@media (max-width: 900px) {
  .hero3d { height: 560vh }
  .hero3d__guia { display: none }
  /* No celular o botão flutuante de contato mora no canto inferior direito e
     cobria a ponta da pílula ("Pular"). Alinhada à calha da esquerda, como a
     chamada, a pílula e o botão formam uma linha só. Se ainda encostar, o
     script encurta o texto (ver `encostaNoBotao`). */
  .hero3d__rolar { left: var(--h3d-calha); transform: none }
  .hero3d__rolar-acao { font-size: 12.5px; gap: 8px; padding-right: 12px }
  .hero3d__pular { font-size: 12.5px; padding-inline: 10px }
  .hero3d__claim {
    top: auto; bottom: max(13vh, var(--h3d-pilula)); transform: none; width: auto;
    right: var(--h3d-calha);
  }
  .hero3d__sub { width: auto; max-width: 34ch }
  .hero3d__caps { padding-inline: clamp(20px, 5vw, 40px) }

  /* O CTA ficou de ponta a ponta por um tempo — pedido para "não ter margens
     das laterais no mobile" — e o resultado leu pior que a pílula: uma barra
     retangular colada nas duas bordas parece componente de sistema, não botão
     de ação de um site. Voltou a ser pílula, ocupando a coluna de texto. */
  .hero3d__claim .hero3d__cta { width: 100%; max-width: 420px }

  /* O botão do fecho não é o mesmo caso: ali ele fica sozinho no centro da
     tela, e sem teto de largura a regra geral `width: 100%` do site o esticava
     de borda a borda por cima da marca. */
  .hero3d__closer .hero3d__cta { width: min(100%, 340px) }
}

/* A altura do herói É a duração da animação: 620vh de rolagem é o que dá
   tempo aos quatro atos. Com movimento reduzido ela cai para uma tela, porque
   não há o que percorrer.

   O `:not([data-animar])` é o que faz a escolha da pessoa valer. Sem ele, quem
   ligava a animação pelo botão continuava sem rolagem: o carrossel girava e as
   partículas apareciam — porque isso é JS —, mas o 3D ficava parado, porque a
   media query já tinha cortado a altura. Media query não lê `sessionStorage`;
   quem carimba o atributo é o trecho no `head` do index. */
@media (prefers-reduced-motion: reduce) {
  :root:not([data-animar]) .hero3d { height: 100svh }
  :root:not([data-animar]) .hero3d__cap { transition: none }
}
/* O mesmo corte pelo parâmetro de teste, para `?movimento=reduzido`
   reproduzir o caso real inteiro — CSS incluído. */
:root[data-movimento="reduzido"]:not([data-animar]) .hero3d { height: 100svh }
:root[data-movimento="reduzido"]:not([data-animar]) .hero3d__cap { transition: none }
