  :root{
    --stripe-bg: url("Assets/save-the-date.png");
    /* Spring-sky grounds — cool pale-blue paper (token names retained) */
    --cream: #EFF6FA;
    --cream-deep: #DCEAF5;
    --cream-warm: #E6F0F8;
    --ink: #2E3220;
    --ink-soft: #4A4C36;
    /* Spring foliage — fresh new-growth greens (token names retained) */
    --sage: #9AC47C;
    --sage-deep: #45703A;
    --olive: #5D9440;
    --forest: #2C5327;
    --mist: #ADBDAC;         /* pastel garden green — RSVP panel surface */
    /* Spring sky — three-role blue system: text / background / accent (token names retained) */
    --peach: #80A3C2;        /* accent */
    --terracotta: #43627E;   /* text */
    --mustard: #80A3C2;      /* accent */
    --gold: #80A3C2;         /* accent */
    --gold-deep: #43627E;    /* text */
    --champagne: #EBF3F6;    /* pale background / surface */
    --dusty-blue: #80A3C2;   /* accent */
    --line: rgba(51,54,31,0.14);
    --line-gold: rgba(128,163,194,0.35);
    --shadow: 0 26px 60px -28px rgba(72,60,28,0.34), 0 10px 26px -18px rgba(72,60,28,0.22);
    --shadow-soft: 0 30px 80px -40px rgba(72,60,28,0.30);
    --shadow-lift: 0 40px 90px -46px rgba(58,48,22,0.42);
    --ease: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    
    /* Warm accent — the single note of warmth against the cool chrome. Sampled from the spring bouquet (blush garden rose). Use sparingly. */
    --warm: #F0B49E; /* blush-coral — primary warm accent */
    --warm-deep: #D98368; /* deeper blush — hover / emphasis */
    --warm-soft: rgba(232,135,155,0.16); /* tint for glows & fills */
    
    /* Typography — Montserrat throughout (headings + body), with a handwritten script reserved for the hero names */
    
    --font-serif: 'Noto Serif Display', Georgia, serif;   /* sub-headin*s / section titles */
    --font-accent: 'Noto Serif Display', Georgia, serif;  /* accents / italic-style te*t */
    --font-sans: 'Montserrat', system-ui, 'Segoe UI', Arial, sans-serif;    /* body text */
    --font-script: 'Great Vibes', 'Segoe Script', 'Brush Script MT', cursive; /* hero*names */

    --text-display: clamp(3.4rem, 9.8vw, 7rem);   /* hero names (script overrides size below) */
    --text-h2: clamp(2.35rem, 4.9vw, 3.6rem);     /* section titles */
    --text-h3: clamp(1.6rem, 3vw, 2.05rem);       /* block headings */
    --text-lead: 1.15rem;                         /* lead / intro sentences */
    --text-body: 1rem;                            /* 16px — reading-copy floor */
    --text-meta: 0.875rem;                        /* 14px — secondary metadata & hints */
    --text-label: 0.75rem;                        /* 12px — uppercase labels */
    --tracking-label: 0.22em;                     /* consistent all-caps tracking */

    /* Spacing scale — 4pt base. Use gap first; fall back to margin/padding only where gap can't reach.
       Fluid tokens (clamp) for section-level rhythm; fixed tokens for component internals. */
    --space-2xs: 4px;
    --space-xs:  8px;
    --space-sm:  12px;
    --space-md:  16px;
    --space-lg:  24px;
    --space-xl:  32px;
    --space-2xl: 48px;
    --space-3xl: 64px;
    --space-4xl: 96px;
    /* Fluid — sections breathe wider on bigger screens */
    --section-pad-y: clamp(44px, 5.2vw, 74px);
    --section-pad-x: 6vw;
    /* Seam feather — every tinted section dissolves to the page ground across
       this distance at its top and bottom edge, so neighbours always meet on
       the same colour instead of butting two different fills together. */
    --seam-feather: clamp(64px, 8vw, 120px);
    /* The same feather expressed as a mask, for sections that paint an opaque
       surface of their own: masking fades every layer — fill, wallpaper, light —
       to nothing at the edge, so the hand-off is exact rather than eyeballed. */
    --seam-mask: linear-gradient(180deg,
      transparent 0,
      #000 var(--seam-feather),
      #000 calc(100% - var(--seam-feather)),
      transparent 100%);
    /* Live nav height, published by scripts.js so sticky sections can clear the bar.
       Fallback approximates the scrolled nav. */
    --nav-h: 78px;
  }

  *{box-sizing:border-box; margin:0; padding:0;}
  html{scroll-behavior:smooth;}
  body{
    background-color: var(--cream);
    background-image:
      radial-gradient(1200px 760px at 6% 0%, rgba(128,163,194,0.10), transparent 62%),
      radial-gradient(1050px 720px at 100% 10%, rgba(150,190,120,0.10), transparent 62%),
      linear-gradient(rgba(239,246,250,0.45), rgba(239,246,250,0.45)),
      var(--stripe-bg);
    background-repeat:
      no-repeat,
      no-repeat,
      repeat,
      repeat;
    background-size:
      auto,
      auto,
      auto,
      1150px auto;
    background-attachment:
      scroll,
      scroll,
      scroll,
      scroll;
    color: var(--ink);
    font-family: var(--font-sans);
    font-weight: 400;
    line-height: 1.6;
    overflow-x: clip;
    font-optical-sizing: auto;
    font-kerning: normal;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
  }
  @media (hover: hover) and (pointer: fine){
    body{
      background-attachment:
        scroll,
        scroll,
        fixed,
        fixed;
    }
  }
  h1,h2,h3, .serif{
    font-family: var(--font-serif);
    font-weight: 600;
    letter-spacing: -0.02em;
    font-optical-sizing: auto;
  }
  p{ max-width: 62ch; text-wrap: pretty; }
  a{ color: inherit; }
  img{max-width:100%; display:block;}

  ::selection{ background: var(--champagne); color: var(--ink); }

  /* Film-grain / pressed-paper texture — fixed, non-interactive, sits under the nav
     so chrome stays crisp. Purely decorative; adds tactile "printed invitation" depth. */
  .paper-grain{
    position: fixed; inset: 0; z-index: 90; pointer-events: none;
    /* No mix-blend-mode: a full-viewport blend layer forces the compositor to
       re-blend it against the page on every scrolled frame — a classic source of
       scroll jank on phones. At 3.5% opacity the grain reads the same unblended. */
    opacity: 0.035;
    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.92' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  }

  @media (prefers-reduced-motion: reduce){
    *{ animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
  }

  /* ---------- Botanical signature SVG (reused as divider) ---------- */
  .sprig{ width: 120px; height: auto; opacity: 0.85; }
  .sprig path, .sprig ellipse{ vector-effect: non-scaling-stroke; }

  /* ---------- Nav ---------- */
  nav{
    position: fixed; top:0; left:0; right:0; z-index: 100;
    display:flex; align-items:center; justify-content:space-between;
    padding: 22px 5vw;
    background: linear-gradient(to bottom, rgba(239,246,250,0.86), rgba(239,246,250,0.66));
    backdrop-filter: blur(14px) saturate(1.1);
    -webkit-backdrop-filter: blur(14px) saturate(1.1);
    border-bottom: 1px solid transparent;
    transition: border-color 0.5s var(--ease), background 0.5s var(--ease);
  }
  nav.scrolled{ border-bottom-color: var(--line-gold); padding: 13px 5vw; background: linear-gradient(to bottom, rgba(239,246,250,0.94), rgba(239,246,250,0.82)); }
  /* A fixed bar with backdrop-filter re-blurs the moving page on every scrolled
     frame, which phone GPUs feel immediately. The bar is already near-opaque, so
     below the desktop breakpoint the blur is dropped. */
  @media (max-width: 1039px){
    nav{ backdrop-filter: none; -webkit-backdrop-filter: none; }
  }
  
  .nav-mark{
    display: inline-flex;
    align-items: center;
    text-decoration: none;
    width: 80px;
    flex: none;
  }

  .nav-mark img{
    width: 100%;
    height: auto;
    display: block;
  }

  .nav-links{ display:flex; gap: clamp(16px, 2.2vw, 36px); list-style:none; font-size: 0.72rem; letter-spacing: 0.2em; text-transform: uppercase; font-weight: 500; }
  .nav-links a{ text-decoration:none; position:relative; padding-bottom: 5px; color: var(--ink-soft); transition: color 0.3s var(--ease); }
  .nav-links a:hover{ color: var(--ink); }
  .nav-links a::after{
    content:''; position:absolute; left:0; bottom:0; width:100%; height:1.5px; border-radius:2px;
    background: linear-gradient(90deg, var(--warm), var(--warm-deep));
    transform: scaleX(0); transform-origin: left center;
    transition: transform 0.4s var(--ease);
  }
  .nav-links a:hover::after{ transform: scaleX(1); }
  .nav-links a.active::after{ width:100%; transform: scaleX(1); }
  .nav-toggle{ display:none; background:none; border:none; font-size:1.5rem; cursor:pointer; color:var(--ink); }
  /* Language flags — a quiet pair at the end of the nav island; the active
     language sits on a paper chip, the other rests at half strength. */
  .lang-switch{ display:flex; align-items:center; gap:4px; flex:none; margin-left:clamp(12px, 1.6vw, 22px); }
  .lang-flag{
    display:grid; place-items:center; width:40px; height:32px; padding:0; cursor:pointer;
    border:1px solid transparent; border-radius:9px; background:transparent; opacity:0.5;
    transition:opacity 0.25s var(--ease), border-color 0.25s var(--ease), background 0.25s var(--ease);
  }
  .lang-flag img{ width:26px; height:17px; object-fit:cover; border-radius:3px; box-shadow:0 0 0 1px rgba(46,50,32,0.14); }
  .lang-flag:hover{ opacity:0.85; }
  .lang-flag[aria-pressed="true"]{ opacity:1; border-color:var(--line-gold); background:rgba(255,255,255,0.66); }

  @media (max-width: 760px){
    .nav-links{
      position:fixed; top:0; right:-100%; height:100vh; width: min(78vw, 320px);
      background: var(--cream); flex-direction:column; justify-content:center; align-items:flex-start;
      padding: 40px; gap: 28px; transition: right 0.45s var(--ease); box-shadow: var(--shadow);
    }
    .nav-links.open{ right:0; }
    .nav-toggle{ display:block; z-index: 101; order:3; }
    .lang-switch{ margin-left:auto; margin-right:8px; }
  }

  /* ---------- Hero ---------- */
  .hero{
    position: relative; overflow: hidden;
    min-height: 100svh; display: flex; flex-direction: column;
    align-items: center; justify-content: flex-end; text-align: center;
    padding: max(120px, calc(env(safe-area-inset-top, 0px) + 80px)) 6vw max(clamp(74px, 9vh, 98px), calc(env(safe-area-inset-bottom, 0px) + 48px));
    perspective:3000px;
  }
  .hero-img{
    position: absolute; inset: 0; z-index: 0;
    width: 100%; height: 100%; object-fit: cover; object-position: 59% 50%;
    transform: scale(1.03);
    opacity: 1;
  }

  @media (max-width: 640px){
    .hero-img{ object-position: 59% 50%; }
  }

  .hero-scrim{
    position: absolute; inset: 0; z-index: 1; pointer-events: none;
    background:
    /* 1 · Bottom legibility wash — only rises through the lower third, where the names, sub-line and countdown sit. */
      linear-gradient(to top,
        rgba(239,246,250,0.99) 0%,
        rgba(239,246,250,0.90) 14%,
        rgba(239,246,250,0.64) 28%,
        rgba(239,246,250,0.28) 42%,
        rgba(239,246,250,0.07) 54%,
        transparent 66%),
       
      /* 2 · Soft focal pool feathered behind the text block, so contrast is highest right under the script names without touching the sky. */
      radial-gradient(120% 60% at 50% 106%, rgba(239,246,250,0.55), transparent 62%),

      /* 3 · A whisper of top vignette to seat the nav — far lighter than before. */
      radial-gradient(120% 48% at 50% 0%, rgba(46,50,32,0.09), transparent 58%);
  }

  /* Formal invitation frame — a hairline gold mat inset from the edges */
  .hero-frame{
      position:absolute;
      inset:clamp(14px,2.4vw,30px);
      z-index:2;
      transform-style:preserve-3d;
      transition:
          transform 0.2s ease-out;
      border:1px solid rgba(128,163,194,0.55);
      border-radius:3px;
  }
  .hero-content{ position: relative; z-index: 3; max-width: 940px; transform-style: preserve-3d; will-change: transform; transition: transform 0.15s ease-out}
  .hero-eyebrow{
    display: inline-flex; align-items: center; gap: 14px;
    font-size: 0.76rem; letter-spacing: 0.34em; text-transform: uppercase; font-weight: 500;
    color: var(--gold-deep); margin-bottom: clamp(18px, 2.6vw, 30px);
    text-shadow: 0 1px 12px rgba(239,246,250,0.95);
  }
  .hero-eyebrow::before, .hero-eyebrow::after{
    content:''; width: clamp(22px, 5vw, 46px); height:1px;
    background: linear-gradient(90deg, transparent, var(--gold));
  }
  .hero-eyebrow::after{ background: linear-gradient(90deg, var(--gold), transparent); }
  .hero-title{
    font-family: var(--font-script);
    font-size: clamp(3.9rem, 11.5vw, 8rem); line-height: 1.04; letter-spacing: 0;
    color: var(--ink); text-wrap: balance; text-shadow: 0 2px 30px rgba(239,246,250,0.66);
    font-weight: 300;
    transform:translateZ(80px);
  }
  .hero-title em{ font-style: normal; color: var(--terracotta); font-weight: 600; }
  .hero-title .ampersand{
    display: block; font-family: var(--font-script); font-style: normal;
    font-size: 0.52em; color: var(--terracotta); margin: 0.02em 0; font-weight: 500;
  }
  .hero-sub{
    margin: clamp(22px, 2.8vw, 34px) auto 0;
    font-family: var(--font-accent); font-style: normal; font-size: clamp(0.92rem, 1.6vw, 1.12rem);
    text-transform: uppercase; letter-spacing: 0.14em; font-weight: 500;
    color: var(--ink-soft); text-shadow: 0 1px 12px rgba(239,246,250,0.9);
    transform:translateZ(40px);
  }

  @keyframes rise{ from{opacity:0; transform: translateY(18px);} to{opacity:1; transform:translateY(0);} }

  /* Countdown */
  .countdown{
    display: inline-flex; gap: clamp(5px, 1.2vw, 12px); margin-top: clamp(34px, 4.5vw, 54px);
    flex-wrap: wrap; justify-content: center; align-items: stretch;
    padding: 9px; border-radius: 18px;
    background: linear-gradient(rgba(239,246,250,0.52), rgba(239,246,250,0.26));
    border: 1px solid var(--line-gold);
    box-shadow: var(--shadow-soft), inset 0 1px 0 rgba(255,255,255,0.5);
    transform:translateZ(140px);
    transition:
    transform 0.2s ease-out,
    box-shadow 0.2s ease-out;
  }

  .countdown:hover{
      transform:
          translateZ(180px)
          translateY(-6px);
      box-shadow:
          0 35px 70px rgba(0,0,0,0.18);
  }

  .countdown .unit{
    text-align: center; min-width: clamp(56px, 12vw, 80px);
    padding: 13px clamp(9px, 1.7vw, 18px); border-radius: 11px;
    background: rgba(239,246,250,0.5);
    box-shadow: inset 0 1px 1px rgba(255,255,255,0.45);
  }
  .countdown .num{
    font-family: var(--font-serif); font-weight: 600; font-size: clamp(2rem, 4.6vw, 3rem);
    line-height: 1; color: var(--ink);
    font-variant-numeric: tabular-nums lining-nums;
  }
  .countdown .label{
    font-family: var(--font-sans);
    font-size: 0.6rem; letter-spacing: 0.2em; text-transform: uppercase;
    color: var(--gold-deep); margin-top: 8px;
  }

  .scroll-cue{
    position: absolute;
    bottom: max(12px, calc(env(safe-area-inset-bottom, 0px) + 4px));
    left: 0; right: 0; margin: 0 auto; width: fit-content; z-index: 4;
    font-size: 0.6rem; letter-spacing: 0.28em; text-transform: uppercase; color: var(--gold-deep);
    display: flex; flex-direction: column; align-items: center; gap: 8px;
  }
  .scroll-cue .line{ width: 1px; height: 34px; background: linear-gradient(var(--gold), transparent); animation: pulse 2s ease-in-out infinite; }
  @keyframes pulse{ 0%,100%{ opacity:0.25; } 50%{ opacity:0.85; } }

  @media (max-height: 760px){
    .hero-title{ font-size: clamp(3.1rem, 8.4vw, 4.8rem); line-height: 1.04; }
    .countdown{ margin-top: clamp(20px, 3vh, 34px); }
  }
  @media (max-height: 640px){
    .scroll-cue{ display: none; }
  }
  @media (max-width: 560px){
    .hero-eyebrow{ font-size: 0.72rem; letter-spacing: 0.18em; }
    .hero-sub{ font-size: 1rem; }
  }

  /* Hero entrance + drift — content is visible by default; animate only when motion is welcome */
  @media (prefers-reduced-motion: no-preference){
    .hero-eyebrow{ opacity:0; animation: rise 0.9s var(--ease) 0.15s forwards; }
    .hero-title{ opacity:0; animation: rise 1s var(--ease) 0.32s forwards; }
    .hero-sub{ opacity:0; animation: rise 1s var(--ease) 0.5s forwards; }
    .countdown{ opacity:0; animation: rise 1s var(--ease) 0.68s forwards; }
    .scroll-cue{ opacity:0; animation: rise 1s var(--ease) 1s forwards; }
  }

  /* ---------- Hero stage ----------
     Layer 1 is the load-bearing image: fully opaque and visible with no JS and
     no motion preference. The stage holds a gentle static crop. */
  .hero-stage{
    position: absolute; inset: 0; z-index: 0;
    transform: scale(1.03);
  }  .hero-layer{
    position: absolute; inset: 0;
    width: 100%; height: 100%; object-fit: cover; object-position: 59% 50%;
    transform: none;
  }
  /* A soft raking light that travels across the frame — the "film" note */
  /* Single-asset hero: keep Hero-Background.png fully visible. */
  .hero-layer,
  .hero-layer:first-child{
    opacity: 1;
    animation: none !important;
  }

  /* Center the source image on narrow screens after the layer rules above. */
  @media (max-width: 640px){
    .hero-img,
    .hero-layer{ object-position: 59% 50%; }
  }

  /* ============================================================
     SCROLL JOURNEY MAP — premium illustrated wedding travel story.
     The map is a deterministic function of section scroll progress:
     Swansea → Southampton → Iceland → Norway.
     ============================================================ */
  #storymap{
    --journey-progress: 0;
    --journey-scale: 1;
    background:
      radial-gradient(120% 70% at 12% 0%, rgba(128,163,194,0.12), transparent 58%),
      radial-gradient(100% 80% at 100% 100%, rgba(154,196,124,0.10), transparent 60%),
      var(--champagne);
    overflow: clip;
  }
  /* Blend bridges: champagne sits between two cream sections, so both edges
     feather into the neighbours to avoid a hard colour-block seam. */
  #storymap::before{
    content:''; position:absolute; left:0; right:0; top:0; z-index:0; pointer-events:none;
    height: clamp(80px, 10vw, 140px);
    background: linear-gradient(180deg, rgba(239,246,250,0.62), transparent);
  }
  #storymap::after{
    content:''; position:absolute; left:0; right:0; bottom:0; z-index:0; pointer-events:none;
    height: clamp(80px, 10vw, 140px);
    background: linear-gradient(180deg, transparent, rgba(239,246,250,0.62));
  }

  .journey-map-layout{
    display:grid;
    grid-template-columns:minmax(0, 1fr) minmax(340px, 0.72fr);
    gap:clamp(32px, 6vw, 88px);
    align-items:start;
  }

  .journey-map-stage{
    position:sticky;
    top: calc(var(--nav-h, 78px) + clamp(6px, 1.5vh, 16px));
    height:min(72vh, 760px);
    min-height:500px;
    border:1px solid var(--line-gold);
    border-radius:24px;
    overflow:hidden;
    background:#EAF3F7;
    box-shadow:var(--shadow-lift);
    isolation:isolate;
  }

  .journey-map-stage::before{
    content:"";
    position:absolute;
    inset:0;
    z-index:4;
    pointer-events:none;
    background:
      radial-gradient(80% 55% at 50% 0%, rgba(255,255,255,0.34), transparent 68%),
      linear-gradient(180deg, rgba(255,255,255,0.08), transparent 34%, rgba(67,98,126,0.04));
  }

  .journey-map-camera{
    position:absolute;
    inset:0;
    transform-origin:center center;
    will-change:transform;
    /* No transition on the transform: JS writes it every scroll frame while the
       map is in view, and a transition on a per-frame-updated property only adds
       style churn and lag. */
  }

  .journey-map-svg{
    display:block;
    width:100%;
    height:100%;
  }

  .journey-map-svg .land{
    fill:url(#journeyLand);
    stroke:rgba(69,112,58,.22);
    stroke-width:1.5;
  }

  .journey-map-svg .land-detail{
    fill:none;
    stroke:rgba(69,112,58,.20);
    stroke-width:1.4;
    stroke-linecap:round;
  }

  .journey-map-svg .water-detail{
    fill:none;
    stroke:rgba(128,163,194,.35);
    stroke-width:1.2;
    stroke-linecap:round;
  }

  .journey-route{
    fill:none;
    stroke:#43627E;
    stroke-width:4;
    stroke-linecap:round;
    stroke-linejoin:round;
    stroke-dasharray:9 12;
    opacity:.9;
    filter:drop-shadow(0 2px 1px rgba(67,98,126,.10));
    vector-effect:non-scaling-stroke;
  }

  .journey-route.route-complete{
    opacity:.82;
  }

  .journey-route--active{
    opacity:1;
  }

  .journey-marker{
    opacity:0;
    transform-box:fill-box;
    transform-origin:center;
    transition:opacity .45s var(--ease), transform .55s var(--ease-out);
  }

  .journey-marker.is-visible{
    opacity:1;
    transform:scale(1);
  }

  .marker-halo{
    fill:rgba(255,255,255,.62);
    stroke:rgba(128,163,194,.28);
    stroke-width:1;
  }

  .marker-ring{
    fill:#FFFFFF;
    stroke:#43627E;
    stroke-width:2;
  }

  .marker-core{
    fill:#D98368;
    stroke:#FFFFFF;
    stroke-width:2;
  }

  .marker-title{
    font-family:var(--font-serif);
    font-size:24px;
    fill:var(--ink);
    font-weight:500;
  }

  .marker-sub{
    font-family:var(--font-sans);
    font-size:12px;
    letter-spacing:.13em;
    text-transform:uppercase;
    fill:var(--gold-deep);
    font-weight:600;
  }

  .marker-illustration{
    fill:none;
    stroke:#43627E;
    stroke-width:2.2;
    stroke-linecap:round;
    stroke-linejoin:round;
  }

  .journey-compass{
    position:absolute;
    z-index:5;
    top:18px;
    right:18px;
    width:54px;
    height:54px;
    border:1px solid var(--line-gold);
    border-radius:50%;
    background:rgba(255,255,255,.72);
    backdrop-filter:blur(8px);
    display:grid;
    place-items:center;
    color:var(--gold-deep);
    font-family:var(--font-serif);
    font-size:.72rem;
    box-shadow:0 12px 30px -18px rgba(67,98,126,.5);
  }

  .journey-compass::before{
    content:"";
    width:1px;
    height:24px;
    background:var(--gold-deep);
    position:absolute;
  }

  .journey-compass::after{
    content:"";
    width:7px;
    height:7px;
    border-top:1px solid var(--gold-deep);
    border-left:1px solid var(--gold-deep);
    transform:translateY(-9px) rotate(45deg);
    position:absolute;
  }

  .journey-map-caption{
    position:absolute;
    z-index:5;
    left:18px;
    bottom:16px;
    max-width:75%;
    padding:8px 12px;
    border:1px solid var(--line-gold);
    border-radius:999px;
    background:rgba(255,255,255,.72);
    backdrop-filter:blur(8px);
    font-size:.62rem;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:var(--gold-deep);
  }

  .journey-story{
    display:flex;
    flex-direction:column;
    gap:clamp(20px, 4vw, 38px);
    padding:clamp(4px, 2vw, 18px) 0;
  }

  .journey-story-head{
    padding-bottom:clamp(8px, 2vw, 18px);
  }

  .journey-story-head .section-title{
    margin-bottom:16px;
  }

  .journey-story-head p{
    color:var(--ink-soft);
  }

  .journey-stage-card{
    position:relative;
    min-height:clamp(360px, 58vh, 560px);
    padding:clamp(26px, 4vw, 42px);
    border:1px solid var(--line-gold);
    border-radius:22px;
    background:linear-gradient(160deg, rgba(255,255,255,.82), rgba(235,243,246,.54));
    box-shadow:var(--shadow-soft);
    display:flex;
    flex-direction:column;
    justify-content:flex-end;
    overflow:hidden;
    opacity:.48;
    transform:translateY(10px);
    transition:opacity .55s var(--ease), transform .55s var(--ease), box-shadow .55s var(--ease);
  }

  .journey-stage-card::before{
    content:"";
    position:absolute;
    width:180px;
    height:180px;
    right:-90px;
    top:-90px;
    border:1px solid rgba(128,163,194,.20);
    border-radius:50%;
  }

  .journey-stage-card.is-active,
  .journey-stage-card.is-complete{
    opacity:1;
    transform:none;
  }

  .journey-stage-card.is-active{
    box-shadow:var(--shadow-lift);
  }

  .journey-stage-kicker{
    display:inline-flex;
    align-items:center;
    gap:9px;
    width:max-content;
    margin-bottom:14px;
    font-size:.68rem;
    letter-spacing:.2em;
    text-transform:uppercase;
    color:var(--gold-deep);
    font-weight:600;
  }

  /* Numbered pin carries the sequence (01–04), echoing the map markers —
     replaces the old ghost numerals. */
  .journey-stage-kicker::before{
    content: attr(data-n);
    display:inline-grid;
    place-items:center;
    width:24px;
    height:24px;
    border-radius:50%;
    background:#FFFFFF;
    border:1.5px solid var(--terracotta);
    color:var(--terracotta);
    font-size:0.6rem;
    font-weight:600;
    letter-spacing:0.04em;
    box-shadow:0 0 0 3px rgba(128,163,194,0.18);
  }

  .journey-stage-card h3{
    font-family:var(--font-serif);
    font-size:clamp(2.1rem, 4vw, 3.2rem);
    line-height:1;
    font-weight:400;
    margin-bottom:14px;
  }

  .journey-stage-card p{
    color:var(--ink-soft);
    max-width:38ch;
  }

  .journey-stage-card .stage-detail{
    margin-top:20px;
    padding-top:16px;
    border-top:1px solid var(--line-gold);
    font-size:.78rem;
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--gold-deep);
  }

  .journey-accessible-list{
    margin-top:clamp(30px, 4vw, 50px);
    padding-top:24px;
    border-top:1px solid var(--line-gold);
  }

  .journey-accessible-list h3{
    font-family:var(--font-serif);
    font-weight:400;
    margin-bottom:12px;
  }

  .journey-accessible-list ol{
    padding-left:1.25rem;
    color:var(--ink-soft);
  }

  .journey-accessible-list li{
    margin:.35rem 0;
  }


  @media (max-width: 900px){
    .journey-map-layout{
      grid-template-columns:1fr;
      gap:28px;
    }

    .journey-map-stage{
      position:sticky;
      top: calc(var(--nav-h, 78px) + 10px);
      height:58svh;
      min-height:360px;
      z-index:2;
    }

    .journey-story{
      gap:18px;
    }

    .journey-stage-card{
      min-height:48vh;
    }
  }

  @media (max-width: 560px){
    .journey-map-stage{
      top: calc(var(--nav-h, 78px) + 8px);
      height:52svh;
      min-height:300px;
      border-radius:18px;
    }

    .journey-map-caption{
      font-size:.55rem;
      left:12px;
      /* Sit above the map attribution, which wraps to two lines on phones. */
      bottom:34px;
    }

    #storymap .leaflet-control-attribution{ font-size:8px; }

    .journey-compass{
      width:46px;
      height:46px;
      top:12px;
      right:12px;
    }

    .journey-stage-card{
      min-height:52vh;
      padding:24px;
      border-radius:18px;
    }

    .marker-title{ font-size:20px; }
    .marker-sub{ font-size:10px; }
  }

  @media (prefers-reduced-motion: reduce){
    .journey-map-camera{ transition:none; }
    .journey-marker,
    .journey-stage-card{
      transition:none;
      transform:none;
    }
    .journey-marker.is-active .marker-halo{ animation:none; }
  }

  /* ============================================================
     LIVING SCHEDULE — light shifts through the day, and on 29 April
     2027 the running order marks whatever is happening right now.
     ============================================================ */
  .day-status{
    display: inline-flex; align-items: center; gap: 10px;
    margin: 18px 0 4px; padding: 9px 16px 9px 13px;
    border-radius: 999px; border: 1px solid var(--line-gold);
    background: rgba(255,255,255,0.6);
    font-size: 0.86rem; color: var(--ink-soft);
  }
  .day-status .dot{
    width: 8px; height: 8px; border-radius: 50%; flex: none;
    background: var(--dusty-blue);
  }
  .day-status.live{ border-color: var(--warm-deep); color: var(--ink); background: var(--warm-soft); }
  .day-status.live .dot{ background: var(--warm-deep); }
  @media (prefers-reduced-motion: no-preference){
    .day-status.live .dot{ animation: nowPulse 2.2s ease-in-out infinite; }
  }
  @keyframes nowPulse{
    0%,100%{ box-shadow: 0 0 0 0 rgba(217,131,104,0.55); }
    50%{ box-shadow: 0 0 0 7px rgba(217,131,104,0); }
  }

  .schedule{ position: relative; }
  /* Morning haze → golden hour → candlelit dusk, tied to scroll where supported.
     Masked at both ends: a rectangle of daylight has an edge, and that edge cut
     a hard horizontal line across the timeline above the first time. Fading the
     wash in and out lets the light arrive and leave without an outline — the
     same dissolve the section seams use. */
  .day-light{
    position: absolute; inset: -22px -6vw; z-index: 0; pointer-events: none;
    opacity: 0.55;
    background: linear-gradient(180deg,
      rgba(214,235,247,0.55) 0%,
      rgba(255,244,222,0.42) 42%,
      rgba(244,201,168,0.34) 72%,
      rgba(90,86,120,0.20) 100%);
    -webkit-mask-image: var(--seam-mask);
            mask-image: var(--seam-mask);
  }
  .schedule-item{ position: relative; z-index: 1; }

  .now-tag{
    display: none; margin-top: 10px;
    font-size: 0.66rem; letter-spacing: 0.18em; text-transform: uppercase; font-weight: 600;
    /* Ink on the blush chip = 4.6:1 (white was 2.8:1) — matches the ink-on-accent button system. */
    color: var(--ink); background: var(--warm-deep);
    padding: 5px 11px; border-radius: 999px;
  }
  .schedule-item.is-now .now-tag{ display: inline-block; }
  .schedule-item.is-now{
    background: linear-gradient(90deg, var(--warm-soft), transparent 78%);
    border-radius: 14px;
  }
  .schedule-item.is-now .schedule-name{ color: var(--terracotta); }
  .schedule-item.is-done{ opacity: 0.5; }
  .schedule-item.is-done .schedule-time{ text-decoration: line-through; text-decoration-thickness: 1px; }

  .day-actions{ margin-top: clamp(22px, 3vw, 34px); }

  /* Shared soft-button treatment for calendar + sort actions */
  .ics-btn, .sort-btn{
    display: inline-flex; align-items: center; gap: 10px;
    padding: 12px 20px; min-height: 44px;
    border-radius: 999px; cursor: pointer;
    border: 1px solid var(--line-gold); background: rgba(255,255,255,0.72);
    color: var(--terracotta); font-family: var(--font-sans); font-size: 0.84rem;
    font-weight: 600; letter-spacing: 0.06em;
    transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease), background 0.25s var(--ease);
  }
  .ics-btn svg, .sort-btn svg{ width: 18px; height: 18px; flex: none; }
  .ics-btn:hover, .sort-btn:hover{
    transform: translateY(-2px); background: #FFFFFF;
    box-shadow: 0 14px 30px -16px rgba(67,98,126,0.5);
  }
  .sort-btn{ margin: 6px 0 22px; }
  .sort-btn[aria-pressed="true"]{ background: var(--warm-soft); border-color: var(--warm-deep); }
  .stay-tiers[hidden], .stays--flat[hidden]{ display: none; }
  .stays--flat{ margin-top: 4px; }
  .stay-tier-tag{
    display: inline-block; margin-top: 10px;
    font-size: 0.62rem; letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--gold-deep); opacity: 0.85;
  }

  /* ============================================================
     PLAN YOUR JOURNEY
     ============================================================ */
  .journey-block{
    padding: clamp(22px, 3vw, 34px);
    border: 1px solid var(--line-gold); border-radius: 20px;
    background: linear-gradient(180deg, rgba(255,255,255,0.78), rgba(235,243,246,0.5));
    box-shadow: var(--shadow-soft);
  }
  .journey-form{ display: flex; gap: 12px; flex-wrap: wrap; margin-top: 6px; }
  .journey-form input{
    flex: 1 1 16rem; min-width: 0;
    padding: 14px 18px; border-radius: 12px;
    border: 1px solid var(--line-gold); background: #FFFFFF;
    font-family: var(--font-sans); font-size: 1rem; color: var(--ink);
  }
  .journey-form input:focus-visible{ outline: 2px solid var(--dusty-blue); outline-offset: 2px; }
  .journey-btn{
    padding: 14px 26px; border-radius: 12px; border: 1px solid transparent; cursor: pointer;
    background: var(--terracotta); color: #FFFFFF;
    font-family: var(--font-sans); font-size: 0.86rem; font-weight: 600; letter-spacing: 0.1em;
    text-transform: uppercase;
    transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease), opacity 0.2s;
  }
  .journey-btn:hover{ transform: translateY(-2px); box-shadow: 0 16px 34px -18px rgba(67,98,126,0.75); }
  .journey-btn:disabled{ opacity: 0.6; cursor: progress; transform: none; }

  .journey-result{
    margin-top: 18px; padding: 18px 20px; border-radius: 14px;
    border: 1px solid var(--line-gold); background: rgba(255,255,255,0.7);
    font-size: var(--text-body); color: var(--ink-soft);
  }
  .journey-result--ok{ border-color: var(--sage); background: rgba(255,255,255,0.86); }
  .journey-result--warn{ border-color: var(--warm-deep); background: var(--warm-soft); }
  .journey-from{ font-family: var(--font-serif); font-size: 1.15rem; color: var(--ink); margin: 0 0 14px; }
  .journey-stats{ display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
  .journey-stat{
    flex: 1 1 8rem; padding: 14px 16px; border-radius: 12px;
    background: var(--champagne); border: 1px solid var(--line-gold); text-align: center;
  }
  .journey-stat .jv{
    display: block; font-family: var(--font-serif); font-size: 1.5rem; font-weight: 600;
    color: var(--ink); font-variant-numeric: tabular-nums;
  }
  .journey-stat .jl{
    display: block; margin-top: 6px;
    font-size: 0.6rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--gold-deep);
  }
  .journey-note{ margin: 0 0 10px; }
  .journey-note:last-of-type{ margin-bottom: 14px; }
  .journey-spin{
    display: inline-block; width: 13px; height: 13px; margin-right: 9px; vertical-align: -1px;
    border: 2px solid var(--line-gold); border-top-color: var(--terracotta); border-radius: 50%;
  }
  @media (prefers-reduced-motion: no-preference){
    .journey-spin{ animation: journeySpin 0.8s linear infinite; }
  }
  @keyframes journeySpin{ to{ transform: rotate(360deg); } }
  .journey-extras{
    margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line-gold);
    display: flex; flex-direction: column; align-items: flex-start; gap: 12px;
  }
  .journey-share{ font-size: 0.9rem; color: var(--ink-soft); margin: 0; }

  /* ---------- Sections ---------- */
  /* Tighter, fluid vertical rhythm — enough air for a wedding page, without the
     cavernous gaps. Individual sections nudge this up or down for cadence. */
  section{ padding: var(--section-pad-y) var(--section-pad-x); position:relative; }
  .section-inner{ max-width: 1080px; margin: 0 auto; }
  .divider{ display:flex; justify-content:center; margin: 0 0 clamp(26px, 3.4vw, 42px); }
.divider--stem .sprig{ width: 84px; opacity: 0.9; }
.divider--bloom .sprig{ width: 132px; opacity: 0.9; }

  .eyebrow{
    display: inline-flex; align-items: center; gap: 9px;
    font-family: var(--font-sans); font-weight: 500;
    font-size: var(--text-label); letter-spacing: var(--tracking-label); text-transform: uppercase;
    color: var(--gold-deep);
    margin-bottom: 20px; padding: 7px 15px 7px 12px;
    border: 1px solid var(--line-gold); border-radius: 999px;
    background: linear-gradient(var(--cream-warm), rgba(128,163,194,0.12));
  }
  .eyebrow::before{
    content:''; width: 5px; height: 5px; border-radius: 50%;
    background: var(--warm); box-shadow: 0 0 0 3px var(--warm-soft);
  }
  .section-title{ font-size: var(--text-h2); margin-bottom: 28px; text-wrap: balance; font-weight: 400; line-height: 1.04; }

  /* Reveal: visible by default; only hide + animate once the html.js-reveal gate
     (set in <head>) confirms JS, IntersectionObserver, and motion are all available. */
  .reveal{ opacity:1; transform:none; }
  @media (prefers-reduced-motion: no-preference){
    html.js-reveal .reveal{ opacity:0; transform: translateY(28px); transition: opacity 0.9s var(--ease), transform 0.9s var(--ease); }
    html.js-reveal .reveal.in{ opacity:1; transform: translateY(0); }
  }

  /* ---------- Our Story ---------- */
  /* Feathered wash: the warm tone swells in and fades back to cream at both edges,
     so there is no hard block seam — the page reads as one continuous surface. */
  #story{
    background: linear-gradient(180deg,
      rgba(220,234,245,0) 0,
      rgba(220,234,245,0.60) var(--seam-feather),
      rgba(220,234,245,0.66) clamp(90px, 12vw, 150px),
      rgba(220,234,245,0.66) calc(100% - clamp(90px, 12vw, 150px)),
      rgba(220,234,245,0.60) calc(100% - var(--seam-feather)),
      rgba(220,234,245,0) 100%);
    padding-block: clamp(48px, 6vw, 88px);
  }
  .story-grid{ display:grid; grid-template-columns: 1.3fr 0.86fr; gap: clamp(34px, 5vw, 82px); align-items:center; }
  .story-copy p{ margin-bottom: 20px; font-size: 1.08rem; color: var(--ink-soft); }
  .story-copy p:last-child{ margin-bottom:0; }
  .story-copy > p:first-of-type::first-letter{
    float:left; font-family: var(--font-serif); font-weight: 500;
    font-size: 3.5em; line-height: 0.72; padding: 8px 12px 0 0; color: var(--terracotta);
  }
  /* Double-bezel frame — a pressed-paper mat cradles the watercolour like matted art */
  .story-visual{
    position: relative; aspect-ratio: 4/5; margin: 0;
    padding: 10px; border-radius: 16px; overflow: hidden;
    background: linear-gradient(158deg, var(--cream-warm), var(--cream-deep));
    border: 1px solid var(--line-gold);
    box-shadow: var(--shadow);
  }
  .story-visual img{
    width:100%; height:100%; object-fit: cover; object-position: 50% 42%;
    border-radius: 9px; box-shadow: 0 0 0 1px rgba(46,50,32,0.08);
  }

  /* ---------- Matted-print frame — shared visual language ----------
   A pressed-paper mat cradling the image like matted art.
   Reused across story, venue, and gallery so the page speaks one language. */
  .matte{
    position: relative;
    padding: 10px;
    border-radius: 16px;
    background: linear-gradient(158deg, var(--cream-warm), var(--cream-deep));
    border: 1px solid var(--line-gold);
    box-shadow: var(--shadow);
  }
  .matte > img,
  .matte figure,
  .matte .matte-img{
    border-radius: 9px;
    box-shadow: 0 0 0 1px rgba(46,50,32,0.08);
  }

  /* Distilled chronology: three clean date anchors; the prose carries the story. */
  .story-timeline{
    list-style:none; margin: clamp(32px, 4vw, 44px) 0 0; padding: clamp(26px, 3vw, 32px) 0 0;
    border-top: 1px solid var(--line-gold);
    display:flex; flex-wrap:wrap; gap: clamp(16px, 2.6vw, 38px); justify-content: center;
  }
  .tl-step{ display:flex; flex-direction:column; gap: 6px; align-items: center; }
  .tl-step .tl-date{ font-family: var(--font-serif); font-weight: 400; font-size: 1.7rem; line-height: 1; color: var(--terracotta); }
  .tl-step .tl-label{ font-family: var(--font-sans); font-size: var(--text-label); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--gold-deep); }

  @media (max-width: 820px){ .story-grid{ grid-template-columns: 1fr; gap: 34px; } .story-visual{ aspect-ratio: 4/3; } }

  /* ---------- Event Details ---------- */
  /* Schedule reads as a garden-path timeline: the day unfolds down a soft spine. */
  .schedule{
    --tl-time: 96px; --tl-gutter: 40px;
    position:relative; margin-top: clamp(30px, 4vw, 46px);
  }
  .schedule-item{
    position:relative;
    display:grid; grid-template-columns: var(--tl-time) 1fr; column-gap: var(--tl-gutter);
    align-items:start; padding: 20px 0 30px;
  }
  .schedule-item:first-child{ padding-top: 6px; }
  .schedule-item:last-child{ padding-bottom: 4px; }
  /* continuous spine + node, drawn in the gutter between time and content */
  .schedule-item::before{
    content:''; position:absolute; top:0; bottom:0;
    left: calc(var(--tl-time) + var(--tl-gutter)/2 - 1px); width:2px;
    background: var(--sage); opacity:0.45;
  }
  /* Spine caps: first item — no dangling line above the first circle;
     last item — spine stops at the circle centre.
     Circle centre in item coords = item padding-top + 50% of .schedule-time height.
     .schedule-time height ≈ 2px padding + (1.4rem × 1.6 line-height) ≈ 38px → centre ≈ 19px.
     First child: 6 + 19 = 25px. Default (last child): 20 + 19 = 39px. */
  .schedule-item:first-child::before{ top: 25px; }
  .schedule-item:last-child::before{ bottom:auto; height:39px; }
  .schedule-time{
    position:relative; overflow:visible;
    text-align:right; padding-top:2px;
    font-family: var(--font-serif); font-weight: 400; font-size: 1.4rem; color: var(--gold-deep);
    font-variant-numeric: lining-nums;
  }
  /* Circle dot sits in the gutter, perfectly centred on the time label.
     Anchored to .schedule-time so top:50% always matches the text, no
     matter what font metrics or padding the item carries. */
  .schedule-time::after{
    content:'';
    position:absolute; top:50%; transform:translateY(-50%);
    left: calc(100% + var(--tl-gutter)/2 - 6px);
    width:12px; height:12px; border-radius:50%;
    background: var(--warm); box-shadow: 0 0 0 4px var(--cream), 0 0 0 5px var(--warm-soft);
  }
  .schedule-name{ font-size: 1.5rem; margin-bottom: 7px; font-family: var(--font-serif); font-weight:400; letter-spacing:-0.01em; }
  .schedule-desc{ font-size: var(--text-body); color: var(--ink-soft); max-width: 50ch; line-height:1.6; }

  @media (max-width: 560px){
    .schedule-item{
      grid-template-columns: 1fr; row-gap:4px; padding: 18px 0 20px;
      border-top: 1px solid var(--line);
    }
    .schedule-item:first-child{ padding-top:18px; }
    .schedule-item:last-child{ border-bottom: 1px solid var(--line); padding-bottom:20px; }
    .schedule-item::before, .schedule-time::after{ display:none; }
    .schedule-time{ text-align:left; }
  }


  .venue-card{
    margin-top: clamp(52px, 6vw, 80px);
    display:grid; grid-template-columns: 1.05fr 1fr; gap: clamp(28px, 4vw, 54px); align-items:center;
    background: linear-gradient(158deg, var(--cream-warm), var(--cream-deep));
    border:1px solid var(--line-gold); border-radius: 20px;
    padding: clamp(20px, 3vw, 34px); box-shadow: var(--shadow-soft);
  }
  .venue-card h3{ font-size: var(--text-h3); margin-bottom: 12px; }

  @media (max-width: 640px){
    .venue-card{
      grid-template-columns: 1fr; gap: 28px;
    }
    .venue-card .venue-photo{ order: -1; max-height: 42vh; }
  }
  /* location node echoes the timeline markers, tying "where" to "when" */
  .venue-loc{
    display:flex; align-items:flex-start; gap:11px; margin-top:22px; max-width:42ch;
    font-size:var(--text-body); line-height:1.55; color: var(--ink-soft);
  }
  .venue-loc::before{
    content:''; flex:none; margin-top:0.42em; width:10px; height:10px; border-radius:50%;
    background: var(--warm); box-shadow: 0 0 0 4px var(--cream-deep), 0 0 0 5px var(--warm-soft);
  }

  .venue-photo{
    margin:0; aspect-ratio: 4/3; overflow:hidden;
    /* mat surround */
    padding: 10px; border-radius: 16px;
    background: linear-gradient(158deg, var(--cream-warm), var(--cream-deep));
    border: 1px solid var(--line-gold);
    box-shadow: var(--shadow);
  }
  .venue-photo img{
    width:100%; height:100%; object-fit:cover; object-position:50% 46%;
    border-radius: 9px;                       /* inner bezel — was square */
    box-shadow: 0 0 0 1px rgba(46,50,32,0.08);
  }

  /* Motion — the timeline draws itself in as the day unfolds; static + visible without JS/motion. */
  @media (prefers-reduced-motion: no-preference){
    /* schedule reveals as a staggered sequence, not one block (parent + item boxes stay put) */
    html.js-reveal .schedule.reveal{ opacity:1; transform:none; }
    html.js-reveal .schedule.reveal .schedule-item{ --i:0; }
    html.js-reveal .schedule.reveal .schedule-item:nth-child(2){ --i:1; }
    html.js-reveal .schedule.reveal .schedule-item:nth-child(3){ --i:2; }
    /* each row's details arrive */
    html.js-reveal .schedule.reveal .schedule-item > *{
      opacity:0; transform: translateY(14px);
      transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
      transition-delay: calc(var(--i) * 0.13s);
    }
    html.js-reveal .schedule.reveal.in .schedule-item > *{ opacity:1; transform:none; }
    /* the spine segment draws down (item box is static, so segments stay aligned) */
    html.js-reveal .schedule.reveal .schedule-item::before{
      transform: scaleY(0); transform-origin: top center;
      transition: transform 0.55s var(--ease);
      transition-delay: calc(var(--i) * 0.13s);
    }
    html.js-reveal .schedule.reveal.in .schedule-item::before{ transform: scaleY(1); }
    /* the node pops onto the path just after its segment */
    html.js-reveal .schedule.reveal .schedule-time::after{
      opacity:0; transform: translateY(-50%) scale(0.3);
      transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
      transition-delay: calc(var(--i) * 0.13s + 0.12s);
    }
    html.js-reveal .schedule.reveal.in .schedule-time::after{ opacity:1; transform: translateY(-50%) scale(1); }

    /* venue photo settles in; location pin pops like the timeline nodes */
    html.js-reveal .venue-card.reveal .venue-photo img{ transform: scale(1.06); transition: transform 1.1s var(--ease); }
    html.js-reveal .venue-card.reveal.in .venue-photo img{ transform: scale(1); }
    html.js-reveal .venue-card.reveal .venue-loc::before{
      opacity:0; transform: scale(0.3);
      transition: opacity 0.5s var(--ease) 0.3s, transform 0.5s var(--ease) 0.3s;
    }
    html.js-reveal .venue-card.reveal.in .venue-loc::before{ opacity:1; transform: scale(1); }
  }

  /* ---------- Dress Code ---------- */
  #dress .divider{ margin-bottom: clamp(22px, 3vw, 36px); }
  .dress-head{ max-width: 640px; margin: 0 auto clamp(34px, 5vw, 52px); text-align:center; }
  .dress-lead{ font-size: var(--text-lead); line-height: 1.62; max-width: 52ch; margin: 0 auto; }

  .dress-visual{ margin: 0 auto; max-width: 960px; }
  .dress-frame{ line-height: 0; }
  .dress-frame img{
    display:block; width:100%; height:auto;
    -webkit-mask-image:
      linear-gradient(to bottom, transparent 0, #000 5%, #000 95%, transparent 100%),
      linear-gradient(to right, transparent 0, #000 4%, #000 96%, transparent 100%);
    -webkit-mask-composite: source-in;
            mask-image:
      linear-gradient(to bottom, transparent 0, #000 5%, #000 95%, transparent 100%),
      linear-gradient(to right, transparent 0, #000 4%, #000 96%, transparent 100%);
            mask-composite: intersect;
  }
  .dress-cap{
    font-family: var(--font-accent); font-style:italic; font-size:1.22rem; color: var(--gold-deep);
    text-align:center; margin:0; padding-top:18px;
  }

  .dress-cues{
    list-style:none; margin: clamp(40px, 6vw, 60px) auto 0; padding:0; max-width: 900px;
    display:grid; grid-template-columns: repeat(3, 1fr); gap: clamp(24px, 4vw, 40px);
  }
  .dress-cues li{ position:relative; padding-left: 26px; }
  .dress-cues li::before{
    content:''; position:absolute; left:0; top:0.42em; width:9px; height:9px; border-radius:50%;
    background: var(--gold); box-shadow: 0 0 0 4px rgba(128,163,194,0.22);
  }
  .cue-t{
    display:block; font-family: var(--font-serif); font-weight:500; font-size:1.32rem;
    color: var(--sage-deep); line-height:1.2; margin-bottom:6px; letter-spacing:-0.01em;
  }
  .cue-d{ display:block; font-size:var(--text-body); line-height:1.58; color: var(--ink-soft); }

  @media (max-width: 720px){
    .dress-cues{ grid-template-columns: 1fr; gap: clamp(20px, 6vw, 28px); }
  }

  /* Dress reveal — visible by default; animate only when JS enables it and motion allowed */
  @media (prefers-reduced-motion: no-preference){
    #dress.js-reveal [data-dr]{ opacity:0; transform: translateY(22px); transition: opacity 0.85s var(--ease), transform 0.85s var(--ease); }
    #dress.js-reveal [data-dr].in{ opacity:1; transform:none; }
    #dress.js-reveal .dress-cues[data-dr]{ transition-delay: 0.12s; }
  }

  /* ---------- Travel & Stay ---------- */
  /* Same feathered wash as the story section — continuous, not a stacked block. */
  #travel{
    background: linear-gradient(180deg,
      rgba(220,234,245,0) 0,
      rgba(220,234,245,0.60) var(--seam-feather),
      rgba(220,234,245,0.66) clamp(90px, 12vw, 150px),
      rgba(220,234,245,0.66) calc(100% - clamp(90px, 12vw, 150px)),
      rgba(220,234,245,0.60) calc(100% - var(--seam-feather)),
      rgba(220,234,245,0) 100%);

  }
  #travel .section-title{ margin-bottom: 16px; }
  .travel-intro{ font-size: var(--text-lead); max-width: 60ch; }

  .sr-only{
    position:absolute; width:1px; height:1px; padding:0; margin:-1px;
    overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
  }

  .travel-blocks{ margin-top: clamp(46px, 7vw, 74px); display:flex; flex-direction:column; gap: clamp(46px, 7vw, 82px); }
  .travel-block{ min-width:0; }
  .block-head{ display:flex; align-items:center; gap: 13px; margin-bottom: 24px; }
  .block-head .ico{ width: 30px; height: 30px; flex:none; }
  .block-head .ico path, .block-head .ico circle, .block-head .ico rect{
    fill:none; stroke: var(--sage-deep); stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round; vector-effect: non-scaling-stroke;
  }
  .block-head h3{ font-size: var(--text-h3); }
  .block-p{ font-size: 1rem; line-height:1.6; max-width: 64ch; margin-bottom: 20px; }

  /* A / B — getting here + by car */
  .getting-here{ display:grid; grid-template-columns: 1.05fr 0.95fr; gap: clamp(26px, 4vw, 50px); align-items:start; }
  .locate{ display:flex; flex-direction:column; gap: 18px; min-width:0; }
  .locate .address{ font-family: var(--font-serif); font-weight:400; font-size: 1.5rem; line-height:1.32; color: var(--ink); }
  .postcode-row{ display:flex; align-items:center; gap: 12px; flex-wrap:wrap; }
  .postcode{ font-family: var(--font-serif); font-weight:400; font-size: 1.65rem; letter-spacing: 0.04em; color: var(--sage-deep); }
  .copy-btn{
    display:inline-flex; align-items:center; gap:7px; background:transparent; cursor:pointer;
    border:1px solid var(--line-gold); color: var(--ink); border-radius:999px;
    padding: 10px 16px; min-height: 44px;
    font-family: var(--font-sans); font-size:0.7rem; letter-spacing:0.14em; text-transform:uppercase;
    transition: background 0.35s var(--ease), border-color 0.35s var(--ease), color 0.35s var(--ease);
  }
  .copy-btn:hover{ background: var(--champagne); border-color: var(--champagne); color: var(--ink); }
  .copy-btn.copied{ background: var(--sage-deep); border-color: var(--sage-deep); color: var(--cream); }
  .copy-btn svg{ width:14px; height:14px; }
  .map-links{ display:flex; gap: 20px; flex-wrap:wrap; }
  .ext-link{
    display:inline-flex; align-items:center; gap:6px; color: var(--sage-deep); text-decoration:none;
    font-size:0.92rem; border-bottom:1px solid rgba(69,112,58,0.35); padding-bottom:2px;
    transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
  }
  .ext-link:hover{ color: var(--terracotta); border-color: var(--terracotta); }
  .ext-link svg{ width:12px; height:12px; }
  .satnav-hint{ font-size: var(--text-body); color: var(--ink); opacity:0.82; max-width: 48ch; }

  .map-frame{
    position:relative; aspect-ratio: 4/3; border-radius: 14px; overflow:hidden;
    border:1px solid var(--line-gold); box-shadow: var(--shadow); background: var(--cream-deep);
  }
  /* Static garden-map: OSM raster tiles composed locally (no third-party framing) */
  .static-map{ position:absolute; inset:0; overflow:hidden; }
  .static-map-tiles{
    position:absolute; top:50%; left:50%; width:1024px; height:1024px;
    display:grid; grid-template-columns: repeat(4, 256px); grid-template-rows: repeat(4, 256px);
    transform: translate(-576px, -684px);
  }
  .static-map-tiles img{ display:block; width:256px; height:256px; background: var(--cream-deep); }
  .map-pin{
    position:absolute; top:50%; left:50%; z-index:2; width:32px; height:32px;
    transform: translate(-50%, -100%); color: var(--terracotta);
    filter: drop-shadow(0 5px 8px rgba(46,50,32,0.38)); pointer-events:none;
  }
  .map-pin svg{ display:block; width:100%; height:100%; }
  .map-pin circle{ fill: var(--cream); }
  .map-cover{
    position:absolute; inset:0; z-index:3; display:block;
    /* Expand touch target via pseudo-element — the map-cover itself
       already fills the container; this ensures the hit area is never
       clipped below 44px in either dimension on very small containers. */
    min-width: 44px; min-height: 44px;
  }
  .map-cover:focus-visible{ outline:3px solid var(--terracotta); outline-offset:-3px; }
  .map-caption{
    position:absolute; left:12px; bottom:12px; z-index:4; pointer-events:none;
    background: rgba(239,246,250,0.92); color: var(--ink); font-family: var(--font-sans);
    font-size:0.78rem; font-weight:500; letter-spacing:0.01em; padding:6px 13px; border-radius:999px;
    box-shadow: 0 6px 16px rgba(46,50,32,0.18);
  }
  .map-attr{
    position:absolute; right:7px; bottom:7px; z-index:5; text-decoration:none;
    background: rgba(239,246,250,0.80); color: var(--sage-deep);
    font-size:0.6rem; letter-spacing:0.01em; padding:2px 6px; border-radius:6px;
  }
  .map-attr:hover{ color: var(--terracotta); text-decoration:underline; }

  .note{ border-radius: 12px; padding: 18px 20px; font-size: var(--text-body); line-height:1.58; }
  .note--warn{ background: rgba(128,163,194,0.16); border:1px solid rgba(67,98,126,0.34); color: var(--ink); }
  .note--warn .note-label{ color: var(--terracotta); }
  .note--pending, .note--ok{ background: rgba(154,196,124,0.18); border:1px solid rgba(69,112,58,0.32); color: var(--ink); }
  .note--pending .note-label, .note--ok .note-label{ color: var(--sage-deep); }
  .note-label{ display:block; font-size:var(--text-label); letter-spacing:var(--tracking-label); text-transform:uppercase; font-weight:600; margin-bottom:5px; }

  /* C — where to stay */
  .stay-tiers{ display:flex; flex-direction:column; gap: clamp(32px, 4vw, 46px); }
  .tier{ min-width:0; }
  .tier-label{ font-size:var(--text-label); letter-spacing:var(--tracking-label); text-transform:uppercase; color: var(--gold-deep); margin-bottom: 16px; font-weight:500; }
  .stays{ display:grid; grid-template-columns: repeat(auto-fill, minmax(255px, 1fr)); gap: 18px; }
  .stay{
    display:flex; flex-direction:column; gap: 7px; min-width:0;
    background: var(--cream); border:1px solid var(--line); border-radius: 14px; padding: 24px 24px 26px;
    transition: transform 0.5s var(--ease), box-shadow 0.5s var(--ease), border-color 0.5s var(--ease);
  }
  .stay:hover{ transform: translateY(-5px); box-shadow: var(--shadow-lift); border-color: var(--line-gold); }
  .stay-name{ font-family: var(--font-serif); font-weight:400; font-size: 1.42rem; line-height:1.2; }
  .stay-name a{ color: var(--ink); text-decoration:none; border-bottom:1px solid transparent; transition: color 0.3s var(--ease), border-color 0.3s var(--ease); }
  .stay-name a:hover{ color: var(--terracotta); border-color: var(--terracotta); }
  .stay-name .arrow{ margin-left:5px; font-size:0.82em; color: var(--sage-deep); }
  .stay-flag{
    align-self:flex-start; margin-top:1px; font-family: var(--font-sans);
    font-size:0.6rem; letter-spacing:0.1em; text-transform:uppercase; color: var(--cream);
    background: var(--sage-deep); border-radius:999px; padding:3px 9px;
  }
  .stay-meta{ font-size:var(--text-meta); color: var(--sage-deep); }
  .stay-desc{ font-size:var(--text-body); color: var(--ink); opacity:0.84; }

  /* D — taxis home */
  /* Three firms, name and number on one line each — the whole block scans in a
     glance, which is what a guest in a dark lane at midnight actually needs. */
  .taxis{ list-style:none; display:flex; flex-direction:column; margin: 10px 0 12px; }
  .taxi{
    display:grid; grid-template-columns: 1fr auto; align-items:center; gap: 4px 18px;
    padding: 11px 0; border-top: 1px solid rgba(51,54,31,0.14);
  }
  .taxi:first-child{ border-top: 0; }
  .taxi-name{ font-family: var(--font-serif); font-size:1.2rem; line-height:1.22; color: var(--ink); }
  .taxi-name em{
    display:block; margin-top:3px; font-family: var(--font-sans); font-style:normal;
    font-size: var(--text-meta); line-height:1.4; color: var(--sage-deep);
  }
  .taxi-tel{
    display:inline-block; padding: 9px 0; white-space:nowrap;
    font-family: var(--font-serif); font-size:1.22rem;
    font-variant-numeric: tabular-nums lining-nums;
    color: var(--terracotta); text-decoration: underline;
    text-decoration-thickness: 1px; text-underline-offset: 5px;
    text-decoration-color: rgba(67,98,126,0.38);
    transition: color 0.3s var(--ease), text-decoration-color 0.3s var(--ease);
  }
  .taxi-tel:hover{ color: var(--ink); text-decoration-color: currentColor; }

  /* D — trains */
  .trains{ display:flex; flex-direction:column; margin: 8px 0 12px; }
  .train-row{ display:flex; justify-content:space-between; align-items:baseline; gap:18px; padding:12px 0; border-top:1px solid rgba(51,54,31,0.14); }
  .train-row:first-child{ border-top:0; }
  .train-dest{ font-size:var(--text-body); }
  .train-time{ font-family:var(--font-serif); font-size:1.3rem; color:#43627E; white-space:nowrap; font-variant-numeric: tabular-nums lining-nums; }

  /* E — good to know */
  .know{ display:grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 24px 34px; }
  .know-item h4{ font-family: var(--font-serif); font-weight:500; font-size:1.28rem; margin-bottom:8px; }
  .know-item p{ font-size:var(--text-body); color: var(--ink); opacity:0.82; }

  /* Travel reveal — visible by default; animate only when JS enables it and motion allowed */
  @media (prefers-reduced-motion: no-preference){
    #travel.js-reveal [data-tr]{ opacity:0; transform: translateY(22px); transition: opacity 0.85s var(--ease), transform 0.85s var(--ease); }
    #travel.js-reveal [data-tr].in{ opacity:1; transform:none; }
  }

  @media (max-width: 820px){
    .getting-here{ grid-template-columns: 1fr; }
  }
  @media (max-width: 374px){
    .countdown .unit{ min-width: 48px; padding: 10px 6px; }
    .countdown .num{ font-size: 1.6rem; }
    .countdown .label{ font-size: 0.52rem; }
  }
  @media (max-width: 520px){
    .train-row{ flex-direction:column; gap:2px; align-items:flex-start; }
    .taxi{ grid-template-columns: 1fr; gap: 2px; }
    .taxi-tel{ justify-self:start; }
  }

/* ---------- Gallery ---------- */
  /* ---------- Gallery — full-bleed scrapbook wall ---------- */
  .gallery-wall{
    margin-top: clamp(40px, 5vw, 64px);
    display: grid;
    gap: clamp(22px, 3.2vw, 46px);
    grid-template-columns: repeat(12, 1fr);
    align-items: center;
    max-width: 1280px;
    margin-inline: auto;
  }
  .gw-item{ margin: 0; position: relative; }
  .gw-item figcaption{
    margin-top: 12px; text-align: center;
    font-family: var(--font-accent); font-style: italic;
    font-size: 1.15rem; color: var(--gold-deep);
  }
  .gw-item .matte{ overflow: hidden; }
  .gw-item img{ width: 100%; height: 100%; object-fit: cover; display: block; }

  /* Collage placement — overlapping columns + varied aspects + pinned tilt */
  .gw-item--a{ grid-column: 1 / 6;  aspect-ratio: 4/3;  transform: rotate(-1.6deg); z-index:1; }
  .gw-item--b{ grid-column: 7 / 11; aspect-ratio: 4/5;  transform: rotate(1.4deg);  margin-top: clamp(-40px,-4vw,-20px); z-index:2; }
  .gw-item--c{ grid-column: 6 / 11; aspect-ratio: 4/3;  transform: rotate(1.1deg);  z-index:1; }
  .gw-item--d{ grid-column: 2 / 7;  aspect-ratio: 5/4;  transform: rotate(-1.2deg); margin-top: clamp(-56px,-5vw,-28px); z-index:2; }

  .gw-item .matte{ transition: transform .5s var(--ease), box-shadow .5s var(--ease); }
  .gw-item:hover{ z-index: 5; }
  .gw-item:hover .matte{ transform: translateY(-8px) scale(1.02); box-shadow: var(--shadow-lift); }
  .gw-item[role="button"]{ cursor: zoom-in; }
  .gw-item[role="button"]:focus-visible{ outline: 2px solid var(--terracotta); outline-offset: 8px; }

  /* Gallery lightbox: a single, quiet moment for the photographs to take over. */
  .gallery-lightbox[hidden]{ display:none; }
  .gallery-lightbox{
    position:fixed; inset:0; z-index:220; display:grid; place-items:center;
    padding:clamp(20px, 5vw, 72px);
    background:rgba(46,50,32,0.82);
    backdrop-filter:blur(12px) saturate(0.9); -webkit-backdrop-filter:blur(12px) saturate(0.9);
    opacity:0; visibility:hidden;
    transition: opacity 0.22s var(--ease), visibility 0s 0.22s;
  }
  .gallery-lightbox.open{ opacity:1; visibility:visible; transition: opacity 0.22s var(--ease), visibility 0s 0s; }
  .gallery-lightbox-inner{ position:relative; width:min(100%, 980px); }
  .gallery-lightbox img{
    width:100%; max-height:78vh; object-fit:contain;
    border:10px solid var(--cream); border-radius:14px;
    box-shadow:0 30px 90px rgba(0,0,0,0.32); background:var(--cream);
  }
  @media (prefers-reduced-motion: no-preference){
    .gallery-lightbox img{ transform: scale(0.94); transition: transform 0.28s var(--ease); }
    .gallery-lightbox.open img{ transform: scale(1); }
  }
  /* Arrow nav: tap targets sit outside the photograph at desktop, tuck inside on mobile */
  .gallery-lightbox-nav{
    position:absolute; top:50%; transform:translateY(-50%);
    width:48px; height:48px; border-radius:50%;
    background:rgba(239,246,250,0.9); color:var(--ink);
    border:1px solid var(--line-gold);
    display:flex; align-items:center; justify-content:center;
    cursor:pointer; z-index:1;
    font-size:1.3rem; line-height:1; box-shadow:var(--shadow-soft);
    transition: background 0.18s var(--ease), transform 0.18s var(--ease);
  }
  .gallery-lightbox-nav:hover{ background:var(--cream); transform:translateY(-50%) scale(1.08); }
  .gallery-lightbox-nav:focus-visible{ outline:2px solid var(--terracotta); outline-offset:3px; }
  .nav-prev{ left:-10px; }
  .nav-next{ right:-10px; }
  @media (prefers-reduced-motion: reduce){
    .gallery-lightbox-nav:hover{ transform:translateY(-50%); }
  }
  .gallery-lightbox-caption{
    margin:16px auto 0; text-align:center;
    color:var(--cream); font-family:var(--font-accent);
    font-style:italic; font-size:1.15rem;
    /* Small photo-counter hint */
  }
  .gallery-lightbox-caption em{ font-style:normal; font-family:var(--font-sans); font-size:0.78rem; opacity:0.62; margin-left:8px; }
  .gallery-lightbox-close{
    position:absolute; top:-18px; right:-18px; width:44px; height:44px;
    border:1px solid rgba(239,246,250,0.5); border-radius:50%;
    background:var(--cream); color:var(--ink);
    cursor:pointer; font-size:1.35rem; box-shadow:var(--shadow-soft);
    transition: background 0.18s var(--ease), transform 0.18s var(--ease);
  }
  .gallery-lightbox-close:hover{ background:var(--champagne); transform:scale(1.05); }
  @media (prefers-reduced-motion: reduce){ .gallery-lightbox-close:hover{ transform:none; } }
  @media (max-width: 680px){
    .gallery-lightbox-nav{ width:40px; height:40px; background:rgba(239,246,250,0.82); }
    .nav-prev{ left:4px; }
    .nav-next{ right:4px; }
    .gallery-lightbox-close{ top:8px; right:8px; }
  }

  /* Tablet — simpler two-column mosaic */
  @media (max-width: 820px){
    .gallery-wall{ grid-template-columns: repeat(2, 1fr); gap: 26px 22px; }
    .gw-item--a,.gw-item--b,.gw-item--c,.gw-item--d{
      grid-column: auto; margin-top: 0;
    }
    .gw-item--a,.gw-item--c{ aspect-ratio: 4/3; }
    .gw-item--b,.gw-item--d{ aspect-ratio: 4/5; }
  }

  /* Phone — single stacked column, prints straighten for calm reading */
  @media (max-width: 520px){
    .gallery-wall{ grid-template-columns: 1fr; }
    .gw-item{ transform: none !important; }
  }

  /* Respect reduced motion — no tilt, no hover lift */
  @media (prefers-reduced-motion: reduce){
    .gw-item{ transform: none !important; }
    .gw-item:hover .matte{ transform: none; }
  }

  /* Garden bridge — the gallery settles gently into the next section via
     a cream→mist→cream ramp so the honeymoon section blends in without a seam. */
  #gallery{
  position: relative;
  /* Same feathered edges as the rest of the page: paper at the top, and a mist
     settle at the foot that dissolves before the honeymoon section begins. */
  background: linear-gradient(180deg,
    rgba(239,246,250,0) 0,
    rgba(239,246,250,0.94) var(--seam-feather),
    rgba(239,246,250,0.94) 58%,
    rgba(173,189,172,0.20) calc(100% - var(--seam-feather)),
    rgba(173,189,172,0) 100%);
  padding-block: clamp(48px, 6vw, 88px);
  }
  /* Gallery breaks the container for a wall-to-wall scrapbook */
  #gallery .section-inner{ max-width: none; padding-inline: clamp(20px, 5vw, 72px); }
  #gallery .section-inner > .reveal:first-child{ max-width: 1080px; margin-inline: auto; } /* keep the heading centred/contained */
  
/* ---------- Honeymoon Fund ---------- */
  #honeymoon{
    background: linear-gradient(180deg,
      rgba(220,234,245,0) 0,
      rgba(220,234,245,0.60) var(--seam-feather),
      rgba(220,234,245,0.66) clamp(90px, 12vw, 150px),
      rgba(220,234,245,0.66) calc(100% - clamp(90px, 12vw, 150px)),
      rgba(220,234,245,0.60) calc(100% - var(--seam-feather)),
      rgba(220,234,245,0) 100%);
  }
  .honeymoon-head{
    max-width: 680px; margin: 0 auto clamp(34px, 5vw, 52px); text-align: center;
  }
  .honeymoon-lead{
    font-size: var(--text-lead); color: var(--ink-soft);
    margin: 0 auto; max-width: 56ch; line-height: 1.62;
  }
  .honeymoon-experiences{
    list-style: none; margin: 0 auto clamp(48px, 6vw, 72px); padding: 0;
    max-width: 1000px;
    display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: clamp(18px, 2.4vw, 26px);
  }
  .exp-card{
    position: relative; padding: 28px 24px 28px 0;
    background: transparent; border: 0; border-top: 1px solid var(--line-gold); border-radius: 0; box-shadow: none;
    transition: transform 0.5s var(--ease), box-shadow 0.5s var(--ease), border-color 0.5s var(--ease);
  }
  .exp-card:hover{
    transform: translateY(-3px); box-shadow: none;
    border-color: rgba(128,163,194,0.55);
  }
  .exp-ico{
    display: grid; place-items: center;
    width: 46px; height: 46px; margin-bottom: 16px;
    border-radius: 50%;
    background: linear-gradient(145deg, rgba(154,196,124,0.22), rgba(128,163,194,0.20));
    color: var(--sage-deep);
    border: 1px solid rgba(128,163,194,0.24);
  }
  .exp-ico svg{ width: 22px; height: 22px; }
  .exp-title{
    font-family: var(--font-serif); font-weight: 500;
    font-size: 1.28rem; color: var(--ink);
    margin-bottom: 8px; letter-spacing: -0.01em;
  }
  .exp-desc{
    font-size: var(--text-body); line-height: 1.55;
    color: var(--ink-soft); margin: 0;
  }
  .honeymoon-give{ max-width: 720px; margin: 0 auto; }
  .give-card{
    padding: clamp(30px, 4.5vw, 48px);
    background: rgba(255,255,255,0.42); border: 1px solid var(--line-gold); border-radius: 16px; box-shadow: none;
    text-align: center;
  }
  .give-card > .eyebrow{ margin-bottom: 16px; }
  .give-card > .serif{
    font-size: var(--text-h3); margin-bottom: 16px;
    font-weight: 500;
  }
  .give-lead{
    font-size: var(--text-lead); line-height: 1.62;
    color: var(--ink-soft); margin: 0 auto clamp(28px, 3.5vw, 36px);
    max-width: 48ch;
  }

  /* Primary CTA — echoes the RSVP submit button so the two "actions" on the page feel related */
  .give-btn{
    position: relative; display: inline-flex; align-items: center; justify-content: center;
    gap: 14px; text-decoration: none;
    background: var(--peach); color: var(--ink);
    padding: 11px 12px 11px 34px;
    font-family: var(--font-sans); font-size: 0.82rem;
    letter-spacing: 0.16em; text-transform: uppercase; font-weight: 500;
    border-radius: 999px;
    box-shadow: 0 16px 34px -16px rgba(67,98,126,0.5);
    transition: transform 0.45s var(--ease-out), background 0.45s var(--ease),
                color 0.45s var(--ease), box-shadow 0.45s var(--ease);
  }
  .give-btn-icon{
    width: 40px; height: 40px; border-radius: 50%; flex: none;
    display: grid; place-items: center;
    background: rgba(46,50,32,0.14); color: var(--ink);
    transition: transform 0.45s var(--ease-out), background 0.45s var(--ease), color 0.45s var(--ease);
  }
  .give-btn-icon svg{ width: 17px; height: 17px; }
  .give-btn:hover{
    background: var(--terracotta); color: var(--cream);
    transform: translateY(-2px); box-shadow: var(--shadow-lift);
  }
  .give-btn:hover .give-btn-icon{
    background: rgba(239,246,250,0.22); color: var(--cream);
    transform: translate(3px, -2px) scale(1.06);
  }
  .give-btn:active{ transform: translateY(1px) scale(0.985); }
  .give-btn:focus-visible{ outline: 2px solid var(--ink); outline-offset: 3px; }
  .give-alt{
    font-size: var(--text-body); line-height: 1.55;
    color: var(--ink-soft); margin: clamp(28px, 3.5vw, 36px) auto 0;
    max-width: 44ch;
    padding-top: clamp(22px, 3vw, 28px);
    border-top: 1px solid var(--line-gold);
  }
  .give-note{
    font-size: var(--text-meta); line-height: 1.55;
    color: var(--gold-deep); margin: 14px auto 0;
    max-width: 42ch; font-style: italic;
  }
  .give-card > .eyebrow{ margin-bottom: 16px; }
  .give-card > .serif{
    font-size: var(--text-h3); margin-bottom: clamp(22px, 3vw, 32px);
    font-weight: 500;
  }
  .give-methods{
    display: grid; grid-template-columns: 1fr 1fr;
    gap: clamp(22px, 3vw, 32px);
    margin-bottom: 24px;
  }
  .give-method{
    padding: 22px 0; border-radius: 0; background: transparent; border: 0; border-top: 1px solid var(--line);
  }
  .give-method-head{
    display: flex; align-items: center; gap: 12px; margin-bottom: 14px;
  }
  .give-ico{
    width: 26px; height: 26px; flex: none;
    color: var(--sage-deep);
  }
  .give-method h4{
    font-family: var(--font-serif); font-weight: 500;
    font-size: 1.18rem; color: var(--ink); margin: 0;
  }
  .give-details{ margin: 0; padding: 0; display: grid; gap: 12px; }
  .give-details > div{
    display: grid; grid-template-columns: 110px 1fr;
    gap: 10px; align-items: center;
  }
  .give-details dt{
    font-size: var(--text-label); letter-spacing: var(--tracking-label);
    text-transform: uppercase; color: var(--gold-deep); font-weight: 500;
  }
  .give-details dd{
    margin: 0; font-family: var(--font-serif);
    font-size: 1.05rem; color: var(--ink);
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    font-variant-numeric: tabular-nums lining-nums;
  }
  .copy-btn--sm{
    padding: 5px 12px; font-size: 0.62rem;
  }
  .copy-btn--sm svg{ width: 12px; height: 12px; }
  .give-desc{
    font-size: var(--text-body); line-height: 1.6;
    color: var(--ink-soft); margin: 0;
  }
  .give-note{
    text-align: center; font-size: var(--text-body);
    color: var(--ink-soft); margin: 8px auto 0;
    max-width: 44ch; line-height: 1.55;
  }
  @media (max-width: 640px){
    .give-methods{ grid-template-columns: 1fr; }
    .give-details > div{ grid-template-columns: 1fr; gap: 4px; }
  }
  /* Reveal — same pattern as your other sections */
  @media (prefers-reduced-motion: no-preference){
    #honeymoon.js-reveal [data-hm]{
      opacity: 0; transform: translateY(22px);
      transition: opacity 0.85s var(--ease), transform 0.85s var(--ease);
    }
    #honeymoon.js-reveal [data-hm].in{ opacity: 1; transform: none; }
  }


  /* ---------- FAQ ---------- */
  #faq{
    /* Fades in off the ground, warms toward the mist green at the foot, then
       dissolves before the RSVP panel — no two fills ever butt together. */
    background: linear-gradient(180deg,
    rgba(230,240,248,0) 0,
    rgba(230,240,248,0.66) var(--seam-feather),
    rgba(230,240,248,0.66) 60%,
    rgba(173,189,172,0.42) calc(100% - var(--seam-feather)),
    rgba(173,189,172,0) 100%);

  }

  .faq-head{
    max-width: 680px;
    margin: 0 auto clamp(34px, 5vw, 52px);
    text-align: center;
  }

  .faq-lead{
    font-size: var(--text-lead);
    color: var(--ink-soft);
    margin: 0 auto;
    max-width: 54ch;
  }

  .faq-list{
    max-width: 820px;
    margin: 0 auto;
    display: grid;
    gap: 14px;
  }

  .faq-item{
    border: 1px solid var(--line-gold);
    border-radius: 16px;
    background: rgba(239,246,250,0.62);
    box-shadow: var(--shadow-soft);
    overflow: hidden;
  }

  .faq-item summary{
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    padding: 20px clamp(18px, 3vw, 28px);
    font-family: var(--font-serif);
    font-size: clamp(1.08rem, 2vw, 1.28rem);
    font-weight: 500;
    color: var(--ink);
  }

  .faq-item summary::-webkit-details-marker{
    display: none;
  }

  .faq-item summary::after{
    content: '+';
    flex: none;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    border: 1px solid var(--line-gold);
    color: var(--gold-deep);
    background: rgba(255,255,255,0.38);
    font-family: var(--font-sans);
    font-size: 1.1rem;
    line-height: 1;
    transition: transform 0.3s var(--ease), background 0.3s var(--ease);
  }

  .faq-item[open] summary::after{
    content: '-';
    transform: rotate(180deg);
    background: var(--champagne);
  }

  .faq-answer{
    padding: 0 clamp(18px, 3vw, 28px) 22px;
    color: var(--ink-soft);
    font-size: var(--text-body);
    line-height: 1.65;
  }

  .faq-answer p{
    margin: 0;
    max-width: 68ch;
  }

  .faq-item summary:focus-visible{
    outline: 2px solid var(--terracotta);
    outline-offset: -4px;
  }

  @media (prefers-reduced-motion: no-preference){
    #faq.js-reveal [data-faq]{
      opacity: 0;
      transform: translateY(22px);
      transition: opacity 0.85s var(--ease), transform 0.85s var(--ease);
    }

    #faq.js-reveal [data-faq].in{
      opacity: 1;
      transform: none;
    }
  }
  /* ---------- RSVP ---------- */
  #rsvp{ position:relative; overflow:hidden; color: var(--ink); }
  /* The mist panel is painted by ::before rather than the section itself, purely
     so it can be masked. Both it and the atmos light dissolve to nothing at the
     section's top and bottom edge, which lets the page ground carry the seam —
     the panel rises out of the paper instead of starting on a line. */
  #rsvp::before{
    content:''; position:absolute; inset:0; z-index:0; pointer-events:none;
    background-image:
      linear-gradient(165deg, rgba(188,201,187,0.90) 0%, rgba(173,189,172,0.90) 100%),
      var(--stripe-bg);
    background-repeat:
      no-repeat,
      repeat;
    background-size:
      auto,
      520px auto;
    background-attachment:
      scroll,
      scroll;
    background-blend-mode: normal, multiply;
    -webkit-mask-image: var(--seam-mask);
            mask-image: var(--seam-mask);
  }
  @media (hover: hover) and (pointer: fine){
    #rsvp::before{
      background-attachment:
        scroll,
        fixed;
    }
  }
  /* Soft spring-garden light on the pastel-green panel — pure CSS, no image dependency */
  .rsvp-atmos{
    position:absolute; inset:0; z-index:0; pointer-events:none;
    background:
      radial-gradient(120% 85% at 12% -8%, rgba(255,255,255,0.38), transparent 55%),
      radial-gradient(95% 78% at 106% 112%, rgba(128,163,194,0.16), transparent 55%),
      radial-gradient(70% 50% at 50% 122%, rgba(69,112,58,0.12), transparent 60%),
      linear-gradient(180deg, rgba(255,255,255,0.12), rgba(69,112,58,0.05));
    -webkit-mask-image: var(--seam-mask);
            mask-image: var(--seam-mask);
  }
  #rsvp .section-inner{ position:relative; z-index:1; }

  .rsvp-intro{ text-align:center; max-width: 640px; margin: 0 auto; }
  #rsvp .eyebrow{
    color: var(--ink); border-color: rgba(46,50,32,0.22);
    background: rgba(255,255,255,0.30);
  }
  #rsvp .eyebrow::before{ background: var(--gold); box-shadow: 0 0 0 3px rgba(128,163,194,0.22); }
  #rsvp .section-title{ color: var(--ink); margin-bottom: 16px; }
  #rsvp .lead{ color: rgba(46,50,32,0.82); font-size: var(--text-lead); margin: 0 auto; max-width: 46ch; }
  #rsvp .lead strong{ color: var(--ink); font-weight: 600; white-space: nowrap; }

  .rsvp-divider{ margin: 32px 0 40px; }

  .rsvp-form{ display:grid; gap: 22px; max-width: 620px; margin: 0 auto; }
  .rsvp-form[hidden]{ display:none; }
  .field{ display:flex; flex-direction:column; gap: 7px; min-width:0; }
  .field[hidden]{ display:none; }
  .field > label, .attend > legend{
    font-family: var(--font-sans); font-size: 0.8rem; letter-spacing: 0.06em;
    text-transform: uppercase; color: var(--ink); font-weight: 500; padding: 0;
  }
  .field .opt{ text-transform:none; letter-spacing:0; color: rgba(46,50,32,0.82); font-weight: 400; }
  .field-hint{ font-size: var(--text-meta); color: rgba(46,50,32,0.85); margin: 0; line-height: 1.45; }

  /* ---------- Guest Picker (RSVP name dropdown) ---------- */
  .guest-picker{ position: relative; }
  .guest-picker-input{
    width: 100%;
    background: rgba(255,255,255,0.55);
    border: 1px solid rgba(46,50,32,0.22);
    border-radius: 10px;
    padding: 14px 44px 14px 16px;
    height: 54px;
    color: var(--ink);
    font-family: var(--font-sans);
    font-size: 0.98rem;
    transition: border-color 0.25s var(--ease), background 0.25s var(--ease), box-shadow 0.25s var(--ease);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%2343627E' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.5-3.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
  }
  .guest-picker-input:focus-visible{
    outline: none;
    border-color: var(--terracotta);
    box-shadow: 0 0 0 3px rgba(128,163,194,0.32);
  }
  .guest-picker-input[aria-invalid="true"]{
    border-color: #C25B6E;
    box-shadow: 0 0 0 3px rgba(194,91,110,0.20);
  }
  .guest-picker-list{
    position: absolute;
    left: 0; right: 0;
    top: calc(100% + 8px);
    z-index: 60;
    list-style: none;
    margin: 0;
    padding: 8px;
    max-height: 260px;
    overflow-y: auto;
    border: 1px solid var(--line-gold);
    border-radius: 16px;
    background: linear-gradient(160deg, rgba(239,246,250,0.98), rgba(220,234,245,0.96));
    box-shadow:
      0 26px 60px -30px rgba(46,50,32,0.55),
      inset 0 1px 0 rgba(255,255,255,0.72);
  }
  .guest-picker-list[hidden]{ display: none; }
  .guest-picker-list li{
    position: relative;
    cursor: pointer;
    padding: 12px 44px 12px 14px;
    border-radius: 10px;
    color: var(--ink);
    font-family: var(--font-sans);
    font-size: 0.98rem;
    line-height: 1.35;
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    transition:
      background 0.22s var(--ease),
      color 0.22s var(--ease),
      transform 0.22s var(--ease);
  }
  .guest-picker-list li:hover,
  .guest-picker-list li.is-active{
    background: linear-gradient(135deg, rgba(128,163,194,0.20), rgba(154,196,124,0.18));
    color: var(--ink);
    transform: translateX(2px);
  }
  .guest-picker-list li.is-responded{
    opacity: 0.55;
    font-style: italic;
  }
  .guest-picker-list li .picker-tag{
    font-size: 0.62rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--sage-deep);
    background: rgba(154,196,124,0.22);
    padding: 3px 9px;
    border-radius: 999px;
    flex: none;
    font-style: normal;
  }
  .guest-picker-list .picker-empty{
    padding: 14px;
    color: rgba(46,50,32,0.7);
    font-style: italic;
    text-align: center;
    cursor: default;
    display: block;
    list-style: none;
  }
  .guest-picker-list .picker-empty:hover{
    background: transparent;
    transform: none;
  }
  .field-note{
    font-size: var(--text-meta);
    color: rgba(46,50,32,0.82);
    margin: 6px 0 0;
    line-height: 1.5;
  }
  .attendance-note{
    margin-top: -8px;
    padding: 12px 18px;
    border: 1px solid rgba(69,112,58,0.22);
    border-radius: 10px;
    background: rgba(154,196,124,0.12);
    color: var(--ink);
    font-family: var(--font-accent);
    font-style: italic;
    font-size: 1.12rem;
    font-weight: 400;
    line-height: 1.5;
    letter-spacing: 0.005em;
  }
  .field-note[hidden]{ display: none; }
  .field-note a{ color: var(--terracotta); text-underline-offset: 2px; }

  .field input, .field textarea, .field select, .guest-input{
    width:100%; background: rgba(255,255,255,0.55); border: 1px solid rgba(46,50,32,0.22); border-radius: 10px;
    padding: 14px 16px; color: var(--ink); font-family: var(--font-sans); font-size: 0.98rem;
    transition: border-color 0.25s var(--ease), background 0.25s var(--ease), box-shadow 0.25s var(--ease);
  }

  .field input:not([type="hidden"]), .guest-input, .select-trigger{
    height: 54px;
  }

  .select-wrap{
  position: relative;
  width: 100%;
  z-index: 5;
  }
  
  .select-wrap.custom-select.open{
    z-index: 50;
  }

  .select-trigger{
    width: 100%;
    min-height: 54px;
    height: 54px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    cursor: pointer;
    border: 1px solid rgba(46,50,32,0.22);
    border-radius: 10px;
    padding: 0 14px 0 16px;
    color: var(--ink);
    font-family: var(--font-sans);
    font-size: 0.98rem;
    line-height: 1.35;
    text-align: left;
    background:
      linear-gradient(135deg, rgba(255,255,255,0.84), rgba(235,243,246,0.58)),
      radial-gradient(140px 80px at 100% 0%, rgba(128,163,194,0.22), transparent 70%);
    box-shadow:
      inset 0 1px 0 rgba(255,255,255,0.62),
      0 14px 30px -24px rgba(46,50,32,0.55);
    transition:
      border-color 0.25s var(--ease),
      background 0.25s var(--ease),
      box-shadow 0.25s var(--ease),
      transform 0.25s var(--ease);
  }

  .select-trigger:hover{
    border-color: rgba(67,98,126,0.44);
    background:
      linear-gradient(135deg, rgba(255,255,255,0.94), rgba(235,243,246,0.72)),
      radial-gradient(140px 80px at 100% 0%, rgba(128,163,194,0.30), transparent 70%);
  }

  .select-trigger:focus-visible{
    outline: none;
    border-color: var(--terracotta);
    box-shadow:
      0 0 0 3px rgba(128,163,194,0.32),
      inset 0 1px 0 rgba(255,255,255,0.68),
      0 16px 32px -24px rgba(46,50,32,0.58);
  }

  .select-chevron{
    position: relative;
    flex: none;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background:
      linear-gradient(145deg, rgba(128,163,194,0.28), rgba(154,196,124,0.18));
    border: 1px solid rgba(128,163,194,0.24);
  }

  .select-chevron::after{
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 9px;
    height: 9px;
    border-right: 2px solid var(--terracotta);
    border-bottom: 2px solid var(--terracotta);
    transform: translate(-50%, -65%) rotate(45deg);
    transition: transform 0.25s var(--ease), border-color 0.25s var(--ease);
  }

  .custom-select.open .select-chevron::after{
    transform: translate(-50%, -35%) rotate(225deg);
    border-color: var(--sage-deep);
  }

  .select-menu{
    position: absolute;
    left: 0;
    right: 0;
    top: calc(100% + 8px);
    z-index: 60;
    list-style: none;
    margin: 0;
    padding: 8px;
    border: 1px solid var(--line-gold);
    border-radius: 16px;
    background:
      linear-gradient(160deg, rgba(239,246,250,0.98), rgba(220,234,245,0.96));
    box-shadow:
      0 26px 60px -30px rgba(46,50,32,0.55),
      inset 0 1px 0 rgba(255,255,255,0.72);
    overflow: hidden;
  }

  .select-menu[hidden]{
    display: none;
  }

  .select-menu li{
    position: relative;
    cursor: pointer;
    padding: 12px 44px 12px 14px;
    border-radius: 10px;
    color: var(--ink);
    font-family: var(--font-sans);
    font-size: 0.98rem;
    line-height: 1.35;
    transition:
      background 0.22s var(--ease),
      color 0.22s var(--ease),
      transform 0.22s var(--ease);
  }

  .select-menu li:hover,
  .select-menu li.is-active{
    background:
      linear-gradient(135deg, rgba(128,163,194,0.20), rgba(154,196,124,0.18));
    color: var(--ink);
    transform: translateX(2px);
  }

  .select-menu li[aria-selected="true"]{
    background:
      linear-gradient(135deg, rgba(67,98,126,0.18), rgba(154,196,124,0.20));
    color: var(--terracotta);
    font-weight: 500;
  }

  .select-menu li[aria-selected="true"]::after{
    content: '';
    position: absolute;
    top: 50%;
    right: 16px;
    width: 12px;
    height: 7px;
    border-left: 2px solid var(--sage-deep);
    border-bottom: 2px solid var(--sage-deep);
    transform: translateY(-65%) rotate(-45deg);
  }

  .field input[aria-invalid="true"], .guest-input[aria-invalid="true"],
  .select-trigger[aria-invalid="true"]{
    border-color: #C25B6E; box-shadow: 0 0 0 3px rgba(194,91,110,0.20);
  }
  /* A long dish name needs room to wrap, so this variant grows past the fixed row height. */
  .custom-select--tall .select-trigger{ height: auto; padding-top: 11px; padding-bottom: 11px; }
  .select-trigger.is-placeholder{ color: rgba(46,50,32,0.72); }
  /* One meal card per guest. With a plus-one, each card is headed by a name. */
  .meal-cards{ display:grid; gap:16px; }
  .meal-cards[hidden]{ display:none; }
  .meal-card{
    display:grid; gap:18px; padding:18px;
    border:1px solid rgba(46,50,32,0.16); border-radius:14px; background:rgba(255,255,255,0.22);
  }
  .meal-card[hidden], .meal-for[hidden]{ display:none; }
  .meal-for{ margin:0; font-family:var(--font-serif); font-size:1.22rem; line-height:1.2; color:var(--ink); }
  .field-row{ display:grid; grid-template-columns: 1fr 1fr; gap: 22px; }
  .field-row--single{ grid-template-columns: 1fr; }

  .field-err{
    display:flex; align-items:center; gap: 6px; margin: 2px 0 0;
    font-size: 0.8rem; color: var(--ink);
  }
  .field-err[hidden]{ display:none; }
  .field-err svg{ width: 14px; height: 14px; flex: none; color: #C25B6E; }

  /* Attending — segmented radio control */
  .attend{ border: none; margin: 0; padding: 0; min-width: 0; }
  .attend-options{ display:grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 6px; }
  .attend-opt{
    position:relative; display:flex; align-items:center; gap: 10px; cursor:pointer;
    padding: 15px 18px; border: 1px solid rgba(46,50,32,0.22); border-radius: 12px;
    background: rgba(255,255,255,0.35); color: var(--ink); font-size: 0.98rem;
    transition: border-color 0.3s var(--ease), background 0.3s var(--ease), transform 0.3s var(--ease);
  }
  .attend-opt:hover{ border-color: rgba(46,50,32,0.4); background: rgba(255,255,255,0.55); }
  .attend-opt:has(input:checked){ border-color: var(--terracotta); background: rgba(128,163,194,0.16); }
  .attend-opt input{ position:absolute; opacity:0; width:1px; height:1px; }
  .attend-opt .dot{
    width: 16px; height: 16px; border-radius: 50%; flex: none;
    border: 1.5px solid rgba(46,50,32,0.4); display:grid; place-items:center;
    transition: border-color 0.2s var(--ease);
  }
  .attend-opt .dot::after{
    content:''; width: 8px; height: 8px; border-radius: 50%; background: var(--peach);
    transform: scale(0); transition: transform 0.2s var(--ease);
  }
  .attend-opt input:checked ~ .dot{ border-color: var(--peach); }
  .attend-opt input:checked ~ .dot::after{ transform: scale(1); }
  .attend-opt input:focus-visible ~ .dot{ box-shadow: 0 0 0 3px rgba(128,163,194,0.4); }

  /* Party details — collapses on decline */
  .rsvp-party{ display:grid; grid-template-rows: 1fr; }
  .rsvp-party-inner{ overflow:visible; min-height:0; display:grid; gap: 22px; }
  .rsvp-party.collapsed .rsvp-party-inner{ overflow: hidden; }
  .rsvp-party.collapsed{ grid-template-rows: 0fr; opacity: 0; margin-top: -22px; }
  @media (prefers-reduced-motion: no-preference){
    .rsvp-party{ transition: grid-template-rows 0.5s var(--ease), opacity 0.35s var(--ease); }
  }

  /* Dynamic guest rows */
  .guest-list{ display:flex; flex-direction:column; gap: 10px; }
  .guest-row{ display:flex; align-items:center; gap: 8px; }
  .guest-input{ flex: 1; }
  @media (prefers-reduced-motion: no-preference){
    .guest-row.entering{ animation: guestIn 0.35s var(--ease); }
  }
  @keyframes guestIn{ from{ opacity:0; transform: translateY(-6px); } to{ opacity:1; transform:none; } }
  .guest-remove{
    flex: none; width: 44px; height: 44px; display:grid; place-items:center;
    background: transparent; border: 1px solid rgba(46,50,32,0.24); border-radius: 3px;
    color: rgba(46,50,32,0.7); cursor:pointer;
    transition: border-color 0.2s var(--ease), color 0.2s var(--ease), background 0.2s var(--ease);
  }
  .guest-remove:hover{ border-color: #C25B6E; color: #C25B6E; background: rgba(194,91,110,0.10); }
  .guest-remove:focus-visible{ outline: 2px solid var(--peach); outline-offset: 2px; }
  .guest-add{
    justify-self:start; display:inline-flex; align-items:center; gap: 8px; margin-top: 2px;
    background: transparent; border: 1px dashed rgba(46,50,32,0.32); border-radius: 3px;
    padding: 12px 16px; min-height: 44px;
    color: var(--ink); font-family: var(--font-sans); font-size: 0.82rem; letter-spacing: 0.04em; cursor:pointer;
    transition: border-color 0.25s var(--ease), background 0.25s var(--ease);
  }
  .guest-add:hover{ border-color: var(--peach); background: rgba(255,255,255,0.5); }
  .guest-add:focus-visible{ outline: 2px solid var(--peach); outline-offset: 3px; }
  .guest-add[hidden]{ display:none; }
  .guest-add svg{ width: 15px; height: 15px; }
  .guest-note{ font-size: var(--text-meta); color: rgba(46,50,32,0.82); margin: 4px 0 0; }
  .guest-note[hidden]{ display:none; }

  .rsvp-actions{ display:flex; justify-content:center; margin-top: 8px; }
  .submit-btn{
    position:relative; display:inline-flex; align-items:center; justify-content:center; gap: 14px;
    background: var(--peach); color: var(--ink); border:none; padding: 11px 12px 11px 34px;
    font-family: var(--font-sans); font-size: 0.82rem; letter-spacing: 0.16em; text-transform: uppercase; font-weight: 500;
    border-radius: 999px; cursor:pointer;
    box-shadow: 0 16px 34px -16px rgba(67,98,126,0.5);
    transition: transform 0.45s var(--ease-out), background 0.45s var(--ease), color 0.45s var(--ease), box-shadow 0.45s var(--ease);
  }
  .submit-btn .btn-icon{
    width: 40px; height: 40px; border-radius: 50%; flex:none;
    display:grid; place-items:center;
    background: rgba(46,50,32,0.14); color: var(--ink);
    transition: transform 0.45s var(--ease-out), background 0.45s var(--ease), color 0.45s var(--ease);
  }
  .submit-btn .btn-icon svg{ width: 17px; height: 17px; }
  .submit-btn:hover{ background: var(--terracotta); color: var(--cream); transform: translateY(-2px); box-shadow: var(--shadow-lift); }
  .submit-btn:hover .btn-icon{ background: rgba(239,246,250,0.22); color: var(--cream); transform: translate(3px, -2px) scale(1.06); }
  .submit-btn:active{ transform: translateY(1px) scale(0.985); }
  .submit-btn:focus-visible{ outline: 2px solid var(--ink); outline-offset: 3px; }
  .submit-btn[disabled]{ cursor: default; opacity: 0.95; }
  .submit-btn.is-sending{ background: var(--terracotta); color: var(--cream); }
  .submit-btn.is-sending .btn-icon{ display:none; }
  .submit-btn .btn-spinner{
    width: 18px; height: 18px; border-radius: 50%; display:none; margin-left: 6px;
    border: 2px solid rgba(239,246,250,0.4); border-top-color: var(--cream);
  }
  .submit-btn.is-sending .btn-spinner{ display:inline-block; }
  @media (prefers-reduced-motion: no-preference){
    .submit-btn.is-sending .btn-spinner{ animation: spin 0.7s linear infinite; }
  }
  @keyframes spin{ to{ transform: rotate(360deg); } }

  .form-note{
    margin: 4px auto 0; text-align:center; font-size: var(--text-meta); color: rgba(46,50,32,0.82);
    max-width: 48ch; line-height: 1.5;
  }
  .form-note:empty{ display:none; }
  .form-note.is-error{ color: var(--ink); }
  .form-note.is-error a{ color: var(--terracotta); text-decoration: underline; text-underline-offset: 2px; }

  .rsvp-success{ text-align:center; max-width: 520px; margin: 0 auto; }
  .rsvp-success[hidden]{ display:none; }
  .rsvp-success .success-mark{ width: 62px; height: 62px; margin: 0 auto 20px; }
  .rsvp-success h3{ font-size: clamp(1.9rem, 3.6vw, 2.5rem); margin-bottom: 12px; color: var(--ink); }
  .rsvp-success p{ font-size: 1.02rem; color: rgba(46,50,32,0.82); margin: 0 auto; max-width: 42ch; }
  .rsvp-success{ position:relative; padding:clamp(28px, 5vw, 58px) clamp(20px, 5vw, 60px); }
  .rsvp-success::before{ content:''; position:absolute; inset:0; border:1px solid rgba(67,98,126,0.28); border-radius:16px; pointer-events:none; }
  .success-kicker{ margin-bottom:14px; color:var(--sage-deep); font-size:var(--text-label); letter-spacing:var(--tracking-label); text-transform:uppercase; font-weight:500; }
  .success-signoff{ margin:24px auto 0; color:var(--terracotta); font-family:var(--font-script); font-size:clamp(1.8rem, 4vw, 2.5rem); line-height:1.1; }
  .success-back{ display:inline-flex; margin-top:26px; color:var(--gold-deep); font-size:var(--text-label); letter-spacing:0.16em; text-transform:uppercase; text-underline-offset:4px; }
  @media (prefers-reduced-motion: no-preference){
    .rsvp-success.in{ animation: rise 0.7s var(--ease); }
  }

  /* Safe scroll reveal — content visible by default; animates only when JS + motion allow */
  @media (prefers-reduced-motion: no-preference){
    #rsvp.js-reveal [data-rv]{ opacity:0; transform: translateY(22px); transition: opacity 0.8s var(--ease), transform 0.8s var(--ease); }
    #rsvp.js-reveal [data-rv].in{ opacity:1; transform:none; }
  }

  @media (max-width: 600px){
    .field-row{ grid-template-columns: 1fr; }
    .attend-options{ grid-template-columns: 1fr; }
  }

  /* ---------- Footer ---------- */
  footer{
    position: relative;
    padding: clamp(64px, 8vw, 104px) 6vw max(clamp(44px, 5vw, 62px), env(safe-area-inset-bottom, 0px));
    text-align:center; background: rgba(239,246,250,0.62);
  }
  /* Twilight lifts back into cream — a smooth exit from the RSVP dark, no razor seam. */
  footer::before{
    content:''; position:absolute; left:0; right:0; top:0; transform: translateY(-100%);
    height: clamp(90px, 11vw, 150px); pointer-events:none;
    background: linear-gradient(180deg, rgba(173,189,172,0), rgba(239,246,250,0.62));
  }
  footer .foot-mark{ display:flex; justify-content:center; margin-bottom: 26px; }
  footer .serif{ font-family: var(--font-script); font-weight:400; font-size: clamp(1.9rem, 4vw, 2.7rem); margin-bottom: 12px; letter-spacing:-0.01em; }
  footer .serif em{ font-family: var(--font-accent); font-style:italic; color: var(--terracotta); }
  footer .sub{ font-family: var(--font-sans); font-size: 0.72rem; letter-spacing: 0.24em; text-transform:uppercase; color: var(--gold-deep); }
  footer .foot-contact{ margin-top: 18px; font-size: 0.9rem; color: var(--ink-soft); }
  footer .foot-contact a{ color: var(--terracotta); text-decoration: none; }
  footer .foot-contact a:hover{ text-decoration: underline; }

  /* Contain independent visual regions to isolate reflow/paint.
     Skip interactive form regions; they need full hit-testing. */
  .gallery-wall, .faq-list, .stay-tiers, .travel-blocks,
  .dress-visual, .story-grid, .venue-card{
    contain: layout style;
  }

  /* Focus visibility */
  a:focus-visible, button:focus-visible{ outline: 2px solid var(--terracotta); outline-offset: 3px; }

  /* Coarse pointer (touch) — ensure interactive elements never ship below 44px */
  @media (pointer: coarse){
    .copy-btn, .ics-btn, .sort-btn, .guest-remove, .guest-add,
    .nav-toggle, .gallery-lightbox-close, .journey-btn, .lang-flag,
    .attend-opt, .faq-item summary{
      min-height: 44px;
    }
  }

  /* ============================================================
     Scroll-driven motion — native CSS scroll timelines.
     Progressive enhancement only: effects apply where the browser
     supports scroll/view timelines AND motion is welcome. Otherwise
     everything degrades to the static / idle-drift / reveal-on-enter
     behaviour already defined above. No JS, runs on the compositor.
     ============================================================ */

  /* A botanical hairline that grows as the page scrolls — the through-line */
  .scroll-progress{
    position: fixed; top: 0; left: 0; z-index: 150;
    width: 100%; height: 2px; transform: scaleX(0); transform-origin: 0 50%;
    background: linear-gradient(90deg, var(--sage) 0%, var(--peach) 55%, var(--terracotta) 100%);
    pointer-events: none;
  }

  @supports (animation-timeline: scroll()){
    @media (prefers-reduced-motion: no-preference){
      .scroll-progress{
        animation: progressGrow linear both;
        animation-timeline: scroll(root block);
      }
    }
  }


  @keyframes progressGrow{ from{ transform: scaleX(0); } to{ transform: scaleX(1); } }

  /* ============================================================
     Overdrive scroll — the living botanical spine + the garden light
     wash. Progressive enhancement only: effects turn on
     where scroll/view timelines exist AND motion is welcome, and fall
     back to a calm static state otherwise. Purely decorative — every
     element is aria-hidden and pointer-events:none, so nothing here
     affects reading, focus order, or the reduced-motion experience.
     ============================================================ */

  /* ---- C · raking garden light: a warm/cool wash that drifts on scroll ---- */
  .garden-light{
    position: fixed; left: 0; right: 0; top: -30vh; height: 160vh; z-index: 89;
    pointer-events: none; mix-blend-mode: soft-light; opacity: 0.5;
    background:
      radial-gradient(44% 26% at 74% 15%, rgba(128,163,194,0.5), transparent 66%),
      radial-gradient(40% 24% at 20% 72%, rgba(154,196,124,0.42), transparent 70%);
  }
  /* Same story as .paper-grain: a full-screen soft-light blend pass runs on every
     scrolled frame. Below the desktop breakpoint the wash drops to a plain
     translucent gradient tuned to read like the soft-light version. */
  @media (max-width: 1039px){
    .garden-light{ mix-blend-mode: normal; opacity: 0.2; }
  }

  /* ---- Divider ---- */
  .divider{ position: relative; }
  .divider .sprig{ position: relative; z-index: 1; }

  /* ---- A · living botanical spine: a vine that draws down the left gutter and
     sprouts a cottage-garden of flowers as you scroll ---- */
  .vine{
    position: fixed; top: 0; bottom: 0; left: clamp(12px, 2.1vw, 34px);
    width: 48px; z-index: 94; pointer-events: none; display: none;
    --vine-reveal: 0%; --vine-bleed: 72px;
    overflow: visible;
    /* Flower palette sampled from assets/Flower Inspiration.jpg (spring bouquet):
       peach + blush garden roses, butter-yellow craspedia + daisy eyes, powder
       blue delphinium, lilac scabiosa, white chamomile, fresh yellow-greens. */
    --fl-peach:#F1B892; --fl-peach-deep:#DD9068;
    --fl-blush:#ECA6B6; --fl-blush-deep:#D67E97;
    --fl-coral:#E8825A; --fl-coral-deep:#CF6237;
    --fl-yolk:#F2C230; --fl-yolk-deep:#D89A16;
    --fl-cream:#FBF2D9; --fl-white:#FCFAF2;
    --fl-blue:#A6C6E9; --fl-blue-deep:#7396C8;
    --fl-lilac:#C6B2DA; --fl-lilac-deep:#A98FC9;
    --fl-leaf:#8FA85C; --fl-leaf-deep:#5E7C3A; --fl-stem:#6E8B3D;
  }
  /* The draw window is a clip on an element that is always the full height of the
     viewport, not a box that grows to a measured height. That distinction is the
     whole fix: a measured height goes stale the moment the viewport changes size
     without a clean resize (URL bars, browser zoom, window snapping, a page that
     grows after load), and a stale height left the stem's tip hanging short of the
     bottom edge — the exact symptom this spine kept showing. A clip cannot go
     stale, so the tip lands on the bottom edge whenever the page has reached it. */
  .vine-reveal{
    position: absolute; top: 0; bottom: 0;
    left: calc(0px - var(--vine-bleed, 72px));
    right: calc(0px - var(--vine-bleed, 72px));
    overflow: hidden;
    clip-path: inset(0 0 calc(100% - var(--vine-reveal, 0%)) 0);
  }
  .vine-content{
    position: absolute; top: 0;
    left: var(--vine-bleed, 72px);
    right: var(--vine-bleed, 72px);
    height: 100%;
  }
  .vine-stem{
    position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible;
  }
  .vine-stem path.stem{
    fill: none; stroke: url(#vineGrad); stroke-width: 2; stroke-linecap: round;
    vector-effect: non-scaling-stroke;
    stroke-dasharray: 1000 1002; stroke-dashoffset: 1002;
  }
  /* Hide every path inside the vine SVG that is NOT the animated stem —
     the SVG contains ~38 decorative/generated paths that would otherwise
     render as a static ghost line behind the scroll-driven stem. */
  .vine-stem path:not(.stem){ opacity: 0; stroke: none; fill: none; }
  /* Each flower head sprouts from the stem. Placement (top / side / rotation /
     size / colour) rides on per-instance custom props; blooming is one
     scroll-driven animation whose range is set per instance via --b0/--b1.
     translate + rotate are independent transform properties, so the scale +
     opacity bloom never clobbers a flower's resting offset or orientation. */
  .vine-bloom{
    position: absolute; left: 50%; top: var(--t);
    width: calc(var(--z, 26px) * var(--vine-scale, 1));
    height: calc(var(--z, 26px) * var(--vine-scale, 1));
    margin-left: calc(var(--z, 26px) * var(--vine-scale, 1) / -2);
    translate: calc(var(--x, 0px) * var(--vine-drift, 1)) -50%; rotate: var(--r, 0deg);
    opacity: 0; scale: 0.14;
  }
  .vine-bloom svg{ display: block; width: 100%; height: 100%; overflow: visible; }

  /* pathLength=1000 + the overflow-hidden reveal window keep the fixed SVG and
     blooms from leaking endpoint artifacts before the stem has grown to them. */
  /* Vine stem + bloom animation driven by JS scroll listener (see script below).
     CSS scroll-driven animations on position:fixed full-viewport elements have
     an inverted range bug in Chromium — JS gives deterministic control. */

  /* Vine is JS-driven — no @supports (animation-timeline) gate needed.
     Show it whenever reduced-motion is not requested; JS handles the rest. */
  @media (min-width: 1040px) and (prefers-reduced-motion: no-preference){
    .vine{ display: block; }
  }

  /* Phones & tablets: slim botanical rail on the left edge.
     left must be >= 0 — iOS Safari clips position:fixed children when
     body has overflow-x:hidden, so negative left values vanish entirely. */
  @media (max-width: 1039px) and (prefers-reduced-motion: no-preference){
    .vine{ display: block; left: 0; width: 28px; --vine-scale: 0.52; --vine-drift: 0.34; }
    @media (max-width: 374px){
      .vine{ left: 0; width: 26px; --vine-drift: 0.26; }
    }
  }
  @keyframes vineDraw{ from{ stroke-dashoffset: 1002; } to{ stroke-dashoffset: 0; } }
  /* Front-loaded scale = an ease-out open (fast unfurl, gentle settle), no bounce. */
  @keyframes bloomOpen{
    0%   { opacity: 0; scale: 0.14; }
    35%  { opacity: 1; }
    60%  { scale: 0.94; }
    100% { opacity: 1; scale: 1; }
  }

  /* ---- B · right-side canopy: botanical elements trailing down the right gutter,
     parallaxing at a slower rate than the scroll-driven vine on the left.
     CSS scroll-driven animation with a static fallback. ---- */
  .canopy{
    position: fixed; top: 0; bottom: 0; right: clamp(6px, 1.6vw, 28px);
    width: 64px; z-index: 93; pointer-events: none; display: none;
    overflow: visible;
  }
  @media (min-width: 1040px) and (prefers-reduced-motion: no-preference){
    .canopy{ display: block; }
  }
  .canopy-leaf{
    position: absolute; left: 50%;
    top: calc(var(--tp, 0) * 1% + var(--ty, 0%));
    width: clamp(26px, 4vw, 52px); height: auto;
    translate: -50% -50%;
    opacity: 0; scale: 0.14;
    transition: opacity .45s var(--ease), scale .55s var(--ease);
  }
  .canopy-leaf svg{ display: block; width: 100%; height: auto; overflow: visible; }
  /* Phones & tablets: slim canopy on the right edge. */
  @media (max-width: 1039px) and (prefers-reduced-motion: no-preference){
    .canopy{ display: block; right: 0; width: 26px; }
    .canopy-leaf{ width: 20px; }
  }

  /* ---- B · mid-depth floaters: scattered botanical specks at 40-80% viewport width,
     parallaxing subtly between the vine and canopy. JS-driven. ---- */
  .depth-float{
    position: fixed; inset: 0; z-index: 92; pointer-events: none; display: none;
  }
  @media (min-width: 760px) and (prefers-reduced-motion: no-preference){
    .depth-float{ display: block; }
  }
  .depth-spec{
    position: absolute;
    left: var(--dx, 50%);
    top:  var(--dy, 50%);
    width: clamp(18px, 2.8vw, 40px); height: auto;
    translate: -50% -50%;
    opacity: 0; scale: 0.14;
    transition: opacity .5s var(--ease), scale .6s var(--ease);
  }
  .depth-spec svg{ display: block; width: 100%; height: auto; overflow: visible; }

  /* ============================================================
     Invitation opening — overdrive first-load choreography.
     A cream "letter" covers the hero at first paint; a botanical
     wax-seal presses in and draws on, then the letter unfolds to
     reveal the page. Shown ONLY under html.invite, which the <head>
     gate adds solely when JS + motion are available — no-JS and
     reduced-motion visitors never see the animation (page is visible
     beneath). On a first visit html.lang-pick also shows the letter,
     held still with the language chooser, for every visitor with JS.
     ============================================================ */
  .invitation-veil{ display:none; }
  @media (prefers-reduced-motion: reduce){
    html.invite .invitation-veil{ display:none !important; }
  }

  html.invite .invitation-veil, html.lang-pick .invitation-veil{
    display:block; position:fixed; inset:0; z-index:300;
    perspective:1600px; overflow:hidden; pointer-events:none;
  }
  html.invite .veil-panel, html.lang-pick .veil-panel{
    position:absolute; left:0; width:100%; height:50.4%;
    background:var(--cream); backface-visibility:hidden; will-change:transform, opacity;
  }
  html.invite .veil-top, html.lang-pick .veil-top{ top:0; transform-origin:50% 0%; animation:veilTop 2.2s var(--ease) forwards; }
  html.invite .veil-bottom, html.lang-pick .veil-bottom{ bottom:0; transform-origin:50% 100%; animation:veilBottom 2.2s var(--ease) forwards; }

  html.invite .veil-seal, html.lang-pick .veil-seal{
    position:absolute; inset:0; z-index:2; pointer-events:none;
    display:flex; flex-direction:column; align-items:center; justify-content:center; gap:16px;
    text-align:center; padding:0 8vw;
    animation:veilSeal 2.2s var(--ease) forwards;
  }
  html.invite .veil-sprig, html.lang-pick .veil-sprig{ width:138px; height:auto; }
  html.invite .veil-sprig .stem, html.lang-pick .veil-sprig .stem{
    stroke:var(--olive); stroke-width:1.5; fill:none; vector-effect:non-scaling-stroke;
    stroke-dasharray:140; stroke-dashoffset:140; animation:veilDraw 0.6s var(--ease) 0.15s forwards;
  }
  html.invite .veil-sprig .leaf, html.lang-pick .veil-sprig .leaf{ fill:var(--olive); opacity:0; transform-box:fill-box; transform-origin:center; }
  html.invite .veil-sprig .leaf-3, html.lang-pick .veil-sprig .leaf-3{ fill:var(--gold); }
  html.invite .veil-sprig .leaf-1, html.lang-pick .veil-sprig .leaf-1{ animation:veilBloom 0.32s var(--ease) 0.55s forwards; }
  html.invite .veil-sprig .leaf-2, html.lang-pick .veil-sprig .leaf-2{ animation:veilBloom 0.32s var(--ease) 0.63s forwards; }
  html.invite .veil-sprig .leaf-3, html.lang-pick .veil-sprig .leaf-3{ animation:veilBloom 0.32s var(--ease) 0.71s forwards; }
  html.invite .veil-mono, html.lang-pick .veil-mono{
    font-family:var(--font-script); font-weight:600; font-size:clamp(2.6rem, 7.4vw, 3.9rem);
    line-height:1; letter-spacing:0.02em; color:var(--ink);
  }
  html.invite .veil-mono em, html.lang-pick .veil-mono em{ font-family:var(--font-script); font-style:normal; color:var(--terracotta); }
  html.invite .veil-rule, html.lang-pick .veil-rule{
    width:min(200px, 44vw); height:1px; background:var(--sage);
    transform:scaleX(0); transform-origin:50% 50%; animation:veilRule 0.6s var(--ease) 0.5s forwards;
  }
  html.invite .veil-date, html.lang-pick .veil-date{
    font-family:var(--font-sans); font-size:var(--text-label); letter-spacing:0.28em;
    text-transform:uppercase; color:var(--sage-deep);
  }

  /* ---- Language chooser (first visit) ----
     The letter waits, fully drawn and still, until a language is picked.
     Shown with or without motion — it is the one functional step here. */
  html.lang-pick body{ overflow:hidden; }
  html.lang-pick .invitation-veil{ pointer-events:auto; }
  html.lang-pick .veil-top, html.lang-pick .veil-bottom{ animation:none; transform:none; opacity:1; }
  html.lang-pick .veil-seal{ animation:none; opacity:1; transform:none; pointer-events:auto; }
  html.lang-pick .veil-sprig .stem{ animation:none; stroke-dashoffset:0; }
  html.lang-pick .veil-sprig .leaf{ animation:none; opacity:1; }
  html.lang-pick .veil-rule{ animation:none; transform:scaleX(1); }
  /* Choice made: the seal fades and the letter unfolds from where it rests. */
  html.invite.lang-chosen .veil-top{ animation:veilTopOpen 0.9s var(--ease) 0.3s both; }
  html.invite.lang-chosen .veil-bottom{ animation:veilBottomOpen 0.9s var(--ease) 0.3s both; }
  html.invite.lang-chosen .veil-seal{ animation:veilSealOut 0.45s var(--ease) both; }
  html.invite.lang-chosen .veil-sprig .stem{ animation:none; stroke-dashoffset:0; }
  html.invite.lang-chosen .veil-sprig .leaf{ animation:none; opacity:1; }
  html.invite.lang-chosen .veil-rule{ animation:none; transform:scaleX(1); }
  .veil-lang{ display:none; }
  html.lang-pick .veil-lang, html.lang-chosen .veil-lang{
    display:flex; flex-direction:column; align-items:center; gap:18px; margin-top:18px;
  }
  .veil-lang-prompt{
    display:flex; flex-direction:column; align-items:center; gap:6px; margin:0; max-width:none;
    font-family:var(--font-sans); font-size:var(--text-label); font-weight:500;
    letter-spacing:var(--tracking-label); text-transform:uppercase; color:var(--gold-deep);
  }
  .veil-lang-prompt span{ color:var(--ink-soft); letter-spacing:0.18em; }
  .veil-lang-options{ display:flex; flex-wrap:wrap; justify-content:center; gap:16px; }
  .veil-lang-btn{
    display:flex; flex-direction:column; align-items:center; gap:10px;
    min-width:136px; min-height:44px; padding:16px 24px 14px; cursor:pointer;
    border:1px solid var(--line-gold); border-radius:16px; background:rgba(255,255,255,0.72);
    font-family:var(--font-serif); font-size:1.12rem; color:var(--ink);
    box-shadow:var(--shadow-soft);
    transition:transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease), background 0.3s var(--ease);
  }
  .veil-lang-btn img{
    width:64px; height:40px; object-fit:cover; border-radius:6px;
    box-shadow:0 0 0 1px rgba(46,50,32,0.12), 0 8px 16px -10px rgba(46,50,32,0.55);
  }
  .veil-lang-btn:hover{ transform:translateY(-3px); background:#FFFFFF; border-color:var(--terracotta); box-shadow:var(--shadow-lift); }
  .veil-lang-btn:focus-visible{ outline:2px solid var(--terracotta); outline-offset:3px; }
  @media (prefers-reduced-motion: reduce){ .veil-lang-btn:hover{ transform:none; } }
  @keyframes veilTopOpen{
    from{ transform:rotateX(0) translateY(0); opacity:1; }
    to{ transform:rotateX(18deg) translateY(-100%); opacity:0; }
  }
  @keyframes veilBottomOpen{
    from{ transform:rotateX(0) translateY(0); opacity:1; }
    to{ transform:rotateX(-18deg) translateY(100%); opacity:0; }
  }
  @keyframes veilSealOut{
    from{ opacity:1; transform:none; }
    to{ opacity:0; transform:scale(1.06); }
  }
  @keyframes veilTop{
    0%, 70%{ transform:rotateX(0) translateY(0); opacity:1; }
    100%{ transform:rotateX(18deg) translateY(-100%); opacity:0; }
  }
  @keyframes veilBottom{
    0%, 70%{ transform:rotateX(0) translateY(0); opacity:1; }
    100%{ transform:rotateX(-18deg) translateY(100%); opacity:0; }
  }
  @keyframes veilSeal{
    0%{ opacity:0; transform:translateY(8px) scale(0.9); }
    14%{ opacity:1; transform:translateY(0) scale(1); }
    68%{ opacity:1; transform:translateY(0) scale(1); }
    82%{ opacity:0; transform:translateY(0) scale(1.06); }
    100%{ opacity:0; }
  }
  @keyframes veilDraw{ to{ stroke-dashoffset:0; } }
  @keyframes veilBloom{ from{ opacity:0; transform:scale(0.2); } to{ opacity:1; transform:scale(1); } }
  @keyframes veilRule{ to{ transform:scaleX(1); } }
  /* ---------- Aesthetic refinement pass ----------
     A quieter editorial frame: one floating navigation island, stronger type
     hierarchy, and a more deliberate surface rhythm across the invitation. */
  nav{
    top:18px; left:50%; right:auto; width:min(calc(100% - 36px), 1180px);
    transform:translateX(-50%); padding:12px 22px;
    border:1px solid rgba(128,163,194,0.28); border-radius:999px;
    background:rgba(239,246,250,0.78);
    box-shadow:0 18px 48px -30px rgba(67,98,126,0.48), inset 0 1px 0 rgba(255,255,255,0.68);
  }
  nav.scrolled{
    top:12px; transform:translateX(-50%); padding:10px 22px;
    border-bottom-color:rgba(128,163,194,0.42);
    background:rgba(239,246,250,0.92);
  }
  .nav-links{ gap:clamp(14px, 1.9vw, 30px); }
  .nav-links a{ color:var(--ink); }
  .nav-links a.active{ color:var(--terracotta); }
  .nav-links a.active::after{ transform: scaleX(1); }
  .section-inner{ max-width:1180px; }
  .section-title{ font-size:clamp(2.55rem, 5.2vw, 4.15rem); line-height:0.98; letter-spacing:-0.035em; }
  .eyebrow{ background:rgba(255,255,255,0.30); }
  .story-copy p, .honeymoon-lead, .faq-lead{ max-width:60ch; }
  .story-grid{ gap:clamp(44px, 7vw, 108px); }
  .story-visual{ transform:rotate(1.2deg); }
  .story-visual:hover{ transform:rotate(0deg) translateY(-5px); }
  .schedule, .travel-blocks{ max-width:960px; }
  .gallery-wall{ gap:clamp(28px, 4vw, 58px); }
  .gw-item figcaption{ letter-spacing:0.01em; }
  .give-card, .rsvp-success{ position:relative; overflow:hidden; }
  .give-card::after, .rsvp-success::after{ content:''; position:absolute; width:220px; height:220px; right:-90px; top:-110px; border:1px solid rgba(128,163,194,0.22); border-radius:50%; pointer-events:none; }

  .skip-link{ position:fixed; left:16px; top:max(16px, env(safe-area-inset-top, 0px)); z-index:310; transform:translateY(-140%); padding:10px 16px; border-radius:999px; background:var(--ink); color:var(--cream); text-decoration:none; transition:transform .35s var(--ease); }
  .skip-link:focus{ transform:none; }
  @media (max-width:760px){ nav{ top:10px; width:calc(100% - 20px); padding:12px 16px; } nav.scrolled{ top:10px; padding:12px 16px; } .nav-links{ gap:28px; } }
  @media (prefers-reduced-motion: reduce){ .story-visual, .story-visual:hover{ transform:none; } }
   /* Interactive European journey map — satellite flyover treatment */
   #journeyLeafletMap{ position:absolute; inset:0; z-index:1; background:#0b3550; }
  /* SVG illustrated map hides only once Leaflet has loaded and drawn on top.
     JS adds .leaflet-ready to the stage when the interactive map initialises. */
  #storymap.leaflet-ready .journey-map-camera{ display:none; }
   #storymap .journey-map-stage{ border-color:rgba(255,255,255,.32); background:#0b3550; box-shadow:0 32px 90px -42px rgba(7,25,41,.82); }
   #storymap .journey-map-stage::before{ z-index:4; background:linear-gradient(180deg, rgba(3,18,34,.12), transparent 38%, rgba(3,18,34,.34)); }
   #storymap .leaflet-container{ height:100%; width:100%; background:#0b3550; font-family:var(--font-sans); }
   #storymap .leaflet-tile-pane{ filter:saturate(1.12) contrast(1.04) brightness(.92); transition:filter .7s ease; }
   #storymap .leaflet-overlay-pane svg{ filter:drop-shadow(0 2px 1px rgba(90,0,0,.5)); }
  /* While the map is scroll-driven it pans every frame; filters on the tile and
     route panes mean re-filtering all of it every frame too. Dropped below the
     desktop breakpoint — only the subtle grade and a route shadow are lost. */
  @media (max-width: 1039px){
    #storymap .leaflet-tile-pane{ filter:none; transition:none; }
    #storymap .leaflet-overlay-pane svg{ filter:none; }
  }
  #storymap .leaflet-control-zoom{ display:none; border:0; box-shadow:0 12px 30px -18px rgba(3,18,34,.9); }
  #storymap .leaflet-control-zoom a{ width:34px; height:34px; line-height:32px; background:rgba(239,246,250,.9); color:var(--ink); border:0; }
  #storymap .leaflet-control-zoom a:first-child{ border-radius:10px 10px 0 0; }
  #storymap .leaflet-control-zoom a:last-child{ border-radius:0 0 10px 10px; }
  #storymap .leaflet-control-attribution{ background:rgba(3,18,34,.58); color:rgba(239,246,250,.72); }
  #storymap .leaflet-control-attribution a{ color:#d4e7f3; }
  .journey-map-pin{ position:relative; display:grid; place-items:center; width:17px; height:17px; border:3px solid #fff; border-radius:50%; background:#e7192c; color:#fff; box-shadow:0 5px 16px rgba(3,18,34,.5); }
  .journey-map-pin::after{ content:""; position:absolute; inset:-8px; border:1px solid rgba(231,25,44,.55); border-radius:50%; animation:journeyPinPulse 2s ease-out infinite; }
  .journey-map-pin span{ display:none; }
  .journey-map-label{ display:grid; grid-template-columns:auto 1fr; align-items:center; gap:7px 10px; min-width:190px; padding:11px 15px; border:0; border-radius:9px; background:#fff; color:#20242a; font-family:var(--font-sans); font-size:10px; letter-spacing:.12em; text-transform:uppercase; text-align:left; box-shadow:0 15px 32px rgba(3,18,34,.25); transform:rotate(-1.4deg); }
  .journey-map-label::before{ display:none; }
  .journey-map-label-flag{ grid-row:span 2; font-size:27px; line-height:1; filter:saturate(1.15); }
  .journey-map-label strong{ display:block; font-family:var(--font-sans); font-size:15px; line-height:1.05; letter-spacing:.04em; text-transform:uppercase; font-weight:600; }
  .journey-map-label small{ display:block; color:#69717a; font-size:9px; letter-spacing:.16em; line-height:1.2; }
  .leaflet-tooltip.journey-tooltip{ padding:0; border:0; background:transparent; box-shadow:none; }
  .leaflet-tooltip.journey-tooltip::before{ display:none; }
   .journey-vehicle-icon{ position:relative; display:grid; place-items:center; width:54px; height:40px; border:0; border-radius:0; background:transparent; color:#f6f7f4; filter:drop-shadow(0 8px 7px rgba(3,18,34,.58)); transform-origin:center; }
  .journey-vehicle-icon svg{ width:48px; height:38px; display:block; fill:currentColor; stroke:#263544; stroke-width:.7; stroke-linecap:round; stroke-linejoin:round; }
  .journey-vehicle-icon img{ width:58px; height:58px; display:block; object-fit:contain; }
   .journey-vehicle-icon.car{ color:#e9eee7; transform:rotate(-7deg); }
   .journey-vehicle-icon.plane{ color:#eef0eb; transform:rotate(-18deg) scale(1.18); }
   .journey-vehicle-icon.cruise{ color:#f0f0ea; transform:scale(1.12); }
   @keyframes journeyPinPulse{ 0%{ opacity:.8; transform:scale(.55); } 100%{ opacity:0; transform:scale(1.3); } }
  .journey-stage-card > :not(.journey-stage-image){ position:relative; z-index:1; }
  .journey-stage-image{ position:absolute; inset:0; z-index:0; width:100%; height:100%; object-fit:cover; opacity:.56; filter:saturate(.88) contrast(.98); }
  .journey-stage-card:has(.journey-stage-image)::after{ content:''; position:absolute; inset:0; z-index:0; background:linear-gradient(180deg, rgba(239,246,250,.04), rgba(239,246,250,.74) 72%); pointer-events:none; }
  @media (max-width:820px){ #storymap .journey-map-stage{ min-height:0; height:clamp(210px, 33vh, 300px); } .journey-map-label{ min-width:174px; } }
