/* ==========================================================================
   A VIAGEM DO CELULAR: PRESA AO DEDO (2026-08-02, correção de rumo)

   A REGRA DE PRODUTO, que vale mais que qualquer técnica
   Está escrita desde 31/07: o movimento fica preso ao dedo rolando. "Só
   enquanto o dedo rola: parou o dedo, parou a tela." Sem autoplay. O Alê
   repetiu a mesma exigência com outras palavras depois de testar no iPhone:
   "ele deve crescer com o scroll da página".

   O ERRO DA RODADA ANTERIOR (2026-08-01, noite)
   A rodada do IntersectionObserver trocou isso por um disparo único: o
   navegador avisava UMA vez que a pessoa havia chegado e daí em diante
   rodava uma `transition` de 1200 a 1500ms sozinha, por RELÓGIO, sem
   nenhuma ligação com o gesto depois de disparada. Isso é autoplay, e é
   exatamente o que a regra proíbe. Foi erro de julgamento, não de número:
   a técnica escolhida contradizia o produto.

   Os dois sintomas que o Alê relatou no aparelho real são o que essa
   técnica produz:
   · "ele não roda" — num flick normal a página anda mais de mil pixels em
     menos de 300ms. A animação de 1500ms começava com o hero em quadro e
     terminava com ele muito acima da tela. Ao voltar, já estava no estado
     final e congelado, porque o disparo era único e sem volta.
   · "textos encavalados um em cima do outro" — animação por relógio tem
     estado no meio: quadros que existem na tela sem corresponder a posição
     nenhuma do dedo, rasterizados fora de hora pelo scroll assíncrono do
     WebKit. Sobreposição estática não existe no layout: medido nesta
     bancada, rótulo, título e sub não se tocam em estado nenhum. O
     encavalamento nasce do quadro em voo, não do CSS.

   O QUE ESTE ARQUIVO FAZ AGORA
   Uma variável só, `--vprog` (0 a 1), escrita no <html> pelo
   js/mobile-viagem.js a cada quadro de rolagem. O CSS interpola TUDO a
   partir dela com calc() e clamp(): a cena da estrada, o caminhão e a foto
   (que é o fallback). Não existe `transition`, não existe `animation`, não
   existe classe de estado final. Parou o dedo, parou a tela. Voltou o dedo,
   a viagem rebobina, porque ela nunca foi um evento: é leitura de posição.
   O porquê de esta rota ser ÚNICA (sem volta do `animation-timeline` e sem
   `CSS.supports` arbitrando nada) está no cabeçalho do js/mobile-viagem.js.
   Exigência de navegador: calc(), clamp(), custom properties e transform.

   A GEOMETRIA, calibrada no viewport REAL dele (402x753), não estimada
   Curso = 55% da altura da tela = 414px naquele aparelho. Não é chute:
   a faixa nasce inteira em quadro e sai por cima em pouco mais de 700px de
   rolagem. Curso de 90vh (678px) só se completava com 70px de faixa
   restando, e o estado final não era visto por ninguém.
   · cena, caminhão e foto   0 → 1 do curso   (o caminhão parte no 1º pixel)
   O lastro e a placa de texto tinham faixas próprias (.036→.345 e
   .127→.455) e SAÍRAM em 2026-08-02 junto com a placa. O porquê está no
   bloco "A PLACA DE TEXTO SAIU DA FAIXA", mais abaixo.
   Conferência no ponto que o próprio aparelho dele registrou, scrollY 172:
   vprog .415, foto 1.083. É o número da calibragem anterior, de propósito:
   a geometria sempre esteve certa, quem estava errado era o gatilho.

   A ALTURA DA FAIXA vem de fora: `--faixa-hero`, declarada no `.hero` em
   css/style.css e herdada por todo mundo aqui. Nunca redeclarar o clamp
   neste arquivo: ele já foi número gêmeo em cinco lugares.

   Sem loop, sem autoplay, sem parallax, sem pin. Ler a posição da rolagem
   não é prender nada: a seção continua subindo com o dedo, normalmente.
   Movimento reduzido e modo econômico continuam desligando tudo.
   ========================================================================== */
/* ==========================================================================
   A CENA DA ESTRADA (2026-08-02, pedido do Alê)

   Revoga "motion e 3D só no desktop": ele pediu o mesmo cenário do
   hero-3d.js rodando no celular, no lugar da foto. A foto virou o fallback.

   É 3D de verdade, em perspectiva CSS, e NÃO um porte do three.js. O porquê
   inteiro (a cena do desktop é feita de planos e de um billboard chapado,
   nada ali precisa girar, e o three.min.js custaria 149 KB gzip mais o risco
   de canvas preto por contexto WebGL perdido no calor) está no HANDOFF.md,
   seção "A CENA DA ESTRADA NO CELULAR". Aqui fica só o que é preciso saber
   pra mexer no arquivo sem quebrar nada.

   As cores são as MESMAS constantes do COR{} do hero-3d.js, em hexadecimal.
   A névoa tem a cor do pé do céu, que foi a correção do CONTRAIA que matou a
   linha dura do horizonte no desktop.

   No desktop a CÂMERA anda e o cenário fica parado. Aqui é o contrário: a
   câmera fica e o cenário vem. Dá o mesmo movimento na tela e evita que o
   plano do chão cruze o olho. Asfalto e defensa são uniformes ao longo do
   comprimento, então ficam parados sem ninguém perceber.

   Tudo é função pura de --vprog: zero transition, zero animation, zero
   relógio. Parou o dedo, parou a cena; rolou pra trás, ela rebobina. Nenhum
   momento coreografado novo: a estrada entrou DENTRO do que já existia.

   PORTÕES: @supports (perspective) / reduced-motion / reduced-data. Nos três
   a foto volta. O @supports é seleção de fallback, não script desistindo:
   errando pra mais, a cena aparece, que é o caminho bom. É o oposto do falso
   positivo do CSS.supports que já custou caro neste hero.
   ========================================================================== */
@supports (perspective:1px){
@media (prefers-reduced-motion:no-preference){

  .hero__cena{
    display:block;
    position:absolute;left:0;right:0;bottom:0;top:auto;
    /* a MESMA faixa da foto e do caminhão, e ela vem de um token só,
       --faixa-hero, declarado no .hero em css/style.css. Era um clamp
       repetido em cinco lugares entre dois arquivos; virou herança de custom
       property. A cena não cresce a página um pixel: ela ocupa exatamente o
       espaço que a foto ocupava, e cresce com ela quando o token cresce. */
    height:var(--faixa-hero);
    z-index:0;
    overflow:hidden;                 /* o recorte mora aqui, FORA do 3D */
    /* TERRA, e isto resolve dois artefatos de uma vez. O plano da pista é
       finito: a borda de longe dele para uns 18px abaixo do horizonte, e as
       bordas laterais entram no quadro perto do ponto de fuga. Como as faixas
       externas do próprio plano JÁ são desta cor, plano e fundo encostam sem
       emenda nenhuma e as três bordas somem. É o mesmo arranjo do desktop, que
       tem um plano de terra de 400x400 por baixo de tudo. */
    background:#3a3628;
    pointer-events:none;

    /* AS DUAS MEDIDAS DA CENA, declaradas num lugar só.
       O horizonte é o ponto de fuga: o céu acaba nele, os morros pousam nele
       e a perspectiva sai dele. O avanço é o quanto o cenário anda no curso
       inteiro da viagem, e é ele que a faixa e os postes leem.
       --vprog tem reserva 0: sem o script, --avanco vale 0 e a cena fica
       parada no primeiro quadro, que é um quadro bom. */
    --horizonte:38%;
    --avanco:calc(var(--vprog,0) * 700px);
  }

  /* A foto sai de cena quando a cena existe: ela é opaca e cobre tudo, e
     manter a faixa inteira sendo composta por baixo é trabalho de GPU por
     nada. Os bytes dela continuam sendo pagos (é uma <img> com
     fetchpriority, e o navegador busca antes de saber deste display), o que
     se ganha aqui é pintura, não rede. Ela volta inteira nos dois caminhos
     de fallback: movimento reduzido (fora deste @media) e modo econômico
     (fim do arquivo). */
  .hero__foto{display:none}

  /* O véu foi calibrado para lavar uma FOTO. Sobre a cena ele estava
     cobrindo o céu e o horizonte de verde no ponto exato onde a estrada
     precisa abrir. A curva foi aberta: continua sólida encostada no texto
     (que é o trabalho dela, emendar a faixa no verde do hero sem costura) e
     solta muito mais cedo. Desde que a placa saiu da faixa, não há texto
     nenhum sobre a cena, então ela responde só pela emenda. */
  .hero__veu{
    background:linear-gradient(to bottom,
      var(--verde-prof) 0%,
      rgba(19,36,32,.62) 9%,
      rgba(19,36,32,.24) 22%,
      rgba(19,36,32,.08) 38%,
      rgba(19,36,32,0) 62%);
  }

  /* --- O PALCO -------------------------------------------------------------
     Uma única `perspective`, e TODOS os elementos com Z são filhos diretos
     dela. Nada de `transform-style:preserve-3d` e nada de 3D aninhado: é o
     arranjo mais conservador que existe em CSS 3D, e é de propósito. Cena
     aninhada é justamente onde WebKit e Blink divergem (contexto achatado
     por um `overflow` no meio do caminho), e este hero já gastou cinco
     rodadas pagando divergência entre motores. Aqui o `overflow:hidden` mora
     no .hero__cena, um nível ACIMA da perspectiva, então não há o que
     achatar.

     perspective:300px sobre uma faixa de ~290px dá uma lente perto dos 46°
     verticais da câmera do desktop (PerspectiveCamera(46,...)). O ponto de
     fuga fica no horizonte, que é onde o olho de quem dirige está. */
  .cena__mundo{
    position:absolute;inset:0;
    perspective:300px;
    perspective-origin:50% var(--horizonte,38%);
  }

  /* --- CÉU -----------------------------------------------------------------
     O shader de quatro linhas do desktop é um degradê vertical de duas
     cores. Aqui é um degradê vertical de duas cores. Mesma coisa, sem GPU. */
  .cena__ceu{
    position:absolute;left:0;right:0;top:0;
    height:calc(var(--horizonte,38%) + 2px);   /* +2px: sem fresta no horizonte */
    /* O CALOR SOBE CEDO, e este número foi corrigido olhando o desktop lado a
       lado. A primeira versão só ficava dourada nos últimos 20% da faixa e a
       cena inteira lia verde-escura, enquanto o desktop é dominado por uma
       bruma dourada. Numa faixa de 110px de céu não há espaço pra rampa
       longa: o ouro precisa começar no meio. */
    background:linear-gradient(to bottom,
      #22453a 0%,#42553f 26%,#8f7f4e 56%,#d9a95f 82%,#f0bd6a 100%);
  }

  /* --- MORROS --------------------------------------------------------------
     Os quatro cones do desktop viram uma silhueta recortada. Na faixa do
     celular eles têm 30px de altura: cone ou polígono, o que se lê é o
     recorte contra o céu, e o recorte é idêntico. */
  .cena__morros{
    position:absolute;left:-6%;right:-6%;
    bottom:calc(100% - var(--horizonte,38%));
    height:11%;
    background:#1d2c25;
    clip-path:polygon(
      0% 100%, 4% 62%, 11% 88%, 19% 34%, 27% 76%, 34% 52%,
      43% 82%, 52% 28%, 61% 70%, 69% 46%, 77% 80%, 86% 40%,
      93% 74%, 100% 58%, 100% 100%);
  }

  /* --- A PISTA -------------------------------------------------------------
     Um plano deitado. `top:100%` ancora a borda de perto no pé da faixa e
     `rotateX(-90deg)` em torno da borda de CIMA joga o resto do plano pra
     longe, até o ponto de fuga. O plano tem 2600px de comprimento: o fim
     dele cai a poucos pixels do horizonte e é comido pela névoa, que é
     exatamente o que a THREE.Fog faz no desktop.

     A seção transversal (terra, acostamento, faixa de borda, asfalto) é UM
     degradê horizontal, na mesma proporção do desktop: lá o asfalto tem
     15.4 de largura e o acostamento 2.2; aqui 624px e 60px. */
  .cena__pista{
    position:absolute;left:50%;top:100%;
    /* 960 de largura, e não 1400: o que aparece na tela junto ao olho são
       402px, e as faixas de terra das pontas só precisam existir até
       encostarem no fundo, que é da mesma cor. Cada 100px a menos de largura
       aqui é ~1 MB a menos de textura no aparelho, e este plano é a maior
       superfície da página. */
    width:960px;height:2600px;margin-left:-480px;
    transform-origin:50% 0%;
    transform:rotateX(-90deg);
    background-color:#33383a;
    background-image:
      /* terra · acostamento · asfalto · e o espelho.
         A faixa de borda CONTÍNUA saiu daqui em 2026-08-14: a marcação das
         bordas virou tracejada e viva, e mora nos dois planos .cena__faixa,
         que andam. Pintar borda contínua aqui embaixo deixaria as duas
         marcações empilhadas no mesmo lugar. */
      linear-gradient(to right,
        #3a3628 0,#3a3628 calc(50% - 364px),
        #3a3226 calc(50% - 364px),#3a3226 calc(50% - 304px),
        #33383a calc(50% - 304px),#33383a calc(50% + 304px),
        #3a3226 calc(50% + 304px),#3a3226 calc(50% + 364px),
        #3a3628 calc(50% + 364px),#3a3628 100%);
    background-repeat:no-repeat;
  }

  /* --- AS FAIXAS DAS BORDAS, QUE SÃO O QUE CORRE ----------------------------
     NÃO EXISTE MAIS FAIXA CENTRAL AQUI (2026-08-14, pedido do Alê). A
     divisória de mão era o único elemento da cena que dizia de que lado da
     pista cada um está, e o desktop tem o caminhão deliberadamente na faixa
     da direita. Tirada a divisória, a estrada continua lida como estrada,
     porque a marcação continua ali: ela mudou de lugar, do centro para as
     duas bordas, e continua tracejada e correndo.

     São DOIS planos gêmeos em vez de um. Um plano único e largo o bastante
     para carregar as duas bordas custaria 640x3400 (2,1 milhões de pixels
     de textura no aparelho); dois planos estreitos custam 16x3400 cada, que
     é o mesmo orçamento da faixa central que saiu.

     O histórico de por que isto é um plano PRÓPRIO, e não uma camada de
     fundo da pista, continua valendo palavra por palavra:
     Ela começou dentro do plano da pista, como mais uma camada de fundo
     deslocada por `background-position`. Funcionava e estava errado: mudar
     background-position INVALIDA E REPINTA o elemento, e o plano da pista
     tem 960x2600 (2,5 milhões de pixels). Repintar isso a cada quadro de
     rolagem é o tipo de conta que um celular quente não entrega, e foi
     medido nesta bancada custando o dobro do resto da cena junto.

     Agora a faixa é um plano PRÓPRIO, estreito (16x3400, 54 mil pixels) e
     deitado como a pista, e ela anda em Z como os postes. O ganho não é de
     bytes, é de natureza da conta: depois desta mudança NENHUM elemento da
     cena repinta durante a viagem. Tudo que muda é `transform` e `opacity`,
     que são as duas propriedades que o compositor resolve sozinho.

     Ela flutua 1px acima do asfalto de propósito. Coplanar com a pista, a
     ordem de desenho entre as duas passaria a depender de como cada motor
     ordena planos empatados, que é exatamente a classe de divergência entre
     WebKit e Blink que já custou cinco rodadas a este hero. 1px resolve por
     construção e, a partir de poucos metros de distância, é sub-pixel. */
  .cena__faixa{
    position:absolute;left:50%;top:100%;
    /* --lado é a distância do eixo da pista até o CENTRO da marcação, e
       304px é exatamente onde o asfalto termina no degradê da .cena__pista */
    width:16px;height:3400px;margin-left:calc(var(--lado,0px) - 8px);
    transform-origin:50% 0%;
    /* a translação vem ANTES da rotação: assim o deslocamento é no Z do
       mundo (o comprimento da estrada), e não no eixo já girado */
    transform:translate3d(0,-1px,var(--avanco,0px)) rotateX(-90deg);
    background-image:linear-gradient(to bottom,
      #e8e2d2 0,#e8e2d2 110px,transparent 110px,transparent 300px);
    background-size:16px 300px;      /* um período exato: nunca há emenda */
    background-repeat:repeat-y;
  }
  .cena__faixa--esq{--lado:-304px}
  .cena__faixa--dir{--lado:304px}

  /* --- DEFENSA -------------------------------------------------------------
     A BoxGeometry de 380 de comprimento do desktop, aqui um plano em pé
     virado pra dentro da pista. Uniforme ao longo do comprimento: fica
     parada e ninguém percebe, como o asfalto. */
  .cena__defensa{
    position:absolute;left:50%;top:100%;
    width:2400px;height:22px;margin-left:404px;
    transform-origin:0% 100%;
    transform:translate3d(0,calc(-100% - 12px),0) rotateY(90deg);
    /* Puxada pro quente e pro escuro depois da comparação com o desktop: em
       cinza claro ela virava a coisa mais brilhante do quadro e roubava o
       olho do caminhão, que é quem tem que ser visto. */
    background:linear-gradient(to bottom,#7d8279,#59645b);
  }

  /* --- POSTES --------------------------------------------------------------
     Estes são os únicos objetos que ANDAM, junto com a faixa: é neles que a
     viagem se lê. Cada um vem em Z e, ao chegar perto, sai de quadro pela
     direita, que é o que um poste de verdade faz pela janela. A base assenta
     na pista sozinha, porque um ponto na altura do chão a Z metros projeta
     no mesmo lugar que o chão a Z metros: a conta é do navegador. */
  .cena__poste{
    position:absolute;left:50%;top:100%;
    width:9px;height:330px;margin-left:470px;
    background:linear-gradient(to right,#3d4c45,#4a5a52 45%,#5b6a62);
    /* --z é a distância de partida; o avanço é o mesmo para todos, então
       eles nunca se cruzam nem mudam de ordem. */
    transform:translate3d(0,-100%,calc(var(--z,0px) + var(--avanco,0px)));
  }
  /* nth-OF-TYPE, e não nth-child: os postes são os únicos <i> do mundo, os
     outros elementos da cena são <div>. Era nth-child(4..8) e quebrou no dia
     em que a faixa central virou duas faixas de borda, porque a contagem de
     irmãos andou um. Contando só entre <i>, nenhum plano novo na cena volta
     a deslocar os postes. */
  .cena__poste:nth-of-type(1){--z:-900px}
  .cena__poste:nth-of-type(2){--z:-1250px}
  .cena__poste:nth-of-type(3){--z:-1700px}
  .cena__poste:nth-of-type(4){--z:-2300px}
  .cena__poste:nth-of-type(5){--z:-3100px}

  /* --- NÉVOA ---------------------------------------------------------------
     A cor do PÉ DO CÉU, nunca uma cor própria. Foi assim que a linha dura do
     horizonte morreu no desktop (achado do CONTRAIA registrado no
     hero-3d.js), e aqui ela já nasce com a correção. É ela que come o fim
     do plano da pista, a base dos morros e a base dos postes distantes. */
  .cena__nevoa{
    position:absolute;left:0;right:0;
    top:calc(var(--horizonte,38%) - 15%);
    height:36%;
    /* Aberta e amaciada: concentrada demais ela virava uma TARJA dourada
       horizontal atravessando a tela, que é exatamente o tipo de faixa reta
       que denuncia máquina. Espalhada, ela vira bruma.

       O PICO SUBIU DE .60 PARA .88 EM 2026-08-02, e o motivo é o oposto do
       que parece. Com a faixa 25% maior a cena virou a metade de baixo da
       primeira tela, e apareceu uma linha reta clara atravessando o quadro
       exatamente no horizonte: ali o pé do céu (#f0bd6a, a cor mais clara
       da paleta) encosta direto na terra (#3a3628, quase a mais escura), e
       .60 de bruma não dava conta de dissolver um degrau desse tamanho.
       A bruma é da MESMA cor do pé do céu: levá-la a .88 no ponto exato do
       horizonte faz os dois lados da emenda virarem a mesma cor, e a linha
       deixa de existir em vez de ser disfarçada. O pico fica em 42% da
       altura desta camada, que é onde o horizonte cai (ela começa 15% acima
       dele e tem 36% de altura). As saias continuam longas nos dois lados,
       que é o que mantém a leitura de bruma e não de tarja. */
    background:linear-gradient(to bottom,
      rgba(240,189,106,0) 0%,
      rgba(240,189,106,.26) 22%,
      rgba(240,189,106,.88) 42%,
      rgba(240,189,106,.48) 58%,
      rgba(240,189,106,.22) 76%,
      rgba(240,189,106,0) 100%);
  }

  /* --- O FIM DE TARDE ------------------------------------------------------
     No desktop três coisas são interpoladas em paralelo (céu alto, céu baixo
     e névoa). Aqui uma camada só faz o serviço das três, porque ela é ela
     mesma um degradê: azula o alto (#18313c), esquenta e escurece a linha do
     sol (#d98f52 puxado pra baixo) e fecha o chão. Uma camada de opacidade é
     a coisa mais barata que existe pra compor, e é a única propriedade que
     muda aqui além dos transforms. */
  .cena__noite{
    position:absolute;inset:0;
    background:linear-gradient(to bottom,
      rgba(24,49,60,.95) 0%,
      rgba(26,52,58,.74) 26%,
      rgba(151,79,38,.30) 40%,
      rgba(120,60,28,.34) 52%,
      rgba(14,26,24,.66) 100%);
    /* reserva 0 sem script: a viagem começa de dia, como no desktop */
    opacity:calc(var(--vprog,0) * .82);
  }

}
}
/* fim da cena. Daqui pra baixo fica o caminhão, que NÃO depende de
   perspectiva nenhuma e por isso mora fora do @supports: se um navegador não
   tiver 3D, ele perde a estrada e continua com a foto e o caminhão chegando
   por cima dela, que é um hero honesto. */

@media (prefers-reduced-motion:no-preference){

  /* --- A PLACA DE TEXTO SAIU DA FAIXA (2026-08-02, pedido do Alê) ----------
     O Alê: "texto ainda fica em cima da rolagem do caminhão". Medido nesta
     bancada a 402x753, em passos de rolagem: era literal. A placa
     (.etapa--fecho: rótulo, título e sub, 156px de altura, largura inteira)
     morava ancorada no PÉ da mesma faixa em que o caminhão cresce, e o
     caminhão chega com 82% da altura da faixa. Da metade da viagem em diante
     as três linhas ficavam impressas na cabine:
       scrollY 240 · caminhão x114-206 y157-271 · título y244-300
       scrollY 320 · caminhão x93-213  y64-213  · rótulo y134-153 (dentro)
       scrollY 414 · caminhão x67-221  y-45-144 · título y67-123  (dentro)
     Não é ajuste de número: os dois não cabem. Numa tela de 402px não existe
     a saída do desktop (texto na coluna esquerda, caminhão na faixa da
     direita, que foi como o Alê aceitou o mesmo problema lá).

     Então a faixa voltou a ser só cena. E o motivo que pôs o texto ali
     ENVELHECEU: ele foi escrito quando a faixa era "a faixa da foto, que era
     decoração sem argumento". Desde que a estrada e o caminhão entraram, a
     faixa é o argumento da página, e o texto que competia com ela é o mesmo
     que a seção seguinte (#naos, "Três cobranças que aqui não existem") diz
     inteiro, com espaço, dois dedos abaixo. Perdeu-se repetição, não conteúdo.

     Com a placa saíram o lastro (.hero__etapas::after) e os dois progressos
     derivados (--p-lastro e --p-placa), que só existiam para ela. O escurecer
     do fim de tarde sobre o caminhão, que era efeito colateral do lastro e é
     o que impedia o desenho de parecer colado, não se perdeu: virou uma
     camada própria, logo abaixo, com a MESMA cor e a MESMA conta da cena.

     A placa continua no HTML e continua viva no desktop (hero-3d.css). Aqui
     ela volta ao display:none da folha base, sem regra nenhuma. */

  /* --- O CAMINHÃO ----------------------------------------------------------
     O MESMO caminhão que cresce na cena 3D do desktop, agora também aqui.
     Revoga a decisão de 31/07 ("zero imagem nova no celular"): o Alê viu a
     viagem funcionando e disse que o que ele esperava era ver ESTE caminhão
     chegar, não um zoom na foto de fundo. Ele aceitou o peso.

     Nasce pequeno no ponto de fuga da estrada, na pista da esquerda, do
     tamanho de um caminhão a alguns quilômetros: com o farol aceso contra o
     pôr do sol ele lê como trânsito real, não como adesivo. Chega grande e de
     frente, com o motorista visível. Só escala e posição mudam, nunca a arte.

     Ele cresce COM O DEDO, que era o pedido literal do Alê: os dois estados
     são os extremos de uma interpolação em calc() sobre --vprog, como todo o
     resto. Ganho lateral no WebKit: transform mudado por estilo a cada quadro
     é re-rasterizado no tamanho do quadro, enquanto uma transition longa de
     scale tende a rasterizar no tamanho de partida e esticar depois, que é
     borrão garantido.

     A PILHA (z-index 2): cena e foto em 0, véu em 1, caminhão em 2. Abaixo do
     véu ele sumiria, porque o véu chega a verde quase sólido no topo da faixa.
     Empilhamento positivo e explícito, como manda a armadilha documentada no
     HANDOFF. Nada de z-index negativo. O 3 era da placa e ficou vago quando
     ela saiu da faixa, em 2026-08-02.

     A máscara dissolve o topo do baú, que inteiro é um retângulo laranja
     chapado e denuncia recorte. Sem máscara, caminhão inteiro: mais duro,
     nunca quebrado. */
  .hero .hero__caminhao{
    --faixa:var(--faixa-hero);         /* o token do .hero, nunca um gêmeo */
    display:block;                     /* acende o que style.css desligou */
    position:absolute;left:0;right:0;bottom:0;z-index:2;
    height:var(--faixa);
    overflow:hidden;                   /* trava o caminhão dentro da faixa */
    pointer-events:none;
  }
  /* --- A MÃO DE DIREÇÃO (2026-08-03, pedido do Alê) ------------------------
     "O caminhão ficou do lado direito da pista, isso eles vão falar."
     No Brasil se anda pela direita. A arte é FRONTAL, ou seja o caminhão vem
     no sentido contrário, ou seja ele está na contramão de quem olha, ou seja
     na pista da ESQUERDA. Não é escolha de composição: é a única posição que
     não é erro.

     O que estava aqui antes NÃO era o espelho do desktop. Medido nesta
     bancada a 402x753: o eixo do caminhão chegava a 33,3% da tela, que é à
     esquerda da faixa central (a faixa central cai sempre em 50%, porque ela
     está no eixo da perspectiva). Só que ele chegava com 240px de largura numa
     tela de 402, então as RODAS iam até x=220 e a faixa tracejada passava por
     baixo dele: o desenho ficava escanchado na divisória, que é o que um
     caminhoneiro chama de estar na pista errada. O erro grosso estava no
     desktop (lá o caminhão chegava inteiro à direita da faixa) e aqui estava a
     versão ambígua do mesmo erro.

     A CONTA DA CORREÇÃO, e por que ela mexe no tamanho
       · faixa central: x = 201px (50% de 402), em qualquer profundidade
       · rodas do caminhão: 71,8% da largura da caixa (medido no alpha da arte)
       · para as rodas ficarem à esquerda de 201 SEM cortar a caixa na borda
         esquerda, precisa valer 120,2·s ≤ eixo ≤ 201 − 86,3·s, e isso só fecha
         com s ≤ 0,973. Por isso a altura caiu de .82 para .72 da faixa: não é
         gosto, é a única forma de o caminhão caber inteiro do lado dele.
     Resultado a 402x753: caixa de 5 a 216px (nada cortado), RODAS de 35 a
     186px, faixa central livre em 201. O caminhão perde 12% de altura (297px
     para 261px, 72% da faixa) e continua sendo o maior objeto da tela. */
  .hero__caminhao::before{
    content:'';position:absolute;
    /* largura e altura saem as duas da MESMA faixa, então a proporção
       810x1000 da arte vale em qualquer tela e o caminhão nunca achata */
    height:calc(var(--faixa) * .72);
    width:calc(var(--faixa) * .72 * .81);
    /* eixo do caminhão NA CHEGADA. Com a translação fechando em -50% da
       própria largura, o eixo cai exatamente aqui em qualquer tela: o número
       é lido direto, sem depender da altura da faixa. */
    left:27.5%;
    bottom:7.5%;                       /* linha do chão na chegada */
    background:url("../img/gerado/caminhao-frontal-520.webp") no-repeat 50% 100%/contain;
    -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 30%);
            mask-image:linear-gradient(to bottom,transparent 0,#000 30%);
    transform-origin:50% 100%;         /* cresce a partir das rodas */
    /* ESTADO DE PARTIDA, e ele mora FORA do bloco .viagem de propósito: se o
       script não chegar, o caminhão fica parado aqui, pequeno e no lugar
       certo da estrada. Nunca gigante, nunca fora de quadro.

       REAPONTADO EM 2026-08-02. Estes números vinham da FOTO, cujo ponto de
       fuga ficava em outra altura: sobre a cena nova ele nascia 91px ABAIXO do
       horizonte e grande demais. O lugar novo foi CALCULADO na perspectiva da
       cena, não escolhido no olho: a base pousa 26px abaixo do horizonte, onde
       a escala da cena é .146, e o caminhão do desktop tem 178px nas unidades
       desta pista (178 x .146 = 26px de altura na tela = escala .11 da arte).
       Os dois números saem da MESMA conta, então ele assenta na estrada em vez
       de flutuar. 26px e não os 14px que a perspectiva pura pediria: abaixo
       disso ele some na bruma e o Alê já reclamou de não enxergar o caminhão.
       É a única licença poética da cena, e é consciente.

       OS TRÊS NÚMEROS FORAM REESCRITOS EM 2026-08-03 SEM MUDAR UM PIXEL DESTE
       QUADRO. Como a caixa encolheu (.82 → .72 da faixa), a escala de partida
       subiu de .11 para .125 e a translação vertical de 55,4% para 63,1% da
       nova altura: as duas contas devolvem os MESMOS 32,6px de caminhão
       pousados 33px abaixo do horizonte. O que mudou foi só onde ele chega.
       A translação horizontal virou `-50% + 18,8vw`: -50% é o eixo pousando
       exatamente no `left`, e os 18,8vw são o desvio de partida, agora em
       unidade de TELA e não de caixa, então o ponto de nascimento fica em
       46,3% da largura em qualquer aparelho (antes ele derivava da altura da
       faixa e escorregava nas telas largas). 46,3% é logo à esquerda do ponto
       de fuga, que é onde a pista da esquerda cai a essa distância. */
    transform:translate(calc(-50% + 18.8vw),-63.1%) scale(.125);
  }

  /* --- O FIM DE TARDE, TAMBÉM SOBRE O CAMINHÃO -----------------------------
     Sem isto o caminhão parece colado, e essa não é uma opinião nova: é o
     efeito que o lastro da placa produzia de graça ("o lastro cai POR CIMA
     dele conforme a viagem avança, e a frente e as rodas escurecem junto com
     o resto da cena", registrado no HANDOFF como o que integra o desenho à
     luz). A placa saiu; o escurecimento não podia sair junto.

     O caminhão é IRMÃO da cena, não filho dela: mora em z-index 2 e a cena
     inteira em 0, então a camada .cena__noite passa por baixo dele e nunca o
     alcança. Esta camada é a mesma coisa, aplicada por cima: gradiente
     idêntico ao do .cena__noite, mesma conta de opacidade sobre --vprog.
     Fim de tarde único, uma luz só para a estrada e para quem chega nela.

     Custo: uma camada de `opacity`, que é a mesma natureza de conta da que
     ela substitui. Nenhum elemento repinta. */
  .hero__caminhao::after{
    content:'';
    position:absolute;inset:0;pointer-events:none;
    background:linear-gradient(to bottom,
      rgba(24,49,60,.95) 0%,
      rgba(26,52,58,.74) 26%,
      rgba(151,79,38,.30) 40%,
      rgba(120,60,28,.34) 52%,
      rgba(14,26,24,.66) 100%);
    opacity:calc(var(--vprog,0) * .82);
  }

  /* o mesmo ponto para onde o object-position já aponta: quem cresce é o
     caminhão, não a moita da beira da estrada */
  .hero__foto img{transform-origin:60% 46%}

  /* --- A VIAGEM, LIDA DA POSIÇÃO DA ROLAGEM --------------------------------
     Quatro declarações, uma variável, zero relógio. Todas leem --vprog com
     `0` de reserva: se o script não escrever nada, cada uma cai sozinha no
     estado de partida e o hero fica exatamente como é hoje, que é a rede de
     proteção que já custou caro duas vezes neste hero. */

  /* Push-in de 20%, teto decidido no parecer original e mantido: acima disso
     o caminhão da FOTO começa a sair de quadro pela direita. O número aparece
     em um lugar só. */
  html.viagem .hero__foto img{
    transform:scale(calc(1 + .20 * var(--vprog,0)));
  }

  /* O caminhão parte no primeiro pixel de rolagem e só assenta no fim do
     curso: é o movimento mais longo, e é ele que a pessoa está olhando.
     Translação e escala interpolam juntas, exatamente os mesmos dois
     extremos que a transition tinha, agora amarrados ao dedo. */
  html.viagem .hero__caminhao::before{
    transform:
      translate(calc(-50% + 18.8vw - 18.8vw * var(--vprog,0)), calc(-63.1% + 63.1% * var(--vprog,0)))
      scale(calc(.125 + .875 * var(--vprog,0)));
  }
}

/* Quem pediu economia de dados também pediu economia de tudo. Custa duas
   regras e é ganho puro onde o navegador entender. Especificidade igual à
   dos blocos acima, e depois deles no arquivo, para vencer sem !important. */
@media (prefers-reduced-data:reduce){
  /* A cena inteira sai e a FOTO VOLTA. Ela nunca foi apagada do projeto: a
     partir de 2026-08-02 o papel dela é este, ser o hero de quem não pode
     rodar a estrada. Como a cena não custa byte nenhum (é CSS), o que se
     economiza aqui é bateria e composição, não rede. Estas duas linhas vêm
     depois das do bloco da cena e com a mesma especificidade, então vencem
     sem !important. */
  .hero__cena{display:none}
  .hero__foto{display:block}

  /* O caminhão sai daqui com dois ganhos de uma vez: some o movimento E
     somem os 62 KB, porque background de elemento não exibido não é baixado.
     Especificidade casada com a do bloco lá em cima (.hero .hero__caminhao),
     senão esta linha perderia. */
  .hero .hero__caminhao{display:none}
  .hero__foto img,
  html.viagem .hero__foto img{transform:none}
}
