/* ══════════════════════════════════════════════════════════════════
   HAPPY BIRTHDAY NATHAN — kartu digital interaktif
   Struktur: #viewport (letterbox hitam) > #stage (kanvas 1600×900,
   di-scale uniform via JS) > .scene (4 scene, cross-fade).
   Semua elemen di dalam #stage otomatis proporsional karena stage-nya
   di-scale() sekaligus — jadi px di sini aman (ikut mengecil/membesar).
   ══════════════════════════════════════════════════════════════════ */

/* ── FONT ASLI (dari desain). Fallback ke Google Fonts di font stack. ── */
@font-face {
  font-family: 'IBM Plex Mono Local';
  src: url('assets/fonts/IBMPlexMono-Light.ttf') format('truetype');
  font-weight: 300; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Snell Roundhand Local';
  /* .ttc = TrueType Collection; browser modern support-nya, kalau tidak
     akan jatuh ke 'Great Vibes' di bawah. */
  src: url('assets/fonts/SnellRoundhand.ttc') format('collection');
  font-display: swap;
}

:root {
  /* ── FONT (ganti di sini kalau punya font custom) ── */
  --font-mono:   'IBM Plex Mono Local', 'IBM Plex Mono', 'Courier Prime', monospace;
  --font-script: 'Snell Roundhand Local', 'Snell Roundhand', 'Great Vibes', cursive;

  /* ── PALET WARNA ── */
  --curtain-a:  #3a5c6e;   /* tirai gradient atas  */
  --curtain-b:  #5f8598;   /* tirai gradient bawah */
  --letter-bg:  #5c7c92;   /* bg scene surat       */
  --paper:      #f2f1ec;   /* kertas surat         */
  --letter-ink: #33424a;   /* teks surat           */
  --accent-navy:#2c4a63;   /* kancing / aksen      */
  --teal:       #6fa0b3;   /* link "next"/"teal"   */

  /* Durasi transisi antar-scene */
  --fade: 600ms;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  width: 100%; height: 100%;
  background: #000;
  overflow: hidden;
  font-family: var(--font-mono);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

/* ── LETTERBOX ── */
#viewport {
  position: fixed; inset: 0;
  background: #000;
  overflow: hidden;
}

/* ── KANVAS 16:9 (base 1600×900). Transform di-set oleh script.js ── */
#stage {
  position: absolute;
  top: 50%; left: 50%;
  width: 1600px; height: 900px;
  transform-origin: center center;
  transform: translate(-50%, -50%) scale(1); /* scale diganti via JS */
  overflow: hidden;
  background: #000;
  user-select: none;
}

/* ── SCENE (cross-fade) ── */
.scene {
  position: absolute; inset: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--fade) ease-in-out;
}
.scene.active {
  opacity: 1;
  pointer-events: auto;
}
/* Scene yang bisa diklik di mana saja untuk maju */
#scene-1, #scene-2 { cursor: pointer; }

/* ══════════════════════════════════════════════════════════════════
   TIRAI (dipakai di Scene 1, 2, 4)
   Dua panel 50% lebar. Panel kanan di-MIRROR (scaleX -1) dari gambar
   yang sama supaya simetris.
   ══════════════════════════════════════════════════════════════════ */
.curtain { position: absolute; inset: 0; }
.curtain-panel {
  position: absolute; top: 0;
  width: 50.2%; height: 100%;    /* sedikit overlap di tengah biar rapat */
  object-fit: cover;
}
.curtain-panel.left  { left: 0; }
.curtain-panel.right { right: 0; transform: scaleX(-1); } /* mirror */

/* Scene 2: tirai MEMBUKA saat scene aktif. Kelas .go ditambah script.js */
#scene-2 .curtain-panel { transition: transform 1200ms ease-in-out; }
#scene-2.go .curtain-panel.left  { transform: translateX(-102%); }
#scene-2.go .curtain-panel.right { transform: scaleX(-1) translateX(-102%); }

/* ══════════════════════════════════════════════════════════════════
   SCENE 1 — COVER
   ══════════════════════════════════════════════════════════════════ */
.cover-text {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  font-family: var(--font-mono);
  font-size: 34px;
  letter-spacing: 1px;
  color: rgba(255, 255, 255, 0.9);
  white-space: nowrap;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
}
.cover-text .cursor { animation: blink 800ms steps(1) infinite; }
@keyframes blink { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }

/* ══════════════════════════════════════════════════════════════════
   SCENE 2 — TAMAN
   ══════════════════════════════════════════════════════════════════ */
.garden-bg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.hint {
  position: absolute; left: 50%; bottom: 7%;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: 18px; letter-spacing: 1px;
  color: rgba(44, 74, 99, 0.75);
  opacity: 0;
  transition: opacity 600ms ease;
}
/* hint muncul setelah tirai selesai membuka (kelas .ready dari JS) */
#scene-2.ready .hint { opacity: 1; }

/* ══════════════════════════════════════════════════════════════════
   SCENE 3 — SURAT / KARTU POS
   ══════════════════════════════════════════════════════════════════ */
.letter-bg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  background: var(--letter-bg);
}

/* Kartu: ±44% lebar kanvas, center horizontal, sedikit di atas center */
.card-wrap {
  position: absolute;
  left: 50%; top: 46%;
  transform: translate(-50%, -50%) scale(0.9);
  width: 44%;                    /* ≈ kartu 43% spec */
  opacity: 0;
}
/* entrance kartu (scale 0.9→1 + fade) saat scene aktif */
#scene-3.play .card-wrap {
  animation: cardIn 500ms ease-out forwards;
}
@keyframes cardIn {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0.9); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
.card { display: block; width: 100%; height: auto; }

/* Teks di dalam kartu */
.card-content {
  position: absolute; inset: 0;
  padding: 12% 12% 14%;
  text-align: center;
  color: var(--letter-ink);
  font-family: var(--font-mono);
  display: flex; flex-direction: column; align-items: center;
  overflow: hidden;              /* jaga-jaga: apa pun yang lolos tetap kepotong di sini */
}
.card-greeting {
  font-size: 20px; letter-spacing: 0.5px;
  margin-bottom: 7%;
  opacity: 0;
  flex: 0 0 auto;                /* greeting tetap, yang scroll cuma isi surat */
}
#scene-3.play .card-greeting { animation: fadeIn 300ms ease forwards 250ms; }

.card-body {
  font-size: 16.5px; line-height: 1.9;
  min-height: 1px;
  white-space: pre-wrap;
  word-break: break-word;
  flex: 1 1 auto;
  min-height: 0;                 /* wajib supaya flex child ini bisa menyusut & men-scroll, bukan meluber */
  width: 100%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: rgba(51,66,74,0.35) transparent;
}
.card-body::-webkit-scrollbar { width: 5px; }
.card-body::-webkit-scrollbar-thumb { background: rgba(51,66,74,0.35); border-radius: 3px; }
.card-body::after { /* kursor typewriter */
  content: '_';
  animation: blink 800ms steps(1) infinite;
}
.card-body.done::after { content: ''; }

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

/* ── DEKORASI kartu (posisi relatif ke .card-wrap) ── */
.deco { position: absolute; opacity: 0; }
#scene-3.play .deco { opacity: 1; }

/* Klip "Archive": pojok kiri-atas, keluar tepi, rotate -12deg */
.deco.clip {
  top: -9%; left: -7%;
  width: 24%;
  transform: rotate(-12deg);
  filter: drop-shadow(0 6px 10px rgba(0,0,0,.25));
  transition: opacity 400ms ease;
}

/* Bola sepak: kiri kartu, tengah vertikal, floating idle */
.deco.ball {
  left: -13%; top: 40%;
  width: 19%;
  filter: drop-shadow(0 8px 12px rgba(0,0,0,.25));
  transition: opacity 400ms ease;
}
#scene-3.play .deco.ball { animation: fadeIn 400ms ease forwards, ballFloat 3s ease-in-out infinite; }
@keyframes ballFloat { 0%, 100% { translate: 0 0; } 50% { translate: 0 -5%; } }

/* Gantungan kunci hati + foto pasangan di jendela tengahnya, gantung di kanan.
   Ukuran visual 2x (via transform:scale, bukan width) supaya posisi/anchor-nya
   (right/top di atas) sama sekali tidak bergeser — cuma tampil lebih besar. */
.deco.locket {
  right: -8%; top: -36%;
  width: 17%;
  transform-origin: 50% 8%;      /* titik gantung di atas (rantai) */
  transform: scale(2);
  filter: drop-shadow(0 8px 12px rgba(0,0,0,.3));
}
.locket-frame { display: block; width: 100%; height: auto; }
/* Foto pasangan pas di jendela hati liontin (fit ke window). Koordinat diukur
   presisi dari lubang transparan asli di locket.png (bukan dikira-kira):
   center 49.4%/66.8%, rasio lubang ~192:170 (bukan persegi 1:1). Atur
   left/top/width di sini kalau ganti asset locket.png. */
.locket-photo {
  position: absolute;
  left: 49.4%; top: 66.8%;
  transform: translate(-50%, -50%);
  width: 47%; aspect-ratio: 192 / 170;
  object-fit: cover;
  border-radius: 2px;
  z-index: 1;
}
#scene-3.play .deco.locket { animation: locketSwing 800ms cubic-bezier(.34,1.4,.5,1) both 300ms; }
@keyframes locketSwing {
  0%   { opacity: 0; transform: rotate(-15deg) scale(2); }
  60%  { opacity: 1; transform: rotate(6deg) scale(2); }
  100% { opacity: 1; transform: rotate(0deg) scale(2); }
}

/* Tombol kancing navy: pojok kanan-bawah kartu */
.deco.button {
  right: -5%; bottom: -3%;
  width: 12%;
  filter: drop-shadow(0 5px 8px rgba(0,0,0,.25));
  transition: opacity 400ms ease;
}
#scene-3.play .deco.button { animation: fadeIn 400ms ease forwards 600ms; }

/* Foto kucing topi pesta: pojok kiri-bawah, MUNCUL duluan (bareng klip/bola,
   sebelum locket & button), scale 0→1 dengan overshoot */
.deco.cat {
  left: -9%; bottom: -6%;
  width: 16.5%;                  /* dikecilkan jadi 3/4 (dari 22%) */
  transform: scale(0);
  transform-origin: bottom center;
  filter: drop-shadow(0 8px 12px rgba(0,0,0,.28));
}
#scene-3.play .deco.cat { animation: catPop 500ms cubic-bezier(.34,1.56,.64,1) forwards 150ms; }
@keyframes catPop {
  from { opacity: 0; transform: scale(0); }
  to   { opacity: 1; transform: scale(1); }
}

/* Link "next" di bawah kartu */
.next-link {
  position: absolute; left: 50%; bottom: 8%;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: 20px; letter-spacing: 1px;
  color: var(--teal);
  text-decoration: underline;
  cursor: pointer;
  opacity: 0;
  transition: opacity 500ms ease, color .2s, scale .2s;
}
#scene-3.play .next-link { opacity: 1; transition-delay: 900ms; }
.next-link:hover { color: #9ecad9; scale: 1.05; }

/* ══════════════════════════════════════════════════════════════════
   SCENE 4 — CLOSING: Hati melayang + Happy Birthday
   Background = curtain tertutup statis. Hati melayang (spring/overshoot)
   ke tengah (2.5s), lalu teks "Happy Birthday Nathan!" fade in di dalam
   hati (delay 2.5s).
   NOTE unit: font-size pakai px (bukan vw) karena #stage sudah di-scale
   uniform → px otomatis proporsional; vw akan lepas dari kanvas.
   ══════════════════════════════════════════════════════════════════ */

/* Transisi masuk: TIRAI MENUTUP dari kiri-kanan ke tengah (di atas bg taman). */
#scene-4 #closing-curtain .curtain-panel { transition: transform 1200ms ease-in-out; }
#scene-4 #closing-curtain .curtain-panel.left  { transform: translateX(-102%); }            /* mulai TERBUKA (di tepi) */
#scene-4 #closing-curtain .curtain-panel.right { transform: scaleX(-1) translateX(-102%); }
#scene-4.play #closing-curtain .curtain-panel.left  { transform: translateX(0); }            /* MENUTUP ke tengah */
#scene-4.play #closing-curtain .curtain-panel.right { transform: scaleX(-1) translateX(0); }

/* Hati melayang — muncul SETELAH tirai menutup (delay ~1.3s). */
.heart-shape {
  position: absolute;
  left: 21.7%; top: 65.9%;
  transform: translate(-50%, -50%) scale(0.8);
  width: 36%; height: auto;
  opacity: 0;                    /* disembunyikan sampai animasi mulai */
  filter: drop-shadow(0 0 26px rgba(255,255,255,.45));
  pointer-events: none;
  z-index: 1;
}
/* Hati versi SVG proporsinya lebih tinggi → dikecilkan lebarnya biar seimbang.
   (Kalau ganti ke PNG hati LEBAR spt heart-text, hapus baris ini → balik 36%.) */
svg.heart-shape { width: 56%; }   /* diperbesar 2× (dari 28%) */
#scene-4.play .heart-shape { animation: heartFloat 2500ms cubic-bezier(0.34,1.56,0.64,1) forwards 1300ms; }
@keyframes heartFloat {
  0%   { left: 21.7%; top: 65.9%; transform: translate(-50%,-50%) scale(0.8);  opacity: 0.30; }
  60%  { left: 62.8%; top: 65.2%; transform: translate(-50%,-50%) scale(1.05); opacity: 0.45; }
  100% { left: 50%;   top: 49.4%; transform: translate(-50%,-50%) scale(1);    opacity: 0.55; }
}

/* Kalimat ucapan closing (1 blok, boleh multi-baris), di dalam hati,
   fade in di 2.5s. Isi diganti dari ?ucapan. */
.final-text {
  position: absolute; left: 50%; top: 46%;
  transform: translate(-50%, -50%);
  z-index: 2;
  width: 62%;
  text-align: center;
  font-family: var(--font-script);
  color: #ffffff;
  font-size: 78px;                 /* diperbesar 1.5× (dari 52px) */
  line-height: 1.15;
  white-space: pre-line;           /* \n dari input → baris baru */
  text-shadow: 0 0 12px rgba(255,255,255,0.55), 0 3px 12px rgba(0,0,0,0.45);
  opacity: 0;
}
#scene-4.play .final-text { animation: fadeIn 1000ms ease forwards 3800ms; }

/* ══════════════════════════════════════════════════════════════════
   UI — dots progres & replay
   ══════════════════════════════════════════════════════════════════ */
#dots {
  position: absolute; left: 50%; bottom: 22px;
  transform: translateX(-50%);
  display: flex; gap: 12px;
  z-index: 50;
}
#dots .dot {
  width: 11px; height: 11px; border-radius: 50%;
  background: rgba(255,255,255,.35);
  border: 1px solid rgba(255,255,255,.5);
  cursor: pointer;
  transition: background .25s, transform .25s;
}
#dots .dot.active { background: #fff; transform: scale(1.25); }

#replay {
  position: absolute; right: 22px; bottom: 18px;
  z-index: 50;
  display: none;                 /* muncul di scene terakhir (via JS) */
  font-family: var(--font-mono);
  font-size: 15px; letter-spacing: .5px;
  color: rgba(255,255,255,.9);
  background: rgba(0,0,0,.28);
  border: 1px solid rgba(255,255,255,.4);
  border-radius: 20px;
  padding: 7px 16px;
  cursor: pointer;
  transition: background .2s;
}
#replay:hover { background: rgba(0,0,0,.5); }
