/* ════════════════════════════════════════════════════════════
   ATMOSFERA MEDIA · CAMADA DE MOVIMENTO (site inteiro)
   ────────────────────────────────────────────────────────────
   Um só vocabulário de entrada para todas as páginas: título que
   sobe linha a linha por trás de uma máscara, texto que respira,
   mídia que abre em cortina. Quem liga o estado inicial é o JS
   (html.mo-on) — sem JS, nada some da tela.

   Uso: data-anim="lines | rise | fade | left | right | mask |
                    stagger | scale"
        data-d="1..6"   → atraso em degraus de 90ms
        data-anim-off   → o auto-marcador do motion.js não encosta
   ════════════════════════════════════════════════════════════ */

:root{
  --mo-ease:cubic-bezier(.16,1,.3,1);
  --mo-soft:cubic-bezier(.22,.61,.36,1);
  --mo-dur:.95s;
}

/* ── degraus de atraso, iguais aos do .reveal da home ── */
[data-d="1"]{ --mo-step:.09s } [data-d="2"]{ --mo-step:.18s }
[data-d="3"]{ --mo-step:.27s } [data-d="4"]{ --mo-step:.36s }
[data-d="5"]{ --mo-step:.45s } [data-d="6"]{ --mo-step:.54s }
[data-anim]{ --mo-step:0s }
[data-anim][data-d="1"]{ --mo-step:.09s } [data-anim][data-d="2"]{ --mo-step:.18s }
[data-anim][data-d="3"]{ --mo-step:.27s } [data-anim][data-d="4"]{ --mo-step:.36s }
[data-anim][data-d="5"]{ --mo-step:.45s } [data-anim][data-d="6"]{ --mo-step:.54s }

/* ═══════════ rise · o padrão para texto corrido e blocos ═══════════ */
html.mo-on [data-anim="rise"]:not(.mo-done){
  opacity:0; transform:translate3d(0,28px,0);
  transition:opacity .9s var(--mo-ease) var(--mo-step,0s),
             transform 1.05s var(--mo-ease) var(--mo-step,0s);
}
html.mo-on [data-anim="rise"].mo-in:not(.mo-done){ opacity:1; transform:none; }

/* ═══════════ fade ═══════════ */
html.mo-on [data-anim="fade"]:not(.mo-done){
  opacity:0; transition:opacity 1.15s var(--mo-ease) var(--mo-step,0s);
}
html.mo-on [data-anim="fade"].mo-in:not(.mo-done){ opacity:1; }

/* ═══════════ entradas laterais ═══════════ */
html.mo-on [data-anim="left"]:not(.mo-done),
html.mo-on [data-anim="right"]:not(.mo-done){
  opacity:0;
  transition:opacity .9s var(--mo-ease) var(--mo-step,0s),
             transform 1.1s var(--mo-ease) var(--mo-step,0s);
}
html.mo-on [data-anim="left"]:not(.mo-done){ transform:translate3d(-38px,0,0); }
html.mo-on [data-anim="right"]:not(.mo-done){ transform:translate3d(38px,0,0); }
html.mo-on [data-anim="left"].mo-in:not(.mo-done),
html.mo-on [data-anim="right"].mo-in:not(.mo-done){ opacity:1; transform:none; }

/* ═══════════ scale · cartões e chamadas ═══════════ */
html.mo-on [data-anim="scale"]:not(.mo-done){
  opacity:0; transform:translate3d(0,20px,0) scale(.965);
  transition:opacity .85s var(--mo-ease) var(--mo-step,0s),
             transform 1.1s var(--mo-ease) var(--mo-step,0s);
}
html.mo-on [data-anim="scale"].mo-in:not(.mo-done){ opacity:1; transform:none; }

/* ═══════════ mask · a cortina que abre a mídia ═══════════
   A cortina desce enquanto a imagem por dentro perde o excesso de
   escala: dá a impressão de que a foto já estava lá e a página só
   tirou o pano.

   Por que mask-size e não clip-path: o IntersectionObserver leva o
   clip-path do próprio elemento em conta ao medir a área visível. Com
   clip-path escondendo a peça, ela nunca "entra em cena" para o
   observador — não ganha .mo-in, o clip nunca abre, e o bloco some da
   página para sempre. A máscara é só pintura: não mexe na geometria
   que o observador enxerga. */
html.mo-on [data-anim="mask"]{
  -webkit-mask-image:linear-gradient(#000,#000); mask-image:linear-gradient(#000,#000);
  -webkit-mask-repeat:no-repeat;                 mask-repeat:no-repeat;
  -webkit-mask-position:0 0;                     mask-position:0 0;
  -webkit-mask-size:100% 0%;                     mask-size:100% 0%;
  transition:-webkit-mask-size 1.25s var(--mo-ease) var(--mo-step,0s),
                     mask-size 1.25s var(--mo-ease) var(--mo-step,0s);
}
html.mo-on [data-anim="mask"].mo-in{
  -webkit-mask-size:100% 100%; mask-size:100% 100%;
}
/* O :not(.mo-done) e o que devolve a midia ao componente no fim da
   entrada. Sem ele, o "transform:none" desta camada — mais especifico
   que qualquer .galeria:hover img — ficava valendo para sempre e
   nenhuma foto ampliava mais no hover. Concluida a cortina, o motion
   nao declara transform nenhum: quem manda de novo e a folha do
   componente. */
html.mo-on [data-anim="mask"]:not(.mo-done) img,
html.mo-on [data-anim="mask"]:not(.mo-done) video,
html.mo-on [data-anim="mask"]:not(.mo-done) iframe{
  transform:scale(1.16);
  transition:transform 1.6s var(--mo-ease) var(--mo-step,0s);
}
html.mo-on [data-anim="mask"].mo-in:not(.mo-done) img,
html.mo-on [data-anim="mask"].mo-in:not(.mo-done) video,
html.mo-on [data-anim="mask"].mo-in:not(.mo-done) iframe{ transform:none; }

/* ═══════════ stagger · filhos entrando em cascata ═══════════ */
html.mo-on [data-anim="stagger"]:not(.mo-done) > *{
  opacity:0; transform:translate3d(0,16px,0);
  transition:opacity .7s var(--mo-ease) var(--mo-d,0s),
             transform .85s var(--mo-ease) var(--mo-d,0s);
}
html.mo-on [data-anim="stagger"].mo-in:not(.mo-done) > *{ opacity:1; transform:none; }

/* ═══════════ lines · o título que sobe por trás da máscara ═══════════
   Cada palavra ganha uma janela com overflow escondido; o atraso vem
   agrupado por LINHA (o JS mede o offsetTop), então a leitura é de
   linha em linha e não de palavra em palavra. O padding/margem de
   .16em existe para a janela não decepar o rabo do "g" e do "ç". */
mo-w{
  display:inline-block; overflow:hidden; vertical-align:bottom;
  /* nowrap: sem isso um nome muito longo encolheria e a janela o decepava */
  white-space:nowrap;
  padding-bottom:.16em; margin-bottom:-.16em;
}
mo-wi{ display:inline-block; }
html.mo-on [data-anim="lines"]:not(.mo-done) mo-wi{
  opacity:0; transform:translate3d(0,112%,0) rotate(2.6deg);
  transition:opacity .7s var(--mo-ease) var(--mo-d,0s),
             transform 1.1s var(--mo-ease) var(--mo-d,0s);
}
html.mo-on [data-anim="lines"].mo-in:not(.mo-done) mo-wi{ opacity:1; transform:none; }
/* enquanto o JS não terminou de cortar as palavras, o título fica
   escondido inteiro — evita ver o texto pular ao ser fatiado */
html.mo-on [data-anim="lines"]:not(.mo-split){ opacity:0; }
html.mo-on [data-anim="lines"].mo-split{ opacity:1; }

/* ═══════════ peca concluida · .mo-done ═══════════
   Terminada a entrada, o motion.js poe .mo-done e TODA a camada de
   movimento sai da frente daquela peca: e por isso que cada regra
   acima carrega um :not(.mo-done).

   Por que isso importa: "html.mo-on [data-anim=...].mo-in{transform:none}"
   e mais especifico que qualquer ".galeria__item:hover img" ou
   ".pilulas li:hover" do tema. Enquanto essa declaracao ficava valendo
   para sempre, nenhum hover que mexesse em transform funcionava depois
   que o bloco entrava na tela — a foto nao ampliava, a pilula nao subia.
   Com o :not(.mo-done), passados os 2,2s da animacao o componente volta
   a mandar no proprio transform.

   De quebra a mascara some, e ela forcava composicao em toda rolagem
   mesmo com a pagina parada. */
html.mo-on [data-anim="mask"].mo-done{
  -webkit-mask-image:none; mask-image:none;
}
html.mo-on [data-anim="mask"].mo-done img,
html.mo-on [data-anim="mask"].mo-done video,
html.mo-on [data-anim="mask"].mo-done iframe{
  transition:transform .55s var(--mo-soft);
}

/* ═══════════ parallax de scroll ═══════════ */
[data-par]{ will-change:translate; }

/* ═══════════ brilho que atravessa o botão ═══════════ */
.btn-primary::after, .nav-cta::after, .pill::after{
  content:""; position:absolute; top:0; bottom:0; left:-60%; width:45%;
  pointer-events:none; z-index:0; transform:skewX(-18deg) translateX(0);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.42),transparent);
  transition:transform .85s var(--mo-soft), opacity .3s;
  opacity:0;
}
.btn-primary:hover::after, .nav-cta:hover::after, .pill:hover::after{
  opacity:1; transform:skewX(-18deg) translateX(360%);
}
.nav-cta, .pill{ position:relative; overflow:hidden; }
.btn-primary > *{ position:relative; z-index:1; }

/* ═══════════ sublinhado que cresce nos links de texto ═══════════ */
.mo-link{ position:relative; }
.mo-link::after{
  content:""; position:absolute; left:0; right:0; bottom:-2px; height:1px;
  background:currentColor; transform:scaleX(0); transform-origin:right center;
  transition:transform .5s var(--mo-ease);
}
.mo-link:hover::after{ transform:scaleX(1); transform-origin:left center; }

/* ═══════════ respeito a quem pediu menos movimento ═══════════ */
@media (prefers-reduced-motion:reduce){
  html.mo-on [data-anim]{
    opacity:1 !important; transform:none !important; clip-path:none !important;
    -webkit-mask-image:none !important; mask-image:none !important;
    transition:none !important;
  }
  html.mo-on [data-anim] mo-wi,
  html.mo-on [data-anim="stagger"] > *,
  html.mo-on [data-anim="mask"] img{
    opacity:1 !important; transform:none !important; transition:none !important;
  }
  .btn-primary::after, .nav-cta::after, .pill::after{ display:none; }
}
