/* A landing.
 *
 * Só esta página a carrega. O assistente de cadastro e as páginas legais ficam
 * com `styles.css` puro: elas são para trabalhar, não para convencer, e um fundo
 * animado atrás de um formulário de CNPJ é ruído.
 *
 * **Sem biblioteca, e não por teimosia.** O CSP das superfícies é
 * `script-src 'self'`, sem CDN, então Bootstrap ou Tailwind por CDN não
 * carregariam; vendorizar exigiria um passo de build que o `site/` não tem por
 * decisão de arquitetura. O que uma delas entregaria aqui — degradê,
 * profundidade, revelação na rolagem — o CSS moderno entrega sozinho, em zero
 * byte de dependência.
 *
 * Toda cor vem de token. As quatro categorias aparecem de propósito: elas SÃO a
 * identidade do Zero — saúde, segurança, meio ambiente, qualidade — e é a mesma
 * paleta que o anel da marca desenha. Isto é o cromo do produto, não a marca de
 * uma empresa, então `--z-brand-*` não entra: nesta página nenhuma empresa
 * entrou ainda.
 */

/* ------------------------------------------------------------ o fundo */

/**
 * A aurora: três manchas de cor desfocadas, girando devagar atrás de tudo.
 *
 * `filter: blur()` numa forma sólida em vez de um degradê radial pronto — a
 * mancha desfocada mistura as bordas de verdade, e é isso que dá a sensação de
 * profundidade que um `radial-gradient` chapado não dá.
 *
 * `pointer-events: none` e `aria-hidden` no elemento: é decoração, e uma
 * decoração que intercepta clique é um defeito.
 */
.landing {
  position: relative;
  isolation: isolate;
  overflow-x: clip;
  background: var(--z-surface-1);
}

.aurora {
  position: fixed;
  inset: -20vmax;
  z-index: -1;
  pointer-events: none;
  filter: blur(90px) saturate(1.15);
  /* Estava em .5, calibrado para uma página de uma dobra e meia — a aurora
     aparecia atrás do herói e acabava. Com as seções que a landing ganhou, ela
     é `fixed` atrás de quatro mil pixels de texto corrido, e a mesma opacidade
     que dava profundidade ao herói passou a lavar parágrafos inteiros: o olho
     em `--z-ink-300` sobre uma mancha roxa saturada some. Decoração não disputa
     com texto — quando disputa, ela perde. */
  opacity: .26;
}

.aurora span {
  position: absolute;
  display: block;
  width: 46vmax;
  height: 46vmax;
  border-radius: 50%;
  transform-origin: center;
  animation: aurora-drift 26s ease-in-out infinite alternate;
}

.aurora span:nth-child(1) { top: 2%;  left: 8%;  background: var(--z-cat-saude); }
.aurora span:nth-child(2) { top: 26%; right: 4%; background: var(--z-cat-ambiente); animation-delay: -9s; }
.aurora span:nth-child(3) { bottom: 4%; left: 32%; background: var(--z-cat-qualidade); animation-delay: -17s; }

@keyframes aurora-drift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(6vmax, -4vmax, 0) scale(1.18); }
}

/* --------------------------------------------------------- o cabeçalho */

/* Vidro, e grudado no topo: os dois botões desta página são a razão dela
   existir, e rolar não pode tirá-los da tela. */
.landing .site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: color-mix(in srgb, var(--z-surface-0) 72%, transparent);
  backdrop-filter: blur(14px) saturate(1.4);
  border-bottom: 1px solid color-mix(in srgb, var(--z-border) 70%, transparent);
}

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

/**
 * O herói recorta o que passa da borda.
 *
 * A onda cresce até 2,6× a largura da marca. Num celular de 390px isso passa da
 * janela, e passar da janela é rolagem horizontal — a página inteira anda de
 * lado ao arrastar. Medido: `scrollWidth` maior que `clientWidth` assim que as
 * ondas entraram.
 *
 * `overflow-x: clip` em `.landing` não resolve, porque o contêiner de rolagem é
 * o `html` e não o body. O recorte tem de estar no bloco que contém o que
 * transborda.
 *
 * `clip` e não `hidden`: `hidden` tornaria o herói um contêiner de rolagem, e
 * um contêiner de rolagem interno interfere na âncora `#baixar` e na
 * `animation-timeline: scroll()` da barra de leitura.
 */
/**
 * Duas colunas: a marca à esquerda, o texto à direita.
 *
 * `auto 1fr` e não `1fr 1fr`: a coluna da marca vale exatamente a largura dela,
 * e a do texto fica com o resto. Com duas frações iguais, a marca ganharia meia
 * tela num monitor largo e a frase — que é o que convence — ficaria espremida
 * ao lado de um desenho de 600px.
 *
 * `align-items: center` porque o símbolo é um círculo: alinhar pelo topo
 * deixaria um vazio visível embaixo dele, do lado do texto.
 */
.landing .hero {
  position: relative;
  overflow: clip;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  /* Linha e coluna separadas, e não um `gap` só.
     A área de respiro da revisão 2 — metade do raio, 130px a 520px — é uma
     distância HORIZONTAL, entre a marca e o texto. Aplicada também na vertical
     ela abria 130px entre a última linha do herói e o que vinha depois. */
  gap: var(--z-space-6) clamp(var(--z-space-6), 6vw, 130px);
  /* 68rem, o MESMO das seções abaixo. Estava em 72rem para dar espaço às duas
     colunas, e o resultado era uma página com duas bordas esquerdas: a tinta da
     marca em 176px e o título da seção seguinte em 208px. Trinta e dois pixels
     de degrau que ninguém consegue nomear mas todo mundo vê. */
  max-width: 68rem;
  text-align: left;
  padding-block: clamp(var(--z-space-6), 8vh, var(--z-space-8));
}

.landing .hero-copy { min-width: 0; }

/**
 * O título com o degradê da marca.
 *
 * `background-clip: text` sobre um degradê nas quatro categorias: a mesma
 * sequência do anel externo do logotipo, na mesma ordem. A cor não decora — ela
 * repete a marca em outro tamanho.
 *
 * O `color` fica declarado antes como reserva: se `background-clip: text` não
 * pegar, o título aparece em tinta sólida em vez de sumir.
 */
.landing .hero h1 {
  color: var(--z-ink-900);
  background: linear-gradient(100deg,
    var(--z-cat-saude), var(--z-cat-seguranca) 38%,
    var(--z-cat-ambiente) 68%, var(--z-cat-qualidade));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  font-size: clamp(2.25rem, 6.2vw, 4rem);
}

.landing .hero-lead {
  max-width: 34rem;
  margin-inline: 0;
  font-size: var(--z-text-h3);
  color: var(--z-ink-500);
}

/* ------------------------------------------------------- a marca do herói

   Só tamanho e posição. **Nenhum efeito.**

   A revisão 2 da marca é explícita: "Sombra, contorno, brilho e rotação não
   fazem parte da marca." A versão anterior desta folha tinha o símbolo
   redesenhado à mão em CSS, com `drop-shadow` de brilho, um halo em anel e um
   giro próprio — três coisas que a marca não tem, aplicadas por uma página, e a
   razão pela qual as logos começaram a divergir entre as telas.

   O movimento agora vem de dentro do arquivo `zero-orbita.svg`, que é oficial e
   é oficial. Esta folha não anima o símbolo, não o pinta e não o recompõe: ela
   decide onde ele fica e de que tamanho.

   Área de respiro: a revisão 2 pede metade do raio em volta. Aqui ela é o `gap`
   da grade na horizontal, e o vazio transparente do próprio arquivo no resto. */

/* O contêiner do `<picture>`: sem ele o elemento é inline e a grade recebe uma
   caixa com folga de linha de base embaixo.

   A largura vive aqui, numa custom property, porque é usada DUAS vezes: como
   largura e como base do recuo negativo logo abaixo. Escrita duas vezes, as
   duas sairiam do lugar assim que alguém mudasse uma. */
.landing .hero-mark-wrap {
  display: block;
  --marca: clamp(200px, 34vw, 520px);
}

/**
 * A marca, puxada para a esquerda pelo próprio vazio.
 *
 * O arquivo tem `viewBox` de 1024 e a tinta começa em 192 — **18,75% de
 * transparente de cada lado**, que é a área de respiro desenhada dentro do
 * próprio SVG. A 490px isso são 92px de nada antes de o anel aparecer, e é por
 * isso que a marca parecia recuada mesmo colada na borda da coluna.
 *
 * A margem negativa vale exatamente esse vazio, então o que encosta na borda do
 * conteúdo é a TINTA e não a caixa. Medido, não estimado: a folga foi lida do
 * arquivo (`r=284`, traço 72 → 512-284-36 = 192 de 1024).
 *
 * Numa coluna de grade `auto`, a margem negativa encolhe a coluna junto — a
 * distância entre a tinta e o texto continua sendo a que o `gap` define.
 */
.landing .hero-mark {
  display: block;
  /* O dobro do que era. O piso subiu junto — 200px — porque abaixo disso a
     escada de simplificação da marca pede outro arquivo, e aqui é sempre o
     completo. O teto de 34vw impede que a marca coma a coluna do texto em
     larguras intermediárias, onde a grade ainda é de duas colunas. */
  width: var(--marca);
  margin-inline-start: calc(var(--marca) * -0.1875);
  height: auto;
  aspect-ratio: 1;
}

/* ----------------------------------------------- os quatro domínios no herói

   Herdaram as pílulas da seção de categorias que saiu. A cor vem de
   `data-categoria` e não da posição: a ordem no HTML pode mudar, o significado
   da cor não pode. */

.landing .hero-domains {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: var(--z-space-2) var(--z-space-4);
  margin: var(--z-space-6) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--z-text-sm);
  font-weight: 600;
  color: var(--z-ink-400);
}

.landing .hero-domains li {
  display: inline-flex;
  align-items: center;
  gap: var(--z-space-2);
}

.landing .hero-domains span {
  width: 9px;
  height: 9px;
  border-radius: 50%;
}

.landing .hero-domains [data-categoria="saude"] span     { background: var(--z-cat-saude); }
.landing .hero-domains [data-categoria="seguranca"] span { background: var(--z-cat-seguranca); }
.landing .hero-domains [data-categoria="ambiente"] span  { background: var(--z-cat-ambiente); }
.landing .hero-domains [data-categoria="qualidade"] span { background: var(--z-cat-qualidade); }

/* ------------------------------------------------------------ botões */

/* Elevação e um brilho que corre no hover. O `::after` é a faixa de luz; ele
   fica fora do botão até o ponteiro chegar. */
.landing .primary-button,
.landing .ghost-button {
  position: relative;
  overflow: hidden;
  transition:
    transform var(--z-dur-fast) var(--z-ease),
    box-shadow var(--z-dur-base) var(--z-ease);
}

.landing .primary-button {
  background: linear-gradient(120deg, var(--z-cat-saude), var(--z-cat-ambiente));  /* dois vizinhos no anel: teal -> verde */
  color: var(--z-surface-0);
  box-shadow: 0 10px 26px -12px color-mix(in srgb, var(--z-cat-saude) 80%, transparent);
}

.landing .primary-button::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 -40%;
  width: 40%;
  background: linear-gradient(100deg, transparent,
    color-mix(in srgb, var(--z-surface-0) 45%, transparent), transparent);
  transform: skewX(-18deg);
  transition: left var(--z-dur-ripple) var(--z-ease);
}

.landing .primary-button:hover::after { left: 120%; }

.landing .primary-button:hover,
.landing .ghost-button:hover {
  transform: translateY(-2px);
  filter: none;
}

.landing .primary-button:hover {
  box-shadow: 0 16px 34px -12px color-mix(in srgb, var(--z-cat-saude) 90%, transparent);
}

.landing .ghost-button {
  background: color-mix(in srgb, var(--z-surface-0) 70%, transparent);
  backdrop-filter: blur(8px);
}

/* ------------------------------------------------------------ cartões */

.landing .feature-grid {
  max-width: 68rem;
  margin-inline: auto;
  padding-inline: var(--z-space-6);
  padding-bottom: var(--z-space-8);
}

/**
 * Vidro sobre a aurora, com uma borda que acende na cor da categoria.
 *
 * A borda é um degradê preso ao `::before` porque `border-image` não acompanha
 * `border-radius`. Cada cartão puxa a sua cor de `--tom`, definido logo abaixo:
 * a ordem repete a do anel da marca.
 */
.landing .feature {
  position: relative;
  padding: var(--z-space-6);
  border: 1px solid color-mix(in srgb, var(--z-border) 60%, transparent);
  border-radius: var(--z-r-lg);
  background: color-mix(in srgb, var(--z-surface-0) 76%, transparent);
  backdrop-filter: blur(12px);
  box-shadow: 0 18px 40px -30px color-mix(in srgb, var(--z-ink-900) 60%, transparent);
  transition:
    transform var(--z-dur-base) var(--z-ease),
    box-shadow var(--z-dur-base) var(--z-ease);
}

.landing .feature::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(140deg, var(--tom), transparent 55%);
  /* Recorta o miolo e deixa só a moldura de 1px. */
  /* A cor da máscara não importa — só a opacidade — e por isso é `currentColor`
     e não um preto literal: uma cor escrita à mão aqui seria uma cor a mais no
     produto, e `validate-brand-tokens.mjs` recusa, com razão. */
  -webkit-mask: linear-gradient(currentColor 0 0) content-box,
                linear-gradient(currentColor 0 0);
  mask: linear-gradient(currentColor 0 0) content-box,
        linear-gradient(currentColor 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0;
  transition: opacity var(--z-dur-base) var(--z-ease);
}

.landing .feature:hover {
  transform: translateY(-4px);
  box-shadow: 0 26px 50px -28px color-mix(in srgb, var(--z-ink-900) 70%, transparent);
}

.landing .feature:hover::before { opacity: 1; }

.landing .feature:nth-child(1) { --tom: var(--z-cat-saude); }
.landing .feature:nth-child(2) { --tom: var(--z-cat-ambiente); }
.landing .feature:nth-child(3) { --tom: var(--z-cat-seguranca); }
.landing .feature:nth-child(4) { --tom: var(--z-cat-qualidade); }

.landing .feature .material-symbols-outlined {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: var(--z-r-md);
  background: color-mix(in srgb, var(--tom) 14%, transparent);
  color: var(--tom);
  font-size: 26px;
}

/* --------------------------------------------------- revelação na rolagem */

/**
 * Entrada por rolagem, sem uma linha de JavaScript.
 *
 * `animation-timeline: view()` liga a animação à posição do elemento na janela.
 * Onde o navegador não conhecer a propriedade, o `@supports` não se aplica e o
 * conteúdo simplesmente aparece — nada fica invisível esperando um script que
 * não veio, que é o defeito clássico de revelação por rolagem.
 */
@supports (animation-timeline: view()) {
  .landing .reveal {
    animation: reveal-up linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 26%;
  }
}

@keyframes reveal-up {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------- rodapé */

.landing .site-footer {
  border-top: 1px solid color-mix(in srgb, var(--z-border) 70%, transparent);
  background: color-mix(in srgb, var(--z-surface-0) 60%, transparent);
  backdrop-filter: blur(10px);
}

/* --------------------------------------------------- menos movimento */

/* Quem pediu menos movimento continua vendo a página inteira: as manchas param
   onde estão, a revelação não acontece, e nada depende do movimento para ficar
   legível. */
@media (prefers-reduced-motion: reduce) {
  .aurora span,
  .landing .reveal { animation: none; }
  .landing .primary-button::after { transition: none; }
  .landing .feature:hover,
  .landing .primary-button:hover,
  .landing .ghost-button:hover { transform: none; }
}

/* ==================================================================== seções

   As seções que a landing ganhou para conversar com a apresentação de SST e com
   o panfleto. Um padrão só, repetido: olho, título, conteúdo, e uma frase de
   fecho que carrega o argumento — que é a forma dos slides.

   Toda cor continua vindo de token, e as quatro categorias continuam sendo as
   únicas cores com significado. `--z-brand-*` não entra em nenhuma delas: nesta
   página nenhuma empresa entrou ainda. */

.landing .landing-section {
  max-width: 68rem;
  margin-inline: auto;
  padding: var(--z-space-8) var(--z-space-6);
}

.landing .section-head { max-width: 44rem; margin-bottom: var(--z-space-6); }

.landing .section-title {
  margin: 0 0 var(--z-space-3);
  font-family: var(--z-font-display);
  font-size: clamp(1.6rem, 3.4vw, 2.35rem);
  line-height: var(--z-leading-tight);
  letter-spacing: var(--z-tracking-display);
  color: var(--z-ink-900);
}

/* A frase que fecha a seção. Ela carrega o argumento, então tem corpo de texto
   e não de legenda — uma conclusão em 12px é uma conclusão que ninguém lê. */
.landing .section-close {
  max-width: 46rem;
  margin: var(--z-space-6) 0 0;
  font-size: var(--z-text-h3);
  line-height: var(--z-leading-snug);
  color: var(--z-ink-500);
}

/* ------------------------------------------------------------- o problema */

.landing .problem-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: var(--z-space-4);
}

/**
 * Duas colunas fixas, e não `auto-fit`.
 *
 * São QUATRO cartões. Com `auto-fit` a largura da janela decide quantos cabem
 * por linha, e numa faixa larga de telas ele acomoda três — deixando o quarto
 * sozinho numa segunda linha, ao lado de dois vazios. Quatro em duas colunas é
 * 2×2 em qualquer largura acima do ponto de quebra, que é a grade que a lista
 * pede: quatro formas de perder um informe, lado a lado.
 */
.landing .problem-grid-pares {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (max-width: 44rem) {
  .landing .problem-grid-pares { grid-template-columns: minmax(0, 1fr); }
}

.landing .problem {
  padding: var(--z-space-5);
  border: 1px solid color-mix(in srgb, var(--z-border) 70%, transparent);
  border-radius: var(--z-r-md);
  background: color-mix(in srgb, var(--z-surface-0) 70%, transparent);
  backdrop-filter: blur(10px);
}

.landing .problem-title {
  display: flex;
  align-items: center;
  gap: var(--z-space-3);
  margin: 0 0 var(--z-space-2);
  font-size: var(--z-text-h3);
  color: var(--z-ink-900);
}

/* O ponto é a severidade CRÍTICA, e é a única coisa nesta página pintada com um
   token de severidade. Aqui ele não classifica um informe: marca as quatro
   formas de perder um. Fica em 10px e sem animação — `BRAND.md` §7 é explícito
   que nada pulsa em vermelho, porque alarme constante é alarme que ninguém vê. */
.landing .problem-dot {
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--z-sev-critico);
}

.landing .problem p { margin: 0; color: var(--z-ink-500); }

/* ------------------------------------------------------------ os três passos */

.landing .step-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: var(--z-space-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.landing .step {
  padding: var(--z-space-5);
  border: 1px solid color-mix(in srgb, var(--z-border) 70%, transparent);
  border-radius: var(--z-r-lg);
  background: color-mix(in srgb, var(--z-surface-0) 76%, transparent);
  backdrop-filter: blur(12px);
}

/* Os três números repetem a ordem do anel da marca: saúde, segurança,
   ambiente. É a mesma sequência do herói e dos cartões acima. */
.landing .step-number {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-bottom: var(--z-space-4);
  border-radius: 50%;
  font-family: var(--z-font-display);
  font-weight: 700;
  font-size: var(--z-text-h3);
  color: var(--z-surface-0);
}

.landing .step:nth-child(1) .step-number { background: var(--z-cat-saude); }
.landing .step:nth-child(2) .step-number { background: var(--z-cat-seguranca); }
.landing .step:nth-child(3) .step-number { background: var(--z-cat-ambiente); }

.landing .step-title {
  margin: 0 0 var(--z-space-2);
  font-size: var(--z-text-h3);
  color: var(--z-ink-900);
}

.landing .step p { margin: 0; color: var(--z-ink-500); }

/* ------------------------------------------------------- o que chega até você */

.landing .delivery-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr));
  gap: var(--z-space-5);
  margin: 0;
  padding: 0;
  list-style: none;
}

.landing .delivery {
  display: flex;
  align-items: flex-start;
  gap: var(--z-space-4);
}

.landing .delivery-mark {
  flex: none;
  width: 12px;
  height: 12px;
  margin-top: 7px;
  border-radius: 50%;
  background: var(--z-cat-saude);
}

.landing .delivery:nth-child(2) .delivery-mark { background: var(--z-cat-seguranca); }
.landing .delivery:nth-child(3) .delivery-mark { background: var(--z-cat-ambiente); }
.landing .delivery:nth-child(4) .delivery-mark { background: var(--z-cat-qualidade); }

.landing .delivery-title {
  margin: 0 0 var(--z-space-2);
  font-size: var(--z-text-h3);
  color: var(--z-ink-900);
}

.landing .delivery p { margin: 0; color: var(--z-ink-500); }

/* ------------------------------------------------------ o que o nome diz */

.landing .meaning {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: var(--z-space-6);
}

/* Sem `filter`: a revisão 2 não admite brilho nem sombra sobre a marca. */
.landing .meaning-mark { display: block; }

.landing .meaning-lead {
  margin: 0 0 var(--z-space-4);
  max-width: 44rem;
  font-size: var(--z-text-h3);
  color: var(--z-ink-500);
}

.landing .meaning-note {
  margin: 0;
  max-width: 44rem;
  color: var(--z-cat-ambiente-ink);
}

@media (max-width: 48rem) {
  .landing .meaning { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------- o download */

.landing .download {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--z-space-7);
}

.landing .download-copy { max-width: 40rem; }

.landing .store-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--z-space-3);
  margin-top: var(--z-space-6);
}

/* Alvo grande: quem lê isto num celular está com o polegar, e às vezes com
   luva. `BRAND.md` fixa 48px, e a altura aqui é maior porque o botão carrega
   duas linhas. */
.landing .store-button {
  display: inline-flex;
  align-items: center;
  gap: var(--z-space-3);
  min-height: 60px;
  padding: var(--z-space-3) var(--z-space-5);
  border-radius: var(--z-r-md);
  background: var(--z-ink-900);
  color: var(--z-surface-0);
  font-family: var(--z-font-display);
  font-weight: 700;
  font-size: var(--z-text-h3);
  text-decoration: none;
  transition: transform var(--z-dur-fast) var(--z-ease),
              box-shadow var(--z-dur-base) var(--z-ease);
}

.landing .store-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 16px 32px -18px color-mix(in srgb, var(--z-ink-900) 90%, transparent);
}

.landing .store-button .material-symbols-outlined { font-size: 30px; }

.landing .store-button small {
  display: block;
  font-family: var(--z-font-sans);
  font-weight: 400;
  font-size: var(--z-text-sm);
  color: var(--z-ink-100);
}

/* Mostrado enquanto nenhum link de loja está configurado. Diz o que a pessoa
   pode fazer AGORA em vez de só informar uma ausência. */
.landing .store-soon {
  margin: 0;
  max-width: 30rem;
  color: var(--z-ink-400);
}

.landing .download-qr { margin: 0; text-align: center; }

/* Fundo sólido sob o QR — o código precisa de contraste máximo e de bordas
   nítidas, e a aurora atrás da página não pode atravessá-lo. */
.landing .qr-frame {
  width: 208px;
  height: 208px;
  padding: var(--z-space-3);
  border-radius: var(--z-r-md);
  background: var(--z-surface-0);
  box-shadow: 0 18px 44px -26px color-mix(in srgb, var(--z-ink-900) 80%, transparent);
}

.landing .qr-frame svg { display: block; width: 100%; height: 100%; }

.landing .qr-caption {
  max-width: 208px;
  margin: var(--z-space-3) auto 0;
  font-size: var(--z-text-sm);
  color: var(--z-ink-400);
}

/* Num celular o QR não serve para nada: a pessoa já está no aparelho em que o
   app seria instalado. Ele sai, e os botões ficam. */
@media (max-width: 52rem) {
  .landing .download { grid-template-columns: 1fr; }
  .landing .download-qr { display: none; }
}

/* --------------------------------------------------------------- o piloto */

.landing .pilot {
  display: grid;
  grid-template-columns: 1fr minmax(18rem, 24rem);
  gap: var(--z-space-7);
  align-items: start;
}

.landing .pilot-copy { min-width: 0; }

.landing .pilot-list {
  display: grid;
  gap: var(--z-space-5);
  margin: var(--z-space-6) 0 0;
  padding: 0;
  list-style: none;
}

.landing .pilot-item p { margin: 0; color: var(--z-ink-500); }

.landing .pilot-aside {
  padding: var(--z-space-6);
  border: 1px solid color-mix(in srgb, var(--z-border) 70%, transparent);
  border-radius: var(--z-r-lg);
  background: color-mix(in srgb, var(--z-surface-0) 78%, transparent);
  backdrop-filter: blur(12px);
}

.landing .pilot-aside-title {
  margin: 0 0 var(--z-space-4);
  font-size: var(--z-text-h3);
  color: var(--z-ink-900);
}

.landing .pilot-need {
  display: grid;
  gap: var(--z-space-3);
  margin: 0 0 var(--z-space-5);
  padding: 0;
  list-style: none;
}

.landing .pilot-need li {
  display: flex;
  align-items: flex-start;
  gap: var(--z-space-3);
  color: var(--z-ink-700);
}

.landing .pilot-need li::before {
  content: "";
  flex: none;
  width: 10px;
  height: 10px;
  margin-top: 8px;
  border-radius: 50%;
  background: var(--z-cat-seguranca);
}

.landing .pilot-note {
  margin: 0;
  font-size: var(--z-text-sm);
  color: var(--z-ink-400);
}

@media (max-width: 52rem) {
  .landing .pilot { grid-template-columns: 1fr; }
}

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

/* Os mesmos dois botões do herói, no fim da rolagem. Quem leu tudo não deve ter
   de subir a página de volta para agir. */
.landing .closing { text-align: center; }
.landing .closing .section-title { max-width: 34rem; margin-inline: auto; }
.landing .closing .hero-actions { margin-top: var(--z-space-6); }

@media (max-width: 40rem) {
  .landing .landing-section {
    padding-left: var(--z-space-4);
    padding-right: var(--z-space-4);
  }
}

/* ----------------------------------------------------- a página de download */

/**
 * O herói simples: uma coluna, centrada. **`/app` não é o herói da landing.**
 *
 * `app.html` é o destino do QR impresso, e ela reaproveita `class="hero"` para
 * herdar tipografia e respiro. Só que o herói desta folha é uma GRADE de duas
 * colunas desenhada para exatamente dois filhos — a marca e o bloco de texto —
 * e `/app` tem sete: marca, sobrelinha, título, frase, aviso de manutenção,
 * botões de loja e a nota do rodapé. Sete filhos numa grade de duas colunas
 * viram quatro linhas de sobras, e a coluna `auto` da marca, que aqui recebe um
 * SVG de 1024px, come a largura inteira. Medido em 1280px:
 * `grid-template-columns: 1024px 0px` — a coluna do texto fechou em ZERO.
 *
 * E a marca vinha a 1024px por uma segunda razão, independente: `.hero-mark`
 * pede `width: var(--marca)`, e `--marca` é declarado em `.hero-mark-wrap`, uma
 * classe que esta página não usa. Custom property ausente não cai para o valor
 * anterior — a declaração inteira fica inválida no tempo de cálculo, `width`
 * volta para `auto`, e `auto` num `<img>` de SVG é o tamanho intrínseco do
 * arquivo. O `width="96"` do HTML não salva: atributo de apresentação perde
 * para qualquer regra de autor. Resultado no Galaxy A56, conferido na produção:
 * um quarto de anel ocupando a tela toda e os botões de loja a uma rolagem e
 * meia de distância de quem acabou de escanear o cartaz.
 *
 * `--marca` passa a existir aqui, com o tamanho que o HTML sempre pediu, e a
 * grade sai de cena.
 */
.landing .hero-simple {
  display: block;
  max-width: 46rem;
  text-align: center;
  --marca: 96px;
}

/* O recuo negativo de `.hero-mark` existe para encostar a TINTA da marca na
   borda da coluna de texto do herói da landing. Centrada, ela não tem borda
   para encostar — e o recuo só a tiraria do meio. */
.landing .hero-simple .hero-mark {
  margin-inline: auto;
  margin-block-end: var(--z-space-4);
}

/* Os mesmos botões de loja da landing, centrados sob o herói. */
.landing .store-buttons-centered { justify-content: center; }

/* ================================================ movimento na rolagem

   Item por item, tudo em CSS: `animation-timeline` liga a animação à posição do
   elemento na janela, sem uma linha de JavaScript e sem observer. Onde o
   navegador não conhece a propriedade, o `@supports` não se aplica e o conteúdo
   simplesmente aparece — nada fica invisível esperando um script que não veio. */

/* A barra de progresso da leitura, no topo, nas quatro cores da marca.
   `animation-timeline: scroll()` mede a rolagem do documento inteiro. */
.landing .read-progress {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 20;
  width: 100%;
  height: 3px;
  transform-origin: 0 50%;
  scale: 0 1;
  /* `--z-ring-linear` é o anel da marca em linha, já na ordem da revisão 2. O
     valor de reserva repete essa ordem: saúde, segurança, ambiente, qualidade. */
  background: var(--z-ring-linear, linear-gradient(90deg,
    var(--z-cat-saude), var(--z-cat-seguranca) 32%,
    var(--z-cat-ambiente) 66%, var(--z-cat-qualidade)));
  pointer-events: none;
}

@supports (animation-timeline: scroll()) {
  .landing .read-progress {
    animation: leitura linear;
    animation-timeline: scroll(root block);
  }
}

@keyframes leitura { to { scale: 1 1; } }

/* O olho de cada seção ganha um traço que se desenha ao entrar. É a "linha
   passando" na escala de uma seção: curta, uma vez, e ligada à rolagem em vez
   de a um relógio — quem não rolar não vê movimento nenhum. */
.landing .section-head .eyebrow,
.landing .download .eyebrow,
.landing .pilot .eyebrow,
.landing .meaning .eyebrow,
.landing .closing .eyebrow {
  position: relative;
  display: inline-block;
  padding-bottom: var(--z-space-2);
}

.landing .section-head .eyebrow::after,
.landing .download .eyebrow::after,
.landing .pilot .eyebrow::after,
.landing .meaning .eyebrow::after,
.landing .closing .eyebrow::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  transform-origin: 0 50%;
  scale: 0 1;
  background: linear-gradient(90deg, var(--z-cat-seguranca), transparent);
}

@supports (animation-timeline: view()) {
  .landing .section-head .eyebrow::after,
  .landing .download .eyebrow::after,
  .landing .pilot .eyebrow::after,
  .landing .meaning .eyebrow::after,
  .landing .closing .eyebrow::after {
    animation: risco linear both;
    animation-timeline: view();
    animation-range: entry 10% cover 30%;
  }
}

@keyframes risco { to { scale: 1 1; } }

/* Entrada em cascata dentro de uma grade: cada cartão começa um pouco depois do
   anterior. O atraso é dado por `animation-range`, não por `animation-delay` —
   numa linha do tempo de rolagem o atraso é uma distância, não um tempo, e um
   `delay` em segundos faria o terceiro cartão aparecer depois de a pessoa já ter
   passado por ele. */
@supports (animation-timeline: view()) {
  .landing .problem-grid .reveal:nth-child(2),
  .landing .step-grid .reveal:nth-child(2),
  .landing .delivery-list .reveal:nth-child(2) { animation-range: entry 0% cover 32%; }

  .landing .problem-grid .reveal:nth-child(3),
  .landing .step-grid .reveal:nth-child(3),
  .landing .delivery-list .reveal:nth-child(3) { animation-range: entry 0% cover 38%; }

  .landing .problem-grid .reveal:nth-child(4),
  .landing .delivery-list .reveal:nth-child(4) { animation-range: entry 0% cover 44%; }
}

/* A seção de download inteira sobe um pouco enquanto entra. Um deslocamento
   pequeno: a intenção é dar peso ao bloco, não puxar o olho para longe do QR. */
@supports (animation-timeline: view()) {
  .landing .download-qr {
    animation: sobe linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 40%;
  }
}

@keyframes sobe {
  from { opacity: 0; transform: translateY(28px) scale(.96); }
  to   { opacity: 1; transform: none; }
}

/* --------------------------------------------------- menos movimento, de novo

   Repetido aqui porque tudo acima é novo. Quem pediu menos movimento continua
   vendo a página inteira: a marca fica no quadro final, as ondas não saem, a
   barra de leitura some, e nada depende do movimento para ser legível. */
@media (prefers-reduced-motion: reduce) {
  /* A marca não é tratada aqui, e nem poderia: nenhuma regra desta folha
     alcança o interior de um `<img>`. Quem resolve é o `<source media="...">`
     do `<picture>` no HTML, que troca o arquivo animado pelo estático antes de
     o navegador escolher qual baixar.

     O SVG traz o próprio `@media (prefers-reduced-motion)`, mas essa regra NÃO
     é avaliada quando ele vem por `<img>` — medido, continuava girando. É por
     isso que o `<picture>` existe. */
  .landing .read-progress { display: none; }

  .landing .section-head .eyebrow::after,
  .landing .download .eyebrow::after,
  .landing .pilot .eyebrow::after,
  .landing .meaning .eyebrow::after,
  .landing .closing .eyebrow::after { animation: none; scale: 1 1; }

  .landing .download-qr { animation: none; }
}

/* ------------------------------------------- o herói numa coluna, no celular

   Abaixo de 62rem a grade colapsa e tudo volta a centrar. Duas colunas em 390px
   dariam 190px para cada uma: a marca ficaria menor do que era antes da mudança
   e a frase quebraria a cada três palavras.

   O ponto de quebra é 62rem e não 48rem porque a conta que importa é a da
   COLUNA DE TEXTO, não a da janela: com a marca em 34vw, é por volta de 62rem
   que sobram menos de 30rem para a frase — a largura em que uma linha de leitura
   deixa de ser confortável. */
@media (max-width: 62rem) {
  .landing .hero {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    text-align: center;
    gap: var(--z-space-5);
  }

  /* Empilhado e centrado, o recuo negativo deixaria a marca fora de centro:
     ela é o único item da linha e não há borda de conteúdo para encostar. */
  .landing .hero-mark-wrap { --marca: clamp(180px, 46vw, 300px); }
  .landing .hero-mark { margin-inline-start: 0; }
  .landing .hero-lead { margin-inline: auto; }
  .landing .hero-actions { justify-content: center; }
  .landing .hero-domains { justify-content: center; }
}
