/* =========================================================================
   Undangan Pernikahan Digital — Shara & Ardi
   Arah desain mengikuti undangan cetak: suntiang & tanjak di puncak cover,
   pita pucuk rebung di kaki halaman. Warna hanya boleh dari blok token.
   ========================================================================= */

/* --- Font self-hosted ---------------------------------------------------- */
/* Work Sans mengikuti situs referensi yang dikirim keluarga. Parisienne dipilih
   Tangerine dipilih keluarga. Huruf-hurufnya jauh lebih tipis dan lapang
   daripada font sambung sebelumnya, jadi setiap ukuran di bawah ini dinaikkan
   agar tetap seimbang dengan teks di sekitarnya.
   Amiri dan Plus Jakarta Sans dibuang: tidak ada lagi yang memakainya sejak
   teks Arab dihapus. */
@font-face {
  font-family: 'Work Sans';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('fonts/work-sans-variable.woff2') format('woff2');
}
/* Dua bobot: Tangerine sangat tipis pada bobot 400, dan di ukuran judul ia
   nyaris hilang di atas krem. Bobot 700 dipakai untuk judul seksi dan label,
   bobot 400 untuk nama besar yang memang punya ruang. */
@font-face {
  font-family: 'Tangerine';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/tangerine-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Tangerine';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/tangerine-700.woff2') format('woff2');
}

/* --- Design token -------------------------------------------------------- */
/* Dua zona warna, bukan dua tema.

   Isi halaman memakai palet krem yang mendekati undangan cetak. Cover memakai
   palet gelap — versi itu yang disetujui keluarga karena fotonya tampil paling
   jelas di atas gelap. Karena custom property mewarisi ke bawah, cukup
   deklarasikan ulang tokennya pada #cover; seluruh aturan di bawah tidak perlu
   tahu apa pun soal ini.

   Nama token semantik, bukan nama warna, supaya tetap masuk akal di dua zona.

   Ambang kontras: 4.5:1 untuk teks biasa, 3.0:1 untuk teks >=24px dan cincin
   fokus. --judul HANYA untuk teks >=24px; --penting untuk teks 16-20px.
   --emas dipakai untuk ornamen dekoratif saja (aria-hidden, bukan teks), jadi
   boleh selembut cetakan; cincin fokus punya --fokus sendiri yang lebih pekat.
   tools/uji.mjs memverifikasi kedua zona. */
:root {
  /* ==== Isi halaman: krem, mengikuti undangan cetak ==== */
  --dasar:        #FDF8E7;   /* krem kertas */
  --permukaan:    #FFFCF2;   /* permukaan kartu */
  --garis:        #E4D5AC;
  --emas:         #C9A03C;   /* ornamen — dekoratif, meniru emas cetakan */
  --emas-tua:     #A67C2E;   /* garis tipis ornamen */
  --fokus:        #8A6520;   /* cincin fokus, 4.99:1 */
  --teks:         #3A352C;   /* abu hangat, seperti teks cetakan */
  --teks-redup:   #645C4C;
  --judul:        #A67C2E;   /* judul & nama mempelai, teks besar, 3.56:1 */
  --penting:      #7E5B1C;   /* nomor rekening, tautan, teks kecil menonjol */
  --aksen:        #8C2A1A;

  /* Panel isi: krem 88% di atas pola bunga. Angka itu bukan selera — pada
     kepekatan ini, judul emas masih 3.33:1 bahkan di atas piksel pola yang
     paling gelap, sedikit di atas ambang 3.0. Lebih tipis dari ini judulnya
     mulai gagal terbaca. */
  --panel:        rgba(253, 248, 231, .88);

  --tombol-latar:       #3A352C;
  --tombol-latar-hover: #2A2620;
  --tombol-teks:        #FDF8E7;

  /* Turunan */
  --tirai:        rgba(253, 248, 231, .68);
  --tirai-pekat:  rgba(253, 248, 231, .95);
  --lightbox:     rgba(35, 27, 12, .96);   /* foto paling jelas di latar gelap */
  --kilau:        rgba(201, 160, 60, .12);
  --kilau-tipis:  rgba(201, 160, 60, .06);
  --bayang:       rgba(58, 53, 44, .18);
  --putih-samar:  rgba(58, 53, 44, .04);

  /* Tipografi */
  --font-nama:    'Tangerine', 'Segoe Script', cursive;   /* nama & judul seksi */
  --font-teks:    'Work Sans', system-ui, -apple-system, sans-serif;

  /* Skala tipe — modular 1.25 */
  --t-xs:  0.8rem;   --t-sm:  1rem;     --t-md:  1.25rem;
  --t-lg:  1.563rem; --t-xl:  1.953rem; --t-2xl: 2.441rem;

  /* Ritme spasi — kelipatan 8 */
  --s-1: 8px;  --s-2: 16px; --s-3: 24px;
  --s-4: 40px; --s-5: 64px; --s-6: 96px;

  --radius: 4px;
  --lebar-isi: 34rem;
}

/* ==== Cover: gelap hangat, emas dominan ====
   Zona ini disetujui apa adanya, jadi nilainya tidak diubah. */
#cover {
  --dasar:        #1A1410;
  --permukaan:    #2A211A;
  --garis:        #3D3025;
  --emas:         #E3B23C;
  --emas-tua:     #A67C2E;
  --fokus:        #E3B23C;
  --teks:         #F5EEDF;
  --teks-redup:   #CDBFA6;
  --judul:        #E3B23C;
  --penting:      #E3B23C;
  --aksen:        #BE5039;   /* versi krem terlalu gelap di atas permukaan ini */

  --tombol-latar:       #E3B23C;
  --tombol-latar-hover: #C89A2E;
  --tombol-teks:        #1A1410;

  --tirai:        rgba(26, 20, 16, .70);
  --tirai-pekat:  rgba(26, 20, 16, .95);
  --kilau:        rgba(227, 178, 60, .14);
  --kilau-tipis:  rgba(227, 178, 60, .07);
  --bayang:       rgba(0, 0, 0, .40);
}

/* --- Dasar --------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  /* Pola bunga dari keluarga. background-attachment dibiarkan scroll:
     'fixed' membuat iOS Safari tersendat saat menggulir. */
  background-color: var(--dasar);
  background-image: url('img/latar.webp');
  background-repeat: repeat;
  background-size: 340px auto;
  color: var(--teks);
  font-family: var(--font-teks);
  font-size: var(--t-sm);          /* 16px — jangan pernah di bawah ini */
  line-height: 1.7;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

body.cover-terkunci { overflow: hidden; height: 100vh; height: 100dvh; }
body.kunci-scroll { overflow: hidden; }

img { max-width: 100%; display: block; }

h1, h2, h3 { font-family: var(--font-teks); font-weight: 500; margin: 0; }

p { margin: 0 0 var(--s-2); }

a { color: var(--penting); }

:focus-visible {
  outline: 2px solid var(--fokus);
  outline-offset: 3px;
  border-radius: var(--radius);
}

.lewati-ke-isi {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--tombol-latar); color: var(--tombol-teks);
  padding: var(--s-1) var(--s-2); font-weight: 600; text-decoration: none;
}
.lewati-ke-isi:focus { left: var(--s-2); top: var(--s-2); }

.kotak-salin {
  position: fixed; left: -9999px; top: 0;
  width: 1px; height: 1px; opacity: 0; border: 0;
}

/* --- Ringkasan tanpa JavaScript ------------------------------------------ */
#ringkasan-darurat {
  display: none;
  max-width: var(--lebar-isi);
  margin: 0 auto;
  background: var(--panel);
  padding: var(--s-4) var(--s-3);
  text-align: center;
}
#ringkasan-darurat h1 {
  font-family: var(--font-nama); font-size: 2.6rem; color: var(--judul);
  letter-spacing: .08em; margin-bottom: var(--s-3);
}
#ringkasan-darurat strong { color: var(--penting); font-weight: 600; }

/* =========================================================================
   COVER
   ========================================================================= */
#cover {
  position: fixed; inset: 0; z-index: 50;
  background-image: none;
  height: 100vh; height: 100dvh;
  display: flex; flex-direction: column;
  align-items: center;
  /* space-evenly membagi sisa ruang jadi empat celah yang persis sama: di atas
     ornamen, antara ornamen dan nama, antara nama dan blok tamu, dan di bawah.
     Keluarga meminta keempatnya seragam, dan itu mustahil dengan angka tetap —
     besarnya harus ikut tinggi layar. */
  justify-content: space-evenly;
  /* Tanpa padding atas-bawah: padding akan menambah ruang di kedua ujung dan
     membuat celah teratas dan terbawah lebih besar dari celah di tengah. */
  padding: 0 var(--s-3);
  text-align: center;
  overflow: hidden;
  background-color: var(--dasar);
  /* Cover ini fixed dengan inset:0 — yang menyisir large viewport — tapi
     tingginya sengaja dikunci ke satuan dvh supaya empat celah space-evenly
     di atas tetap presisi. Begitu bilah URL ponsel terlihat, dvh jadi lebih
     pendek daripada kotak inset:0, dan selisih beberapa puluh piksel di bawah
     cover menyingkap motif bunga milik body.
     Bayangan sebesar ini mengecat warna yang sama ke segala arah di luar
     kotak cover, jadi celah seberapa pun tertutup tanpa mengubah tinggi yang
     sudah disetel — dan tanpa mematikan background-image body, yang kalau
     dimatikan bikin motifnya berkedip saat undangan dibuka.
     Bukan efek dekoratif; jangan dihapus. Diuji: 'cover menambal celah'. */
  box-shadow: 0 0 0 100vmax var(--dasar);
}

.cover-latar { position: absolute; inset: 0; z-index: -1; overflow: hidden; }
.cover-latar::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to bottom, var(--tirai) 0%, var(--tirai) 45%, var(--tirai-pekat) 100%);
}
/* Tanpa pembesaran sama sekali. Versi sebelumnya membuat gambar 134% lebih
   tinggi supaya wajah turun, tapi efek sampingnya foto terpotong 47% di sisi
   kiri-kanan dan terasa seperti di-zoom di ponsel. Sekarang wajah dibuat
   terlihat dengan menggeser blok teksnya ke bawah, bukan dengan memperbesar
   fotonya. */
#cover-foto {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center top;
}
/* Saat foto belum tersedia, latar tetap layak pandang, bukan ikon rusak. */
#cover-foto.foto-gagal { display: none; }
.cover-latar.foto-gagal {
  background:
    radial-gradient(circle at 50% 30%, var(--kilau), transparent 60%),
    linear-gradient(160deg, var(--permukaan) 0%, var(--dasar) 70%);
}

/* Ornamen kini salah satu dari tiga kelompok di cover, bukan elemen
   mengambang. Posisinya ditentukan pembagian ruang, bukan angka vh — itu yang
   memungkinkan celah di atas dan di bawahnya sama besar. */
.orn-kepala {
  width: min(34vw, 6.8rem);
  flex: 0 0 auto;
  pointer-events: none;
}
.orn-kepala img { width: 100%; height: auto; }

.cover-blok { max-width: 26rem; width: 100%; flex: 0 0 auto; }

/* Irama vertikal cover, disusun berkelompok bukan seragam:
     pratanda -> nama       16px   satu kesatuan, dirapatkan
     nama -> kepada Yth.    40px   kelompok baru
     kepada Yth. -> sapaan   4px   satu kalimat sapaan, hampir menempel
     sapaan -> tombol       24px   ajakan, diberi ruang sendiri
     tombol -> catatan       8px   keterangan kecil, menempel pada tombolnya */
.cover-pratanda {
  font-size: var(--t-xs); letter-spacing: .28em; text-transform: uppercase;
  color: var(--teks-redup); margin-bottom: var(--s-2);
}
.cover-nama {
  font-family: var(--font-nama);
  font-size: 4.6rem; line-height: 1.05; letter-spacing: .02em;
  color: var(--judul); margin-bottom: 0;
}
.cover-nama .amper {
  display: block; font-size: 2.6rem; line-height: 1;
  color: var(--emas-tua); margin: .1em 0;
}
.cover-kepada { font-size: var(--t-xs); color: var(--teks-redup); margin-bottom: 4px; }
.cover-sapaan {
  font-size: var(--t-xs); letter-spacing: .06em;
  color: var(--teks-redup); margin-bottom: 0;
}
#buka-undangan { margin-top: var(--s-3); }
/* Diberi jarak dari sapaan di atasnya: tanpa itu nama tamu menempel pada
   "Bapak/Ibu/Saudara/i" dan keduanya terbaca sebagai satu baris panjang. */
.cover-tamu-nama {
  font-size: var(--t-md); font-weight: 500;
  color: var(--teks); margin: var(--s-1) 0 0;
  overflow-wrap: anywhere;
}

.cover-catatan {
  font-size: var(--t-xs); color: var(--teks-redup);
  margin: var(--s-1) 0 0;
}

/* Cover mengangkat dan sedikit membesar saat keluar, seperti tirai dibuka. */
body.cover-selesai #cover {
  opacity: 0; transform: translateY(-40px) scale(1.06);
  transition: opacity .8s ease-out, transform .8s ease-out;
  pointer-events: none;
}
/* #cover punya display:flex dari author, dan itu mengalahkan aturan [hidden]
   bawaan browser — tanpa baris ini `cover.hidden = true` di script.js tidak
   berefek apa pun, dan cover tetap ter-render seumur halaman lengkap dengan
   foto serta bayangan penambalnya. Pola yang sama sudah dipakai .lightbox,
   .panel-amplop, dan .tombol-musik. */
#cover[hidden] { display: none; }

/* Isi undangan masuk perlahan setelah cover pergi. */
@keyframes isi-masuk {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: none; }
}
body.cover-selesai #utama { animation: isi-masuk .9s .15s ease-out both; }

/* Sempat ada lapisan ::before untuk memudarkan pola bunga saat undangan
   dibuka. Dibuang: lapisan itu justru menutupi polanya, dan versi yang
   benar mengharuskan latar jadi position:fixed — yang membuat iOS Safari
   tersendat saat menggulir. Transisi cover dan isi sudah cukup. */

/* =========================================================================
   Tombol
   ========================================================================= */
.tombol {
  font-family: var(--font-teks); font-size: var(--t-sm); font-weight: 600;
  min-height: 44px; padding: 12px var(--s-3);
  border-radius: var(--radius); cursor: pointer;
  transition: background-color .25s ease, color .25s ease, border-color .25s ease;
}
.tombol-utama {
  background: var(--tombol-latar); color: var(--tombol-teks);
  border: 1px solid var(--tombol-latar);
  letter-spacing: .06em;
}
.tombol-utama:hover:not(:disabled) {
  background: var(--tombol-latar-hover); border-color: var(--tombol-latar-hover);
}
.tombol-garis {
  background: transparent; color: var(--penting);
  border: 1px solid var(--emas-tua);
}
.tombol-garis:hover:not(:disabled) { background: var(--kilau); }
.tombol.kecil { font-size: var(--t-xs); padding: 10px var(--s-2); }
.tombol:disabled { opacity: .6; cursor: default; }

/* =========================================================================
   Kerangka isi
   ========================================================================= */
/* Seluruh isi duduk di atas panel krem, dengan pola bunga terlihat di kedua
   tepinya — cara yang sama dipakai situs referensi. Tanpa panel ini, teks emas
   tidak lolos ambang kontras di atas pola. */
main {
  display: block;
  width: calc(100% - 3rem);
  max-width: 44rem;
  margin: 0 auto;
  background: var(--panel);
  box-shadow: 0 0 20px var(--bayang);
}

.seksi {
  max-width: var(--lebar-isi);
  margin: 0 auto;
  padding: var(--s-5) var(--s-3);
  text-align: center;
}

.judul-seksi {
  /* Tegak bersambung, sama dengan font nama mempelai — permintaan keluarga
     untuk setiap judul seksi. Huruf sambung butuh ukuran lebih besar agar
     terbaca, dan tidak boleh dikapitalkan: bentuk sambungnya rusak. */
  font-family: var(--font-nama);
  font-size: clamp(2.1rem, 8.4vw, 2.8rem);
  color: var(--judul);
  letter-spacing: 0; text-transform: none;
  font-weight: 700; line-height: 1.2; margin-bottom: var(--s-3);
}
.judul-kecil {
  font-family: var(--font-nama); font-weight: 700;
  font-size: 2.1rem; color: var(--judul);
  letter-spacing: 0; margin-bottom: var(--s-2);
}

/* Pembatas antar seksi. Diletakkan di luar .seksi supaya membentang penuh
   dari tepi ke tepi panel — di dalam seksi ia terpotong padding kiri-kanan dan
   terlihat seperti terputus. Petak dan cara mengulangnya sama persis dengan
   pita di kaki halaman, jadi keduanya terasa satu keluarga. */
.pita-seksi {
  display: block; width: 100%; height: 2.4rem;
  background: url('img/orn-pita.webp') repeat-x center bottom / auto 100%;
  opacity: .9;
  margin: var(--s-3) 0;
}


.paragraf { color: var(--teks-redup); font-weight: 350; }
.salam { color: var(--teks); font-size: 0.875rem; font-weight: 350; }

/* --- Foto & logo pembuka ------------------------------------------------- */
/* Foto pembuka berbingkai oval bergaris emas, mengikuti contoh yang dikirim
   keluarga — bukan kotak. Cincin emasnya dibuat dari border pada wadah plus
   sedikit padding, jadi ada jarak tipis antara garis dan fotonya. Bentuknya
   sama dengan bingkai foto mempelai supaya seluruh halaman konsisten. */
/* Layar pertama: seksi 1 dan pembatasnya jadi satu kotak setinggi layar,
   dengan pembatas ditempel ke dasarnya. Menghitung tinggi seksinya lewat
   aritmetika sempat dicoba dan selalu meleset — terlalu banyak padding, margin,
   dan tinggi baris yang harus ditebak. Ini menyerahkannya ke tata letak.

   Memakai svh, bukan dvh: pada iOS bilah alamat terlihat saat halaman baru
   dibuka, dan svh mengukur tepat keadaan itu. dvh ikut memanjang begitu
   bilahnya menyembunyi, dan pitanya akan bergeser turun. */
.layar-pertama {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}
.layar-pertama .seksi-foto-pembuka {
  flex: 1 1 auto;
  min-height: 0;
  padding-top: var(--s-3);
  padding-bottom: var(--s-4);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.layar-pertama .pita-seksi {
  flex: 0 0 auto;
  margin: 0;
}
/* Tingginya yang ditentukan, bukan lebarnya, dan ikut tinggi layar. Dengan
   lebar tetap, foto ini berukuran sama di layar tinggi maupun pendek sehingga
   isi seksi melebihi satu layar dan pembatasnya jatuh di bawah lipatan. */
.foto-pembuka {
  /* Foto ini diukur dari tinggi supaya memenuhi layar pertama, dan lebarnya
     turunan dari aspect-ratio — artinya ia tidak bisa menyusut sendiri kalau
     kolomnya sempit. Suku ketiga yang menahannya: di layar 360px foto minta
     308px sementara kolom isi cuma 264px, seksinya melar jadi 356px, lalu
     Chrome melebarkan layout viewport ke 380px dan seluruh halaman bergeser.
     96px itu 3rem gutter main + 2 x var(--s-3) padding seksi; kalau salah
     satunya diubah, max-width di bawah yang menangkap sisanya. */
  height: min(26rem, 52vh, calc((100vw - 96px) * 4 / 3));
  height: min(26rem, 52svh, calc((100vw - 96px) * 4 / 3));
  width: auto; margin: 0 auto;
  max-width: 100%;
  aspect-ratio: 3 / 4;
  padding: 6px;
  border: 1px solid var(--emas);
  border-radius: 50%;
}
.foto-pembuka img {
  width: 100%; height: 100%; object-fit: cover;
  border-radius: 50%;
}

/* --- Logo pembuka -------------------------------------------------------- */
/* Tanpa aspect-ratio paksa: logonya nyaris persegi dan akan terpotong buruk
   kalau dijejalkan ke bingkai tegak. */
.seksi-pembuka { padding-top: var(--s-3); }
.logo-pembuka { margin-bottom: var(--s-3); }
.logo-pembuka img { width: min(48%, 10.5rem); height: auto; margin: 0 auto; }

/* Nama di bawah foto pembuka, sejajar satu baris. */
.pembuka-pratanda {
  font-size: var(--t-xs); letter-spacing: .28em; text-transform: uppercase;
  color: var(--teks-redup); margin: var(--s-4) 0 var(--s-2);
}
.pembuka-nama {
  font-family: var(--font-nama);
  font-size: clamp(2.6rem, 11vw, 3.6rem);
  line-height: 1.15; color: var(--judul); margin: 0 0 var(--s-2);
}
.pembuka-nama .amper { color: var(--emas-tua); margin: 0 .2em; }
.pembuka-tanggal {
  font-size: var(--t-sm); letter-spacing: .14em;
  color: var(--teks); margin: var(--s-2) 0 0;
}

/* --- Pembuka ------------------------------------------------------------- */
/* Bismillah dikecilkan atas permintaan keluarga: dari --t-lg (25px) ke --t-md
   (20px). Karena tidak lagi tergolong teks besar, warnanya turun ke --penting
   yang memenuhi ambang 4.5:1. */
/* Bismillah tetap huruf biasa dan kecil, tidak ikut tegak bersambung.
   Kata ini panjang dan bukan nama; dalam huruf sambung ia jadi sangat lebar
   dan justru terasa besar lagi — persis yang diminta keluarga untuk dihindari. */
.seksi-pembuka .judul-seksi {
  font-family: var(--font-teks);
  font-size: 0.8125rem;
  color: var(--penting);
  letter-spacing: .16em;
  font-weight: 400;
  text-transform: uppercase;
}

.ayat { margin: 0 0 var(--s-4); padding: 0; }
/* Terjemahan dikecilkan lagi atas permintaan keluarga: 16px -> 15px.
   Ini di bawah lantai 16px yang diminta PRD demi tamu berusia lanjut, jadi
   sengaja berhenti di sini dan tidak diturunkan lagi. */
.ayat-terjemahan {
  color: var(--teks); font-style: italic;
  font-size: 0.9375rem; line-height: 1.75;
}
.ayat-sumber {
  display: block; font-style: normal; font-size: var(--t-xs);
  letter-spacing: .16em; color: var(--teks-redup);
}

/* --- Mempelai ------------------------------------------------------------ */
.mempelai-tunggal { display: block; }

.mempelai-kartu { display: block; }
/* Oval, bukan persegi — permintaan keluarga. Rasio 3:4 dengan wajah di
   sepertiga atas, karena bagian bawah oval terpotong lengkung. */
.mempelai-foto-bingkai {
  width: 100%; max-width: 15rem; margin: 0 auto var(--s-3);
  aspect-ratio: 3 / 4; overflow: hidden;
  border-radius: 50%;
  border: 1px solid var(--garis);
  background: linear-gradient(160deg, var(--permukaan) 0%, var(--dasar) 100%);
}
.mempelai-foto-bingkai img { width: 100%; height: 100%; object-fit: cover; }
/* Nama harus muat satu baris. clamp() menskalakan dengan lebar layar supaya
   "Shara Novia Annas, S.Tr.Par." tetap sebaris di layar 360px maupun tablet,
   tanpa memaksa nowrap yang bisa meluber keluar panel. */
.mempelai-nama {
  font-family: var(--font-nama); font-weight: 700;
  font-size: clamp(1.5rem, 6.2vw, 2.1rem);
  color: var(--judul); letter-spacing: .01em;
  margin-bottom: var(--s-1); line-height: 1.35;
  white-space: nowrap;
}
.mempelai-urutan, .mempelai-ortu { color: var(--teks-redup); font-size: var(--t-xs); margin-bottom: 4px; }
.mempelai-ortu { color: var(--teks); font-size: var(--t-sm); }
.mempelai-ig {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 44px; font-size: var(--t-xs); letter-spacing: .08em;
  text-decoration: none;
}
.mempelai-ig:hover { text-decoration: underline; }


/* --- Hitung mundur ------------------------------------------------------- */
.countdown {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: var(--s-1); max-width: 24rem; margin: 0 auto;
}
.cd-blok {
  background: var(--permukaan); border: 1px solid var(--garis);
  border-radius: var(--radius); padding: var(--s-2) 4px;
}
.cd-angka {
  display: block; font-size: var(--t-lg); font-weight: 600;
  color: var(--judul); line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.cd-label {
  display: block; font-size: var(--t-xs); letter-spacing: .1em;
  color: var(--teks-redup); text-transform: uppercase;
}
.cd-tiba {
  font-family: var(--font-nama); font-weight: 700; font-size: 2.6rem;
  color: var(--penting); letter-spacing: .08em;
}

/* --- Acara --------------------------------------------------------------- */
.acara-grid { display: grid; gap: var(--s-3); }

.kartu {
  background: var(--permukaan);
  border: 1px solid var(--garis);
  border-radius: var(--radius);
  padding: var(--s-3);
  text-align: center;
}
.acara-jenis {
  font-size: var(--t-md); font-weight: 600;
  color: var(--penting); letter-spacing: .1em; margin-bottom: var(--s-2);
}
.acara-tanggal { font-weight: 600; margin-bottom: 2px; }
.acara-jam { color: var(--teks); margin-bottom: var(--s-2); }
.acara-tempat { font-weight: 600; margin-bottom: 2px; }
.acara-alamat { color: var(--teks-redup); font-size: var(--t-xs); margin-bottom: var(--s-2); }
.acara-peta { display: inline-block; text-decoration: none; }

/* --- Galeri -------------------------------------------------------------- */
/* Susunan mosaik seperti contoh yang dikirim keluarga: tiap baris berisi satu
   foto sempit dan satu foto lebar, dan sisi yang lebar berganti tiap baris.

   Tingginya sengaja dibuat sama persis: dengan tiga kolom, foto sempit selebar
   1/3 pada rasio 2:3 setinggi 0.5x lebar grid, dan foto lebar selebar 2/3 pada
   rasio 4:3 juga setinggi 0.5x. Jadi barisnya rata tanpa perlu masonry. */
.galeri-grid {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-1);
}
.galeri-item { margin: 0; grid-column: span 1; }
.galeri-item.lebar { grid-column: span 2; }
.galeri-item.penuh { grid-column: 1 / -1; }
.galeri-tombol {
  display: block; width: 100%; padding: 0; border: 0; background: none;
  cursor: pointer; border-radius: var(--radius); overflow: hidden;
  line-height: 0;
}
.galeri-tombol img {
  width: 100%; height: 100%; object-fit: cover;
  aspect-ratio: 2 / 3;
  background: linear-gradient(160deg, var(--permukaan) 0%, var(--dasar) 100%);
  transition: transform .4s ease;
}
.galeri-item.lebar .galeri-tombol img { aspect-ratio: 4 / 3; }
.galeri-item.penuh .galeri-tombol img { aspect-ratio: 3 / 2; }
.galeri-tombol:hover img { transform: scale(1.04); }
.galeri-tombol:hover img { transform: scale(1.04); }

/* Penanda foto yang belum diisi — tampil rapi, bukan ikon rusak. */
.foto-kosong {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 3 / 4;
  background:
    radial-gradient(circle at 50% 40%, var(--kilau-tipis), transparent 65%),
    linear-gradient(160deg, var(--permukaan) 0%, var(--dasar) 100%);
  border: 1px dashed var(--garis);
  border-radius: var(--radius);
  color: var(--teks-redup); font-size: var(--t-xs);
  letter-spacing: .1em; text-align: center; padding: var(--s-1);
}
.mempelai-foto-bingkai .foto-kosong,
.penutup-foto .foto-kosong { aspect-ratio: auto; width: 100%; height: 100%; border: 0; }

/* --- Amplop -------------------------------------------------------------- */
.panel-amplop { margin-top: var(--s-3); text-align: left; }
.panel-amplop[hidden] { display: none; }

/* Dianimasikan hanya saat dibuka; tanpa blur, tanpa opacity untuk menyembunyikan. */
.panel-amplop.membuka {
  animation: buka-panel .3s ease-out;
}
@keyframes buka-panel {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}

.rekening-kartu {
  background: var(--permukaan); border: 1px solid var(--garis);
  border-radius: var(--radius); padding: var(--s-3);
  margin-bottom: var(--s-2); text-align: center;
}
.rekening-bank {
  font-size: var(--t-xs); letter-spacing: .2em; text-transform: uppercase;
  color: var(--teks-redup); margin-bottom: 4px;
}
.rekening-nomor {
  font-size: var(--t-md); font-weight: 600;
  color: var(--penting); letter-spacing: .12em;
  font-variant-numeric: tabular-nums; margin-bottom: 4px;
}
.rekening-atas-nama { font-size: var(--t-xs); color: var(--teks); margin-bottom: var(--s-2); }
.kado-blok {
  border: 1px dashed var(--garis); border-radius: var(--radius);
  padding: var(--s-3); text-align: center;
}
.kado-judul { font-size: var(--t-xs); letter-spacing: .2em; text-transform: uppercase;
  color: var(--teks-redup); margin-bottom: 4px; }

/* --- Formulir ------------------------------------------------------------ */
.kartu-form { text-align: left; }
.baris { margin-bottom: var(--s-3); border: 0; padding: 0; }
.baris > label, .baris > legend {
  display: block; font-size: var(--t-xs); font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--teks-redup); margin-bottom: var(--s-1); padding: 0;
}
input[type="text"], input[type="number"], textarea {
  width: 100%; min-height: 44px;
  padding: 10px var(--s-2);
  font-family: var(--font-teks); font-size: var(--t-sm);
  color: var(--teks);
  background: var(--dasar);
  border: 1px solid var(--garis); border-radius: var(--radius);
}
textarea { resize: vertical; line-height: 1.6; }
input:focus, textarea:focus { border-color: var(--emas-tua); }

.pilihan { display: grid; gap: var(--s-1); }
.pilihan label {
  display: flex; align-items: center; gap: var(--s-1);
  min-height: 44px; padding: 0 var(--s-2);
  border: 1px solid var(--garis); border-radius: var(--radius);
  cursor: pointer;
}
.pilihan input { accent-color: var(--emas); width: 18px; height: 18px; }
.pilihan label:has(input:checked) { border-color: var(--emas); background: var(--kilau-tipis); }

.penghitung {
  font-size: var(--t-xs); color: var(--teks-redup);
  text-align: right; margin: 4px 0 0;
  font-variant-numeric: tabular-nums;
}
.galat-field { font-size: var(--t-xs); color: var(--penting); margin: 4px 0 0; }
.pesan-form {
  margin: var(--s-2) 0 0; padding: var(--s-2);
  border-radius: var(--radius); font-size: var(--t-xs); line-height: 1.6;
}
.pesan-form.galat { border: 1px solid var(--aksen); background: var(--putih-samar); color: var(--teks); }
.pesan-form.sukses { border: 1px solid var(--emas-tua); color: var(--teks); }
#kirim-rsvp { width: 100%; }

.terima-kasih { text-align: center; padding: var(--s-2) 0; }
.terima-kasih .judul-kecil { color: var(--penting); }

/* --- Daftar ucapan ------------------------------------------------------- */
.ucapan-wadah { margin-top: var(--s-4); }
.daftar-ucapan { list-style: none; margin: 0 0 var(--s-2); padding: 0; text-align: left; }
.ucapan-item {
  border-bottom: 1px solid var(--garis);
  padding: var(--s-2) 0;
}
.ucapan-nama { font-weight: 600; color: var(--penting); font-size: var(--t-sm); margin-bottom: 2px; }
.ucapan-waktu { font-size: var(--t-xs); color: var(--teks-redup); margin-bottom: 4px; }
.ucapan-teks { color: var(--teks); margin: 0; overflow-wrap: anywhere; }
.kosong { color: var(--teks-redup); font-size: var(--t-xs); }

/* --- Penutup ------------------------------------------------------------- */
.penutup-foto {
  width: 100%; max-width: 20rem; margin: 0 auto var(--s-3);
  aspect-ratio: 4 / 5; overflow: hidden; border-radius: var(--radius);
  border: 1px solid var(--garis);
}
.penutup-foto img { width: 100%; height: 100%; object-fit: cover; }
.penutup-nama {
  font-family: var(--font-nama); font-size: 3.6rem;
  color: var(--judul); letter-spacing: .02em; margin-top: var(--s-3);
  line-height: 1.3;
}
.penutup-nama .amper { color: var(--emas-tua); margin: 0 var(--s-1); }

/* Logo monogram. Ukurannya ditahan supaya tidak bersaing dengan nama mempelai. */
.logo-wadah { margin: 0 auto var(--s-4); }
.logo-wadah[hidden] { display: none; }
.logo-wadah img {
  width: min(60%, 11rem); height: auto; margin: 0 auto;
  /* Latar putihnya sudah benar-benar dibuang saat konversi, jadi tidak perlu
     mix-blend-mode — trik itu tidak jalan konsisten di semua browser. */
}

/* Pita pucuk rebung di kaki halaman, dari aset yang sama.
   Petaknya berulang mulus, jadi cukup diulang lewat background dan tidak perlu
   elemen apa pun — motifnya tidak pernah teregang di lebar layar mana pun. */
.pita-pucuk {
  height: 3.5rem; width: 100%; display: block;
  background: url('img/orn-pita.webp') repeat-x center bottom / auto 100%;
  pointer-events: none;
}

.kaki {
  max-width: var(--lebar-isi); margin: 0 auto;
  text-align: center; padding: var(--s-3) var(--s-3) var(--s-5);
  font-size: var(--t-xs); color: var(--teks-redup);
}
.kaki p { margin: 0; }

/* Catatan bahwa undangan bersifat personal. Nadanya minta maaf, jadi
   dibiarkan tenang: tanpa kotak, tanpa warna peringatan. */
.catatan-personal {
  border-top: 1px solid var(--garis);
  padding-top: var(--s-3);
  margin-bottom: var(--s-3) !important;
  line-height: 1.8; text-align: justify;
  /* Tanpa hyphens, teks rata kanan-kiri di kolom sempit meninggalkan celah
     antar kata yang lebar. */
  hyphens: auto;
}

.blok-kontak { margin-bottom: var(--s-3); }
.blok-kontak[hidden] { display: none; }
.kontak-pengantar { margin-bottom: var(--s-1) !important; }

/* =========================================================================
   Lightbox
   ========================================================================= */
.lightbox {
  position: fixed; inset: 0; z-index: 80;
  display: flex; align-items: center; justify-content: center;
  background: var(--lightbox);
  padding: var(--s-4) var(--s-2);
}
.lightbox[hidden] { display: none; }
.lb-panggung { margin: 0; max-width: 100%; max-height: 100%; text-align: center; }
#lb-foto {
  max-width: 100%; max-height: 78vh; max-height: 78dvh;
  margin: 0 auto; object-fit: contain;
}
#lb-keterangan {
  margin-top: var(--s-2); font-size: var(--t-xs); color: var(--teks-redup);
}
.lb-tutup {
  position: absolute; top: var(--s-2); right: var(--s-2);
  width: 44px; height: 44px; font-size: var(--t-lg); line-height: 1;
  background: transparent; color: var(--teks);
  border: 1px solid var(--garis); border-radius: 50%; cursor: pointer;
}
.lb-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px; font-size: var(--t-lg); line-height: 1;
  background: transparent; color: var(--teks);
  border: 1px solid var(--garis); border-radius: 50%; cursor: pointer;
}
.lb-prev { left: var(--s-2); }
.lb-next { right: var(--s-2); }

/* =========================================================================
   Kontrol musik
   ========================================================================= */
.tombol-musik {
  position: fixed; z-index: 60;
  right: var(--s-2);
  bottom: max(var(--s-2), env(safe-area-inset-bottom));
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  background: var(--permukaan); color: var(--penting);
  border: 1px solid var(--emas-tua); border-radius: 50%;
  box-shadow: 0 2px 12px var(--bayang);
  cursor: pointer;
}
.tombol-musik[hidden] { display: none; }
.tombol-musik svg { width: 20px; height: 20px; }
.tombol-musik .ikon-jeda { display: none; }
.tombol-musik.berputar .ikon-main { display: none; }
.tombol-musik.berputar .ikon-jeda { display: block; }

/* =========================================================================
   Gerak — satu kali saja, dan patuh pada preferensi pengguna
   ========================================================================= */
/* Setiap elemen masuk sekali saat seksinya mendekati layar. Arah masuknya
   dibedakan supaya tiap seksi terasa punya gerakan sendiri, bukan satu pola
   yang diulang dari atas ke bawah:
     reveal        naik dari bawah   — teks dan judul
     reveal-kiri   masuk dari kiri   — kartu/foto sisi kiri
     reveal-kanan  masuk dari kanan  — kartu/foto sisi kanan
     reveal-zoom   membesar pelan    — foto besar dan logo
   Jeda bertingkat antar elemen dalam satu seksi diatur JavaScript. */
.ada-js .reveal       { opacity: 0; transform: translateY(30px); }
.ada-js .reveal-kiri  { opacity: 0; transform: translateX(-36px); }
.ada-js .reveal-kanan { opacity: 0; transform: translateX(36px); }
.ada-js .reveal-zoom  { opacity: 0; transform: scale(.92); }

.ada-js .reveal.tampil,
.ada-js .reveal-kiri.tampil,
.ada-js .reveal-kanan.tampil,
.ada-js .reveal-zoom.tampil {
  opacity: 1; transform: none;
  transition: opacity .75s ease-out,
              transform .75s cubic-bezier(.22, .68, .28, 1);
}

/* =========================================================================
   Layar lebih lebar
   ========================================================================= */
@media (min-width: 40rem) {
  :root { --lebar-isi: 46rem; }

  .cover-nama { font-size: 3.05rem; }
  .acara-grid { grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }
  .seksi { padding: var(--s-5) var(--s-3); }
}

/* =========================================================================
   Layar sangat pendek
   =========================================================================
   Ponsel kecil seperti iPhone SE hanya punya sekitar 570px tinggi terlihat.
   Di situ jarak antar baris di layar pertama dirapatkan supaya pembatasnya
   tetap jatuh di tepi bawah, bukan terdorong ke bawah lipatan. */
@media (max-height: 640px) {
  .layar-pertama .seksi-foto-pembuka {
    padding-top: var(--s-2);
    padding-bottom: var(--s-3);
  }
  .pembuka-pratanda { margin: var(--s-2) 0 var(--s-1); }
  .pembuka-nama { margin-bottom: var(--s-1); }
  .pembuka-tanggal { margin-top: var(--s-1); }
  /* Suku lebar harus ikut diulang di sini — tanpa itu layar pendek sekaligus
     sempit (misalnya 320x600) melubernya kembali. */
  .foto-pembuka {
    height: min(26rem, 48vh, calc((100vw - 96px) * 4 / 3));
    height: min(26rem, 48svh, calc((100vw - 96px) * 4 / 3));
  }

  /* Cover dirapatkan: tanpa ini isinya lebih tinggi dari layar, celahnya
     habis jadi nol, dan catatan musiknya terpotong. */
  .cover-nama { font-size: 3rem; }
  .cover-nama .amper { font-size: 1.7rem; margin: 0; }
  .cover-pratanda { margin-bottom: var(--s-1); }
  .cover-sapaan { margin-bottom: var(--s-2); }
  #buka-undangan { margin-top: var(--s-2); }
  .orn-kepala { width: min(28vw, 5.4rem); }
}

/* Ponsel dalam posisi mendatar. Isi cover butuh 402px tinggi — diukur, bukan
   diperkirakan — sedangkan ponsel yang diputar hanya menyisakan 360-393px.
   Karena #cover overflow:hidden, kelebihannya dipangkas diam-diam: tombol
   "Buka Undangan" dan catatan musik hilang, dan tamu tidak bisa masuk sama
   sekali. Potret tidak pernah kena, bahkan pada 360x480.

   space-evenly harus diganti flex-start: begitu ruang sisa jadi negatif ia
   memusatkan isi, sehingga bagian atas keluar layar dan tidak bisa dijangkau
   scroll. overflow-y jadi jaring pengaman kalau ukuran di bawah masih kurang;
   overflow-x tetap hidden dari aturan induk. */
@media (max-height: 405px) {
  #cover {
    justify-content: flex-start;
    overflow-y: auto;
    padding-top: var(--s-2);
    padding-bottom: var(--s-1);
  }
  /* Mendatar itu kekurangan tinggi tapi kelebihan lebar, jadi lebar ditukar
     dengan tinggi: melonggarkan 26rem membuat nama tamu terpanjang muat satu
     baris, bukan dua. Nama dua baris menambah 34px dan itu cukup untuk
     mendorong tombol keluar layar. Terpanjang di daftar 44 huruf. */
  .cover-blok { max-width: 44rem; }
  .orn-kepala { width: min(18vw, 3.4rem); }
  .cover-nama { font-size: 2.1rem; }
  .cover-nama .amper { font-size: 1.2rem; }
  .cover-pratanda { margin-bottom: 0; }
  .cover-kepada { margin-top: var(--s-2); }
  .cover-sapaan { margin-bottom: var(--s-1); }
  #buka-undangan { margin-top: var(--s-2); }
}

/* =========================================================================
   prefers-reduced-motion — matikan seluruh gerak
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .ada-js .reveal,
  .ada-js .reveal-kiri,
  .ada-js .reveal-kanan,
  .ada-js .reveal-zoom { opacity: 1; transform: none; transition-delay: 0s !important; }
  .galeri-tombol:hover img { transform: none; }
  body.cover-selesai #utama { animation: none; }
}
