/* Kesatria — undangan pernikahan bertema kastel abad pertengahan, ilustrasi buku cerita bergerak: sampul foto, lalu
   gerbang kastel berhias mawar putih di seberang parit, ditutup jembatan angkat yang berdiri tegak. Saat dibuka
   jembatan rebah ke arah kamera dan turun menyeberangi parit, jeruji gerbang terangkat memperlihatkan lapangan
   turnamen, lentera menyala, lalu panji bertiup terompet tergelar membawa nama. Selama pembuka digulir kamera
   menyeberangi jembatan dan masuk lewat gerbang sampai layar memutih. Dua ksatria penjaga di kaki jembatan
   menyilangkan tombak di depan gerbang; saat digulir tombaknya diangkat tegak (silakan lewat) dan kedua penjaga
   terlewati kamera ke kiri-kanan.
   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: #f6efe2; --bg2: #fbf7ef; --ink: #2b2a33; --soft: #6b6470; --navy: #22325a; --navy2: #16213f; --crimson: #8e1f2b;
  --gold: #b8913f; --gold-hi: #e8d29a; --card: #fffbf3; --line: #e8dcc4; --sky: #f8e3b8;
  --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(--navy); }
: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(30, 30, 60, .28); } }

/* Adegan: .stage berbanding 1116:2000 (ukuran lukisan) dan selalu menutup layar; semua posisi dalam persen. Urutan
   dari belakang: latar (langit senja + lapangan turnamen) → kastel (bukaan gerbang transparan; jeruji di .lubang di
   belakangnya, lentera, kilau air, jembatan tegak dan jembatan turun di depannya) → dua penjaga. Keadaan dasar =
   gerbang terbuka dan jembatan sudah turun; sebelum dibuka (.js:not(.is-open)) jembatan masih berdiri menutup gerbang. */
.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(--sky); 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% 60%; }
.ly > img { position: absolute; max-width: none; }
.ly-bg > img, .ly-kastel > .kastel { inset: 0; width: 100%; height: 100%; }
.fx { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.mentari { position: absolute; left: 50%; top: 50%; width: 70%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; background: radial-gradient(closest-side, rgba(255, 244, 205, .8), rgba(255, 220, 150, .3) 50%, transparent); mix-blend-mode: screen; }
.bw { fill: none; stroke: #6a5a52; stroke-width: 4.4; stroke-linecap: round; stroke-linejoin: round; opacity: .55; transform-box: fill-box; transform-origin: 50% 100%; }
.burung { translate: -300px 760px; }
.ly-kastel { perspective: 1500px; perspective-origin: 50% 70%; }
.lubang { position: absolute; left: 34.83%; top: 41.64%; width: 30.6%; height: 31.87%; overflow: hidden; }
.jeruji { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; transform: translateY(-102%); }
.sinar { position: absolute; inset: 0; background: radial-gradient(70% 55% at 50% 72%, rgba(255, 236, 180, .7), transparent 70%); mix-blend-mode: screen; opacity: .7; }
.lentera { position: absolute; width: 7%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; background: radial-gradient(closest-side, rgba(255, 236, 170, .95), rgba(255, 200, 100, .35) 45%, transparent); mix-blend-mode: screen; }
.lentera.a { left: 34.9%; top: 72.9%; } .lentera.b { left: 67.7%; top: 72.9%; } .lentera.c { left: 76.6%; top: 75.1%; } .lentera.d { left: 3.3%; top: 79.1%; } .lentera.e { left: 96.6%; top: 79.1%; }
.kilau-air { position: absolute; left: 0; right: 0; top: 89%; bottom: 0; background: repeating-linear-gradient(180deg, transparent 0 9px, rgba(255, 255, 255, .22) 9px 10px, transparent 10px 23px); background-size: 140% 100%; -webkit-mask-image: linear-gradient(90deg, transparent, #000 20%, #000 80%, transparent); mask-image: linear-gradient(90deg, transparent, #000 20%, #000 80%, transparent); mix-blend-mode: screen; opacity: .6; }
.pintu { position: absolute; left: 34.3%; top: 33.4%; width: 31.6%; height: 40.6%; transform-origin: 50% 100%; transform: rotateX(-88deg); opacity: 0; }
.pintu img, .jembatan img { display: block; width: 100%; height: 100%; max-width: none; }
.jembatan { position: absolute; left: 15%; top: 79.1%; width: 70%; height: 23.9%; transform-origin: 50% 35.2%; }
/* Dua ksatria penjaga di kaki jembatan (kanan = cermin kiri). Ukuran dalam persen kotak .penjaga: gambar ksatria
   360×910, kepalan tangan di (90,5% 33%); tombak 200×1301, batangnya di 16,1% lebar dan digenggam di 55% panjangnya.
   Keadaan dasar: tombak miring 33° sehingga kedua ujungnya bersilang di depan gerbang. */
.penjaga { position: absolute; left: 11%; top: 62.2%; width: 24%; aspect-ratio: 360 / 910; }
.penjaga.r { left: auto; right: 11%; transform: scaleX(-1); }
.penjaga img { position: absolute; max-width: none; }
.penjaga .badan { inset: 0; width: 100%; height: 100%; }
.penjaga .tombak { left: 80.8%; top: -51.6%; width: 59.6%; height: 153.8%; transform-origin: 16.1% 55%; rotate: 33deg; }
.kelopak { position: absolute; inset: 0; }
.kelopak i { position: absolute; top: -4%; width: 10px; height: 8px; border-radius: 70% 0 70% 0; background: #c43a46; display: none; }
.kelopak i:nth-child(3n) { background: #fff7ef; } .kelopak i:nth-child(4n) { background: #e9b9b9; } .kelopak i:nth-child(7n) { width: 6px; height: 6px; border-radius: 1px; background: var(--gold-hi); }
.kelopak i:nth-child(1) { left: 76%; animation-duration: 11.2s, 3.6s; animation-delay: -12.6s, -2.6s; }
.kelopak i:nth-child(2) { left: 56%; animation-duration: 12.9s, 4s; animation-delay: -1.7s, -1.9s; }
.kelopak i:nth-child(3) { left: 45%; animation-duration: 12.4s, 2.4s; animation-delay: -3.3s, -1.1s; }
.kelopak i:nth-child(4) { left: 17%; animation-duration: 9.8s, 3.5s; animation-delay: -1.9s, 0s; }
.kelopak i:nth-child(5) { left: 23%; animation-duration: 14.8s, 2.7s; animation-delay: -2.5s, -1.3s; }
.kelopak i:nth-child(6) { left: 66%; animation-duration: 10.2s, 4.1s; animation-delay: -10.4s, -3.9s; }
.kelopak i:nth-child(7) { left: 35%; animation-duration: 11.5s, 4.1s; animation-delay: -4s, -1.3s; }
.kelopak i:nth-child(8) { left: 73%; animation-duration: 11s, 3s; animation-delay: -12.3s, -1.9s; }
.kelopak i:nth-child(9) { left: 8%; animation-duration: 13.2s, 2.5s; animation-delay: -14.6s, -.1s; }
.kelopak i:nth-child(10) { left: 48%; animation-duration: 13.7s, 3.1s; animation-delay: -8.7s, 0s; }
.kelopak i:nth-child(11) { left: 87%; animation-duration: 14.7s, 2.8s; animation-delay: -11.3s, -3.7s; }
.kelopak i:nth-child(12) { left: 41%; animation-duration: 14.4s, 2.9s; animation-delay: -6.9s, -2.4s; }
.kelopak i:nth-child(13) { left: 29%; animation-duration: 14.7s, 2.6s; animation-delay: -5.1s, -2.4s; }
.kelopak i:nth-child(14) { left: 60%; animation-duration: 12.3s, 3s; animation-delay: -4.8s, -.7s; }
.kelopak i:nth-child(15) { left: 93%; animation-duration: 10.9s, 3.4s; animation-delay: -7.2s, -1.2s; }
.kelopak i:nth-child(16) { left: 3%; animation-duration: 12.1s, 2.9s; animation-delay: -9.9s, -2s; }
.terang { position: absolute; inset: 0; background: radial-gradient(circle at 50% 56%, #fffdf6 0, #fff6e4 55%, var(--bg) 100%); opacity: 0; }

/* Pembukaan: jembatan tegak rebah ke arah kamera (0,6–1,7 dtk) → jembatan turun menyeberangi parit dan memantul
   (1,6–2,9) → jeruji gerbang terangkat (2,6–4,6), cahaya lapangan turnamen masuk → pandangan sedikit mundur
   (0,8–4,8) → panji judul tergelar dari terompet (4,6). */
.js .pintu { transition: transform 1.1s cubic-bezier(.55, 0, .9, .5) .6s, opacity .15s linear 1.6s; }
.js .jembatan { transition: transform 1.3s cubic-bezier(.25, 1.35, .45, 1) 1.6s, opacity .1s linear 1.6s; }
.js .jeruji { transition: transform 2s cubic-bezier(.5, 0, .3, 1) 2.6s; }
.js .sinar { transition: opacity 1.6s ease 3.2s; }
.js .ly { transition: transform 4s cubic-bezier(.5, 0, .2, 1) .8s; }
.js .penjaga .tombak { transition: rotate 1.1s cubic-bezier(.5, -.4, .35, 1.35) 3.1s; }
.js .penjaga.r .tombak { transition-delay: 3.35s; }
.js:not(.is-open) .pintu { transform: none; opacity: 1; }
.js:not(.is-open) .jembatan { transform: rotateX(82deg); opacity: 0; }
.js:not(.is-open) .jeruji { transform: none; }
.js:not(.is-open) .sinar { opacity: 0; }
.js:not(.is-open) .ly { transform: scale(1.07) translateY(2.5%); }
.js:not(.is-open) .penjaga .tombak { rotate: 0deg; }
.js.no-anim .pintu, .js.no-anim .jembatan, .js.no-anim .jeruji, .js.no-anim .sinar, .js.no-anim .ly, .js.no-anim .penjaga .tombak { transition: none; }

.caps { font: 500 13px/1.4 var(--display); letter-spacing: .3em; text-transform: uppercase; }
.script { font: 400 50px/1.1 var(--script); color: var(--crimson); }
.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(--navy); border-radius: 4px; background: var(--navy); color: #fff8ea; text-decoration: none; cursor: pointer; font: 600 13px/1 var(--display); letter-spacing: .2em; text-transform: uppercase; box-shadow: inset 0 0 0 3px var(--navy), inset 0 0 0 4px rgba(232, 210, 154, .7); }
.btn-line { background: transparent; color: inherit; border-color: currentColor; box-shadow: none; }
.btn.copied { background: var(--gold); border-color: var(--gold); color: #fff; }

/* ---------- Sampul ---------- */
.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: radial-gradient(90% 60% at 50% 35%, var(--bg2), var(--bg) 60%, #ead9b8); 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(14, 18, 36, .58) 0%, rgba(14, 18, 36, .05) 34%, rgba(14, 18, 36, .1) 56%, rgba(14, 18, 36, .8) 100%); }
.cover.has-photo .cover-art { display: none; }
.cover-art { position: absolute; inset: 0; }
.cover-pedang { position: absolute; left: 50%; top: 13vh; width: 150px; translate: -50% 0; }
.cover-rangkai { position: absolute; left: 50%; bottom: 25%; width: 82%; max-width: none; translate: -50% 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: break-word; }
.names .amp { margin: 0 .25em; font: 400 40px/1 var(--script); text-transform: none; letter-spacing: 0; color: var(--gold); }
.cover:not(.has-photo) .cover-top { margin-top: 30vh; }
.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, .6); background: rgba(255, 255, 255, .2); color: inherit; box-shadow: none; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.cover:not(.has-photo) .open { border-color: var(--navy); background: var(--navy); color: #fff8ea; }
.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; }
.memuat .cover .open { pointer-events: none; opacity: .55; }

/* ---------- Pembuka: judul di panji gading yang tergantung dari dua terompet (judul.webp, teks HTML di atasnya) ---------- */
.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(--sky), var(--bg)); }
.js .hero { background: none; display: block; padding: 0; }
.hero-pin { display: grid; place-items: start center; width: 100%; position: relative; }
.js .hero-pin { position: fixed; left: 50%; bottom: 0; width: min(100%, 480px); height: 100vh; height: 100svh; translate: -50% 0; padding: 4vh 0 0; pointer-events: none; overflow: hidden; }
.scene-off .hero-pin { visibility: hidden; }
.title-wrap { width: min(88%, 360px); }
.panji-judul { position: relative; transform-origin: 50% 0; }
.panji-judul > img { display: block; width: 100%; height: auto; max-width: none; }
.panji-t { position: absolute; left: 17%; right: 17%; top: 29%; bottom: 31%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; text-align: center; container-type: inline-size; }
.panji-t .caps { font-size: max(7px, 4.6cqw); letter-spacing: .24em; color: var(--soft); }
.t-name { font: 400 max(22px, 12.5cqw)/1.05 var(--script); color: var(--crimson); overflow-wrap: break-word; max-width: 100%; }
.t-name .amp { font: italic 500 .62em var(--serif); color: var(--gold); vertical-align: .12em; }
.pl-date { margin-top: 3px; font: 600 max(8px, 4.8cqw)/1.3 var(--display); letter-spacing: .14em; text-transform: uppercase; color: var(--navy); }
.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; }
.hero-pin > .mouse { position: absolute; left: 50%; bottom: 4vh; margin: 0 0 0 -11px; border-color: #fff; opacity: .9; }
.hero-pin > .mouse::after { background: #fff; }
html:not(.js) .hero-pin { padding: 40px 0; } html:not(.js) .hero-pin > .mouse { display: none; }

/* ---------- Isi: latar lapangan turnamen tetap di belakang (.latar-isi, muncul setelah pembuka lewat), bagian krem
   tembus pandang di tepi, ornamen kerajaan per bagian. ---------- */
.latar-isi { position: fixed; top: 0; left: 50%; width: min(100%, 480px); height: 100%; translate: -50% 0; z-index: 0; overflow: hidden; contain: strict; pointer-events: none; background: var(--bg); transition: opacity 1.2s ease; }
.latar-isi img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; object-position: 50% 62%; }
.li-kabut { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(246, 239, 226, .35), rgba(246, 239, 226, .1) 40%, rgba(246, 239, 226, .55)); }
.js:not(.scene-off) .latar-isi { opacity: 0; }
.orn { pointer-events: none; max-width: none; }
main > section:not(.hero) { position: relative; padding: 64px 28px; display: flex; flex-direction: column; align-items: center; gap: 20px; text-align: center; overflow: hidden; background: linear-gradient(90deg, rgba(246, 239, 226, .2), rgba(251, 247, 239, .88) 16%, rgba(251, 247, 239, .88) 84%, rgba(246, 239, 226, .2)); }
main h2.script::after { content: ""; display: block; width: 240px; max-width: 76vw; height: 20px; margin: 6px auto 0; background: url("img/pembatas.webp") center / contain no-repeat; }

/* Kutipan: untaian mawar di atas, kutipan di antara dua garis emas. */
.rangkai-atas { width: 300px; margin: -24px auto -10px; }
.quote { font: italic 500 21px/1.6 var(--serif); max-width: 20em; padding: 18px 6px; border-top: 1px solid var(--gold); border-bottom: 1px solid var(--gold); }
.source { font: 600 14px/1.4 var(--display); letter-spacing: .14em; color: var(--navy); }

/* Mempelai: foto di dalam perisai lambang (foto dipotong berbentuk perisai lewat mask), nama di pita merah. */
.couple { display: flex; flex-direction: column; align-items: center; gap: 6px; width: 100%; margin-top: 6px; }
.person { display: flex; flex-direction: column; align-items: center; gap: 6px; width: 100%; }
.perisai { position: relative; width: 230px; aspect-ratio: 420 / 557; }
.perisai-b { position: absolute; inset: 0; width: 100%; height: 100%; }
.portrait { position: absolute; left: 10%; right: 10%; top: 10%; bottom: 7%; overflow: hidden; background: var(--bg2); -webkit-mask: url("img/perisai.webp") center / 100% 100% no-repeat; mask: url("img/perisai.webp") center / 100% 100% no-repeat; display: flex; }
.portrait > * { flex: 1; width: 100%; height: 100%; object-fit: cover; }
.portrait span { display: flex; align-items: center; justify-content: center; font: 400 96px/1 var(--script); color: var(--navy); background: radial-gradient(circle at 50% 40%, #fff, var(--gold-hi)); }
.pita { position: relative; z-index: 0; margin-top: -26px; padding: 8px 30px 10px; background: var(--crimson); color: #fff8ea; font: 400 32px/1.15 var(--script); max-width: 92%; overflow-wrap: anywhere; box-shadow: 0 8px 16px rgba(60, 20, 20, .2); }
.pita::before, .pita::after { content: ""; position: absolute; top: 10px; bottom: -10px; width: 22px; background: #6e1520; }
.pita::before { left: -22px; clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 40% 50%); } .pita::after { right: -22px; clip-path: polygon(0 0, 100% 0, 60% 50%, 100% 100%, 0 100%); }
.pita span { display: block; }
.parents { font-size: 17px; line-height: 1.45; color: var(--soft); max-width: 17em; margin-top: 6px; }
.ig { font: 600 14px/1.4 var(--display); letter-spacing: .08em; color: var(--navy); }
.dan { margin: 14px 0 6px; } .dan img { width: 96px; margin: 0 auto; }

/* Save the Date: tembok batu biru malam, angka di empat perisai kecil. */
main > section.count, main > section.rsvp { color: #fff8ea; background: linear-gradient(180deg, rgba(22, 33, 63, 0), rgba(22, 33, 63, .92) 90px, rgba(22, 33, 63, .94) calc(100% - 90px), rgba(22, 33, 63, 0)), repeating-linear-gradient(0deg, transparent 0 38px, rgba(255, 255, 255, .05) 38px 40px), var(--navy2); background-clip: padding-box; }
main > section.count { background: linear-gradient(180deg, rgba(246, 239, 226, .6), rgba(22, 33, 63, .94) 90px, rgba(22, 33, 63, .94) calc(100% - 90px), rgba(246, 239, 226, .6)), linear-gradient(90deg, rgba(255, 255, 255, .05) 1px, transparent 1px) 0 0 / 64px 40px, linear-gradient(0deg, rgba(255, 255, 255, .05) 1px, transparent 1px) 0 0 / 64px 40px; padding-top: 110px; padding-bottom: 110px; }
.count .script, .rsvp .script { color: var(--gold-hi); } .count .lead { color: #e8e2d6; }
.countdown { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; width: 100%; }
.countdown div { position: relative; aspect-ratio: 5 / 6; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; padding-bottom: 14%; background: linear-gradient(180deg, var(--crimson), #6e1520); clip-path: polygon(0 0, 100% 0, 100% 52%, 50% 100%, 0 52%); }
.countdown div:nth-child(even) { background: linear-gradient(180deg, #2f4680, var(--navy)); }
.countdown div::before { content: ""; position: absolute; inset: 4px; border: 2px solid var(--gold-hi); clip-path: polygon(0 0, 100% 0, 100% 52%, 50% 100%, 0 52%); }
.countdown b { font: 600 26px/1.1 var(--display); font-variant-numeric: tabular-nums; color: #fff8ea; }
.countdown span { font: 600 10px/1.4 var(--display); letter-spacing: .14em; text-transform: uppercase; color: var(--gold-hi); }
html:not(.js) .countdown { display: none; }
.count .btn-line { color: var(--gold-hi); border-color: var(--gold-hi); }

/* Acara: gulungan perkamen bersegel lilin (perkamen.webp sebagai latar kartu). */
main > section.programme { gap: 30px; }
.event { width: min(100%, 340px); padding: 74px 42px 104px; background: url("img/perkamen.webp") center / 100% 100% no-repeat; display: flex; flex-direction: column; align-items: center; gap: 10px; transform-origin: 50% 0; }
.event .script { font-size: 40px; } .event h2.script::after { width: 170px; }
.when { font: 600 18px/1.5 var(--serif); color: var(--navy); }
.where { font-size: 16px; line-height: 1.5; color: var(--soft); overflow-wrap: anywhere; }
.where b { display: block; font: 600 11px/1.6 var(--display); letter-spacing: .2em; text-transform: uppercase; color: var(--ink); }
.event .btn { min-height: 42px; padding: 0 20px; }
.dress { font-size: 17px; font-style: italic; color: var(--soft); }

/* Kisah: peta kerajaan — jalur bertitik merah, tiap bab ditandai bendera kecil. */
main > section.story { background: linear-gradient(90deg, rgba(246, 239, 226, .2), rgba(245, 233, 205, .92) 14%, rgba(245, 233, 205, .92) 86%, rgba(246, 239, 226, .2)); }
.chapters { list-style: none; padding: 0 0 0 52px; position: relative; width: 100%; display: flex; flex-direction: column; gap: 26px; text-align: left; }
.chapters::before { content: ""; position: absolute; left: 22px; top: 10px; bottom: 10px; border-left: 3px dotted var(--crimson); }
.chapters li { position: relative; padding: 16px 18px; border-radius: 4px; background: rgba(255, 251, 243, .9); border: 1px solid var(--gold-hi); box-shadow: 0 8px 18px rgba(60, 45, 20, .1); }
.bendera { position: absolute; left: -50px; top: -14px; width: 40px; }
.chapters h3 { font: 600 17px/1.3 var(--display); letter-spacing: .08em; text-transform: uppercase; color: var(--navy); margin-bottom: 4px; }
.chapters p { font-size: 17px; line-height: 1.55; color: var(--soft); }

/* Galeri: jendela kaca patri melengkung berbingkai biru-emas. */
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 12px; width: 100%; }
.grid img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; border-radius: 999px 999px 6px 6px / 46% 46% 6px 6px; border: 5px solid var(--navy); outline: 2px solid var(--gold); outline-offset: -9px; box-shadow: 0 0 0 2px var(--gold-hi), 0 12px 22px rgba(30, 30, 60, .18); }
.grid img:nth-child(3n+1) { grid-column: 1 / -1; aspect-ratio: 4 / 3; border-radius: 999px 999px 6px 6px / 60% 60% 6px 6px; }

/* Amplop: peti harta di atas, kartu bergaris emas. */
.peti { width: 140px; margin: -10px auto -14px; }
.gift-list { display: grid; gap: 12px; width: 100%; }
.gift-card { position: relative; padding: 16px 18px 16px 26px; border-radius: 4px; background: var(--card); border: 1px solid var(--gold-hi); display: flex; align-items: center; justify-content: space-between; gap: 12px; text-align: left; overflow: hidden; }
.gift-card::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 8px; background: linear-gradient(180deg, var(--crimson) 0 50%, var(--navy) 50%); }
.bank { font: 600 12px/1.4 var(--display); letter-spacing: .22em; text-transform: uppercase; color: var(--crimson); }
.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: 40px; padding: 0 16px; color: var(--navy); }
.address { width: 100%; padding: 14px 16px; border-radius: 4px; border: 1px dashed var(--gold); font-size: 16px; line-height: 1.5; color: var(--soft); text-align: left; background: rgba(255, 251, 243, .8); }

/* Ucapan */
.note { width: 100%; padding: 14px 16px; border: 1px dashed rgba(255, 255, 255, .7); border-radius: 6px; font-size: 16px; }
.thanks { width: 100%; padding: 22px 18px; border-radius: 6px; background: rgba(255, 255, 255, .14); 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: 4px; background: #fffbf3; 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: 4px; font: 600 13px/1 var(--display); letter-spacing: .14em; text-transform: uppercase; }
.opt input:checked + span { background: var(--gold-hi); border-color: var(--gold-hi); color: var(--navy2); }
.opt input:focus-visible + span { outline: 2px solid var(--gold-hi); outline-offset: 2px; }
.rsvp .btn { min-height: 50px; background: var(--gold-hi); border-color: var(--gold-hi); color: var(--navy2); box-shadow: none; }
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(--crimson); }
.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: 4px; 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(--navy); }
.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); }

/* Penutup: pedang bersilang di bawah mahkota, buket pengantin. */
main > section.closing { padding-top: 70px; background: linear-gradient(180deg, rgba(251, 247, 239, .3), rgba(251, 247, 239, .85) 40%, #f1e4c8); }
.pedang-tutup { width: 150px; }
.closing .buket { width: 170px; margin-top: -40px; }
.merci { font-size: 38px; white-space: nowrap; }
.thanks-line { font-size: 17px; font-style: italic; color: var(--soft); max-width: 20em; }
.pl-name { font: 500 22px/1.3 var(--display); letter-spacing: .14em; text-transform: uppercase; color: var(--navy); }
footer { position: relative; padding: 18px 16px 26px; text-align: center; font-size: 14px; color: var(--soft); background: #f1e4c8; }

.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(--navy); color: #fff; cursor: pointer; box-shadow: 0 8px 18px rgba(30, 30, 60, .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 ---------- */
.rv { opacity: 0; translate: 0 26px; }
.rv.script { translate: 0 -22px; }
.couple > .rv.person { translate: 0 0; scale: .8; } .countdown .rv { translate: 0 -40px; } .rv.event { translate: 0 0; scale: 1 .2; } .grid .rv { scale: .86; translate: 0 0; } .chapters .rv { translate: -30px 0; }
.rv.in { opacity: 1; translate: 0 0; scale: 1; transition: opacity 1s ease calc(var(--d, 0) * 1ms), translate 1.2s cubic-bezier(.22, 1, .36, 1) calc(var(--d, 0) * 1ms), scale 1.2s cubic-bezier(.22, 1, .36, 1) calc(var(--d, 0) * 1ms); }
.countdown .rv.in { transition-timing-function: ease, cubic-bezier(.3, 1.5, .5, 1), ease; }
@media (prefers-reduced-motion: no-preference) {
  /* Berulang: kelopak mawar dan konfeti emas, merpati melintas, lentera berkedip, kilau air parit, penjaga bernapas,
     penjaga bernapas, panji judul berayun. */
  .kelopak i { display: block; animation-name: gugur, kibar; animation-timing-function: linear, ease-in-out; animation-iteration-count: infinite; animation-direction: normal, alternate; }
  .burung { animation: lintas 26s 3s linear infinite; } .bw { animation: sayap .45s ease-in-out infinite alternate; } .bw.b2 { animation-delay: -.2s; } .bw.b3 { animation-delay: -.3s; }
  .mentari { animation: napas 5s ease-in-out infinite alternate; }
  .lentera { animation: kedip 1.4s ease-in-out infinite alternate; } .lentera.b, .lentera.d { animation-duration: 1.9s; animation-delay: -.6s; } .lentera.c { animation-duration: 1.1s; animation-delay: -.3s; }
  .kilau-air { animation: riak 7s linear infinite; }
  .penjaga .badan { animation: napas2 4s ease-in-out infinite alternate; } .penjaga.r .badan { animation-delay: -1.7s; }
  .panji-judul { animation: ayun 6s ease-in-out infinite; }
  .js.is-open:not(.no-anim) .panji-judul { animation: gelar 1.6s 4.6s cubic-bezier(.3, .9, .4, 1) both, ayun 6s 6.2s ease-in-out infinite; }
  .js.is-open:not(.no-anim) .panji-t { animation: naik 1s 5.6s both; }
  .js.is-open:not(.no-anim) .hero-pin > .mouse { animation: naik 1s 6.2s both; }
  .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; }
  .cover-pedang { animation: turun 1.4s .1s both; }
  .closing .buket { animation: ayun 7s ease-in-out infinite; transform-origin: 50% 10%; }
}
@keyframes gugur { from { translate: 0 0; } to { translate: 70px 112vh; } }
@keyframes kibar { from { rotate: -50deg; scale: 1 1; } to { rotate: 190deg; scale: .4 1; } }
@keyframes lintas { from { translate: -300px 760px; } to { translate: 1800px 420px; } }
@keyframes sayap { from { scale: 1 1; } to { scale: 1 -.6; } }
@keyframes napas { from { opacity: .75; scale: .96; } to { opacity: 1; scale: 1.04; } }
@keyframes napas2 { from { translate: 0 0; } to { translate: 0 -.6%; } }
@keyframes kedip { from { opacity: .55; scale: .9; } to { opacity: 1; scale: 1.08; } }
@keyframes riak { from { background-position: 0 0; } to { background-position: 140% 0; } }
@keyframes gelar { from { clip-path: inset(0 0 88% 0); opacity: 0; } 15% { opacity: 1; } to { clip-path: inset(0 0 -4% 0); opacity: 1; } }
@keyframes ayun { 0%, 100% { rotate: -1.2deg; } 50% { rotate: 1.2deg; } }
@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(232, 210, 154, 0); } 50% { box-shadow: 0 0 0 9px rgba(232, 210, 154, .25); } }
@keyframes gulir { 0% { translate: 0 0; opacity: 1; } 70% { translate: 0 12px; opacity: 0; } 100% { translate: 0 0; opacity: 0; } }
@keyframes kibarBendera { from { rotate: -6deg; } to { rotate: 6deg; } }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } .rv { opacity: 1; translate: none; scale: none; } *, *::before, *::after { animation: none !important; } .js .ly, .js .pintu, .js .jembatan, .js .jeruji, .js .sinar, .js .penjaga .tombak { transition: none; } }

@media (prefers-reduced-motion: no-preference) {
  .js .hero { min-height: 260vh; min-height: 260svh; }
  /* Perjalanan gulir: --p (0→1) dipasang kesatria.js setelah pembukaan; di p = 0 sama dengan keadaan akhir pembukaan.
     Kamera menyeberangi jembatan dan masuk lewat gerbang (titik 50% 57,6% = tengah bukaan gerbang). Urutannya:
     tombak penjaga diangkat tegak (p 0–0,16) → penjaga (paling dekat kamera) terlewati ke kiri-kanan sambil membesar
     (--q, p 0,08–0,4). */
  .ready .ly { transition: none; }
  .js.is-open.ready .ly-bg { transform: scale(calc(1 + var(--p, 0) * .6)); }
  .js.is-open.ready .ly-kastel { transform-origin: 50% 57.6%; transform: scale(calc(1 + var(--p, 0) * var(--p, 0) * 3.6)); opacity: calc(1 - (var(--p, 0) - .55) * 4); }
  .ready .penjaga .tombak { transition: none; rotate: calc((1 - clamp(0, calc(var(--p, 0) / .16), 1)) * 33deg); }
  .js.is-open.ready .ly-penjaga { transform: none; }
  .ready .penjaga { --q: clamp(0, calc((var(--p, 0) - .08) / .32), 1); transform-origin: 50% 100%; translate: calc(var(--q) * (var(--q) + 1) * -95%) calc(var(--q) * 10%); scale: calc(1 + var(--q) * .7); }
  .ready .penjaga.r { translate: calc(var(--q) * (var(--q) + 1) * 95%) calc(var(--q) * 10%); }
  .ready .title-wrap { opacity: calc(1 - var(--p, 0) * 5); translate: 0 calc(var(--p, 0) * -140px); }
  .ready .hero-pin > .mouse { opacity: calc(.9 - var(--p, 0) * 6); }
  .ready .terang { opacity: calc((var(--p, 0) - .68) * 3.4); }
  .ready .kelopak { opacity: calc(1 - var(--p, 0) * 2.5); }

  /* Ornamen isi (.tampak dipasang kesatria.js saat bagian/elemen masuk layar; keadaan dasar = sudah tampil). */
  .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; }
  .perisai { transition: transform 1.2s cubic-bezier(.3, 1.2, .4, 1); }
  .gerak .person:not(.tampak) .perisai { transform: perspective(800px) rotateY(90deg); }
  .pita { transition: clip-path 1s ease .7s; clip-path: inset(-20px -30px); }
  .gerak .person:not(.tampak) .pita { clip-path: inset(-20px 50% -20px 50%); }
  .event { transition: clip-path 1.4s cubic-bezier(.5, 0, .2, 1) .1s; clip-path: inset(0); }
  .gerak .event:not(.tampak) { clip-path: inset(0 0 82% 0); }
  .bendera { transform-origin: 20% 100%; animation: kibarBendera 1.8s ease-in-out infinite alternate; }
  .gerak .chapters li:not(.tampak) .bendera { scale: 0; }
  .chapters li .bendera { transition: scale .7s cubic-bezier(.3, 1.6, .4, 1) .3s; }
  .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); }
  .peti { transition: translate 1s cubic-bezier(.3, 1.4, .4, 1), opacity .6s ease; }
  .gerak .gifts:not(.tampak) .peti { translate: 0 40px; opacity: 0; }
  .pedang-tutup { transition: scale 1.2s cubic-bezier(.3, 1.4, .4, 1), rotate 1.2s cubic-bezier(.3, 1.4, .4, 1), opacity .6s ease; }
  .gerak .closing:not(.tampak) .pedang-tutup { scale: .3; rotate: -90deg; opacity: 0; }
}
.js body.locked { overflow: visible; }

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