/* ==========================================================================
   Undangan Fury & Yolla — tampilan
   Semua ukuran di dalam dunia diturunkan dari --lp ("satu piksel gambar"),
   jadi satu aturan saja sudah membuat mobile dan desktop konsisten.
   ========================================================================== */

/* Huruf pixel "Determination" — FontStruct, lisensi CC-BY 3.0.
   Berkas lisensi ikut disertakan di assets/font/. */
@font-face {
  font-family: "Determination";
  src: url("../assets/font/determination.ttf?v=9") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  --vh: 1vh;
  --land-h: calc(84 * var(--vh));     /* tinggi gambar desa            */
  --lp: calc(var(--land-h) / 400);    /* 1 piksel gambar dalam CSS     */
  --ground: calc(var(--lp) * 130);    /* jarak garis tanah dari bawah  */
  --char-x: 32%;                      /* posisi tokoh di layar         */

  --cream: #fcf6ea;
  --cream-2: #f2e8d5;
  --ink: #2f2833;
  --ink-2: #6b6070;
  --gold: #e0b25c;
  --gold-d: #b98d3c;
  --rose: #ef9db1;
  --rose-d: #cf6f8d;
  --leaf: #5f9f4a;
  --leaf-d: #477a37;
  --panel: #f5e8c8;
  --panel-sh: #ded0a6;
  --panel-ln: #78582f;

  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia,
           "Times New Roman", serif;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
          Arial, sans-serif;
  /* huruf permainan: judul, papan misi, tombol, label benda */
  --pixel: "Determination", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --shadow: 0 .28rem 0 rgba(47, 40, 51, .22);
  --card-r: 1.1rem;
}
@supports (height: 1dvh) { :root { --vh: 1dvh; } }

@media (orientation: landscape) and (min-width: 900px) {
  :root { --land-h: calc(88 * var(--vh)); --char-x: 26%; }
}
@media (max-width: 380px) { :root { --char-x: 30%; } }

* { box-sizing: border-box; }

/* `display` di aturan lain akan mengalahkan atribut hidden — kunci di sini */
[hidden] { display: none !important; }

html { background: #8ec8e6; }

body {
  margin: 0;
  font-family: var(--sans);
  color: var(--ink);
  background: #8ec8e6;
  overscroll-behavior-y: none;
  -webkit-text-size-adjust: 100%;
}
body.locked { overflow: hidden; height: 100%; }

/* ── gambar tidak boleh bisa ditekan-lama lalu disimpan ──────────────────
   Di Android, menahan sebuah <img> memunculkan menu "Simpan gambar /
   Cari dengan Lens" dan itu merusak rasa permainannya. Semua gambar di
   dalam dunia dikunci; teks di dalam dialog tetap bisa disorot dan disalin
   supaya nomor rekening dan alamat masih bisa diambil tamu. */
img {
  display: block;
  max-width: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
  user-select: none;
  -webkit-user-select: none;
  pointer-events: none;
}
#world, #loader, #modal {
  -webkit-touch-callout: none;
  user-select: none;
  -webkit-user-select: none;
}
.modal-body { user-select: text; -webkit-user-select: text; }
.modal-body .d-bank .no, .modal-body p { -webkit-touch-callout: default; }

.pixel, #land, #bg-img, #character img, #objects img, .dpad,
.loader-heart, .q-icon, .avatar img, .t-love, #quest-size {
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  image-rendering: crisp-edges;
}

/* ── panggung ───────────────────────────────────────────────────────────── */
#world {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 1;
}

#bg {
  position: absolute;
  left: 0; top: 0;
  height: 100%;
  width: 100%;
  overflow: hidden;
}
/* Skala pikselnya disamakan dengan landgame.png: 552 baris × --lp.
   `min-width` adalah jaring pengaman: bg.png sudah cukup lebar untuk layar
   sampai rasio 3,15:1, tapi di jendela yang lebih ekstrem dari itu langitnya
   melar sedikit — jauh lebih baik daripada tepi kanannya habis dan warna
   dasar halaman menyembul sebagai garis tegak. */
#bg-img {
  height: calc(116 * var(--vh));
  width: auto;
  min-width: 100%;
  position: absolute;
  left: 0;
  top: calc(-11 * var(--vh));
  opacity: .96;
  will-change: transform;
}

#frame {
  position: absolute;
  left: 0;
  bottom: 0;
  height: var(--land-h);
  will-change: transform;
}
#land { height: 100%; width: auto; }

#objects { position: absolute; inset: 0; }

/* setiap benda berdiri di garis tanah yang sama */
.obj {
  position: absolute;
  bottom: var(--ground);
  transform: translateX(-50%);
  pointer-events: none;
}
.obj > img { height: 100%; width: auto; }
.obj.aksi { pointer-events: auto; cursor: pointer; }
.obj.aksi::after {
  content: "";
  position: absolute;
  left: 50%; bottom: 0;
  width: calc(var(--lp) * 46);
  height: calc(var(--lp) * 60);
  transform: translateX(-50%);
}

/* Benda yang bisa disapa diberi garis tepi. Dari jauh tipis saja; begitu
   tamu mendekat, garisnya menebal dan namanya muncul — jadi jelas mana yang
   bisa ditekan tanpa perlu menebak. */
.obj.aksi > img.body {
  filter:
    drop-shadow(var(--lp) 0 0 rgba(44, 38, 46, .55))
    drop-shadow(calc(var(--lp) * -1) 0 0 rgba(44, 38, 46, .55))
    drop-shadow(0 var(--lp) 0 rgba(44, 38, 46, .55))
    drop-shadow(0 calc(var(--lp) * -1) 0 rgba(44, 38, 46, .55));
  transition: filter .2s;
}
.obj.aksi.dekat > img.body {
  filter:
    drop-shadow(var(--lp) 0 0 #2c262e) drop-shadow(calc(var(--lp) * -1) 0 0 #2c262e)
    drop-shadow(0 var(--lp) 0 #2c262e) drop-shadow(0 calc(var(--lp) * -1) 0 #2c262e)
    drop-shadow(var(--lp) 0 0 #2c262e) drop-shadow(calc(var(--lp) * -1) 0 0 #2c262e)
    drop-shadow(0 var(--lp) 0 #2c262e) drop-shadow(0 calc(var(--lp) * -1) 0 #2c262e);
}

/* gelembung "!" saat masih jauh, papan nama saat sudah dekat */
.bubble, .obj-nama {
  position: absolute;
  left: 50%; bottom: 100%;
  transform: translate(-50%, .4rem) scale(.6);
  opacity: 0;
  transition: transform .28s cubic-bezier(.2, 1.5, .4, 1), opacity .22s;
}
.bubble { width: calc(var(--lp) * 22); }
.obj-nama {
  white-space: nowrap;
  font: 400 calc(var(--lp) * 11)/1 var(--pixel);
  color: var(--ink);
  background: var(--panel);
  border: calc(var(--lp) * 1.6) solid var(--panel-ln);
  box-shadow: 0 calc(var(--lp) * 1.6) 0 rgba(44, 38, 46, .3);
  padding: calc(var(--lp) * 4) calc(var(--lp) * 6) calc(var(--lp) * 3);
  /* duduk di atas papan nama tamu, yang tingginya sekitar 48 piksel gambar */
  margin-bottom: calc(var(--lp) * 16);
  z-index: 8;
}
.obj.dekat .bubble { opacity: 0; }
.obj:not(.dekat) .bubble { opacity: 1; transform: translate(-50%, -.35rem) scale(1); }
.obj.dekat .obj-nama { opacity: 1; transform: translate(-50%, -.1rem) scale(1); }

/* Penerima tamu: papan namanya menyala terus dan tidak pernah pakai "!",
   karena tugas mereka justru terlihat dari jauh. */
.obj.penerima .bubble { display: none; }
.obj.penerima .obj-nama {
  opacity: 1;
  transform: translate(-50%, -.1rem) scale(1);
  padding: calc(var(--lp) * 4) calc(var(--lp) * 5) calc(var(--lp) * 3);
  margin-bottom: calc(var(--lp) * 6);
}
.obj.penerima.label-tinggi .obj-nama { margin-bottom: calc(var(--lp) * 40); }
/* tali kecil dari papan yang dinaikkan ke kepala pemiliknya */
.obj.penerima.label-tinggi .obj-nama::after {
  content: "";
  position: absolute;
  left: 50%; top: 100%;
  width: calc(var(--lp) * 2);
  height: calc(var(--lp) * 32);
  transform: translateX(-50%);
  background: var(--panel-ln);
}
.obj.penerima .obj-nama b {
  display: block; font-weight: 400; text-align: center;
  font-size: calc(var(--lp) * 11);
}
.obj.penerima .obj-nama i {
  display: block; font-style: normal; text-align: center;
  font-size: calc(var(--lp) * 7);
  letter-spacing: .04em;
  color: var(--gold-d);
}
/* garis tepinya sudah tebal sejak awal, bukan hanya saat didekati */
.obj.penerima > img.body {
  filter:
    drop-shadow(var(--lp) 0 0 #2c262e) drop-shadow(calc(var(--lp) * -1) 0 0 #2c262e)
    drop-shadow(0 var(--lp) 0 #2c262e) drop-shadow(0 calc(var(--lp) * -1) 0 #2c262e);
}
.obj.penerima.dekat > img.body { animation: sapa 1.1s ease-in-out infinite; }
@keyframes sapa {
  0%, 100% { transform: translateY(0) rotate(0); }
  50% { transform: translateY(calc(var(--lp) * -3)); }
}
.obj.dekat > img.body { animation: nudge .9s ease-in-out infinite; }
.obj.selesai .bubble { display: none; }

@keyframes nudge {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(calc(var(--lp) * -2)); }
}

/* Papan nama mempelai di tepi jalan. Empat baris duduk di dalam panel krem
   setinggi 42 piksel gambar: nama, hati, nama, tanggal. */
.obj .sign-text {
  position: absolute;
  left: 50%;
  top: calc(var(--lp) * 11);
  transform: translateX(-50%);
  width: calc(var(--lp) * 56);
  text-align: center;
  font-family: var(--pixel);
  line-height: 1;
  color: var(--ink);
}
.sign-text b { display: block; font-size: calc(var(--lp) * 11); font-weight: 400; }
.sign-love {
  display: block;
  height: calc(var(--lp) * 8);
  width: auto;
  margin: calc(var(--lp) * 1) auto;
}
.sign-text small {
  display: block;
  margin-top: calc(var(--lp) * 1);
  font-size: calc(var(--lp) * 6);
  color: var(--gold-d);
}

/* makhluk kecil: ayam, kupu-kupu, merpati, kucing — dua bingkai, berkeliaran */
.critter .cbody {
  width: 100%; height: 100%;
  background-repeat: no-repeat;
  background-size: 200% 100%;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  animation: cframes .42s steps(2) infinite,
             patrol var(--patrol, 5s) ease-in-out infinite alternate;
}
.critter.float .cbody { animation-name: cframes, bob; }
@keyframes cframes {
  from { background-position-x: 0; }
  to   { background-position-x: -200%; }
}
@keyframes patrol {
  from { transform: translateX(calc(var(--lp) * -14)); }
  to   { transform: translateX(calc(var(--lp) * 14)); }
}
@keyframes bob {
  0%   { transform: translate(calc(var(--lp) * -10), 0); }
  50%  { transform: translate(0, calc(var(--lp) * -7)); }
  100% { transform: translate(calc(var(--lp) * 10), 0); }
}

/* ── tokoh utama ────────────────────────────────────────────────────────── */
#character {
  position: absolute;
  left: var(--char-x);
  bottom: var(--ground);
  width: calc(var(--lp) * 36);
  height: calc(var(--lp) * 48);
  transform: translateX(-50%);
  z-index: 6;
  pointer-events: none;
}
#character .sprite {
  position: absolute; inset: 0;
  background-repeat: no-repeat;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
}
/* satu bingkai diam — gambarnya dipasang dari JS supaya jalur url()
   dihitung relatif terhadap halaman, bukan terhadap berkas CSS ini */
#character .stand { background-size: 100% 100%; }
/* lembar 4 bingkai, digeser per langkah */
#character .walk {
  opacity: 0;
  background-size: calc(var(--lp) * 144) calc(var(--lp) * 48);
  animation: walkcycle .52s steps(4) infinite;
}
@keyframes walkcycle {
  from { background-position-x: 0; }
  to   { background-position-x: calc(var(--lp) * -144); }
}
#character.moving .stand { opacity: 0; }
#character.moving .walk { opacity: 1; }
#character.back { transform: translateX(-50%) scaleX(-1); }
#character.back .c-name { transform: translateX(-50%) scaleX(-1); }

.c-name {
  position: absolute;
  left: 50%; bottom: 100%;
  transform: translateX(-50%);
  white-space: nowrap;
  font: 400 .66rem/1 var(--pixel);
  color: var(--ink);
  background: var(--panel);
  border: 2px solid var(--panel-ln);
  padding: .24rem .42rem .18rem;
  margin-bottom: .3rem;
  box-shadow: 0 .12rem 0 rgba(47, 40, 51, .28);
  transition: opacity .2s;
}
/* saat tamu berdiri di depan sebuah benda, nama bendanya yang penting */
body.dekat-objek .c-name { opacity: 0; }

/* ── judul ──────────────────────────────────────────────────────────────── */
#title {
  position: absolute;
  left: 0; right: 0;
  top: 7%;
  text-align: center;
  z-index: 7;
  transition: top .9s cubic-bezier(.4, 0, .2, 1),
              transform .9s cubic-bezier(.4, 0, .2, 1);
  text-shadow: 0 .12rem .5rem rgba(255, 255, 255, .7);
}
body.intro #title { top: 20%; transform: scale(1.18); }
.t-kecil {
  margin: 0 0 .3rem;
  font-family: var(--pixel);
  font-size: .72rem;
  letter-spacing: .34em;
  text-transform: uppercase;
  color: var(--ink);
}
.t-nama {
  margin: 0;
  font-family: var(--pixel);
  font-weight: 400;
  font-size: clamp(2.1rem, 10vw, 3.4rem);
  line-height: 1;
  letter-spacing: .02em;
}
.t-nama span { display: inline-block; }
.t-love {
  height: clamp(1.3rem, 5.6vw, 2.1rem);
  width: auto;
  display: inline-block;
  margin: 0 .45rem;
  vertical-align: -.04em;
}
.t-tanggal {
  margin: .5rem 0 0;
  font-family: var(--pixel);
  font-size: .92rem;
  letter-spacing: .12em;
  color: var(--ink);
}

/* ── kartu sampul ───────────────────────────────────────────────────────── */
#cover {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: end center;
  padding: 0 1.1rem calc(6 * var(--vh));
  z-index: 8;
  pointer-events: auto;
  background: linear-gradient(to bottom, rgba(252,246,234,0) 40%,
                                          rgba(252,246,234,.55) 100%);
  transition: opacity .5s, visibility .5s;
}
body:not(.intro) #cover { opacity: 0; visibility: hidden; pointer-events: none; }

.cover-card {
  width: min(100%, 26rem);
  background: var(--cream);
  border-radius: var(--card-r);
  padding: 1.35rem 1.2rem 1.15rem;
  text-align: center;
  box-shadow: var(--shadow), 0 1rem 2.5rem rgba(47, 40, 51, .16);
  border: 2px solid #fff;
}
.cv-kpd { margin: 0; font-size: .78rem; color: var(--ink-2); }
.cv-tamu {
  margin: .2rem 0 .55rem;
  font-family: var(--serif);
  font-size: 1.45rem;
  font-weight: 600;
  line-height: 1.2;
}
.cv-teks { margin: 0 0 1rem; font-size: .85rem; line-height: 1.6; color: var(--ink-2); }
.cv-hint { margin: .7rem 0 0; font-size: .66rem; color: var(--ink-2); opacity: .8; }

/* ── tombol ─────────────────────────────────────────────────────────────── */
.btn {
  display: inline-block;
  text-align: center;
  text-decoration: none;
  font: 400 1rem/1 var(--pixel);
  letter-spacing: .02em;
  color: #fff;
  background: var(--leaf);
  border: 0;
  border-radius: .75rem;
  padding: .8rem 1.5rem;
  cursor: pointer;
  box-shadow: 0 .22rem 0 var(--leaf-d);
  transition: transform .12s, box-shadow .12s;
  pointer-events: auto;
}
.btn:active { transform: translateY(.18rem); box-shadow: 0 .04rem 0 var(--leaf-d); }
.btn.ghost {
  background: var(--cream-2); color: var(--ink); box-shadow: 0 .22rem 0 #d6c8ad;
}
.btn.ghost:active { box-shadow: 0 .04rem 0 #d6c8ad; }
.btn.rose { background: var(--rose); box-shadow: 0 .22rem 0 var(--rose-d); }
.btn.rose:active { box-shadow: 0 .04rem 0 var(--rose-d); }
.btn.block { display: block; width: 100%; }

/* ── daftar misi ─────────────────────────────────────────────────────────
   Papan kayu bergaya pixel. Jaraknya dari judul sengaja dilebarkan, dan
   tombol di sudutnya membesarkan papan untuk yang perlu huruf lebih besar. */
#quest {
  position: absolute;
  left: .9rem;
  top: calc(13 * var(--vh) + 5.2rem);
  z-index: 5;
  background: var(--panel);
  border: 3px solid var(--panel-ln);
  box-shadow:
    inset 0 0 0 2px var(--panel-sh),
    0 4px 0 rgba(44, 38, 46, .28);
  padding: .45rem .55rem .5rem;
  max-width: 11.6rem;
  pointer-events: auto;
  transition: max-width .28s, padding .28s;
}
.q-head { display: flex; align-items: center; gap: .45rem; margin-bottom: .25rem; }
#quest h2 {
  margin: 0; flex: 1;
  font: 400 .7rem/1 var(--pixel);
  letter-spacing: .04em;
  color: var(--panel-ln);
}
#quest-size {
  flex: none;
  width: 1.2rem; height: 1.2rem;
  border: 2px solid var(--panel-ln);
  background: var(--cream) center / 68% no-repeat;
  background-image: url("../assets/ico_expand.png?v=9");
  cursor: pointer;
  padding: 0;
}
#quest-size:active { transform: translateY(1px); }
#quest.besar #quest-size { background-image: url("../assets/ico_collapse.png?v=9"); }

#quest ul { margin: 0; padding: 0; list-style: none; }
#quest li {
  display: flex; align-items: center; gap: .38rem;
  font: 400 .68rem/1.85 var(--pixel);
  color: var(--ink);
}
#quest li.done { color: var(--ink-2); text-decoration: line-through; }
.q-icon { width: .84rem; height: .84rem; flex: none; }

#quest.besar { max-width: min(22rem, calc(100vw - 1.8rem)); padding: .8rem .95rem .85rem; }
#quest.besar h2 { font-size: 1.2rem; }
#quest.besar li { font-size: 1.08rem; line-height: 2; gap: .6rem; }
#quest.besar .q-icon { width: 1.35rem; height: 1.35rem; }
#quest.besar #quest-size { width: 1.7rem; height: 1.7rem; }

/* ── panel ucapan ───────────────────────────────────────────────────────── */
#wishes {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translate(calc(100% - 2.6rem), -50%);
  z-index: 5;
  display: flex;
  align-items: flex-start;
  transition: transform .45s cubic-bezier(.4, 0, .2, 1);
  pointer-events: auto;
}
#wishes.open { transform: translate(0, -50%); }
#wish-toggle {
  flex: none;
  width: 2.5rem; height: 2.8rem;
  border: 3px solid var(--panel-ln);
  border-right: 0;
  background: var(--panel);
  box-shadow: 0 3px 0 rgba(44, 38, 46, .28);
  cursor: pointer;
  display: grid; place-items: center; gap: 0;
  font-size: 1rem;
  padding: 0;
}
.wt-count { font: 400 .62rem/1 var(--pixel); color: var(--rose-d); }
.wish-body {
  width: min(58vw, 14rem);
  max-height: 44vh;
  overflow-y: auto;
  background: var(--panel);
  padding: .7rem .75rem;
  border: 3px solid var(--panel-ln);
  border-right: 0;
  box-shadow: 0 3px 0 rgba(44, 38, 46, .28);
}
.wish-body h2 {
  margin: 0 0 .5rem;
  font: 400 .82rem/1 var(--pixel);
  letter-spacing: .04em; color: var(--panel-ln);
}
.wish-item {
  background: #fff;
  border-radius: .6rem;
  padding: .45rem .55rem;
  margin-bottom: .45rem;
  font-size: .7rem;
  line-height: 1.5;
}
.wish-item b { display: block; font-family: var(--serif); font-size: .82rem; }
.wish-item i { font-style: normal; color: var(--ink-2); font-size: .62rem; }

/* ── kontrol ─────────────────────────────────────────────────────────────
   Panahnya latar CSS, bukan <img>: tidak ada gambar yang bisa ditahan lalu
   disimpan, dan petunjuk gulir duduk tenang di antara keduanya. */
#controls {
  position: absolute;
  inset: auto 0 calc(3.5 * var(--vh)) 0;
  z-index: 9;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .6rem;
  padding: 0 1rem;
}
.dpad {
  flex: none;
  width: clamp(3.2rem, 15vw, 4.6rem);
  aspect-ratio: 40 / 32;
  padding: 0; border: 0;
  background: center / contain no-repeat;
  cursor: pointer;
  transition: transform .1s, filter .15s;
  filter: drop-shadow(0 2px 0 rgba(44, 38, 46, .35));
  pointer-events: auto;
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
}
#go-left { background-image: url("../assets/arrow-left.png?v=9"); }
#go-right { background-image: url("../assets/arrow-right.png?v=9"); }
.dpad.hold { transform: scale(.9) translateY(2px); filter: none; }

#music {
  position: absolute;
  right: 1rem;
  top: calc(2 * var(--vh) + .5rem);
  z-index: 9;
  width: 2.3rem; height: 2.3rem;
  border: 0; border-radius: 50%;
  background: rgba(252, 246, 234, .9);
  color: var(--ink);
  font-size: 1rem;
  cursor: pointer;
  pointer-events: auto;
  box-shadow: 0 .12rem 0 rgba(47, 40, 51, .14);
}
#music.on { background: var(--gold); color: #fff; animation: spin 4s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Petunjuk gulir — dibiarkan tetap terlihat, bukan hilang setelah beberapa
   detik: tamu yang baru membuka undangan di tengah acara tetap perlu tahu. */
#hint {
  flex: 0 1 auto;
  margin: 0;
  text-align: center;
  font: 400 clamp(.6rem, 2.7vw, .78rem)/1.45 var(--pixel);
  color: #fff;
  text-shadow: 0 1px 0 rgba(30, 52, 26, .95), 0 0 .5rem rgba(30, 52, 26, .8);
  animation: pulse 3.2s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .62; } }

/* hanya di layar sampul — begitu permainan mulai, tempat itu milik petunjuk
   gulir dan tombol panah */
#mark {
  position: absolute;
  left: 0; right: 0; bottom: .35rem;
  margin: 0;
  text-align: center;
  font-family: var(--pixel);
  font-size: .6rem;
  letter-spacing: .12em;
  color: rgba(47, 40, 51, .45);
  transition: opacity .4s;
}
body:not(.intro) #mark { opacity: 0; }

/* ── layar muat ─────────────────────────────────────────────────────────── */
#loader {
  position: fixed; inset: 0; z-index: 50;
  background: var(--cream);
  display: grid; place-items: center;
  transition: opacity .6s, visibility .6s;
}
#loader.hide { opacity: 0; visibility: hidden; }
.loader-inner { text-align: center; width: min(80vw, 16rem); }
.loader-heart { width: 2.4rem; margin: 0 auto .8rem; animation: beat 1.1s ease-in-out infinite; }
@keyframes beat { 0%, 100% { transform: scale(1); } 45% { transform: scale(1.22); } }
.loader-text { margin: 0 0 .7rem; font-size: .78rem; color: var(--ink-2); }
.loader-bar { height: .5rem; background: var(--cream-2); border-radius: 1rem; overflow: hidden; }
.loader-bar i { display: block; height: 100%; width: 0; background: var(--leaf); transition: width .25s; }

/* ── dialog ─────────────────────────────────────────────────────────────── */
#modal { position: fixed; inset: 0; z-index: 30; display: grid; place-items: center; padding: 1rem; }
#modal[hidden] { display: none; }
.modal-back { position: absolute; inset: 0; background: rgba(47, 40, 51, .48); animation: fade .3s; }
@keyframes fade { from { opacity: 0; } }

.modal-card {
  position: relative;
  width: min(100%, 30rem);
  max-height: 88vh;
  background: var(--cream);
  border-radius: var(--card-r);
  border: 2px solid #fff;
  box-shadow: 0 1.2rem 3rem rgba(47, 40, 51, .3);
  animation: pop .34s cubic-bezier(.2, 1.3, .4, 1);
  display: flex;
  flex-direction: column;
}
@media (min-width: 900px) { .modal-card { width: min(100%, 34rem); } }
@keyframes pop { from { transform: translateY(1.4rem) scale(.96); opacity: 0; } }

.modal-close {
  position: absolute;
  right: -.5rem; top: -.7rem;
  width: 2.1rem; height: 2.1rem;
  border: 2px solid #fff;
  border-radius: 50%;
  background: var(--ink);
  color: #fff;
  font-size: 1.15rem; line-height: 1;
  cursor: pointer;
  z-index: 2;
}
.modal-body { overflow-y: auto; padding: 1.5rem 1.25rem 1.35rem; -webkit-overflow-scrolling: touch; }

/* isi dialog */
.d-eyebrow {
  margin: 0 0 .35rem; text-align: center;
  font-family: var(--pixel);
  font-size: .68rem; letter-spacing: .26em; text-transform: uppercase; color: var(--gold-d);
}
.d-title {
  margin: 0 0 .9rem; text-align: center;
  font-family: var(--pixel); font-weight: 400;
  font-size: clamp(1.4rem, 6.2vw, 1.85rem); line-height: 1.2;
}
.d-body p { margin: 0 0 .75rem; font-size: .86rem; line-height: 1.72; }
.d-center { text-align: center; }
.d-ayat {
  font-style: italic; font-size: .82rem; line-height: 1.8;
  background: #fff; border-radius: .8rem; padding: .9rem 1rem; margin: 0 0 .6rem;
  border-left: 3px solid var(--gold);
}
.d-sumber { text-align: right; font-size: .7rem; color: var(--gold-d); margin: 0 0 1rem; }
.d-rule { border: 0; border-top: 1px dashed #d8ccb5; margin: 1.1rem 0; }
.d-actions { display: grid; gap: .5rem; margin-top: 1rem; }
@media (min-width: 480px) { .d-actions.two { grid-template-columns: 1fr 1fr; } }

/* mempelai */
.d-couple { display: grid; gap: .9rem; text-align: center; }
@media (min-width: 480px) { .d-couple { grid-template-columns: 1fr auto 1fr; align-items: center; } }
.d-amp { font-family: var(--serif); font-size: 1.6rem; color: var(--gold-d); }
.d-person h3 { margin: 0 0 .2rem; font-family: var(--serif); font-weight: 600; font-size: 1.25rem; }
.d-person p { margin: 0; font-size: .76rem; line-height: 1.6; color: var(--ink-2); }

/* acara */
.d-event {
  background: #fff; border-radius: .9rem; padding: .95rem 1rem; margin-bottom: .7rem;
  text-align: center;
}
.d-event h3 {
  margin: 0 0 .45rem; font-family: var(--serif); font-size: 1.15rem; font-weight: 600;
  color: var(--leaf-d);
}
.d-event .ev-tgl { font-size: .84rem; font-weight: 600; margin: 0 0 .1rem; }
.d-event .ev-jam { font-size: .78rem; color: var(--ink-2); margin: 0 0 .5rem; }
.d-event .ev-tmp { font-size: .82rem; font-weight: 600; margin: 0 0 .1rem; }
.d-event .ev-alm { font-size: .74rem; color: var(--ink-2); margin: 0 0 .7rem; line-height: 1.5; }

/* hitung mundur */
.d-count { display: grid; grid-template-columns: repeat(4, 1fr); gap: .4rem; margin: 0 0 1rem; }
.d-count div {
  background: #fff; border-radius: .7rem; padding: .5rem .2rem; text-align: center;
}
.d-count b { display: block; font-family: var(--serif); font-size: 1.35rem; line-height: 1; }
.d-count-pesan {
  grid-column: 1 / -1; background: #fff; border-radius: .7rem;
  padding: .8rem .6rem; margin: 0; text-align: center;
  font-family: var(--serif); font-size: 1rem; color: var(--ink);
}
.d-count span { font-size: .58rem; letter-spacing: .1em; color: var(--ink-2); text-transform: uppercase; }

/* kredit pembuat di kartu sampul — kecil, hangat, tidak menyaingi undangan */
.cv-kredit {
  margin: .9rem 0 0;
  font-size: .62rem;
  color: var(--ink-2);
  opacity: .85;
}
.cv-kredit a {
  color: var(--rose-d);
  text-decoration: none;
  border-bottom: 1px dotted var(--rose-d);
}

/* tautan Instagram mempelai — kata "Instagram" ditampilkan sebagai lencana
   supaya jelas ini akun IG, bukan sekadar nama panggilan ber-@ */
.d-person .ig {
  display: inline-flex; align-items: center; gap: .35rem;
  margin-top: .35rem; font-size: .74rem;
  color: var(--rose-d); text-decoration: none;
}
.d-person .ig-ico {
  width: .95em; height: .95em; flex: none;
  fill: none; stroke: currentColor; stroke-width: 2.4;
}
.d-person .ig-ico .titik { fill: currentColor; stroke: none; }
.d-person .ig:hover, .d-person .ig:focus-visible { text-decoration: underline; }

/* info praktis + tombol aksi di kartu acara */
.ev-info {
  font-size: .72rem; color: var(--ink-2);
  background: var(--cream-2); border-radius: .5rem;
  padding: .45rem .6rem; margin: .5rem 0 0;
}
/* dua tombol sejajar: tinggi sama, teksnya rata tengah sempurna — labelnya
   bisa 1 sampai 3 baris (huruf pixel lebar), tanpa ini terlihat timpang */
.ev-aksi { display: flex; gap: .5rem; margin-top: .6rem; align-items: stretch; }
.ev-aksi .btn {
  flex: 1;
  display: flex; align-items: center; justify-content: center;
  text-align: center;
  font-size: .88rem; line-height: 1.3;
  padding: .6rem .45rem;
}

/* foto mempelai di Papan Info */
.d-foto {
  width: 100%; height: auto; border-radius: .8rem;
  margin: .2rem 0 .45rem; pointer-events: none;
}
.d-foto-ket {
  text-align: center; font-size: .7rem; color: var(--ink-2);
  margin: 0 0 1rem;
}

/* kisah */
.d-story { position: relative; padding-left: 1.5rem; }
.d-story::before {
  content: ""; position: absolute; left: .32rem; top: .4rem; bottom: .4rem;
  width: 2px; background: #e3d8c2;
}
.d-story .st {
  position: relative; margin-bottom: 1.1rem;
}
.d-story .st::before {
  content: ""; position: absolute; left: -1.5rem; top: .25rem;
  width: .7rem; height: .7rem; border-radius: 50%;
  background: var(--rose); border: 2px solid var(--cream);
}
.d-story h4 { margin: 0; font-family: var(--serif); font-size: 1.05rem; }
.d-story .yr { font-size: .66rem; letter-spacing: .16em; color: var(--gold-d); }
.d-story p { margin: .25rem 0 0; font-size: .8rem; line-height: 1.65; color: var(--ink-2); }

/* galeri */
.d-gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: .4rem; }
.d-gallery img { width: 100%; height: 100%; aspect-ratio: 1; object-fit: cover; border-radius: .55rem; }

/* amplop */
.d-bank {
  background: #fff; border-radius: .8rem; padding: .8rem .9rem; margin-bottom: .6rem;
}
.d-bank .bk { font-size: .68rem; letter-spacing: .14em; color: var(--gold-d); text-transform: uppercase; }
.d-bank .no { font-family: var(--serif); font-size: 1.2rem; letter-spacing: .06em; margin: .1rem 0; }
.d-bank .an { font-size: .74rem; color: var(--ink-2); margin-bottom: .55rem; }

/* formulir */
.d-field { margin-bottom: .7rem; }
.d-field label { display: block; font-size: .72rem; margin-bottom: .25rem; color: var(--ink-2); }
.d-field input, .d-field select, .d-field textarea {
  /* 16px minimum — di bawah itu iOS memperbesar halaman saat form difokus,
     dan viewport-nya sudah tidak memakai maximum-scale */
  width: 100%; font: inherit; font-size: 1rem;
  padding: .65rem .7rem;
  border: 1px solid #ded2ba; border-radius: .6rem;
  background: #fff; color: var(--ink);
}
.d-field textarea { min-height: 5rem; resize: vertical; }
.d-note { font-size: .72rem; color: var(--ink-2); text-align: center; margin: .7rem 0 0; }
.d-ok {
  background: #eaf5e4; border-radius: .8rem; padding: .8rem;
  font-size: .8rem; text-align: center; color: var(--leaf-d);
}

/* menu panitia */
.d-menu { display: grid; gap: .5rem; }
.d-menu button {
  display: flex; align-items: center; gap: .7rem;
  width: 100%; text-align: left;
  font: 600 .88rem/1.3 var(--sans); color: var(--ink);
  background: #fff; border: 0; border-radius: .8rem;
  padding: .85rem .9rem; cursor: pointer;
  box-shadow: 0 .16rem 0 #e2d6bf;
}
.d-menu button:active { transform: translateY(.1rem); box-shadow: 0 .06rem 0 #e2d6bf; }
.d-menu .mi { font-size: 1.2rem; }
.d-menu small { display: block; font-weight: 400; font-size: .7rem; color: var(--ink-2); }

.avatar { text-align: center; margin: -.4rem 0 .5rem; }
.avatar img { width: min(58%, 11rem); height: auto; margin: 0 auto; }

.d-tamu {
  text-align: center; font-family: var(--serif); font-size: 1.15rem;
  background: #fff; border-radius: .7rem; padding: .55rem; margin: 0 0 1rem;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
