/* ==========================================================================
   NEXUS theme-final / assets/css/sections/hero.css
   Território exclusivo do agente hero. Layout e visual específico de #hero.
   Reaproveita .section/.container (02-base.css), .eyebrow/.lead (02-base.css),
   .btn (03-ui.css), .media-frame (04-sections.css). Só o que é genuinamente
   específico do hero mora aqui: grade da dobra, escalonamento do título,
   halo radial de fundo e os pontos de ruptura próprios (§7.2, §7.4).

   Só consome tokens de 01-tokens.css. Nenhum hex, nenhum px de raio, nenhuma
   família de fonte literal. Motion: só transform e opacity animam, duração
   sempre multiplicada por var(--motion).
   ========================================================================== */

/* --------------------------------------------------------------------------
   Chassi da dobra.
   Altura é restrição de primeira classe (§7.2): min-height por clamp com
   svh, nunca vh, nunca 100vh. overflow: hidden contém o halo radial sem
   gerar scroll horizontal no body.
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  min-height: clamp(560px, 78svh, 880px);

  /* Respiro da dobra: proporcional à ALTURA da viewport, não à largura.
     O padrão --section-y de .section é calculado sobre vw (3rem + 6vw), e
     em 1280x800 valia 124px de cada lado: só de respiro o hero gastava
     250px de uma tela que tem 800px, e o quadro de mídia começava depois
     de 720px, ou seja, praticamente fora da dobra.

     Aqui o topo reserva a barra fixa do header (--header-h) mais uma folga
     em svh, e a base usa svh puro (§7.2: svh, nunca vh, nunca 100vh). Em
     1280x800 dá 104px no topo e 48px na base; em 360x740 dá 44px na base,
     que é o que fecha a lacuna escura entre o quadro de mídia e a régua de
     provas. */
  padding-block-start: calc(var(--header-h) + clamp(var(--space-4), 4svh, var(--space-12)));
  padding-block-end: clamp(var(--space-8), 6svh, var(--space-14));
}

/* Halo radial: camada própria do hero, acima do padrão global de --pattern
   (que vive em body::before, z-index -1) e atrás do conteúdo. Só transform
   anima, gated por --motion via a mesma keyframe nx-drift já definida em
   01-tokens.css / 02-base.css. */
.hero::before {
  content: "";
  position: absolute;
  inset: -20% -8% -12%;
  z-index: 0;
  pointer-events: none;
  /* Luz, não cor. A receita anterior derivava a matiz da marca com calc() e
     saturação literal de 70% a 74%, o que com a paleta neutra (matiz 0)
     produzia âmbar em +40 e rosa em -30. Em um site preto e branco o halo é
     luz branca de baixa opacidade, com um único toque de --signal.

     Só DOIS gradientes agora (topo-esquerda, topo-direita). Havia um
     terceiro, `radial-gradient(50% 46% at 50% 100%, ...)`, ancorado no
     canto inferior-central da caixa deste ::before -- que é a caixa do
     .hero INTEIRO, não a da moldura de mídia. Como o rodapé do hero é só
     respiro (padding-block-end, sem conteúdo próprio), esse terceiro
     gradiente pintava uma mancha clara difusa exatamente ali, visível como
     "nuvem" flutuando entre a base do vídeo e o filete de borda de
     #provas (pedido do dono, com captura). Confirmado isolando a camada:
     removendo só este gradiente (mantendo o box-shadow/blur zero, sem
     tocar mais nada) a mancha some por completo -- os outros dois
     gradientes (ambos no terço superior do hero, atrás do título) nunca
     alcançavam essa região. Vazamento removido, não contido: não havia
     leitura visual que justificasse mantê-lo em nenhuma caixa. */
  background:
    radial-gradient(46% 52% at 24% 18%, hsl(var(--foreground) / 0.07), transparent 70%),
    radial-gradient(38% 42% at 84% 8%, hsl(var(--signal) / 0.08), transparent 68%);
  animation-name: nx-drift;
  animation-duration: calc(var(--motion) * 32s);
  animation-timing-function: var(--ease-io);
  animation-iteration-count: infinite;
  animation-direction: alternate;
  will-change: transform;
}

.hero__grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr;
  /* mesmo raciocínio do padding: o intervalo entre a copy e o quadro de
     mídia é medido em svh, porque é altura que falta na dobra, não largura */
  gap: clamp(var(--space-8), 5.5svh, var(--space-12));
  inline-size: 100%;
}

/* --------------------------------------------------------------------------
   Copy: eyebrow, título, lead, CTAs. Centralizado no layout padrão
   (empilhado), à esquerda no layout de duas colunas do ultrawide baixo.
   -------------------------------------------------------------------------- */

/* grid-template-columns explícito (não "auto" implícito): sem ele o único
   trilho desta grade se dimensiona pelo max-content dos filhos -- e como
   justify-items:center também tira o item de stretch, cada filho (h1, .lead,
   .hero__ctas) media a si mesmo pelo próprio conteúdo em vez de ocupar a
   largura disponível. Era a causa raiz do bloco de copy medir 588px numa
   faixa que tinha mais de 1000px livres (pedido do dono, 3 capturas,
   05/08/2026): "aumentar a largura do bloco de texto" não pedia um teto
   maior (o max-width abaixo já dava até 1024px), pedia este trilho realmente
   USAR o teto que já existia. minmax(0, 1fr) faz o único trilho ocupar todo
   o espaço livre do item (que por sua vez já estica dentro de .hero__grid,
   herdando o comportamento padrão de grid item). */
.hero__copy {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  /* Passo acima do que era (space-4/6): pedido explícito do dono, via
     captura do DEPOIS aprovado -- "mais respiro entre título, lead e
     botões do que no arranjo antigo", citando que o texto não pode ficar
     grudado. */
  gap: clamp(var(--space-5), 3.2svh, var(--space-7));
  max-width: min(100%, 64rem);
  margin-inline: auto;
  text-align: center;
}

/* O título do hero não usa --fs-h1 puro.

   --fs-h1 é uma clamp de largura (1.5rem + 4.2vw): em 1280x800 dava 78px e
   o título de quatro linhas sozinho comia 321px, empurrando o quadro de
   mídia para além dos 720px e cortando a dobra. O termo min(..., svh)
   acrescenta a altura à conta: em telas baixas o título encolhe mesmo que a
   tela seja larga, que é exatamente o caso de 1280x800, 1440x900 e do
   ultrawide 29" (2560x1080).

   Continua multiplicado por --scale, como todo tamanho do §3, para o
   estúdio e as media queries do §7.3 seguirem valendo, e continua sem
   nenhum px fixo. */
/* Entrelinha e passo entre as linhas do título, revistos a pedido do dono
   (mesma rodada do item acima): --lh-display (1.02) é a entrelinha "de
   catálogo" do §3, calibrada para título de UMA linha; aqui o título é
   sempre multilinha (partials/hero.js quebra cada frase de content.js num
   <span> próprio) e 1.02 lia como texto grudado. 1.12 é só deste
   componente -- não sobe a --lh-display global, que serviria a outros
   títulos de uma linha só -- e seguindo o mesmo precedente das peles (glass
   usa 1.14, surface 1.1, cult 1.04: cada uma já escreve line-height literal
   aqui, não um token novo). O gap entre os <span> sobe de space-1 para
   space-2 pelo mesmo motivo: mais respiro visível entre as linhas. */
.hero__title {
  display: grid;
  gap: var(--space-2);
  font-family: var(--font-display);
  font-size: calc(clamp(2.2rem, min(1.05rem + 3.35vw, 8svh), 4.6rem) * var(--scale));
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: var(--tracking-display);
  color: hsl(var(--foreground));
}

.hero__line {
  display: block;
}

/* Última linha: peso e cor diferenciados, a assinatura da seção. */
.hero__line--accent {
  font-weight: 800;
  color: hsl(var(--primary));
}

.hero__lead {
  margin-inline: auto;
}

.hero__ctas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
}

/* --------------------------------------------------------------------------
   Vídeo/mídia.

   O quadro NÃO usa mais .media-frame--blend. O `mix-blend-mode: screen` de
   04-sections.css foi calibrado para nexus-loop, uma marca clara sobre preto,
   onde o screen servia para dissolver o preto do arquivo. O vídeo atual
   (nx-plates-ring) são placas de vidro ESCURAS sobre preto, já dessaturadas:
   contra o véu o screen só levanta o preto, o quadro fica leitoso e a
   separação entre placa e fundo, que é o assunto da peça, some. Medido nos
   dois temas antes de remover.

   O que o blend trazia de útil era o FUNDO: .media-frame--blend pintava
   hsl(var(--scrim)) por baixo, e por isso o quadro ficava igual nos dois
   temas. Esse fundo continua, declarado aqui, no lugar de --muted (que é
   quase branco no tema claro e transformaria qualquer falha de carga do
   vídeo em uma caixa clara no meio da dobra escura).

   A máscara de gradiente nas bordas vem de .media-frame (04-sections.css),
   reaproveitada sem reescrita.
   -------------------------------------------------------------------------- */

.hero__stage {
  position: relative;
  inline-size: 100%;
}

/* O motor de scroll (core/fx.js, scroll-paralaxe, grupo global) escrevia um
   translate3d vertical em TODO ".media-frame video/img" do site, sem exceção
   por seção. --media-ratio aqui é a proporção EXATA do filme orbita-piso
   (abaixo) e object-fit: cover não corta nenhuma sobra — então, com o
   paralaxe ligado, o primeiro pixel de deslocamento expunha o fundo --scrim
   da moldura como tarja (a "barra preta" do pedido anterior). A correção
   daquela vez foi dar 9% de sobra por lado ao vídeo (overscan) só para
   esconder esse deslocamento — só que a folga cortava o TOPO do logo
   ("X NEXUS") que o filme mostra, pedido do dono para devolver inteiro.

   Correção definitiva: o vídeo do hero saiu do alcance do paralaxe (atributo
   `data-paralaxe="off"` em partials/hero.js, opt-out lido no unico ponto de
   colheita de alvo de core/fx.js, `aplicar()`). Sem deslocamento nenhum não
   há mais o que o overscan precisasse esconder — o vídeo volta a cobrir
   exatamente os 4 lados da moldura, sem sobra e sem falta, com o logo
   inteiro (incluindo o topo) visível. */
.hero__media video,
.hero__media img {
  object-fit: cover;
}

.hero__media {
  --media-ratio: 1600 / 694; /* proporcao exata do filme orbita-piso */
  inline-size: 100%;
  max-width: var(--container-wide);
  margin-inline: auto;
  /* palco escuro nos dois temas: o pôster e o vídeo são pretos, e o quadro
     não pode piscar claro entre o primeiro paint e o primeiro frame */
  background-color: hsl(var(--scrim));

  /* O motor de revelação (core/fx.js) aplica UM efeito por seção a TODO
     [data-reveal] dentro dela — na hero é rev-mascara-linhas, calibrado para
     fatiar A FRASE do título em linhas (comentário do próprio motor: "a
     dobra revela uma FRASE"). Sem linhas de texto para fatiar, o motor tem
     um fallback documentado ("Sem alvo fatiavel, cai em subir"): um leve
     rev-subir de 28px. O bug era o motor ENXERGAR linha onde não tinha:
     .hero__stage[data-reveal] só tem ESTE elemento como filho, e por ser
     display:block ele passava no teste "filhos são block/flex/grid" que o
     motor usa para decidir se fatia — então tratava o quadro de vídeo
     inteiro como se fosse uma linha de texto e o arrastava 110% da própria
     altura (o pulo de ~350px reportado). display: flow-root continua
     block-level (mesmo encaixe, mesma largura, sem o espaço fantasma de
     inline-block) mas seu valor computado não é "block", então o motor não
     reconhece mais o quadro como fatiável e cai no fallback correto. */
  display: flow-root;
}

/* O FILME DO TOPO FICA EM TODAS AS LARGURAS (06/08/2026). Houve uma volta
   atrás registrada aqui de propósito: numa primeira leitura o pedido de
   "no mobile não precisa exibir esse vídeo" foi aplicado a ESTE filme, mas
   o dono esclareceu logo depois — "pode deixar o do topo da página e
   remover esse aí" — apontando o palco de #capacidades. Quem sai do
   celular é aquele (ver sections/capacidades.css), não este. */

/* --------------------------------------------------------------------------
   §7.4 (promovido a padrão de fábrica, 06/08/2026): duas colunas -- copy à
   esquerda, vídeo à direita -- passam a ser o arranjo PADRÃO da dobra em
   telas largas, não mais uma exceção de ultrawide baixo. Pedido do dono,
   com ANTES e DEPOIS em captura: no ANTES (empilhado) o vídeo virava uma
   faixa larga e alta que dominava a tela; no DEPOIS (aprovado) o título e o
   lead ficam à esquerda e o vídeo encolhe para uma moldura quase quadrada à
   direita, ~metade da largura da coluna de texto, centralizada com o bloco
   de texto.

   Por que promover em vez de duplicar: o sistema de Seções 2.0 já tinha
   ESTE MESMO arranjo como variante opcional,
   html[data-nx-lay~="hero:lateral"] (assets/css/12-secoes.css, bloco 2,
   ativa a partir de 60rem/960px com proporção 0.9fr/1.1fr). Duplicar essa
   grade aqui seria a mesma decisão escrita duas vezes. A variante continua
   existindo (não é território deste agente editar 12-secoes.css), mas com
   o padrão de fábrica cobrindo o mesmo resultado ela fica redundante --
   registrado para o dono/outro agente em
   scratchpad/pendencias-i18n-hero.md.

   Limiar 1080px, não 960px como a variante: cult (09-skin-cult.css) e
   surface (08-skin-surface.css) já têm grade de duas colunas SEMPRE ligada
   para o hero, cada uma com seu próprio limiar (1080px e 1024px), e as
   duas rodam em seletor mais específico que ganha desta regra em qualquer
   largura. 1080px é o maior desses dois limiares: abaixo dele nenhuma pele
   com grade própria ainda decidiu nada, então esta regra nunca abre uma
   janela de transição onde a fábrica já virou 2 colunas mas a pele
   ainda está com o CSS de 1 coluna (o problema que a própria 09-skin-cult
   já documenta ter resolvido para a janela ultrawide antiga). Pele
   "smooth" nem entra nessa conta: esconde .hero__stage por decisão de
   identidade, sem media query (10-skin-smooth.css), em qualquer largura.

   Proporção 1.4fr/1fr, não 1fr/1fr nem 0.9/1.1 da variante: medida na
   captura do DEPOIS (dono, 1760px de viewport) -- moldura de vídeo em
   ~550×540px, quase quadrada, a coluna de texto nitidamente mais larga.
   Com o container em 1760px (~1440px de .hero__grid, gap de --space-14),
   1.4fr/1fr entrega ~751px de coluna de texto (4 linhas confortáveis de
   título + 2 do lead, como a captura) e ~537px de coluna de vídeo -- a 13px
   do medido, dentro da margem de "aproximadamente" de uma medição feita a
   olho sobre print.

   --media-ratio: 1/1, não mais 4/3: também da medida da captura (550/540 =
   1,02, praticamente quadrado). Verificado que o logo cabe inteiro num
   recorte 1:1 do frame de vídeo (recorte de teste sobre
   assets/video/nexus-orbita-piso.jpg, centralizado, sem cortar nenhuma
   ponta do X nem do NEXUS) -- mesmo cuidado que gerou o data-paralaxe="off"
   e o overscan removido logo acima: aqui não sobra crop nenhum, é só a
   proporção do quadro que muda, o vídeo continua object-fit:cover sem
   deslocamento algum. */

@media (min-width: 1080px) {
  /* PAINEL QUASE QUADRADO (06/08/2026, terceira volta do dono, com captura
     aprovada e a medida que ele mesmo testou: "fiz com 450/500px, mas não
     deve ser assim que você faz, só para ter uma ideia").

     O histórico desta linha, porque ele explica o vaivém: o quadro 1:1
     cortava o wordmark (a razão do filme é 2,30 e um quadrado descarta 57%
     da largura); a razão exata do filme não cortava nada, mas deixava o
     painel com 217px de altura ao lado de um bloco de texto alto, e ficou
     "pequeno" na palavra dele. O ponto de equilíbrio é um quadro POUCO
     mais largo que alto: perto do quadrado que ele quer, com margem para o
     wordmark que 1:1 não tinha.

     A largura é limitada por max-inline-size (na ordem dos 500px que ele
     testou) em vez de sair de uma fração da grade: assim o painel não
     cresce indefinidamente em telas largas e a coluna de texto fica com a
     sobra, que é a leitura da captura aprovada. */
  .hero__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    gap: var(--space-12);
  }

  .hero__copy {
    justify-items: start;
    margin-inline: 0;
    text-align: left;
  }

  .hero__lead {
    margin-inline: 0;
  }

  .hero__ctas {
    justify-content: flex-start;
  }

  /* ZOOM OUT DO FILME (06/08/2026, pedido do dono: "dá um zoom out nele,
     está muito perto; quando roda corta um pedaço do nome").

     A moldura quadrada foi calibrada sobre o PÔSTER, e o pôster engana: o
     filme é 1600x694 (proporção 2,30) e um quadro 1:1 com object-fit: cover
     mostra só a faixa central de 694 de largura, ou seja, DESCARTA 57% do
     quadro. Parado, o logo cabia na sobra; em movimento, o vaivém da órbita
     leva o wordmark para fora do recorte e corta a palavra. Foi o pôster que
     escondeu o defeito, não a medição que estava errada.

     A correção devolve a proporção EXATA do filme ao quadro: com
     object-fit: cover e a mesma razão do arquivo, o recorte é zero e nada
     mais sai da moldura em nenhum instante da animação. A coluna continua
     com a mesma largura (o arranjo de duas colunas não muda); o que muda é
     a altura do painel, que passa a acompanhar o filme em vez de forçá-lo
     dentro de um quadrado. É a mesma disciplina do bloco de cima, onde
     --media-ratio já era "a proporção EXATA do filme orbita-piso". */
  .hero__media {
    --media-ratio: 6 / 5;
    max-width: 32rem;
    margin-inline: auto 0;
  }
}

/* --------------------------------------------------------------------------
   Guarda de pele smooth (mesma causa do bloco "Guarda de pele" que
   12-secoes.css já mantém para hero:lateral/palcoprimeiro -- aqui é a
   correção equivalente para o padrão de fábrica).

   A pele smooth esconde .hero__stage por decisão de IDENTIDADE, não por
   bug: display: none, sem media query nenhuma, em QUALQUER largura
   (10-skin-smooth.css, "Ponto 6: o quadro de vídeo sai da dobra"). Este
   agente não edita 10-skin-smooth.css (fora do território), então a
   correção mora aqui, no lado que introduziu a grade de duas colunas.

   Sem esta guarda, a regra acima abre a SEGUNDA trilha (a de
   --media-ratio) mesmo sem nada para ocupá-la -- grid-template-columns
   declara trilhas explícitas, e uma trilha explícita existe mesmo vazia,
   um item display:none não a colapsa sozinho. Medido: em 1280px sob
   smooth, .hero__copy caía de 864px (a largura cheia que esta pele pede,
   texto centrado) para 645px alinhado à esquerda, com ~460px de vazio à
   direita -- exatamente o defeito "título de um lado, nada do outro, meia
   tela desperdiçada" que o bloco irmão de 12-secoes.css já documentou para
   a variante hero:lateral. */
@media (min-width: 1080px) {
  :is([data-skin="smooth"], [data-skin-base="smooth"]:not([data-skin])) .hero__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  :is([data-skin="smooth"], [data-skin-base="smooth"]:not([data-skin])) .hero__copy {
    justify-items: center;
    margin-inline: auto;
    text-align: center;
  }

  :is([data-skin="smooth"], [data-skin-base="smooth"]:not([data-skin])) .hero__lead {
    margin-inline: auto;
  }

  :is([data-skin="smooth"], [data-skin-base="smooth"]:not([data-skin])) .hero__ctas {
    justify-content: center;
  }
}

/* --------------------------------------------------------------------------
   §7.2: paisagem com altura útil abaixo de 700px reduz o título e compacta
   o ritmo vertical da dobra, para a dobra inteira não engolir a viewport.
   -------------------------------------------------------------------------- */

@media (orientation: landscape) and (max-height: 700px) {
  .hero {
    min-height: clamp(480px, 88svh, 700px);
  }

  .hero__grid {
    gap: var(--space-6);
  }

  .hero__copy {
    gap: var(--space-3);
  }

  .hero__title {
    font-size: calc(clamp(1.7rem, 1.1rem + 3.2vw, 2.75rem) * var(--scale));
  }
}

/* --------------------------------------------------------------------------
   Mobile: o gatilho do estúdio é fixo na viewport, então nenhum padding do
   hero o afasta; quem resolve a sobreposição sobre a marca é o recuo que
   studio.js aplica enquanto a dobra está em vista (data-recuado, tratado em
   07-studio.css). O que cabe a esta folha é o outro lado do defeito: a
   lacuna escura entre o quadro de mídia e a régua de provas, que era o
   padding-block-end de --section-y. Com o respiro em svh declarado no topo
   deste arquivo a base do hero cai para cerca de 44px em 360x740, e o
   quadro passa a ocupar mais da faixa que antes ficava vazia.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
  .hero__media {
    /* o quadro usa a largura toda do container no mobile: sem o teto de
       --container-wide sobra menos moldura e a marca fica maior */
    max-width: none;
  }
}

/* --------------------------------------------------------------------------
   Alvo de toque e empilhamento em telas muito estreitas: os dois CTAs
   ocupam a largura inteira, um por linha, mantendo --tap-min herdado
   de .btn.
   -------------------------------------------------------------------------- */

@media (max-width: 480px) {
  .hero__ctas {
    flex-direction: column;
    align-self: stretch;
    inline-size: 100%;
  }

  .hero__ctas .btn {
    inline-size: 100%;
  }
}

/* --------------------------------------------------------------------------
   prefers-reduced-motion: o halo para de derivar. O vídeo é pausado por JS
   (hero.js, no 'nx:mounted'); aqui só a parte puramente visual do CSS.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .hero::before {
    animation: none;
  }
}

/* (Experimento hero--film desfeito a pedido do dono na mesma rodada: o
   filme em tela cheia leu feio e pesado. A moldura abaixo da copy ficou.) */
