/* Reveal Cortina — Helix Loja de Efeitos
   Tokens: personalize no :root (contrato --fx-*). */
:root{
  --fx-bg:#f5f4f0;
  --fx-ink:#1a2543;
  --fx-accent:#ea5420;
  --fx-muted:#6f7791;
  --fx-speed:1;            /* multiplicador global de duração */
  --fx-radius:12px;
  --fx-wipe-dur:.85s;      /* duração base do wipe */
  --fx-stagger:.08s;       /* intervalo entre filhos de um data-fx-grupo */
}

/* Anti-FOUC: os estados iniciais só valem sob .fx-js.
   SEM JavaScript, [data-fx-cortina] não é selecionado e a página fica íntegra
   (progressive enhancement por design).

   Estratégia de duas fases pra o IntersectionObserver enxergar layout OK:
   1. Init: só opacity 0 (o IO calcula layout normal — clip-path degenerado
      no estado inicial faria o Chromium reportar isIntersecting:false pra
      todo mundo, quebrando o efeito).
   2. Ao entrar na viewport, o JS aplica .fx-armed (clip degenerado + scale
      + transition none), no rAF seguinte substitui por .fx-in (clip pleno +
      transition ativa) — a cortina animada.

   O clip-path fica no PRÓPRIO elemento marcado, portanto NÃO coloque a
   sombra aqui: envolva num wrapper externo (ver README §Como usar →
   "card com sombra"). */
.fx-reveal-cortina.fx-js [data-fx-cortina]{
  opacity:0;
  will-change:clip-path,transform,opacity;
}

/* Estado "armado" — invisível por clip, pronto pra abrir.
   default = up (cortina revela subindo, base primeiro).
   Classe no namespace do efeito (fx-reveal-cortina__armed) porque é
   auxiliar interna, não estado compartilhado do contrato. */
.fx-reveal-cortina.fx-js [data-fx-cortina].fx-reveal-cortina__armed{
  opacity:1;
  clip-path:inset(100% 0 0 0);
  transform:scale(1.08);
  transition:none;
}
.fx-reveal-cortina.fx-js [data-fx-cortina="down"].fx-reveal-cortina__armed{clip-path:inset(0 0 100% 0)}
.fx-reveal-cortina.fx-js [data-fx-cortina="left"].fx-reveal-cortina__armed{clip-path:inset(0 0 0 100%)}
.fx-reveal-cortina.fx-js [data-fx-cortina="right"].fx-reveal-cortina__armed{clip-path:inset(0 100% 0 0)}

/* Estado revelado — cortina totalmente aberta + escala assentada. */
.fx-reveal-cortina.fx-js [data-fx-cortina].fx-in{
  opacity:1;
  clip-path:inset(0);
  transform:scale(1);
  transition:clip-path calc(var(--fx-wipe-dur) * var(--fx-speed)) cubic-bezier(.65,0,.35,1),
             transform calc(var(--fx-wipe-dur) * var(--fx-speed)) cubic-bezier(.19,1,.22,1);
}

/* reduced motion: estado final visível, sem animação (contrato).
   compound obrigatório .fx-reveal-cortina.fx-rm — sem espaço. */
.fx-reveal-cortina.fx-rm [data-fx-cortina]{
  opacity:1 !important;
  clip-path:none !important;
  transform:none !important;
  transition:none !important;
}
