/* Exact typefaces verified against the supplied Illustrator letter outlines. */
@font-face{font-family:"P052";src:url('card/fonts/P052-Roman.otf') format('opentype');font-style:normal;font-weight:400;font-display:swap}
@font-face{font-family:"Z003";src:url('card/fonts/Z003-MediumItalic.otf') format('opentype');font-style:italic;font-weight:400;font-display:swap}
@font-face{font-family:"Nimbus Roman";src:url('card/fonts/NimbusRoman-Italic.otf') format('opentype');font-style:italic;font-weight:400;font-display:swap}
:root{--font-body:"P052","Palatino Linotype",Palatino,serif;--font-script:"Z003","URW Chancery L",cursive;--font-ampersand:"Nimbus Roman","Times New Roman",serif;--paper:#fcf9e6;--ink:#3f482d;--blue:#315b97;--gold:#e9b525;--line:#b9b58c;--muted:#696c4c}
*{box-sizing:border-box}html{scroll-behavior:smooth;scroll-padding-top:30px}body{margin:0;background:var(--paper) url('card/paper.png') repeat;color:var(--ink);font:16px/1.65 var(--font-body)}a{color:inherit}button,input,select,textarea{font:inherit}button,a,input,select,textarea{-webkit-tap-highlight-color:transparent}button{cursor:pointer}header{max-width:1100px;margin:auto;padding:18px 32px;display:flex;align-items:center;justify-content:flex-end;gap:20px}.monogram{font:italic 28px var(--font-script);text-decoration:none;color:var(--blue)}nav{display:flex;gap:28px;font:10px var(--font-body);letter-spacing:.15em;text-transform:uppercase}nav a{min-height:44px;display:flex;align-items:center;text-decoration:none}nav a:hover{color:var(--blue)}
/* The center of the source card is never drawn: only its painted perimeter.
   Source: 1014 x 1400. Slices exclude all printed wording.
   Corner proportions are preserved; side strips stay continuous, without visible repeat seams. */
.hero{--edge:min(calc(22.18935vw - 7.10059px),213.01775px);width:calc(100% - 32px);max-width:960px;margin:0 auto 35px;border-style:solid;border-color:transparent;border-width:calc(var(--edge) * 285 / 225) var(--edge) calc(var(--edge) * 350 / 225);border-image-source:url('card/back.png');border-image-slice:285 225 350 225;border-image-repeat:stretch;padding:12px 16px 28px;text-align:center;min-width:0}
.hero-copy{max-width:650px;margin:auto;animation:arrive 1.3s ease both}.eyebrow{font:10px/1.8 var(--font-body);letter-spacing:.2em;text-transform:uppercase;color:var(--blue);margin:0}h1{font:italic clamp(60px,6.4vw,76px)/1.12 var(--font-script);letter-spacing:normal;font-weight:normal;margin:26px 0}h1 span,.amp{color:var(--ink);font-family:var(--font-ampersand);font-size:.87em;margin:0 .08em}.intro{max-width:335px;font-size:21px;line-height:1.6;margin:24px auto}.date-rule{height:1px;width:62px;background:#8e9865;margin:28px auto}.date,.venue{font:italic 30px/1.4 var(--font-script)}.date{margin:6px 0 8px}.date span{display:inline-block;white-space:nowrap}.venue{margin:0 0 28px}.caption{font:italic 16px/1.6 var(--font-script);margin:24px 0 0;color:var(--muted)}
.button,.submit{display:inline-block;background:var(--blue);color:var(--paper);border:1px solid var(--blue);border-radius:3px 5px 4px 3px;padding:16px 25px;text-decoration:none;font:11px/1.6 var(--font-body);letter-spacing:.12em;text-transform:uppercase;box-shadow:inset 0 0 10px #fcf9e620;transition:background-color .3s,transform .3s}.button:hover,.submit:hover{background:#274e84;transform:translateY(-2px)}h2{font:italic 49px/1.2 var(--font-script);margin:15px 0 26px}.day{max-width:790px;margin:45px auto 65px;padding:0 30px;text-align:center}.day-copy>p:not(.eyebrow){max-width:400px;margin:0 auto}.schedule{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));border-block:1px solid #b6aa6b88;margin-top:35px;padding:28px 0}.moment{padding:10px 22px}.moment+.moment{border-left:1px solid #b6aa6b55}.moment time{font:normal 30px var(--font-body);color:var(--ink);display:block;margin-bottom:16px}.moment h3{font:normal 23px/1.4 var(--font-body);margin:0}.dress{margin-top:32px}.dress p{margin:7px 0}.swatches{display:flex;gap:11px;justify-content:center;margin-bottom:20px}.swatches i{width:19px;height:19px;border-radius:46% 54% 48% 52%;background:#77804a;box-shadow:inset 2px 1px 5px #fff6}.swatches i:nth-child(2){background:#e9bf3f}.swatches i:nth-child(3){background:#527db8}.swatches i:nth-child(4){background:#d6c6a4}
.rsvp-section{padding:15px 24px 55px}.rsvp-wrap{max-width:620px;margin:auto}.rsvp-heading{text-align:center;margin-bottom:34px}.rsvp-heading h2{margin-bottom:20px}.rsvp-heading>p:not(.eyebrow){margin:12px 0}.preview-note,.privacy,.hint,.small,.optional{font:12px/1.65 var(--font-body);color:var(--muted)}.preview-note{max-width:330px;margin-inline:auto!important}fieldset{min-inline-size:0;border:0;padding:0;margin:0 0 24px}.label,legend{display:block;font:13px/1.55 var(--font-body);margin-bottom:9px}.choices,.identity-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}.choice{display:flex;align-items:center;gap:9px;padding:16px 13px;min-height:54px;border:1px solid #a5a47c99;border-radius:3px 6px 4px 3px;cursor:pointer;background:#fffef338}.choice:has(input:checked){border-color:var(--blue);background:#ced9dc55}input[type=radio]{width:17px;height:17px;flex-shrink:0;margin:0;accent-color:var(--blue)}input:not([type=radio]),select,textarea{width:100%;min-width:0;min-height:48px;padding:12px 13px;color:var(--ink);border:1px solid #a5a47c99;background:#fffef344;border-radius:3px 5px 3px 4px;font:16px/1.5 var(--font-body)}input::placeholder,textarea::placeholder{color:#797b65}textarea{min-height:94px;resize:vertical}.field{min-width:0;margin-bottom:23px}.hint{margin:7px 0 0}.party-picker{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:14px;border:1px solid #a5a47c88;padding:14px}.party-description small{display:block;font:12px/1.5 var(--font-body);margin-top:5px}.count-controls{display:flex;align-items:center;gap:8px}.count-controls button,.edit{border:1px solid #a5a47c99;border-radius:3px 5px;background:#fffef333;color:var(--blue);min-width:44px;min-height:44px;padding:8px 12px}.count-controls button:disabled{opacity:.4;cursor:default}.count-controls input:not([type=radio]){width:56px;padding:8px;text-align:center}.party-total{font-size:14px;margin:8px 0}.submit{width:100%;min-height:51px}.privacy{text-align:center}.success{text-align:center;padding:25px 0}.symbol{font-size:35px;color:var(--blue)}.edit{padding:10px 20px}footer{text-align:center;padding:22px 24px 55px}footer p{font:italic 27px var(--font-script);margin:0 0 17px}:focus-visible{outline:2px solid var(--blue);outline-offset:4px}[hidden]{display:none!important}.reveal{transition:opacity 1s,transform 1s}.js .reveal.pending{opacity:0;transform:translateY(20px)}@keyframes arrive{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@media(max-width:850px){h1{font-size:65px}}
@media(max-width:600px){header{padding:12px 23px}.monogram{font-size:24px}nav{gap:22px}.hero{--edge:calc(22.18935vw - 2.66272px);width:calc(100% - 12px);padding:8px 7px 22px;margin-bottom:30px}.hero .eyebrow{font-size:9px;letter-spacing:.13em}h1{font-size:clamp(52px,15vw,76px);line-height:1.04;margin:23px 0}h1 span{display:block;font-size:.47em;line-height:1.1;margin:8px 0}.intro{font-size:18px;line-height:1.6;margin:21px auto;max-width:270px}.date-rule{margin:22px auto}.date{margin-top:8px}.venue{margin-bottom:24px}.button{font-size:10px;letter-spacing:.07em;padding:14px 16px;max-width:100%}.caption{font-size:14px;margin-top:20px}.day{padding:0 23px;margin:35px auto 45px}h2{font-size:39px}.schedule{padding:21px 0;margin-top:28px}.moment{padding:8px 12px}.moment time{font-size:25px}.moment h3{font-size:19px}.rsvp-section{padding:0 23px 35px}.rsvp-heading h2{font-size:37px}.choices,.identity-grid{grid-template-columns:minmax(0,1fr);gap:12px}.identity-grid{gap:0}.choice{padding:14px}.optional{font-size:11px}footer{padding-bottom:35px}}
@media(max-width:360px){.hero{padding-inline:3px}h1{font-size:51px}.hero .eyebrow{font-size:8px}.intro{font-size:17px}.button{font-size:9px;padding-inline:12px}.moment{padding-inline:7px}.moment h3{font-size:17px}.rsvp-section{padding-inline:18px}}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}*,*::before,*::after{animation:none!important;transition:none!important}.js .reveal.pending{opacity:1;transform:none}}

/* Compact mobile copy keeps the continuous painted vines close to their source proportions. */
@media(max-width:600px){.hero .intro,.hero .caption{display:none}.hero h1{font-size:clamp(45px,13vw,66px);margin:18px 0}.hero .date-rule{margin:18px auto}.hero .venue{margin-bottom:20px}}

/* Supplied wordmark, kept at its original square aspect ratio. */
.monogram{display:block;flex:0 0 auto;width:96px;line-height:0;mix-blend-mode:multiply}.monogram img{display:block;width:100%;height:auto}
@media(max-width:600px){.monogram{width:76px}}

/* Match the printed invitation copy and olive lettering. */
.hero .eyebrow{font-size:clamp(16px,2vw,21px);line-height:1.5;letter-spacing:normal;text-transform:none;color:var(--ink)}
.hero .intro{max-width:440px;font-size:clamp(18px,2vw,21px);line-height:1.4}
.hero .date,.hero .venue{font-size:clamp(25px,3vw,30px)}
.date-rule{background:var(--line)}
.dress-code{font-size:clamp(18px,2.4vw,24px);line-height:1.4}
@media(max-width:600px){.hero .intro{display:block;margin:18px auto;font-size:17px}.hero .date,.hero .venue{font-size:clamp(22px,6vw,29px)}.hero .eyebrow{font-size:16px}.hero h1{font-size:clamp(43px,12vw,63px)}}

/* Narrow screens make the copy far taller than the card's painted sides; use
   variants whose side vines are lengthened (scripts/build_card_borders.py)
   instead of stretching them. Same slice values: only the side strips grow. */
@media(max-width:600px){.hero{border-image-source:url('card/back-tablet.png')}}
@media(max-width:480px){.hero{border-image-source:url('card/back-phone.png')}}

.errors{border:1px solid var(--ink);padding:16px;margin-bottom:24px}.legal-links{justify-content:center;align-items:center;flex-wrap:wrap;gap:8px 16px;text-align:center;margin-top:24px;font-size:13px}.form-panel.success{max-width:620px;margin:80px auto;padding:24px;text-align:center}

/* The film opens the invitation; the painted card follows on the paper. */
.opening-page>header{position:absolute;inset:0 0 auto;z-index:2;max-width:none;color:var(--paper);padding:20px 32px;text-shadow:0 1px 10px #171b1380}
.opening-page>header a:hover{color:var(--gold)}
.opening{position:relative;isolation:isolate;display:grid;place-items:center;height:100vh;height:100svh;min-height:420px;overflow:hidden;color:var(--paper);background:#1d1912}
/* Scrolling past the opening moves into the picture. invitation.js adds
   .zooming and sets --zoom: the film holds in place for a screen of scrolling
   while the footage (not the wordmark) scales up toward the couple, then the
   page carries on to the card. Without the script, or with reduced motion,
   the film simply scrolls away. */
.opening-page{--hold:100svh}
.opening-stage.zooming{height:calc(100svh + var(--hold));min-height:calc(420px + var(--hold))}
.opening-stage.zooming .opening{position:sticky;top:0}
.opening-stage.zooming .opening:before,.opening-stage.zooming .opening-film{will-change:transform}
/* The film is portrait and only 432px wide: filling a landscape screen would
   crop the couple and blur the picture. Show the whole frame sharp at full
   height, and fill the sides with a blurred, dimmed copy of the same scene. */
.opening:before{content:"";position:absolute;inset:-80px;z-index:-3;background:url('opening/poster.jpg') center/cover;filter:blur(56px) brightness(.62) saturate(1.2);transform:scale(var(--zoom,1))}
.opening-film{position:absolute;top:0;left:50%;z-index:-2;width:min(100%,56.25vh);width:min(100%,56.25svh);height:100%;transform:translateX(-50%) scale(var(--zoom,1));transform-origin:50% 38%;object-fit:cover;object-position:center;box-shadow:0 0 70px #0009}
/* Portrait screens are close to the film's shape: fill them edge to edge.
   Tall phones lose up to 18% of the width; the first frame (also the poster)
   has the bride at its right edge, so take more of the crop from the left. */
@media(max-aspect-ratio:3/4){.opening:before{display:none}.opening-film{left:0;width:100%;transform:scale(var(--zoom,1));box-shadow:none;object-position:75% center}}
.opening:after{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(180deg,#171b1366,transparent 22%,transparent 58%,#171b13b3);pointer-events:none}
/* White in the supplied logo becomes black, which screen blends away.
   This preserves the original artwork while showing a light wordmark on film.
   The wordmark sits low, just above the scroll link, small and slightly
   see-through so the film leads. --above is the scroll link's top edge; the
   PNG has 15.5% empty margin under the lettering, taken off the offset. */
.opening{--logo:min(240px,28vh,52vw);--above:126px}
@supports(height:1svh){.opening{--logo:min(240px,28svh,52vw)}}
.opening-logo{display:block;align-self:end;width:var(--logo);height:auto;margin-bottom:calc(var(--above) - var(--logo)*.155);opacity:.8;filter:grayscale(1) invert(1) brightness(2);mix-blend-mode:screen}
.opening-scroll{position:absolute;bottom:max(40px,env(safe-area-inset-bottom));left:50%;transform:translateX(-50%);display:flex;flex-direction:column;align-items:center;gap:12px;color:var(--paper);text-decoration:none;text-shadow:0 1px 8px #171b13b3;font-size:11px;letter-spacing:.16em;text-transform:uppercase;white-space:nowrap;padding:12px}
.opening-scroll span{font-size:24px;line-height:1}
.opening-scroll:hover{color:var(--gold)}
.opening-motion{position:absolute;right:24px;bottom:max(26px,env(safe-area-inset-bottom));min-height:44px;padding:10px 14px;border:1px solid #fcf9e666;border-radius:2px;background:#171b1359;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);color:var(--paper);font-size:12px;transition:background-color .3s}
.opening-motion:hover{background:#171b13a6}
.opening-page .hero{margin-top:64px;scroll-margin-top:32px;transition:opacity 1.4s ease,transform 1.4s cubic-bezier(.2,.7,.2,1)}
/* Set by invitation.js only, so the card is never hidden without it. */
.opening-page .hero.arriving{opacity:0;transform:translateY(32px)}
@media(max-width:600px){.opening-page>header{padding:12px 23px}.opening{--above:168px}.opening-scroll{bottom:85px;font-size:10px}.opening-motion{right:18px;bottom:max(18px,env(safe-area-inset-bottom))}.opening-page .hero{margin-top:36px}}
