/* Digital invitation chrome — diamond envelope intro overlay + phone-frame for the
   published page underneath. Loaded only when shared.php detects mode='invitation'.
   Adapted from invitacion-boda-digital/envelop/index2.html. */:root{--inv-cream-light:#fafaf8;--inv-cream-deep:#ece4cc;--inv-border:#d8d8d6;--inv-border-dark:#c8c2af;--inv-gold:#a58a4f;--inv-ink:#5e5848;--inv-frame-max:448px}/* Body backdrop and viewport lock — only when the body is in invitation mode. */body.is-invitation{background:linear-gradient(135deg, rgb(83 88 83 / 55%), rgb(83 88 83 / 85%)),radial-gradient(ellipse at center, #3f433f, #232624);overflow:hidden;-webkit-font-smoothing:antialiased}body.is-invitation .invitation-backdrop{position:fixed;inset:0;background:linear-gradient(135deg, rgb(83 88 83 / 50%), rgb(83 88 83 / 80%));z-index:0}/* Phone frame for the published page. Centered column on desktop, full-bleed on mobile.
   Published invitation pages render their content inside an iframe so the template's
   media queries match the phone-frame width (not the desktop viewport). */body.is-invitation #preview-content,body.is-invitation .invitation-frame{position:fixed;top:0;left:50%;transform:translateX(-50%);width:100%;max-width:var(--inv-frame-max);height:100vh;min-height:0;overflow-x:hidden;overflow-y:auto;background:var(--inv-cream-light);box-shadow:0 0 60px rgba(0, 0, 0, 0.45);z-index:20}body.is-invitation .invitation-frame{border:0;display:block}/* Loading screen: phone-frame shaped (dark backdrop shows around it), kept ON TOP of
   the envelope so the heart is visible while the envelope + stamp image load. shared.php
   fades it out once the stamp has loaded, revealing the envelope underneath. */body.is-invitation .loading-container{position:fixed;top:0;left:50%;transform:translateX(-50%);width:100%;max-width:var(--inv-frame-max);height:100vh;background:var(--inv-cream-light);z-index:200}/* ===== Envelope overlay ===== */body.is-invitation .envelope{position:fixed;top:0;left:50%;transform:translateX(-50%);z-index:50;width:100%;max-width:var(--inv-frame-max);height:100vh;overflow:hidden;background:transparent;border:0;padding:0;cursor:pointer;-webkit-tap-highlight-color:transparent;font-family:'Georgia','Times New Roman',serif}body.is-invitation .envelope .env-inner{position:absolute;inset:0;z-index:40;display:flex;height:100%;width:100%;flex-direction:column;justify-content:center}/* Diamond base shared by all envelope panels */body.is-invitation .invitation-panel-tile{position:absolute;display:block;height:70vh;width:70vh;border:1px solid var(--inv-border);background-color:var(--inv-cream-light)}/* Lower half — three back panels + hint */body.is-invitation .env-bottom{position:absolute;bottom:0;left:0;width:100%;height:75vh;will-change:transform;transition:transform 1.8s cubic-bezier(0.68, 0.02, 0.28, 1)}body.is-invitation .env-back-a{top:10%;left:50%;transform:translate(-100%, 5%) rotate(45deg);border-radius:6px}body.is-invitation .env-back-b{top:10%;left:50%;transform:translate(0%, 5%) rotate(45deg);border-radius:6px}body.is-invitation .env-back-c{bottom:10%;left:50%;transform:translate(-50%, 55%) rotate(45deg);border-radius:24px;border-width:2px;z-index:2}body.is-invitation .hint{position:absolute;bottom:0;left:0;right:0;height:50%;display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:3;pointer-events:none;color:var(--inv-ink);text-align:center;transition:opacity 0.35s ease-out;padding:0 24px}body.is-invitation .hint .intro{display:block;font-style:italic;font-size:17px;margin-bottom:10px;opacity:0.8;line-height:1.4}body.is-invitation .hint .cta{display:inline-block;font-weight:700;font-size:15px;letter-spacing:1.5px;color:#879696;transform-origin:center}@keyframes invitationCtaZoomPulse{0%,100%{opacity:0.5;transform:scale(1)}50%{opacity:1;transform:scale(1.12)}}body.is-invitation .hint .cta{animation:invitationCtaZoomPulse 2s ease-in-out infinite}/* Top flap (front face) */body.is-invitation .env-top{position:absolute;display:flex;align-items:flex-end;justify-content:flex-end;height:70vh;width:70vh;border-radius:24px;border:2px solid var(--inv-border-dark);background-color:var(--inv-cream-light);will-change:transform;top:10%;left:50%;z-index:3;box-shadow:7px 3px 14px 1px rgba(0, 0, 0, 0.15),0 2px 4px -2px rgba(0, 0, 0, 0.15);transform:translateX(-50%) translateY(-50%) rotate(45deg)}/* Names — counter-rotated to read upright. */body.is-invitation .env-names{position:absolute;inset:0;z-index:30;display:flex;height:100%;width:100%;flex-direction:column;align-items:center;justify-content:flex-start;padding-top:64px;color:#879696;transform:translate(25%, 25%) rotate(-45deg);will-change:opacity;transition:opacity 0.6s ease-out}body.is-invitation .env-names .name{font-family:'Brush Script MT','Lucida Handwriting',cursive;font-size:clamp(34px, 9vmin, 46px);line-height:1;text-shadow:0 1px 2px rgba(100, 110, 110, 0.12);white-space:nowrap}body.is-invitation .env-names .amp{font-family:'Brush Script MT','Lucida Handwriting',cursive;font-size:clamp(20px, 5vmin, 26px);font-style:italic;margin:4px 0;opacity:0.9}/* Stamp — counter-rotated, sits in the bottom-right corner of the diamond. */body.is-invitation .env-stamp{position:relative;z-index:30;transform:translate(25%, 25%) rotate(-45deg);filter:drop-shadow(0 8px 14px rgba(80, 50, 10, 0.35));will-change:transform,opacity;transition:transform 0.65s cubic-bezier(0.5, 0, 0.75, 0),opacity 0.5s ease-out}body.is-invitation .env-stamp img{display:block;width:clamp(80px, 16vmin, 108px);object-fit:contain;user-select:none;-webkit-user-drag:none}@keyframes invitationStampPulse{0%,100%{transform:translate(25%, 25%) rotate(-45deg) scale(1)}50%{transform:translate(25%, 25%) rotate(-45deg) scale(1.05)}}body.is-invitation .envelope:not(.opened) .env-stamp{animation:invitationStampPulse 2.6s ease-in-out infinite}/* Editor mode (preview iframe inside app.php): the stamp + hint text act as
   shortcuts that open the bottom edit sheet on mobile. Re-enable pointer
   events on the hint children (the wrapper has pointer-events:none above)
   and give them an explicit pointer cursor. */body.is-invitation-editor .env-stamp,body.is-invitation-editor .env-names,body.is-invitation-editor .hint .intro,body.is-invitation-editor .hint .cta{cursor:pointer}body.is-invitation-editor .hint .intro,body.is-invitation-editor .hint .cta{pointer-events:auto}/* Opened state — stamp shrinks, names fade, top flap flies off (handled by JS),
   bottom panels slide down. */body.is-invitation .envelope.opened{pointer-events:none}body.is-invitation .envelope.opened .hint{opacity:0}body.is-invitation .envelope.opened .env-stamp{transform:translate(25%, 25%) rotate(-45deg) scale(0.3);opacity:0}body.is-invitation .envelope.opened .env-names{opacity:0;transition-delay:0.1s}body.is-invitation .envelope.opened .env-bottom{transform:translateY(120%);transition-delay:0.3s}/* Music toggle — small floating button revealed after envelope opens. */.invitation-music-toggle{position:fixed;bottom:18px;right:18px;width:44px;height:44px;border-radius:50%;background:rgba(255, 255, 255, 0.92);border:1px solid rgba(0, 0, 0, 0.08);box-shadow:0 4px 14px rgba(0, 0, 0, 0.12);cursor:pointer;z-index:100;display:flex;align-items:center;justify-content:center;font-size:18px;color:var(--inv-ink);transition:transform 0.2s ease,opacity 0.2s ease;opacity:0;transform:scale(0.8);pointer-events:none}.invitation-music-toggle.is-visible{opacity:1;transform:scale(1);pointer-events:auto}.invitation-music-toggle:hover{transform:scale(1.08)}.invitation-music-toggle.is-muted{color:#9ca3af}.invitation-music-toggle.is-muted::after{content:'';position:absolute;width:60%;height:2px;background:currentColor;transform:rotate(-45deg);pointer-events:none}/* Persistent "playing" indicator: the note glyph gently bounces while
   music is on, so the button doubles as a now-playing status. Frozen
   when muted (.is-muted overrides via the selector below). */@keyframes invitationMusicNoteBounce{0%,100%{transform:translateY(0) rotate(0deg)}25%{transform:translateY(-2px) rotate(-6deg)}50%{transform:translateY(0) rotate(0deg)}75%{transform:translateY(-2px) rotate(6deg)}}.invitation-music-toggle.is-playing .music-icon{display:inline-block;animation:invitationMusicNoteBounce 1.4s ease-in-out infinite;transform-origin:center}.invitation-music-toggle.is-muted .music-icon{animation:none}/* One-shot onboarding hint: a soft pulse ring + scale wobble that runs
   for ~4s right after the envelope opens, to draw the eye to the button
   the first time it appears. Removed on click or timeout. */@keyframes invitationMusicHintPulse{0%,100%{transform:scale(1)}50%{transform:scale(1.12)}}@keyframes invitationMusicHintRing{0%{box-shadow:0 0 0 0 rgba(165, 138, 79, 0.55),0 4px 14px rgba(0, 0, 0, 0.12)}70%{box-shadow:0 0 0 16px rgba(165, 138, 79, 0),0 4px 14px rgba(0, 0, 0, 0.12)}100%{box-shadow:0 0 0 0 rgba(165, 138, 79, 0),0 4px 14px rgba(0, 0, 0, 0.12)}}.invitation-music-toggle.is-hint{animation:invitationMusicHintPulse 1.4s ease-in-out 3,invitationMusicHintRing 1.4s ease-out 3}@media (prefers-reduced-motion: reduce){.invitation-music-toggle.is-playing .music-icon,.invitation-music-toggle.is-hint{animation:none}}