/* =========================================================
   PPN animations
   Preloader, reveals de scroll, desenho de icones.
   Anima apenas transform e opacity.
   ========================================================= */

/* ---------- Preloader ----------
   O monograma desenha-se traco a traco, o lettering entra por baixo,
   um brilho verde varre a marca e a cortina sobe para abrir o site. */
.preloader {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 300;
  background: var(--ppn-black);
  place-content: center;
  justify-items: center;
  gap: 26px;
  overflow: hidden;
}
.js .preloader { display: grid; }

/* Halo verde suave por tras da marca */
.preloader::before {
  content: "";
  position: absolute;
  width: min(90vw, 900px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, var(--ppn-green-a08) 0%, var(--ppn-black-a00) 62%);
  opacity: 0;
  transition: opacity 900ms var(--ease-out);
}
.preloader.is-drawing::before { opacity: 1; }

.preloader__mark {
  position: relative;
  width: min(72vw, 420px);
  color: var(--ppn-green);
}
.preloader__mark svg { width: 100%; height: auto; overflow: visible; }

/* Monograma: tracos por desenhar */
.pl-mono { stroke-width: 14; }
.pl-mono path {
  stroke-dasharray: var(--len, 900);
  stroke-dashoffset: var(--len, 900);
}
.preloader.is-drawing .pl-mono path {
  animation: drawStroke 900ms cubic-bezier(0.5, 0, 0.2, 1) forwards;
}
.preloader.is-drawing .pl-mono path:nth-child(2) { animation-delay: 120ms; }
.preloader.is-drawing .pl-mono path:nth-child(3) { animation-delay: 240ms; }
.preloader.is-filled .pl-mono { animation: thickenStroke 320ms var(--ease-out) forwards; }

/* Lettering: entra depois do monograma fechar */
.pl-word, .pl-sub, .pl-rules { opacity: 0; }
.preloader.is-signing .pl-word {
  animation: wordIn 620ms var(--ease-out) forwards;
}
.preloader.is-signing .pl-sub {
  animation: wordIn 620ms var(--ease-out) 160ms forwards;
}
.preloader.is-signing .pl-rules {
  animation: rulesIn 520ms var(--ease-out) 260ms forwards;
}

/* Brilho que varre a marca de um lado ao outro */
.preloader__sweep {
  position: absolute;
  inset: -12% -30%;
  pointer-events: none;
  background: linear-gradient(100deg,
    var(--ppn-black-a00) 42%,
    var(--ppn-green-a30) 50%,
    var(--ppn-black-a00) 58%);
  mix-blend-mode: screen;
  opacity: 0;
}
.preloader.is-sweeping .preloader__sweep {
  animation: markSweep 900ms var(--ease-out) forwards;
}

.preloader__status {
  position: absolute;
  bottom: 40px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-ui);
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  color: var(--ppn-grey);
  opacity: 0;
  transition: opacity 400ms linear;
  white-space: nowrap;
}
.preloader__status.is-visible { opacity: 1; }

/* A saida e o painel inteiro a subir, revelando a pagina por baixo */
.preloader.is-leaving {
  animation: preloaderLift 640ms cubic-bezier(0.76, 0, 0.24, 1) forwards;
}
.preloader.is-leaving .preloader__mark,
.preloader.is-leaving .preloader__status {
  animation: markExit 540ms var(--ease-out) forwards;
}
.preloader.is-done { display: none; }

@keyframes drawStroke { to { stroke-dashoffset: 0; } }
@keyframes thickenStroke {
  from { stroke-width: 14; }
  to   { stroke-width: 27; }
}
@keyframes wordIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes rulesIn {
  from { opacity: 0; transform: scaleX(0.4); }
  to   { opacity: 1; transform: scaleX(1); }
}
@keyframes markSweep {
  from { opacity: 1; transform: translateX(-42%); }
  to   { opacity: 0; transform: translateX(42%); }
}
@keyframes markExit {
  to { opacity: 0; transform: translateY(-18px) scale(0.94); }
}
@keyframes preloaderLift {
  from { transform: translateY(0); }
  to   { transform: translateY(-100%); }
}

/* Enquanto o preloader corre, o scroll fica travado */
body.is-loading { overflow: hidden; }

/* ---------- Entrada do hero ---------- */
.js .hero [data-hero] {
  opacity: 0;
  transform: translateY(24px);
}
.js body.hero-in .hero [data-hero] {
  animation: heroIn 760ms var(--ease-out) forwards;
  animation-delay: calc(var(--i, 0) * 110ms);
}
@keyframes heroIn {
  to { opacity: 1; transform: translateY(0); }
}

/* ---------- Reveal base (IntersectionObserver) ---------- */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 600ms var(--ease-out), transform 600ms var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
.js [data-reveal].is-in {
  opacity: 1;
  transform: translateY(0);
}

/* Revelacao dos titulos display: cortina a abrir de cima para baixo.

   NAO usar clip-path para o estado escondido. O IntersectionObserver conta
   o clip do proprio elemento no calculo da interseccao, por isso um
   inset(0 0 100% 0) devolve intersectionRatio 0, o observer nunca marca
   .is-in e o titulo fica recortado para sempre. Verificado em Chrome:
   com clip-path ratio 0, sem clip-path ratio 1.

   A mascara faz o mesmo efeito visual mas e so pintura: nao entra no
   calculo do observer. A base fica em opacity/transform, que funciona
   mesmo onde as mascaras nao existem. */
.js [data-reveal-lines] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 420ms var(--ease-out), transform 700ms var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
.js [data-reveal-lines].is-in {
  opacity: 1;
  transform: translateY(0);
}

@supports (mask-image: linear-gradient(#000, #000)) or (-webkit-mask-image: linear-gradient(#000, #000)) {
  .js [data-reveal-lines] {
    -webkit-mask-image: linear-gradient(to bottom, var(--mask-solid) 50%, transparent 50%);
            mask-image: linear-gradient(to bottom, var(--mask-solid) 50%, transparent 50%);
    -webkit-mask-size: 100% 200%;
            mask-size: 100% 200%;
    /* 100% mostra a metade transparente da mascara, logo esconde */
    -webkit-mask-position: 0 100%;
            mask-position: 0 100%;
    transition: opacity 420ms var(--ease-out),
                transform 700ms var(--ease-out),
                -webkit-mask-position 760ms var(--ease-out),
                mask-position 760ms var(--ease-out);
  }
  .js [data-reveal-lines].is-in {
    -webkit-mask-position: 0 0;
            mask-position: 0 0;
  }
}

/* Desenho do traco dos icones no reveal */
.js .fcard__icon path,
.js .fcard__icon circle,
.js .fcard__icon rect,
.js .fcard__icon ellipse {
  stroke-dasharray: 120;
  stroke-dashoffset: 120;
  transition: stroke-dashoffset 500ms var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
.js .is-in .fcard__icon path,
.js .is-in .fcard__icon circle,
.js .is-in .fcard__icon rect,
.js .is-in .fcard__icon ellipse {
  stroke-dashoffset: 0;
}

/* Retrato do fundador */
.js [data-portrait-reveal] {
  opacity: 0;
  transform: scale(1.06);
  transition: opacity 1200ms var(--ease-out), transform 1200ms var(--ease-out);
}
.js [data-portrait-reveal].is-in { opacity: 1; transform: scale(1); }

/* Parallax: aplicado por JS via --parallax */
[data-parallax] {
  transform: translate3d(0, var(--parallax, 0px), 0);
  will-change: transform;
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal],
  .js [data-portrait-reveal],
  .js .hero [data-hero] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    animation: none !important;
  }
  .js [data-reveal-lines] {
    opacity: 1 !important;
    transform: none !important;
    -webkit-mask-image: none !important;
            mask-image: none !important;
  }
  .js .fcard__icon path,
  .js .fcard__icon circle,
  .js .fcard__icon rect,
  .js .fcard__icon ellipse {
    stroke-dasharray: none;
    stroke-dashoffset: 0;
  }
  [data-parallax] { transform: none !important; }
  .hero__slide,
  .hero__layer--haze,
  .hero__layer--beam,
  .fcard__aurora,
  .btn-hero .btn-hero__body,
  .btn-cta__glow,
  .scroll-hint__dot,
  .scroll-hint__mouse::before,
  .scroll-hint__chevrons svg { animation: none !important; }
  .hero__inner { transform: none !important; opacity: 1 !important; }
  .hero__slide { opacity: 0; transform: none !important; clip-path: none !important; }
  .hero__slide--1 { opacity: 1; }
  .scroll-hint-wrap { opacity: 1 !important; }
  .pl-word, .pl-sub, .pl-rules { opacity: 1; }
  .preloader__mark path { stroke-dashoffset: 0; }
  .pl-mono { stroke-width: 27; }
  .preloader__sweep { display: none; }
}
