*{box-sizing:border-box}
html,body{margin:0;padding:0;height:100%;background:#000}
body{font-family:'Montserrat',Arial,sans-serif;-webkit-font-smoothing:antialiased;overflow:hidden}
img{max-width:none}
.bt-app{position:relative;max-width:480px;min-height:100dvh;margin:0 auto;overflow:hidden;background:#efe0d0}
.bt-cover{position:relative;width:100%;height:100dvh;min-height:100dvh;overflow:hidden;background:#efe0d0;--bwk:2.3;transition:opacity .8s cubic-bezier(.22,.61,.36,1),translate .8s cubic-bezier(.22,.61,.36,1)}
.bt-cover-scene{position:absolute;left:50%;top:50%;width:1080px;height:1920px;transform:translate(-50%,-50%);transform-origin:50% 50%;overflow:hidden}
.bt-hero{display:none;position:relative;width:100%;height:100dvh;min-height:100dvh;overflow:hidden;background:#c8b3a1;--bwk:2.3}
.bt-app.is-hero-active .bt-cover{display:none}
.bt-app.is-hero-active .bt-hero{display:block}
.bt-hero-scene{position:absolute;left:50%;top:50%;width:1080px;height:1920px;transform:translate(-50%,-50%);transform-origin:50% 50%;overflow:hidden}
.bt-ayat{position:relative;width:100%;overflow:hidden;background:#771613;--bwk:2.3}
.bt-ayat-scene{position:absolute;left:0;top:0;width:1080px;height:1797px;transform-origin:0 0;overflow:hidden}
.bt-pasangan{position:relative;width:100%;overflow:hidden;background:#d5c8bc;--bwk:2.3}
.bt-pasangan-scene{position:absolute;left:0;top:0;width:1080px;height:3370px;transform-origin:0 0;overflow:hidden}
.bt-acara{position:relative;width:100%;overflow:hidden;background:#8a7256;--bwk:2.3}
.bt-acara-scene{position:absolute;left:0;top:0;width:1080px;height:2859px;transform-origin:0 0;overflow:hidden}
.bt-l{position:absolute;display:block;max-width:none;user-select:none;-webkit-user-drag:none}
.bt-deco{pointer-events:none}
.bt-text{display:flex;align-items:center;justify-content:center;text-align:center;white-space:nowrap;line-height:1;color:#891617;text-rendering:geometricPrecision}
.bt-eyebrow{font-family:'Noto Serif',serif;font-size:38px;font-weight:600;letter-spacing:17px;color:#821615}
.bt-names{font-family:'Cinzel',serif;font-size:50px;font-weight:700;letter-spacing:12px;text-transform:uppercase;color:#8d1514;text-shadow:0 2px 16px rgba(248,236,222,.55)}
.bt-to{font-family:'Montserrat',Arial,sans-serif;font-size:37px;font-weight:300;letter-spacing:8px;color:#050505}
.bt-guest{font-family:'Playfair Display',serif;font-size:56px;font-weight:700;letter-spacing:8px;color:#050505;text-shadow:0 2px 18px rgba(255,255,255,.44)}
.bt-photo{overflow:hidden;border:9px solid #875008;border-radius:999px;background:#d8c1a9;box-shadow:0 10px 22px rgba(56,28,12,.22)}
.bt-photo img{width:100%;height:100%;display:block;object-fit:cover;object-position:50% 50%}
.bt-open{display:flex;align-items:center;justify-content:center;gap:24px;padding:0;border:2px solid #2e0806;border-radius:999px;background:#8f1714;color:#fff;font-family:'Montserrat',Arial,sans-serif;font-size:26px;font-weight:400;letter-spacing:3px;line-height:1;box-shadow:none;cursor:pointer;transform-origin:50% 50%}
.bt-open img{width:60px;height:40px;display:block;flex:0 0 auto}
.bt-open span{display:block;translate:0 1px}
.bt-app.is-open .bt-cover{opacity:0;translate:0 -3%;pointer-events:none}
.bt-hero-init,.bt-hero-amp,.bt-hero-date{display:flex;align-items:center;justify-content:center;text-align:center;white-space:nowrap;line-height:1;text-rendering:geometricPrecision}
.bt-hero-init{font-family:'Cinzel',Georgia,'Times New Roman',serif;font-weight:500;color:#771613}
.bt-hero-amp{font-family:Cochin,Georgia,'Times New Roman',serif;font-weight:400;color:#771613}
.bt-hero-init-top{font-size:280px}
.bt-hero-init-bottom{font-size:280px}
.bt-hero-amp{font-size:116px}
.bt-hero-date{font-family:Georgia,'Times New Roman',serif;font-style:italic;font-weight:700;font-size:38px;letter-spacing:12px;color:#fff;text-shadow:0 1px 4px rgba(80,40,35,.18)}
.bt-ayat-photo{overflow:hidden;border-radius:64px 64px 0 0;background:#5f1c18}
.bt-ayat-photo img{width:100%;height:100%;display:block;object-fit:cover;object-position:50% 50%}
.bt-ayat-initials{display:flex;align-items:center;justify-content:center;text-align:center;white-space:nowrap;font-family:'Cinzel',Georgia,'Times New Roman',serif;font-weight:700;font-size:75px;line-height:1;color:#771613;text-rendering:geometricPrecision}
.bt-ayat-verse{display:flex;align-items:center;justify-content:center;text-align:center;font-family:'Montserrat','Avenir Light',Arial,sans-serif;font-weight:400;font-size:34.5px;line-height:1.18;color:#050505;white-space:normal;text-rendering:geometricPrecision}
.bt-ayat-verse-text{width:100%}
.bt-ayat-source{display:flex;align-items:center;justify-content:center;text-align:center;white-space:nowrap;font-family:'Montserrat','Avenir Light',Arial,sans-serif;font-weight:400;font-size:34.5px;line-height:1;color:#050505;text-rendering:geometricPrecision}
.bt-pas-photo{overflow:hidden;background:#8b7663}
.bt-pas-photo img{width:100%;height:100%;display:block;object-fit:cover;object-position:50% 50%}
.bt-pas-frame{pointer-events:none}
.bt-pas-greeting,.bt-pas-intro,.bt-pas-heading,.bt-pas-name,.bt-pas-parents{display:flex;align-items:center;justify-content:center;text-align:center;text-rendering:geometricPrecision}
.bt-pas-greeting{font-family:Georgia,'Times New Roman',serif;font-style:italic;font-weight:700;font-size:46px;line-height:1.18;color:#171719}
.bt-pas-intro{font-family:Georgia,'Times New Roman',serif;font-weight:400;font-size:32px;line-height:1.34;color:#302b2a}
.bt-pas-heading{font-family:Georgia,'Times New Roman',serif;font-style:italic;font-weight:700;font-size:46px;line-height:1.14;color:#2f3439}
.bt-pas-name{font-family:Georgia,'Times New Roman',serif;font-weight:700;font-size:49px;line-height:1;color:#8f1714;white-space:nowrap}
.bt-pas-parents{font-family:'Montserrat','Avenir Light',Arial,sans-serif;font-weight:400;font-size:29px;line-height:1.18;color:#151313}
.bt-pas-ig{display:flex;align-items:center;justify-content:center;gap:22px;border:2px solid #2e0806;border-radius:999px;background:#8f1714;color:#fff;text-decoration:none;font-family:'Montserrat',Arial,sans-serif;font-weight:700;font-size:27px;line-height:1}
.bt-pas-ig img{width:24px;height:26px;display:block;flex:0 0 auto}
.bt-pas-ig[hidden]{display:none !important}

.bt-acara-title{display:flex;align-items:center;justify-content:center;text-align:center;font-family:'Cinzel',Georgia,serif;font-weight:700;font-size:52px;line-height:1;color:#ead38d;text-rendering:geometricPrecision}
.bt-acara-dt{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:8px;font-family:Georgia,'Times New Roman',serif;font-weight:400;font-size:34px;line-height:1.2;color:#fff;text-rendering:geometricPrecision}
.bt-acara-divider{background:#fff}
.bt-acara-venue{display:flex;align-items:center;justify-content:center;text-align:center;font-family:'Playfair Display',Georgia,serif;font-weight:700;font-size:34px;line-height:1.2;color:#fff;text-rendering:geometricPrecision}
.bt-acara-address{display:flex;align-items:center;justify-content:center;text-align:center;font-family:Georgia,'Times New Roman',serif;font-weight:400;font-size:33px;line-height:1.2;color:#fff;text-rendering:geometricPrecision}
.bt-acara-maps{display:flex;align-items:center;justify-content:center;border-radius:999px;background:#ead38d;color:#171200;text-decoration:none;font-family:Georgia,'Times New Roman',serif;font-weight:700;font-size:30px;line-height:1}
.bt-acara-cd-label{display:flex;align-items:center;justify-content:center;text-align:center;font-family:'Playfair Display',Georgia,serif;font-weight:700;font-size:36px;line-height:1;color:#fff;text-rendering:geometricPrecision}
.bt-acara-cd-box{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;border-radius:24px;background:#ead38d;color:#171200}
.bt-acara-cd-box span{font-family:Georgia,'Times New Roman',serif;font-weight:700;font-size:46px;line-height:1;font-variant-numeric:oldstyle-nums}
.bt-acara-cd-box em{font-style:normal;font-family:'Montserrat',Arial,sans-serif;font-weight:700;font-size:18px;letter-spacing:.06em;text-transform:uppercase}
.bt-acara-save{display:flex;align-items:center;justify-content:center;gap:20px;border-radius:999px;background:#ead38d;color:#171200;text-decoration:none;font-family:Georgia,'Times New Roman',serif;font-weight:700;font-size:32px;line-height:1}

.bt-pasangan .bt-safe-flower[data-mo],.bt-acara .bt-safe-flower[data-mo]{overflow:visible;animation-fill-mode:none}
.bt-pasangan .bt-safe-flower[data-mo="pas-in"]{animation-timing-function:cubic-bezier(.25,.85,.3,1.15)}
.bt-safe-flower-img{display:block;width:100%;height:100%;max-width:none;user-select:none;-webkit-user-drag:none;transform-origin:inherit;animation-duration:var(--mo-i-dur,12000ms);animation-delay:0ms;animation-timing-function:ease-in-out;animation-iteration-count:infinite;animation-fill-mode:none;animation-play-state:paused}
.bt-pasangan .bt-safe-flower-img{animation-name:btPasLive}
.bt-acara .bt-safe-flower-img{animation-name:btAcaraLive}
.bt-safe-flower.is-mo-idle-running .bt-safe-flower-img{animation-play-state:running}

.bt-acara [data-mo="acara-in"]{
  animation-name:btRpIn;
  animation-duration:var(--mo-dur,1300ms);
  animation-delay:var(--mo-d,0ms);
  animation-timing-function:cubic-bezier(.22,.61,.36,1);
  animation-fill-mode:both;
  animation-play-state:paused;
}
.bt-acara [data-mo="acara-in"][data-ua-role^="decorative"]{animation-timing-function:cubic-bezier(.25,.85,.3,1.15)}
.bt-acara [data-mo="acara-in"][data-mo-idle]{
  animation-name:btRpIn,btAcaraLive;
  animation-duration:var(--mo-dur,1300ms),var(--mo-i-dur,12000ms);
  animation-delay:var(--mo-d,0ms),calc(var(--mo-d,0ms) + var(--mo-dur,1300ms) + var(--mo-i-off,0ms));
  animation-timing-function:cubic-bezier(.25,.85,.3,1.15),ease-in-out;
  animation-iteration-count:1,infinite;
  animation-fill-mode:both,none;
}
.bt-acara.is-acara-active [data-mo="acara-in"]{animation-play-state:running}
.bt-acara.bt-js-replay.is-acara-active [data-mo="acara-in"]{animation-play-state:paused}
.bt-acara.bt-js-replay.is-acara-active [data-mo="acara-in"][data-mo-idle]{animation-play-state:running}

@keyframes btRpIn{
  from{
    opacity:var(--rp-o,0);
    translate:calc(var(--rp-x,0px) * var(--bwk,3)) calc(var(--rp-y,0px) * var(--bwk,3));
    scale:var(--rp-sx,var(--rp-s,1)) var(--rp-sy,var(--rp-s,1));
  }
  to{opacity:1;translate:0 0;scale:1 1}
}
@keyframes btRpLive{
  0%,100%{translate:0 0;rotate:0deg}
  30%{translate:var(--i-x,0px) var(--i-y,0px);rotate:var(--i-r,0deg)}
  60%{translate:calc(var(--i-x,0px) * .6) calc(var(--i-y,0px) * .6);rotate:calc(var(--i-r,0deg) * .4)}
}
@keyframes btPasLive{
  0%,100%{translate:0 0;rotate:0deg}
  18%{translate:calc(var(--live-x,0px) * .55) calc(var(--live-y,0px) * -.25);rotate:calc(var(--live-r,0deg) * .65)}
  44%{translate:var(--live-x,0px) var(--live-y,0px);rotate:var(--live-r,0deg)}
  67%{translate:calc(var(--live-x,0px) * -.45) calc(var(--live-y,0px) * .55);rotate:calc(var(--live-r,0deg) * -.55)}
  84%{translate:calc(var(--live-x,0px) * -.9) calc(var(--live-y,0px) * -.25);rotate:calc(var(--live-r,0deg) * -.9)}
}
@keyframes btAcaraLive{
  0%,100%{translate:0 0;rotate:0deg}
  22%{translate:calc(var(--live-x,0px) * .45) calc(var(--live-y,0px) * -.28);rotate:calc(var(--live-r,0deg) * .5)}
  46%{translate:var(--live-x,0px) var(--live-y,0px);rotate:var(--live-r,0deg)}
  68%{translate:calc(var(--live-x,0px) * -.52) calc(var(--live-y,0px) * .62);rotate:calc(var(--live-r,0deg) * -.45)}
  86%{translate:calc(var(--live-x,0px) * -.9) calc(var(--live-y,0px) * -.18);rotate:calc(var(--live-r,0deg) * -.82)}
}
.bt-cover [data-mo="rp-in"],.bt-cover [data-mo="rp-deco"],
.bt-hero [data-mo="rp-in"],.bt-hero [data-mo="rp-deco"]{
  animation-name:btRpIn;
  animation-duration:var(--mo-dur,1300ms);
  animation-delay:var(--mo-d,0ms);
  animation-timing-function:cubic-bezier(.22,.61,.36,1);
  animation-fill-mode:both;
}
.bt-cover [data-mo="rp-deco"],.bt-hero [data-mo="rp-deco"]{animation-timing-function:cubic-bezier(.25,.85,.3,1.15)}
.bt-cover [data-mo="rp-deco"][data-mo-idle],
.bt-hero [data-mo="rp-deco"][data-mo-idle]{
  animation-name:btRpIn,btRpLive;
  animation-duration:var(--mo-dur,1400ms),var(--mo-i-dur,12000ms);
  animation-delay:var(--mo-d,0ms),calc(var(--mo-d,0ms) + var(--mo-dur,1400ms) + var(--mo-i-off,0ms));
  animation-timing-function:cubic-bezier(.25,.85,.3,1.15),ease-in-out;
  animation-iteration-count:1,infinite;
  animation-fill-mode:both,none;
}
.bt-open[data-mo="rp-in"]{
  animation-name:btButtonIn;
}
.bt-ayat [data-mo="ayat-in"]{
  animation-name:btRpIn;
  animation-duration:var(--mo-dur,1300ms);
  animation-delay:var(--mo-d,0ms);
  animation-timing-function:cubic-bezier(.22,.61,.36,1);
  animation-fill-mode:both;
  animation-play-state:paused;
}
.bt-ayat.is-ayat-active [data-mo="ayat-in"]{animation-play-state:running}
.bt-ayat.bt-js-replay.is-ayat-active [data-mo="ayat-in"]{animation-play-state:paused}
.bt-pasangan [data-mo="pas-in"]{
  animation-name:btRpIn;
  animation-duration:var(--mo-dur,1300ms);
  animation-delay:var(--mo-d,0ms);
  animation-timing-function:cubic-bezier(.22,.61,.36,1);
  animation-fill-mode:both;
  animation-play-state:paused;
}
.bt-pasangan [data-mo="pas-in"][data-mo-idle]{
  animation-name:btRpIn,btPasLive;
  animation-duration:var(--mo-dur,1300ms),var(--mo-i-dur,12000ms);
  animation-delay:var(--mo-d,0ms),calc(var(--mo-d,0ms) + var(--mo-dur,1300ms) + var(--mo-i-off,0ms));
  animation-timing-function:cubic-bezier(.25,.85,.3,1.15),ease-in-out;
  animation-iteration-count:1,infinite;
  animation-fill-mode:both,none;
}
.bt-pasangan.is-pasangan-active [data-mo="pas-in"]{animation-play-state:running}
.bt-pasangan.bt-js-replay.is-pasangan-active [data-mo="pas-in"]{animation-play-state:paused}
.bt-pasangan.bt-js-replay.is-pasangan-active [data-mo="pas-in"][data-mo-idle]{animation-play-state:running}
@keyframes btButtonIn{
  from{opacity:0}
  to{opacity:1}
}

@media (prefers-reduced-motion:reduce){
  [data-mo]{animation:none !important;opacity:1 !important;translate:none !important;scale:none !important;rotate:none !important}
  .bt-cover{transition:none}
}

.bt-nomo [data-mo]{animation:none !important;opacity:1 !important;translate:none !important;scale:none !important;rotate:none !important}
.bt-nomo .bt-cover{transition:none}

/* Isolated first-entrance reveal for just the Pasangan/Acara flower
   decorations whose --rp-* entrance was neutralized for guaranteed
   visibility. Base state (no .bt-flower-safe-in) already IS the correct
   final PSD position, so if the class is never added this simply stays
   put -- never hidden. Uses the `transform` property (not the standalone
   translate/rotate the idle-sway keyframes use), so it composes on top
   without conflicting with idle motion, and has no tie to setupReplay. */
#bt-pasangan .bt-flower-safe-in,#bt-acara .bt-flower-safe-in{animation:btFlowerRise 900ms cubic-bezier(.22,.61,.36,1) 1 forwards}
@keyframes btFlowerRise{
  from{transform:translateY(60px)}
  to{transform:translateY(0)}
}

/* Galeri -- Phase 1 layout + swipe function (entrance motion added
   separately below, isolated the same way as the flower/house fixes).
   Native 1080x1920 scene from Galeri.psd. Two rows of 4 canonical
   foto_galeri_1..8 photos, each
   row a native horizontal scroll-snap strip (same proven mechanism as
   Betawi's gallery, no library) showing 2 photos at a time; swipe stays
   inside the row (overflow-x on the track only) so it never fights the
   page's own vertical scroll. Dots below each row track that row's
   scroll position. */
.bt-galeri{position:relative;width:100%;overflow:hidden;background:#65120f}
.bt-galeri-scene{position:absolute;left:0;top:0;width:1080px;height:1920px;transform-origin:0 0}
.bt-galeri-title{display:flex;align-items:center;justify-content:center;text-align:center;font-family:'Cinzel',Georgia,serif;font-weight:700;font-size:34px;letter-spacing:.12em;text-transform:uppercase;color:#ead38d;text-rendering:geometricPrecision}
.bt-galeri-heading{display:flex;align-items:center;justify-content:center;text-align:center;font-family:'Cinzel',Georgia,serif;font-weight:700;font-size:68px;line-height:1;color:#ead38d;text-rendering:geometricPrecision}
.bt-galeri-sub{display:flex;align-items:center;justify-content:center;text-align:center;font-family:Georgia,'Times New Roman',serif;font-weight:400;font-size:28px;line-height:1.3;color:#fff;text-rendering:geometricPrecision}
.bt-gal-row{overflow:hidden}
.bt-gal-track{display:flex;gap:17px;width:100%;height:100%;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;scrollbar-width:none;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;touch-action:pan-x}
.bt-gal-track::-webkit-scrollbar{display:none}
.bt-gal-slide{flex:0 0 460px;height:100%;scroll-snap-align:start;border-radius:30px;overflow:hidden;background:rgba(255,255,255,.06)}
.bt-gal-slide[hidden]{display:none}
.bt-gal-slide img{display:block;width:100%;height:100%;object-fit:cover;-webkit-user-drag:none;user-select:none}
.bt-gal-dots{display:flex;align-items:center;justify-content:center;gap:10px}
.bt-gal-dots span{display:block;width:10px;height:10px;border-radius:5px;background:rgba(255,255,255,.35);flex:0 0 auto;transition:width .3s ease,background-color .3s ease}
.bt-gal-dots span.is-active{width:29px;background:#ead38d}

/* Acara right-side house -- restores its previously-working replay
   motion. It used to be a plain [data-mo="acara-in"] element (no
   data-mo-idle), which relies entirely on setupReplay's imperative
   getAnimations()/play() to ever run; on real devices it was found
   stuck paused at its own entrance "from" keyframe (confirmed: visible
   the whole time thanks to --rp-o:1, but never actually animating, on
   first load and every re-entry alike). Driven entirely from JS below
   via element.animate() -- a fresh Animation object every re-entry, so
   there is no CSS class/keyframe restart to be unreliable, and no
   getAnimations()/play()/pause() on a pre-existing animation either.
   No CSS rule sets its transform, so with no JS at all (or before the
   observer ever fires) it simply sits at its correct resting position
   -- never hidden or offset. Same for the Galeri text/row motion
   further down script.js: no CSS keyframes needed here at all. */

/* Galeri entrance motion -- same element.animate()-driven approach as
   the house fix above (see script.js), for the same reliability reason
   (a plain CSS class-toggle restart was tested and found to sometimes
   not take under rapid repeated re-entry). Applies only to the text and
   the two row WRAPPERS -- never to .bt-gal-track, so the swipe strip is
   untouched. No CSS rule sets their transform, so with no JS at all (or
   before the observer fires) they simply sit at their correct resting
   position -- content can never disappear. */

/* Live Streaming -- inserted between Acara and Galeri. Native 1080x1480
   scene from Live Streaming.psd. Reuses the flowers already exported
   for Pasangan/Acara (pixel-identical artwork in this PSD too, just
   repositioned). The house and green-tree assets were removed from
   this section per owner decision -- not repositioned, just dropped.
   Entrance motion is the same isolated element.animate()-driven
   approach as the house/Galeri fixes (see script.js) -- its own
   separate observer/IIFE, not touching Gallery's. */
.bt-live{position:relative;width:100%;overflow:hidden;background:#8f705e}
.bt-live-scene{position:absolute;left:0;top:0;width:1080px;height:1480px;transform-origin:0 0}
.bt-live-wash{background:rgba(255,255,255,.42)}
.bt-live-title{display:flex;align-items:center;justify-content:center;text-align:center;font-family:'Cinzel',Georgia,serif;font-weight:700;font-size:40px;color:#171200;text-rendering:geometricPrecision}
.bt-live-desc{display:flex;align-items:center;justify-content:center;text-align:center;font-family:Georgia,'Times New Roman',serif;font-weight:400;font-size:26px;line-height:1.3;color:#fff;text-rendering:geometricPrecision}
.bt-live-btn{display:flex;align-items:center;justify-content:center;gap:14px;text-decoration:none;color:#171200;-webkit-tap-highlight-color:transparent}
.bt-live-btn-bg{position:absolute;inset:0;width:100%;height:100%;z-index:0}
.bt-live-ico,.bt-live-btn-t{position:relative;z-index:1}
.bt-live-btn-t{font-family:Georgia,'Times New Roman',serif;font-weight:700;font-size:28px;line-height:1}

/* Video -- inserted after Galeri. Native 1882x2658 scene from Video.psd
   (same 1882-wide convention as the proven UA video section). The
   PSD's baked YouTube screenshot is rebuilt as a real click-to-play
   frame (canonical WEDDING_CONFIG.video.url / features.video data --
   see script.js). Entrance motion is the same isolated
   element.animate()-driven approach as Live/Galeri -- its own separate
   observer/IIFE. The video frame itself only gets a one-time entrance
   reveal (never continuously animated), so playback/touch are never
   interfered with. One decorative flower gets a plain always-on CSS
   idle sway, no observer/toggle at all. */
.bt-video{position:relative;width:100%;overflow:hidden;background:#65120f}
.bt-video-scene{position:absolute;left:0;top:0;width:1882px;height:2658px;transform-origin:0 0}
.bt-video-eyebrow{display:flex;align-items:center;justify-content:center;text-align:center;font-family:'Montserrat',Arial,sans-serif;font-weight:400;font-size:34px;letter-spacing:.2em;color:#fff;text-rendering:geometricPrecision}
.bt-video-heading{display:flex;align-items:center;justify-content:center;text-align:center;font-family:'Cinzel',Georgia,serif;font-weight:700;font-size:78px;color:#ead38d;text-rendering:geometricPrecision}
.bt-video-sub{display:flex;align-items:center;justify-content:center;text-align:center;font-family:Georgia,'Times New Roman',serif;font-weight:400;font-size:34px;letter-spacing:.08em;color:#fff;text-rendering:geometricPrecision}
.bt-video-frame{position:absolute;background:#000;overflow:hidden}
.bt-video-idle{animation:btVideoSway 10000ms ease-in-out infinite;transform-origin:50% 100%}
@keyframes btVideoSway{0%,100%{transform:rotate(0deg)}50%{transform:rotate(.8deg)}}
.vd-poster{position:absolute;inset:0;width:100%;height:100%;border:0;padding:0;background:#000;cursor:pointer;-webkit-tap-highlight-color:transparent}
.vd-thumb{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.vd-thumb[hidden]{display:none}
.vd-btn{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:130px;height:130px;border-radius:50%;background:rgba(23,18,0,.55);display:flex;align-items:center;justify-content:center}
.vd-btn svg{width:60px;height:60px;margin-left:8px}
.vd-poster:active .vd-btn{background:rgba(23,18,0,.75)}
.vd-player{position:absolute;border:0;background:#000;display:block}
iframe.vd-player{left:0;top:178px;width:100%;height:1056px}
video.vd-player{left:0;top:0;width:100%;height:100%;object-fit:contain}

/* Love Story -- inserted after Video. Native 1080x2364 scene from
   "love story.psd". The PSD's card+timeline block (a single flattened
   layer with baked demo text) was rebuilt as clean CSS cards + a CSS
   dot/line timeline, using the PSD's own measured pixel bounds (card
   body, dot diameter/offset, line column) -- so no customer text is
   ever baked into an exported asset. The tree/flowers/house cluster
   at the bottom is pixel-identical artwork to Pasangan/Acara/Live
   Streaming (verified: exact size match), reused with THIS PSD's own
   positions. Geometry/typography below is unchanged across the motion
   clean-rebuild -- see the "Love Story -- motion" block further down
   for [data-mo] rules (same [data-mo]/setupReplay mechanism already
   running Ayat/Pasangan/Acara, not a section-specific reinvention). */
.bt-love{position:relative;width:100%;overflow:hidden;background:#99857a}
.bt-love-scene{position:absolute;left:0;top:0;width:1080px;height:2364px;transform-origin:0 0}
.bt-love-eyebrow{display:flex;align-items:center;justify-content:center;text-align:center;font-family:'Montserrat',Arial,sans-serif;font-weight:400;font-size:31px;letter-spacing:.28em;color:#fff;text-rendering:geometricPrecision}
.bt-love-heading{display:flex;align-items:center;justify-content:center;text-align:center;font-family:'Cinzel',Georgia,serif;font-weight:700;font-size:88px;color:#771613;text-rendering:geometricPrecision}
.bt-lv-line{background:#c9a874}
.bt-lv-card{border-radius:28px;background:linear-gradient(180deg,#fffffe,#f7f2e9);box-shadow:0 10px 26px rgba(40,20,10,.18);display:flex;align-items:center;justify-content:center}
.bt-lv-dot{position:absolute;left:-89px;top:39px;width:51px;height:51px;border-radius:50%;background:#7a1416;border:5px solid #f0e4d0;box-sizing:border-box}
.bt-lv-body{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;padding:0 40px;text-align:center;text-rendering:geometricPrecision}
.bt-lv-year{font-family:Georgia,'Times New Roman',serif;font-weight:700;font-style:italic;font-size:38px;color:#221f1c}
.bt-lv-text{font-family:Georgia,'Times New Roman',serif;font-weight:400;font-size:30px;line-height:1.35;color:#221f1c}

/* Love Story -- motion. Clean-rebuild replacement for the discarded
   per-element WAAPI/IntersectionObserver patches (removed entirely --
   no data-gmo/data-delay/data-scale/data-idle-* hooks remain on this
   section). Reuses Batak's OWN already-proven [data-mo]/btRpIn/
   setupReplay mechanism byte-for-byte -- the exact same keyframe,
   easing split (content vs decorative) and two-observer replay
   lifecycle already running Ayat ([data-mo="ayat-in"]) and Pasangan
   ([data-mo="pas-in"]) in production; called via window.btSetupReplay
   in script.js. Cards use the proven Jawa Love Story card recipe
   identified directly from templates/jawa/style.css/index.html:
   data-mo="love-in", alternating --rp-x:+-100px (no --rp-y), 1300ms,
   the same content easing, no per-card stagger, one element per card,
   no separate child/text animation.
   DELIBERATE DIFFERENCE from Ayat/Pasangan/Acara's own copy of this
   same rule: fill-mode is "forwards", not "both". "both" backfills the
   "from" keyframe (opacity:var(--rp-o,0), offset translate/scale) onto
   the element for as long as it sits paused before JS ever plays it --
   which is the exact documented root cause of the Pasangan/Acara
   stuck-invisible bug (a getAnimations() race leaving an element
   paused at "from" forever) and of this section's own "flashing"
   regression. With "forwards" only, a paused-and-never-played (or not
   yet played) animation has no visual effect at all -- the element
   simply renders its own plain CSS (correct PSD position, opacity 1)
   until JS actually calls .play(), and holds the animated-to end state
   after finishing. Visibility and geometry therefore never depend on
   JS/observer firing; only the slide/grow-in motion itself does. */
.bt-love [data-mo="love-in"],.bt-love [data-mo="love-deco"]{
  animation-name:btRpIn;
  animation-duration:var(--mo-dur,1300ms);
  animation-delay:var(--mo-d,0ms);
  animation-timing-function:cubic-bezier(.22,.61,.36,1);
  animation-fill-mode:forwards;
  animation-play-state:paused;
}
.bt-love [data-mo="love-deco"]{animation-timing-function:cubic-bezier(.25,.85,.3,1.15)}
.bt-love [data-mo="love-deco"][data-mo-idle]{
  animation-name:btRpIn,btRpLive;
  animation-duration:var(--mo-dur,1300ms),var(--mo-i-dur,12000ms);
  animation-delay:var(--mo-d,0ms),calc(var(--mo-d,0ms) + var(--mo-dur,1300ms) + var(--mo-i-off,0ms));
  animation-timing-function:cubic-bezier(.25,.85,.3,1.15),ease-in-out;
  animation-iteration-count:1,infinite;
  animation-fill-mode:forwards,none;
}
.bt-love.is-love-active [data-mo="love-in"],.bt-love.is-love-active [data-mo="love-deco"]{animation-play-state:running}
.bt-love.bt-js-replay.is-love-active [data-mo="love-in"],.bt-love.bt-js-replay.is-love-active [data-mo="love-deco"]{animation-play-state:paused}
.bt-love.bt-js-replay.is-love-active [data-mo="love-deco"][data-mo-idle]{animation-play-state:running}

/* RSVP -- inserted after Love Story. Native 1882x4542 scene from
   RSCV.psd (same 1882-wide convention as Video/Live Streaming). The
   PSD's form/wishes-cards block is a single flattened mockup layer
   (baked placeholder text) -- rebuilt here as real <form>/<input>/
   <select>/<textarea>/<button> controls using the PSD's own measured
   field positions/heights/widths, wired to the EXISTING canonical
   UndanganAdat RSVP contract (POST /api/public/{slug}/rsvp -- see
   script.js), never a new endpoint/data model. The bottom floral
   cluster (4 decorative layers in the PSD) is exported as one
   flattened crop taken directly from the PSD's own true composite
   render (pixel-exact, avoids guessing at blend modes). See the
   "RSVP -- motion" block further down for [data-mo] rules -- the
   actual form controls are
   never targeted by any transform/animation. */
.bt-rsvp{position:relative;width:100%;overflow:hidden;background:#c9a67f}
.bt-rsvp-scene{position:absolute;left:0;top:0;width:1882px;height:4542px;transform-origin:0 0}
.bt-rsvp-eyebrow{display:flex;align-items:center;justify-content:center;text-align:center;font-family:'Montserrat',Arial,sans-serif;font-weight:600;font-size:46px;letter-spacing:.22em;color:#171200;text-rendering:geometricPrecision}
.bt-rsvp-heading{display:flex;align-items:center;justify-content:center;text-align:center;font-family:Georgia,'Times New Roman',serif;font-style:italic;font-weight:700;font-size:74px;color:#65120f;text-rendering:geometricPrecision}
.bt-rsvp-sub{display:flex;align-items:center;justify-content:center;text-align:center;font-family:Georgia,'Times New Roman',serif;font-weight:400;font-size:32px;line-height:1.32;color:#171200;text-rendering:geometricPrecision}
.bt-rsvp-form{position:absolute}
.bt-rsvp-form [hidden]{display:none!important}
.rs-field{margin:0 0 92px}
.rs-label{display:block;height:44px;margin:0 0 30px;font:700 34px/44px Georgia,'Times New Roman',serif;letter-spacing:.04em;color:#0d4a63;white-space:nowrap}
.rs-ctl{display:block;width:100%;box-sizing:border-box;margin:0;border:2px solid #c9a874;border-radius:28px;background-color:#fff;color:#171200;font:400 32px/1.25 Georgia,'Times New Roman',serif;padding:0 54px;outline:0;-webkit-appearance:none;appearance:none;box-shadow:none}
.rs-ctl::placeholder{color:#5e5e5e;opacity:1}
.rs-ctl:focus{border-color:#65120f}
input.rs-ctl{height:192px}
.rs-select{height:201px;padding-right:110px;cursor:pointer;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 34 20'%3E%3Cpath d='M3 3l14 14L31 3' fill='none' stroke='%23171200' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 26px center;background-size:32px 19px}
.rs-select:invalid{color:#171200}
.rs-area{height:336px;padding-top:50px;padding-bottom:36px;resize:none;overflow:auto;line-height:1.35}
.rs-submit-wrap{position:relative;margin:60px -4px 0 -4px}
.rs-submit{display:block;width:100%;height:196px;border:0;border-radius:28px;background:#65120f;color:#fff;font:600 42px/1 Georgia,'Times New Roman',serif;letter-spacing:.24em;text-indent:.24em;text-transform:uppercase;cursor:pointer;-webkit-appearance:none;appearance:none}
.rs-submit:disabled{opacity:.72;cursor:default}
.rs-status{position:absolute;left:0;right:0;top:calc(100% + 24px);margin:0;text-align:center;font:600 30px/1.2 'Montserrat',Arial,sans-serif;color:#65120f}
.rs-status.is-ok{color:#154800}
.rs-cards{margin-top:118px;width:100%}
.rs-cards:empty{display:none}
.rs-card{box-sizing:border-box;height:316px;margin:0 0 58px;padding:0 58px;display:flex;flex-direction:column;justify-content:center;border:5px solid #e4d4a4;border-radius:28px;background:#fff;overflow:hidden}
.rs-card-name{font:italic 600 40px/1.15 Georgia,'Times New Roman',serif;color:#0d4a63;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rs-card-msg{margin:24px 0 0;font:400 30px/1.3 Georgia,'Times New Roman',serif;color:#2c2c2c;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* RSVP -- motion. Clean-rebuild replacement for the discarded
   per-element WAAPI/IntersectionObserver patches (removed entirely --
   no data-gmo/data-delay/data-scale/data-idle-* hooks remain on this
   section). Decorations/heading reuse Batak's OWN already-proven
   [data-mo]/btRpIn/setupReplay mechanism byte-for-byte (same as Love
   Story above and Ayat/Pasangan in production); called via
   window.btSetupReplay in script.js. fill-mode is "forwards", not
   "both" -- see the matching comment on Love Story's motion block for
   why: with "both", a paused-and-never-played element backfills the
   "from" keyframe (offset/opacity:0) forever, which is the documented
   root cause of the Pasangan/Acara stuck-invisible bug and of this
   section's own "flashing" regression; with "forwards" only, an
   unplayed animation has no visual effect, so the element simply shows
   its own plain CSS (correct PSD position, opacity 1) until JS calls
   .play(). The form wrapper (#btRsvpForm) is NOT part of this
   [data-mo] system at all -- matching Betawi's own actual reference,
   which also keeps its RSVP form out of setupReplay and instead plays
   a one-shot reveal (window.bwRv('z')) with a focus guard so
   in-progress typing is never disrupted; see script.js. The real
   <input>/<select>/<textarea>/<button> controls are never targeted by
   any rule here. */
.bt-rsvp [data-mo="rsvp-in"],.bt-rsvp [data-mo="rsvp-deco"]{
  animation-name:btRpIn;
  animation-duration:var(--mo-dur,1300ms);
  animation-delay:var(--mo-d,0ms);
  animation-timing-function:cubic-bezier(.22,.61,.36,1);
  animation-fill-mode:forwards;
  animation-play-state:paused;
}
.bt-rsvp [data-mo="rsvp-deco"]{animation-timing-function:cubic-bezier(.25,.85,.3,1.15)}
.bt-rsvp [data-mo="rsvp-deco"][data-mo-idle]{
  animation-name:btRpIn,btRpLive;
  animation-duration:var(--mo-dur,1300ms),var(--mo-i-dur,12000ms);
  animation-delay:var(--mo-d,0ms),calc(var(--mo-d,0ms) + var(--mo-dur,1300ms) + var(--mo-i-off,0ms));
  animation-timing-function:cubic-bezier(.25,.85,.3,1.15),ease-in-out;
  animation-iteration-count:1,infinite;
  animation-fill-mode:forwards,none;
}
.bt-rsvp.is-rsvp-active [data-mo="rsvp-in"],.bt-rsvp.is-rsvp-active [data-mo="rsvp-deco"]{animation-play-state:running}
.bt-rsvp.bt-js-replay.is-rsvp-active [data-mo="rsvp-in"],.bt-rsvp.bt-js-replay.is-rsvp-active [data-mo="rsvp-deco"]{animation-play-state:paused}
.bt-rsvp.bt-js-replay.is-rsvp-active [data-mo="rsvp-deco"][data-mo-idle]{animation-play-state:running}

/* Hadiah -- inserted after RSVP. Native 1882x3693 scene from
   Hadiah.psd (psd-tools, recursive); same 1882-wide convention as
   Video/Live/RSVP. Card geometry (1205x822 each, two slots) is
   pixel-identical to Betawi's own approved Hadiah card, so this reuses
   Betawi's proven .hd-* flex layout/spacing verbatim, recolored to
   Batak's own PSD-measured palette. The PSD's card text (bank, number,
   holder, date) and SALIN button are baked into the mockup art -- not
   exported as assets; rebuilt as real elements bound to the EXISTING
   canonical gift data (bank_N_* / deskripsi_hadiah / tanggal_singkat,
   same contract Betawi's /dashboard/hadiah writes -- see script.js).
   The bottom scenery (4 decorative PSD layers) is exported as one
   flattened crop from the PSD's own true composite, matching how
   Betawi's own proven Hadiah treats its scenery as a single asset with
   a single idle-sway treatment (not split into independent pieces).
   Motion reuses Batak's own [data-mo]/btRpIn/btRpLive/setupReplay
   mechanism (see the Love Story/RSVP motion blocks above for why
   fill-mode is "forwards", not "both") -- called via
   window.btSetupReplay in script.js. The real <button> COPY controls
   are never targeted by any [data-mo] rule. */
.bt-hadiah{position:relative;width:100%;overflow:hidden;background:#5c130f}
.bt-hadiah-scene{position:absolute;left:0;top:0;width:1882px;height:3693px;transform-origin:0 0}
.bt-hadiah-desc{display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;color:#fff;font-family:'Montserrat',Arial,sans-serif;font-weight:300;font-size:38px;line-height:1.48;text-rendering:geometricPrecision}
.hd-card{font-family:'Montserrat',Arial,sans-serif;color:#2a0f06;background:#f8f8f4;border-radius:44px;box-shadow:0 10px 26px rgba(40,10,5,.22);box-sizing:border-box}
.hd-body{position:relative;box-sizing:border-box;height:100%;padding:104px 92px 96px 92px;display:flex;flex-direction:column;justify-content:space-between;gap:64px}
.hd-row{display:flex;gap:64px}
.hd-row-head{align-items:center;justify-content:space-between}
.hd-row-num{align-items:center;justify-content:space-between}
.hd-row-meta{align-items:flex-start;justify-content:space-between}
.hd-col{display:flex;flex-direction:column;gap:30px;flex:1 1 0;min-width:0}
.hd-col-r{flex:0 0 auto;max-width:46%;align-items:flex-end;text-align:right}
.hd-title{flex:1 1 0;min-width:0;overflow-wrap:break-word;font:600 53px/1.15 'Montserrat',Arial,sans-serif}
.hd-label{color:#0d4a63;font:400 34px/1.1 'Montserrat',Arial,sans-serif}
.hd-num{overflow-wrap:anywhere;font:600 50px/1.15 'Montserrat',Arial,sans-serif;letter-spacing:8px}
.hd-holder{overflow-wrap:break-word;font:500 42px/1.2 'Montserrat',Arial,sans-serif}
.hd-date{white-space:nowrap;font:500 42px/1.2 'Montserrat',Arial,sans-serif}
.hd-logo{flex:0 0 auto;max-width:40%;min-height:86px;display:flex;align-items:center;justify-content:flex-end}
.hd-logo img{display:block;max-width:294px;width:auto;max-height:86px;object-fit:contain}
.hd-logo-t{font:600 42px/1.1 'Montserrat',Arial,sans-serif;color:#0d4a63;text-transform:uppercase;letter-spacing:.02em;text-align:right}
.hd-copy{position:relative;flex:0 0 auto;width:309px;height:103px;display:flex;align-items:center;justify-content:center;gap:26px;border:0;border-radius:52px;background:#65120f;color:#fff;font:600 34px/1 'Montserrat',Arial,sans-serif;letter-spacing:.02em;cursor:pointer;padding:0;-webkit-appearance:none;appearance:none;-webkit-tap-highlight-color:transparent;touch-action:manipulation}
.hd-copy svg{width:30px;height:36px;flex:0 0 auto}
.hd-copy:focus-visible{outline:3px solid #fff;outline-offset:4px}
.hd-copy.is-done{background:#154800}
.hd-copy-t{white-space:nowrap}
.hd-card[hidden],.hd-card [hidden]{display:none!important}

.bt-hadiah [data-mo="hadiah-in"],.bt-hadiah [data-mo="hadiah-deco"]{
  animation-name:btRpIn;
  animation-duration:var(--mo-dur,1300ms);
  animation-delay:var(--mo-d,0ms);
  animation-timing-function:cubic-bezier(.22,.61,.36,1);
  animation-fill-mode:forwards;
  animation-play-state:paused;
}
.bt-hadiah [data-mo="hadiah-deco"]{animation-timing-function:cubic-bezier(.25,.85,.3,1.15)}
.bt-hadiah [data-mo="hadiah-deco"][data-mo-idle]{
  animation-name:btRpIn,btRpLive;
  animation-duration:var(--mo-dur,1300ms),var(--mo-i-dur,12000ms);
  animation-delay:var(--mo-d,0ms),calc(var(--mo-d,0ms) + var(--mo-dur,1300ms) + var(--mo-i-off,0ms));
  animation-timing-function:cubic-bezier(.25,.85,.3,1.15),ease-in-out;
  animation-iteration-count:1,infinite;
  animation-fill-mode:forwards,none;
}
.bt-hadiah.is-hadiah-active [data-mo="hadiah-in"],.bt-hadiah.is-hadiah-active [data-mo="hadiah-deco"]{animation-play-state:running}
.bt-hadiah.bt-js-replay.is-hadiah-active [data-mo="hadiah-in"],.bt-hadiah.bt-js-replay.is-hadiah-active [data-mo="hadiah-deco"]{animation-play-state:paused}
.bt-hadiah.bt-js-replay.is-hadiah-active [data-mo="hadiah-deco"][data-mo-idle]{animation-play-state:running}

/* Closing -- inserted after Hadiah, the FINAL Batak section. Native
   1882x3971 scene from Clousing.psd (psd-tools, recursive). The PSD's
   own baked couple photo is NOT shipped (matching Betawi's own
   approved decision): the photo is the EXISTING canonical closing
   background (WEDDING_DATA.bg_penutup); with no photo the block
   collapses and the text/footer move up onto the solid panel -- same
   mechanism as Betawi's proven bw-closing, ported directly (see
   script.js). The veil gradient ramp (0%..78%..100%) is Betawi's own
   proven stop structure, recolored to Batak's PSD-sampled maroon
   (#65120f, matching the PSD's own solid panel colour exactly).
   kata_penutup/couple names are live text; "We are blessed," and the
   UA logo/social links/music toggle are static UA branding artwork,
   not customer data (same as every other UA template's Closing).

   SAFETY: aggressive fast-scroll stress testing (rapid up/down
   direction reversals) reproduced the same setupReplay stuck-paused-
   at-opacity:0 race already documented for Pasangan/Acara -- an
   element mid-reset (leaveIO's pause()+currentTime=0) can end up
   never replayed if enterIO's next callback batches before the
   reversal settles. Since setupReplay itself is shared, proven, and
   out of scope to change, this uses the SAME established per-element
   fix already used for Pasangan/Acara: --rp-o:1 neutralizes the
   opacity portion of the entrance (kept here at the whole rule level,
   since ANY Closing content element could be the one caught by a
   given scroll pattern) -- the translateY/scale slide-in motion is
   unaffected, only the fade component is dropped, and visibility can
   no longer depend on which of the two observers' callbacks wins. */
.bt-closing{position:relative;width:100%;overflow:hidden;background:#65120f}
.bt-closing-scene{position:absolute;left:0;top:0;width:1882px;height:3971px;transform-origin:0 0}
.cl-photo{overflow:hidden;background:transparent}
.cl-slides{position:absolute;inset:0}
.cl-slide{position:absolute;inset:0;background-size:cover;background-position:50% 12%;opacity:0;transition:opacity 1.4s ease}
.cl-slide.is-active{opacity:1}
.cl-veil{
  position:absolute;inset:0;
  background:linear-gradient(to bottom,
    rgba(101,18,15,0) 0%, rgba(101,18,15,.13) 9%, rgba(101,18,15,.23) 18%,
    rgba(101,18,15,.33) 27%, rgba(101,18,15,.43) 36%, rgba(101,18,15,.53) 45%,
    rgba(101,18,15,.68) 55%, rgba(101,18,15,.77) 64%, rgba(101,18,15,.93) 73%,
    rgb(101,18,15) 78%, rgb(101,18,15) 100%);
}
.cl-body{position:absolute;left:0;top:0;width:1882px;height:3971px}
.cl-text{position:absolute;left:0;top:2635px;width:1882px;display:flex;flex-direction:column;align-items:center;text-align:center;color:#fff}
.cl-text>.bt-l{position:relative;margin:0}
.cl-kata{max-width:1160px;padding:0 20px;box-sizing:border-box;font:400 38px/1.6 'Montserrat',Arial,sans-serif}
.cl-blessed{margin-top:50px!important;font:400 32px/1.3 'Montserrat',Arial,sans-serif;color:#fff5d4}
.cl-names{margin-top:24px!important;max-width:1700px;padding:0 20px;box-sizing:border-box;font:italic 600 72px/1.15 Georgia,'Times New Roman',serif;letter-spacing:.04em;color:#ead38d}
.cl-logo,.cl-soc-a{display:block}
.cl-logo img{display:block;width:100%;height:100%}
.cl-soc{pointer-events:none}
.cl-soc-a{position:absolute;border-radius:50%}
.cl-music{padding:0;border:0;background:transparent;cursor:pointer;border-radius:50%;-webkit-appearance:none;appearance:none;-webkit-tap-highlight-color:transparent}
.cl-music img{display:block;width:100%;height:100%;opacity:.82;transition:opacity .3s ease}
.cl-music.is-on img{opacity:1;animation:btClSpin 9s linear infinite}
.cl-music:focus-visible{outline:4px solid #fff;outline-offset:6px}
@keyframes btClSpin{to{transform:rotate(360deg)}}

.bt-closing [data-mo="closing-in"],.bt-closing [data-mo="closing-deco"]{
  --rp-o:1;
  animation-name:btRpIn;
  animation-duration:var(--mo-dur,1300ms);
  animation-delay:var(--mo-d,0ms);
  animation-timing-function:cubic-bezier(.22,.61,.36,1);
  animation-fill-mode:forwards;
  animation-play-state:paused;
}
.bt-closing [data-mo="closing-deco"]{animation-timing-function:cubic-bezier(.25,.85,.3,1.15)}
.bt-closing.is-closing-active [data-mo="closing-in"],.bt-closing.is-closing-active [data-mo="closing-deco"]{animation-play-state:running}
.bt-closing.bt-js-replay.is-closing-active [data-mo="closing-in"],.bt-closing.bt-js-replay.is-closing-active [data-mo="closing-deco"]{animation-play-state:paused}
