/* Kincir — undangan pernikahan bergaya lukisan cat air: kincir angin Belanda di tepi ladang tulip pada pagi musim semi.
   Sampul berupa pintu kayu Belanda dua daun (atas & bawah) yang terbuka bergantian; di baliknya pandangan naik dari
   kanal ke kincir besar yang terpotong di tepi kanan. Baling-balingnya (lapisan sendiri) selalu berputar, digulir atau
   tidak, dan tiap tulip di depan bergoyang dengan iramanya sendiri serta condong saat halaman digulir (angin dari
   kincir.js). Nama tertulis di piring Delft biru; isi memakai ubin Delft, sepeda bertulip, dan tulip yang tumbuh. */
@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: #f7f2e7; --bg2: #eef1f4; --ink: #2b3550; --soft: #626b80; --delft: #23468f; --delft-dk: #1b356c; --red: #cf4a4a;
  --pink: #e48d9b; --yellow: #f0c55a; --leaf: #5c8a4c; --door: #3e6b56; --door-dk: #2c5040; --line: rgba(35, 70, 143, .3);
  --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: #e3e8ee; }
body { margin: 0; background: #e3e8ee; 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, figure { margin: 0; }
a { color: var(--delft); }
:focus-visible { outline: 2px solid var(--delft); 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(30, 50, 90, .18); } }

/* ---------- Adegan ladang: lapisan selebar kolom halaman, di belakang pembuka ----------
   .stage berbanding 940:1684 (ukuran lukisan) dan selalu menutup layar. Lapisan latar memuat langit, ladang, kanal, dan
   badan kincir; baling-baling (.poros) duduk tepat di poros lukisan (76,34% 29,01%) dan berputar terus di dalam lapisan
   latar sehingga ikut membesar bersamanya. Lapisan depan berisi tulip satuan yang masing-masing bergoyang. Sebelum
   dibuka pandangan dekat ke kanal (latar dibesarkan dari 35% 80%); saat dibuka pandangan mundur dan naik ke kincir. */
.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: #f1e7e4; 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.7915)); aspect-ratio: 940 / 1684; translate: -50% -50%; }
.ly { position: absolute; inset: 0; will-change: transform; }
.ly-latar { transform-origin: 35% 80%; }
.ly-latar > img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; }
.poros { position: absolute; left: 76.34%; top: 29.01%; width: 100%; aspect-ratio: 1; translate: -50% -50%; }
.putar, .sayap { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; }
.ly-depan { transform-origin: 50% 100%; }
.tl { position: absolute; bottom: -2%; height: 24%; width: auto; max-width: none; transform-origin: 50% 100%; transform: rotate(calc(var(--angin, 0) * 1deg)); transition: transform .9s cubic-bezier(.3, 1.5, .5, 1); }
.t1 { left: -4%; height: 27%; } .t2 { left: 4%; height: 21%; bottom: 1%; } .t3 { left: 11%; height: 25%; } .t4 { left: 19%; height: 20%; bottom: 2%; } .t5 { left: 26%; height: 26%; bottom: -4%; }
.t6 { left: 35%; height: 19%; bottom: 3%; } .t7 { left: 43%; height: 23%; bottom: -1%; } .t8 { left: 52%; height: 20%; bottom: 2%; } .t9 { left: 59%; height: 26%; bottom: -3%; }
.t10 { left: 68%; height: 21%; bottom: 1%; } .t11 { left: 76%; height: 25%; bottom: -2%; } .t12 { left: 84%; height: 20%; bottom: 3%; } .t13 { left: 90%; height: 27%; bottom: -4%; }
.js .ly-latar { transition: transform 4.4s cubic-bezier(.45, 0, .15, 1) .4s; }
.js .ly-depan { transition: transform 3.6s cubic-bezier(.3, 0, .2, 1) .8s; }
.js .poros { transition: rotate 5.5s cubic-bezier(.2, .6, .3, 1) .3s; }
.js:not(.is-open) .ly-latar { transform: scale(1.55); }
.js:not(.is-open) .ly-depan { transform: translateY(14%) scale(1.3); }
.js:not(.is-open) .poros { rotate: -300deg; }
.js.no-anim .ly, .js.no-anim .poros { transition: none; }
.sinar { position: absolute; left: 22%; top: 2%; width: 34%; height: 46%; rotate: 24deg; background: linear-gradient(180deg, rgba(255, 250, 225, .6), rgba(255, 244, 210, .2) 60%, transparent); filter: blur(10px); mix-blend-mode: screen; }
.kilau-air { position: absolute; left: 12%; top: 70%; width: 38%; height: 12%; background: repeating-linear-gradient(100deg, transparent 0 14px, rgba(255, 255, 255, .55) 15px 17px, transparent 18px 34px); -webkit-mask-image: radial-gradient(closest-side, #000 30%, transparent); mask-image: radial-gradient(closest-side, #000 30%, transparent); mix-blend-mode: screen; opacity: .6; }
.angin { position: absolute; inset: 0; overflow: hidden; }
.angin i { position: absolute; left: -4%; width: 1.4%; height: .6%; border-radius: 60% 0 60% 0; background: var(--pink); opacity: 0; }
.angin i:nth-child(1) { top: 30%; } .angin i:nth-child(2) { top: 46%; background: var(--yellow); } .angin i:nth-child(3) { top: 58%; background: var(--red); }
.angin i:nth-child(4) { top: 38%; background: #fff; } .angin i:nth-child(5) { top: 66%; } .angin i:nth-child(6) { top: 52%; background: #b892d6; }
.terang { position: absolute; inset: 0; background: radial-gradient(circle at 37% 64%, #fffdf6 0, #fbf0d8 18%, rgba(247, 242, 231, 0) 55%), var(--bg); opacity: 0; }

.caps { font: 500 13px/1.4 var(--display); letter-spacing: .34em; text-transform: uppercase; }
.script { font: 400 50px/1.05 var(--script); color: var(--delft); }
.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(--delft); border-radius: 999px; background: var(--delft); color: #fbf8f0; text-decoration: none; cursor: pointer; font: 600 13px/1 var(--display); letter-spacing: .22em; text-transform: uppercase; }
.btn-line { background: transparent; color: var(--delft); border-color: currentColor; }
.btn.copied { background: var(--leaf); border-color: var(--leaf); color: #fff; }

/* ---------- Sampul: pintu kayu Belanda dua daun (atas & bawah) bercat hijau ---------- */
.cover { position: relative; min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; text-align: center; color: #fbf6ea; background: var(--door-dk); overflow: hidden; perspective: 1400px; }
.cover[hidden] { display: none; }
.daun { position: relative; display: flex; flex-direction: column; align-items: center; padding: 22px 22px; background: linear-gradient(90deg, rgba(0, 0, 0, .12), transparent 8%, transparent 92%, rgba(0, 0, 0, .14)), linear-gradient(180deg, #477a62, var(--door)); box-shadow: inset 0 0 0 10px var(--door-dk); transform-origin: 0 50%; backface-visibility: hidden; }
.daun::before { content: ""; position: absolute; inset: 22px; border: 2px solid rgba(255, 255, 255, .18); border-radius: 4px; box-shadow: inset 0 0 0 6px rgba(0, 0, 0, .08), 0 0 0 6px rgba(255, 255, 255, .05); pointer-events: none; }
.daun-atas { flex: 1.45; justify-content: center; gap: 14px; padding-top: 44px; border-bottom: 4px solid var(--door-dk); }
.daun-bawah { flex: 1; justify-content: center; }
.daun-bawah::after { content: ""; position: absolute; left: 22px; right: 22px; top: 0; height: 12px; background: linear-gradient(180deg, #2a4a3b, #355d4b); }
.cover-top, .cover-bottom { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 10px; }
.cover .caps { color: #e8dcc0; }
.cover .names { font: 500 30px/1.15 var(--display); letter-spacing: .08em; text-transform: uppercase; overflow-wrap: anywhere; color: #fff8e8; }
.names .amp { margin: 0 .25em; font: 400 40px/1 var(--script); text-transform: none; letter-spacing: 0; color: var(--yellow); }
.piring-sampul { position: relative; z-index: 1; width: min(60vw, 250px); aspect-ratio: 760 / 758; background: url("img/piring.webp") center / contain no-repeat; }
.piring-sampul .foto { position: absolute; left: 20.5%; right: 19.2%; top: 18.9%; bottom: 19%; border-radius: 50%; overflow: hidden; }
.piring-sampul .foto img { width: 100%; height: 100%; object-fit: cover; }
.piring-sampul.tanpa-foto::after { content: ""; position: absolute; inset: 24%; background: url("img/bunga1.webp") 30% 50% / auto 90% no-repeat, url("img/bunga4.webp") 70% 50% / auto 80% no-repeat; }
@media (max-height: 640px) { .piring-sampul { display: none; } }
.gagang { position: absolute; z-index: 1; right: 40px; top: 30px; width: 14px; height: 44px; border-radius: 7px; background: linear-gradient(90deg, #a07c3c, #e2c47a 45%, #a07c3c); box-shadow: 0 2px 4px rgba(0, 0, 0, .35); }
.to { font-size: 16px; line-height: 1.5; color: #e8dcc0; }
.guest-name { font: 600 24px/1.2 var(--serif); overflow-wrap: anywhere; }
.cover .open { margin-top: 8px; min-width: 230px; min-height: 48px; background: #fbf6ea; border-color: #fbf6ea; color: var(--door-dk); box-shadow: 0 10px 24px rgba(0, 0, 0, .25); }
html:not(.js) .cover .open { display: none; }

/* Dengan JS: sampul menutup layar; "Buka undangan" mengayun daun atas lalu daun bawah ke kiri seperti pintu. */
.js .cover { position: fixed; top: 0; bottom: 0; left: 50%; width: min(100%, 480px); transform: translateX(-50%); z-index: 40; background: none; }
.js:not(.is-open) body { overflow: hidden; }
.js.is-open .cover { pointer-events: none; }
.js.is-open .daun-atas { transform: rotateY(-108deg); transition: transform 1.4s cubic-bezier(.55, 0, .3, 1) .1s; }
.js.is-open .daun-bawah { transform: rotateY(-108deg); transition: transform 1.4s cubic-bezier(.55, 0, .3, 1) .45s; }
.js.is-open .cover { opacity: 0; transition: opacity .4s ease 1.8s; }
.js.no-anim .daun, .js.no-anim .cover { transition: none; }
.memuat .cover .open { pointer-events: none; opacity: .55; }

/* ---------- Pembuka: nama di piring Delft biru yang menggelinding masuk ---------- */
.hero { position: relative; min-height: 100vh; min-height: 100svh; padding: 44px 20px; display: grid; place-items: center; text-align: center; background: linear-gradient(rgba(247, 242, 231, .55), rgba(247, 242, 231, .8)), url("img/induk.webp") center / cover; }
.hero-pin { display: grid; place-items: center; width: 100%; }
.js .hero { display: block; padding: 0; background: none; }
.js .hero-pin { position: fixed; left: 50%; top: 0; width: min(100%, 480px); height: 100vh; height: 100svh; translate: -50% 0; padding: 27vh 0 0 5%; place-items: start; pointer-events: none; }
.scene-off .hero-pin { visibility: hidden; }
.title-wrap { width: 100%; }
.js .title-wrap { align-self: stretch; }
.js:not(.is-open) .title-wrap { opacity: 0; }
.title { display: flex; flex-direction: column; align-items: center; }
.js .title { height: 100%; align-items: flex-start; justify-content: space-between; padding-bottom: 5vh; }
.piring { position: relative; width: min(68vw, 300px); aspect-ratio: 760 / 758; padding: 24%; background: url("img/piring.webp") center / contain no-repeat; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; color: var(--delft); }
.piring .caps { font-size: 8.5px; letter-spacing: .26em; }
.t-name { display: flex; flex-direction: column; align-items: center; font: 400 clamp(26px, 8.6vw, 38px)/.95 var(--script); color: var(--delft-dk); overflow-wrap: anywhere; }
.t-name .amp { font-size: .6em; color: var(--red); line-height: 1; }
.pl-date { margin-top: 4px; font: 600 10px/1.3 var(--display); letter-spacing: .14em; text-transform: uppercase; color: var(--delft); }
.mouse { display: block; margin-top: 18px; width: 22px; height: 36px; border: 1.5px solid #fff; border-radius: 12px; position: relative; opacity: .9; }
.js .mouse { align-self: center; margin-left: -5%; }
.mouse::after { content: ""; position: absolute; left: 50%; top: 7px; width: 3px; height: 7px; margin-left: -1.5px; border-radius: 2px; background: #fff; animation: gulir 1.6s ease-in-out infinite; }

/* ---------- Isi: krem hangat dengan motif ubin Delft yang samar ---------- */
main > section:not(.hero) { position: relative; padding: 64px 26px; display: flex; flex-direction: column; align-items: center; gap: 20px; text-align: center;
  background: radial-gradient(circle at 50% 50%, rgba(35, 70, 143, .07) 0 3px, transparent 4px) 0 0 / 46px 46px, linear-gradient(180deg, var(--bg), #f3efe6); }
main h2.script::after { content: ""; display: block; width: 250px; max-width: 80vw; height: 40px; margin: 2px auto 0; background: url("img/pembatas.webp") center / contain no-repeat; }

/* Kutipan: sepeda bertulip melintas di jalan setapak di atasnya. */
.verse { padding-top: 30px !important; }
.jalan { position: relative; width: calc(100% + 52px); height: 130px; margin: 0 -26px; overflow: hidden; }
.jalan::after { content: ""; position: absolute; left: 0; right: 0; bottom: 6px; height: 3px; border-radius: 2px; background: linear-gradient(90deg, transparent, rgba(92, 138, 76, .5) 15%, rgba(92, 138, 76, .5) 85%, transparent); }
.sepeda { position: absolute; left: 50%; bottom: 8px; width: 170px; margin-left: -85px; }
.quote { font: italic 500 21px/1.6 var(--serif); max-width: 20em; }
.source { font: 600 14px/1.4 var(--display); letter-spacing: .14em; color: var(--delft); }

/* Mempelai: potret di tengah piring Delft, diapit tulip yang bergoyang. */
.couple { display: flex; flex-direction: column; align-items: center; gap: 14px; width: 100%; margin-top: 8px; }
.person { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.potret { position: relative; width: 250px; aspect-ratio: 760 / 758; background: url("img/piring.webp") center / contain no-repeat; }
.potret .foto { position: absolute; left: 20.5%; right: 19.2%; top: 18.9%; bottom: 19%; border-radius: 50%; overflow: hidden; background: #eef1f4; display: flex; }
.potret .foto > * { flex: 1; width: 100%; height: 100%; object-fit: cover; }
.potret .foto span { display: flex; align-items: center; justify-content: center; font: 400 80px/1 var(--script); color: var(--delft); }
.hias-tl { position: absolute; bottom: -10px; height: 120px; width: auto; transform-origin: 50% 100%; transform: rotate(calc(var(--angin, 0) * 1deg)); }
.hias-tl.kiri { left: -26px; } .hias-tl.kanan { right: -26px; }
.person h3 { font: 400 40px/1.05 var(--script); color: var(--delft-dk); 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(--red); }
.dan { font: 400 64px/1 var(--script); color: var(--red); }

/* Hitung mundur: empat ubin Delft; angka dilukis biru di tengahnya. */
.countdown { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; width: 100%; perspective: 600px; }
.ubin { position: relative; display: flex; flex-direction: column; align-items: center; }
.ubin b { display: flex; align-items: center; justify-content: center; width: 100%; aspect-ratio: 1; background: url("img/ubin.webp") center / contain no-repeat; font: 600 22px/1 var(--display); letter-spacing: -.02em; font-variant-numeric: tabular-nums; color: var(--delft); overflow: hidden; position: relative; }
.ubin b::after { content: ""; position: absolute; inset: 0; background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, .8) 48%, transparent 60%) 200% 0 / 250% 100% no-repeat; }
.ubin span { margin-top: 6px; font-size: 15px; color: var(--soft); }
html:not(.js) .countdown { display: none; }

/* Acara: kartu berbingkai ubin Delft (border-image dari ubin.webp); kitiran kecil berputar di sudutnya. */
.programme { gap: 34px !important; }
.event { position: relative; width: min(100%, 340px); display: flex; flex-direction: column; align-items: center; gap: 14px; }
.panel { position: relative; width: 100%; padding: 30px 18px 26px; border: 44px solid transparent; border-image: url("img/ubin.webp") 26% fill / 44px stretch; display: flex; flex-direction: column; align-items: center; gap: 8px; filter: drop-shadow(0 12px 18px rgba(30, 50, 90, .12)); }
.panel .script { font-size: 42px; }
.when { font: 700 18px/1.45 var(--serif); }
.where { font-size: 16px; line-height: 1.4; max-width: 15em; overflow-wrap: anywhere; color: var(--soft); }
.kitiran { position: absolute; top: -74px; right: -28px; width: 72px; }
.event:nth-of-type(odd) .kitiran { right: auto; left: -28px; }
.dress { font-size: 17px; font-style: italic; color: var(--soft); }

/* Kisah: tiap kartu ditemani tunas yang tumbuh menjadi tulip saat kartunya sampai di layar. */
.chapters { list-style: none; padding: 0; width: 100%; display: flex; flex-direction: column; gap: 26px; text-align: left; }
.chapters li { position: relative; display: grid; grid-template-columns: 46px 1fr; gap: 8px; align-items: end; }
.chapters li:nth-child(even) { grid-template-columns: 1fr 46px; }
.chapters li:nth-child(even) .tunas { order: 2; }
.tunas { position: relative; height: 140px; }
.tunas .tanah { position: absolute; left: -4px; right: -4px; bottom: 0; height: 12px; border-radius: 50% 50% 0 0; background: radial-gradient(ellipse at 50% 100%, #7a5a3a, #9b7650 70%); }
.tunas .batang { position: absolute; left: 0; right: 0; bottom: 6px; height: 132px; background: url("img/bunga1.webp") 50% 100% / contain no-repeat; transform-origin: 50% 100%; transform: rotate(calc(var(--angin, 0) * 1deg)); }
.chapters li:nth-child(6n+2) .batang { background-image: url("img/bunga2.webp"); } .chapters li:nth-child(6n+3) .batang { background-image: url("img/bunga3.webp"); }
.chapters li:nth-child(6n+4) .batang { background-image: url("img/bunga4.webp"); } .chapters li:nth-child(6n+5) .batang { background-image: url("img/bunga5.webp"); }
.chapters li:nth-child(6n) .batang { background-image: url("img/bunga6.webp"); }
.kartu { padding: 24px 22px 22px; border-radius: 4px; background: #fffdf8; border: 1px solid var(--line); box-shadow: inset 0 0 0 5px #fffdf8, inset 0 0 0 6px rgba(35, 70, 143, .35), 0 12px 26px rgba(30, 50, 90, .1); }
.chapters h3 { font: 400 34px/1.05 var(--script); color: var(--delft-dk); margin-bottom: 6px; }
.chapters p { font-size: 17px; line-height: 1.55; color: var(--soft); }
.kisah-foto { margin: 0 0 12px; padding: 6px 6px 18px; background: #fff; border-radius: 3px; rotate: -1.2deg; box-shadow: 0 8px 18px rgba(30, 50, 90, .16); }
.chapters li:nth-child(even) .kisah-foto { rotate: 1.2deg; }
.kisah-foto img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }

/* Galeri: foto di bingkai biru Delft yang tergantung di dinding, bergoyang pelan. */
.dinding { display: grid; grid-template-columns: 1fr 1fr; gap: 22px 14px; width: 100%; padding-top: 8px; }
.bingkai { position: relative; padding: 9px; background: #fff; border: 3px solid var(--delft); box-shadow: inset 0 0 0 3px #fff, inset 0 0 0 4px rgba(35, 70, 143, .5), 0 10px 22px rgba(30, 50, 90, .14); transform-origin: 50% -10px; }
.bingkai::before { content: ""; position: absolute; top: -12px; left: 50%; width: 10px; height: 10px; margin-left: -5px; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff, #c9b28a 50%, #8a6d3f); }
.bingkai img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
.bingkai:nth-child(odd) { rotate: -1.2deg; } .bingkai:nth-child(even) { rotate: 1.4deg; }
.bingkai:last-child:nth-child(odd) { grid-column: 1 / -1; width: 70%; justify-self: center; }

/* Amplop: sepeda bertulip diparkir, belnya berdering sesekali; rekening di kartu berbingkai ubin. */
.sepeda-parkir { width: 210px; margin-bottom: -6px; transform-origin: 50% 100%; }
.gift-list { display: grid; gap: 14px; width: 100%; }
.gift-card { position: relative; padding: 6px 4px; border: 30px solid transparent; border-image: url("img/ubin.webp") 26% fill / 30px stretch; 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(--delft); }
.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; }

/* Ucapan & RSVP. */
.note { width: 100%; padding: 14px 16px; border: 1px dashed var(--line); border-radius: 14px; font-size: 16px; }
.thanks { width: 100%; padding: 22px 18px; border-radius: 18px; background: rgba(255, 255, 255, .7); border: 1px solid var(--line); display: flex; flex-direction: column; align-items: center; gap: 6px; }
.thanks .big { font: 400 38px/1.1 var(--script); color: var(--delft); }
.tunas.besar { width: 60px; height: 150px; }
.tunas.besar .batang { height: 142px; background-image: url("img/bunga2.webp"); }
.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: 1px solid var(--line); 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(--delft); 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 var(--line); border-radius: 12px; background: rgba(255, 255, 255, .7); font: 600 13px/1 var(--display); letter-spacing: .14em; text-transform: uppercase; }
.opt input:checked + span { background: var(--delft); border-color: var(--delft); color: #fbf8f0; }
.opt input:focus-visible + span { outline: 2px solid var(--delft); outline-offset: 2px; }
.rsvp .btn { min-height: 50px; }

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(--delft); }
.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 { position: relative; padding: 14px 16px 14px 32px; border-radius: 16px; background: rgba(255, 255, 255, .75); border: 1px solid var(--line); display: flex; flex-direction: column; gap: 4px; }
.wishes li::before { content: ""; position: absolute; left: 12px; top: 18px; width: 10px; height: 12px; border-radius: 50% 50% 45% 45% / 60% 60% 40% 40%; background: var(--red); }
.wishes li:nth-child(3n+2)::before { background: var(--yellow); } .wishes li:nth-child(3n)::before { background: var(--pink); }
.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(--red); font-size: 12px; letter-spacing: .06em; text-transform: uppercase; color: var(--red); }
.status { font-size: 14px; font-weight: 700; color: var(--delft); }
.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(--delft); font-style: italic; color: var(--soft); }

/* Penutup: kincir yang sama di bawah langit senja, baling-balingnya masih berputar. */
main > section.closing { padding-top: 0; padding-bottom: 54px; }
.senja { position: relative; width: calc(100% + 52px); margin: 0 -26px 6px; aspect-ratio: 940 / 1180; overflow: hidden; -webkit-mask-image: linear-gradient(#000 80%, transparent); mask-image: linear-gradient(#000 80%, transparent); }
.senja > img, .senja > .poros { position: absolute; }
.senja > img { left: 0; top: 0; width: 100%; height: auto; }
.senja > .poros { top: calc(29.01% * 1684 / 1180); }
.lembayung { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(232, 130, 110, .38), rgba(250, 190, 140, .25) 45%, rgba(120, 90, 150, .18)); mix-blend-mode: multiply; }
.merci { font-size: 56px; }
.thanks-line { font-size: 17px; font-style: italic; color: var(--soft); }
.buket { width: 200px; margin-top: 4px; transform-origin: 50% 85%; }
.pl-name { font: 500 22px/1.2 var(--display); letter-spacing: .14em; text-transform: uppercase; color: var(--delft); }
footer { position: relative; padding: 18px 16px 26px; text-align: center; font-size: 14px; color: var(--soft); background: #e9edf2; }

.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: 1px solid var(--delft); border-radius: 50%; background: rgba(251, 248, 240, .92); color: var(--delft); cursor: pointer; box-shadow: 0 6px 16px rgba(30, 50, 90, .2); }
.music-toggle svg { width: 18px; height: 18px; }
.music-toggle[aria-pressed="false"]::after { content: ""; position: absolute; width: 24px; height: 1.5px; background: var(--delft); 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 kincir.js). */
.rv { opacity: 0; translate: 0 26px; }
.rv.script { translate: 0 -22px; }
.rv.panel, .rv.event, .dinding .rv { translate: 0 0; scale: .9; }
.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); }
/* Bagian yang tidak sedang terlihat (tanpa .aktif) membekukan geraknya. */
main > section:not(.hero):not(.aktif) *, main > section:not(.hero):not(.aktif) *::before, main > section:not(.hero):not(.aktif) *::after { animation-play-state: paused !important; }

@media (prefers-reduced-motion: no-preference) {
  .js .hero { min-height: 260vh; min-height: 260svh; }
  /* Baling-baling selalu berputar, sejak sampul masih tertutup sampai penutup. */
  .putar { animation: putar 16s linear infinite; }
  .tl { animation: goyang 3.2s ease-in-out infinite alternate; }
  .t2, .t8 { animation-duration: 2.6s; animation-delay: -1.1s; } .t3, .t11 { animation-duration: 3.8s; animation-delay: -2.4s; } .t4, .t12 { animation-duration: 2.9s; animation-delay: -.7s; }
  .t5, .t13 { animation-duration: 4.2s; animation-delay: -3s; } .t6 { animation-duration: 3.4s; animation-delay: -1.8s; } .t7 { animation-duration: 2.7s; animation-delay: -2s; } .t9 { animation-duration: 3.6s; animation-delay: -.4s; } .t10 { animation-duration: 3s; animation-delay: -2.7s; }
  .sinar { animation: napas 6s ease-in-out infinite alternate; }
  .kilau-air { animation: arus 5s linear infinite; }
  .angin i { animation: terbawa 11s linear infinite; } .angin i:nth-child(2) { animation-delay: -3s; animation-duration: 13s; } .angin i:nth-child(3) { animation-delay: -6s; animation-duration: 10s; }
  .angin i:nth-child(4) { animation-delay: -8s; animation-duration: 14s; } .angin i:nth-child(5) { animation-delay: -1.5s; animation-duration: 12s; } .angin i:nth-child(6) { animation-delay: -9.5s; animation-duration: 15s; }
  .cover-top { animation: turun 1.2s .2s both; } .piring-sampul { animation: gelinding-masuk 1.6s .3s cubic-bezier(.3, .7, .3, 1) both; } .cover-bottom { animation: naik 1.2s .5s both; }
  .js.is-open:not(.no-anim) .piring-sampul { animation: none; }
  /* Judul: piring menggelinding masuk dari kiri, lalu tulisan muncul. */
  .js.is-open:not(.no-anim) .piring { animation: gelinding-masuk 1.8s 3.8s cubic-bezier(.3, .7, .3, 1) both; }
  .js.is-open:not(.no-anim) .piring .caps { animation: muncul 1s 5.4s both; }
  .js.is-open:not(.no-anim) .t-name { animation: tulis 1.8s 5.6s ease-in-out both; }
  .js.is-open:not(.no-anim) .pl-date { animation: naik 1s 6.6s both; }
  .js.is-open:not(.no-anim) .title .mouse { animation: muncul 1s 7.2s both; }
  /* Perjalanan gulir: setelah pembukaan (.ready), --p 0→1 membawa pandangan menyusuri kanal ke cakrawala. */
  .ready .ly { transition: none; }
  .ready .ly-latar { transform-origin: 37% 64%; transform: scale(calc(1 + var(--p, 0) * var(--p, 0) * 5)); }
  .ready .ly-depan { transform: translateY(calc(var(--p, 0) * 60%)) scale(calc(1 + var(--p, 0) * 1.2)); }
  .ready .title-wrap { opacity: calc(1 - var(--p, 0) * 4); translate: 0 calc(var(--p, 0) * -140px); }
  .ready .terang { opacity: calc((var(--p, 0) - .5) * 2.4); }

  /* Isi yang hidup. Keadaan awal ornamen ditulis untuk bagian yang belum .tampak; geraknya berulang selama terlihat. */
  .sepeda { animation: gowes 13s linear infinite; }
  .hias-tl { animation: goyang 3.4s ease-in-out infinite alternate; } .hias-tl.kanan { animation-duration: 2.8s; animation-delay: -1.3s; }
  .js .intro:not(.tampak) .hias-tl { scale: 1 0; }
  .hias-tl { transition: scale 1.2s cubic-bezier(.3, 1.4, .5, 1) .4s, transform .9s cubic-bezier(.3, 1.5, .5, 1); }
  .js .count:not(.tampak) .ubin b { rotate: y 90deg; opacity: 0; }
  .ubin b { transition: rotate 1s cubic-bezier(.3, 1.3, .5, 1), opacity .5s ease; }
  .ubin:nth-child(2) b { transition-delay: .15s; } .ubin:nth-child(3) b { transition-delay: .3s; } .ubin:nth-child(4) b { transition-delay: .45s; }
  .ubin b::after { animation: kilap 6s 1.2s ease-in-out infinite; } .ubin:nth-child(2) b::after { animation-delay: 1.5s; } .ubin:nth-child(3) b::after { animation-delay: 1.8s; } .ubin:nth-child(4) b::after { animation-delay: 2.1s; }
  .kitiran { animation: putar 5s linear infinite; } .event:nth-of-type(2) .kitiran { animation-duration: 6.5s; animation-direction: reverse; }
  .js .story li:not(.nyala) .batang { scale: 1 0; }
  .batang { transition: scale 1.6s cubic-bezier(.3, 1.3, .5, 1) .2s, transform .9s cubic-bezier(.3, 1.5, .5, 1); }
  .chapters li.nyala .batang { animation: goyang 3.3s 1.8s ease-in-out infinite alternate; }
  .bingkai { animation: ayun 5s ease-in-out infinite alternate; } .bingkai:nth-child(3n+2) { animation-duration: 6.2s; animation-delay: -2s; } .bingkai:nth-child(3n) { animation-duration: 4.4s; animation-delay: -1s; }
  .js .gifts:not(.tampak) .sepeda-parkir { opacity: 0; translate: -80px 0; }
  .sepeda-parkir { transition: opacity .8s ease, translate 1.4s cubic-bezier(.2, .7, .2, 1); animation: bel 6s 2s ease-in-out infinite; }
  .thanks .batang { animation: tumbuh 1.8s .5s cubic-bezier(.3, 1.3, .5, 1) both, goyang 3.3s 2.4s ease-in-out infinite alternate; }
  .lembayung { animation: napas 6s ease-in-out infinite alternate; }
  .buket { animation: ayun 7s ease-in-out infinite alternate; }
}
@keyframes putar { to { rotate: 360deg; } }
@keyframes goyang { from { rotate: -3.2deg; } to { rotate: 3.2deg; } }
@keyframes napas { from { opacity: .6; } to { opacity: 1; } }
@keyframes arus { from { background-position: 0 0; } to { background-position: 68px 0; } }
@keyframes terbawa { 0% { translate: 0 0; rotate: 0deg; opacity: 0; } 8% { opacity: .9; } 50% { translate: 55vw -6vh; rotate: 260deg; } 92% { opacity: .8; } 100% { translate: 110vw 4vh; rotate: 540deg; opacity: 0; } }
@keyframes gelinding-masuk { from { opacity: 0; translate: -120% 0; rotate: -300deg; } 70% { opacity: 1; translate: 4% 0; rotate: 12deg; } to { opacity: 1; translate: 0 0; rotate: 0deg; } }
@keyframes tulis { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 -10% 0 0); } }
@keyframes muncul { from { opacity: 0; } to { opacity: 1; } }
@keyframes gowes { 0% { translate: calc(-50vw - 120px) 0; } 48% { translate: 0 0; } 52% { translate: 0 0; } 100% { translate: calc(50vw + 120px) 0; } }
@keyframes kilap { 0%, 55% { background-position: 200% 0; } 100% { background-position: -100% 0; } }
@keyframes ayun { from { rotate: -2.2deg; } to { rotate: 2.2deg; } }
@keyframes bel { 0%, 82%, 100% { rotate: 0deg; } 85% { rotate: -2deg; } 88% { rotate: 2deg; } 91% { rotate: -1.5deg; } 94% { rotate: 1deg; } }
@keyframes tumbuh { from { scale: 1 0; } to { scale: 1 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 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 .poros, .js .daun { transition: none; } }
