/* =========================================================
   MOTION — animasi halus berbasis transform/opacity (GPU-friendly)
   Prinsip: PERFORMANCE > ANIMATION. Tidak ada animasi paint tak-berujung.
   ========================================================= */

/* opacity awal .01 (tak terlihat) — bukan 0 — agar browser mencatat elemen tampil sejak frame pertama animasi */
@keyframes rise {
  from { opacity: .01; transform: translate3d(0, 22px, 0); }
  to { opacity: 1; transform: none; }
}
@keyframes rise-blur {
  from { opacity: .01; transform: translate3d(0, 16px, 0) scale(.98); filter: blur(8px); }
  to { opacity: 1; transform: none; filter: blur(0); }
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes kenburns { from { transform: scale(1.14); } to { transform: scale(1.02); } }
@keyframes hero-settle { from { transform: scale(1.12); } to { transform: scale(1); } }
@keyframes twinkle {
  0%, 100% { opacity: 0; transform: scale(calc(var(--s, 1) * .4)); }
  45% { opacity: .95; transform: scale(var(--s, 1)); }
  60% { opacity: .6; }
}
/* kilau bintang perak: muncul sambil berputar sedikit */
@keyframes glint {
  0%, 100% { opacity: 0; transform: scale(calc(var(--s, 1) * .3)) rotate(0deg); }
  45% { opacity: 1; transform: scale(var(--s, 1)) rotate(45deg); }
  62% { opacity: .55; }
}
/* sapuan kilau di tombol & kartu rekening (transform saja) */
@keyframes btn-sheen { 0% { transform: translateX(-120%); } 38%, 100% { transform: translateX(120%); } }
@keyframes card-sheen { 0% { transform: translateX(0) rotate(8deg); } 42%, 100% { transform: translateX(400%) rotate(8deg); } }
@keyframes breathe { 0%, 100% { opacity: .5; } 50% { opacity: .95; } }
@keyframes gold-sheen { from { background-position: 100% 50%; } to { background-position: 0% 50%; } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes eq {
  0%, 100% { transform: scaleY(.3); }
  50% { transform: scaleY(1); }
}
@keyframes cue { 0%, 100% { transform: translateY(0); opacity: .75; } 50% { transform: translateY(6px); opacity: 1; } }
@keyframes pulse-ring { from { transform: scale(.9); opacity: .9; } to { transform: scale(1.45); opacity: 0; } }
@keyframes dock-in { from { opacity: 0; transform: translate3d(0, 24px, 0); } to { opacity: 1; transform: none; } }

/* ---------- Loader ---------- */
.loader__mark { animation: fade 1s ease both; }

/* ---------- Sampul: masuk ----------
   Sebelum font & foto siap, teks sampul tidak di-layout (display:none) → layout pertama sangat ringan
   dan teks hanya di-shaping sekali dengan font yang benar. Hero ([data-defer]) menyusul setelah sampul
   tampil, sehingga fotonya (loading=lazy) tidak berebut bandwidth dengan font & foto sampul. */
.js:not(.is-ready):not(.boot-failed) .cover__content { display: none; }
.js.is-ready .cover__media img { animation: kenburns 16s var(--ease-lux) both; }
.js .cover [data-anim] { opacity: 0; }
.js.is-ready .cover [data-anim] { animation: rise 1.1s var(--ease-out-expo) both; }
.js.is-ready .cover [data-anim="1"] { animation-delay: .15s; }
.js.is-ready .cover [data-anim="2"] { animation-name: rise-blur; animation-duration: 1.5s; animation-delay: 0s; }
.js.is-ready .cover [data-anim="3"] { animation-delay: .75s; }
.js.is-ready .cover [data-anim="4"] { animation-delay: .95s; }
.js.is-ready .cover [data-anim="5"] { animation-delay: 1.15s; }
.js.is-ready .cover [data-anim="6"] { animation-delay: 1.35s; }
.js.is-ready .cover__names > span:not(.amp) { animation: gold-sheen 3.2s ease-in-out 1.4s 2 both; }

/* ---------- Sampul: keluar (sinematik: konten naik, tirai tergeser ke atas) ---------- */
.cover { transition: transform 1.25s cubic-bezier(.77, 0, .18, 1), opacity 1.25s ease; }
.cover__content { transition: opacity .6s ease, transform .8s var(--ease-lux); }
.cover.is-leaving .cover__content { opacity: 0; transform: translate3d(0, -30px, 0); }
.cover.is-leaving { transform: translate3d(0, -100%, 0); transition-delay: .25s; }

/* ---------- Hero: masuk setelah undangan dibuka ---------- */
.js .hero__content > *, .js .scroll-cue { opacity: 0; }
.js.is-opened .hero__media img { animation: hero-settle 2.6s var(--ease-out-expo) both; }
.js.is-opened .hero__content > * { animation: rise 1.2s var(--ease-out-expo) both; }
.js.is-opened .hero__content > :nth-child(1) { animation-delay: .7s; }
.js.is-opened .hero__content > :nth-child(2) { animation-name: rise-blur; animation-duration: 1.6s; animation-delay: .85s; }
.js.is-opened .hero__content > :nth-child(3) { animation-delay: 1.15s; }
.js.is-opened .hero__content > :nth-child(4) { animation-delay: 1.3s; }
.js.is-opened .hero__content > :nth-child(5) { animation-delay: 1.45s; }
.js.is-opened .scroll-cue { animation: fade 1s ease 1.9s both; }
.js.is-opened .scroll-cue .icon { animation: cue 2.2s ease-in-out 3s infinite; }
.js.is-opened .hero__names > span:not(.amp) { animation: gold-sheen 3.2s ease-in-out 1.6s 1 both; }

/* ---------- Efek cahaya ---------- */
.sparkles i { animation: twinkle 4.8s ease-in-out var(--d, 0s) infinite; }
.sparkles i:nth-child(2n), .sparkles.sparkles--silver i { animation-name: glint; animation-duration: 5.2s; }
.rays { animation: breathe 9s ease-in-out infinite; }
.gift-card__shine::before { animation: card-sheen 5.6s var(--ease-lux) 1.4s infinite; }
.is-offscreen .sparkles i, .is-offscreen .rays, .is-offscreen .gift-card__shine::before { animation-play-state: paused; }

/* ---------- Scroll reveal ---------- */
.js [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 28px, 0);
  transition: opacity 1s var(--ease-lux), transform 1.2s var(--ease-out-expo), filter 1.2s var(--ease-lux);
  transition-delay: var(--delay, 0ms);
}
.js [data-reveal="scale"] { transform: scale(.94); }
.js [data-reveal="blur"] { transform: translate3d(0, 14px, 0); filter: blur(8px); }
.js [data-reveal].is-visible { opacity: 1; transform: none; filter: none; }
.js [data-reveal] .arch__frame img { transform: scale(1.12); transition: transform 2s var(--ease-out-expo); }
.js [data-reveal].is-visible .arch__frame img { transform: none; }
.js .date-lockup.is-visible .date-lockup__num,
.js .closing__names.is-visible > span:not(.amp) { animation: gold-sheen 3.4s ease-in-out .5s 1 both; }
/* judul emas di section maroon & nama mempelai: kilau emas menyapu sekali saat tampil */
.js .section--maroon .section-head.is-visible .section-title,
.js .section--maroon .profile.is-visible .profile__name { animation: gold-sheen 3.4s ease-in-out .35s 1 both; }

/* ---------- Dock & tombol ---------- */
.dock.is-shown .bottom-nav { animation: dock-in .9s var(--ease-out-expo) both; }
.dock.is-shown .fab-stack { animation: dock-in .9s var(--ease-out-expo) .15s both; }
.fab--music.is-playing .fab__disc .icon { animation: spin 7s linear infinite; }
.fab--music.is-playing .fab__eq i { animation: eq .9s ease-in-out infinite; }
.fab--music.is-playing .fab__eq i:nth-child(2) { animation-delay: -.3s; animation-duration: .7s; }
.fab--music.is-playing .fab__eq i:nth-child(3) { animation-delay: -.6s; animation-duration: 1.1s; }
.fab--music.needs-tap::after { animation: pulse-ring 1.6s ease-out infinite; }
.fab--scroll.is-running .icon { animation: cue 1.8s ease-in-out infinite; }

/* ---------- Parallax ringan (scroll-driven, di thread compositor; progressive enhancement) ---------- */
@supports (animation-timeline: view()) {
  @keyframes parallax-y {
    from { transform: translate3d(0, -7%, 0) scale(1.16); }
    to { transform: translate3d(0, 7%, 0) scale(1.16); }
  }
  .bg-media img {
    animation: parallax-y linear both;
    animation-timeline: view();
    animation-range: cover 0% cover 100%;
  }
}

/* ---------- Fallback bila modul JS gagal dimuat ---------- */
.boot-failed .hero__content > *, .boot-failed .scroll-cue, .boot-failed [data-reveal] {
  opacity: 1 !important; transform: none !important; filter: none !important;
}
.boot-failed body { overflow: auto; }

/* ---------- Reduce motion: matikan animasi berat, partikel, parallax ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0s !important;
    transition-duration: .001ms !important;
    transition-delay: 0s !important;
  }
  .sparkles, .rays { display: none !important; }
  .js [data-reveal] { opacity: 1; transform: none; filter: none; }
  .bg-media img { animation: none !important; transform: none !important; }
  .js [data-reveal] .arch__frame img { transform: none; }
}
