/* PENJELASAN: Aturan dasar untuk semua elemen. box-sizing memudahkan menghitung ukuran; margin dan padding awal dihapus lalu diatur per komponen. */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* PENJELASAN: Pengaturan halaman dan teks umum. Ubah background untuk warna latar, color untuk warna teks, dan font-family untuk font dasar. */
html {
  scroll-behavior: smooth;
}

body {
  min-height: 100vh;
  background: #000000;
  color: #26201b;
  font-family: 'Times New Roman', Georgia, serif;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* ===== LANDING PAGE ===== */
/* PENJELASAN: Layar pembuka mengisi tinggi layar dan menengahkan isinya. Ubah background untuk mengganti warna latarnya. */

.landing-page {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 100vh;
  background: #f7f4ef;
}

/* PENJELASAN: Class hidden menyembunyikan landing page setelah transisi selesai. */
.landing-page.hidden {
  display: none;
}

/* PENJELASAN: Efek memudar saat pindah dari landing page. Ubah opacity atau durasi transition hanya jika ingin mengubah efek visual. */
.landing-page.is-fading {
  opacity: 0;
  pointer-events: none;
  transition: opacity 1s ease-in-out;
}

/* PENJELASAN: Batas bidang layar pembuka. Lebar mengikuti tinggi pada layar pendek dan aspect-ratio menjaga komposisi desain. */
#landingPage {
  position: relative;
  width: min(100vw, 402px, 46.0183vh);
  height: auto;
  min-height: 0;
  aspect-ratio: 402 / 874;
  overflow: hidden;
  margin-left: auto;
  margin-right: auto;
}

/* PENJELASAN: Kumpulan salam dan judul. top dan left menentukan posisi, width dan padding menentukan area, z-index menempatkan teks di depan roda. */
.landing-copy {
  position: absolute;
  top: clamp(18px, 3.2%, 28px);
  left: 0;
  z-index: 15;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  padding: 0 16px;
  color: #3f362e;
  text-align: center;
  pointer-events: none;
}

/* PENJELASAN: Ukuran, warna, jarak antarbaris, jarak huruf, dan jarak dari tepi untuk teks salam. */
/* PENJELASAN: Catatan belajar: font-style biasanya menerima normal/italic/oblique; nilai Bold di bawah dapat diabaikan browser. Tidak diubah agar tampilan tetap sama. */
.landing-greeting {
  font-size: 21px;
  line-height: 1.2;
  font-style: Bold;
  color: #890F24;
  letter-spacing: 0.06em;
  margin-top: 10px;
}

/* PENJELASAN: Gaya teks keterangan upacara. Ubah font-size untuk ukuran dan letter-spacing untuk jarak huruf. */
.landing-ceremony {
  margin-top: 10px;
  margin-bottom: 5px;
  font-size: 12px;
  line-height: 1.2;
  letter-spacing: 0.12em;
}
  

/* PENJELASAN: Gaya judul utama pada layar pembuka; margin-top mengatur jarak dari teks sebelumnya. */
.landing-title {
  margin-top: 10px;
  font-size: clamp(17px, 4.98vw, 20px);
  line-height: 1.1;
  letter-spacing: 0.06em;
  font-weight: bold;
}

/* PENJELASAN: Sapaan penerima undangan di dekat bawah layar. bottom dan left mengatur posisi; z-index menjaga teks tetap terlihat. */
.landing-guest {
  position: absolute;
  bottom: clamp(86px, 14.9%, 130px);
  left: 0;
  z-index: 15;
  width: 100%;
  color: #000000;
  font-size: 15px;
  text-align: center;
  pointer-events: none;
}

/* PENJELASAN: Nama penerima undangan. bottom menentukan jarak dari bawah; font-size dan letter-spacing mengatur tampilannya. */
.landing-gname{
  position: absolute;
  bottom: clamp(66px, 11.45%, 100px);
  left: 0;
  z-index: 15;
  width: 100%;
  color: #4D3602;
  font-size: 17px;
  line-height: 1.2;
  letter-spacing: 0.15em;
  text-align: center;
  pointer-events: none;
}

/* PENJELASAN: Tombol untuk membuka undangan. bottom mengatur posisi dari bawah, z-index lapisannya, font-size ukuran teks, dan transform menengahkan tombol. */
.open-invitation-btn {
  position: absolute;
  left: 50%;
  bottom: clamp(20px, 5%, 44px);
  z-index: 20;
  padding: 10px;
  transform: translateX(-50%);
  border: 0;
  background: transparent;
  color: #4D3602;
  cursor: pointer;
  font-family: 'Cinzel', serif;
  font-size: clamp(10px, 2.8vw, 13px);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-decoration: underline;
  text-underline-offset: 5px;
  white-space: nowrap;
}

/* ===== RODA FOTO LANDING PAGE ===== */
/* PENJELASAN: Wadah roda. width mengatur ukuran maksimal, aspect-ratio menjaga bentuk, dan left menggeser roda ke kiri/kanan. */
.stage-container {
  width: min(100%, 402px);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* PENJELASAN: Area yang memotong bagian roda yang keluar. Ubah width untuk ukuran roda dan left untuk menggeser posisinya. */
.wheel-wrapper {
  position: relative;
  left: -5.225%;
  width: min(89.55%, 340px);
  aspect-ratio: 420 / 680;
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
  background-color: transparent;
}

/* PENJELASAN: Lapisan roda yang berputar. width memperbesar atau mengecilkan roda; top, margin, dan transform-origin menentukan pusat putaran; z-index mengatur lapisannya. */
.wheel-rotating {
  position: absolute;
  left: 0;
  top: 50%;
  width: 154.76%;
  aspect-ratio: 1 / 1;
  margin-left: -77.38%;
  margin-top: -77.38%;
  transform-origin: 50% 50%;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  transform: translate3d(0, 0, 0);
  animation-name: wheelRotation;
  animation-duration: 90s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  z-index: 1;
}

/* PENJELASAN: Putaran roda penuh dari 0 sampai 360 derajat. Lama satu putaran diatur oleh animation-duration pada .wheel-rotating. */
@keyframes wheelRotation {
  0% {
    transform: translate3d(0, 0, 0) rotate(0deg);
  }
  100% {
    transform: translate3d(0, 0, 0) rotate(360deg);
  }
}

/* PENJELASAN: SVG roda mengikuti ukuran wadah dan menampilkan bagian gambar yang melewati bidangnya. */
.wheel-rotating svg {
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}

/* PENJELASAN: Kursor menjadi penunjuk saat mengarah ke sektor foto yang dapat diklik. */
.photo-sector {
  cursor: pointer;
}

/* PENJELASAN: Foto di roda dibuat hitam-putih dan sedikit transparan. filter mengubah efek warna, opacity mengatur transparansi. */
.photo-sector image {
  filter: grayscale(100%) contrast(1.05);
  opacity: 0.94;
}

/* PENJELASAN: Lapisan tipis di atas setiap sektor. fill mengatur warna dan tingkat transparansinya. */
.sector-overlay {
  fill: rgba(0, 0, 0, 0.03);
}

/* PENJELASAN: Garis pemisah sektor roda. stroke mengatur warna garis dan stroke-width ketebalannya. */
.sector-border {
  fill: none;
  stroke: #ffffff;
  stroke-width: 1.8;
  stroke-linejoin: round;
}

/* PENJELASAN: Lapisan lingkaran diam di atas roda. inset: 0 memenuhi wadah; z-index menentukan lapisan; pointer-events mengatur apakah klik diteruskan. */
.stationary-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 5;
}

/* PENJELASAN: SVG lingkaran mengikuti ukuran lapisan diam. */
.stationary-overlay svg {
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}

/* PENJELASAN: Cincin luar roda; fill none berarti tanpa isi dan stroke menentukan warna serta tebal garis. */
.outer-ring {
  fill: none;
  stroke: #ffffff;
  stroke-width: 2;
}

/* PENJELASAN: Lingkaran tengah roda. fill dan stroke mengatur warnanya; cursor dan pointer-events membuat lingkaran bisa diklik. */
.beige-hub-disk {
  fill: #cbbca9;
  stroke: #ffffff;
  stroke-width: 2.5;
  pointer-events: auto;
  cursor: pointer;
}

/* PENJELASAN: Panel teks di bagian tengah roda. left/top mengatur posisi, transform menengahkan vertikal, width/height mengatur area, padding mengatur ruang teks, dan z-index menentukan lapisan. */
.stationary-beige-panel {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 33.81%;
  height: 41.76%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: left;
  padding-left: clamp(10px, 3.2vw, 15px);
  padding-right: clamp(6px, 2.2vw, 11px);
  pointer-events: none;
  z-index: 10;
}

/* PENJELASAN: Menyusun tulisan panel secara vertikal. gap mengatur jarak antarbaris atau paragraf. */
.panel-content {
  display: flex;
  flex-direction: column;
  gap: clamp(3px, 1.2vw, 7px);
  pointer-events: auto;
}

/* PENJELASAN: Gaya judul panel jika elemen ber-class panel-title dipakai. font-family, font-size, warna, dan letter-spacing mengatur teks. */
.panel-title {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-style: italic;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: #26201b;
  line-height: 1.15;
  text-transform: uppercase;
  font-size: clamp(11.5px, 3.6vw, 16px);
}

/* PENJELASAN: Gaya teks kecil pertama di panel tengah. margin dan padding mengatur jarak; font-size, warna, dan font-style mengatur teks. */
.panel-subtitle {
  font-family: 'times new roman', Georgia, serif;
  font-style: italic;
  color: #4D3602;
  line-height: 1.2;
  font-size: clamp(9px, 2.4vw, 10px);
  padding-left: 0px;
  margin-left:-10px;
  margin-top:-20px;
  margin-bottom: 5px;
  font-weight: 800;
}

/* PENJELASAN: Gaya paragraf penjelas di panel tengah. line-height mengatur jarak baris; font-size dapat menyesuaikan ukuran layar melalui clamp. */
.panel-prose {
  font-family: 'times new roman', Georgia, serif;
  font-style: italic;
  color: #4D3602;
  line-height: 1.32;
  font-size: clamp(7.5px, 2.1vw, 9.6px);
  padding-left: 0px;
  margin-left:-10px;
}

/* PENJELASAN: Gaya kutipan di panel tengah, termasuk jarak atas, jarak baris, ukuran, dan warna teks. */
.panel-quote {
  font-family: 'times new roman', Georgia, serif;
  font-style: italic;
  color: #4D3602;
  line-height: 1.2;
  padding-top: 3px;
  padding-left: 0px;
  font-size: clamp(8px, 2.4vw, 10.5px);
  padding-left: 0px;
  margin-left:-10px;
  font-weight: 800;
}

/* PENJELASAN: Gaya tombol panel jika digunakan. gap mengatur jarak isi; cursor menunjukkan area klik; font properties mengatur tulisan tombol. */
.panel-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: none;
  border: none;
  cursor: pointer;
  padding-top: 2px;
  color: #3f362e;
  font-family: 'Cinzel', serif;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-size: clamp(7px, 2vw, 9px);
}

/* PENJELASAN: Titik kecil pada tombol panel. width dan height mengatur ukuran; border-radius 50% membuatnya bulat. */
.panel-btn .btn-dot {
  display: inline-block;
  width: clamp(4px, 1.2vw, 6px);
  height: clamp(4px, 1.2vw, 6px);
  border-radius: 50%;
  background-color: #4a3f36;
  flex-shrink: 0;
}

/* PENJELASAN: Garis bawah pada teks tombol panel. */
.panel-btn .btn-text {
  text-decoration: underline;
  text-decoration-color: #7d6f62;
  text-underline-offset: 2px;
}

/* ===== HALAMAN UTAMA DAN FRAME FOTO ===== */
/* PENJELASAN: Main page tersembunyi sampai mendapat class is-visible. max-width membatasi lebar, margin menengahkan, padding-bottom memberi ruang bawah, dan overflow menyembunyikan dekorasi yang keluar. */
.main-page {
  display: none;
  position: relative;
  width: 100%;
  max-width: 470px;
  margin: 0 auto;
  min-height: 100vh;
  background: #fff;
  overflow: hidden;
  text-align: center;
  padding-bottom: 60px;
  isolation: isolate;
  --main-section-space: clamp(24px, 7vw, 34px);
  --main-section-space-tight: clamp(16px, 5vw, 22px);
}

/* PENJELASAN: Menampilkan halaman utama setelah JavaScript menambahkan class ini. */
.main-page.is-visible {
  display: block;
}

/* PENJELASAN: Jarak atas dan bawah sebelum konten judul utama. */
.main-header {
  padding: clamp(42px, 12vw, 56px) 0 20px;
}

/* PENJELASAN: Gaya dua baris judul upacara. font-size/line-height mengatur ukuran dan tinggi baris, color warna teks, letter-spacing jarak antarhuruf. */
/* PENJELASAN: Catatan belajar: letter-spacing umumnya memakai satuan panjang, sehingga nilai persentase di bawah mungkin diabaikan browser. */
.ceremony-title {
  margin: 0;
  color: #8b1730;
  font-size: 20px;
  line-height: 30px;
  letter-spacing: 50%;
  font-weight: bold;
}

/* PENJELASAN: Jarak tanggal dari judul serta ukuran teks tanggal. */
.main-date {
  margin-top: 26px;
  margin-bottom: 0;
  font-size: 20px;
}

/* PENJELASAN: Wadah frame foto utama. position relative menjadi acuan lapisan slideshow yang diposisikan absolute; width mengatur ukuran dan margin menengahkan. */
.main-flower {
  position: relative;
  width: 90%;
  margin: 0 auto;
}

/* PENJELASAN: Gambar di dalam frame utama. width menentukan lebarnya; display block dan margin auto menengahkan gambar. */
.main-flower img {
  width: 90%;
  display: block;
  margin: auto;
}

/* PENJELASAN: Kotak slideshow yang diletakkan di atas gambar frame. top/left mengatur posisi, width ukuran, z-index urutan lapisan, dan aspect-ratio proporsinya. */
.main-flower .photo-frame-slideshow {
  position: absolute;
  top: 0;
  left: 5%;
  z-index: 1;
  width: 90%;
  aspect-ratio: 1055 / 1491;
}

/* PENJELASAN: Area foto di dalam frame. top/left/width/height menentukan batas foto; overflow memotong foto; border-radius membuat jendela foto oval. */
.main-flower .photo-container {
  position: absolute;
  top: 15%;
  left: 18%;
  width: 64%;
  height: 70%;
  overflow: hidden;
  border-radius: 50%;
}

/* PENJELASAN: Semua foto slideshow bertumpuk di tempat yang sama. inset mengisi wadah, object-fit mengatur crop, opacity/animation mengatur pergantian foto. */
.main-flower .photo-frame-slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  object-fit: cover;
  object-position: center;
  opacity: 0;
  animation: photo-frame-sequence 25s ease-in-out infinite;
}

/* PENJELASAN: Posisi crop foto pertama. Nilai kedua pada object-position menggeser titik fokus foto secara vertikal. */
.main-flower .photo-frame-slide-one {
  object-position: center 55%;
  opacity: 1;
}

/* PENJELASAN: Waktu mulai foto kedua relatif terhadap animasi utama. Ubah animation-delay untuk mengatur urutan tampil. */
.main-flower .photo-frame-slide-two {
  object-position: center center;
  animation-delay: -20s;
}

/* PENJELASAN: Delay foto ketiga, keempat, dan kelima membuat foto tampil bergantian. */
.main-flower .photo-frame-slide-three {
  animation-delay: -15s;
}

.main-flower .photo-frame-slide-four {
  animation-delay: -10s;
}

.main-flower .photo-frame-slide-five {
  animation-delay: -5s;
}

/* PENJELASAN: Gambar ornamen utama berada di atas slideshow; z-index lebih tinggi berarti tampil di depan foto. */
.main-flower > .photo-frame-overlay {
  position: relative;
  z-index: 2;
}

/* PENJELASAN: Mengatur kapan foto slideshow terlihat dan menghilang. Total durasi animation pada foto adalah 25 detik. */
@keyframes photo-frame-sequence {
  0%, 16% { opacity: 1; }
  20%, 96% { opacity: 0; }
  100% { opacity: 1; }
}

/* ===== BUNGA DAN DEKORASI ===== */
/* PENJELASAN: Wadah bunga menutupi halaman dan berada di lapisan latar. inset 0 memenuhi halaman; z-index 0 menaruhnya di bawah isi; pointer-events none membuat bunga tidak menghalangi klik. */
#mainPage > .main-flower-layer {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

/* PENJELASAN: Aturan dasar ukuran dan penyesuaian seluruh gambar bunga dekoratif. */
#mainPage > .main-flower-layer > img {
  position: absolute;
  display: block;
  height: auto;
  max-width: 48%;
  max-height: 280px;
  object-fit: contain;
}

/* PENJELASAN: Posisi dan ukuran bunga pertama. width memperbesar/memperkecil; top dan left menggeser; animation menentukan nama serta durasi gerak. */
#mainPage .bunga1 {
  width: 150px;
  top: 40%;
  left: -3%;
  animation: bunga-angin-satu 3s ease-in-out infinite;
}

/* PENJELASAN: Posisi dan ukuran bunga kedua; right mengatur jarak dari tepi kanan. */
#mainPage .bunga2 {
  width: 300px;
  top: 50%;
  right: -7%;
  animation: bunga-angin-dua 2.8s ease-in-out infinite;
}

/* PENJELASAN: Pengaturan khusus bunga ketiga. width/height menentukan ukuran; top/left/bottom menentukan posisi; animation mengatur gerak. */
#mainPage > .main-flower-layer > img.bunga3 {
  position: absolute;
  width: 385px;
  height: 549px;
  max-width: none;
  max-height: none;
  top: 70%;
  left: -25px;
  bottom: -15px;
  animation: bunga-angin-tiga 4.3s ease-in-out infinite;
}

/* PENJELASAN: Semua anak halaman selain wadah bunga berada di atas dekorasi. position dan z-index menentukan urutan lapisannya. */
#mainPage > :not(.main-flower-layer) {
  position: relative;
  z-index: 1;
}

/* PENJELASAN: Gerakan bunga pertama. Angka translate mengatur jarak geser dan rotate sudut kemiringan; durasi ada pada properti animation di selector bunga. */
@keyframes bunga-angin-satu {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  50% { transform: translate(8px, 3px) rotate(2.5deg); }
}

/* PENJELASAN: Gerakan bunga kedua; angka translate dan rotate menentukan jarak serta sudut gerak. */
@keyframes bunga-angin-dua {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  50% { transform: translate(-8px, 4px) rotate(-2.5deg); }
}

/* PENJELASAN: Gerakan bunga ketiga; angka translate dan rotate menentukan jarak serta sudut gerak. */
@keyframes bunga-angin-tiga {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  50% { transform: translate(7px, -3px) rotate(2deg); }
}

/* PENJELASAN: Jika perangkat meminta gerakan dikurangi, animasi bunga dimatikan demi kenyamanan pengguna. */
@media (prefers-reduced-motion: reduce) {
  .wheel-rotating,
  .main-flower .photo-frame-slide {
    animation: none;
  }

  #mainPage .bunga1,
  #mainPage .bunga2,
  #mainPage .bunga3 {
    animation: none;
  }
}

/* PENJELASAN: Pembatas hias. width/height menentukan area; margin mengatur jarak dari bagian lain; overflow memotong bagian gambar di luar area. */
.ornament-divider {
  width: 100%;
  height: 100px;
  position: relative;
  overflow: hidden;
  margin: var(--main-section-space-tight) 0;
}

/* PENJELASAN: Ukuran serta posisi gambar pembatas. left dan transform menengahkan horizontal; top menggeser gambar vertikal. */
.ornament-divider img {
  position: absolute;
  width: min(76%, 360px);
  height: auto;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

/* ===== TEKS UNDANGAN DAN FRAME NAMA ===== */
/* PENJELASAN: Ruang kiri/kanan untuk paragraf pembuka. Ubah padding horizontal untuk mengatur lebar teks. */
.opening-section {
  padding: 0 clamp(24px, 10vw, 45px);
}

/* PENJELASAN: Ukuran huruf, tinggi baris, dan jarak sebelum/sesudah paragraf pembuka. */
.opening-text {
  font-size: 15px;
  line-height: 1.30;
  margin: 0 0 var(--main-section-space-tight);
}

/* PENJELASAN: Jarak bagian foto nama dari paragraf sebelumnya. */
.name-section {
  margin-top: var(--main-section-space);
}

/* PENJELASAN: Area setiap frame nama. width menentukan lebar foto/frame dasar, aspect-ratio menjaga proporsi, margin menengahkan. */
.name-frame {
  position: relative;
  display: block;
  width: min(55%, 180px);
  aspect-ratio: 196 / 201;
  margin: 0 auto;
}

/* PENJELASAN: Ukuran dan posisi foto tetap memenuhi area name-frame; padding memberi ruang tepi. */
.name-frame-photo {
  position: absolute;
  display: block;
  width: 100%;
  height: 100%;
  inset: 0;
  z-index: 0;
  padding: 5%;
  object-fit: cover;
  opacity: 0;
  animation: name-frame-photo-sequence 12s ease-in-out infinite;
}

/* PENJELASAN: Menentukan foto pertama terlihat saat awal animasi. */
.name-frame-photo-first {
  opacity: 1;
}

/* PENJELASAN: Menggeser waktu mulai foto kedua agar tampil bergantian dengan foto pertama. */
.name-frame-photo-second {
  animation-delay: -6s;
}

/* PENJELASAN: Jeda animasi saat tab tidak terlihat untuk mengurangi pemakaian CPU dan GPU. */
.page-hidden .wheel-rotating,
.page-hidden .photo-frame-slide,
.page-hidden .name-frame-photo,
.page-hidden #mainPage .bunga1,
.page-hidden #mainPage .bunga2,
.page-hidden #mainPage .bunga3 {
  animation-play-state: paused;
}

.main-flower.is-out-of-view .photo-frame-slide,
.name-frame.is-out-of-view .name-frame-photo,
#mainPage .main-flower-layer > img.is-out-of-view {
  animation-play-state: paused;
}

/* PENJELASAN: Garis ganda dekoratif berada di atas foto, terpisah dari ukuran foto. */
.name-frame::before {
  position: absolute;
  inset: 4%;
  border: 1px solid #ad9162;
  box-shadow: inset 0 0 0 4px #fffefa, inset 0 0 0 5px rgba(173, 145, 98, 0.8);
  z-index: 2;
  pointer-events: none;
  content: "";
}

/* PENJELASAN: Aksen garis dan titik kecil membentuk detail di keempat sudut frame. */
.name-frame::after {
  position: absolute;
  inset: 2%;
  z-index: 3;
  background:
    linear-gradient(#ad9162, #ad9162) left top / 14px 1px no-repeat,
    linear-gradient(#ad9162, #ad9162) left top / 1px 14px no-repeat,
    linear-gradient(#ad9162, #ad9162) right top / 14px 1px no-repeat,
    linear-gradient(#ad9162, #ad9162) right top / 1px 14px no-repeat,
    linear-gradient(#ad9162, #ad9162) left bottom / 14px 1px no-repeat,
    linear-gradient(#ad9162, #ad9162) left bottom / 1px 14px no-repeat,
    linear-gradient(#ad9162, #ad9162) right bottom / 14px 1px no-repeat,
    linear-gradient(#ad9162, #ad9162) right bottom / 1px 14px no-repeat,
    radial-gradient(circle, #ad9162 1.5px, transparent 2px) left top / 8px 8px no-repeat,
    radial-gradient(circle, #ad9162 1.5px, transparent 2px) right top / 8px 8px no-repeat,
    radial-gradient(circle, #ad9162 1.5px, transparent 2px) left bottom / 8px 8px no-repeat,
    radial-gradient(circle, #ad9162 1.5px, transparent 2px) right bottom / 8px 8px no-repeat;
  pointer-events: none;
  content: "";
}

/* PENJELASAN: Jadwal opasitas dua foto bergantian. Total satu siklusnya ditentukan oleh animation-duration pada .name-frame-photo. */
@keyframes name-frame-photo-sequence {
  0%, 42% { opacity: 1; }
  50%, 92% { opacity: 0; }
  100% { opacity: 1; }
}

/* PENJELASAN: Gaya nama di bawah frame. margin mengatur jarak, color warna, font-size ukuran, dan line-height jarak antarbaris. */
.person-name {
  margin: 4px 0 10px;
  color: #8b1730;
  font-size: 15px;
  line-height: 176%;
  font-weight: bold;
  font-style: italic;
}

/* PENJELASAN: Ruang sisi dan jarak atas untuk teks pengantar sebelum detail acara. */
.invitation-message {
  padding: 0 clamp(24px, 9vw, 40px);
  margin-top: var(--main-section-space);
  font-size: 15px;
  line-height: 1.30;
}

/* ===== DETAIL ACARA DAN BUKU TAMU ===== */
/* PENJELASAN: Jarak antara teks pengantar dan detail acara. */
.event-details {
  margin-top: var(--main-section-space-tight);
}

/* PENJELASAN: Jarak antar kelompok tanggal, waktu, dan lokasi. */
.event-item {
  margin-bottom: 12px;
}

/* PENJELASAN: Warna, ukuran, dan jarak label Tanggal/Waktu/Lokasi. */
.event-label {
  margin: 0 0 2px;
  color: #890F24;
  font-size: 14px;
}

/* PENJELASAN: Gaya judul nilai tanggal dan waktu. font-size mengatur ukuran, color warna, letter-spacing jarak huruf. */
/* PENJELASAN: Catatan belajar: letter-spacing umumnya memakai satuan panjang, sehingga nilai persentase di bawah mungkin diabaikan browser. */
.event-item h3 {
  margin: 0;
  font-size: 15px;
  letter-spacing: 2%;
  color: #4D3602;
}

/* PENJELASAN: Tampilan tombol simpan kalender. width/min-height ukuran, margin dan padding jarak, border/background/color warna dan bentuk. */
.calendar-save-button {
  display: block;
  width: min(100%, 240px);
  min-height: 40px;
  margin: 14px auto 10px;
  padding: 8px 14px;
  border: 1px solid rgba(112, 87, 54, 0.55);
  border-radius: 4px;
  background: #fbf8f1;
  color: #6f5435;
  cursor: pointer;
  font: inherit;
  font-size: 14px;
}

/* PENJELASAN: Outline terlihat saat tombol kalender dipilih dengan keyboard. */
.calendar-save-button:focus-visible {
  outline: 2px solid #9b7b4e;
  outline-offset: 2px;
}

/* ===== RESPONSIVE MOBILE ===== */
/* PENJELASAN: Pada viewport pendek, roda sedikit mengecil agar tidak bersinggungan dengan sapaan dan nama penerima. */
@media (max-height: 860px) {
  .wheel-wrapper {
    width: min(89.55%, 340px, 38vh);
  }
}

@media (max-height: 760px) {
  .wheel-wrapper {
    width: min(89.55%, 340px, 34vh);
  }
}

/* PENJELASAN: Tampilan tautan lokasi; warna, ukuran teks, tinggi baris, dan garis bawah diatur di sini. */
.location-link {
  display: inline-block;
  color: #4D3602;
  font-size: 15px;
  line-height: 1.3;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* PENJELASAN: Jarak, padding, dan ukuran teks bagian penutup. */
.closing-section {
  margin-top: var(--main-section-space);
  padding: 0 clamp(24px, 7vw, 35px);
  font-size: 15px;
}

/* PENJELASAN: Jarak atas dan ukuran teks salam penutup. */
.closing-section h3 {
  margin-top: 14px;
  font-size: 15px;
   color: #890F24;
}

/* ===== TRANSISI TEKS SAAT DIGULIR ===== */
/* PENJELASAN: Teks mulai transparan dan sedikit turun; transition mengatur lama serta kelunakan perubahan; delay berasal dari variabel CSS yang dipasang JavaScript. */
.scroll-reveal {
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity 1s cubic-bezier(0.22, 1, 0.36, 1),
    transform 1s cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: var(--scroll-reveal-delay, 0ms);
}

/* PENJELASAN: Saat elemen terlihat di layar, teks menjadi penuh dan kembali ke posisi semula. */
.scroll-reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* PENJELASAN: Menonaktifkan animasi teks dan foto frame pada perangkat yang meminta gerakan dikurangi. */
@media (prefers-reduced-motion: reduce) {
  .scroll-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .name-frame-photo {
    animation: none;
  }

  .name-frame-photo-second {
    opacity: 0;
  }
}
