/* ==========================================================================
   HERO — vídeo em loop como superfície · prefixo vfd-

   Tokens usados:
     --dark --dark-rgb   fundo da dobra, scrim, véu e emenda
     --fg --fg-2         tinta da headline e do apoio
     --fg-muted          rótulo da régua
     --rule              filete da régua
     --accent            realce em itálico e chave da régua
     --display           face da headline e das chaves
     --fs-body           corpo do apoio
     --nav-h             folga do menu fixo no topo da dobra
     --ease              curva única do projeto

   Parafusos (custom properties do próprio componente, §3):
     --vfd-alt           altura da dobra
     --vfd-video-op      opacidade do vídeo sob o scrim — o parafuso do
                         CONTRASTE, ver a nota abaixo
     --vfd-veu-alt       altura do véu desfocado
     --vfd-veu-blur      raio do desfoque do véu — o ÚNICO custo por quadro
                         desta peça. Zerar mantém o degradê e devolve a GPU.

   POR QUE --vfd-video-op É .46 NO DESKTOP E .38 NO CELULAR, e não um número
   redondo: os dois saíram de medição de PIXEL, não de gosto. O que se mediu
   foi a razão de contraste WCAG de cada texto contra o quadro renderizado,
   no pior pixel de cada caixa, e o cenário de aferição é um quadro de vídeo
   BRANCO CHAPADO — nenhum vídeo real é mais claro que isso, então o número
   medido ali é o PISO do contraste da peça, não a média dela.

     opacidade      1440x900: título / apoio        390x844: título / apoio
       .52              4,69   /  3,99                  —
       .46              5,47   /  4,60                5,28  /  3,76
       .38                —                           6,54  /  4,61

   O alvo é 4,5:1 em todos os quatro textos, que é o mínimo da WCAG AA para
   texto normal — o título ainda é texto grande e só precisaria de 3:1, mas
   passar o apoio já obriga a chegar lá. Com o poster real desta demo, os
   mesmos textos medem 10,1 / 7,4 / 11,8 / 5,9. Ou seja: a peça é AA contra
   QUALQUER vídeo, e não só contra um vídeo bem-comportado.

   O celular precisa de mais escuro porque a copy ocupa uma fração muito
   maior da dobra: o apoio sobe até a faixa mais clara do scrim, onde no
   desktop só há imagem. Quem tiver um vídeo escuro de verdade pode subir o
   parafuso — a tabela acima é para a decisão ser informada, não para o
   número ser sagrado.

   A REGRA QUE ORGANIZA O ARQUIVO: nenhum estado de repouso depende só do
   script. Cada bloco que nasce invisível tem, colado nele, o
   @media(scripting:none) que o devolve pronto e o
   @media(prefers-reduced-motion) que o entrega parado. Sem os dois, uma
   página sem JavaScript mostraria vídeo e nada mais — que é o defeito exato
   que o core/motion.css trata para os ganchos DELE, e que nenhum componente
   herda de graça quando o portão é uma classe própria.

   NÃO HÁ [data-rv] AQUI, e não é esquecimento. Hero está acima da linha de
   corte: já intersecta na carga, e o que se quer é uma CASCATA em ordem
   escrita (linha, linha, apoio, ações, régua), não cinco reveals disparando
   juntos. Quem abre o portão é a classe .in que o script põe na raiz.

   NÃO HÁ PARALLAX, ao contrário do irmão hero/full-bleed-media. Lá o
   deslocamento existe justamente porque a foto está parada. Aqui a mídia já
   é movimento; somar um segundo eixo faria a dobra inteira nadar.
   ========================================================================== */

.vfd{
  --vfd-alt:100vh;
  --vfd-video-op:.46;
  --vfd-veu-alt:56%;
  --vfd-veu-blur:10px;

  position:relative;overflow:hidden;
  background:var(--dark);
  min-height:var(--vfd-alt);
}
/* svh desconta a barra do navegador no celular, onde vh a ignora e o pé da
   dobra fica embaixo dela. Em @supports porque a peça tem de abrir inteira
   em base antiga, e ali vh é o que existe. */
@supports (height:100svh){.vfd{--vfd-alt:100svh}}

/* ---- mídia ----------------------------------------------------------------
   z-index:0 de propósito: cria o contexto de empilhamento que prende o
   .grain (que traz z-index:1 do core) aqui dentro, e deixa véu e corpo
   ordenados sem ninguém adivinhar número. */
.vfd-media{position:absolute;inset:0;z-index:0;overflow:hidden}

/* object-fit vale para o vídeo E para o poster. Sem ele o poster de 16:9
   entra com tarja dos dois lados em tela mais alta que larga — e o poster é
   o que sustenta a dobra em três casos reais: movimento reduzido, economia
   de dados e autoplay recusado. */
.vfd-video{
  position:absolute;inset:0;
  width:100%;height:100%;
  object-fit:cover;object-position:50% 46%;
  opacity:var(--vfd-video-op);
}

/* Dois gradientes cruzados. O VERTICAL é o principal, e essa é a diferença
   de forma para o irmão de foto: lá o texto mora à esquerda e o scrim é
   horizontal a 100°; aqui o texto atravessa a coluna inteira ancorado
   embaixo, e o que precisa escurecer é o pé — mais o topo, por causa do
   menu fixo. O horizontal entra fraco, só para o canto direito não brilhar
   sozinho em tela larga. */
.vfd-scrim{
  position:absolute;inset:0;
  background:
    linear-gradient(to bottom,
      rgba(var(--dark-rgb),.60) 0%,
      rgba(var(--dark-rgb),.18) 26%,
      rgba(var(--dark-rgb),.30) 54%,
      rgba(var(--dark-rgb),.62) 100%),
    linear-gradient(92deg,
      rgba(var(--dark-rgb),.40) 0%,
      rgba(var(--dark-rgb),.08) 54%,
      rgba(var(--dark-rgb),.26) 100%);
}

/* Dissolve a dobra no fundo da página. Sem isto o vídeo termina em corte
   reto contra a seção seguinte, e a emenda fica visível em tela larga. */
.vfd-fade{
  position:absolute;left:0;right:0;bottom:0;height:30%;
  background:linear-gradient(to bottom,
    rgba(var(--dark-rgb),0) 0%,
    rgba(var(--dark-rgb),.34) 46%,
    rgba(var(--dark-rgb),.84) 80%,
    rgb(var(--dark-rgb)) 100%);
}

/* ---- véu desfocado -------------------------------------------------------
   A regra de forma do §6: backdrop-filter SEMPRE com máscara em degradê.
   Caixa reta desenharia uma linha horizontal dura no meio do vídeo e leria
   "chapado".

   POR QUE O VÍDEO PEDE ISTO E A FOTO NÃO: com foto o autor escolhe o quadro
   e calibra o scrim contra ele. Com vídeo todo quadro é outro — a headline
   tem de sobreviver ao clarão que passa no segundo sete. Gradiente escurece
   a média; o desfoque apaga o DETALHE, que é o que come a leitura de um
   texto claro sobre imagem em movimento.

   É também o único custo por quadro da peça: o desfoque é recalculado
   enquanto a imagem por baixo muda. Em máquina fraca, --vfd-veu-blur:0
   mantém o degradê e devolve a GPU. */
.vfd-veu{
  position:absolute;left:0;right:0;bottom:0;z-index:1;
  height:var(--vfd-veu-alt);pointer-events:none;
  background:linear-gradient(to top,
    rgba(var(--dark-rgb),.62) 0%,
    rgba(var(--dark-rgb),.36) 50%,
    rgba(var(--dark-rgb),0) 100%);
  -webkit-mask-image:linear-gradient(to top,#000 0%,rgba(0,0,0,.9) 46%,transparent 100%);
  mask-image:linear-gradient(to top,#000 0%,rgba(0,0,0,.9) 46%,transparent 100%);
}
/* Mesma cautela do .glass no core: sem suporte sobra só o degradê, em vez de
   uma faixa translúcida e sem função. */
@supports (backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px)){
  .vfd-veu{
    backdrop-filter:blur(var(--vfd-veu-blur)) saturate(112%);
    -webkit-backdrop-filter:blur(var(--vfd-veu-blur)) saturate(112%);
  }
}

/* ---- corpo ---------------------------------------------------------------
   Ancorado embaixo: o topo fica para a mídia respirar sob o menu fixo, e o
   texto vive DENTRO da imagem, como manda o §6. */
.vfd-body{
  position:relative;z-index:2;
  min-height:var(--vfd-alt);
  display:flex;flex-direction:column;justify-content:flex-end;
  padding-top:calc(var(--nav-h) + clamp(40px,8vh,88px));
  padding-bottom:clamp(48px,8vh,96px);
}
.vfd-copy{max-width:min(760px,100%)}

/* ---- headline ------------------------------------------------------------
   Reveal por linha: a máscara é o overflow da .vfd-ln, quem se move é o
   span de dentro. Não use data-split — quebrar por palavra desmancha a
   força de uma headline de seis palavras.

   O blur vem junto, e não é enfeite: o §5 do contrato não aceita entrada
   seca. Termina em blur(0), e não em none, pelo mesmo motivo do core — a
   transição sai de um filtro, e none não interpola a partir de filtro. */
.vfd-title{
  font-family:var(--display);font-weight:700;
  font-size:clamp(32px,5.2vw,60px);line-height:1.08;letter-spacing:-.035em;
  color:var(--fg);margin-top:20px;
}
.vfd-ln{display:block;overflow:hidden}
.vfd-ln > span{
  display:block;
  transform:translateY(112%);opacity:0;filter:blur(12px);
  transition:transform .95s var(--ease),opacity .95s var(--ease),filter 1s var(--ease);
}
.vfd.in .vfd-ln > span{transform:none;opacity:1;filter:blur(0)}
.vfd .vfd-ln:nth-child(2) > span{transition-delay:.09s}
.vfd-title em{font-style:italic;font-weight:700;letter-spacing:-.01em;color:var(--accent)}

/* ---- apoio, ações e pé ---------------------------------------------------
   Cascata em delays fixos: 0,52s / 0,70s / 0,88s, depois das duas linhas. É
   o que dá a leitura de "a página se monta" em vez de "tudo apareceu junto".
   Mesma coreografia do irmão hero/full-bleed-media, de propósito: os dois
   abrem a mesma família de página. */
.vfd-desc{
  font-size:var(--fs-body);line-height:1.6;color:var(--fg-2);
  max-width:56ch;margin-top:24px;
  opacity:0;transform:translateY(14px);filter:blur(10px);
  transition:opacity .8s var(--ease) .52s,transform .8s var(--ease) .52s,filter .9s var(--ease) .52s;
}
.vfd.in .vfd-desc{opacity:1;transform:none;filter:blur(0)}

.vfd-cta{
  display:flex;flex-wrap:wrap;gap:14px;
  margin-top:32px;
  opacity:0;transform:translateY(14px);filter:blur(10px);
  transition:opacity .8s var(--ease) .70s,transform .8s var(--ease) .70s,filter .9s var(--ease) .70s;
}
.vfd.in .vfd-cta{opacity:1;transform:none;filter:blur(0)}

/* Régua à esquerda e controle do vídeo à direita, na mesma linha: o botão
   fica onde o olho procura um controle de mídia, e continua DENTRO da coluna
   do .wrap — sem inset calculado e sem ninguém mexer em padding-inline. */
.vfd-pe{
  display:flex;align-items:flex-end;justify-content:space-between;gap:24px;
  margin-top:clamp(38px,6vh,68px);
  border-top:1px solid var(--rule);padding-top:24px;
  opacity:0;transform:translateY(14px);filter:blur(10px);
  transition:opacity .8s var(--ease) .88s,transform .8s var(--ease) .88s,filter .9s var(--ease) .88s;
}
.vfd.in .vfd-pe{opacity:1;transform:none;filter:blur(0)}

/* Movimento reduzido: os quatro blocos acima nascem no estado final, sem
   transição. Fica COLADO às regras que desliga, como manda o §6.6 — e é
   preciso escrever aqui porque o @media do core cobre só [data-rv], .w e
   .ttl, e esta peça não usa nenhum dos três.

   O core precisa forçar a prioridade nessas regras porque ele não sabe o que
   o componente vai escrever depois dele. Aqui não precisa, e por isso não
   força: os dois seletores valem o mesmo e este vem depois no mesmo arquivo.
   Se algum dia precisar, o token está errado (§6.2). */
@media(prefers-reduced-motion:reduce){
  .vfd-ln > span,
  .vfd-desc,.vfd-cta,.vfd-pe{
    opacity:1;transform:none;filter:none;transition:none;
  }
}
/* Sem JavaScript não existe quem ponha .in, e os quatro blocos ficariam
   invisíveis para sempre: o vídeo tocaria sobre uma dobra vazia. Mesma
   consulta e mesmo motivo do core/motion.css — só que ali ela protege os
   ganchos globais, e aqui protege o portão do próprio componente. */
@media(scripting:none){
  .vfd-ln > span,
  .vfd-desc,.vfd-cta,.vfd-pe{
    opacity:1;transform:none;filter:none;transition:none;
  }
}

/* ---- régua de números ---------------------------------------------------- */
.vfd-regua{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;flex:1 1 auto}
.vfd-k{font-family:var(--display);font-weight:700;font-size:18px;color:var(--accent);letter-spacing:-.02em}
.vfd-v{font-size:12px;line-height:1.7;color:var(--fg-muted);margin-top:7px;letter-spacing:.02em}

/* ---- controle do vídeo ---------------------------------------------------
   Veste .btn-disc e .btn-play do core. Sobra UMA linha aqui, e é só um
   parafuso: 40px de disco em vez dos 42px do padrão, porque o botão divide a
   fileira com a régua de três números e o pé tem de caber na dobra.

   O QUE SAIU DAQUI, na promoção das duas primitivas (2026-09-21):
     - .vfd-toggle[hidden]{display:none} — a armadilha do §6.5 continua de pé,
       mas quem a desarma agora é a própria primitiva, em .btn-play[hidden],
       que é um seletor MAIS específico que o .btn-disc{display:grid} e vence
       em qualquer ordem de carregamento (§6.4). Repetir a regra aqui seria
       copiar core;
     - .vfd-ico{width:15px;height:15px} — 15px é o padrão do --play-ico;
     - a troca de ícone por .vfd.is-tocando na RAIZ, que custava ao componente
       uma classe de estado global só para desenhar um ícone. Agora quem
       comanda é [data-pausado] no próprio botão. */
.vfd-toggle{--disc-size:40px}

/* ---- variação: banner de página interna ---------------------------------
   Mesma linguagem, meia altura, sem régua e sem segundo botão. */
.vfd-curto{--vfd-alt:58vh;--vfd-veu-alt:72%}
@supports (height:100svh){.vfd-curto{--vfd-alt:58svh}}

/* ---- mobile --------------------------------------------------------------
   TODA regra aqui existe para a dobra fechar dentro da tela, e o número é
   medido: a peça abria em 1000px num iPhone de 844, com a régua e o botão
   abaixo da linha de corte. Um hero que não caiba na primeira tela não é um
   hero. As quatro economias, na ordem em que rendem:

     régua e botão na MESMA linha            -60px
     folga do topo reduzida ao menu + 24px   -43px
     respiro do pé (67px -> 36px)            -31px
     respiro acima da régua (51px -> 20px)   -30px

   Somam 164px e devolvem a dobra a 836px medidos, com 8px de folga contra a
   janela de 844. O irmão hero/full-bleed-media fecha em 895px no mesmo
   aparelho, ou seja NÃO cabe — e não por acaso: a régua dele é 2x2 e a daqui
   é uma coluna, que verticaliza mais e obrigou a medir. */
@media(max-width:760px){
  /* --vfd-video-op cai de .46 para .38 aqui, e o motivo é contraste medido,
     não estética: com a copy ocupando quase toda a dobra, o apoio sobe até a
     faixa mais clara do scrim. Contra um quadro branco chapado ele mede 3,76
     em .46 e 4,61 em .38 — a tabela está no topo do arquivo. */
  .vfd{--vfd-veu-alt:74%;--vfd-veu-blur:8px;--vfd-video-op:.38}
  .vfd-body{
    padding-top:calc(var(--nav-h) + 24px);
    padding-bottom:36px;
  }
  /* Três colunas de 96px partem "Política de investimentos" em quatro
     linhas. Em coluna única, chave e rótulo ficam lado a lado. */
  .vfd-pe{margin-top:20px}
  .vfd-regua{grid-template-columns:1fr;gap:12px}
  .vfd-item{display:grid;grid-template-columns:6.2em 1fr;gap:14px;align-items:baseline}
  .vfd-v{margin-top:0}
}
