/* Layout: a printed invitation that opens into a site — centred paper cards on alternating linen / sage / moss bands, painting under the RSVP. Single, deliberate paper theme. */
:root{
  --linen:#f1ece2; --linen-deep:#e7e0d2; --sage:#a6ae9a; --moss:#596452;
  --navy:#26364a; --earth:#332c26; --earth-muted:#6b6259; --gold:#c3ab82;
  --display:"Cinzel","Trajan Pro",Georgia,serif;
  --script:"Italianno","Pinyon Script",cursive;
  color-scheme:light;
}
*{box-sizing:border-box}
html,body{height:100%}
body{background:var(--linen);color:var(--earth);font-family:var(--display);font-size:15px;line-height:1.75;letter-spacing:.03em;-webkit-font-smoothing:antialiased}
h1,h2,h3,p{margin:0}
h1,h2,h3{font-weight:400;text-wrap:balance}
a{color:inherit}
button,input{font:inherit}
:focus-visible{outline:2px solid var(--gold);outline-offset:3px}

.eyebrow{font-size:12px;letter-spacing:.24em;text-transform:uppercase;color:var(--earth-muted)}
.script{font-family:var(--script);font-size:64px;line-height:.8;letter-spacing:0;text-transform:none}
.rule{width:56px;height:1px;background:var(--gold);border:0;margin:0 auto}

/* Monogram */
.mono{display:inline-flex;flex-direction:column;align-items:center;justify-content:center;width:46px;height:70px;border:1px solid var(--gold);border-radius:999px;position:relative;font-size:17px;line-height:1;gap:2px;color:var(--earth)}
.mono::after{content:"";position:absolute;inset:3px;border:1px solid var(--gold);border-radius:999px;opacity:.6}
.mono.light{color:var(--linen)}

/* ---------- Stage screens ---------- */
.stage{position:fixed;inset:0;display:grid;place-items:center;background:var(--linen);z-index:20;
  padding:env(safe-area-inset-top,0px) max(16px,env(safe-area-inset-right,0px)) env(safe-area-inset-bottom,0px) max(16px,env(safe-area-inset-left,0px));
  transition:opacity .8s ease}
.stage.gone{opacity:0;pointer-events:none}
.paper-grain{background-image:radial-gradient(rgba(51,44,38,.035) 1px,transparent 1px);background-size:3px 3px}

/* Gate */
.gate{display:grid;gap:28px;justify-items:center;text-align:center;max-width:360px;width:100%}
.gate h1{font-size:30px;letter-spacing:.12em;line-height:1.25}
.gate form{display:grid;gap:14px;width:100%}
.gate label{font-size:12px;letter-spacing:.24em;color:var(--earth-muted)}
.gate input{width:100%;background:transparent;border:0;border-bottom:1px solid var(--earth-muted);padding:10px 4px;text-align:center;font-size:17px;letter-spacing:.14em;color:var(--earth)}
.gate input:focus{outline:none;border-bottom-color:var(--moss)}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;background:var(--moss);color:var(--linen);border:0;border-radius:2px;padding:14px 28px;font-size:13px;letter-spacing:.24em;text-transform:uppercase;cursor:pointer;transition:background .25s}
.btn:hover{background:var(--earth)}
.btn[disabled]{background:transparent;color:var(--linen);border:1px solid rgba(241,236,226,.55);cursor:default}
.err{min-height:1.5em;font-size:12px;letter-spacing:.1em;color:#8a3b2a}
.shake{animation:shake .4s}
.seal.nope{animation:shake .4s}
@keyframes shake{20%,60%{transform:translateX(-6px)}40%,80%{transform:translateX(6px)}}

/* Envelope */
.env-wrap{display:grid;gap:28px;width:100%;justify-items:center;text-align:center}
.env{--w:min(460px,86vw);--h:calc(var(--w)*.66);position:relative;width:var(--w);height:var(--h);perspective:1400px;margin-top:calc(var(--h)*.55)}
.linen-tex{background-color:var(--sage);background-image:
  repeating-linear-gradient(0deg,rgba(255,255,255,.07) 0 1px,transparent 1px 3px),
  repeating-linear-gradient(90deg,rgba(51,44,38,.06) 0 1px,transparent 1px 3px)}
.env-back{position:absolute;inset:0;border-radius:2px;background-color:#8f9883}
.env-liner{position:absolute;left:6%;right:6%;top:0;height:60%;clip-path:polygon(0 0,100% 0,50% 100%);background:center/cover}
.env-card{position:absolute;left:7%;right:7%;top:8%;height:86%;background:var(--linen);box-shadow:0 1px 4px rgba(51,44,38,.18);display:grid;align-content:center;justify-items:center;gap:6px;text-align:center;padding:12px;transition:transform 1.1s cubic-bezier(.3,.7,.2,1);z-index:2}
.env-card .n{font-size:clamp(13px,3.6vw,18px);letter-spacing:.1em}
.env-card .s{font-family:var(--script);font-size:clamp(26px,7vw,36px);line-height:.7}
.env-card .d{font-size:11px;letter-spacing:.24em;color:var(--earth-muted);margin-top:4px}
.env-front{position:absolute;inset:0;z-index:3;pointer-events:none;filter:drop-shadow(0 -1px 1px rgba(51,44,38,.12))}
.env-front .l,.env-front .r,.env-front .b{position:absolute;inset:0}
.env-front .l{clip-path:polygon(0 0,52% 56%,0 100%)}
.env-front .r{clip-path:polygon(100% 0,48% 56%,100% 100%)}
.env-front .b{clip-path:polygon(0 100%,50% 46%,100% 100%);filter:brightness(.97)}
.env-flap{position:absolute;left:0;right:0;top:0;height:62%;transform-origin:top;transform-style:preserve-3d;transition:transform .9s cubic-bezier(.5,0,.3,1),z-index 0s .45s;z-index:4}
.env-flap .f,.env-flap .in{position:absolute;inset:0;clip-path:polygon(0 0,100% 0,50% 100%);backface-visibility:hidden}
.env-flap .in{transform:rotateX(180deg);background:center/cover;clip-path:polygon(0 100%,100% 100%,50% 0)}
.env-flap .f{filter:brightness(1.03)}
.seal{position:absolute;left:50%;top:calc(var(--h)*.62);width:58px;height:58px;margin:-29px 0 0 -29px;border-radius:50%;z-index:5;display:grid;place-items:center;
  background:radial-gradient(circle at 35% 30%,#d8c39c,var(--gold) 55%,#a88f63);box-shadow:0 2px 6px rgba(51,44,38,.3),inset 0 0 0 4px rgba(255,255,255,.12);
  font-size:13px;line-height:1;letter-spacing:.06em;color:#5e4c2d;transition:opacity .4s,transform .4s}
.env.open .seal{opacity:0;transform:scale(.6)}
.env.open .env-flap{transform:rotateX(180deg);z-index:1}
.env.lift .env-card{transform:translateY(-62%)}
.env-cta{transition:opacity .4s}
.env.open + .env-cta{opacity:0;pointer-events:none}

/* card zoom to site */
.zoom{position:fixed;background:var(--linen);z-index:30;pointer-events:none;transition:all .9s cubic-bezier(.6,0,.2,1)}

/* ---------- Site ---------- */
#site{opacity:0;transition:opacity .9s ease}
#site.show{opacity:1}
.wrap{padding-left:max(16px,env(safe-area-inset-left,0px));padding-right:max(16px,env(safe-area-inset-right,0px))}
.inner{max-width:1080px;margin:0 auto}

body::before{content:"";position:fixed;inset:0 0 auto;height:env(safe-area-inset-top,0px);z-index:10;background:var(--linen)}
nav.top{position:sticky;top:env(safe-area-inset-top,0px);z-index:9;background:rgba(241,236,226,.94);backdrop-filter:blur(6px);border-bottom:1px solid rgba(195,171,130,.45)}
nav.top .inner{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;height:64px}
nav.top ul{display:flex;gap:28px;list-style:none;margin:0;padding:0;font-size:12px;letter-spacing:.22em}
nav.top ul:last-child{justify-content:flex-end}
nav.top a{text-decoration:none;color:var(--earth-muted);transition:color .2s}
nav.top a:hover{color:var(--earth)}
nav.top .mono{width:30px;height:46px;font-size:12px}

/* Hero = the invitation */
.hero{padding-block:72px 0;text-align:center}
.invite{max-width:620px;margin:0 auto;display:grid;gap:22px;justify-items:center}
.invite .names{font-size:clamp(28px,5.4vw,52px);letter-spacing:.1em;line-height:1.15}
.invite .lead{max-width:380px;color:var(--earth-muted);font-size:14px}
.invite .date{font-size:clamp(34px,6vw,54px);letter-spacing:.08em;line-height:1}
.invite .where{font-size:13px;letter-spacing:.22em;line-height:1.9}
.castle{width:min(560px,100%);margin-top:12px;display:block;
  /* darken (not multiply) so the drawing's paper vanishes into the linen instead of doubling it */
  mix-blend-mode:darken;
  /* soft falloff on all four sides, so no edge of the scan reads as a frame */
  mask-image:linear-gradient(90deg,transparent 0,#000 13%,#000 87%,transparent 100%),
    linear-gradient(180deg,transparent 0,#000 11%,#000 86%,transparent 100%);
  mask-size:100% 100%,100% 100%;
  mask-position:0 0;
  mask-repeat:no-repeat;
  mask-composite:intersect}
/* third layer is the sweep that paints it in — only where JS can finish the job */
.js .castle{mask-image:linear-gradient(90deg,transparent 0,#000 13%,#000 87%,transparent 100%),
    linear-gradient(180deg,transparent 0,#000 11%,#000 86%,transparent 100%),
    linear-gradient(96deg,#000 50%,rgba(0,0,0,.42) 76%,transparent 100%);
  mask-size:100% 100%,100% 100%,0% 100%}
.js .castle.shown{mask-size:100% 100%,100% 100%,320% 100%}
.count{display:flex;gap:36px;justify-content:center;padding-block:28px 64px;border-top:1px solid rgba(195,171,130,.5);max-width:520px;margin:0 auto}
.count div{display:grid;gap:2px}
.count b{font-weight:400;font-size:30px;font-variant-numeric:tabular-nums;letter-spacing:.04em}
.count span{font-size:11px;letter-spacing:.24em;color:var(--earth-muted)}

/* Program */
.program{background:var(--sage);padding-block:112px;text-align:center}
.sec-head{display:grid;gap:14px;justify-items:center;margin-bottom:56px}
.sec-head h2{font-size:clamp(34px,5vw,48px);letter-spacing:.12em;line-height:1.1}
.days{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px}
.day{background:var(--linen);box-shadow:0 24px 46px -34px rgba(51,44,38,.5);padding:44px 28px 48px;display:grid;align-content:start;gap:22px;justify-items:center;min-width:0}
.day.main{background:var(--moss);color:var(--linen)}
.day.main .when{color:rgba(241,236,226,.72)}
.day h3{font-size:24px;letter-spacing:.14em}
.day .sub{margin-top:-14px}
.day ol{list-style:none;margin:0;padding:0;display:grid;gap:16px;width:100%}
.day li{display:grid;gap:0}
.when{font-size:12px;letter-spacing:.22em;color:var(--earth-muted);font-variant-numeric:tabular-nums}
.what{font-size:15px;letter-spacing:.08em}

/* Details + Gifts arches */
.details{padding-block:112px;background:var(--linen)}
.arches{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);align-items:end;gap:0;max-width:960px;margin:0 auto}
.arch{border-radius:999px 999px 0 0;box-shadow:0 34px 64px -44px rgba(51,44,38,.45);text-align:center;display:grid;align-content:start;justify-items:center;gap:26px;padding:clamp(72px,10vw,120px) clamp(28px,6vw,64px) 64px;min-width:0}
.arch.a{background:var(--linen-deep)}
.arch.b{background:var(--moss);color:var(--linen);margin-left:-56px;margin-bottom:-40px;position:relative}
.arch h2{font-size:clamp(28px,4vw,38px);letter-spacing:.12em;line-height:1.15}
.facts{display:grid;gap:26px;max-width:420px}
.facts h3{font-size:16px;letter-spacing:.2em;margin-bottom:4px}
.facts p{color:var(--earth-muted);font-size:14px}
.arch.b p{color:rgba(241,236,226,.85);max-width:280px}
.lily{width:64px;height:120px;stroke:var(--gold);fill:none;stroke-width:1}
.arch.b .script{font-size:56px;color:var(--linen)}

/* Venue */
.venue{background:var(--linen);padding-block:120px 112px}
.venue .inner{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:64px;align-items:center}
.venue .text{display:grid;gap:20px;max-width:440px}
.venue h2{font-size:clamp(30px,4.4vw,42px);letter-spacing:.1em;line-height:1.15}
.venue p{color:var(--earth-muted)}
.venue dl{display:grid;grid-template-columns:auto 1fr;gap:10px 24px;margin:8px 0 0;font-size:13px}
.venue dt{letter-spacing:.22em;color:var(--earth-muted)}
.venue dd{margin:0;letter-spacing:.06em}
.frame{padding:14px;border:1px solid var(--gold);background:var(--linen);box-shadow:0 28px 52px -36px rgba(51,44,38,.45)}
.frame img{display:block;width:100%;mix-blend-mode:darken}

/* RSVP */
.rsvp{position:relative;padding-block:140px;text-align:center;color:var(--linen);background:var(--earth) center/cover;overflow:hidden}
.rsvp::before{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(51,44,38,.55),rgba(89,100,82,.78))}
.rsvp .inner{position:relative;display:grid;gap:22px;justify-items:center}
.rsvp h2{font-size:clamp(56px,10vw,104px);letter-spacing:.12em;line-height:1}
.rsvp p{max-width:440px;color:rgba(241,236,226,.88)}
.rsvp .eyebrow{color:rgba(241,236,226,.75)}

footer{background:var(--navy);color:var(--linen);text-align:center;padding-block:64px}
footer .inner{display:grid;gap:14px;justify-items:center}
footer .script{font-size:52px}
footer small{font-size:11px;letter-spacing:.24em;color:rgba(241,236,226,.6)}

/* ---------- Reveal: the page writes and paints itself in ----------
   Atoms hide only once JS is there to bring them back. Each box stamps an
   index on its children; --d turns that into a stagger. Parallax rides on
   `translate` so it composes with the entry `transform` instead of fighting it. */
.flt{translate:0 var(--py,0px)}
.js .rv-a{--d:calc(var(--i,0)*90ms)}
.js .day,.js .arch,.js .frame{opacity:0;transform:translateY(20px);
  transition:opacity .9s ease,transform 1.2s cubic-bezier(.2,.65,.2,1)}
.js .day.shown,.js .arch.shown,.js .frame.shown{opacity:1;transform:none}

/* body copy: settles up out of the paper */
.js .rv-a.ink{opacity:0;transform:translateY(12px);
  transition:opacity .85s ease var(--d),transform 1.1s cubic-bezier(.2,.65,.2,1) var(--d)}
.js .rv-a.ink.shown{opacity:1;transform:none}

/* headings, dates, rules: a nib laying ink left to right.
   The mask GROWS from zero width rather than sliding — mask-position does not
   interpolate in Chrome, mask-size does, and a growing gradient gives the same
   travelling soft edge. */
.js .rv-a.write{
  -webkit-mask-image:linear-gradient(93deg,#000 52%,rgba(0,0,0,.45) 76%,transparent 100%);
  mask-image:linear-gradient(93deg,#000 52%,rgba(0,0,0,.45) 76%,transparent 100%);
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:0 0;mask-position:0 0;
  -webkit-mask-size:0% 100%;mask-size:0% 100%;
  transition:-webkit-mask-size 1.4s cubic-bezier(.35,.55,.2,1) var(--d),
    mask-size 1.4s cubic-bezier(.35,.55,.2,1) var(--d)}
.js .rv-a.write.shown{-webkit-mask-size:340% 100%;mask-size:340% 100%}

/* images and marks: wash in from blurred, like pigment drying */
.js .rv-a.paint{opacity:0;filter:blur(7px);
  transition:opacity 1s ease var(--d),filter 1.5s ease var(--d),
    mask-size 1.9s cubic-bezier(.35,.55,.2,1) var(--d)}
.js .rv-a.paint.shown{opacity:1;filter:none}

@media (max-width:760px){
  nav.top ul{display:none}
  nav.top .inner{grid-template-columns:1fr}
  nav.top .inner>a{justify-self:center}
  .days{grid-template-columns:minmax(0,1fr)}
  .arches{grid-template-columns:minmax(0,1fr)}
  .arch.b{margin:-48px 20px 0}
  .venue .inner{grid-template-columns:minmax(0,1fr);gap:40px}
  .count{gap:22px}
  .program,.details{padding-block:80px}
  .rsvp{padding-block:104px}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{transition-duration:.01ms!important;animation:none!important}
  .flt{translate:none}
  .js .rv-a.ink,.js .rv-a.write,.js .rv-a.paint,
  .js .day,.js .arch,.js .frame{opacity:1;transform:none;filter:none}
  .js .rv-a.write{-webkit-mask-image:none;mask-image:none}
  .js .castle{mask-size:100% 100%,100% 100%,320% 100%}
}
