/* majlis.click — animasi pembukaan kad (tema Kad Buka). Warna & seni daripada tema-{kunci}.css */
.opener {
  --op-bg: var(--bg); --op-paper: #fff; --op-ink: var(--text); --op-accent: var(--accent); --op-mono-c: #fff;
  --op-art: none; --op-art2: none; --op-seal: none; --op-font: var(--f-script);
  position: fixed; inset: 0; z-index: 55; overflow: hidden; cursor: pointer; background: var(--op-bg);
  -webkit-tap-highlight-color: transparent; user-select: none; -webkit-user-select: none;
  transition: background-color .6s ease .3s;
}
.opener:focus { outline: none; }
.opener:focus-visible .op-seal, .opener:focus-visible .op-bow, .opener:focus-visible .op-knot { outline: 2px solid var(--op-accent); outline-offset: 6px; }
.has-preview .opener { top: 60px; }
.op-stage { position: absolute; inset: 0; margin: 0 auto; width: min(100%, 560px); perspective: 1600px; perspective-origin: 50% 50%; }
.opener.is-opening { background-color: transparent; pointer-events: none; }
.opener.is-done { opacity: 0; transition: opacity .35s ease; }

/* Teks kaki: nama tetamu + petunjuk ketuk */
.op-foot { position: absolute; left: 0; right: 0; bottom: max(28px, env(safe-area-inset-bottom)); z-index: 20; display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none; text-align: center; padding: 0 20px; transition: opacity .3s ease; }
.op-guest { font: 500 13px/1.4 var(--f-body, 'Jost', sans-serif); color: var(--op-ink); background: color-mix(in srgb, var(--op-paper) 88%, transparent); padding: 6px 14px; border-radius: 999px; box-shadow: 0 4px 14px rgba(0,0,0,.08); }
.op-guest b { font-weight: 600; }
.op-hint { font: 600 11px/1 var(--f-label, var(--f-body, 'Jost', sans-serif)); letter-spacing: .28em; text-transform: uppercase; color: var(--op-ink); background: color-mix(in srgb, var(--op-paper) 80%, transparent); padding: 9px 16px; border-radius: 999px; animation: op-pulse 2.2s ease-in-out infinite; }
.opener.is-opening .op-foot { opacity: 0; }
@keyframes op-pulse { 0%, 100% { opacity: .55; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-3px); } }

/* Mohor lilin (umum) */
.op-seal {
  position: absolute; z-index: 10; left: 50%; top: 50%; width: 118px; height: 118px; margin: -59px 0 0 -59px;
  display: flex; align-items: center; justify-content: center;
  transition: transform .45s cubic-bezier(.5,-0.4,.6,1), opacity .35s ease .15s; will-change: transform;
  animation: op-breathe 3s ease-in-out infinite;
}
.op-seal::before { content: ''; position: absolute; left: 12%; right: 12%; top: 22%; bottom: 2%; border-radius: 50%; background: radial-gradient(closest-side, rgba(0,0,0,.32), transparent); transform: translateY(7px); }
.op-seal::after { content: ''; position: absolute; inset: 0; background: var(--op-seal) no-repeat center / contain; }
.op-seal .op-mono { position: relative; z-index: 1; }
.op-mono { font-family: var(--op-font); font-size: 34px; line-height: 1; color: var(--op-mono-c); text-shadow: 0 1px 0 rgba(0,0,0,.25), 0 -1px 0 rgba(255,255,255,.3); white-space: nowrap; transform: translateY(2px); }
@keyframes op-breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.04); } }
.opener.is-opening .op-seal { animation: none; transform: scale(1.25); opacity: 0; }

/* Seni latar penuh */
.op-art { position: absolute; inset: 0; background: var(--op-art) no-repeat center / cover; }

/* ============ 1. GATEFOLD: dua panel + mohor di sambungan ============ */
.op-gatefold { --seam: 44%; }
.op-gatefold .op-panel { will-change: transform; position: absolute; top: 0; bottom: 0; overflow: hidden; background: var(--op-paper); transition: transform 1.3s cubic-bezier(.55,.05,.25,1) .35s, box-shadow 1.3s ease .35s; backface-visibility: hidden; }
.op-gatefold .op-l { left: 0; width: var(--seam); transform-origin: 0 50%; }
.op-gatefold .op-r { right: 0; width: calc(100% - var(--seam)); transform-origin: 100% 50%; box-shadow: -10px 0 22px rgba(0,0,0,.13); }
.op-gatefold .op-panel .op-art { right: auto; width: min(100vw, 560px); }
.op-gatefold .op-r .op-art { left: auto; right: 0; }
.op-gatefold .op-seal { left: var(--seam); }
.op-gatefold.is-opening .op-l { transform: rotateY(-105deg); }
.op-gatefold.is-opening .op-r { transform: rotateY(105deg); box-shadow: 0 0 0 rgba(0,0,0,0); }

/* ============ 2. GATE: pintu gerbang berkembar + burung merpati ============ */
.op-gate .op-glow { position: absolute; inset: 0; background: radial-gradient(ellipse at 50% 55%, rgba(255,250,235,1) 0%, rgba(255,246,220,.85) 30%, transparent 70%); opacity: 0; transition: opacity .8s ease .4s; }
.op-gate .op-door { will-change: transform; position: absolute; top: 0; bottom: 0; width: 50%; overflow: hidden; background: var(--op-paper); transition: transform 1.6s cubic-bezier(.6,.02,.3,1) .45s; backface-visibility: hidden; }
.op-gate .op-door .op-art { background-image: var(--op-art2); background-size: 100% 100%; }
.op-gate .op-l { left: 0; transform-origin: 0 50%; }
.op-gate .op-r { right: 0; transform-origin: 100% 50%; }
.op-gate .op-r .op-art { transform: scaleX(-1); }
.op-gate .op-frame { position: absolute; inset: 0; background: var(--op-art) no-repeat center / 100% 100%; z-index: 5; pointer-events: none; transition: transform 2s cubic-bezier(.5,0,.3,1) .5s, opacity 1s ease 1.2s; }
.op-gate .op-seal { width: 96px; height: 96px; margin: -48px 0 0 -48px; }
.op-gate .op-mono { font-size: 28px; }
.op-gate.is-opening .op-glow { opacity: 1; }
.op-gate.is-opening .op-l { transform: rotateY(82deg); }
.op-gate.is-opening .op-r { transform: rotateY(-82deg); }
.op-gate.is-opening .op-frame { transform: scale(1.35); opacity: 0; }

/* ============ 3. BUTTERFLY: rama-rama hinggap, terbang bila diketuk ============ */
.op-butterfly .op-art { transition: transform 1.4s ease .3s, opacity 1s ease .7s; }
.op-card { position: absolute; left: 50%; top: 46%; transform: translate(-50%, -50%); width: 64%; max-width: 300px; padding: 34px 18px; text-align: center; display: flex; flex-direction: column; gap: 10px; align-items: center;
  background: color-mix(in srgb, var(--op-paper) 86%, transparent); border-radius: 160px 160px 18px 18px; border: 1px solid color-mix(in srgb, var(--op-accent) 55%, transparent); box-shadow: 0 18px 50px rgba(60,40,80,.14);
  transition: transform 1.2s ease .2s, opacity .5s ease .2s; }
.op-kicker { font: 600 10px/1.2 var(--f-label, var(--f-body, 'Jost', sans-serif)); letter-spacing: .3em; color: var(--op-accent); text-transform: uppercase; }
.op-names { font-family: var(--op-font); font-size: 40px; line-height: 1.1; color: var(--op-ink); overflow-wrap: anywhere; }
.op-bf { position: absolute; left: var(--x); top: var(--y); width: 92px; height: 74px; margin: -37px 0 0 -46px; z-index: 6; transform: rotate(var(--r)) scale(var(--s)); transition: transform 2.2s cubic-bezier(.45,.05,.35,1) calc(var(--i) * .08s), opacity .7s ease calc(1.4s + var(--i) * .08s); }
.op-bf b { position: absolute; top: 0; width: 50%; height: 100%; background: var(--bf) no-repeat right center / 200% 100%; transform-origin: 100% 50%; animation: op-flap 1.6s ease-in-out infinite; animation-delay: var(--d); }
.op-bf b:first-child { left: 0; }
.op-bf b:last-child { right: 0; background-position: left center; transform-origin: 0 50%; animation-name: op-flap-r; }
.op-bf1 { --bf: var(--op-bf1); } .op-bf2 { --bf: var(--op-bf2); } .op-bf3 { --bf: var(--op-bf3); }
@keyframes op-flap { 0%, 60%, 100% { transform: scaleX(1); } 75% { transform: scaleX(.35); } }
@keyframes op-flap-r { 0%, 60%, 100% { transform: scaleX(1); } 75% { transform: scaleX(.35); } }
.op-butterfly.is-opening .op-bf b { animation-duration: .22s; animation-delay: 0s; animation-name: op-flap-fast; }
@keyframes op-flap-fast { 0%, 100% { transform: scaleX(1); } 50% { transform: scaleX(.2); } }
.op-butterfly.is-opening .op-bf { transform: translate(var(--fx, 0), var(--fy, -120vh)) rotate(calc(var(--r) + 25deg)) scale(calc(var(--s) * .8)); opacity: 0; }
.op-butterfly.is-opening .op-art { transform: scale(1.12); opacity: 0; }
.op-butterfly.is-opening .op-card { transform: translate(-50%, -50%) scale(1.25); opacity: 0; }

/* ============ 4. ENVELOPE: sampul surat, penutup terbuka, surat keluar ============ */
.op-envelope .op-art { transition: opacity .9s ease 2.1s; }
.op-env { position: absolute; left: 50%; top: 50%; width: 84%; max-width: 380px; aspect-ratio: 1.45; transform: translate(-50%, -42%); perspective: 900px; transition: transform 1s cubic-bezier(.5,0,.3,1) 2.1s; }
.op-back, .op-pocket { position: absolute; inset: 0; border-radius: 6px; }
/* bahagian dalam sampul: pelapik bercorak bunga */
.op-back { background: var(--op-liner, var(--op-env2, #E9DCCB)) center / cover; box-shadow: 0 22px 50px rgba(50,30,20,.25); }
.op-pocket { background: var(--op-env, #F3E8DA); clip-path: polygon(0 0, 50% 54%, 100% 0, 100% 100%, 0 100%); z-index: 3;
  background-image: linear-gradient(155deg, rgba(0,0,0,.07), transparent 42%), linear-gradient(205deg, rgba(0,0,0,.07), transparent 42%), var(--op-env-img, none); background-size: auto, auto, cover; }
/* garis lipatan sampul */
.op-pocket::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to top right, transparent calc(50% - 1px), rgba(120,80,60,.14) 50%, transparent calc(50% + 1px)) left bottom / 50% 100% no-repeat, linear-gradient(to top left, transparent calc(50% - 1px), rgba(120,80,60,.14) 50%, transparent calc(50% + 1px)) right bottom / 50% 100% no-repeat; }
.op-flap { position: absolute; left: 0; right: 0; top: 0; height: 62%; transform-origin: 50% 0; z-index: 4; transform-style: preserve-3d;
  transition: transform .8s cubic-bezier(.5,0,.4,1) .3s, z-index 0s linear .7s; }
.op-f1, .op-f2 { position: absolute; inset: 0; clip-path: polygon(0 0, 100% 0, 50% 100%); backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.op-f1 { background: linear-gradient(180deg, rgba(0,0,0,.02), rgba(0,0,0,.1)), var(--op-env-img, none) center / cover, var(--op-env, #F3E8DA); }
.op-f2 { background: var(--op-liner, var(--op-env2, #E9DCCB)) center / cover; transform: rotateX(180deg); clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.op-letter { position: absolute; left: 6%; right: 6%; top: 6%; height: 88%; background: var(--op-paper); border-radius: 4px; z-index: 2; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; text-align: center; padding: 10px;
  box-shadow: 0 2px 8px rgba(0,0,0,.1); background-image: var(--op-art2); background-size: cover; background-position: center; transition: transform 1.1s cubic-bezier(.4,0,.2,1) 1s; }
.op-letter .op-names { font-size: 32px; }
.op-envelope .op-seal { width: 74px; height: 74px; margin: -37px 0 0 -37px; top: 60%; z-index: 6; }
.op-envelope .op-mono { font-size: 22px; }
.op-envelope.is-opening .op-flap { transform: rotateX(180deg); z-index: 1; }
.op-envelope.is-opening .op-letter { animation: op-letter 3s cubic-bezier(.4,0,.2,1) forwards; }
@keyframes op-letter { 0%, 32% { transform: none; opacity: 1; } 62% { transform: translateY(-62%); opacity: 1; } 100% { transform: translateY(-20%) scale(2.3); opacity: 0; } }
.op-envelope.is-opening .op-env { transform: translate(-50%, 30%) scale(1.05); }
.op-envelope.is-opening .op-back, .op-envelope.is-opening .op-pocket, .op-envelope.is-opening .op-f1, .op-envelope.is-opening .op-f2 { opacity: 0; transition: opacity .6s ease 2s; }
.op-envelope.is-opening .op-art { opacity: 0; }

/* ============ 5. CURTAIN: tirai baldu terbelah ============ */
.op-curtain .op-glow { position: absolute; inset: 0; background: radial-gradient(ellipse at 50% 35%, rgba(255,236,190,.55), transparent 65%); opacity: 0; transition: opacity 1s ease .3s; }
.op-drape { position: absolute; top: 0; bottom: 0; width: 50.5%; background: var(--op-art) repeat-x 0 0 / auto 100%; transition: transform 1.7s cubic-bezier(.6,0,.25,1) .4s; z-index: 2; will-change: transform; transform-origin: 0 50%; }
.op-drape::after { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(0,0,0,.25), transparent 18%, transparent 82%, rgba(0,0,0,.3)); }
.op-curtain .op-l { left: 0; }
.op-curtain .op-r { right: 0; transform-origin: 100% 50%; }
.op-valance { position: absolute; left: 0; right: 0; top: 0; height: 13%; z-index: 4; background: var(--op-art2) repeat-x center top / auto 100%; filter: drop-shadow(0 6px 8px rgba(0,0,0,.3)); transition: transform 1.2s ease 1s; }
.op-tassel { position: absolute; top: 44%; width: 26px; height: 96px; background: var(--op-tassel) no-repeat center / contain; z-index: 5; transition: transform 1.7s cubic-bezier(.6,0,.25,1) .4s, opacity .6s ease .5s; }
.op-tl { left: 4%; } .op-tr { right: 4%; }
.op-curtain .op-seal { z-index: 6; }
.op-curtain.is-opening .op-glow { opacity: 1; }
.op-curtain.is-opening .op-l { transform: scaleX(.26); }
.op-curtain.is-opening .op-r { transform: scaleX(.26); }
.op-curtain.is-opening .op-valance { transform: translateY(-110%); }

/* ============ 6. SLIDE: pintu kekisi gelongsor ============ */
.op-slide .op-glow { position: absolute; inset: 0; background: radial-gradient(ellipse 40% 60% at 50% 50%, rgba(255,244,210,1), rgba(255,232,170,.6) 45%, rgba(255,232,170,0) 75%); opacity: 0; transform: scaleX(.05); transition: opacity .5s ease .4s, transform 1.5s cubic-bezier(.65,0,.3,1) .55s; z-index: 1; will-change: transform; }
.op-leaf { will-change: transform; position: absolute; top: 0; bottom: 0; width: 50%; overflow: hidden; background: var(--op-paper); z-index: 2; transition: transform 1.5s cubic-bezier(.65,0,.3,1) .55s; }
.op-leaf .op-art { background: var(--op-art2) no-repeat center / 100% 100%; }
.op-slide .op-l { left: 0; }
.op-slide .op-r { right: 0; }
.op-slide .op-r .op-art { transform: scaleX(-1); }
.op-slide .op-mono { font-family: 'Amiri', serif; font-size: 20px; line-height: 1.5; }
.op-slide.is-opening .op-glow { opacity: 1; transform: scaleX(2.2); }
.op-slide.is-opening .op-l { transform: translateX(-102%); }
.op-slide.is-opening .op-r { transform: translateX(102%); }
.op-slide.is-opening .op-seal { transform: translateY(-40px) scale(1.1); }

/* ============ 7. FOLD: lipatan atas & bawah ============ */
.op-flap2 { will-change: transform; position: absolute; left: 0; right: 0; height: 50%; overflow: hidden; background: var(--op-paper); transition: transform 1.25s cubic-bezier(.55,0,.3,1); backface-visibility: hidden; }
.op-flap2 .op-art { height: 200%; }
.op-t { top: 0; transform-origin: 50% 0; transition-delay: .35s; }
.op-b { bottom: 0; transform-origin: 50% 100%; transition-delay: .75s; box-shadow: 0 -10px 22px rgba(0,0,0,.18); }
.op-b .op-art { top: auto; bottom: 0; }
.op-fold .op-seal { z-index: 10; }
.op-fold.is-opening .op-t { transform: rotateX(100deg); }
.op-fold.is-opening .op-b { transform: rotateX(-100deg); }

/* ============ 8. RIBBON: kotak hadiah berreben ============ */
.op-lid { position: absolute; inset: 0; transition: transform 1.2s cubic-bezier(.6,0,.3,1) 1.1s, opacity .9s ease 1.4s; }
.op-rib { position: absolute; --lo: var(--op-rib-lo, #A87B55); --mid: var(--op-rib, #D8B593); --hi: var(--op-rib-hi, #F7E3C8);
  box-shadow: 0 3px 10px rgba(80,50,30,.22); transition: transform 1s cubic-bezier(.6,0,.3,1) .45s; }
/* satin: gelap di tepi, kilat di tengah, jahitan halus di kedua-dua sisi */
.op-rib::before { content: ''; position: absolute; inset: 0; border: 0 dashed rgba(255,248,236,.55); }
.op-rv1, .op-rv2 { left: 50%; width: 50px; margin-left: -25px; background: linear-gradient(90deg, var(--lo) 0, var(--mid) 14%, var(--hi) 36%, var(--mid) 56%, color-mix(in srgb, var(--mid) 80%, var(--lo)) 80%, var(--lo) 100%); }
.op-rv1::before, .op-rv2::before { left: 5px; right: 5px; border-left-width: 1px; border-right-width: 1px; }
.op-rv1 { top: 0; height: 56%; } .op-rv2 { bottom: 0; height: 44%; }
.op-rh1, .op-rh2 { top: 56%; height: 44px; margin-top: -22px; background: linear-gradient(180deg, var(--lo) 0, var(--mid) 14%, var(--hi) 36%, var(--mid) 56%, color-mix(in srgb, var(--mid) 80%, var(--lo)) 80%, var(--lo) 100%); }
.op-rh1::before, .op-rh2::before { top: 5px; bottom: 5px; border-top-width: 1px; border-bottom-width: 1px; }
.op-rh1 { left: 0; width: 50%; } .op-rh2 { right: 0; width: 50%; }
.op-bow { position: absolute; left: 50%; top: 56%; width: 206px; height: 158px; margin: -84px 0 0 -103px; background: var(--op-bow) no-repeat center / contain; z-index: 8; transition: transform .6s cubic-bezier(.5,-0.5,.6,1), opacity .4s ease .2s; animation: op-breathe 3s ease-in-out infinite; }
.op-tag { position: absolute; left: 50%; top: 22%; transform: translateX(-50%) rotate(-4deg); background: var(--op-paper); padding: 16px 26px 14px; border-radius: 6px; box-shadow: 0 8px 20px rgba(0,0,0,.12); z-index: 7; text-align: center; transition: transform .8s ease .2s, opacity .5s ease .2s; }
.op-tag::before { content: ''; position: absolute; left: 50%; top: 7px; width: 8px; height: 8px; margin-left: -4px; border-radius: 99px; box-shadow: inset 0 0 0 1.5px var(--op-accent); }
.op-tag .op-names { font-size: 30px; }
.op-ribbon.is-opening .op-bow { animation: none; transform: scale(.2) rotate(40deg); opacity: 0; }
.op-ribbon.is-opening .op-tag { transform: translate(-50%, -30px) rotate(-12deg); opacity: 0; }
.op-ribbon.is-opening .op-rib { opacity: 0; transition: transform 1s cubic-bezier(.6,0,.3,1) .45s, opacity .3s ease 1.1s; }
.op-ribbon.is-opening .op-rv1 { transform: translateY(-105%); }
.op-ribbon.is-opening .op-rv2 { transform: translateY(105%); }
.op-ribbon.is-opening .op-rh1 { transform: translateX(-105%); }
.op-ribbon.is-opening .op-rh2 { transform: translateX(105%); }
.op-ribbon.is-opening .op-lid { transform: translateY(-104%) rotate(-3deg); opacity: .2; }

/* ============ 9. BLOOM: kelopak bunga mekar terbuka ============ */
.op-bloom .op-art { transition: opacity .9s ease 1s; }
.op-petals { position: absolute; left: 50%; top: 50%; width: 0; height: 0; }
.op-ring { position: absolute; left: 0; top: 0; width: 0; height: 0; will-change: transform, opacity; }
.op-ring-o { transition: transform 1.6s cubic-bezier(.4,0,.2,1) .5s, opacity .9s ease 1.1s; }
.op-ring-i { transition: transform 1.3s cubic-bezier(.4,0,.2,1) .2s, opacity .7s ease .6s; }
.op-petal { position: absolute; left: -150px; top: -420px; width: 300px; height: 420px; background: var(--op-petal) no-repeat center bottom / 100% 100%; transform-origin: 50% 100%; transform: rotate(var(--a)) scale(var(--sc, 1)); }
.op-petal.op-in { --sc: .62; background-image: var(--op-petal2, var(--op-petal)); }
.op-bloom.is-opening .op-ring-o { transform: rotate(28deg) scale(1.7); opacity: 0; }
.op-bloom.is-opening .op-ring-i { transform: rotate(-35deg) scale(2.4); opacity: 0; }
.op-bloom .op-seal { width: 128px; height: 128px; margin: -64px 0 0 -64px; }
.op-bloom.is-opening .op-art { opacity: 0; }

/* ============ 10. SCROLL: gulungan titah dibuka ============ */
.op-scroll .op-art { transition: opacity .8s ease 1.7s; }
.op-paper { position: absolute; left: 9%; right: 9%; top: 12%; bottom: 12%; background: var(--op-paper) var(--op-art2) center / cover; box-shadow: 0 10px 40px rgba(0,0,0,.35);
  clip-path: inset(50% 0 50% 0); transition: clip-path 1.3s cubic-bezier(.55,0,.25,1) .55s, opacity .7s ease 1.8s; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; text-align: center; padding: 20px; }
.op-paper .op-names { font-size: 44px; }
.op-rod { position: absolute; left: 4%; right: 4%; height: 34px; top: 50%; background: var(--op-rod) no-repeat center / 100% 100%; z-index: 4; filter: drop-shadow(0 6px 8px rgba(0,0,0,.35)); transition: transform 1.3s cubic-bezier(.55,0,.25,1) .55s, opacity .7s ease 1.8s; }
.op-rt { margin-top: -33px; } .op-rb { margin-top: -1px; }
.op-knot { position: absolute; left: 50%; top: 50%; width: 92px; height: 150px; margin: -52px 0 0 -46px; background: var(--op-knot) no-repeat center top / contain; z-index: 6; transition: transform .7s cubic-bezier(.5,-0.3,.6,1), opacity .4s ease .2s; animation: op-breathe 3s ease-in-out infinite; }
.op-scroll.is-opening .op-knot { animation: none; transform: translateY(60px) rotate(12deg); opacity: 0; }
.op-scroll.is-opening .op-paper { clip-path: inset(0 0 0 0); opacity: 0; }
.op-scroll.is-opening .op-rt { transform: translateY(calc(-38vh + 20px)); opacity: 0; }
.op-scroll.is-opening .op-rb { transform: translateY(calc(38vh - 20px)); opacity: 0; }
.op-scroll.is-opening .op-art { opacity: 0; }

/* ============ Makhluk terbang (lapisan berasingan) ============ */
.op-fly { position: fixed; inset: 0; z-index: 56; pointer-events: none; overflow: hidden; }
.op-fly i { position: absolute; left: var(--x0); top: var(--y0); width: var(--w); height: var(--h); margin: calc(var(--h) / -2) 0 0 calc(var(--w) / -2);
  animation: op-flyaway var(--t) cubic-bezier(.35,.1,.45,1) var(--dl) forwards; opacity: 0; }
.op-fly i > s { position: absolute; inset: 0; background: var(--img) no-repeat center / contain; }
.op-fly i.op-flip > s { transform: scaleX(-1); }
@keyframes op-flyaway {
  0% { opacity: 0; transform: translate(0, 0) rotate(var(--r0)) scale(.4); }
  12% { opacity: 1; }
  80% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) rotate(var(--r1)) scale(var(--s1)); }
}
.op-fly .op-dove > s { animation: op-wing .36s steps(1) infinite; }
@keyframes op-wing { 0% { background-image: var(--img); } 50% { background-image: var(--img2); } }
.op-fly .op-bfly > s { animation: op-flap var(--fl, .2s) ease-in-out infinite alternate; }
@keyframes op-flap { from { transform: scaleX(1); } to { transform: scaleX(.3); } }

/* Kurang gerakan: pudar sahaja (JS guna .is-fade, bukan .is-opening) */
.opener.is-fade { opacity: 0; pointer-events: none; transition: opacity .45s ease; }
@media (prefers-reduced-motion: reduce) {
  .opener, .opener * { animation: none !important; }
  .op-fly { display: none; }
}

/* =====================================================================
   KAD BUKA 3D (5 Okt 2026): 10 gaya asal kini Kad 3D.
   Kamera (.op-cam) bergoyang perlahan sebelum diketuk & meluncur masuk bila dibuka,
   panel ada muka / belakang / tebal kertas / bayang, lapisan pada kedalaman berbeza.
   Elakkan opacity < 1 pada elemen preserve-3d yang ada anak 3D (Chrome meratakannya).
   ===================================================================== */
.opener:not(.op-3d) .op-stage { perspective: 1100px; perspective-origin: 50% 50%; }
.op-cam { position: absolute; inset: 0; transform-style: preserve-3d; will-change: transform;
  animation: op-idle3d 7s ease-in-out infinite; transition: transform 2.3s cubic-bezier(.5,0,.2,1) .3s; }
@keyframes op-idle3d { 0%, 100% { transform: rotateY(-2.2deg) rotateX(1.2deg); } 50% { transform: rotateY(2.2deg) rotateX(-1.2deg); } }
.opener.is-opening .op-cam { animation: none; transform: translateZ(var(--cam-z, 220px)); }

/* Panel tebal: muka bercetak, belakang (nampak bila panel melepasi 90°), tebal kertas & bayang */
.op-panel, .op-door, .op-leaf, .op-flap2 { transform-style: preserve-3d; overflow: visible !important; background: none !important;
  -webkit-backface-visibility: visible !important; backface-visibility: visible !important; box-shadow: none !important; }
.op-face { position: absolute; inset: 0; overflow: hidden; background: var(--op-paper); -webkit-backface-visibility: hidden; backface-visibility: hidden; }
.op-rear { position: absolute; inset: 0; -webkit-backface-visibility: hidden; backface-visibility: hidden; transform: rotateY(180deg);
  background: linear-gradient(90deg, rgba(0,0,0,.18), rgba(0,0,0,.04) 40%, rgba(0,0,0,.12)), color-mix(in srgb, var(--op-paper) 88%, var(--op-accent)); }
.op-thick { position: absolute; background: linear-gradient(90deg, color-mix(in srgb, var(--op-paper) 62%, #5a4632), color-mix(in srgb, var(--op-paper) 80%, #5a4632)); }
.op-sh { position: absolute; inset: 0; pointer-events: none; opacity: 0; z-index: 3; }
/* panel berengsel kiri/kanan */
.op-panel.op-l .op-thick, .op-door.op-l .op-thick, .op-leaf.op-l .op-thick { top: 0; bottom: 0; right: 0; width: 9px; transform-origin: 100% 50%; transform: rotateY(90deg); }
.op-panel.op-r .op-thick, .op-door.op-r .op-thick, .op-leaf.op-r .op-thick { top: 0; bottom: 0; left: 0; width: 9px; transform-origin: 0 50%; transform: rotateY(-90deg); }
.op-panel.op-l .op-sh, .op-door.op-l .op-sh, .op-leaf.op-l .op-sh { background: linear-gradient(90deg, rgba(20,10,0,.06), rgba(20,10,0,.5)); }
.op-panel.op-r .op-sh, .op-door.op-r .op-sh, .op-leaf.op-r .op-sh { background: linear-gradient(270deg, rgba(20,10,0,.06), rgba(20,10,0,.5)); }
/* panel berengsel atas/bawah (lipatan) */
.op-flap2 .op-rear { transform: rotateX(180deg); background: linear-gradient(180deg, rgba(0,0,0,.16), rgba(0,0,0,.04)), color-mix(in srgb, var(--op-paper) 88%, var(--op-accent)); }
.op-flap2.op-t .op-thick { left: 0; right: 0; bottom: 0; height: 9px; transform-origin: 50% 100%; transform: rotateX(-90deg); }
.op-flap2.op-b .op-thick { left: 0; right: 0; top: 0; height: 9px; transform-origin: 50% 0; transform: rotateX(90deg); }
.op-flap2.op-t .op-sh { background: linear-gradient(180deg, rgba(20,10,0,.05), rgba(20,10,0,.5)); }
.op-flap2.op-b .op-sh { background: linear-gradient(0deg, rgba(20,10,0,.05), rgba(20,10,0,.5)); }
.op-flap2.op-b .op-face { box-shadow: 0 -10px 22px rgba(0,0,0,.18); }

/* 1. Mohor (gatefold): panel tebal berayun, kamera masuk */
.op-gatefold { --cam-z: 260px; }
.op-gatefold .op-r .op-face { box-shadow: -10px 0 22px rgba(0,0,0,.13); }
.op-gatefold .op-sh { transition: opacity 1.4s ease .35s; }
.op-gatefold .op-panel { transition: transform 1.8s cubic-bezier(.45,0,.25,1) .35s !important; }
.op-gatefold.is-opening .op-sh { opacity: 1; }
.op-gatefold.is-opening .op-l { transform: rotateY(118deg); }
.op-gatefold.is-opening .op-r { transform: rotateY(-118deg); }

/* 2. Merpati (gate): pintu gerbang tebal berayun ke dalam, cahaya jauh di belakang, kamera melangkah masuk */
.op-gate { --cam-z: 330px; }
.op-gate .op-glow { transform: translateZ(-320px) scale(1.3); }
.op-gate .op-frame { transform-origin: 50% 55%; }
.op-gate .op-sh { transition: opacity 1.6s ease .45s; }
.op-gate.is-opening .op-sh { opacity: 1; }
.op-gate.is-opening .op-frame { transform: translateZ(140px) scale(1.2); }

/* 3. Rama-rama (butterfly): kepak 3D sebenar, setiap rama-rama pada kedalaman sendiri, terbang ke arah tetamu */
.op-butterfly { --cam-z: 160px; }
.op-butterfly .op-art { transform: translateZ(-160px) scale(1.15); }
.op-butterfly .op-card { transform-style: preserve-3d; }
.op-butterfly .op-bf { transform-style: preserve-3d; transform: translateZ(calc((var(--i) - 2.5) * 46px)) rotate(var(--r)) scale(var(--s)); }
.op-butterfly .op-bf b { -webkit-backface-visibility: visible; backface-visibility: visible; }
.op-butterfly .op-bf b:first-child { animation-name: op-w3l; }
.op-butterfly .op-bf b:last-child { animation-name: op-w3r; }
@keyframes op-w3l { 0%, 55%, 100% { transform: rotateY(0); } 72% { transform: rotateY(62deg); } }
@keyframes op-w3r { 0%, 55%, 100% { transform: rotateY(0); } 72% { transform: rotateY(-62deg); } }
@keyframes op-w3lf { 0%, 100% { transform: rotateY(8deg); } 50% { transform: rotateY(72deg); } }
@keyframes op-w3rf { 0%, 100% { transform: rotateY(-8deg); } 50% { transform: rotateY(-72deg); } }
.op-butterfly.is-opening .op-bf b:first-child { animation: op-w3lf .22s ease-in-out infinite; }
.op-butterfly.is-opening .op-bf b:last-child { animation: op-w3rf .22s ease-in-out infinite; }
.op-butterfly.is-opening .op-bf { transform: translate(var(--fx, 0), var(--fy, -120vh)) translateZ(420px) rotate(calc(var(--r) + 25deg)) scale(calc(var(--s) * .8)); }
.op-butterfly.is-opening .op-art { transform: translateZ(-160px) scale(1.3); }
.op-butterfly.is-opening .op-card { transform: translate(-50%, -50%) translateZ(-260px) rotateX(58deg); opacity: 0; transition: transform 1.3s cubic-bezier(.5,0,.3,1) .15s, opacity .7s ease .55s; }

/* 4. Warkah (envelope): sampul terbaring condong, surat naik ke arah tetamu */
.op-envelope { --cam-z: 120px; }
.op-envelope .op-art { transform: translateZ(-140px) scale(1.13); }
.op-env { transform-style: preserve-3d; transform: translate(-50%, -42%) rotateX(24deg); }
.op-env .op-back { box-shadow: 0 34px 46px -12px rgba(50,30,20,.38); }
.op-envelope.is-opening .op-env { transform: translate(-50%, 30%) rotateX(48deg) scale(1.05); }
.op-envelope.is-opening .op-letter { animation-name: op-letter3d; }
@keyframes op-letter3d {
  0%, 30% { transform: none; opacity: 1; }
  60% { transform: translateY(-64%) translateZ(70px) rotateX(-24deg); opacity: 1; }
  100% { transform: translateY(-34%) translateZ(330px) rotateX(-24deg) scale(1.35); opacity: 0; }
}

/* 5. Tirai (curtain): tirai tebal menyapu ke arah tetamu, pentas jauh di belakang */
.op-curtain { --cam-z: 200px; }
.op-curtain .op-glow { transform: translateZ(-300px) scale(1.35); }
.op-curtain .op-drape { transition: transform 1.8s cubic-bezier(.6,0,.25,1) .4s; }
.op-curtain.is-opening .op-l { transform: translateZ(90px) rotateY(-34deg) scaleX(.3); }
.op-curtain.is-opening .op-r { transform: translateZ(90px) rotateY(34deg) scaleX(.3); }
.op-curtain .op-valance { transform-origin: 50% 0; }
.op-curtain.is-opening .op-valance { transform: translateZ(160px) translateY(-110%) rotateX(-20deg); }
.op-curtain.is-opening .op-tassel { transform: translateZ(90px); opacity: 0; }

/* 6. Raudhah (slide): daun pintu tebal tergelongsor ke belakang di atas landasan */
.op-slide { --cam-z: 260px; }
.op-slide .op-glow { transform: translateZ(-260px) scaleX(.05) scale(1.25); }
.op-slide.is-opening .op-glow { transform: translateZ(-260px) scaleX(2.2) scale(1.25); }
.op-slide .op-leaf { transition: transform 1.6s cubic-bezier(.65,0,.3,1) .55s; }
.op-slide .op-sh { transition: opacity 1.2s ease .55s; }
.op-slide.is-opening .op-sh { opacity: .8; }
.op-slide.is-opening .op-l { transform: translateX(-104%) translateZ(-70px) rotateY(18deg); }
.op-slide.is-opening .op-r { transform: translateX(104%) translateZ(-70px) rotateY(-18deg); }

/* 7. Nilakandi (fold): lipatan tebal terbuka ke dalam */
.op-fold { --cam-z: 240px; }
.op-fold .op-t .op-sh { transition: opacity 1.25s ease .35s; }
.op-fold .op-b .op-sh { transition: opacity 1.25s ease .75s; }
.op-fold.is-opening .op-sh { opacity: 1; }
.op-fold.is-opening .op-t { transform: rotateX(108deg); }
.op-fold.is-opening .op-b { transform: rotateX(-108deg); }

/* 8. Reben (ribbon): reben ditarik keluar, penutup kotak terangkat ke arah tetamu */
.op-ribbon { --cam-z: 140px; }
.op-ribbon .op-lid { transform-origin: 50% 0; }
.op-ribbon.is-opening .op-rv1 { transform: translateY(-105%) translateZ(60px); }
.op-ribbon.is-opening .op-rv2 { transform: translateY(105%) translateZ(60px); }
.op-ribbon.is-opening .op-rh1 { transform: translateX(-105%) translateZ(60px); }
.op-ribbon.is-opening .op-rh2 { transform: translateX(105%) translateZ(60px); }
.op-ribbon.is-opening .op-bow { transform: translateZ(380px) scale(.6) rotate(40deg); }
.op-ribbon.is-opening .op-tag { transform: translate(-50%, -30px) translateZ(260px) rotate(-12deg); }
.op-ribbon.is-opening .op-lid { transform: translateZ(220px) translateY(-96%) rotateX(-42deg) rotateZ(-3deg); }

/* 9. Kembang (bloom): kelopak 3D mekar ke arah tetamu */
.op-bloom { --cam-z: 180px; }
.op-bloom .op-art { transform: translateZ(-150px) scale(1.14); }
.op-petals, .op-ring { transform-style: preserve-3d; }
.op-ring-o, .op-ring-i { opacity: 1 !important; }
.op-bloom .op-petal { transition: transform 1.6s cubic-bezier(.4,0,.2,1) .5s, opacity .9s ease 1.1s; }
.op-bloom .op-petal.op-in { transition: transform 1.3s cubic-bezier(.4,0,.2,1) .2s, opacity .7s ease .6s; }
.op-bloom.is-opening .op-ring-o { transform: rotate(24deg) scale(1.25); }
.op-bloom.is-opening .op-ring-i { transform: rotate(-30deg) scale(1.5); }
.op-bloom.is-opening .op-petal { transform: rotate(var(--a)) scale(var(--sc, 1)) rotateX(-72deg); opacity: 0; }

/* 10. Titah (scroll): gulungan condong ke belakang, tegak & terbuka menghadap tetamu */
.op-scroll { --cam-z: 200px; }
.op-scroll .op-art { transform: translateZ(-140px) scale(1.13); }
.op-sobj { position: absolute; inset: 0; transform-style: preserve-3d; transform: translateZ(-40px) rotateX(30deg); transition: transform 1.4s cubic-bezier(.55,0,.25,1) .45s; }
.op-scroll.is-opening .op-sobj { transform: translateZ(60px) rotateX(0); }
.op-scroll .op-rod { transform-style: preserve-3d; }
.op-scroll.is-opening .op-knot { transform: translateY(60px) translateZ(180px) rotate(12deg); }

@media (prefers-reduced-motion: reduce) { .op-cam { animation: none !important; } }

/* =====================================================================
   PINTU BERLOGO (13 Okt 2026, tema khas korporat): latar biru penuh & logo sahaja.
   Ketuk: logo berdenyut + kilauan, kemudian pudar; dua daun pintu bergeser ke tepi. Hanya transform + opacity.
   Warna: --ld-a (tengah), --ld-b (tepi), --ld-seam (garis emas di sambungan pintu)
   ===================================================================== */
.op-logodoor { --ld-a: #2E4C94; --ld-b: #13234C; --ld-seam: #C5A35C; }
.op-logodoor .op-stage { width: 100%; }
.op-logodoor .op-cam { animation: none; transform: none; transition: none; }
.opener.op-logodoor.is-opening .op-cam { transform: none; }
.op-ld-panel { position: absolute; top: 0; bottom: 0; width: 50.5%; will-change: transform;
  background: radial-gradient(ellipse 120% 70% at var(--ld-x) 50%, var(--ld-a), var(--ld-b) 75%);
  transition: transform 1.15s cubic-bezier(.7, 0, .2, 1) .55s; }
.op-ld-panel::before { content: ''; position: absolute; inset: 0; opacity: .5;
  background: repeating-linear-gradient(0deg, rgba(255, 255, 255, .025) 0 1px, transparent 1px 3px); }
.op-ld-panel::after { content: ''; position: absolute; top: 0; bottom: 0; width: 2px;
  background: linear-gradient(180deg, transparent, var(--ld-seam) 18%, var(--ld-seam) 82%, transparent); opacity: .3; }
.op-ld-panel.op-l { left: 0; --ld-x: 100%; box-shadow: 8px 0 24px rgba(0, 0, 0, .28); }
.op-ld-panel.op-l::after { right: 0; }
.op-ld-panel.op-r { right: 0; --ld-x: 0%; box-shadow: -8px 0 24px rgba(0, 0, 0, .28); }
.op-ld-panel.op-r::after { left: 0; }
.op-ld-logo { position: absolute; z-index: 5; left: 50%; top: 47%; width: min(64vw, 300px); aspect-ratio: 900 / 793; translate: -50% -50%;
  display: grid; place-items: center; transition: opacity .45s ease .45s, transform .9s cubic-bezier(.3, 0, .2, 1) .45s;
  animation: op-ld-float 4s ease-in-out infinite; }
.op-ld-logo img { width: 100%; height: 100%; object-fit: contain; filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .35)); }
.op-ld-shine { position: absolute; inset: 0; pointer-events: none;
  -webkit-mask: var(--logo) no-repeat center / contain; mask: var(--logo) no-repeat center / contain;
  background: linear-gradient(105deg, transparent 38%, rgba(255, 252, 235, .95) 50%, transparent 62%) no-repeat;
  background-size: 260% 100%; background-position: 130% 0; animation: op-ld-shine 3.6s ease-in-out 1s infinite; }
@keyframes op-ld-shine { 0%, 55% { background-position: 130% 0; } 100% { background-position: -30% 0; } }
@keyframes op-ld-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
.op-ld-logo .op-mono { font-size: 48px; color: var(--op-mono-c); }
.op-logodoor.is-opening .op-ld-logo { animation: op-ld-pulse .5s cubic-bezier(.3, 0, .3, 1); opacity: 0; transform: scale(1.12); }
.op-logodoor.is-opening .op-ld-shine { animation: op-ld-shine-now .55s ease-out forwards; }
@keyframes op-ld-pulse { 0% { scale: 1; } 50% { scale: 1.07; } 100% { scale: 1; } }
@keyframes op-ld-shine-now { from { background-position: 130% 0; } to { background-position: -30% 0; } }
.op-logodoor.is-opening .op-ld-panel.op-l { transform: translateX(-102%); }
.op-logodoor.is-opening .op-ld-panel.op-r { transform: translateX(102%); }
.op-logodoor.is-opening { background-color: transparent; transition: background-color 0s; }
.op-logodoor .op-hint { background: rgba(14, 26, 58, .55); color: #F3E3B5; border: 1px solid rgba(197, 163, 92, .55); }


/* Majlis intimate pada pintu (14 Okt 2026) */
.op-intimate { display: inline-flex; align-items: center; gap: 7px; font: 600 10.5px/1.2 var(--f-label, var(--f-body, 'Jost', sans-serif)); letter-spacing: .16em; text-transform: uppercase;
  color: var(--op-ink); background: color-mix(in srgb, var(--op-paper) 92%, transparent); padding: 7px 14px; border-radius: 999px; box-shadow: 0 4px 14px rgba(0,0,0,.12); }
.op-intimate svg { flex: none; opacity: .85; }
.op-logodoor .op-intimate { background: rgba(14, 26, 58, .6); color: #F3E3B5; border: 1px solid rgba(197, 163, 92, .55); }
.opener[data-skip] { display: none; }
/* Skrin PIN selepas pintu (kad intimate berpintu) */
.has-door .pin-gate { animation: pinIn .5s ease both; }
@keyframes pinIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .has-door .pin-gate { animation: none; } }
