:root{color-scheme:light;--ink:#344c48;--paper:#f3ebdc;--sand:#b69673;--line:#bdc7bb;--accent:#28544d;--error:#8b2926;font-family:Georgia,'Times New Roman',serif;color:var(--ink);background:#d4c9b5}
*{box-sizing:border-box}body{margin:0}button,input,a{-webkit-tap-highlight-color:transparent}button,input{font:inherit}button,a,input{touch-action:manipulation}button{cursor:pointer}button:disabled{cursor:wait;opacity:.65}a{color:inherit}button:focus-visible,a:focus-visible,summary:focus-visible,input:focus-visible{outline:3px solid #164d58;outline-offset:4px}button{color:inherit} [hidden]{display:none!important}
/* Layer order: artwork 0; controls 10; loader 20; native dialogs in the top layer. */
.invitation-page{max-width:1024px;margin:auto}.artwork{position:relative;overflow:hidden;width:100%;isolation:isolate}.background{width:100%;height:auto;display:block}.layer{position:absolute;pointer-events:none}.layer img{display:block;width:100%;height:auto;transform-origin:50% 85%}.section-anchor{position:absolute;left:0;width:1px;height:1px;scroll-margin-top:calc(clamp(44px,11.13vw,114px) + 16px)}
.navigation{position:fixed;left:50%;transform:translateX(-50%);top:0;width:min(100%,1024px);z-index:10;padding-top:env(safe-area-inset-top);background:var(--sand)}.navigation>img{display:block;width:100%;height:auto;min-height:44px}.navigation nav{position:absolute;inset:env(safe-area-inset-top) 0 0;display:grid;grid-template-columns:repeat(4,1fr)}.navigation a{display:block;min-height:44px}.navigation a:hover{background:#fff1}.navigation a:focus-visible{outline-offset:-5px;background:#fff2}.artwork{margin-top:calc(max(0px,44px - 9.765625vw) + env(safe-area-inset-top))}
.rsvp-button{position:fixed;right:max(14px,calc((100vw - 1024px)/2 + 30px));bottom:calc(18px + env(safe-area-inset-bottom));z-index:10;width:clamp(68px,12vw,118px);padding:0;border:0;background:none;border-radius:50%;filter:drop-shadow(0 4px 6px #5b493433)}.rsvp-button img{display:block;width:100%;height:auto}.art-button{position:absolute;display:block;background:none;padding:0;border:0;min-height:0}.art-button img{width:100%;height:auto;display:block}.art-button:after{content:'';position:absolute;inset:-14px -6px;min-height:44px}.art-button:hover{filter:brightness(1.08)}
.loader{display:none;position:fixed;inset:0;background:var(--paper);z-index:20;align-items:center;justify-content:center;pointer-events:none}.loader.active{display:flex}.loader span{width:180px;height:3px;background:#d9c5a7;position:relative;overflow:hidden}.loader span:after{content:'';position:absolute;inset:0;background:var(--accent);transform:scaleX(var(--progress,.05));transform-origin:left;transition:transform .3s}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.skip-link{position:fixed;left:16px;top:-70px;z-index:21;padding:12px;background:var(--paper)}.skip-link:focus{top:12px}
dialog{border:1px solid #b3baac;border-radius:8px;background:var(--paper);color:var(--ink);width:min(540px,calc(100% - 28px));max-height:calc(100dvh - 36px);padding:40px;overscroll-behavior:contain;box-shadow:0 18px 70px #21352e30}dialog::backdrop{background:#193d3e99;backdrop-filter:blur(3px)}body.modal-open{overflow:hidden}.close-dialog{position:absolute;top:10px;right:10px;border:0;background:transparent;width:44px;height:44px;font-size:30px;line-height:1}.modal-heading{margin-bottom:28px}.occasion{font-size:15px;margin:0 0 10px}.modal-heading h2,.access-card h1{font-weight:400;font-size:38px;line-height:1.1;margin:0 0 14px}.modal-heading>p:last-child{font-size:15px;line-height:1.5}label.name-label,.access-card label{display:block;margin:16px 0 8px}input:not([type=radio]):not([type=hidden]){width:100%;padding:12px;border:1px solid #788d80;background:#fffaf0;color:#233e35;border-radius:4px;min-height:48px;font-size:17px}fieldset{border:0;padding:0;margin:26px 0}legend{font-size:20px;line-height:1.4;padding:0}p.event-detail{font-family:Arial,sans-serif;font-size:13px;line-height:1.6;margin:8px 0 14px}.choices{display:flex;gap:12px}.choices label{position:relative;display:flex;align-items:center;gap:10px;border:1px solid #788d80;border-radius:4px;padding:11px 20px;min-width:100px;min-height:46px;cursor:pointer}.choices label:has(input:checked){background:#d4e2d8;border-color:var(--accent)}input[type=radio]{width:18px;height:18px;margin:0;accent-color:var(--accent)}.plus-question{border-top:1px solid var(--line);padding-top:22px}.plus-question legend{float:left;width:100%;margin-bottom:16px}.plus-question .choices{clear:both}#companion-details{border-top:1px solid var(--line);padding-top:10px}#companion-details h3{font-weight:400;font-size:27px}.primary{width:100%;padding:14px 22px;background:var(--accent);color:#fffaf0;border:1px solid var(--accent);border-radius:4px;min-height:50px}.primary:hover{background:#1d443e}.error{color:var(--error);font-family:Arial,sans-serif;font-size:14px;line-height:1.5}.error:empty{display:none}.honey{position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden}#rsvp-success h3{font-size:28px;font-weight:400}#rsvp-success p{line-height:1.6}#pending-dialog p{line-height:1.6}.access-page{min-height:100dvh;display:grid;place-items:center;padding:24px;background:#c9e0dc}.access-card{width:min(420px,100%);background:var(--paper);padding:36px;border:1px solid #aab9aa;border-radius:8px}.access-card>p{line-height:1.6}.noscript-note{padding:20px;background:var(--paper)}
@media(max-width:540px){dialog{padding:34px 23px 25px}.modal-heading h2{font-size:33px}.navigation>img{height:44px;min-height:44px}.section-anchor{scroll-margin-top:60px}.rsvp-button{width:74px}}
/* Keep the close control available while the long companion form scrolls. */
.close-dialog{position:sticky;top:0;float:right;margin:-24px -20px 0 0;background:var(--paper);z-index:2;border-radius:50%}
.artwork{margin-top:0}#home{padding-top:calc(max(0px,44px - 9.765625vw) + env(safe-area-inset-top));scroll-margin-top:120px}

/* Every moving piece sits inside a stationary wrapper measured from the artwork. */
.artwork{container-type:inline-size}
#invitation-details{top:0;left:0}
.layer-motion,.image-window{width:100%;height:100%;position:relative}
.layer-motion{transform-origin:var(--origin,50% 50%)}
.entrance-trigger{position:absolute;left:50%;width:1px;height:1px;pointer-events:none}
.background-motion{visibility:hidden;position:absolute;pointer-events:none;z-index:0;overflow:hidden}
.background-motion.motion-patch-ready{visibility:visible}
.background-motion>canvas{display:block;width:100%;height:100%}
.background-motion-covered{visibility:hidden}
.image-window{overflow:hidden}
.layer img{max-width:none;transform:none}
.torch>img{position:absolute;inset:0}
/* Intro crop: video y=400..1600 at 1080px, scaled to the 1024px artwork. */
.door-opening{display:block;visibility:hidden;position:absolute;left:0;top:4.253692%;width:100%;aspect-ratio:9/10;z-index:3;pointer-events:none}
/* The top 50px of the 1000px clip contains cut flower tips. Reveal the
   original flower-free lintel beneath it, keeping the moving panels intact. */
.door-opening>.door-intro{display:block;width:100%;height:100%;object-fit:fill;clip-path:inset(5% 0 0)}
/* Matched to the final 900x1000 intro frame, after trimming a 2px capture border. */
.door-inside{display:block;position:absolute;left:16%;top:25.3%;width:69.333333%;height:71.4%;object-fit:fill;opacity:0}
.door-opening.is-looping>.door-inside{opacity:1}
.door-foreground{z-index:5}
.door-opening.is-active{visibility:visible}
/* Text remains below the video, which already includes the wedding wording. */
.reveal{z-index:1}
.palm-left,.palm-right{z-index:4}
/* A small, transparent canvas carries only the flame from the reference clip. */
.fire-source{display:none}.fire-canvas{display:none;position:absolute;left:28.57%;top:-11.8594%;width:61.29%;height:31.9912%;pointer-events:none}
.fire-live .fire-canvas{display:block}
.fire-live .torch-still{clip-path:polygon(0 18.7%,14% 18.7%,45% 20.9%,73% 20%,100% 18.2%,100% 100%,0 100%)}
.fire-glow{position:absolute;left:15%;top:-7%;width:100%;height:39%;background:radial-gradient(ellipse,#ffba4144 0%,#ff992622 34%,transparent 70%);opacity:0;transform-origin:50% 70%}

@media(prefers-reduced-motion:no-preference){
  html{scroll-behavior:smooth}
  .palm-left>.layer-motion{animation:palm-left 3s ease-in-out infinite alternate}
  .palm-right>.layer-motion{animation:palm-right 3.4s ease-in-out infinite alternate;animation-delay:-1.4s}
  .botanical>.layer-motion{animation:flower-wave 3s ease-in-out infinite alternate;animation-delay:calc(-1 * var(--delay))}
  .chair-botanical>.layer-motion{animation:chair-flower-wave 3.6s ease-in-out infinite alternate;animation-delay:calc(-1 * var(--delay))}
  .lemon-sway>.layer-motion{animation:lemon-wave 3.5s ease-in-out infinite alternate;animation-delay:calc(-1 * var(--delay))}
  .sun-turn>.layer-motion{animation:sun-turn 16s linear infinite;animation-delay:calc(-1 * var(--delay))}
  .motion-ready .layer[data-entrance]:not(.has-arrived){opacity:0}
  .layer.has-arrived[data-entrance="chair-left"]{animation:chair-enter-left 1.3s cubic-bezier(.22,.61,.36,1) both}
  .layer.has-arrived[data-entrance="chair-right"]{animation:chair-enter-right 1.3s cubic-bezier(.22,.61,.36,1) both}
  .layer.has-arrived[data-entrance="gate"]{animation:gate-enter 1.5s cubic-bezier(.22,.61,.36,1) both}
  .motion-ready .reveal:not(.has-entered)>.layer-motion{opacity:0}
  .reveal.has-entered>.layer-motion{animation:text-arrive .85s cubic-bezier(.22,.61,.36,1) both;animation-delay:var(--delay)}
  .torch.in-view .fire-glow{animation:fire-warmth 1.4s ease-in-out infinite alternate}
  .rsvp-button img{animation:attention 6s ease-in-out infinite}
  .layer:not(.in-view)>.layer-motion{animation-play-state:paused}
  /* Finish each one-time reveal even when a guest scrolls past quickly. */
  .reveal.has-entered>.layer-motion{animation-play-state:running}
  .motion-paused .layer,.motion-paused .layer *,.motion-paused .rsvp-button img{animation-play-state:paused!important}
}
/* These exports are trimmed at the page edges. Sway outward from the original
   pose so their straight cut edges never rotate into the visible canvas. */
@keyframes palm-left{0%{transform:rotate(-3.6deg)}100%{transform:rotate(0deg)}}
@keyframes palm-right{0%{transform:rotate(0deg)}100%{transform:rotate(3.6deg)}}
@keyframes flower-wave{from{transform:rotate(0deg)}to{transform:rotate(var(--sway-angle,3.6deg))}}
@keyframes chair-flower-wave{from{transform:rotate(0deg)}to{transform:rotate(2.8deg)}}
@keyframes lemon-wave{from{transform:rotate(0deg)}to{transform:rotate(-3.8deg)}}
/* Side entrances start beyond the page; their trimmed edges never move inward. */
@keyframes chair-enter-left{from{opacity:0;transform:translateX(-8cqw)}to{opacity:1;transform:translateX(0)}}
@keyframes chair-enter-right{from{opacity:0;transform:translateX(8cqw)}to{opacity:1;transform:translateX(0)}}
@keyframes gate-enter{from{opacity:0;transform:translateY(10cqw)}to{opacity:1;transform:translateY(0)}}
@keyframes sun-turn{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
@keyframes text-arrive{from{opacity:0;transform:scale(.2)}to{opacity:1;transform:scale(1)}}
/* Small, continuous shape changes; no hard flashes or full-opacity blinking. */
@keyframes fire-warmth{0%{opacity:.28;transform:scale(.92)}100%{opacity:.55;transform:scale(1.1)}}
@keyframes attention{0%,70%,100%{transform:scale(1)}80%{transform:scale(1.055)}}
@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;scroll-behavior:auto!important;transition:none!important}.layer-motion{opacity:1!important;transform:none!important}.fire-glow,.ember{display:none}}

@media(prefers-reduced-motion:reduce){.door-opening,.fire-canvas{display:none!important}.fire-live .torch-still{clip-path:none}}
@media(prefers-reduced-motion:reduce){.background-motion{visibility:hidden!important}.background-motion-covered{visibility:visible!important}}
