/* Mapag — undangan pernikahan adat Sunda bergaya lukisan cat air, konsep "Mapag Panganten": sampul foto penuh layar,
   lalu tirai ronce melati yang tersibak ke kiri-kanan; pandangan berjalan di jalan batu berjajar janur menuju pendopo
   beratap julang ngapak berlatar gunung dan sawah, sepasang payung agung naik di tangga, saweran (koin, beras kuning,
   melati, kelopak, permen) berjatuhan, lalu bingkai ukiran bersiger turun membawa judul. 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: #f6f1e3; --bg2: #fbf8ee; --deep: #8c9c6c; --deep2: #66794b; --ink: #4b3d2d; --soft: #7a6d59; --gold: #b8934a; --gold-hi: #e6d3a0;
  --aksen: #94583a; --r1: #fbf3e2; --r2: #f1c9c2; --r3: #dc9a94; --sky1: #f7f3e6; --sky2: #eceedb; --card: #fffdf6; --line: #e2dcc6;
  --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: lapisan gambar selebar kolom halaman, di belakang isi; hanya bagian pembuka (.hero) yang tembus pandang.
   .stage berbanding 1116:2000 (ukuran lukisan induk) dan selalu menutup layar. Urutan lapisan dari belakang: latar
   (langit, gunung, sawah) → pendopo + dua payung agung → jalan batu → tiga pasang janur (satu gambar yang sama,
   diperkecil ke .41 dan .63 dari titik hilang 50% 66.5%) → tirai tersibak (.ly-sibak) → kabut → dua belah tirai
   tertutup (.tr, satu gambar dipotong dua dengan clip-path). Keadaan dasar = tirai sudah tersibak dan pandangan sudah
   di jalan. Sebelum dibuka (.js:not(.is-open)) dua belah tirai menutup layar di depan kabut gading. */
.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% 66.5%; }
.ly > img, .tr > img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; }
.ly-bg { transform: scale(1.04); }
.ar { transform: scale(calc(var(--s) * var(--k, 1))); } .a1 { --s: 1; } .a2 { --s: .63; } .a3 { --s: .41; }
.pdp { position: absolute; left: 27.21%; top: 42.82%; width: 45.57%; }
.pg { position: absolute; top: 54.51%; width: 11.8%; transform-origin: 50% 100%; } .pg.l { left: 24.7%; } .pg.r { left: 63.5%; }
.pdp img, .pg img { display: block; width: 100%; height: auto; max-width: none; }
.tr { position: absolute; inset: 0; z-index: 2; will-change: transform; transform: scaleX(.04); opacity: 0; }
.tr.l { clip-path: inset(0 50% 0 0); transform-origin: 0 0; } .tr.r { clip-path: inset(0 0 0 50%); transform-origin: 100% 0; }
.kabut { position: absolute; inset: 0; z-index: 1; background: linear-gradient(180deg, #fbf7ea, #f4eedb 70%, #e9ecd6); opacity: 0; }
.js .ly { transition: transform 4.2s cubic-bezier(.6, 0, .2, 1) 2s; }
.js .ly-sibak { transition: transform 4.2s cubic-bezier(.6, 0, .2, 1) 2s, opacity 1.2s ease 2s; }
.js .tr { transition: transform 2.4s cubic-bezier(.6, 0, .25, 1) .9s, opacity .7s ease 2.6s; }
.js .kabut { transition: opacity 2.4s ease 1.1s; }
.js .pg { transition: transform 1.3s cubic-bezier(.3, 1.3, .4, 1) 5s, opacity .5s ease 5s; } .js .pg.r { transition-delay: 5.3s; }
.js:not(.is-open) .tr { transform: none; opacity: 1; }
.js:not(.is-open) .kabut { opacity: .9; }
.js:not(.is-open) .ly-sibak { opacity: 0; transform: scale(1.05); }
.js:not(.is-open) .ly-bg { transform: none; }
.js:not(.is-open) .ar { --k: .8; }
.js:not(.is-open) .ly-house { transform: scale(.9); }
.js:not(.is-open) .ly-path { transform: scale(.92); }
.js:not(.is-open) .pg { transform: translateY(30%) scale(.5); opacity: 0; }
.js.no-anim .ly, .js.no-anim .tr, .js.no-anim .kabut, .js.no-anim .pg { transition: none; }
.rays { position: absolute; left: 50%; top: 52%; width: 190%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; background: repeating-conic-gradient(rgba(255, 250, 225, .3) 0 5deg, transparent 5deg 18deg); -webkit-mask-image: radial-gradient(circle, #000 6%, transparent 40%); mask-image: radial-gradient(circle, #000 6%, transparent 40%); opacity: .6; }
/* Saweran: butir gambar kecil (koin, beras kuning, melati, kelopak, permen) yang berjatuhan sekali setelah pandangan tiba. */
.sawer { position: absolute; inset: 0; }
.sawer i { position: absolute; top: -8%; width: 26px; aspect-ratio: 1; background: center / contain no-repeat; opacity: 0; display: none; }
.sawer .s1 { background-image: url("img/koin.webp"); } .sawer .s2 { background-image: url("img/beras.webp"); } .sawer .s3 { background-image: url("img/melati.webp"); }
.sawer .s4 { background-image: url("img/kelopak.webp"); } .sawer .s5 { background-image: url("img/permen.webp"); } .sawer .s6 { background-image: url("img/koin2.webp"); }
.petals { position: absolute; inset: 0; }
.petals i { position: absolute; top: -4%; border-radius: 90% 10% 80% 20%; background: linear-gradient(135deg, #fff, var(--r1) 60%, var(--r2)); display: none; }
.veil { position: absolute; inset: 0; background: radial-gradient(circle at 50% 54%, #fffdf0 0, rgba(255, 250, 225, .7) 40%, transparent 78%); opacity: 0; }
.terang { position: absolute; inset: 0; background: radial-gradient(circle at 50% 56%, #fff 0, #fffdf5 60%, var(--bg) 100%); opacity: 0; }
.strip { position: relative; width: calc(100% + 56px); margin: -64px -28px 0; -webkit-mask-image: linear-gradient(transparent, #000 12%, #000 78%, transparent); mask-image: linear-gradient(transparent, #000 12%, #000 78%, transparent); }
.strip img { display: block; width: 100%; height: auto; }
.petals i:nth-child(1) { left: 48%; width: 12px; height: 10px; animation-duration: 13.9s, 2.6s; animation-delay: -5.3s, -1.2s; opacity: 0.6; }
.petals i:nth-child(2) { left: 68%; width: 8px; height: 6px; animation-duration: 10.1s, 3.5s; animation-delay: -13.9s, -2.8s; opacity: 0.7; }
.petals i:nth-child(3) { left: 47%; width: 13px; height: 8px; animation-duration: 11.5s, 3.1s; animation-delay: -4s, -0.6s; opacity: 0.7; }
.petals i:nth-child(4) { left: 71%; width: 8px; height: 8px; animation-duration: 15.7s, 2.6s; animation-delay: -8.8s, -3.9s; opacity: 0.5; }
.petals i:nth-child(5) { left: 45%; width: 8px; height: 9px; animation-duration: 12.3s, 2.8s; animation-delay: -1.8s, -3s; opacity: 0.8; }
.petals i:nth-child(6) { left: 1%; width: 13px; height: 9px; animation-duration: 14s, 4s; animation-delay: -9.7s, -3.4s; opacity: 0.8; }
.petals i:nth-child(7) { left: 43%; width: 11px; height: 9px; animation-duration: 13.1s, 3.5s; animation-delay: -3.3s, -1.8s; opacity: 0.8; }
.petals i:nth-child(8) { left: 83%; width: 10px; height: 10px; animation-duration: 14.7s, 4.2s; animation-delay: -0.6s, -0.6s; opacity: 0.6; }
.petals i:nth-child(9) { left: -3%; width: 12px; height: 10px; animation-duration: 13.5s, 3.5s; animation-delay: -13.9s, -1.4s; opacity: 0.6; }
.petals i:nth-child(10) { left: 10%; width: 10px; height: 8px; animation-duration: 9.8s, 2.9s; animation-delay: -10s, -4s; opacity: 0.8; }
.petals i:nth-child(11) { left: 82%; width: 12px; height: 9px; animation-duration: 9.9s, 2.8s; animation-delay: -9s, -3.3s; opacity: 0.7; }
.petals i:nth-child(12) { left: 33%; width: 13px; height: 6px; animation-duration: 10.9s, 2.4s; animation-delay: -3.8s, -2.8s; opacity: 0.8; }
.sawer i:nth-child(1) { left: 43%; width: 18px; --t: 3.3s; --dl: 6.3s; --x: 18px; --r: -387deg; }
.sawer i:nth-child(2) { left: 76%; width: 16px; --t: 4.2s; --dl: 6.8s; --x: -39px; --r: 414deg; }
.sawer i:nth-child(3) { left: 10%; width: 19px; --t: 2.8s; --dl: 7.3s; --x: 22px; --r: -314deg; }
.sawer i:nth-child(4) { left: 82%; width: 26px; --t: 3.6s; --dl: 6.4s; --x: 24px; --r: 225deg; }
.sawer i:nth-child(5) { left: 30%; width: 16px; --t: 3.6s; --dl: 6.5s; --x: 3px; --r: -476deg; }
.sawer i:nth-child(6) { left: 17%; width: 25px; --t: 3.2s; --dl: 8.3s; --x: -27px; --r: -497deg; }
.sawer i:nth-child(7) { left: 75%; width: 26px; --t: 2.9s; --dl: 6.5s; --x: 41px; --r: -488deg; }
.sawer i:nth-child(8) { left: 9%; width: 25px; --t: 3.0s; --dl: 8.0s; --x: 4px; --r: 438deg; }
.sawer i:nth-child(9) { left: 76%; width: 30px; --t: 3.4s; --dl: 7.0s; --x: -27px; --r: -241deg; }
.sawer i:nth-child(10) { left: 75%; width: 20px; --t: 3.5s; --dl: 8.5s; --x: 43px; --r: 347deg; }
.sawer i:nth-child(11) { left: 79%; width: 17px; --t: 2.8s; --dl: 7.3s; --x: 46px; --r: 277deg; }
.sawer i:nth-child(12) { left: 64%; width: 22px; --t: 2.7s; --dl: 7.9s; --x: 47px; --r: 374deg; }
.sawer i:nth-child(13) { left: 90%; width: 21px; --t: 3.7s; --dl: 7.7s; --x: 8px; --r: -247deg; }
.sawer i:nth-child(14) { left: 36%; width: 23px; --t: 3.9s; --dl: 6.4s; --x: 43px; --r: 531deg; }
.sawer i:nth-child(15) { left: 75%; width: 26px; --t: 4.1s; --dl: 6.9s; --x: -1px; --r: 211deg; }
.sawer i:nth-child(16) { left: 61%; width: 21px; --t: 2.9s; --dl: 6.5s; --x: -43px; --r: -593deg; }
.sawer i:nth-child(17) { left: 38%; width: 18px; --t: 3.9s; --dl: 7.2s; --x: 13px; --r: -285deg; }
.sawer i:nth-child(18) { left: 59%; width: 22px; --t: 3.6s; --dl: 8.5s; --x: 5px; --r: 561deg; }
.sawer i:nth-child(19) { left: 55%; width: 21px; --t: 3.8s; --dl: 7.2s; --x: -21px; --r: -242deg; }
.sawer i:nth-child(20) { left: 24%; width: 18px; --t: 3.0s; --dl: 6.8s; --x: 12px; --r: -334deg; }
.sawer i:nth-child(21) { left: 38%; width: 16px; --t: 2.9s; --dl: 7.6s; --x: 28px; --r: 264deg; }
.sawer i:nth-child(22) { left: 90%; width: 29px; --t: 3.5s; --dl: 7.8s; --x: 36px; --r: -433deg; }
.sawer i:nth-child(23) { left: 89%; width: 28px; --t: 3.6s; --dl: 7.2s; --x: 0px; --r: -446deg; }
.sawer i:nth-child(24) { left: 83%; width: 22px; --t: 2.7s; --dl: 6.4s; --x: -24px; --r: 283deg; }

.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: tirai melati berayun pelan → tersibak ke kiri-kanan dan kabut menipis (0,9–3,3 dtk) → berjalan maju di
     antara janur (2–6,2) → dua payung agung naik (5–6,6) → saweran berjatuhan (6,2–13) → bingkai bersiger turun (6,7)
     lalu berayun. Berulang terus: kelopak melati, sinar di balik pendopo, ayunan payung dan janur. */
  .petals i { display: block; animation-name: gugur, kibar; animation-timing-function: linear, ease-in-out; animation-iteration-count: infinite; animation-direction: normal, alternate; }
  .rays { animation: putar2 110s linear infinite; }
  .js:not(.is-open) .tr > img { animation: ayunT 4.2s ease-in-out infinite alternate; transform-origin: 50% 0; }
  .pg img { animation: ayunK 5.2s ease-in-out infinite alternate; transform-origin: 50% 100%; } .pg.r img { animation-delay: -2.1s; }
  .ar > img { animation: ayunJ 6.4s ease-in-out infinite alternate; transform-origin: 50% 90%; } .a2 > img { animation-delay: -2s; } .a3 > img { animation-delay: -4s; }
  .js.is-open:not(.no-anim) .sawer i { display: block; animation: sawer var(--t) var(--dl) cubic-bezier(.4, .1, .7, 1) 2 both; }
  .js.is-open:not(.no-anim) .veil { animation: silau 3s 1.6s ease-in-out both; }
  .papan { animation: goyang 5s ease-in-out infinite alternate; }
  .js.is-open:not(.no-anim) .papan { animation: turunP 1.6s 6.7s cubic-bezier(.3, 1.2, .4, 1) both, goyang 5s 8.3s ease-in-out infinite alternate; }
  .js.is-open:not(.no-anim) .hero-pin > .mouse { animation: naik 1s 8s both; }
  .spray { animation: ayun 6s ease-in-out infinite; transform-origin: 50% 100%; } .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 Mapag: judul di bingkai ukiran lonjong bermahkota siger (gambar bingkai.webp, teks HTML di
   atasnya) yang turun dan berayun pelan. Selama pembuka digulir (.ready, --p 0→1 dipasang mapag.js) pandangan terus
   berjalan: tirai tersibak terlewati, janur lewat satu per satu sampai ke tangga pendopo, lalu layar memutih. ---------- */
.script, .person h3, .chapters h3, .wishes-head h2 { color: var(--aksen); }
.count .script, .rsvp .script { color: #fff; }
.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: 5vh 0 0; pointer-events: none; overflow: hidden; }
.scene-off .hero-pin { visibility: hidden; }
.title-wrap { width: min(60%, 240px); }
.papan { position: relative; transform-origin: 50% 0; filter: drop-shadow(0 10px 18px rgba(75, 61, 45, .22)); }
.papan > img { display: block; width: 100%; height: auto; max-width: none; }
.papan-t { position: absolute; left: 23%; right: 23%; top: 30%; bottom: 22%; 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: .22em; color: var(--soft); }
.t-name { font: 400 clamp(24px, 7.8vw, 32px)/1.05 var(--script); color: var(--aksen); overflow-wrap: anywhere; }
.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: var(--ink); opacity: .75; }
html:not(.js) .hero-pin { padding: 40px 0; } html:not(.js) .hero-pin > .mouse { display: none; }
main h2.script::after { content: ""; display: block; width: 240px; max-width: 80vw; height: 30px; margin: 6px 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: aktif setelah pembukaan selesai. --p = seberapa jauh pembuka sudah digulir. Di p = 0 semua
     nilainya sama dengan keadaan akhir pembukaan, jadi tidak ada lompatan. */
  .ready .ly, .ready .ly-sibak { transition: none; }
  .ready .tr, .ready .kabut { visibility: hidden; }
  .ready .ly-bg { transform: scale(calc(1.04 + var(--p, 0) * .3)); }
  .ready .ly-house { transform: scale(calc(1 + var(--p, 0) * var(--p, 0) * 2.6)); }
  .ready .ly-path { transform: scale(calc(1 + var(--p, 0) * 2.2)); }
  .ready .ar { --k: calc(1 + var(--p, 0) * 3.2); }
  .ready .a1 { opacity: calc(1 - (var(--p, 0) - .12) * 6); } .ready .a2 { opacity: calc(1 - (var(--p, 0) - .42) * 6); } .ready .a3 { opacity: calc(1 - (var(--p, 0) - .72) * 6); }
  .ready .ly-sibak { transform: scale(calc(1 + var(--p, 0) * 2.4)); opacity: calc(1 - var(--p, 0) * 6); }
  .ready .title-wrap { opacity: calc(1 - var(--p, 0) * 5); translate: 0 calc(var(--p, 0) * -160px); }
  .ready .hero-pin > .mouse { opacity: calc(.75 - var(--p, 0) * 6); }
  .ready .terang { opacity: calc((var(--p, 0) - .64) * 3.2); }
  .ready .petals, .ready .sawer { opacity: calc(1 - var(--p, 0) * 2.5); transition: none; }
}
@keyframes putar2 { from { rotate: 0deg; } to { rotate: 360deg; } }
@keyframes ayunK { from { rotate: -1.6deg; } to { rotate: 1.6deg; } }
@keyframes ayunT { from { transform: skewX(-.7deg); } to { transform: skewX(.7deg); } }
@keyframes ayunJ { from { transform: skewX(-.5deg); } to { transform: skewX(.5deg); } }
@keyframes sawer { 0% { opacity: 0; translate: 0 0; rotate: 0deg; } 8% { opacity: 1; } 85% { opacity: 1; } 100% { opacity: 0; translate: var(--x) 118vh; rotate: var(--r); } }
@keyframes goyang { from { rotate: -1.4deg; } to { rotate: 1.4deg; } }
@keyframes turunP { from { opacity: 0; translate: 0 -110%; rotate: 6deg; } to { opacity: 1; translate: 0 0; rotate: -1.4deg; } }

/* ---------- Isi Mapag: tata letak dan ornamen khas tiap bagian. Ornamen bertanda .orn tidak ikut animasi .rv;
   geraknya memakai .tampak yang dipasang mapag.js saat bagian masuk layar (hanya bila .gerak ada di <html>, yaitu
   ada JS dan gerak tidak dikurangi). Tanpa itu semua ornamen langsung tampil di keadaan akhirnya. ---------- */
main > section.count, main > section.rsvp { -webkit-mask: radial-gradient(15px at 50% 0, #0000 97%, #000) 50% 0 / 30px 100%; mask: radial-gradient(15px at 50% 0, #0000 97%, #000) 50% 0 / 30px 100%; padding-top: 84px; }

/* Pangjajap: rumbai ronce melati bergantung di tepi atas, kutipan diapit garis emas. */
main > section.verse { padding-top: calc(42% + 14px); }
.rumbai { position: absolute; top: 0; left: 0; right: 0; pointer-events: none; transform-origin: 50% 0; }
.rumbai img { display: block; width: 100%; height: auto; aspect-ratio: 760 / 322; }
.quote { padding: 22px 6px; border-top: 1px solid var(--gold); border-bottom: 1px solid var(--gold); outline: 1px solid var(--gold-hi); outline-offset: 5px; }

/* Panganten: potret lonjong di dalam bingkai ukiran bersiger, zigzag kiri-kanan, masing-masing dinaungi payung agung. */
.couple { gap: 10px; }
.person { align-items: flex-start; text-align: left; width: 100%; }
.person ~ .person { align-items: flex-end; text-align: right; }
.pigura { position: relative; width: 62%; max-width: 268px; margin-bottom: 8px; }
.pigura-b { position: relative; z-index: 1; display: block; width: 100%; height: auto; filter: drop-shadow(0 12px 18px rgba(75, 61, 45, .2)); }
.pigura .portrait { position: absolute; z-index: 2; left: 15%; right: 15%; top: 20%; bottom: 19.5%; width: auto; height: auto; padding: 0; border: 0; border-radius: 50%; overflow: hidden; background: var(--bg2); box-shadow: 0 0 0 2px var(--gold); }
.pigura .portrait > * { border-radius: 0; }
.pg-s { position: absolute; z-index: 0; left: 94%; bottom: -3%; width: 44%; max-width: none; transform-origin: 50% 100%; }
.person ~ .person .pg-s { left: auto; right: 94%; }
.person .parents { max-width: 15em; }
.dan { align-self: center; display: flex; flex-direction: column; align-items: center; margin: -4px 0 2px; }
.dan img { width: 66px; height: auto; }
.dan span { font: 400 46px/1 var(--script); color: var(--gold); }
.person ~ .person .rv { translate: 30px 0; }

/* Titimangsa: sepasang janur tumbuh di tepi, hitung mundur berupa empat medali bundar. */
main > section.count { padding-left: 76px; padding-right: 76px; padding-bottom: 76px; }
.jn { position: absolute; bottom: -6px; width: 25%; max-width: 112px; height: auto; aspect-ratio: 180 / 620; transform-origin: 50% 100%; pointer-events: none; }
.jn.l { left: -3%; } .jn.r { right: -3%; scale: -1 1; }
.countdown { grid-template-columns: repeat(2, minmax(0, 104px)); justify-content: center; gap: 14px; }
.countdown div { aspect-ratio: 1; padding: 0; justify-content: center; border-radius: 50%; border-color: var(--gold-hi); outline: 1px solid rgba(255, 255, 255, .45); outline-offset: -7px; background: rgba(255, 255, 255, .08); }
.countdown .rv { scale: .3; }
.count .btn-line { padding: 0 14px; font-size: 11.5px; letter-spacing: .14em; white-space: nowrap; }

/* Acara: tiap kartu berupa pendopo — atap lukisan di atas, badan kartu di antara dua tiang jati di atas umpak batu. */
main > section.programme { gap: 34px !important; }
.event { position: relative; width: min(72%, 300px); margin-top: 50%; padding: 22px 16px 24px; border: solid; border-width: 0 10px 14px; border-color: #a8764d #a8764d #b7b0a2; border-radius: 0 0 5px 5px; outline: 0; background: linear-gradient(180deg, #f3ead6, var(--card) 26px); box-shadow: 0 22px 34px rgba(75, 61, 45, .16); }
.event ~ .event { margin-top: 44%; }
.atap { position: absolute; left: 50%; bottom: calc(100% - 3px); width: calc(128% + 26px); max-width: none; aspect-ratio: 620 / 325; translate: -50% 0; pointer-events: none; }
.event .script { font-size: 40px; }
.event h2.script::after { width: 100%; }
.event .where { max-width: none; }

/* Carita Urang: garis waktu berupa seuntai melati, tiap bab ditandai bunga melati yang mekar. */
.chapters { position: relative; padding-left: 46px; gap: 22px; }
.chapters::before { content: ""; position: absolute; left: 6px; top: -6px; bottom: -6px; width: 24px; background: url("img/untai.webp") top center / 24px auto repeat-y; }
.chapters li { padding: 18px 20px; border-radius: 4px 24px 24px 24px; border-color: var(--gold-hi); }
.chapters li::before { left: -52px; top: 12px; bottom: auto; width: 38px; height: 38px; border-radius: 0; background: url("img/melati.webp") center / contain no-repeat; }

/* Galeri: foto kotak dalam pigura ukiran jati (pigura.webp dipasang sebagai border-image 9 potong langsung di <img>,
   sisi diulang supaya ukiran tidak melar di foto lebar), bunga melati di dua sudut kisi, di bawah untaian melati. */
.untaian { width: 210px; margin: -6px auto 2px; pointer-events: none; }
.grid { position: relative; gap: 16px 14px; padding: 6px 4px; }
.grid img { aspect-ratio: 1; padding: 0; background: var(--card) padding-box; border: 22px solid #c9a888; border-image: url("img/pigura.webp") 84 / 22px round; border-radius: 0; outline: 0; box-shadow: none; filter: drop-shadow(0 8px 12px rgba(75, 61, 45, .13)); }
.grid img:nth-child(3n+1) { aspect-ratio: 4 / 3; border-width: 26px; border-image-width: 26px; }
.grid::before, .grid::after { content: ""; position: absolute; z-index: 1; width: 46px; aspect-ratio: 1; background: url("img/melati.webp") center / contain no-repeat; pointer-events: none; filter: drop-shadow(0 3px 5px rgba(75, 61, 45, .25)); }
.grid::before { left: -12px; top: -14px; } .grid::after { right: -12px; bottom: -14px; }
.grid .rv { rotate: -5deg; } .grid .rv:nth-child(even) { rotate: 5deg; }
.grid .rv.in { rotate: 0deg; 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), rotate 1.1s cubic-bezier(.3, 1.5, .4, 1) calc(var(--d, 0) * 1ms); }

/* Tanda Asih: kartu rekening berkoin saweran. */
.gift-card { position: relative; padding-left: 68px; border-radius: 44px 16px 16px 44px; border-color: var(--gold-hi); perspective: 600px; }
.koin { position: absolute; left: 12px; top: 50%; width: 44px; height: auto; margin-top: -22px; }

/* Ucapan: tirai ronce melati tersibak membingkai formulir. */
.gorden { position: absolute; top: 0; left: 0; right: 0; aspect-ratio: 720 / 1290; pointer-events: none; opacity: .4; -webkit-mask-image: linear-gradient(#000 50%, transparent 88%); mask-image: linear-gradient(#000 50%, transparent 88%); }
.gorden img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; }
.gorden .l { clip-path: inset(0 50% 0 0); } .gorden .r { clip-path: inset(0 0 0 50%); }
.rsvp > :not(.gorden) { position: relative; z-index: 1; }

/* Penutup: pemandangan pendopo di atas, buket melati, ucapan terima kasih. */
main > section.closing { padding-top: 64px; }
.closing .strip img { aspect-ratio: 940 / 842; transform-origin: 50% 70%; }

@media (prefers-reduced-motion: no-preference) {
  /* Keadaan awal sebelum bagian terlihat (.gerak …:not(.tampak)), lalu transisi ke keadaan akhir. */
  .rumbai { transition: transform 1.5s cubic-bezier(.3, 1.3, .5, 1), opacity .6s ease; }
  .gerak .verse:not(.tampak) .rumbai { transform: translateY(-70%) scaleY(.4); opacity: 0; }
  .pg-s { transition: transform 1.2s cubic-bezier(.3, 1.5, .4, 1) .5s, opacity .4s ease .5s; }
  .gerak .person:not(.tampak) .pg-s { transform: translateY(8%) scale(.25, .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(-9deg) scale(.82); opacity: 0; }
  .gerak .person ~ .person:not(.tampak) .pigura-b { transform: rotate(9deg) scale(.82); }
  .pigura .portrait { transition: clip-path 1.1s ease .45s; clip-path: circle(75%); }
  .gerak .person:not(.tampak) .portrait { clip-path: circle(0%); }
  .dan img { animation: kilau 3.4s ease-in-out infinite alternate; }
  .jn { transition: transform 1.5s cubic-bezier(.3, 1.2, .4, 1) .2s, opacity .5s ease .2s; }
  .gerak .count:not(.tampak) .jn { transform: scaleY(.05); opacity: 0; }
  .jn { animation: ayunJ 5.6s ease-in-out infinite alternate; } .jn.r { animation-delay: -2.4s; }
  .atap { transition: translate 1s cubic-bezier(.3, 1.4, .4, 1) .15s, opacity .5s ease .15s; }
  .gerak .event:not(.tampak) .atap { translate: -50% -70%; opacity: 0; }
  .chapters::before { transition: clip-path 2.4s ease; clip-path: inset(0); }
  .gerak .story:not(.tampak) .chapters::before { clip-path: inset(0 0 100% 0); }
  .chapters li::before { transition: scale .9s cubic-bezier(.3, 1.6, .4, 1) .25s, rotate .9s ease .25s; }
  .gerak .chapters li:not(.tampak)::before { scale: 0; rotate: -140deg; }
  .chapters li.tampak::before, html:not(.gerak) .chapters li::before { animation: putar2 26s linear infinite; }
  .untaian { transition: scale 1.1s cubic-bezier(.3, 1.3, .4, 1), opacity .6s ease; }
  .gerak .gallery:not(.tampak) .untaian { scale: .2 1; opacity: 0; }
  .grid::before, .grid::after { transition: scale .9s cubic-bezier(.3, 1.6, .4, 1) .5s, rotate .9s ease .5s; }
  .gerak .gallery:not(.tampak) .grid::before, .gerak .gallery:not(.tampak) .grid::after { scale: 0; rotate: -140deg; }
  .koin { transition: transform 1.3s cubic-bezier(.2, .8, .2, 1) .2s, opacity .4s ease .2s; }
  .gerak .gift-card:not(.tampak) .koin { transform: rotateY(540deg) scale(.3); opacity: 0; }
  .gift-card.tampak .koin { animation: balikK 7s 2s ease-in-out infinite; }
  .gorden img { transition: transform 2s cubic-bezier(.5, 0, .2, 1) .2s, opacity 1s ease .2s; }
  .gerak .rsvp:not(.tampak) .gorden .l { transform: translateX(30%) scaleX(1.5); opacity: 0; }
  .gerak .rsvp:not(.tampak) .gorden .r { transform: translateX(-30%) scaleX(1.5); opacity: 0; }
  .gorden .l { transform-origin: 0 0; } .gorden .r { transform-origin: 100% 0; }
  .closing .strip img { animation: napas 9s ease-in-out infinite alternate; }
  .rumbai img { animation: ayunT 4.6s ease-in-out infinite alternate; transform-origin: 50% 0; }
  .pg-s { animation: ayunK 5.2s ease-in-out infinite alternate; }
}
@keyframes kilau { from { filter: brightness(1); } to { filter: brightness(1.18) drop-shadow(0 0 6px rgba(230, 200, 120, .7)); } }
@keyframes balikK { 0%, 78%, 100% { transform: rotateY(0deg); } 90% { transform: rotateY(360deg); } }

/* 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; }
