:root{color-scheme:light;--ink:#514b47;--paper:#ebc5c8}
*{box-sizing:border-box}body{margin:0;min-height:100svh;background:#f4e5e6;color:var(--ink);font-family:"KaiTi","STKaiti","Kaiti SC",serif;display:grid;place-items:center;padding:16px 0 max(12px,env(safe-area-inset-bottom))}.invitation{width:min(100%,570px)}
.stage{position:relative;width:100%;aspect-ratio:3/4;overflow:hidden;container-type:inline-size;background:var(--paper);box-shadow:0 12px 60px #76545322}
.scene,.backdrop,.portrait-art{position:absolute;inset:0;width:100%;height:100%}.scene{opacity:0;visibility:hidden;transition:none}.scene.active{opacity:1;visibility:visible}.backdrop{object-fit:fill}.opening-copy{position:absolute;top:30%;left:8%;width:84%;text-align:center;font-size:3.5cqw;line-height:1.85;letter-spacing:.1em}.opening-copy p{margin:0}
.portrait-art{transform:none;transition:none}.photo-window{position:absolute;left:29.35%;top:23.7%;width:41.5%;height:52.2%;border-radius:50%;overflow:hidden;background:#b1a593}.photo-window img{width:100%;height:100%;object-fit:cover;object-position:44% 35%;display:block;transform:scale(1.6);transform-origin:25% 15%}
.details p,.details h1{position:absolute;margin:0;left:5%;width:90%;text-align:center;font-weight:400}.wedding-title{top:15.5%;font-family:"Monotype Corsiva","Gabriola","URW Chancery L","Apple Chancery",cursive;font-size:6cqw;font-style:italic}.names{top:25%;display:flex;align-items:center;justify-content:center;gap:5cqw;font-size:6.1cqw;letter-spacing:.13em}.amp{font-family:Georgia,serif;font-size:4.6cqw;font-style:italic}.date{top:33%;font-family:Georgia,serif;font-size:3.05cqw;letter-spacing:.18em}.venue{top:41%;font-size:3.35cqw;letter-spacing:.1em}.address{top:46%;font-size:2.55cqw;letter-spacing:.08em;white-space:nowrap}.event{position:absolute;top:59%;width:25%;display:grid;text-align:center;gap:1cqw;font-size:4.2cqw;letter-spacing:.16em}.event time{font:3cqw Georgia,serif;letter-spacing:.13em}.checkin{left:12%}.lunch{right:12%}
#effects{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}.cover{position:absolute;inset:0;background:#ebc4c8b8;backdrop-filter:blur(5px);display:flex;flex-direction:column;align-items:center;justify-content:center;transition:opacity .8s,visibility .8s}.cover.hidden{opacity:0;visibility:hidden;pointer-events:none}.cover-kicker{font-size:3.1cqw;letter-spacing:.2em}.cover-names{font-size:6.3cqw;letter-spacing:.1em;margin:3cqw 0}.cover-names i{font-family:Georgia,serif;font-size:.75em}.cover-date{font:3cqw Georgia,serif;letter-spacing:.16em}.start{margin-top:9cqw;border:1px solid #81706b80;border-radius:2px;background:#fff3;min-height:48px;padding:12px 30px;font-family:inherit;font-size:3.3cqw;color:inherit;cursor:pointer;letter-spacing:.15em}.start span{margin-left:12px}
.controls{position:absolute;right:12px;top:12px;z-index:6;display:flex;gap:5px;opacity:.45;transition:opacity .2s}.controls:hover,.controls:focus-within{opacity:1}.controls button,.replay{border:1px solid #fff5;background:#f9e9eb70;color:#675350;font:12px system-ui,sans-serif;min-height:44px;padding:8px 12px;border-radius:22px;cursor:pointer;backdrop-filter:blur(6px)}.controls button:disabled{opacity:.35}.replay{position:absolute;bottom:12px;left:50%;transform:translateX(-50%);z-index:6;font-size:12px}.controls[hidden],.replay[hidden]{display:none}button:focus-visible{outline:2px solid #79565b;outline-offset:3px}.status{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.paused *{animation-play-state:paused!important}.paused .portrait-art{transition:none}
@keyframes appear{from{opacity:0;translate:0 8px}to{opacity:1;translate:0 0}}
@media(min-width:600px){.invitation{width:min(570px,calc((100svh - 36px)*.75))}}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}.portrait-art{transform:none!important}}

/* One JS timeline owns curtain, text and photo motion so pause/replay stay in sync. */
.opening{z-index:3}.portrait{z-index:1}.details{z-index:2}#effects{z-index:4}.cover{z-index:5}
.curtain{position:absolute;top:0;bottom:0;width:50%;background-image:url("assets/curtain-mobile.jpg");background-size:200% 100%;will-change:transform}.curtain-left{left:0;background-position:left center}.curtain-right{right:0;background-position:right center}.opening-copy{will-change:opacity}.details .wedding-title,.details .names,.details .date,.details .venue,.details .address,.details .event{will-change:clip-path,opacity}

#fabric{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}.opening-copy{z-index:1}

/* Fill the actual WeChat viewport, including tall iPhone screens. */
@media(max-width:599px){
 body{display:block;padding:0;min-height:100svh;overflow:hidden}
 .invitation{width:100%;height:100svh;height:100dvh}
 .stage{height:100%;aspect-ratio:auto;box-shadow:none}
 .controls{top:max(12px,env(safe-area-inset-top));right:12px}
 .replay{bottom:max(12px,env(safe-area-inset-bottom))}
}

@font-face{font-family:InvitationDoodle;src:url("assets/invitation-doodle.woff2") format("woff2");font-weight:400;font-style:normal;font-display:block}
@font-face{font-family:InvitationScript;src:url("assets/invitation-script.woff2") format("woff2");font-weight:400;font-style:normal;font-display:block}
body{font-family:InvitationDoodle,serif}
.wedding-title{font-family:InvitationScript,cursive;font-style:normal;font-size:7.5cqw}
.stage{background:#deb0b4 url("assets/paper-extension.jpg") center/480px 480px repeat}
.stage{--scene-center:43.333333%}
.composition{position:absolute;left:0;top:var(--scene-center);width:100%;height:auto;aspect-ratio:3/4;transform:translateY(-50%);container-type:inline-size;z-index:1}
.composition .backdrop{mask-image:linear-gradient(to bottom,transparent,#000 14px,#000 calc(100% - 14px),transparent);-webkit-mask-image:linear-gradient(to bottom,transparent,#000 14px,#000 calc(100% - 14px),transparent)}
.opening-copy{top:var(--scene-center);transform:translateY(-50%)}
@media(max-width:599px) and (max-aspect-ratio:3/4){.composition{width:100%;height:auto}}
@media(max-width:599px) and (min-aspect-ratio:3/4){.composition{height:100%;width:auto;max-width:100%;left:50%;transform:translate(-50%,-50%)}}

/* Keep sparkles above the cloth while sharing the artwork's coordinate system. */
#effects{top:50%;bottom:auto;height:auto;aspect-ratio:3/4;transform:translateY(-50%)}
@media(max-width:599px) and (min-aspect-ratio:3/4){#effects{height:100%;width:auto;max-width:100%;left:50%;transform:translate(-50%,-50%)}}


/* One paper surface under transparent, independently placed ornaments. */
.details{container-type:inline-size;background:transparent}
.composition .backdrop{mask-image:none;-webkit-mask-image:none;z-index:1;pointer-events:none}
.detail-flora,.fountain-art,.cake-art,.candle-art{position:absolute;overflow:hidden;pointer-events:none}
.detail-flora{left:4%;top:20px;width:92%;height:19cqw}
.detail-flora img{position:absolute;left:0;top:0;width:100%;height:auto;aspect-ratio:3/4}
.fountain-art{left:50%;bottom:var(--art-bottom);width:calc(var(--fountain-width)*.44);height:calc(var(--fountain-height)*.46);transform:translateX(-50%)}
.fountain-art img{position:absolute;left:50%;bottom:calc(var(--fountain-height)*-.04);width:var(--fountain-width);height:var(--fountain-height);max-width:none;transform:translateX(-50%)}
.cake-art,.candle-art{bottom:var(--art-bottom);width:26cqw;height:36cqw}
.cake-art{left:0}.candle-art{right:0}
.cake-art img,.candle-art img{position:absolute;bottom:0;width:100cqw;height:133.333cqw;max-width:none}
.cake-art img{left:0}.candle-art img{right:0}
.details .wedding-title{top:16%;font-size:8.5cqw}
.details .names{top:24%;font-size:7.8cqw;gap:5cqw;letter-spacing:.08em}
.details .amp{font-size:5.8cqw}
.details .date{top:32%;font-size:4.6cqw;letter-spacing:.15em}
.details .venue{top:38.5%;font-size:4.7cqw;letter-spacing:.06em}
.details .address{top:43%;font-size:clamp(14px,3.8cqw,22px);letter-spacing:.02em}
.details .event{top:calc(var(--event-top) - 1.5em);width:22%;font-size:5.4cqw;gap:1.5cqw}
.details .event time{font-size:4.7cqw;letter-spacing:.06em}
.details .checkin{left:1.5%}.details .lunch{right:1.5%}
.opening-copy{left:5%;width:90%;font-size:5.2cqw;line-height:1.9;letter-spacing:.04em}
.cover-kicker{font-size:4.3cqw}.cover-names{font-size:8.2cqw}.cover-date{font-size:4.5cqw}.start{font-size:4.5cqw}
#effects{inset:0;width:100%;height:100%;aspect-ratio:auto;transform:none}
.controls{top:calc(20px + 16cqw)}
.replay{top:calc(20px + 16cqw);bottom:auto;left:12px;right:auto;transform:none;min-height:44px;padding:8px 12px}

/* Isolate the original ivory ink in-browser; retain the actual frame pixels. */
.portrait-art>.backdrop{filter:url(#lace-alpha)}
.photo-window{z-index:2}
.detail-flora img,.fountain-art img,.cake-art img,.candle-art img{filter:grayscale(1)}

/* Corner ornaments retain their proportions and clear the larger basin. */
.cake-art,.candle-art{width:24cqw;height:30cqw}
.cake-art img,.candle-art img{width:72cqw;height:96cqw}
.cake-art img{clip-path:inset(0 72.3% 0 0)}
.candle-art img{clip-path:inset(0 0 0 72.8%)}

/* Playful hand lettering stays consistent across phones. */
.names,.cover-names,.opening-copy,.venue,.address,.event,.start,.cover-kicker{font-family:InvitationDoodle, sans-serif}
.date,.cover-date,.event time,.amp,.cover-names i{font-family:InvitationDoodle,sans-serif;font-style:normal}
.names,.cover-names{letter-spacing:.04em}

/* Fine rounded doodle handwriting; no synthetic bold or brush strokes. */
.details .names{font-size:8.2cqw;letter-spacing:.035em}
.details .venue{font-size:4.9cqw}
.details .address{font-size:clamp(14px,3.85cqw,22px);letter-spacing:.015em}
.opening-copy{font-size:5.2cqw;letter-spacing:.045em}
.cover-names{font-size:8.6cqw}
.details .date,.cover-date{font-size:4.7cqw}
.details .event{font-size:5.6cqw}
.details .event time{font-size:4.8cqw}

/* Keep the final-scene navigation out of the flex control row. */
.controls button[hidden]{display:none}

/* A single bottom row occupies the blank margin below the ornaments. */
.stage{--control-bottom:max(12px,env(safe-area-inset-bottom))}
.controls{top:auto;right:12px;left:12px;bottom:var(--control-bottom);justify-content:center;gap:8px;opacity:.8}
.controls .replay{position:static;inset:auto;transform:none;margin:0}
.controls button{white-space:nowrap}
.start{position:absolute;bottom:var(--control-bottom);left:50%;transform:translateX(-50%);margin:0;white-space:nowrap}

/* Match the marked low-high-low positions in chronological order. */
.details .event{width:20%}
.details .checkin{top:calc(var(--event-top) - 1.5em + 10cqw)}
.details .seating{left:24%;top:calc(var(--event-top) - 1.5em - 3cqw)}
.details .lunch{right:6.5%;top:calc(var(--event-top) - 1.5em + 10cqw)}

/* Individually masked rows share one transparent image, without paper blocks. */
.sr-copy{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip-path:inset(50%)!important;white-space:nowrap!important}
.ink-strip{display:inline-block;flex:none;max-width:100%;background:var(--ink);mask-image:url('assets/handwritten-text-v24.png');-webkit-mask-image:url('assets/handwritten-text-v24.png');mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat;vertical-align:middle}
.lettered{line-height:1;letter-spacing:normal!important}
.ink-line{display:flex;align-items:center;justify-content:center;height:1.55em}
.lettering-ready .opening-copy{font-size:6.4cqw;line-height:1.55}
.lettering-ready .names,.lettering-ready .cover-names{font-size:11cqw;gap:0}
.lettering-ready .venue{font-size:6cqw}
.lettering-ready .address{font-size:5.2cqw}
.lettering-ready .cover-kicker{font-size:5cqw}
.lettering-ready .event time{line-height:1.2}

/* v25: airy hierarchy using the accepted lettering, with a gently arched title. */
.ink-arc{display:inline-block;position:relative;vertical-align:middle;max-width:100%}
.arc-letter{position:absolute;transform-origin:50% 50%}
.lettering-ready .names,.lettering-ready .cover-names{font-size:7.7cqw}
.lettering-ready .venue{font-size:5.1cqw}
.lettering-ready .address{font-size:4.4cqw}
.details .wedding-title{top:14%}
.details .names{top:25.5%}
.details .date{top:31.5%}
.details .venue{top:37.5%}
.details .address{top:41.5%}

/* Illustrated cover: the artwork contains no text or fake button. */
.cover{display:block;background:#edbfc0 url('assets/cover-illustration-v27.jpg') center/cover no-repeat;backdrop-filter:none}
.cover>p{position:absolute;left:50%;width:90%;margin:0;text-align:center;transform:translate(-50%,-50%)}
.cover .cover-kicker{top:38.5%}
.cover .cover-names{top:45.5%}
.cover .cover-date{top:52%}
.cover .start{bottom:max(6.5%,calc(env(safe-area-inset-bottom) + 12px));min-width:48%;padding:12px 24px;border-color:#997d7080;background:#f4d1cf55}

/* Cover audio is available before starting the invitation timeline. */
.lettering-ready .cover .cover-kicker{font-size:7.1cqw}
.cover .cover-kicker{filter:url(#cover-ink-match)}
.cover-actions{position:absolute;left:5%;bottom:max(6.5%,calc(env(safe-area-inset-bottom) + 12px));width:90%;display:flex;align-items:stretch;justify-content:center;gap:10px}
.cover-actions .start{position:static;transform:none;min-width:48%;padding:12px 20px}
.cover-music{min-height:48px;padding:10px 14px;border:1px solid #997d7080;border-radius:2px;background:#f4d1cf55;color:inherit;font:14px InvitationDoodle,sans-serif;white-space:nowrap;cursor:pointer}

/* A real accessible button follows the envelope in the cover-cropped artwork. */
.cover .start{position:absolute;left:var(--envelope-left,52.6%);top:var(--envelope-top,78.2%);bottom:auto;transform:translate(-50%,-50%);width:var(--envelope-width,29%);height:var(--envelope-height,10%);min-width:44px;min-height:44px;margin:0;padding:0;border:0;background:transparent;color:transparent;font-size:0;z-index:1}
.cover .start:focus-visible{outline:2px dashed #8e6d5c;outline-offset:4px;border-radius:8px}
.cover-hint{position:absolute;left:var(--hint-left,62.6%);top:var(--hint-top,79.9%);width:var(--hint-width,28%);height:var(--hint-height,10%);color:#8e6d5c;pointer-events:none}
.cover-hint svg{display:block;width:100%;height:70%;overflow:visible}
.cover-hint path{stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}
.cover-hint span{display:block;text-align:center;font:4.1cqw/1.2 InvitationDoodle,sans-serif;white-space:nowrap;transform:rotate(-6deg)}
.cover-actions{bottom:var(--control-bottom)}
.cover-music{min-height:44px;padding:8px 16px;border-radius:22px;background:#f9e9eb70;font-size:13px}
