/* Gaya tema Zamrud Senja.

   Nilainya diambil dari tema acuan di folder referensi - "3D Motion 16
   (Tanpa Foto)" - bukan dikarang ulang: maron #550000 dan #820000, merah
   muda #F1E2E2, krem #FFFCF3, tinta #333333, daun #85A57A, dan emas #88775D;
   Cormorant Infant untuk nama dan angka, Aref Ruqaa untuk teks, Pinyon
   Script dan Aston Script untuk tulisan tangan; lengkung 300px untuk kubah
   dan kapsul, 25px untuk kartu acara, 125px untuk bingkai foto, dan 20-25px untuk
   tombol.

   Acuannya dirakit Elementor, jadi satu bagian di sana bisa jadi lima lapis
   div dengan latar dan overlay sendiri-sendiri. Di sini lapisannya dipadatkan
   ke ::before dan ::after selama hasilnya sama - yang ditiru rupanya, bukan
   cara WordPress menyusunnya.

   Lebar undangan 450px, sama seperti acuan. Itu bukan batas "maksimal" yang
   kebetulan: seluruh ukuran huruf di bawah ini dipilih untuk lebar itu. */

@font-face {
  font-family: "aston-script";
  /* Huruf tulisan tangan milik acuan. Ikut tersusun ke dalam binary lewat
     embed folder temanya, jadi undangan tetap tampil benar di jaringan yang
     memblokir unduhan dari luar. */
  src: url("aston-script.woff2") format("woff2");
  font-display: swap;
}

:root {
  --maron: #550000;
  --maron-terang: #820000;
  --merah: #c20000;
  --jambu: #f1e2e2;
  --krem: #fffcf3;
  --tinta: #333333;
  --daun: #85a57a;
  --emas: #88775d;
  --kertas: #f3f1ef;

  --lebar: 450px;

  --judul: "Cormorant Infant", "Times New Roman", serif;
  --teks: "Aref Ruqaa", "Times New Roman", serif;
  --skrip: "aston-script", "Pinyon Script", cursive;
  --tangan: "Pinyon Script", cursive;

  --tombol-latar: linear-gradient(75deg, #820000 0%, #550000 100%);
  --bayang: 0 0 10px rgba(0, 0, 0, .5);
}

*, *::before, *::after { box-sizing: border-box; }

/* Beberapa elemen di bawah ini memasang display sendiri - lampu sorot, tombol
   musik, hitung mundur. Aturan [hidden] milik peramban kalah dari aturan
   kelas, jadi tanpa baris ini elemen yang ditandai hidden tetap tergambar:
   lampu sorotnya saja sudah menutupi seluruh undangan. */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--jambu);
  color: var(--tinta);
  font-family: var(--teks);
  font-size: 14px;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
  overflow-x: hidden;
}

/* Satu hamparan bunga untuk seluruh halaman, bukan satu salinan per bagian.
   Itu yang dilakukan acuan: hampir semua bagiannya tidak punya gambar
   sendiri, cuma lapisan warna di atas latar halaman - jadi tiap bagian
   memperlihatkan potongan yang berbeda dari satu gambar yang sama. Disalin
   per bagian, gambar yang sama (lengkap dengan joglo di tengahnya) berulang
   belasan kali dan isinya jadi sulit dibaca.

   Dipasang sebagai pseudo-element position:fixed, bukan
   background-attachment:fixed: yang terakhir itu diabaikan Safari iOS dan
   gambarnya malah direntang setinggi seluruh halaman. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: url("zs-latar.jpg") center center / cover no-repeat;
}

/* Selama sampul masih terpasang, halaman tidak boleh digulung. Tingginya ikut
   dipaku supaya iOS tidak memantulkan badan halaman di belakang sampul. */
body.terkunci { overflow: hidden; height: 100vh; }
body.lampu-terbuka { overflow: hidden; }

img { display: block; max-width: 100%; height: auto; }

h1, h2, h3, h4, p { margin: 0; }

.ikon {
  width: 1.05em;
  height: 1.05em;
  flex: none;
  vertical-align: -.15em;
}

/* ============================================================
   BAGIAN GERAK - nama kelas dan nilainya dari acuan
   ============================================================

   Acuannya memasang kelas .active pada elemen yang masuk layar dan
   melepasnya lagi saat keluar, jadi tiap bagian bergerak ulang setiap kali
   tamu menggulung balik. Nama kelasnya dipertahankan apa adanya
   (.inv-atas, .inv-kiri, ...) supaya potongan markup dari acuan bisa
   dibandingkan baris per baris dengan yang di sini. */

.inv-fade-in, .inv-atas, .inv-bawah, .inv-kiri, .inv-kanan,
.inv-rotate-in, .inv-flip-x, .inv-flip-y, .inv-zoom-in, .inv-zoom-out,
.inv-petak {
  will-change: transform, opacity;
}

.inv-fade-in { opacity: 0; transition: opacity 1.5s ease-in-out; }
.inv-fade-in.active { opacity: 1; }

.inv-atas {
  transform: translateY(50%); opacity: 0;
  transition: transform 1.5s ease, opacity 1.5s ease;
}
.inv-atas.active { transform: translateY(0); opacity: 1; }

.inv-bawah {
  transform: translateY(-50%); opacity: 0;
  transition: transform 1.5s ease, opacity 1.5s ease;
}
.inv-bawah.active { transform: translateY(0); opacity: 1; }

.inv-kiri {
  transform: translateX(-100%) scale(.93); opacity: 0;
  transition: opacity .5s ease, transform 1.5s ease;
}
.inv-kiri.active { transform: translateX(0) scale(1); opacity: 1; }

.inv-kanan {
  transform: translateX(100%) scale(.93); opacity: 0;
  transition: opacity .5s ease, transform 1.5s ease;
}
.inv-kanan.active { transform: translateX(0) scale(1); opacity: 1; }

.inv-rotate-in {
  transform: rotate(-180deg); opacity: 0;
  transition: transform 1.5s ease-out, opacity 1.5s ease-out;
}
.inv-rotate-in.active { transform: rotate(0deg); opacity: 1; }

.inv-flip-x {
  transform: rotateX(90deg); opacity: 0;
  transition: transform 1.5s ease, opacity 1.5s ease;
}
.inv-flip-x.active { transform: rotateX(0deg); opacity: 1; }

.inv-flip-y {
  transform: rotateY(90deg); opacity: 0;
  transition: transform 1.5s ease, opacity 1.5s ease;
}
.inv-flip-y.active { transform: rotateY(0deg); opacity: 1; }

.inv-zoom-in {
  transform: scale(.9); opacity: 0;
  transition: transform 1.5s ease, opacity 1.5s ease;
}
.inv-zoom-in.active { transform: scale(1); opacity: 1; }

.inv-zoom-out {
  transform: scale(1.1); opacity: 0;
  transition: transform 1.5s ease, opacity 1.5s ease;
}
.inv-zoom-out.active { transform: scale(1); opacity: 1; }

/* Foto galeri: gerak .inv-kiri, tapi arahnya berganti tiap foto genap.
   Dipisah jadi kelasnya sendiri supaya template tidak perlu menghitung
   ganjil-genap - :nth-child memang pekerjaan yang sudah dimiliki CSS. */
.inv-petak {
  transform: translateX(-100%) scale(.93); opacity: 0;
  transition: opacity .5s ease, transform 1.5s ease;
}
.inv-petak:nth-child(even) { transform: translateX(100%) scale(.93); }
.inv-petak.active { transform: translateX(0) scale(1); opacity: 1; }

/* Jeda bertingkat dipasang dari template lewat style="--jeda:.2s". Harus
   berada SESUDAH aturan di atas: tiap kelas memasang transition dalam bentuk
   ringkas, dan bentuk ringkas itu mengembalikan transition-delay ke nol.
   Ditulis lebih dulu, seluruh jedanya hilang tanpa jejak. */
.inv-fade-in, .inv-atas, .inv-bawah, .inv-kiri, .inv-kanan,
.inv-rotate-in, .inv-flip-x, .inv-flip-y, .inv-zoom-in, .inv-zoom-out,
.inv-petak {
  transition-delay: var(--jeda, 0s);
}

/* Gerak masuk sekali. Acuan memasang dua gerak di gambar hiasnya: animasi
   masuk Elementor yang hanya diputar sekali, di atas kelas inv-* yang terus
   hidup-mati mengikuti gulungan. Yang pertama itu dipasang di sini - skrip
   menambahkan .masuk sekali saja dan tidak pernah mencabutnya.

   Sengaja tanpa fill-mode, sama seperti .animated milik Elementor: begitu
   geraknya habis, transform-nya dilepas kembali ke kelas inv-* supaya
   gulungan balik tetap menggerakkan elemennya. */
.masuk[data-masuk="turun-kiri"] {
  animation: zs-rotate-in-down-left 2s var(--masuk-jeda, 0s);
}
.masuk[data-masuk="turun-kanan"] {
  animation: zs-rotate-in-down-right 2s var(--masuk-jeda, 0s);
}

/* Perspektif dipasang di induk langsung elemen yang berputar - hanya anak
   langsung yang terkena. Tanpa ini rotateX/rotateY cuma memipihkan
   elemennya, tidak memutarnya menjauh. */
.bagian, .kapsul, .kubah, .hitung { perspective: 1400px; }

/* ============================================================
   KERANGKA
   ============================================================ */

/* Kolom undangan. Acuan mengunci 450px dan menaruh sisa layar di belakangnya;
   di bawah itu undangannya memenuhi layar. */
.bingkai {
  position: relative;
  width: 100%;
  max-width: var(--lebar);
  margin: 0 auto;
  overflow: hidden;
  z-index: 1;
}

/* Panel nama yang mengisi sisa layar lebar. Fixed, jadi ia diam di tempat
   sementara undangannya digulung - persis seperti kolom kiri di acuan. */
.latar-sisi {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 0;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0 2em;
  text-align: center;
  background: var(--jambu) url("zs-latar.jpg") center / cover no-repeat;
}
.latar-sisi::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, .35);
}
.latar-sisi > * { position: relative; z-index: 1; }

.sisi-pembuka { font-family: var(--tangan); font-size: 30px; line-height: 1.3; }
.sisi-nama {
  font-family: var(--judul);
  font-weight: 600;
  font-size: 4.2vw;
  text-transform: uppercase;
  color: var(--maron);
}
.sisi-tanggal { font-size: 16px; font-weight: 600; }

.bagian {
  position: relative;
  overflow: hidden;
}

/* ============================================================
   TOMBOL
   ============================================================ */

.tombol {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5em;
  border: 0;
  cursor: pointer;
  font-family: var(--teks);
  font-size: 15px;
  line-height: 1.2;
  color: #fff;
  background: var(--tombol-latar);
  border-radius: 20px;
  padding: 10px 30px;
  text-decoration: none;
  transition: transform .3s ease;
}
.tombol:hover { transform: scale(.9); }
.tombol:disabled { opacity: .6; cursor: default; transform: none; }

.tombol.kecil { font-size: 12px; border-radius: 20px; padding: 5px 15px; }

.tombol.putih {
  color: var(--maron);
  background: #fff;
  border-radius: 25px;
}

/* ============================================================
   SAMPUL
   ============================================================ */

.sampul {
  position: fixed;
  inset: 0;
  z-index: 99999;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  /* 2,5 detik dengan easeInOutCubic - angka dan kurva yang sama dipakai
     acuan lewat $("#cover").animate({opacity:0,top:"-100vh"},2500,
     'easeInOutCubic'). */
  transition: transform 2.5s cubic-bezier(.645, .045, .355, 1), opacity 2.5s cubic-bezier(.645, .045, .355, 1);
}
.sampul.pergi { transform: translateY(-100%); opacity: 0; }

.sampul-latar {
  position: absolute;
  inset: 0;
  max-width: var(--lebar);
  margin: 0 auto;
  background: url("zs-sampul.jpg") center center / cover no-repeat;
}

.sampul-isi {
  position: relative;
  width: 100%;
  max-width: var(--lebar);
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0 1em;
  text-align: center;
}

/* Jarak antar barisnya dipasang satu per satu, bukan lewat gap, supaya tiap
   angkanya bisa sama persis dengan acuan: 10px di antara widget, 16px di
   bawah nama (di sana nama duduk di section tersendiri yang bermargin 1em),
   dan 16+10px di bawah catatan. Diukur dari acuan saat dijalankan, bukan
   dikira-kira. */
.sampul-isi > .pembuka    { margin-bottom: 10px; }
.sampul-isi > .nama-besar { margin-bottom: 16px; }
.sampul-isi > .kepada     { margin-bottom: 10px; }
.sampul-isi > .nama-tamu  { margin-bottom: 10px; }
.sampul-isi > .maaf       { margin-bottom: 26px; }

/* Isi sampul datang satu per satu, dan tiap elemennya memakai gerak yang
   sama persis dengan acuan - nama animasinya, lamanya, dan jedanya:

     pohon kiri      rotateInDownLeft    jeda 600ms   lama 2s
     pohon kanan     rotateInDownRight   jeda 1400ms  lama 2s
     "The Wedding Of" zoomIn             tanpa jeda   lama 1,25s
     nama mempelai   zoomIn              jeda 400ms   lama 1,25s
     sapaan          fadeInUp            jeda 1000ms  lama 2s
     nama tamu       fadeInUp            jeda 1400ms  lama 2s
     catatan         fadeInUp            jeda 1800ms  lama 2s
     tombol          zoomIn              jeda 2200ms  lama 2s

   Acuannya menahan tiap elemen dengan visibility:hidden selama jedanya lalu
   memasang kelas animasinya lewat setTimeout; di sini hasil yang sama
   didapat dari animation-delay dengan fill-mode both - selama jedanya
   elemennya duduk di bingkai "from", jadi sama-sama tidak terlihat.

   Keyframe-nya disalin apa adanya dari animate.css milik Elementor di
   referensi/, cuma namanya yang diberi awalan supaya tidak bertabrakan. */
.sampul-isi > .pembuka    { animation: zs-zoom-in 1.25s both; }
.sampul-isi > .nama-besar { animation: zs-zoom-in 1.25s .4s both; }
.sampul-isi > .kepada     { animation: zs-fade-in-up 2s 1s both; }
.sampul-isi > .nama-tamu  { animation: zs-fade-in-up 2s 1.4s both; }
.sampul-isi > .maaf       { animation: zs-fade-in-up 2s 1.8s both; }
.sampul-isi > .buka-bungkus { animation: zs-zoom-in 2s 2.2s both; }

.sampul .pohon-kiri  { animation: zs-rotate-in-down-left 2s .6s both; }
.sampul .pohon-kanan { animation: zs-rotate-in-down-right 2s 1.4s both; }

.buka-bungkus { text-align: center; }

/* Acuan mengecilkan tombol sampulnya jadi 12px di bawah 768px - titik
   patah dan angkanya diambil apa adanya. Tombol lain tidak ikut. */
@media (max-width: 767px) {
  .buka-bungkus .tombol { font-size: 12px; }
}

@keyframes naik {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes zs-zoom-in {
  from { opacity: 0; transform: scale3d(.3, .3, .3); }
  50%  { opacity: 1; }
}

@keyframes zs-fade-in-up {
  from { opacity: 0; transform: translate3d(0, 100%, 0); }
  to   { opacity: 1; transform: none; }
}

@keyframes zs-rotate-in-down-left {
  from { transform-origin: left bottom; transform: rotate3d(0, 0, 1, -45deg); opacity: 0; }
  to   { transform-origin: left bottom; transform: none; opacity: 1; }
}

@keyframes zs-rotate-in-down-right {
  from { transform-origin: right bottom; transform: rotate3d(0, 0, 1, 45deg); opacity: 0; }
  to   { transform-origin: right bottom; transform: none; opacity: 1; }
}

/* Pohon. Pembungkusnya yang berputar, gambarnya yang dipantulkan - dua
   lapis, seperti di acuan. Satu lapis saja tidak cukup: scaleX(-1) dan
   rotate di satu transform yang sama ikut menghitung tumpuan yang sama,
   dan pohon kirinya melompat ke seberang begitu geraknya mulai. */
.pohon {
  position: absolute;
  z-index: 0;
  pointer-events: none;
}
.pohon img { max-width: none; }
.pohon-kiri img { transform: scaleX(-1); }

/* Letaknya tidak sama di sampul dan di bagian ayat - di acuan pun begitu. */
.sampul .pohon-kiri  { top: 120px; left: -100px; }
.sampul .pohon-kanan { top: 50px; right: -125px; }
.sampul .pohon-kiri img  { width: 230px; }
.sampul .pohon-kanan img { width: 250px; }

.ayat-bagian .pohon-kiri  { top: 150px; left: -150px; }
.ayat-bagian .pohon-kanan { top: 50px; right: -150px; }
.ayat-bagian .pohon-kiri img  { width: 230px; }
.ayat-bagian .pohon-kanan img { width: 250px; }

/* Kawanan burung di atas pohon - pengganti animasi Lottie milik acuan.
   Letak 10% dari atas, selebar kolomnya, tinggi 238px, dan kesamaran 0,4
   diukur dari widget-nya saat acuan dijalankan; letak tiap burungnya
   diambil dari tangkapan layar acuan di lebar yang sama. */
.burung {
  position: absolute;
  top: 10%;
  left: 0;
  z-index: 0;
  width: 100%;
  height: 259px;
  opacity: .4;
  pointer-events: none;
}
.burung svg {
  position: absolute;
  overflow: visible;
  fill: none;
  stroke: var(--tinta);
  stroke-width: 1.6;
  stroke-linecap: round;
  animation: zs-melayang 7s ease-in-out infinite alternate;
}
.burung .sayap-kiri, .burung .sayap-kanan {
  transform-box: view-box;
  transform-origin: 20px 13px;
}
.burung .sayap-kiri  { animation: zs-kepak-kiri .62s ease-in-out infinite alternate; }
.burung .sayap-kanan { animation: zs-kepak-kanan .62s ease-in-out infinite alternate; }

.burung .burung-1 { left: 20%; top: 30px;  width: 26px; }
.burung .burung-2 { left: 42%; top: 98px;  width: 21px; animation-delay: -1.9s; }
.burung .burung-3 { left: 56%; top: 106px; width: 30px; animation-delay: -3.4s; }
.burung .burung-4 { left: 86%; top: 168px; width: 22px; animation-delay: -5.1s; }
.burung .burung-5 { left: 9%;  top: 136px; width: 17px; animation-delay: -2.6s; }

.burung .burung-2 path { animation-delay: -.21s; }
.burung .burung-3 path { animation-delay: -.38s; }
.burung .burung-4 path { animation-delay: -.14s; }
.burung .burung-5 path { animation-delay: -.47s; }

@keyframes zs-kepak-kiri {
  from { transform: rotate(-6deg); }
  to   { transform: rotate(16deg); }
}

@keyframes zs-kepak-kanan {
  from { transform: rotate(6deg); }
  to   { transform: rotate(-16deg); }
}

@keyframes zs-melayang {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(16px, -12px, 0); }
}

.pembuka {
  font-family: var(--tangan);
  font-size: 30px;
  line-height: 1.3;
  color: var(--tinta);
}

.nama-besar {
  font-family: var(--judul);
  font-weight: 600;
  font-size: 55px;
  line-height: 1;
  text-transform: uppercase;
  color: var(--maron);
}

.amp {
  display: inline-block;
  font-family: var(--skrip);
  font-size: 24px;
  font-weight: 400;
  text-transform: none;
  color: var(--tinta);
}

/* line-height 1 di dua baris terakhir bukan kelalaian: Elementor memasang
   line-height:1 di tiap judulnya, dan acuan tidak menimpanya di sini. */
.kepada { font-size: 15px; line-height: 1.4; }
.nama-tamu { font-size: 20px; font-weight: 700; line-height: 1; padding: 0 1em; }
.maaf { font-size: 11px; font-style: italic; line-height: 1; padding: 0 1em; }

/* ============================================================
   PANGGUNG
   ============================================================ */

.panggung {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.lapis {
  position: absolute;
  inset: -10% 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  will-change: transform;
}
.lapis-bawaan { background-image: url("zs-panggung.jpg"); }

.panggung-isi {
  position: relative;
  z-index: 2;
  width: 100%;
  padding: 0 20px;
  text-align: center;
}

/* Isi panggung baru masuk sesudah sampulnya menepi, dan memakai kosakata
   gerak yang sama dengan acuan: tiga zoomIn berurutan lalu fadeInDown untuk
   penunjuk gulung, masing-masing 2 detik dengan jeda 0/400/800/1200 ms.

   Yang tidak ikut: di acuan isinya baru dipasang 6 detik sesudah tombol
   ditekan, menunggu video latarnya habis. Di sini videonya tidak ada - 6
   detik layar yang diam cuma terasa seperti undangan yang macet - jadi yang
   dipakai jeda acuan apa adanya, dihitung dari saat sampulnya mulai pergi. */
/* Disembunyikan dengan visibility, bukan opacity. zoomIn tidak punya bingkai
   "to", jadi keadaan akhirnya diambil dari gaya elemennya sendiri - dengan
   opacity:0 di situ, geraknya justru berakhir tidak terlihat. Acuan pun
   memakai visibility (.elementor-invisible) untuk alasan yang sama. */
.panggung-isi > * { visibility: hidden; }
.undangan-terbuka .panggung-isi > * { visibility: visible; }
.undangan-terbuka .panggung-isi .t1 { animation: zs-zoom-in 2s both; }
.undangan-terbuka .panggung-isi .t2 { animation: zs-zoom-in 2s .4s both; }
.undangan-terbuka .panggung-isi .t3 { animation: zs-zoom-in 2s .8s both; }
.undangan-terbuka .panggung-isi .t4 { animation: zs-fade-in-down 2s 1.2s both; }

/* Pengganti video latar acuan. Panggung bawaan kita memakai gambar yang
   persis frame cadangan video itu (fallback-general-motion-v1-.jpg), jadi
   yang hilang memang geraknya saja. Yang dipasang di sini dorongan kamera
   pelan selama 7 detik - mundur dari 1,18 ke diam, sepanjang video acuan -
   bukan tiruan isi videonya, yang tidak ikut terunduh ke referensi/.

   Lapisan milik pemilik hajatan tidak ikut: yang itu sudah punya parallax
   berlapis sendiri. */
.lapis-bawaan { background-image: none; }
.lapis-gerak {
  position: absolute;
  inset: 0;
  background: url("zs-panggung.jpg") center center / cover no-repeat;
  transform: scale(1.18);
  transform-origin: 50% 65%;
}
.undangan-terbuka .lapis-gerak {
  animation: zs-panggung-masuk 7s cubic-bezier(.25, .46, .45, .94) both;
}

@keyframes zs-panggung-masuk {
  from { transform: scale(1.18); }
  to   { transform: scale(1); }
}

@keyframes zs-fade-in-down {
  from { opacity: 0; transform: translate3d(0, -100%, 0); }
  to   { opacity: 1; transform: none; }
}

.nama-panggung {
  font-family: var(--judul);
  font-weight: 600;
  font-size: 50px;
  line-height: 1.2;
  text-transform: uppercase;
  color: var(--maron);
}

.tanggal-panggung { font-size: 15px; font-weight: 700; line-height: 1.3; }

.turun {
  display: inline-block;
  margin-top: 20px;
  width: 40px;
  height: 40px;
  color: var(--maron);
}
.turun .ikon { width: 100%; height: 100%; animation: melambai 1.8s ease-in-out infinite; }

@keyframes melambai {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(8px); }
}

/* ============================================================
   AYAT - kubah di atas latar maron
   ============================================================ */

.ayat-bagian {
  background: radial-gradient(at center center, var(--maron-terang) 0%, var(--maron) 100%);
  padding: 2em 0;
}
.ayat-bagian::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url("zs-latar.jpg") top center / cover no-repeat;
  opacity: .08;
  pointer-events: none;
}

.kubah {
  position: relative;
  margin: 2em 20px 0;
  /* Lengkung 300px memakan sudut atas, dan bunga di tepi bawah menutup
     sekitar 200px terakhir. Jarak dalam atas-bawah di sini yang menjaga
     monogram dan sumber ayat tetap berada di luar keduanya. */
  padding: 3em 1.5em 12em;
  background: var(--jambu);
  border-radius: 300px 300px 0 0;
  box-shadow: var(--bayang);
  text-align: center;
  overflow: hidden;
}
.kubah::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url("zs-latar.jpg") bottom center / cover no-repeat;
  opacity: .15;
  pointer-events: none;
}
.kubah > * { position: relative; z-index: 1; }

.monogram {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .2em;
  margin: 2em 0 1.5em;
}
.monogram .huruf {
  font-family: var(--judul);
  font-weight: 500;
  font-size: 70px;
  line-height: 1.3;
  color: var(--maron);
}
.monogram .huruf:first-of-type { margin-bottom: 1em; }
.monogram .huruf:last-of-type { margin-top: 1em; }

.amp-bunga { width: 35px; height: auto; }
.amp-bunga.besar { width: 55px; margin: 3em auto; }

.arab {
  font-family: var(--teks);
  font-size: 18px;
  line-height: 2;
  margin: 0 1.5em 1em;
}

.ayat {
  font-size: 14px;
  font-weight: 600;
  font-style: italic;
  line-height: 1.5;
  margin: 0 1.5em 1em;
}

.sumber { font-size: 16px; font-weight: 600; }

.bunga-bawah {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  z-index: 2;
  pointer-events: none;
}

/* ============================================================
   MEMPELAI - kapsul berlengkung penuh
   ============================================================ */

/* Tanpa lapisan apa pun: bagian ini memperlihatkan hamparan bunga halaman
   apa adanya, seperti di acuan. */
.mempelai-bagian { background: transparent; }

.kapsul {
  position: relative;
  margin: 2em 1em;
  padding: 6em 1em 8em;
  background: rgba(241, 226, 226, .93);
  border: 4px solid var(--maron);
  border-radius: 300px;
  text-align: center;
}

.judul-skrip {
  font-family: var(--skrip);
  font-size: 30px;
  font-weight: 500;
  line-height: 1.2;
  color: var(--tinta);
}
.judul-skrip.terang { color: #fff; }

.salam { font-size: 14px; line-height: 1.5; margin-top: 1.5em; }

.mempelai { margin-top: 2em; }

.potret {
  width: 160px;
  height: 200px;
  object-fit: cover;
  margin: 0 auto 1em;
  border: 3px solid var(--maron);
  border-radius: 125px 125px 8px 8px;
}

.panggilan {
  font-family: var(--skrip);
  font-size: 28px;
  font-weight: 500;
  line-height: 1.3;
  color: var(--maron);
  margin: 1em 0;
}

.nama-penuh {
  font-family: var(--judul);
  font-weight: 600;
  font-size: 26px;
  line-height: 1;
  margin-bottom: .5em;
}

.anak { font-size: 14px; font-weight: 700; letter-spacing: .5px; margin-bottom: .25em; }
.ortu { font-size: 14px; letter-spacing: .5px; }

.mempelai .tombol.kecil { margin-top: 1em; font-size: 12px; }

/* ============================================================
   SAVE THE DATE
   ============================================================ */

.tanggal-bagian::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--maron);
  opacity: .9;
}

.tanggal-isi {
  position: relative;
  z-index: 1;
  padding: 4em 1.5em 2em;
  text-align: center;
}

/* Di belakang isinya, bukan di depan. Di acuan bunga sudut ini memang
   digambar paling akhir, tapi di sana bagiannya selalu panjang - ada daftar
   ucapan di bawahnya - jadi bunganya tidak pernah bertemu teks. Undangan
   yang ucapannya masih kosong akan tertutup, dan nama tamu lebih penting
   daripada urutan gambar. */
/* Seperti pohon: pembungkusnya yang bergerak, gambarnya yang dipantulkan. */
.bunga-sudut {
  position: absolute;
  z-index: 0;
  pointer-events: none;
}
.bunga-sudut img { width: 100px; max-width: none; }
.bunga-sudut.sudut-kanan img { transform: scaleX(-1); }
.bunga-sudut.sudut-kiri { top: 180px; left: -40px; }
.bunga-sudut.sudut-kanan { top: 10px; right: -25px; }

.hitung {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  max-width: 90%;
  margin: 1.5em auto 1em;
}
.hitung > div {
  padding: 12px 0;
  border: 1px solid #fff;
  border-radius: 8px;
  color: #fff;
}
.hitung strong {
  display: block;
  font-family: var(--judul);
  font-weight: 700;
  font-size: 26px;
  line-height: 1.1;
}
.hitung span { font-size: 12px; }

/* Angka yang berganti tergulung sedikit, bukan melompat. */
.hitung strong.ganti { animation: ganti .45s ease; }
@keyframes ganti {
  from { transform: translateY(-40%); opacity: .2; }
  to   { transform: translateY(0); opacity: 1; }
}

.usai { color: #fff; font-size: 14px; margin: 1em 0; }

/* ============================================================
   ACARA

   Di acuan, lengkung 250px-nya dipasang pada dua lapis section yang
   latarnya kosong - jadi tidak pernah terlihat. Yang tergambar adalah
   kolom di dalamnya: persegi lengkung 25px berlatar foto acara dengan
   bayangan ke dalam, dan satu panel merah muda 35% di dalamnya lagi.
   Itu yang ditiru di sini, bukan angka 250px-nya.
   ============================================================ */

.acara-bagian { padding: 2em 0 4em; }
.acara-bagian::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--maron);
  opacity: .9;
  mix-blend-mode: multiply;
}

.acara-kartu {
  position: relative;
  z-index: 1;
  margin: 2em 1.5em 0;
  padding: 20px;
  border-radius: 25px;
  background: url("zs-acara.jpg") center center / cover no-repeat;
  box-shadow: inset 0 0 10px rgba(0, 0, 0, .5);
}

.acara-dalam {
  position: relative;
  padding: 4em 1em;
  border-radius: 25px;
  background: rgba(241, 226, 226, .35);
  text-align: center;
}

.acara-nama {
  font-family: var(--judul);
  font-weight: 700;
  font-size: 26px;
  line-height: 1.3;
  text-transform: uppercase;
}

.garis {
  display: block;
  width: 75%;
  height: 1px;
  margin: 1em auto 2em;
  background: var(--tinta);
}

.acara-hari {
  font-family: var(--tangan);
  font-size: 42px;
  line-height: 1;
  color: #000;
}

.acara-angka {
  font-family: var(--judul);
  font-weight: 700;
  font-size: 60px;
  line-height: 1.3;
  text-transform: uppercase;
  color: var(--maron);
  margin: -.1em 0;
}

.acara-bulan {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .6em;
  margin-bottom: 1em;
  font-family: var(--judul);
  font-weight: 700;
  font-size: 20px;
  text-transform: uppercase;
}
/* Titik pemisah bulan dan tahun memakai hijau daun acuan - satu-satunya
   tempat warna itu dipakai, dan memang cuma sebesar ini. */
.acara-bulan span + span::before {
  content: "\2022";
  color: var(--daun);
  margin-right: .6em;
}

.acara-jam {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .5em;
  margin-bottom: 2em;
  font-size: 18px;
  font-weight: 700;
}
.acara-jam .ikon { color: var(--maron); }

.acara-lokasi-judul {
  font-family: var(--judul);
  font-weight: 700;
  font-size: 20px;
  line-height: 1.3;
  margin-bottom: .5em;
}

.acara-lokasi { font-size: 14px; line-height: 1.5; }

.acara-dalam .tombol { margin-top: 1em; }

/* ============================================================
   GALERI

   Varian acuan yang dipakai di sini "Tanpa Foto", jadi tidak punya galeri.
   Lengkung 125px-nya diambil dari varian acuan yang berfoto supaya galeri
   milik pemilik hajatan tidak terlihat seperti tempelan dari tema lain.
   ============================================================ */

.galeri-bagian {
  padding: 4em 1.5em;
  text-align: center;
}
.galeri-bagian::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--jambu);
  opacity: .8;
  mix-blend-mode: multiply;
}
.galeri-bagian > * { position: relative; z-index: 1; }

.kisi {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-top: 2em;
}

.petak {
  padding: 0;
  border: 3px solid var(--maron);
  border-radius: 125px 125px 12px 12px;
  background: none;
  cursor: pointer;
  overflow: hidden;
  aspect-ratio: 3 / 4;
}
.petak img { width: 100%; height: 100%; object-fit: cover; }

/* ============================================================
   LOVE STORY
   ============================================================ */

.kisah-bagian {
  background: radial-gradient(at center center, var(--maron-terang) 0%, var(--maron) 100%);
  padding: 4em 1.5em;
  text-align: center;
}
.kisah-bagian > * { position: relative; z-index: 1; }

.lajur {
  position: relative;
  list-style: none;
  margin: 2em 0 0;
  padding: 0 0 0 15px;
  text-align: left;
}
.lajur::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 15px;
  width: 2px;
  background: rgba(255, 252, 243, .53);
}

.lajur li { position: relative; padding-left: 40px; }
.lajur li + li { margin-top: 30px; }

.titik {
  position: absolute;
  left: -15px;
  top: 0;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--maron);
  color: rgba(255, 255, 255, .74);
}
.titik .ikon { width: 12px; height: 12px; }

.kisah-kartu {
  position: relative;
  padding: 1em;
  border-radius: 12px;
  background: rgba(243, 241, 239, .93);
  box-shadow: var(--bayang);
}
/* Panah kecil yang menunjuk balik ke lajur waktunya - bagian dari rupa
   kartu di acuan, bukan hiasan tambahan. */
.kisah-kartu::before {
  content: "";
  position: absolute;
  left: -8px;
  top: 14px;
  width: 16px;
  height: 16px;
  background: rgba(243, 241, 239, .93);
  transform: rotate(45deg);
}

.kisah-kartu h4 {
  font-size: 16px;
  font-weight: 700;
  color: var(--maron);
  margin-bottom: .4em;
}
.kisah-kartu p { font-size: 14px; line-height: 1.5; }
.kisah-kartu em { display: block; margin-top: .4em; color: var(--emas); }

/* ============================================================
   WEDDING GIFT
   ============================================================ */

.hadiah-bagian { padding: 2em 1em; }

.kotak {
  position: relative;
  padding: 4em 1em;
  background: rgba(241, 226, 226, .93);
  border: 4px solid var(--maron);
  border-radius: 20px;
  box-shadow: var(--bayang);
  text-align: center;
}

.keterangan { font-size: 14px; line-height: 1.5; margin: 1.5em 0 1em; }

.isi-hadiah { overflow: hidden; }

.kartu {
  position: relative;
  display: flex;
  gap: 1em;
  margin-top: 1.5em;
  padding: 1em;
  border: 1px solid #fff;
  border-radius: 12px;
  box-shadow: 0 0 12px rgba(0, 0, 0, .15);
  background: url("zs-kartu.jpg") center center / cover no-repeat;
  text-align: left;
  color: #fff;
}
/* Merah kartu dipasang sebagai lapisan multiply di atas teksturnya, persis
   seperti di acuan: kalau dicampur jadi satu warna rata, serat kertasnya
   hilang dan kartunya terlihat seperti kotak polos. */
.kartu::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 11px;
  background: var(--merah);
  mix-blend-mode: multiply;
  pointer-events: none;
}
.kartu > * { position: relative; z-index: 1; }

.kartu-kiri { width: 70%; }
.kartu-kanan {
  width: 30%;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1em;
}

.bank {
  display: inline-block;
  margin-bottom: 1em;
  padding: 8px 10px;
  border-radius: 8px;
  background: #fff;
  color: var(--maron);
  font-family: var(--judul);
  font-weight: 700;
  font-size: 16px;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: .5px;
}

.kartu-label { font-size: 14px; font-weight: 700; margin-bottom: .5em; }
.kartu-nomor {
  font-family: "Noto Sans", "Segoe UI", sans-serif;
  font-size: 14px;
  letter-spacing: 1px;
  margin-bottom: 1em;
  word-break: break-all;
}
.kartu-nama { font-size: 14px; }

.chip { width: 55%; margin-left: auto; }
.hadiah-ikon { width: 32px; height: 32px; margin-left: auto; }
.kado-judul { font-family: var(--judul); font-size: 26px; font-weight: 700; margin-bottom: .5em; }

/* ============================================================
   WISHES
   ============================================================ */

.ucapan-bagian::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--jambu);
  opacity: .8;
  mix-blend-mode: multiply;
}

.ucapan-isi {
  position: relative;
  z-index: 1;
  padding: 4em 1em;
  text-align: center;
}

.borang-bingkai {
  margin-top: 1em;
  padding: 1em;
  border: 1px solid var(--maron);
  border-radius: 12px;
  background: rgba(255, 252, 243, .55);
  text-align: left;
}

.jumlah-ucapan {
  margin-bottom: 1em;
  font-size: 14px;
  color: var(--tinta);
}
.jumlah-ucapan strong { color: var(--maron); }

.borang { display: grid; gap: .75em; }

.borang input,
.borang textarea {
  width: 100%;
  padding: .7em .9em;
  border: 1px solid rgba(85, 0, 0, .2);
  border-radius: 10px;
  background: #fff;
  font-family: var(--teks);
  font-size: 14px;
  color: var(--tinta);
  resize: vertical;
}
.borang input:focus-visible,
.borang textarea:focus-visible {
  outline: 2px solid var(--maron);
  outline-offset: 1px;
}

.dari-tamu { font-size: 14px; }
.dari-tamu strong { color: var(--maron); }

.pesan-galat { font-size: 13px; color: var(--merah); }

.borang .tombol { justify-self: center; }

.daftar-ucapan {
  margin-top: 1.5em;
  max-height: 320px;
  overflow-y: auto;
  display: grid;
  gap: 1em;
}

.balon {
  padding-bottom: 1em;
  border-bottom: 1px solid rgba(51, 51, 51, .31);
}
.balon:last-child { border-bottom: 0; }
.balon-nama { display: block; font-size: 14px; font-weight: 700; color: var(--emas); }
.balon p { font-size: 14px; line-height: 1.5; margin: .3em 0; }
.balon time { font-size: 12px; font-family: "Nunito Sans", sans-serif; color: var(--tinta); opacity: .75; }

.kosong { font-size: 14px; opacity: .75; }

/* ============================================================
   PENUTUP
   ============================================================ */

.penutup-bagian { padding-bottom: 11em; }
.penutup-bagian::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--jambu);
  opacity: .8;
}

.penutup-isi {
  position: relative;
  z-index: 1;
  padding: 4em 2em 0;
  text-align: center;
}

.penutup-isi .judul-skrip { margin-bottom: 2em; }
.penutup-isi .keterangan { margin-bottom: 4em; }

.berbahagia { font-size: 16px; font-weight: 700; line-height: 1.5; margin-bottom: 1em; }

.nama-penutup {
  font-family: var(--judul);
  font-weight: 700;
  font-size: 26px;
  line-height: 1.3;
  text-transform: uppercase;
  color: var(--maron);
}

.tagar {
  margin-top: 1em;
  font-family: var(--tangan);
  font-size: 22px;
  color: var(--maron);
}

/* ============================================================
   MUSIK, LAMPU SOROT, ROTI
   ============================================================ */

.musik {
  position: fixed;
  right: 1em;
  bottom: 2em;
  z-index: 999;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  color: #fff;
  background: var(--tombol-latar);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35);
  transition: transform .4s ease, opacity .4s ease;
}
.musik .ikon { width: 24px; height: 24px; }
.musik.berputar .ikon { animation: berputar 8s linear infinite; }
.musik.minggir { transform: translateX(120%); opacity: 0; }

@keyframes berputar {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

.lampu {
  position: fixed;
  inset: 0;
  z-index: 100000;
  display: grid;
  place-items: center;
  padding: 1.5em;
  background: rgba(34, 0, 0, .94);
}
.lampu img { max-width: 100%; max-height: 85vh; border-radius: 8px; }
.lampu .tutup {
  position: absolute;
  top: 1em;
  right: 1em;
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  color: #fff;
  background: rgba(255, 255, 255, .15);
}
.lampu .tutup .ikon { width: 20px; height: 20px; }

.roti {
  position: fixed;
  left: 50%;
  bottom: 5.5em;
  z-index: 100001;
  transform: translateX(-50%);
  padding: .6em 1.2em;
  border-radius: 25px;
  background: var(--maron);
  color: #fff;
  font-size: 13px;
  white-space: nowrap;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35);
}

/* ============================================================
   LAYAR LEBAR
   ============================================================ */

@media (min-width: 900px) {
  .latar-sisi { display: flex; }
  .bingkai { box-shadow: 0 0 40px rgba(0, 0, 0, .45); }
  .sampul-isi { box-shadow: 0 0 40px rgba(0, 0, 0, .45); }
  .musik { right: calc(50% - var(--lebar) / 2 + 1em); }
}

/* ============================================================
   GERAK SEMINIMALNYA

   Tamu yang memintanya tetap harus bisa membaca undangannya. Semua kelas
   gerak dimatikan di sini sekaligus, bukan satu per satu di skrip - yang
   dimatikan memang gayanya, bukan logikanya.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .inv-fade-in, .inv-atas, .inv-bawah, .inv-kiri, .inv-kanan,
  .inv-rotate-in, .inv-flip-x, .inv-flip-y, .inv-zoom-in, .inv-zoom-out,
  .inv-petak {
    transform: none !important;
    opacity: 1 !important;
    transition: none !important;
  }

  /* Gambar ini memakai transform sebagai rupanya, bukan sebagai gerak:
     tanpa baris ini pantulannya ikut hilang. Pohonnya tidak perlu disebut
     lagi - pantulannya sudah pindah ke gambar di dalam pembungkusnya, dan
     yang dimatikan di sini pembungkusnya. */
  .bunga-sudut.sudut-kanan { transform: scaleX(-1) !important; }

  .turun .ikon, .musik.berputar .ikon { animation: none !important; }
  .masuk[data-masuk], .lapis-gerak { animation: none !important; }
  .lapis-gerak { transform: none; }
  .burung svg, .burung path { animation: none !important; }

  /* Kawanan burungnya dilewati: kesamaran 0,4 itu rupanya, bukan sisa
     gerak yang belum selesai. */
  .sampul-isi > *:not(.burung), .panggung-isi > * {
    animation: none !important;
    opacity: 1;
    transform: none;
  }
  .sampul.pergi { transition: none !important; }
}
