/* ============================================================
   INK & PAPER — This Is Ryan Edwards (wedding services)
   Tactile wedding-stationery storytelling.
   Palette: warm paper, rich ink, eucalyptus, dusty rose.
   ============================================================ */

:root{
  /* paper + ink */
  --paper:        #F7F2E9;
  --paper-deep:   #EFE6D5;
  --paper-shade:  #E7DBC5;
  --ink:          #23201C;   /* warm near-black */
  --ink-soft:     #5A5147;   /* muted brown for secondary text */
  --ink-faint:    #726755;   /* tertiary text — kept ≥4.5:1 on paper for AA */

  /* muted accents */
  --eucalyptus:   #6E7C63;
  --eucalyptus-d: #56624D;
  --rose:         #BC8A85;
  --rose-d:       #A56F6A;   /* decorative / borders (≥3:1) — NOT for small text */
  --rose-text:    #925A55;   /* AA rose for small error/placeholder TEXT (4.94:1 on paper) */

  --rule:         rgba(35,32,28,0.18);
  --rule-soft:    rgba(35,32,28,0.10);

  /* type */
  --serif-display: "Fraunces", "Hoefler Text", "Georgia", "Times New Roman", serif;
  --serif-body:    "EB Garamond", "Iowan Old Style", "Palatino Linotype", "Georgia", serif;
  --script:        "Caveat", "Segoe Script", "Bradley Hand", cursive;

  /* fluid type scale */
  --fs-micro:   clamp(0.68rem, 0.64rem + 0.18vw, 0.76rem);
  --fs-eyebrow: clamp(0.72rem, 0.68rem + 0.2vw, 0.82rem);
  --fs-body:    clamp(1.04rem, 1.0rem + 0.28vw, 1.2rem);
  --fs-lead:    clamp(1.3rem, 1.08rem + 1.0vw, 1.78rem);
  --fs-h3:      clamp(1.45rem, 1.15rem + 1.5vw, 2.15rem);
  --fs-h2:      clamp(2.05rem, 1.4rem + 3.1vw, 3.5rem);
  --fs-h1:      clamp(2.7rem, 1.5rem + 5.6vw, 5.7rem);
  --fs-numeral: clamp(2.6rem, 1.4rem + 5vw, 5rem);

  /* layout */
  --measure: 62ch;
  --gutter:  clamp(1.15rem, 5vw, 6rem);
  --section-y: clamp(4.5rem, 10vw, 9rem);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

*,*::before,*::after{ box-sizing:border-box; }

html{ -webkit-text-size-adjust:100%; overflow-x:hidden; overflow-x:clip; }

body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--serif-body);
  font-size:var(--fs-body);
  line-height:1.72;
  font-weight:440;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
  overflow-x:clip;
}

/* Only hide the native cursor when we actually paint a custom one (set by JS). */
html.has-cursor, html.has-cursor a, html.has-cursor button{ cursor:none; }
html.has-cursor input,
html.has-cursor textarea,
html.has-cursor select{ cursor:text; }

img{ max-width:100%; display:block; }

a{ color:inherit; text-decoration:none; }

::selection{ background:var(--eucalyptus); color:var(--paper); }

/* ---------- accessibility: focus + skip link ---------- */
:focus-visible{
  outline:2px solid var(--eucalyptus-d);
  outline-offset:3px;
  border-radius:2px;
}
.skip{
  position:absolute; left:50%; top:-4rem; transform:translateX(-50%);
  background:var(--ink); color:var(--paper);
  padding:0.6rem 1.1rem; z-index:1000; border-radius:0 0 6px 6px;
  font-family:var(--serif-body); letter-spacing:0.02em;
  transition:top 0.25s var(--ease);
}
.skip:focus{ top:0; }

/* ---------- texture layers ---------- */
.grain{
  position:fixed; inset:0; width:100%; height:100%;
  pointer-events:none; z-index:0;
  opacity:0.06;
  /* RASTERISED once, tiled cheaply — no live filter, and no blend mode, so
     there is no full-viewport GPU backdrop render surface (was a freeze factor).
     Over near-white paper at 0.06, a plain darken reads the same. */
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:140px 140px;
}
/* very soft vignette to give the paper a printed edge */
.vignette{
  position:fixed; inset:0; pointer-events:none; z-index:0;
  background:radial-gradient(120% 90% at 50% 20%, transparent 55%, rgba(120,104,80,0.10) 100%);
}

/* ---------- the connective ink line (spine) ---------- */
.page{ position:relative; z-index:1; }
/* keep real content above the spine (a z-index:0 positioned element would
   otherwise paint over in-flow text). Transparent areas still reveal the line. */
main, .site-footer{ position:relative; z-index:1; }

.spine-wrap{
  position:absolute; top:0; bottom:0;
  left:clamp(0.4rem, 4.5vw, 5rem);
  width:140px;
  z-index:0; pointer-events:none;
  opacity:0.85;
}
.spine-wrap svg{ width:100%; height:100%; display:block; }
.spine-path{
  fill:none;
  stroke:var(--eucalyptus-d);
  stroke-width:1.6;
  stroke-linecap:round;
  stroke-linejoin:round;
  vector-effect:non-scaling-stroke;
  opacity:0.55;
}
@media (max-width:900px){
  .spine-wrap{ left:0.15rem; width:56px; opacity:0.5; }
}
/* phones: there is no gutter for the line to live in — it ends up running
   under the text, so it hides entirely. (The draw scrub in app.js is guarded:
   a hidden path just never animates.) */
@media (max-width:767px){
  .spine-wrap{ display:none; }
}

/* ---------- custom cursor (nib) ---------- */
.cursor{
  position:fixed; top:0; left:0; z-index:9999;
  pointer-events:none; opacity:0;
  will-change:transform;
}
.cursor__dot{
  width:8px; height:8px; margin:-4px 0 0 -4px;
  border-radius:50%; background:var(--ink);
}
.cursor__ring{
  position:fixed; top:0; left:0; z-index:9998;
  width:40px; height:40px; margin:-20px 0 0 -20px;
  border:1px solid var(--rule); border-radius:50%;
  pointer-events:none; opacity:0; will-change:transform;
}

/* ============================================================
   TYPOGRAPHY HELPERS
   ============================================================ */
.eyebrow{
  font-family:var(--serif-body);
  font-size:var(--fs-eyebrow);
  letter-spacing:0.32em; text-transform:uppercase;
  color:var(--ink-soft); font-weight:560;
  margin:0;
}
.script{
  font-family:var(--script);
  font-size:clamp(1.35rem,1rem+1.4vw,2rem);
  color:var(--eucalyptus-d);
  line-height:1.1;
}
.numeral{
  font-family:var(--serif-display);
  font-optical-sizing:auto;
  font-size:var(--fs-numeral);
  font-weight:340; line-height:0.9;
  color:var(--rose-d);
  font-feature-settings:"lnum" 0;
}
h1,h2,h3{ font-family:var(--serif-display); font-optical-sizing:auto; font-weight:380; }
h1{ font-size:var(--fs-h1); line-height:1.02; letter-spacing:-0.012em; margin:0; }
h2{ font-size:var(--fs-h2); line-height:1.06; letter-spacing:-0.01em; margin:0; }
h3{ font-size:var(--fs-h3); line-height:1.12; margin:0; }
em, .i{ font-style:italic; }
.lead{
  font-family:var(--serif-display); font-optical-sizing:auto;
  font-size:var(--fs-lead); line-height:1.45; font-weight:340;
  color:var(--ink); font-style:italic;
}
p{ margin:0 0 1.1em; max-width:var(--measure); }
.hairline{ border:0; height:1px; background:var(--rule); margin:0; }

/* ornament rule: — ◆ — */
.ornament{
  display:flex; align-items:center; justify-content:center; gap:1rem;
  color:var(--ink-faint); margin:var(--section-y) auto;
  max-width:340px;
}
.ornament::before,.ornament::after{
  content:""; height:1px; flex:1; background:var(--rule);
  transform:scaleX(var(--orn,1)); transform-origin:center;   /* draw-in hook (JS sets --orn) */
}
.ornament span{ font-size:0.8rem; transform:rotate(45deg); color:var(--rose-d); }

/* ============================================================
   LAYOUT SHELL
   ============================================================ */
.wrap{
  width:min(100% - 2 * var(--gutter), 1160px);
  margin-inline:auto;
}
.measure{ max-width:var(--measure); }

section{ position:relative; }
.section-pad{ padding-block:var(--section-y); }

/* section header block (order-of-service style) */
.sec-head{ margin-bottom:clamp(2rem,5vw,3.5rem); }
.sec-head .eyebrow{ margin-bottom:0.9rem; }

/* ============================================================
   NAV
   ============================================================ */
.site-header{
  position:fixed; top:0; left:0; right:0; z-index:100;
  transition:background 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
.site-header::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:1px;
  background:var(--rule-soft); opacity:0; transition:opacity 0.4s var(--ease);
}
.site-header.is-stuck{
  background:rgba(247,242,233,0.82);
  backdrop-filter:blur(9px) saturate(1.1);
}
.site-header.is-stuck::after{ opacity:1; }
.nav{
  display:flex; align-items:center; justify-content:space-between;
  gap:1rem; padding-block:clamp(0.8rem,2vw,1.3rem);
}
.brand{
  display:inline-flex; align-items:baseline; gap:0.55rem;
  font-family:var(--serif-display); font-weight:400;
  font-size:clamp(1.05rem,0.9rem+0.6vw,1.35rem); letter-spacing:0.01em;
}
/* circular illustrated brand mark (nav) — same footprint as the old monogram */
.brand__mark{
  display:inline-block; flex:none;
  width:2.1rem; height:2.1rem;
  border:1px solid var(--ink); border-radius:50%;
  overflow:hidden; background:var(--paper);
  align-self:center;
}
.brand__mark img{
  width:100%; height:100%;
  object-fit:cover; object-position:50% 20%;   /* head sits high in the source — pull the face into the circle */
  border-radius:50%;
}
.brand small{
  font-family:var(--serif-body); font-size:var(--fs-micro);
  letter-spacing:0.24em; text-transform:uppercase; color:var(--ink-soft);
  display:block; margin-top:2px;
}
.nav__links{ display:flex; align-items:center; gap:clamp(1rem,2.2vw,2.1rem); }
.nav__links a{
  font-family:var(--serif-body); font-size:var(--fs-eyebrow);
  letter-spacing:0.16em; text-transform:uppercase; color:var(--ink-soft);
  position:relative; padding-block:0.2rem;
}
.nav__links a .u{
  position:absolute; left:0; right:0; bottom:-2px; height:1px;
  background:var(--ink); transform:scaleX(0); transform-origin:left;
  transition:transform 0.42s var(--ease);
}
.nav__links a:hover .u,.nav__links a:focus-visible .u{ transform:scaleX(1); }
.nav__cta{
  font-family:var(--serif-body); font-size:var(--fs-eyebrow);
  letter-spacing:0.16em; text-transform:uppercase;
  border:1px solid var(--ink); border-radius:100px;
  padding:0.55rem 1.15rem; color:var(--ink);
  position:relative; overflow:hidden; isolation:isolate;
  transition:color 0.4s var(--ease);
}
.nav__cta::before{
  content:""; position:absolute; inset:0; z-index:-1; background:var(--ink);
  transform:translateY(101%); transition:transform 0.45s var(--ease);
}
.nav__cta:hover,.nav__cta:focus-visible{ color:var(--paper); }
.nav__cta:hover::before,.nav__cta:focus-visible::before{ transform:translateY(0); }

.nav__toggle{
  display:none; background:none; border:0; padding:0.4rem;
  font-family:var(--serif-body); letter-spacing:0.2em; text-transform:uppercase;
  font-size:var(--fs-eyebrow); color:var(--ink); cursor:pointer;
  align-items:center; gap:0.5rem;
}
.nav__toggle .bars{ display:inline-grid; gap:4px; width:22px; }
.nav__toggle .bars i{ height:1.5px; background:var(--ink); display:block; }

@media (max-width:820px){
  /* Without JS the links stay visible (they simply wrap). With JS we collapse. */
  html.js .nav__links{
    position:fixed; inset:0; z-index:120;
    flex-direction:column; justify-content:center; gap:1.6rem;
    background:var(--paper-deep);
    transform:translateY(-100%); transition:transform 0.5s var(--ease);
    padding:2rem;
  }
  html.js .nav__links a{ font-size:1.1rem; }
  html.js .nav[data-open="true"] .nav__links{ transform:translateY(0); }
  html.js .nav__toggle{ display:inline-flex; z-index:130; }
  html.js .nav__cta{ display:none; }
}

/* ============================================================
   HERO — the invitation front
   ============================================================ */
.hero{
  min-height:100svh; display:flex; align-items:center;
  padding-block:clamp(7rem,14vh,10rem) clamp(3rem,8vh,5rem);
}
.hero__inner{ width:100%; position:relative; perspective:1400px; }
.invite{
  position:relative;
  border:1px solid var(--rule);
  padding:clamp(1.8rem,5vw,4rem) clamp(1.4rem,5vw,3.5rem);
  text-align:center;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.35), rgba(255,255,255,0) 40%);
}
/* inner letterpress double-rule */
.invite::before{
  content:""; position:absolute; inset:9px; border:1px solid var(--rule-soft);
  pointer-events:none;
}
.invite__corner{
  position:absolute; width:26px; height:26px; opacity:0.5;
  color:var(--eucalyptus-d);
}
.invite__corner svg{ width:100%; height:100%; }
.invite__corner.tl{ top:14px; left:14px; }
.invite__corner.tr{ top:14px; right:14px; transform:scaleX(-1); }
.invite__corner.bl{ bottom:14px; left:14px; transform:scaleY(-1); }
.invite__corner.br{ bottom:14px; right:14px; transform:scale(-1,-1); }

.hero__eyebrow{ margin-bottom:clamp(1.4rem,3vw,2.2rem); }
.hero__eyebrow b{ color:var(--ink); font-weight:560; }
.hero h1{ margin:0 auto; max-width:16ch; }
.hero h1 .accent{ font-style:italic; color:var(--rose-d); }
.hero__note{
  position:absolute; right:clamp(-0.5rem,2vw,1rem); top:-1.4rem;
  transform:rotate(-6deg);
  color:var(--eucalyptus-d);
}
.hero__meta{
  margin-top:clamp(1.6rem,3.5vw,2.6rem);
  font-family:var(--serif-body); font-style:italic;
  font-size:clamp(1rem,0.95rem+0.4vw,1.24rem); color:var(--ink-soft);
}
.hero__meta .dot{ color:var(--rose-d); margin:0 0.5rem; }
.hero__cues{
  margin-top:clamp(1.8rem,4vw,3rem);
  display:flex; flex-wrap:wrap; gap:0.8rem 1.4rem; align-items:center; justify-content:center;
}
.hero__scroll{
  display:inline-flex; align-items:center; gap:0.6rem;
  font-family:var(--serif-body); font-size:var(--fs-eyebrow);
  letter-spacing:0.24em; text-transform:uppercase; color:var(--ink-soft);
}
.hero__scroll .down{
  width:1px; height:38px; background:var(--ink-soft); position:relative; overflow:hidden;
}
.hero__scroll .down::after{
  content:""; position:absolute; inset:0; background:var(--rose-d);
  transform:translateY(-100%); animation:drip 2.6s var(--ease) infinite;
}
@keyframes drip{ 0%{transform:translateY(-100%);} 45%{transform:translateY(0);} 100%{transform:translateY(101%);} }

.btn{
  display:inline-flex; align-items:center; gap:0.7rem;
  font-family:var(--serif-body); font-size:var(--fs-eyebrow);
  letter-spacing:0.16em; text-transform:uppercase;
  padding:0.85rem 1.6rem; border-radius:100px;
  border:1px solid var(--ink); color:var(--paper); background:var(--ink);
  position:relative; overflow:hidden; isolation:isolate;
  transition:color 0.4s var(--ease); cursor:pointer;
}
.btn::before{
  content:""; position:absolute; inset:0; z-index:-1; background:var(--paper);
  transform:translateY(101%); transition:transform 0.5s var(--ease);
}
.btn:hover,.btn:focus-visible{ color:var(--ink); }
.btn:hover::before,.btn:focus-visible::before{ transform:translateY(0); }
.btn.btn--ghost{ background:transparent; color:var(--ink); }
.btn.btn--ghost::before{ background:var(--ink); }
.btn.btn--ghost:hover,.btn.btn--ghost:focus-visible{ color:var(--paper); }
.btn[disabled]{ opacity:0.6; cursor:default; }

/* ============================================================
   INTRO — one person, your whole day (interlocking rings)
   ============================================================ */
.intro{ text-align:center; }
.intro .rings{
  width:min(240px,55vw); margin:0 auto clamp(1.6rem,4vw,2.6rem);
}
.intro .rings svg{ width:100%; height:auto; overflow:visible; }
.ring-a{ fill:none; stroke:var(--ink); stroke-width:2; }
.ring-b{ fill:none; stroke:var(--rose-d); stroke-width:2; }
.intro h2{ max-width:18ch; margin:0 auto; }
.intro .lead{ margin:1.6rem auto 0; }
.intro__three{
  margin-top:clamp(2.4rem,5vw,3.6rem);
  display:flex; flex-wrap:wrap; gap:0.4rem 1.4rem; justify-content:center;
  font-family:var(--serif-display); font-style:italic;
  font-size:clamp(1.1rem,0.95rem+0.7vw,1.5rem); color:var(--ink-soft);
}
.intro__three .amp{ color:var(--rose-d); font-style:normal; }

/* ============================================================
   CHAPTERS — Ceremony / Reception / First Dance
   ============================================================ */
.chapter{
  display:grid; gap:clamp(1.8rem,4vw,3.5rem);
  grid-template-columns:1fr;
  align-items:center;
  padding-block:clamp(3rem,7vw,5.5rem);
  position:relative;
}
/* full-width rule between chapter bands — reads as the crease across the sheet */
.chapter-band + .chapter-band{ border-top:1px solid var(--rule-soft); }
@media (min-width:900px){
  .chapter{ grid-template-columns:1.05fr 0.95fr; }
  .chapter.flip .chapter__media{ order:-1; }
}
.chapter__body{ max-width:56ch; }
.chapter__kicker{ display:flex; align-items:baseline; gap:1rem; margin-bottom:1.1rem; }
.chapter__kicker .role{
  font-family:var(--serif-body); font-size:var(--fs-eyebrow);
  letter-spacing:0.28em; text-transform:uppercase; color:var(--eucalyptus-d);
  font-weight:560;
}
.chapter h3{ margin:0.1rem 0 0.4rem; }
.chapter__sub{
  font-family:var(--serif-display); font-style:italic; font-weight:340;
  font-size:clamp(1.1rem,1rem+0.5vw,1.4rem); color:var(--ink-soft); margin:0 0 1.3rem;
}
.included{ list-style:none; margin:1.5rem 0 0; padding:0; }
.included li{
  display:grid; grid-template-columns:auto 1fr; gap:0.9rem; align-items:baseline;
  padding:0.7rem 0; border-top:1px solid var(--rule-soft);
  max-width:52ch;
}
.included li:last-child{ border-bottom:1px solid var(--rule-soft); }
.included .mk{ color:var(--rose-d); font-family:var(--serif-display); }
.legal-note{
  margin-top:1.3rem; font-size:0.94rem; color:var(--ink-faint); font-style:italic;
  max-width:52ch;
}

/* media plates — real imagery bundled locally in /assets (absolute paths).
   The labelled plate below stays as an onerror fallback, so the page still
   reads if an image fails to load. */
.plate{
  position:relative; aspect-ratio:4/5; border:1px solid var(--rule);
  display:grid; place-items:center; text-align:center;
  overflow:hidden; isolation:isolate; margin:0;
  background:
    linear-gradient(135deg, var(--paper-deep), var(--paper-shade));
  box-shadow:0 20px 44px -26px rgba(35,32,28,0.55);
}
.plate::before{ /* mat frame, sits above the mounted photo */
  content:""; position:absolute; inset:10px; border:1px solid var(--rule-soft); z-index:3;
}
.plate::after{ /* soft ink wash for depth — only visible when no image is present */
  content:""; position:absolute; inset:0; z-index:-1;
  background:radial-gradient(90% 70% at 30% 20%, rgba(110,124,99,0.16), transparent 60%),
             radial-gradient(80% 60% at 80% 90%, rgba(188,138,133,0.16), transparent 60%);
}
/* mounted keepsake-print treatment: cover photo + sepia/palette duotone,
   grain, vignette and album photo-corners, so imagery feels engraved on the paper */
.plate__img{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:center; z-index:1;
  filter:sepia(0.30) saturate(0.82) contrast(1.03) brightness(1.02);
  /* De-promoted: previously forced a permanent GPU layer (13 full-res filtered
     images → part of the compositor-wedge freeze). backface-visibility:hidden
     alone keeps the filtered img painted without a permanent compositing layer;
     the clip-wipe scrub promotes it transiently while on-screen, then clears. */
  backface-visibility:hidden;
}
.plate__wash{
  position:absolute; inset:0; z-index:2; pointer-events:none;
  mix-blend-mode:multiply;
  background:
    linear-gradient(135deg, var(--ink) 0 9px, transparent 9px) left 5px top 5px / 15px 15px no-repeat,
    linear-gradient(225deg, var(--ink) 0 9px, transparent 9px) right 5px top 5px / 15px 15px no-repeat,
    linear-gradient(45deg,  var(--ink) 0 9px, transparent 9px) left 5px bottom 5px / 15px 15px no-repeat,
    linear-gradient(315deg, var(--ink) 0 9px, transparent 9px) right 5px bottom 5px / 15px 15px no-repeat,
    radial-gradient(120% 92% at 50% 42%, transparent 56%, rgba(35,32,28,0.30) 100%),
    linear-gradient(180deg, rgba(110,124,99,0.12), rgba(35,32,28,0.10));
}
.plate__wash::before{ /* fine paper grain over the print */
  content:""; position:absolute; inset:0; pointer-events:none;
  opacity:0.40; mix-blend-mode:soft-light;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size:140px 140px;
}
.plate--hero{
  aspect-ratio:auto; width:100%; height:clamp(180px, 34vh, 360px);
  margin-top:clamp(1.4rem, 4vw, 2.4rem);
}
.plate .cap{
  font-family:var(--serif-body); font-style:italic; color:var(--ink-soft);
  font-size:0.98rem; letter-spacing:0.01em; padding:1.4rem; max-width:26ch;
}
.plate .cap b{
  display:block; font-style:normal; font-family:var(--serif-body);
  font-size:var(--fs-micro); letter-spacing:0.28em; text-transform:uppercase;
  color:var(--ink-soft); margin-bottom:0.6rem; font-weight:560; /* AA on the plate's darker paper tint */
}
.plate.tall{ aspect-ratio:3/4; }

/* the waveform → melody motif */
.motif{ width:100%; margin:1.6rem 0 0; }
.motif svg{ width:100%; height:auto; overflow:visible; }
.wave-line{ fill:none; stroke:var(--eucalyptus-d); stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.note-dot{ fill:var(--rose-d); }

/* ============================================================
   ABOUT — the author's page
   ============================================================ */
.about{ position:relative; }
.about__grid{
  display:grid; gap:clamp(1.8rem,4vw,3.4rem); grid-template-columns:1fr; align-items:start;
}
@media (min-width:900px){ .about__grid{ grid-template-columns:0.85fr 1.15fr; } }
.about__body{ max-width:58ch; }
.about__body .lead{ margin-top:0.2rem; }
.dropcap::first-letter{
  font-family:var(--serif-display); font-weight:400;
  float:left; font-size:3.6em; line-height:0.72; padding:0.06em 0.12em 0 0;
  color:var(--rose-d);
}
.notes{ list-style:none; margin:1.8rem 0 0; padding:0; }
.notes li{
  display:grid; grid-template-columns:auto 1fr; gap:1rem; align-items:baseline;
  padding:0.55rem 0; font-size:0.98rem; color:var(--ink-soft);
}
.notes .yr{ font-family:var(--serif-display); font-style:italic; color:var(--eucalyptus-d); white-space:nowrap; }
.coast{ margin-top:2rem; }
.coast svg{ width:100%; height:auto; overflow:visible; }
.coast-line{ fill:none; stroke:var(--ink); stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; }
.coast-note{ font-family:var(--script); fill:var(--eucalyptus-d); font-size:20px; }

/* ============================================================
   ON STAGE — twenty-year performance archive strip
   ============================================================ */
.onstage{ position:relative; }
.onstage__strip{
  display:grid;
  gap:clamp(1rem,2.6vw,1.8rem);
  grid-template-columns:repeat(auto-fit, minmax(clamp(140px, 40vw, 195px), 1fr));
}
.onstage__item{ margin:0; }
.onstage__cap{
  font-family:var(--serif-body); font-style:italic; color:var(--ink-soft);
  font-size:0.96rem; line-height:1.45; text-align:center;
  margin-top:0.9rem;
}

/* ============================================================
   HOW IT WORKS — RSVP-style steps
   ============================================================ */
.steps{ counter-reset:step; margin-top:clamp(2rem,4vw,3rem); }
.step{
  display:grid; grid-template-columns:auto 1fr; gap:clamp(1.1rem,3vw,2.4rem);
  padding:clamp(1.4rem,3vw,2.2rem) 0; border-top:1px solid var(--rule);
  align-items:start;
}
.step:last-child{ border-bottom:1px solid var(--rule); }
.step__no{
  font-family:var(--serif-display); font-weight:330; line-height:0.9;
  font-size:clamp(2rem,1.4rem+2.4vw,3.2rem); color:var(--rose-d);
}
.step h3{ margin-bottom:0.5rem; }
.step p{ margin-bottom:0; color:var(--ink-soft); }

/* ============================================================
   FAQ — order-of-service questions (accessible accordion)
   ============================================================ */
.faq__list{ margin-top:clamp(2rem,4vw,3rem); }
.faq__item{ border-top:1px solid var(--rule); }
.faq__item:last-child{ border-bottom:1px solid var(--rule); }
.faq__q{
  list-style:none; cursor:pointer;
  display:grid; grid-template-columns:1fr auto; gap:1rem; align-items:baseline;
  padding:clamp(1.1rem,2.6vw,1.6rem) 0;
  font-family:var(--serif-display); font-optical-sizing:auto; font-weight:380;
  font-size:clamp(1.15rem,1rem+0.7vw,1.55rem); line-height:1.2; color:var(--ink);
}
.faq__q::-webkit-details-marker{ display:none; }   /* Safari default triangle */
.faq__q::marker{ content:""; }                       /* Firefox/Chrome list marker */
.faq__mk{
  flex:none; align-self:center;
  font-size:0.85rem; color:var(--rose-d);
  transform:rotate(45deg); transform-origin:center;
  transition:transform 0.4s var(--ease);
}
.faq__item[open] .faq__mk{ transform:rotate(225deg); }
.faq__a{
  padding:0 0 clamp(1.2rem,2.6vw,1.9rem);
  max-width:62ch;
}
.faq__a p{ margin:0; color:var(--ink-soft); }

/* ============================================================
   ENQUIRY — RSVP card form
   ============================================================ */
.rsvp{ position:relative; }
.card{
  position:relative;
  border:1px solid var(--rule);
  padding:clamp(1.6rem,5vw,3.4rem);
  background:linear-gradient(180deg, rgba(255,255,255,0.4), transparent 30%);
}
.card::before{ content:""; position:absolute; inset:9px; border:1px dashed var(--rule-soft); pointer-events:none; }
.card__head{ text-align:center; margin-bottom:clamp(1.8rem,4vw,2.8rem); }
.card__head .script{ display:block; margin-top:0.5rem; }
.boutique-note{
  margin:1.1rem auto 0; max-width:46ch;
  font-size:var(--fs-micro); letter-spacing:0.16em; text-transform:uppercase;
  color:var(--ink-faint); font-style:normal;
}
.form-grid{ display:grid; gap:clamp(1.1rem,2.5vw,1.7rem) clamp(1.4rem,3vw,2.4rem); grid-template-columns:1fr; max-width:none; }
@media (min-width:680px){ .form-grid{ grid-template-columns:1fr 1fr; } }
.field{ display:flex; flex-direction:column; gap:0.5rem; }
.field.full{ grid-column:1 / -1; }
.field label{
  font-family:var(--serif-body); font-size:var(--fs-eyebrow);
  letter-spacing:0.16em; text-transform:uppercase; color:var(--ink-soft);
}
.field label .req{ color:var(--rose-d); }
.field input,.field textarea{
  font-family:var(--serif-body); font-size:1.05rem; color:var(--ink);
  background:transparent; border:0; border-bottom:1px solid var(--rule);
  padding:0.5rem 0.1rem; border-radius:0; transition:border-color 0.3s var(--ease);
}
.field textarea{ resize:vertical; min-height:5.5rem; }
.field input::placeholder,.field textarea::placeholder{ color:var(--ink-faint); font-style:italic; }
.field input:focus,.field textarea:focus{ outline:none; border-color:var(--eucalyptus-d); }
.field input[aria-invalid="true"],.field textarea[aria-invalid="true"]{ border-color:var(--rose-d); }
.field .err{ font-size:0.85rem; color:var(--rose-text); font-style:italic; min-height:1em; }

fieldset.services{ border:0; padding:0; margin:0; grid-column:1 / -1; }
fieldset.services legend{
  font-family:var(--serif-body); font-size:var(--fs-eyebrow);
  letter-spacing:0.16em; text-transform:uppercase; color:var(--ink-soft); padding:0; margin-bottom:0.9rem;
}
.chips{ display:flex; flex-wrap:wrap; gap:0.7rem; }
.chip{ position:relative; }
.chip input{ position:absolute; opacity:0; inset:0; cursor:pointer; }
.chip span{
  display:inline-flex; align-items:center; gap:0.5rem;
  border:1px solid var(--rule); border-radius:100px; padding:0.55rem 1.05rem;
  font-family:var(--serif-body); letter-spacing:0.04em; color:var(--ink-soft);
  transition:all 0.3s var(--ease); cursor:pointer;
}
.chip span::before{
  content:""; width:8px; height:8px; border-radius:50%;
  border:1px solid var(--ink-faint); transition:all 0.3s var(--ease);
}
.chip input:checked + span{ border-color:var(--ink); color:var(--ink); background:rgba(110,124,99,0.10); }
.chip input:checked + span::before{ background:var(--eucalyptus-d); border-color:var(--eucalyptus-d); }
.chip input:focus-visible + span{ outline:2px solid var(--eucalyptus-d); outline-offset:2px; }

/* CELEBRANT-PENDING: disabled celebrant chip, heading star and status note — remove this block when registration is confirmed */
.chip--soon span{ cursor:not-allowed; }
.chip input:disabled + span{ opacity:0.5; cursor:not-allowed; background:transparent; border-color:var(--rule); color:var(--ink-soft); }
.chip input:disabled + span::before{ opacity:0.45; }
.chip__soon{
  font-style:normal; font-size:0.62rem; line-height:1; letter-spacing:0.14em; text-transform:uppercase;
  padding:0.2rem 0.45rem; border-radius:100px; border:1px solid var(--rule); color:var(--ink-soft);
}
.celebrant-star{ color:var(--rose-d); text-decoration:none; font-weight:600; padding-left:0.12em; }
.celebrant-star:hover, .celebrant-star:focus-visible{ text-decoration:underline; }
.celebrant-note{ font-style:normal; }
.celebrant-note__star{ color:var(--rose-d); font-weight:600; }

.form-foot{ grid-column:1 / -1; display:flex; flex-wrap:wrap; align-items:center; gap:1rem 1.6rem; margin-top:0.6rem; }
.form-foot .note{ font-size:0.92rem; color:var(--ink-faint); font-style:italic; max-width:40ch; }
.form-status{ grid-column:1 / -1; font-family:var(--serif-body); }
.form-status[data-state="ok"]{ color:var(--eucalyptus-d); }
.form-status[data-state="err"]{ color:var(--rose-text); }
.hp{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }

/* ============================================================
   FOOTER
   ============================================================ */
.site-footer{
  padding-block:clamp(3.5rem,8vw,6rem) clamp(2rem,4vw,3rem);
  border-top:1px solid var(--rule); margin-top:var(--section-y);
  text-align:center; position:relative;
}
.footer__sign{ margin-bottom:1.4rem; }
.footer__mark{
  display:inline-block; width:3.4rem; height:3.4rem; margin:0 auto 0.4rem;
  border:1px solid var(--ink); border-radius:50%;
  overflow:hidden; background:var(--paper);
}
.footer__mark img{
  width:100%; height:100%;
  object-fit:cover; object-position:50% 20%;
  border-radius:50%;
}
.footer__brand{ font-family:var(--serif-display); font-size:clamp(1.6rem,1.2rem+2vw,2.6rem); margin:0.4rem 0 1.4rem; }
.footer__nav{
  display:flex; flex-wrap:wrap; gap:0.9rem 1.6rem; justify-content:center;
  margin:1.6rem 0 0.4rem;
}
.footer__nav a{
  font-family:var(--serif-body); font-size:var(--fs-eyebrow);
  letter-spacing:0.16em; text-transform:uppercase; color:var(--ink-soft);
  position:relative; padding-bottom:3px;
}
.footer__nav a::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:1px;
  background:var(--ink); transform:scaleX(0); transform-origin:left;
  transition:transform 0.4s var(--ease);
}
.footer__nav a:hover::after,.footer__nav a:focus-visible::after{ transform:scaleX(1); }
.footer__social{ display:flex; gap:1.6rem; justify-content:center; margin:1.4rem 0 2rem; }
.footer__social a{
  font-family:var(--serif-body); font-size:var(--fs-eyebrow);
  letter-spacing:0.18em; text-transform:uppercase; color:var(--ink-soft);
  position:relative; padding-bottom:3px;
}
.footer__social a::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:1px;
  background:var(--ink); transform:scaleX(0); transform-origin:left;
  transition:transform 0.4s var(--ease);
}
.footer__social a:hover::after,.footer__social a:focus-visible::after{ transform:scaleX(1); }
.footer__meta{ font-size:0.88rem; color:var(--ink-faint); line-height:1.9; }

/* ============================================================
   REDUCED MOTION — everything static + fully drawn
   ============================================================ */
@media (prefers-reduced-motion: reduce){
  .hero__scroll .down::after{ animation:none; }
  *{ scroll-behavior:auto !important; }
}

/* split-line masking (applied only when SplitText runs; harmless otherwise).
   The clip window is extended past the line box (padding, cancelled by equal
   negative margin so layout is unchanged) — Fraunces descenders (y, g) and
   italic swashes reach beyond the tight display line-height and were being
   sliced off at rest. Hidden lines start at yPercent:130 (app.js) so they
   cannot peek through the taller window before their reveal. */
.split-mask{
  overflow:hidden;
  padding:0.08em 0 0.22em;
  margin:-0.08em 0 -0.22em;
}

/* small screens spacing tweaks */
@media (max-width:560px){
  .hero__note{ position:static; display:block; margin:1rem auto 0; transform:rotate(-3deg); }
  .invite{ padding-inline:1.1rem; }
}

/* ============================================================
   WAX SEAL — shared component (loader seal + RSVP stamp)
   Dusty-rose pressed wax with an embossed interlocking-rings
   motif echoing the site's rings. Purely decorative.
   ============================================================ */
.wax-seal{
  --seal-size:58px;
  width:var(--seal-size); height:var(--seal-size);
  border-radius:50%; position:relative;
  display:grid; place-items:center;
  background:radial-gradient(circle at 38% 30%, #CB9C97 0%, var(--rose) 32%, var(--rose-d) 76%, #8C5B57 100%);
  box-shadow:
    inset 0 2px 4px rgba(255,244,240,0.30),
    inset 0 -3px 7px rgba(88,48,46,0.55),
    0 6px 14px -5px rgba(88,48,46,0.55);
}
.wax-seal::after{                 /* pressed inner rim */
  content:""; position:absolute; inset:4px; border-radius:50%;
  border:1px solid rgba(74,38,36,0.32);
}
.wax-seal svg{ width:62%; height:auto; position:relative; }
.wax-seal .seal-ring{ fill:none; stroke:rgba(72,36,34,0.72); stroke-width:2.6; }
.wax-seal .seal-hi{ fill:none; stroke:rgba(255,242,238,0.32); stroke-width:1; }

/* ============================================================
   ENVELOPE PRE-LOADER — injected by JS only.
   Never shown for reduced-motion / no-GSAP / returning session.
   ============================================================ */
/* Pre-paint gate (class set by the inline head script when the loader will
   run): hide the page so first paint is bare paper, never a flash of content.
   The loader overlay is a SIBLING of .page, so it stays visible. app.js (or
   the inline 4s failsafe) lifts the class. */
.tire-preload .page{ visibility:hidden; }

.tire-loader{
  position:fixed; inset:0; z-index:4000;
  display:flex; align-items:center; justify-content:center;
  background:transparent;                 /* sits directly on the real cream paper — no colour jump on lift */
  overflow:hidden; -webkit-tap-highlight-color:transparent;
}
/* Size set by JS around the scaled invite clone. NOT transformed during the
   rise, so the clone (a sibling between back and front) interleaves by z-index. */
.tire-scene{ position:relative; }
.tire-env{ position:absolute; inset:0; }
/* envelope back — palette-true paper, hairline rule, soft grounded shadow */
.tire-env__body{
  position:absolute; inset:0; z-index:1; border-radius:9px;
  background:var(--paper);
  border:1px solid var(--rule);
  box-shadow:0 36px 72px -34px rgba(35,32,28,0.42);
}
.tire-env__body::before{                  /* inner lining */
  content:""; position:absolute; inset:0; border-radius:9px;
  background:linear-gradient(180deg, var(--paper-deep), var(--paper));
  opacity:0.55;
}
/* interior shadow revealed as the flap lifts (the "shadow pass") */
.tire-env__mouth{
  position:absolute; left:0; right:0; top:0; height:60%; z-index:2;
  border-radius:9px 9px 0 0; pointer-events:none; opacity:0;
  background:linear-gradient(180deg, rgba(35,32,28,0.22), transparent 78%);
}
/* the rising card = a live clone of the real invite. Sits BETWEEN back and
   front (z-index 3); the front pocket overlaps its lower part = the "clip". */
.tire-clone{
  position:absolute; z-index:3; margin:0; will-change:transform;
  box-shadow:0 30px 60px -28px rgba(35,32,28,0.45);
}
/* front pocket — OPAQUE paper (fully occludes the rising card, like a real
   envelope) with the classic V-seam hairlines. The interior opening shadow is
   the separate .tire-env__mouth layer behind the card. */
.tire-env__front{
  position:absolute; inset:0; z-index:4; border-radius:9px;
  clip-path:polygon(0 42%, 50% 92%, 100% 42%, 100% 100%, 0 100%);
  background-color:var(--paper);            /* opaque — no smoked-glass show-through */
  background-image:
    linear-gradient(to bottom right, transparent calc(50% - 0.7px), var(--rule) 50%, transparent calc(50% + 0.7px)),
    linear-gradient(to bottom left,  transparent calc(50% - 0.7px), var(--rule) 50%, transparent calc(50% + 0.7px));
  background-repeat:no-repeat;
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.55);
}
/* top flap — folds up and back; letterpress double-rule echoing .invite::before */
.tire-env__flap{
  position:absolute; inset:0; z-index:5;
  transform-origin:50% 0%; backface-visibility:hidden;
  clip-path:polygon(0 0, 100% 0, 50% 66%);
  background:linear-gradient(180deg, var(--paper), var(--paper-deep));
  border-top:1px solid var(--rule);
  filter:drop-shadow(0 4px 5px rgba(35,32,28,0.12));
}
.tire-env__flap::before{                  /* faint inner rule (letterpress echo) */
  content:""; position:absolute; inset:6px 6px 0; z-index:1;
  clip-path:polygon(0 0, 100% 0, 50% 64%);
  border-top:1px solid var(--rule-soft);
  background:linear-gradient(180deg, rgba(255,255,255,0.35), transparent 40%);
}
.tire-seal{
  position:absolute; left:50%; top:46%; transform:translate(-50%,-50%);
  z-index:6; --seal-size:clamp(46px, 12vw, 58px);
}
.tire-skip{
  position:absolute; bottom:clamp(1.3rem,5vh,2.6rem); left:50%; transform:translateX(-50%);
  z-index:20; font-family:var(--serif-body); font-size:var(--fs-eyebrow);
  letter-spacing:0.2em; text-transform:uppercase; color:var(--ink-soft);
  background:transparent; border:1px solid var(--rule); border-radius:100px;
  padding:0.5rem 1.3rem; cursor:pointer;
  transition:color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.tire-skip:hover, .tire-skip:focus-visible{ color:var(--ink); border-color:var(--ink); }

/* RSVP wax seal — stamped onto the enquiry card's top-right corner */
.wax-seal--rsvp{
  position:absolute; top:-20px; right:-14px; z-index:6;
  --seal-size:clamp(54px, 6vw, 66px); pointer-events:none;
}
@media (max-width:560px){
  .wax-seal--rsvp{ top:-14px; right:-6px; --seal-size:46px; }
}

/* ============================================================
   MICRO-POLISH — restrained tactility (fine pointers only)
   ============================================================ */
.btn{ transition:color 0.4s var(--ease), transform 0.12s var(--ease); }
.btn:active{ transform:translateY(1.5px) scale(0.99); }
@media (prefers-reduced-motion: no-preference) and (hover:hover) and (pointer:fine){
  .plate{ transition:transform 0.5s var(--ease), box-shadow 0.5s var(--ease); }
  .chapter__media:hover .plate,
  .about__media:hover .plate,
  .onstage__item:hover .plate{
    transform:perspective(900px) rotateX(1.6deg) rotateY(-1.8deg) translateY(-3px);
    box-shadow:0 30px 58px -28px rgba(35,32,28,0.6);
  }
}

/* belt-and-braces: loader must never appear under reduced motion */
@media (prefers-reduced-motion: reduce){
  .tire-loader{ display:none !important; }
}

/* ============================================================
   FOLDED-PAPER SCROLL CHOREOGRAPHY
   Panels fold open (rotateX around a top crease) as the letter
   unfolds on scroll. BOTH the rotation and this overlay's opacity
   are driven by JS (app.js) inside its
   hasGSAP && hasST && !reduceMotion guard. With no JS / no GSAP /
   reduced motion these elements are never injected, nothing is
   rotated, and the page renders flat + fully visible. The rules
   below only STYLE the injected overlay — they hide no content.
   ============================================================ */
.fold-panel{ position:relative; }        /* contain the absolutely-placed shade */
.fold-shade{
  position:absolute; inset:0; z-index:20; pointer-events:none;
  opacity:0;                             /* flat default = invisible; JS tweens 1 → 0 with the fold */
  background:linear-gradient(180deg,
    rgba(35,32,28,0.50) 0%,
    rgba(35,32,28,0.20) 18%,
    rgba(35,32,28,0.06) 40%,
    rgba(35,32,28,0)    60%);
}
/* hairline crease at the hinge (top edge), with a soft shadow falling
   away beneath it — fades out with the overlay as the panel flattens */
.fold-shade::before{
  content:""; position:absolute; left:0; right:0; top:0; height:16px;
  border-top:1px solid rgba(35,32,28,0.30);
  background:linear-gradient(180deg, rgba(35,32,28,0.42), rgba(35,32,28,0) 100%);
}
/* belt-and-braces: never shade under reduced motion (JS won't inject it either) */
@media (prefers-reduced-motion: reduce){
  .fold-shade{ display:none !important; }
}
