/* Kencana — undangan pernikahan mewah bertema mobil pengantin klasik, lukisan cat air bergerak: sampul foto penuh
   layar, lalu galeri mobil di dalam rumah besar — lengkung gading berlis emas, lampu kristal, guci mawar putih, lantai
   marmer — dengan pintu garasi berpanel emas yang tertutup. Saat dibuka pintu terangkat, cahaya senja masuk, lampu
   belakang mobil pengantin (berpelat inisial & tanggal) menyala, lalu bingkai judul turun. Selama pembuka digulir mobil
   melaju menjauh di jalan bercemara menuju rumah resepsi. Adegannya lapisan gambar (assets/img/*.webp) yang digerakkan CSS. */
@font-face { font-family: "Cinzel"; src: url("fonts/cinzel.woff2") format("woff2"); font-weight: 400 700; font-display: swap; }
@font-face { font-family: "Cormorant Garamond"; src: url("fonts/cormorant-garamond.woff2") format("woff2"); font-weight: 300 700; font-display: swap; }
@font-face { font-family: "Cormorant Garamond"; src: url("fonts/cormorant-garamond-italic.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "Pinyon Script"; src: url("fonts/pinyon-script.woff2") format("woff2"); font-weight: 400; font-display: swap; }

:root {
  --bg: #f5efe3; --bg2: #fbf8f1; --deep: #24304d; --deep2: #18213a; --ink: #2f2a24; --soft: #6f665a; --gold: #b8934a; --gold-hi: #e6d3a0;
  --aksen: #8a6a35; --r1: #fffaf2; --r2: #f3dcd6; --r3: #e2b9b0; --sky1: #f7efe2; --sky2: #efe7da; --card: #fffdf7; --line: #e7dfcf;
  --display: "Cinzel", "Cormorant Garamond", Georgia, serif;
  --serif: "Cormorant Garamond", Georgia, serif;
  --script: "Pinyon Script", "Cormorant Garamond", cursive;
}
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; background: var(--bg); }
body { margin: 0; background: var(--bg); color: var(--ink); font: 500 19px/1.55 var(--serif); -webkit-font-smoothing: antialiased; }
img { max-width: 100%; display: block; }
h1, h2, h3, p, ol { margin: 0; }
a { color: var(--deep2); }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.page { position: relative; z-index: 1; max-width: 480px; margin: 0 auto; min-height: 100vh; overflow: hidden; }
@media (min-width: 560px) { .page { box-shadow: 0 30px 80px rgba(75, 61, 45, .28); } }

/* Adegan: .stage berbanding 1116:2000 (ukuran lukisan induk) dan selalu menutup layar. Urutan dari belakang: latar
   (jalan bercemara, air mancur, rumah resepsi, langit senja) → pintu garasi di dalam .lubang (persegi panjang di tengah
   lengkung; pintu terangkat ke atas dan terpotong lubangnya) → bingkai garasi (lengkung, lampu kristal, guci, lantai
   marmer) → mobil pengantin. Titik hilang 50% 52%. Keadaan dasar = pintu sudah terangkat; sebelum dibuka
   (.js:not(.is-open)) pintu tertutup dan pandangan sedikit lebih jauh. */
.scene { position: fixed; top: 0; left: 50%; width: min(100%, 480px); height: 100%; transform: translateX(-50%); z-index: 0; pointer-events: none; overflow: hidden; contain: strict; background: var(--sky1); display: none; }
.js .scene { display: block; }
.scene-off .scene { visibility: hidden; }
.stage { position: absolute; left: 50%; top: 50%; height: max(100%, calc(min(100vw, 480px) * 1.7922)); aspect-ratio: 1116 / 2000; translate: -50% -50%; }
.ly { position: absolute; inset: 0; will-change: transform; transform-origin: 50% 52%; }
.ly > img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; }
.senja { position: absolute; inset: 0; background: radial-gradient(60% 40% at 50% 38%, rgba(255, 214, 160, .45), transparent 70%); mix-blend-mode: soft-light; }
.lubang { position: absolute; left: 21.03%; top: 33.76%; width: 58.07%; height: 48.04%; overflow: hidden; }
.pintu { position: absolute; inset: 0; will-change: transform; }
.pintu img { display: block; width: 100%; height: 100%; max-width: none; }
.celah { position: absolute; left: 0; right: 0; bottom: 0; height: 12%; background: linear-gradient(0deg, rgba(255, 220, 150, .85), transparent); opacity: .5; }
.kristal { position: absolute; left: 50%; top: 9%; width: 46%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; background: radial-gradient(closest-side, rgba(255, 244, 210, .85), rgba(255, 226, 160, .3) 50%, transparent); mix-blend-mode: screen; }
.mb { position: absolute; left: 19%; top: 67.7%; width: 62%; container-type: inline-size; }
.mb img { display: block; width: 100%; height: auto; max-width: none; }
.lampu { position: absolute; top: 31%; width: 15%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; background: radial-gradient(closest-side, rgba(255, 70, 60, .95), rgba(255, 60, 40, .35) 45%, transparent); mix-blend-mode: screen; opacity: 0; }
.lampu.l { left: 8.5%; } .lampu.r { left: 91.5%; }
.plat-nomor { position: absolute; left: 50%; top: 59.5%; translate: -50% -50%; font: 700 3.3cqw/1 var(--display); letter-spacing: .12em; color: #24304d; white-space: nowrap; }
.js .pintu { transition: transform 2.6s cubic-bezier(.55, 0, .2, 1) .5s; }
.js .ly { transition: transform 4s cubic-bezier(.6, 0, .2, 1) 1.8s; }
.js .celah { transition: opacity 1s ease; }
.js .lampu { transition: opacity .6s ease 3.4s; }
.js.is-open .lampu { opacity: .9; }
.js .pintu { transform: translateY(-103%); }
.js:not(.is-open) .pintu { transform: none; }
.js:not(.is-open) .celah { opacity: .9; }
.js:not(.is-open) .ly-bg { transform: scale(.94); }
.js:not(.is-open) .ly-garasi, .js:not(.is-open) .ly-mobil { transform: scale(.96); }
.js.is-open .ly-garasi, .js.is-open .ly-mobil { transform: scale(1.04); }
.js.no-anim .ly, .js.no-anim .pintu, .js.no-anim .lampu { transition: none; }
.petals { position: absolute; inset: 0; }
.petals i { position: absolute; top: -4%; border-radius: 90% 10% 80% 20%; background: linear-gradient(135deg, #fff, var(--r1) 50%, var(--r2)); display: none; box-shadow: 0 1px 2px rgba(120, 90, 60, .15); }
.veil { position: absolute; inset: 0; background: radial-gradient(circle at 50% 50%, #fff7e6 0, rgba(255, 240, 210, .7) 40%, transparent 78%); opacity: 0; }
.terang { position: absolute; inset: 0; background: radial-gradient(circle at 50% 52%, #fff 0, #fffaf0 60%, var(--bg) 100%); opacity: 0; }
.petals i:nth-child(1) { left: 76%; width: 11px; height: 12px; animation-duration: 11.2s, 3.6s; animation-delay: -12.6s, -2.6s; opacity: 0.6; }
.petals i:nth-child(2) { left: 56%; width: 15px; height: 8px; animation-duration: 12.9s, 4.0s; animation-delay: -1.7s, -1.9s; opacity: 0.7; }
.petals i:nth-child(3) { left: 45%; width: 13px; height: 7px; animation-duration: 12.4s, 2.4s; animation-delay: -3.3s, -1.1s; opacity: 0.9; }
.petals i:nth-child(4) { left: 17%; width: 15px; height: 7px; animation-duration: 9.8s, 3.5s; animation-delay: -1.9s, -0.0s; opacity: 0.6; }
.petals i:nth-child(5) { left: 23%; width: 15px; height: 8px; animation-duration: 14.8s, 2.7s; animation-delay: -2.5s, -1.3s; opacity: 0.7; }
.petals i:nth-child(6) { left: 66%; width: 14px; height: 12px; animation-duration: 10.2s, 4.1s; animation-delay: -10.4s, -3.9s; opacity: 0.9; }
.petals i:nth-child(7) { left: 35%; width: 9px; height: 9px; animation-duration: 11.5s, 4.1s; animation-delay: -4.0s, -1.3s; opacity: 0.6; }
.petals i:nth-child(8) { left: 73%; width: 14px; height: 12px; animation-duration: 11.0s, 3.0s; animation-delay: -12.3s, -1.9s; opacity: 0.8; }
.petals i:nth-child(9) { left: 20%; width: 12px; height: 10px; animation-duration: 13.2s, 2.5s; animation-delay: -14.6s, -0.1s; opacity: 0.8; }
.petals i:nth-child(10) { left: 48%; width: 9px; height: 11px; animation-duration: 13.7s, 3.1s; animation-delay: -8.7s, -0.0s; opacity: 0.6; }
.petals i:nth-child(11) { left: 87%; width: 10px; height: 11px; animation-duration: 14.7s, 2.8s; animation-delay: -11.3s, -3.7s; opacity: 0.9; }
.petals i:nth-child(12) { left: 41%; width: 13px; height: 9px; animation-duration: 14.4s, 2.9s; animation-delay: -6.9s, -2.4s; opacity: 0.8; }
.petals i:nth-child(13) { left: 34%; width: 9px; height: 10px; animation-duration: 14.7s, 2.6s; animation-delay: -5.1s, -2.4s; opacity: 0.7; }
.petals i:nth-child(14) { left: 40%; width: 11px; height: 12px; animation-duration: 12.3s, 3.0s; animation-delay: -4.8s, -0.7s; opacity: 0.6; }


.caps { font: 500 13px/1.4 var(--display); letter-spacing: .34em; text-transform: uppercase; }
.script { font: 400 50px/1.05 var(--script); color: var(--deep2); }
.lead { font-size: 18px; line-height: 1.6; color: var(--soft); max-width: 22em; }
.btn { display: inline-flex; align-items: center; justify-content: center; min-height: 46px; padding: 0 26px; border: 1px solid var(--deep2); border-radius: 12px; background: var(--deep2); color: #fff; text-decoration: none; cursor: pointer; font: 600 13px/1 var(--display); letter-spacing: .22em; text-transform: uppercase; }
.btn-line { background: transparent; color: inherit; border-color: currentColor; }
.btn.copied { background: var(--gold); border-color: var(--gold); color: #fff; }

/* Rangkaian melati lukisan: di bawah foto mempelai, di sampul tanpa foto, dan buket di penutup. */
.spray { position: relative; width: 220px; margin: -58px auto 0; pointer-events: none; }
.cover-buket { position: absolute; left: 50%; bottom: 21%; width: 40%; max-width: none; translate: -50% 0; opacity: .92; pointer-events: none; }
.buket { position: relative; width: 170px; margin: -30px auto 0; pointer-events: none; }

/* ---------- Sampul: foto penuh layar dengan gradasi gelap, nama di atas, tamu dan tombol di bawah ---------- */
.cover { position: relative; min-height: 100vh; min-height: 100svh; padding: 54px 26px 44px; display: flex; flex-direction: column; justify-content: space-between; align-items: center; text-align: center; background: linear-gradient(180deg, var(--bg2), var(--bg) 55%, color-mix(in srgb, var(--deep) 45%, var(--bg))); color: var(--ink); overflow: hidden; }
.cover[hidden] { display: none; }
.cover-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cover.has-photo { color: #fff; }
.cover.has-photo::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(20, 10, 12, .55) 0%, rgba(20, 10, 12, .05) 34%, rgba(20, 10, 12, .1) 56%, rgba(20, 10, 12, .78) 100%); }
.cover.has-photo .cover-art { display: none; }
.cover-art { position: absolute; inset: 0; }
.cover-top, .cover-bottom { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 10px; }
.cover .names { font: 500 34px/1.15 var(--display); letter-spacing: .08em; text-transform: uppercase; overflow-wrap: anywhere; }
.names .amp { margin: 0 .25em; font: 400 40px/1 var(--script); text-transform: none; letter-spacing: 0; }
.cover:not(.has-photo) .cover-top { margin-top: 26vh; }
.to { font-size: 16px; line-height: 1.5; opacity: .9; }
.guest-name { font: 600 24px/1.2 var(--serif); overflow-wrap: anywhere; }
.cover .open { margin-top: 10px; min-width: 230px; min-height: 48px; border-color: rgba(255, 255, 255, .55); background: rgba(255, 255, 255, .22); color: inherit; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.cover:not(.has-photo) .open { border-color: var(--deep2); background: var(--deep2); color: #fff; }

/* Dengan JS: sampul menutup layar sampai tamu menekan "Buka undangan", lalu memudar dan tirai melati terlihat. */
.js .cover { position: fixed; top: 0; bottom: 0; left: 50%; width: min(100%, 480px); transform: translateX(-50%); z-index: 40; overflow-y: auto; transition: opacity .9s ease; }
.js:not(.is-open) body { overflow: hidden; }
.js.is-open .cover { opacity: 0; pointer-events: none; }
.js.no-anim .cover { transition: none; }
html:not(.js) .cover .open { display: none; }

/* ---------- Pembuka: judul di bingkai ukiran bersiger (lihat bagian akhir berkas) ---------- */
.hero { position: relative; min-height: 100vh; min-height: 100svh; padding: 44px 20px; display: grid; place-items: center; text-align: center; background: linear-gradient(180deg, var(--sky1), var(--sky2)); }
.js .hero { background: none; }
.frame-art { position: absolute; inset: 0; overflow: hidden; }
.pl-name { font: 500 40px/1.15 var(--display); letter-spacing: .14em; text-transform: uppercase; overflow-wrap: anywhere; }
.pl-name.small { font-size: 22px; margin-top: 10px; }
.pl-and { font: 400 34px/1 var(--script); color: var(--deep2); }
.pl-date { margin-top: 10px; font: 500 15px/1.4 var(--display); letter-spacing: .2em; text-transform: uppercase; }
.mouse { display: block; margin-top: 18px; width: 22px; height: 36px; border: 1.5px solid var(--ink); border-radius: 12px; position: relative; opacity: .7; }
.mouse::after { content: ""; position: absolute; left: 50%; top: 7px; width: 3px; height: 7px; margin-left: -1.5px; border-radius: 2px; background: var(--ink); animation: gulir 1.6s ease-in-out infinite; }

/* ---------- Isi: bagian berlatar gading dan hijau padi bergantian ---------- */
main > section:not(.hero) { position: relative; padding: 64px 28px; display: flex; flex-direction: column; align-items: center; gap: 20px; text-align: center; background: var(--bg); }
.verse { background: linear-gradient(180deg, var(--bg2), var(--bg)) !important; }
.quote { font: italic 500 21px/1.6 var(--serif); max-width: 20em; }
.source { font: 600 14px/1.4 var(--display); letter-spacing: .14em; }
.couple { display: flex; flex-direction: column; gap: 44px; width: 100%; margin-top: 8px; }
.person { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.portrait { width: 230px; height: 300px; padding: 7px; border: 1.5px solid var(--gold); border-radius: 999px 999px 18px 18px; background: var(--card); display: flex; }
.portrait > * { flex: 1; width: 100%; height: 100%; border-radius: 999px 999px 12px 12px; object-fit: cover; }
.portrait span { display: flex; align-items: center; justify-content: center; background: var(--bg2); font: 400 90px/1 var(--script); color: var(--deep2); }
.person h3 { font: 400 42px/1.05 var(--script); color: var(--deep2); overflow-wrap: anywhere; }
.parents { font-size: 17px; line-height: 1.45; color: var(--soft); max-width: 16em; }
.ig { font-size: 16px; font-weight: 700; color: var(--deep2); }

main > section.count, main > section.rsvp { background: linear-gradient(180deg, var(--deep), var(--deep2)); color: #fff; }
.count .script, .rsvp .script, .count .lead { color: #fff; }
.countdown { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; width: 100%; }
.countdown div { padding: 14px 0 12px; border: 1.5px solid rgba(255, 255, 255, .75); border-radius: 14px; display: flex; flex-direction: column; gap: 2px; }
.countdown b { font: 500 30px/1.1 var(--display); font-variant-numeric: tabular-nums; }
.countdown span { font-size: 15px; }
html:not(.js) .countdown { display: none; }

.programme { gap: 26px !important; background: linear-gradient(180deg, var(--bg), var(--bg2)) !important; }
.event { width: 100%; padding: 34px 22px 30px; border-radius: 110px 110px 22px 22px; background: var(--card); border: 1.5px solid var(--gold); outline: 1px solid var(--gold-hi); outline-offset: -8px; box-shadow: 0 18px 40px rgba(75, 61, 45, .12); display: flex; flex-direction: column; align-items: center; gap: 12px; }
.when { font: 600 19px/1.5 var(--serif); }
.where { font-size: 17px; line-height: 1.5; color: var(--soft); max-width: 17em; overflow-wrap: anywhere; }
.where b { display: block; font: 600 12px/1.6 var(--display); letter-spacing: .2em; text-transform: uppercase; color: var(--ink); }
.dress { font-size: 17px; font-style: italic; color: var(--soft); }

.chapters { list-style: none; padding: 0; width: 100%; display: flex; flex-direction: column; gap: 18px; text-align: left; }
.chapters li { position: relative; padding: 20px 20px 20px 26px; border-radius: 18px; background: var(--card); border: 1px solid var(--line); }
.chapters li::before { content: ""; position: absolute; left: 0; top: 18px; bottom: 18px; width: 4px; border-radius: 2px; background: var(--gold); }
.chapters h3 { font: 400 34px/1.05 var(--script); color: var(--deep2); margin-bottom: 6px; }
.chapters p { font-size: 17px; line-height: 1.55; color: var(--soft); }

.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; width: 100%; }
.grid img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; border-radius: 16px; border: 4px solid var(--card); box-shadow: 0 10px 22px rgba(75, 61, 45, .14); }
.grid img:nth-child(3n+1) { grid-column: 1 / -1; aspect-ratio: 4 / 3; }

.gift-list { display: grid; gap: 12px; width: 100%; }
.gift-card { padding: 16px 18px; border-radius: 18px; background: var(--card); border: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; gap: 12px; text-align: left; }
.bank { font: 600 12px/1.4 var(--display); letter-spacing: .22em; text-transform: uppercase; color: var(--deep2); }
.number { font-size: 22px; font-weight: 700; letter-spacing: .04em; overflow-wrap: anywhere; }
.holder { font-size: 15px; color: var(--soft); }
.gift-card .btn { flex-shrink: 0; min-height: 42px; padding: 0 16px; }
.address { width: 100%; padding: 14px 16px; border-radius: 14px; border: 1px dashed var(--line); font-size: 16px; line-height: 1.5; color: var(--soft); text-align: left; }

.note { width: 100%; padding: 14px 16px; border: 1px dashed rgba(255, 255, 255, .7); border-radius: 14px; font-size: 16px; }
.thanks { width: 100%; padding: 22px 18px; border-radius: 18px; background: rgba(255, 255, 255, .16); display: flex; flex-direction: column; gap: 6px; }
.thanks .big { font: 400 38px/1.1 var(--script); }
.form { width: 100%; display: flex; flex-direction: column; gap: 14px; text-align: left; }
.field { display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 0; border: 0; font-size: 16px; font-weight: 700; }
.field legend { padding: 0 0 6px; }
.field input, .field textarea { width: 100%; min-height: 48px; padding: 0 14px; border: 0; border-radius: 12px; background: #fff; color: var(--ink); font: 500 18px/1.4 var(--serif); }
.field textarea { padding: 12px 14px; min-height: 110px; resize: vertical; }
.field input:focus, .field textarea:focus { outline: 2px solid var(--gold-hi); outline-offset: 1px; }
.opts { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.opt { position: relative; }
.opt input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; margin: 0; cursor: pointer; }
.opt span { display: flex; align-items: center; justify-content: center; min-height: 48px; border: 1.5px solid rgba(255, 255, 255, .8); border-radius: 12px; font: 600 13px/1 var(--display); letter-spacing: .14em; text-transform: uppercase; }
.opt input:checked + span { background: #fff; color: var(--deep2); }
.opt input:focus-visible + span { outline: 2px solid var(--gold-hi); outline-offset: 2px; }
.rsvp .btn { min-height: 50px; background: #fff; border-color: #fff; color: var(--deep2); }

main > section.wishes-box { align-items: stretch; text-align: left; gap: 0; padding-top: 30px; }
.wishes-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.wishes-head h2 { font: 400 36px/1.1 var(--script); color: var(--deep2); }
.wishes-head span { font-size: 15px; color: var(--soft); white-space: nowrap; }
.wishes { list-style: none; margin: 12px 0 0; padding: 0; max-height: 560px; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; }
.wishes li { padding: 14px 16px; border-radius: 16px; background: var(--card); border: 1px solid var(--line); display: flex; flex-direction: column; gap: 4px; }
.wish-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.wish-head b { font-size: 18px; }
.tag { padding: 2px 8px; border-radius: 999px; border: 1px solid var(--gold); font-size: 12px; letter-spacing: .06em; text-transform: uppercase; color: var(--gold); }
.status { font-size: 14px; font-weight: 700; color: var(--deep2); }
.wish-text { font-size: 17px; line-height: 1.5; color: var(--soft); overflow-wrap: anywhere; }
.wish-reply { margin-top: 6px; padding: 8px 12px; border-left: 2px solid var(--gold); font-style: italic; color: var(--soft); }

main > section.closing { padding-top: 90px; background: linear-gradient(180deg, var(--bg), var(--sky2)); }

.merci { font-size: 54px; }
.thanks-line { font-size: 17px; font-style: italic; color: var(--soft); }
footer { position: relative; padding: 18px 16px 26px; text-align: center; font-size: 14px; color: var(--soft); background: var(--sky2); }

.music-toggle { position: fixed; bottom: 16px; right: max(14px, calc(50% - 226px)); z-index: 50; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; border: 0; border-radius: 50%; background: var(--deep2); color: #fff; cursor: pointer; box-shadow: 0 8px 18px rgba(75, 61, 45, .3); }
.music-toggle svg { width: 18px; height: 18px; }
.music-toggle[aria-pressed="false"]::after { content: ""; position: absolute; width: 24px; height: 1.5px; background: #fff; transform: rotate(-45deg); }
html:not(.js) .music-toggle, .js:not(.is-open) .music-toggle { display: none; }

/* ---------- Animasi ---------- */
/* Isi muncul bertahap saat digulir (kelas .rv dipasang mapag.js): judul turun, foto membesar, mempelai dari kiri/kanan. */
.rv { opacity: 0; translate: 0 26px; }
.rv.script { translate: 0 -22px; }
.rv.portrait, .grid .rv, .rv.event { translate: 0 0; scale: .86; }
.person:nth-child(odd) .rv { translate: -30px 0; } .person:nth-child(even) .rv { translate: 30px 0; }
.rv.in { opacity: 1; translate: 0 0; scale: 1; transition: opacity .9s cubic-bezier(.2, .7, .2, 1) calc(var(--d, 0) * 1ms), translate .9s cubic-bezier(.2, .7, .2, 1) calc(var(--d, 0) * 1ms), scale .9s cubic-bezier(.2, .7, .2, 1) calc(var(--d, 0) * 1ms); }
@media (prefers-reduced-motion: no-preference) {
  /* Urutan: celah cahaya di bawah pintu berdenyut → pintu terangkat (0,5–3,1 dtk), cahaya senja masuk → pandangan maju
     sedikit (1,8–5,8) → lampu belakang mobil menyala (3,4) → bingkai judul turun (5,2) lalu berayun. Berulang: kelopak
     mawar, kilau lampu kristal, denyut lampu belakang. */
  .petals i { display: block; animation-name: gugur, kibar; animation-timing-function: linear, ease-in-out; animation-iteration-count: infinite; animation-direction: normal, alternate; }
  .js:not(.is-open) .celah { animation: sinar 1.8s ease-in-out infinite alternate; }
  .kristal { animation: kilau2 3.2s ease-in-out infinite alternate; }
  .js.is-open .lampu { animation: nyala 2.4s 4s ease-in-out infinite alternate; }
  .js.is-open:not(.no-anim) .veil { animation: silau 2.6s 1.8s ease-in-out both; }
  .papan { animation: goyang 5s ease-in-out infinite alternate; }
  .js.is-open:not(.no-anim) .papan { animation: turunP 1.5s 5.2s cubic-bezier(.3, 1.2, .4, 1) both, goyang 5s 6.7s ease-in-out infinite alternate; }
  .js.is-open:not(.no-anim) .hero-pin > .mouse { animation: naik 1s 6.4s both; }
  .buket { animation: ayun 7s ease-in-out infinite; transform-origin: 50% 20%; }
  .cover-top { animation: turun 1.2s .2s both; } .cover-bottom { animation: naik 1.2s .5s both; }
  .cover .open { animation: denyut 2.8s 2s ease-in-out infinite; }
}
@keyframes gugur { from { translate: 0 0; } to { translate: 70px 112vh; } }
@keyframes kibar { from { rotate: -50deg; scale: 1 1; } to { rotate: 190deg; scale: .5 1; } }
@keyframes kelip { 0%, 100% { opacity: 0; translate: 0 0; } 50% { opacity: .75; translate: 6px -26px; } }
@keyframes kepak { from { scale: 1 1; } to { scale: .2 1; } }
@keyframes terbang1 { 0%, 100% { translate: 0 0; rotate: 20deg; } 25% { translate: 70px -60px; rotate: -10deg; } 50% { translate: 150px -20px; rotate: 30deg; } 75% { translate: 60px 30px; rotate: -25deg; } }
@keyframes terbang2 { 0%, 100% { translate: 0 0; rotate: -20deg; } 30% { translate: -90px 40px; rotate: 15deg; } 60% { translate: -150px -10px; rotate: -30deg; } 80% { translate: -50px -40px; rotate: 20deg; } }
@keyframes alir { to { stroke-dashoffset: -14; } }
@keyframes riak { from { scale: .4; opacity: .9; } to { scale: 2.6; opacity: 0; } }
@keyframes apung { from { translate: -2px 1px; } to { translate: 2px -1px; } }
@keyframes apung2 { from { translate: -1px 0; rotate: -.25deg; } to { translate: 1px 0; rotate: .25deg; } }
@keyframes kelip2 { 0%, 100% { scale: .3; opacity: 0; } 50% { scale: 1.1; opacity: .95; } }
@keyframes sinar { from { opacity: .55; } to { opacity: 1; } }
@keyframes napas { from { scale: 1; } to { scale: 1.035; } }
@keyframes silau { 0%, 100% { opacity: 0; } 50% { opacity: .5; } }
@keyframes mekarR { from { opacity: 0; scale: -.3 .3; } to { opacity: 1; scale: -1 1; } }
@keyframes naik2 { from { opacity: 0; translate: 0 50%; } to { opacity: 1; translate: 0 0; } }
@keyframes kabut { from { opacity: .9; } to { opacity: 0; } }
@keyframes toleh { from { rotate: -4deg; } to { rotate: 5deg; } }
@keyframes kibas { from { rotate: -1.2deg; } to { rotate: 1.2deg; } }
@keyframes plakat { from { opacity: 0; translate: 0 26px; scale: .94; } to { opacity: 1; translate: 0 0; scale: 1; } }
@keyframes mekar { from { opacity: 0; scale: .3; } to { opacity: 1; scale: 1; } }
@keyframes turun { from { opacity: 0; translate: 0 -18px; } to { opacity: 1; translate: 0 0; } }
@keyframes naik { from { opacity: 0; translate: 0 18px; } to { opacity: 1; translate: 0 0; } }
@keyframes denyut { 0%, 100% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0); } 50% { box-shadow: 0 0 0 9px rgba(255, 255, 255, .18); } }
@keyframes ayun { 0%, 100% { rotate: -2deg; } 50% { rotate: 2deg; } }
@keyframes gulir { 0% { translate: 0 0; opacity: 1; } 70% { translate: 0 12px; opacity: 0; } 100% { translate: 0 0; opacity: 0; } }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } .rv { opacity: 1; translate: none; scale: none; } *, *::before, *::after { animation: none !important; } .js .ly, .js .tr, .js .kabut, .js .pg { transition: none; } .pigura .portrait, .chapters::before { clip-path: none; } }
.js body.locked { overflow: visible; }

/* ---------- Pembuka Kencana: judul di bingkai lengkung berukir emas (judul.webp, teks HTML di atasnya) yang turun dan
   berayun. Selama pembuka digulir (.ready, --p 0→1 dipasang kencana.js) mobil melaju menjauh ke titik hilang, lengkung
   garasi terlewati, lalu layar memutih di depan rumah resepsi. ---------- */
.script, .person h3, .chapters h3, .wishes-head h2 { color: var(--aksen); }
.count .script, .rsvp .script { color: var(--gold-hi); }
.hero-pin { display: grid; place-items: start center; width: 100%; position: relative; }
.js .hero { display: block; padding: 0; }
.js .hero-pin { position: fixed; left: 50%; bottom: 0; width: min(100%, 480px); height: 100vh; height: 100svh; translate: -50% 0; padding: 6vh 0 0; pointer-events: none; overflow: hidden; }
.scene-off .hero-pin { visibility: hidden; }
.title-wrap { width: min(58%, 236px); }
.papan { position: relative; transform-origin: 50% 0; }
.papan > img { display: block; width: 100%; height: auto; max-width: none; }
.papan-t { position: absolute; left: 18%; right: 18%; top: 22%; bottom: 16%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; text-align: center; color: var(--ink); }
.papan-t .caps { font-size: 8px; letter-spacing: .24em; color: var(--soft); }
.t-name { font: 400 clamp(24px, 7.8vw, 32px)/1.05 var(--script); color: var(--aksen); overflow-wrap: break-word; }
.t-name .amp { display: block; font-size: .7em; line-height: .9; color: var(--gold); }
.papan-t .pl-date { margin: 4px 0 0; font-size: 8.5px; letter-spacing: .12em; }
.hero-pin > .mouse { position: absolute; left: 50%; bottom: 5vh; margin: 0 0 0 -11px; border-color: #fff; opacity: .85; }
.hero-pin > .mouse::after { background: #fff; }
html:not(.js) .hero-pin { padding: 40px 0; } html:not(.js) .hero-pin > .mouse { display: none; }
main h2.script::after { content: ""; display: block; width: 260px; max-width: 80vw; height: 22px; margin: 8px auto 0; background: url("img/pembatas.webp") center / contain no-repeat; }
.memuat .cover .open { pointer-events: none; opacity: .55; }
@media (prefers-reduced-motion: no-preference) {
  .js .hero { min-height: 260vh; min-height: 260svh; }
  /* Perjalanan gulir: --p = seberapa jauh pembuka sudah digulir; di p = 0 sama dengan keadaan akhir pembukaan. */
  .ready .ly { transition: none; }
  .js.is-open.ready .ly-bg { transform: scale(calc(1 + var(--p, 0) * .55)); }
  .ready .lubang { visibility: hidden; }
  .js.is-open.ready .ly-garasi { transform: scale(calc(1.04 + var(--p, 0) * var(--p, 0) * 3.2)); opacity: calc(1 - (var(--p, 0) - .45) * 4); }
  .js.is-open.ready .ly-mobil { transform: scale(calc(1.04 - var(--p, 0) * .9)); opacity: calc(1 - (var(--p, 0) - .78) * 6); }
  .ready .title-wrap { opacity: calc(1 - var(--p, 0) * 5); translate: 0 calc(var(--p, 0) * -160px); }
  .ready .hero-pin > .mouse { opacity: calc(.85 - var(--p, 0) * 6); }
  .ready .terang { opacity: calc((var(--p, 0) - .7) * 3.4); }
  .ready .petals { opacity: calc(1 - var(--p, 0) * 2.5); }
}
@keyframes kilau2 { from { opacity: .55; scale: .94; } to { opacity: 1; scale: 1.04; } }
@keyframes nyala { from { opacity: .65; } to { opacity: 1; } }
@keyframes goyang { from { rotate: -1.2deg; } to { rotate: 1.2deg; } }
@keyframes turunP { from { opacity: 0; translate: 0 -110%; rotate: 6deg; } to { opacity: 1; translate: 0 0; rotate: -1.2deg; } }

/* ---------- Isi Kencana: ornamen bertanda .orn tidak ikut animasi .rv; geraknya memakai .tampak yang dipasang
   kencana.js saat bagian masuk layar (hanya bila .gerak ada di <html>). ---------- */
main > section.count, main > section.rsvp { background: radial-gradient(120% 70% at 50% 0%, #2f3d60, var(--deep) 45%, var(--deep2)); color: #f4ecdc; }
main > section.count::before, main > section.rsvp::before { content: ""; position: absolute; inset: 12px; border: 1px solid rgba(230, 211, 160, .55); outline: 1px solid rgba(230, 211, 160, .25); outline-offset: 5px; pointer-events: none; }
.count .lead { color: #e9e1cf; }
.btn { border-radius: 999px; background: var(--deep); border-color: var(--deep); }
.count .btn-line { color: var(--gold-hi); border-color: var(--gold-hi); background: transparent; }

/* With Love: rangkaian mawar di atas, kutipan diapit garis emas ganda. */
.rangkai-atas { width: 280px; margin: -18px auto -6px; pointer-events: none; }
.quote { padding: 22px 8px; border-top: 1px solid var(--gold); border-bottom: 1px solid var(--gold); outline: 1px solid var(--gold-hi); outline-offset: 5px; }

/* Bride & Groom: potret di dalam bingkai lengkung berukir emas, zigzag kiri-kanan. */
.couple { gap: 8px; }
.person { align-items: flex-start; text-align: left; width: 100%; }
.person ~ .person { align-items: flex-end; text-align: right; }
.pigura { position: relative; width: 64%; max-width: 270px; margin-bottom: 8px; }
.pigura-b { position: relative; z-index: 1; display: block; width: 100%; height: auto; filter: drop-shadow(0 14px 20px rgba(47, 42, 36, .2)); }
.pigura .portrait { position: absolute; z-index: 2; left: 16.5%; right: 16.5%; top: 18.5%; bottom: 13.8%; width: auto; height: auto; padding: 0; border: 0; border-radius: 48% 48% 10% 10% / 30% 30% 5% 5%; overflow: hidden; background: var(--bg2); box-shadow: 0 0 0 2px var(--gold); }
.pigura .portrait > * { border-radius: 0; }
.person .parents { max-width: 15em; }
.dan { align-self: center; margin: -6px 0 0; }
.dan span { font: 400 54px/1 var(--script); color: var(--gold); }
.person ~ .person .rv { translate: 30px 0; }

/* Save the Date: hitung mundur berupa empat panel spidometer berbingkai emas. */
.countdown { grid-template-columns: repeat(2, minmax(0, 116px)); justify-content: center; gap: 16px; }
.countdown div { position: relative; aspect-ratio: 1; padding: 0; justify-content: center; border-radius: 50%; border: 2px solid var(--gold-hi); background: radial-gradient(circle, #2b3858 0 58%, #1b2440 60%); box-shadow: inset 0 0 0 6px #1b2440, inset 0 0 0 7px rgba(230, 211, 160, .6), 0 10px 20px rgba(0, 0, 0, .3); }
.countdown div::before { content: ""; position: absolute; inset: 9px; border-radius: 50%; background: repeating-conic-gradient(from -135deg, rgba(230, 211, 160, .85) 0 1.4deg, transparent 1.4deg 13.5deg); -webkit-mask: radial-gradient(closest-side, transparent 80%, #000 81% 93%, transparent 94%); mask: radial-gradient(closest-side, transparent 80%, #000 81% 93%, transparent 94%); clip-path: polygon(50% 50%, 0 100%, 0 0, 100% 0, 100% 100%); }
.countdown b { color: #fff6e2; font-size: 32px; } .countdown span { color: var(--gold-hi); font: 600 11px/1.6 var(--display); letter-spacing: .2em; text-transform: uppercase; }
.countdown .rv { scale: .4; }

/* Acara: kartu gading berbingkai emas ganda dengan pelat nomor sebagai judul. */
main > section.programme { gap: 70px !important; padding-top: 84px; }
.event { position: relative; width: 100%; padding: 48px 22px 30px; border-radius: 26px; background: var(--card); border: 1.5px solid var(--gold); outline: 1px solid var(--gold-hi); outline-offset: -9px; box-shadow: 0 22px 40px rgba(47, 42, 36, .14); }
.plat { display: flex; align-items: center; justify-content: center; width: 236px; aspect-ratio: 560 / 226; padding: 0 12%; background: url("img/pelat.webp") center / 100% 100% no-repeat; font: 700 17px/1.1 var(--display); letter-spacing: .18em; text-transform: uppercase; color: var(--deep); filter: drop-shadow(0 8px 12px rgba(47, 42, 36, .25)); }
.event .plat { position: absolute; left: 50%; top: 0; translate: -50% -55%; }
.plat-tutup { width: 270px; margin-top: 12px; font-size: 15px; letter-spacing: .14em; }

/* Our Journey: garis waktu berupa jalan aspal dengan marka putih putus-putus, tiap bab ditandai lampu emas. */
.chapters { position: relative; padding-left: 50px; gap: 22px; }
.chapters::before { content: ""; position: absolute; left: 6px; top: -10px; bottom: -10px; width: 26px; border-radius: 4px; background: linear-gradient(90deg, #8f8a83, #5d5852 15%, #4a4641 50%, #5d5852 85%, #8f8a83), #4a4641; }
.chapters::after { content: ""; position: absolute; left: 18px; top: -4px; bottom: -4px; width: 2px; background: repeating-linear-gradient(180deg, #fff 0 12px, transparent 12px 24px); }
.chapters li { padding: 18px 20px; border-radius: 6px 22px 22px 22px; border-color: var(--gold-hi); }
.chapters li::before { left: -46px; top: 16px; bottom: auto; width: 24px; height: 24px; border-radius: 50%; background: radial-gradient(circle, #fff6d8, #e6c27a 55%, var(--gold)); box-shadow: 0 0 0 3px var(--card), 0 0 14px rgba(230, 190, 110, .8); z-index: 1; }

/* Gallery: foto kotak dalam bingkai emas berlapis gading. */
.grid { gap: 14px 12px; }
.grid img { aspect-ratio: 1; padding: 5px; background: var(--card); border: 7px solid var(--gold); border-image: linear-gradient(135deg, #f1e2b8, #b8934a 35%, #f6ebcd 55%, #9c7a3c) 1; border-radius: 0; box-shadow: 0 12px 22px rgba(47, 42, 36, .16); }
.grid img:nth-child(3n+1) { aspect-ratio: 4 / 3; }

/* Wedding Gift: kartu gading dengan garis emas di sisi kiri. */
.gift-card { position: relative; padding-left: 26px; border-radius: 16px; border-color: var(--gold-hi); overflow: hidden; }
.gift-card .btn-line { background: transparent; color: var(--deep); border-color: var(--deep); }
.gift-card::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 6px; background: linear-gradient(180deg, #f1e2b8, var(--gold), #9c7a3c); }

/* Wishes & penutup */
.rsvp .btn { background: var(--gold-hi); border-color: var(--gold-hi); color: var(--deep2); }
.opt input:checked + span { color: var(--deep2); }
main > section.closing { padding-top: 70px; background: linear-gradient(180deg, var(--bg), var(--sky2)); }
.buket { width: 200px; margin: 0 auto; }

@media (prefers-reduced-motion: no-preference) {
  .rangkai-atas { transition: scale 1.1s cubic-bezier(.3, 1.3, .4, 1), opacity .6s ease; }
  .gerak .verse:not(.tampak) .rangkai-atas { scale: .2 1; opacity: 0; }
  .pigura-b { transition: transform 1.1s cubic-bezier(.2, .8, .2, 1), opacity .7s ease; }
  .gerak .person:not(.tampak) .pigura-b { transform: rotate(-8deg) scale(.82); opacity: 0; }
  .gerak .person ~ .person:not(.tampak) .pigura-b { transform: rotate(8deg) scale(.82); }
  .pigura .portrait { transition: clip-path 1.1s ease .45s; clip-path: circle(75%); }
  .gerak .person:not(.tampak) .portrait { clip-path: circle(0%); }
  .countdown div::before { transition: clip-path 1.6s cubic-bezier(.3, .8, .3, 1) .3s; }
  .gerak .count:not(.tampak) .countdown div::before { clip-path: polygon(50% 50%, 0 100%, 0 100%, 0 100%, 0 100%); }
  .event .plat { transition: translate 1s cubic-bezier(.3, 1.4, .4, 1) .15s, opacity .5s ease .15s; }
  .gerak .event:not(.tampak) .plat { translate: -50% -160%; opacity: 0; }
  .chapters::before, .chapters::after { transition: clip-path 2.4s ease; clip-path: inset(0); }
  .gerak .story:not(.tampak) .chapters::before, .gerak .story:not(.tampak) .chapters::after { clip-path: inset(0 0 100% 0); }
  .chapters li::before { transition: scale .8s cubic-bezier(.3, 1.6, .4, 1) .3s; }
  .gerak .chapters li:not(.tampak)::before { scale: 0; }
  .chapters li.tampak::before { animation: nyala 1.8s 1.2s ease-in-out infinite alternate; }
  .gift-card::before { transition: transform 1s cubic-bezier(.2, .8, .2, 1) .2s; transform-origin: 50% 0; }
  .gerak .gift-card:not(.tampak)::before { transform: scaleY(0); }
}

/* Foto tiap kisah cinta (opsional, sub-field stories.photo): polaroid kecil di atas judul, miring bergantian. */
.kisah-foto { margin: 2px 0 14px; padding: 6px 6px 20px; background: #fff; border-radius: 3px; box-shadow: 0 10px 22px rgba(30, 20, 20, .16); rotate: -1.4deg; }
:nth-child(even) > .kisah-foto { rotate: 1.4deg; }
.kisah-foto img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 2px; }
