/* ══════════════════════════════════════════════════════════════
   Paged wedding invitation — full-screen scroll-snap cards
   Dark theme: every page carries the deep maroon/ember gradient.
   ══════════════════════════════════════════════════════════════ */

:root {
  /* Raw palette */
  --gold:       #c9a84c;
  --gold-light: #e8c97e;
  --gold-pale:  #f5e6c8;
  --deep-red:   #8b1a1a;
  --maroon:     #6b0f1a;
  --saffron:    #e8720c;
  --ivory:      #fdf8f0;
  --cream:      #faf0dc;
  --dark:       #1a0a00;
  --text:       #2c1505;

  /* ── Semantic tokens ───────────────────────────────────────
     Each page sets --glow / --glow-mid / --accent via a .theme-*
     class. Every theme fades out to the SAME --base at the page
     edges, so stacked pages join without a visible band.
     Glow centres are kept at luminance <= 0.095 so gold ink stays
     above 4.5:1 where the colour is strongest — that's the real
     constraint on how bright a theme can go. */
  --base:       #fdf5f1;             /* overscroll behind the deck */
  --glow-mid:   #fbe6e6;             /* gradient top    (overridden) */
  --glow:       #f2c9c9;             /* gradient middle (overridden) */
  --glow-deep:  #e8b3b3;             /* gradient bottom (overridden) */
  --accent:     #8a2b2b;             /* dividers, eyebrows */

  --ink:        #5a332f;             /* body copy      >= 6.7:1 */
  --ink-strong: var(--maroon);       /* headings       >= 7.6:1 */
  --ink-soft:   #694e46;             /* captions       >= 4.7:1 */
  --panel:      rgba(255, 255, 255, .58);  /* translucent cards */
  --hairline:   rgba(140, 60, 60, .30);
  --hairline-soft: rgba(140, 60, 60, .16);

  --display: "Cinzel", Georgia, serif;
  --serif:   "Cormorant Garamond", Georgia, serif;
  --script:  "Great Vibes", cursive;
  --sans:    "Lato", -apple-system, "Segoe UI", sans-serif;
}

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

html { scroll-behavior: smooth; background: var(--base); }

body {
  font-family: var(--sans);
  font-weight: 300;
  background: var(--base);          /* so overscroll never flashes light */
  color: var(--ink);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* Flat base behind everything, so rubber-band overscroll never flashes
   light and any gap between themed pages reads as the shared edge colour. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: var(--base);
}

img { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.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;
}

.noscript {
  padding: 3rem 1.5rem; text-align: center;
  font-family: var(--serif); font-size: 1.15rem; color: var(--ink);
}

/* ══ Snap container ══════════════════════════════════════════ */
.snap-wrap {
  height: 100dvh;
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
}
.snap-wrap::-webkit-scrollbar { display: none; }

.page {
  scroll-snap-align: start;
  min-height: 100dvh;
  width: 100%;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: 4.5rem 1.4rem 4rem;
  text-align: center;
  color: var(--ink);
  /* Full-bleed per-page gradient. Earlier this faded to a shared --base at
     the edges to hide the page joins, but that washed every page toward the
     same cream and bled neighbours into each other. Each page now owns its
     colour edge to edge; the boundary only shows mid-scroll, and scroll-snap
     means guests rest on whole pages. */
  background:
    radial-gradient(130% 70% at 50% 32%, rgba(255, 255, 255, .22), transparent 62%),
    linear-gradient(168deg, var(--glow-mid) 0%, var(--glow) 52%, var(--glow-deep) 100%);
}

/* The family page keeps its own flow rules (content can exceed one screen) */
.page--dark { justify-content: flex-start; overflow-y: auto; }

/* ══ Per-event themes ════════════════════════════════════════
   Add `theme: "haldi"` to an event in config.js to pick one
   explicitly; otherwise the event's `icon` chooses it. */

/* ── Per-page palettes ────────────────────────────────────────
   Each theme owns its gradient AND its ink, so daytime pages run
   dark-on-light and the two night functions run light-on-dark.
   Every value below was checked to clear WCAG AA against all three
   of its own gradient stops, not just the mid tone. */

/* Blush pink, picking up the envelope the guest just opened */
.theme-title {
  --glow-mid: #fbe6e6; --glow: #f2c9c9; --glow-deep: #e8b3b3;
  --ink: #5a332f; --ink-strong: #6b0f1a; --ink-soft: #5e4238; --accent: #8a2b2b;
}
/* Sage and cream — matches the Haldi dress code (sage / pastel green) */
.theme-haldi {
  --glow-mid: #eef4e4; --glow: #dfe8cc; --glow-deep: #cbd8b0;
  --ink: #3c4423; --ink-strong: #2c3614; --ink-soft: #4a5430; --accent: #45551c;
}
/* Night function: dark aubergine stage, white glitter */
.theme-sangeet {
  --glow-mid: #4a1340; --glow: #2e0a2b; --glow-deep: #170519;
  --ink: #f7e6f3; --ink-strong: #fdeef9; --ink-soft: #dcc0d6; --accent: #f0a8d8;
  --panel: rgba(0, 0, 0, .28);
  --hairline: rgba(240, 168, 216, .34);
}
/* Pushed firmly onto the red side */
.theme-vivah,
.theme-phere,
.theme-phera,
.theme-pheras {
  --glow-mid: #fad3cc; --glow: #f2a89e; --glow-deep: #eb978c;
  --ink: #5c2a26; --ink-strong: #5a0f14; --ink-soft: #5c2a26; --accent: #7d1410;
}
/* Night procession: deep blue sky with fireworks */
.theme-barat,
.theme-baraat {
  --glow-mid: #1d3f6e; --glow: #142c52; --glow-deep: #0a1830;
  --ink: #e8eef8; --ink-strong: #f4f8ff; --ink-soft: #bcc9de; --accent: #9ec9ee;
  --panel: rgba(0, 0, 0, .26);
  --hairline: rgba(158, 201, 238, .34);
}
.theme-mehndi {
  --glow-mid: #d8e9c4; --glow: #bcd79e; --glow-deep: #a3c47f;
  --ink: #2c3f14; --ink-strong: #223310; --ink-soft: #3a5020; --accent: #3f5a18;
}
.theme-reception {
  --glow-mid: #1a3d52; --glow: #122b3c; --glow-deep: #0a1a26;
  --ink: #e4eff6; --ink-strong: #f2f8fc; --ink-soft: #b6c9d6; --accent: #a9d8ef;
  --panel: rgba(0, 0, 0, .26);
  --hairline: rgba(169, 216, 239, .34);
}
.theme-blessings {
  --glow-mid: #faeedb; --glow: #f3e0c4; --glow-deep: #e8cea6;
  --ink: #5a332f; --ink-strong: #6b0f1a; --ink-soft: #694e46; --accent: #664705;
}
.theme-family {
  --glow-mid: #fbeae6; --glow: #f4d9d2; --glow-deep: #e9c2b8;
  --ink: #5a332f; --ink-strong: #6b0f1a; --ink-soft: #694e46; --accent: #8a2b2b;
}
.theme-rsvp {
  --glow-mid: #fbf0e5; --glow: #f5e3d2; --glow-deep: #ebd3bb;
  --ink: #5a332f; --ink-strong: #6b0f1a; --ink-soft: #694e46; --accent: #664705;
}

/* The cross-hatch is drawn in dark ink, which vanishes on the night
   pages — give those a light version instead. */
.theme-sangeet .pattern-bg,
.theme-barat .pattern-bg,
.theme-baraat .pattern-bg,
.theme-reception .pattern-bg {
  opacity: .06;
  background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/svg%3E");
}

/* ── Baraat fireworks ────────────────────────────────────────
   Two bursts built from box-shadow spokes, scaled and faded on a
   loop with offset delays. Pure CSS, no extra DOM. */
.theme-barat::before, .theme-barat::after,
.theme-baraat::before, .theme-baraat::after {
  content: "";
  position: absolute; z-index: 3; pointer-events: none;
  width: 4px; height: 4px; border-radius: 50%;
  background: transparent;
  box-shadow:
      0   -34px 0 0 #ffd98a,  24px -24px 0 0 #ff9ec4,  34px   0px 0 0 #9fe0e6,
     24px  24px 0 0 #fff3c0,   0px  34px 0 0 #ffd98a, -24px  24px 0 0 #ff9ec4,
    -34px   0px 0 0 #9fe0e6, -24px -24px 0 0 #fff3c0,
      0   -56px 0 0 #fff6de,  40px -40px 0 0 #ffd98a,  56px   0px 0 0 #ff9ec4,
     40px  40px 0 0 #9fe0e6,   0px  56px 0 0 #fff3c0, -40px  40px 0 0 #ffd98a,
    -56px   0px 0 0 #fff6de, -40px -40px 0 0 #ff9ec4;
  animation: firework 3s ease-out infinite;
}
.theme-barat::before, .theme-baraat::before { left: 22%; top: 20%; animation-delay: .3s; }
.theme-barat::after,  .theme-baraat::after  { left: 76%; top: 15%; animation-delay: 1.7s; }

@keyframes firework {
  0%   { transform: scale(.08); opacity: 0; }
  10%  { opacity: 1; }
  65%  { transform: scale(1);   opacity: .85; }
  100% { transform: scale(1.4); opacity: 0; }
}

/* ── Sangeet glitter ─────────────────────────────────────────
   White sparkles against the night stage. The scattered dot field sits on
   its own .sparkles element so both page pseudo-elements are free to carry
   a burst each, mirroring Baraat. */
.sparkles { position: absolute; inset: 0; z-index: 3; pointer-events: none; }

.theme-sangeet .sparkles {
  /* Solid-core dots. An earlier version ramped to transparent across the
     dot's own 1.5px radius, so no pixel was ever opaque and nothing showed.
     A hard colour stop before the fade is what makes them read.
     This lives on its own element rather than on .pattern-bg, because that
     element's 6% opacity would fade these dots away with it. */
  background-image:
    radial-gradient(circle 2.5px at 12% 18%, #ffffff 0 55%, transparent 100%),
    radial-gradient(circle 2px   at 78% 12%, #ffe9fb 0 55%, transparent 100%),
    radial-gradient(circle 3px   at 34% 76%, #fff6c9 0 55%, transparent 100%),
    radial-gradient(circle 2px   at 88% 62%, #ffffff 0 55%, transparent 100%),
    radial-gradient(circle 2.5px at 22% 48%, #ffd9f4 0 55%, transparent 100%),
    radial-gradient(circle 3px   at 64% 34%, #ffffff 0 55%, transparent 100%),
    radial-gradient(circle 2px   at 52% 88%, #fff6c9 0 55%, transparent 100%),
    radial-gradient(circle 2.5px at 8%  70%, #ffffff 0 55%, transparent 100%),
    radial-gradient(circle 2px   at 94% 86%, #ffe9fb 0 55%, transparent 100%),
    radial-gradient(circle 3px   at 44% 8%,  #ffffff 0 55%, transparent 100%),
    radial-gradient(circle 2px   at 60% 60%, #ffffff 0 55%, transparent 100%),
    radial-gradient(circle 2.5px at 30% 30%, #fff6c9 0 55%, transparent 100%);
  animation: twinkle 2.6s ease-in-out infinite;
}

/* Silver-white glitter bursts, same mechanism as the Baraat fireworks.
   Two of them, one each side, matching Baraat. */
.theme-sangeet::before, .theme-sangeet::after {
  content: "";
  position: absolute; z-index: 3; pointer-events: none;
  width: 4px; height: 4px; border-radius: 50%;
  background: transparent;
  box-shadow:
      0   -30px 0 0 #ffffff,  21px -21px 0 0 #ffe9fb,  30px   0px 0 0 #fff6c9,
     21px  21px 0 0 #ffffff,   0px  30px 0 0 #ffd9f4, -21px  21px 0 0 #ffffff,
    -30px   0px 0 0 #fff6c9, -21px -21px 0 0 #ffe9fb,
      0   -50px 0 0 #ffffff,  35px -35px 0 0 #fff6c9,  50px   0px 0 0 #ffffff,
     35px  35px 0 0 #ffe9fb,   0px  50px 0 0 #ffffff, -35px  35px 0 0 #ffd9f4,
    -50px   0px 0 0 #fff6c9, -35px -35px 0 0 #ffffff;
  animation: firework 2.8s ease-out infinite;
}
.theme-sangeet::before { left: 24%; top: 24%; animation-delay: .5s; }
.theme-sangeet::after  { left: 78%; top: 17%; animation-delay: 1.9s; }

/* ══ Decorative layers ═══════════════════════════════════════ */
.pattern-bg {
  position: absolute; inset: 0; z-index: 1; opacity: .08; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%238c3c3c'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/svg%3E");
}

.gold-frame {
  position: absolute; inset: 10px; z-index: 4; pointer-events: none;
  border: 1px solid var(--hairline);
}
.gold-frame::before, .gold-frame::after {
  content: "◆"; position: absolute; left: 50%; translate: -50% 0;
  color: var(--accent); opacity: .55; font-size: .7rem; line-height: 1;
}
.gold-frame::before { top: -.55rem; }
.gold-frame::after  { bottom: -.55rem; }

.corner-svg {
  position: absolute; width: 85px; height: 85px;
  opacity: .5; z-index: 5; pointer-events: none;
  color: var(--accent);
}
.corner-svg.tl { top: 0; left: 0; }
.corner-svg.tr { top: 0; right: 0; transform: scaleX(-1); }
.corner-svg.bl { bottom: 0; left: 0; transform: scaleY(-1); }
.corner-svg.br { bottom: 0; right: 0; transform: scale(-1, -1); }

.ganesh-top {
  position: absolute; top: .8rem; left: 50%; translate: -50% 0;
  width: 66px; z-index: 30; color: var(--accent);
  animation: ganeshGlow 4s ease-in-out infinite;
}

/* ══ Dividers ════════════════════════════════════════════════ */
.divider {
  display: flex; align-items: center; justify-content: center; gap: .7rem;
  width: 100%; max-width: 260px; margin: .5rem auto;
}
.divider-line { flex: 1; height: 1px; background: linear-gradient(90deg, transparent, var(--accent), transparent); }
.divider-gem { width: 6px; height: 6px; background: var(--accent); rotate: 45deg; flex-shrink: 0; }
.hero-heart { font-size: 1.4rem; line-height: 1; animation: heartbeat 2.4s ease-in-out infinite; }

/* ══ Page 1 — title ══════════════════════════════════════════ */
.hero-inner { position: relative; z-index: 10; max-width: 680px; }

.hero-badge {
  display: inline-block;
  font-family: var(--sans); font-size: .64rem; font-weight: 400;
  letter-spacing: .34em; text-transform: uppercase;
  color: var(--accent);
  border: 1px solid var(--hairline);
  padding: .5em 1.4em; margin-bottom: 1.6rem;
  background: var(--panel);
}

.hero-name {
  font-family: var(--display); font-weight: 600;
  font-size: clamp(1.85rem, 7.2vw, 3.1rem);
  line-height: 1.16; letter-spacing: .02em;
  color: var(--ink-strong);
}
.hero-lineage {
  font-family: var(--serif); font-size: clamp(.86rem, 2.9vw, 1rem);
  line-height: 1.75; color: var(--ink); opacity: .9;
  margin-top: .45rem;
}
.lineage-title { font-size: .82em; letter-spacing: .05em; color: var(--accent); }

.hero-title {
  font-family: var(--script); font-weight: 400;
  font-size: clamp(2.3rem, 9vw, 3.6rem);
  color: var(--accent); line-height: 1.2; margin-top: .4rem;
}
.hero-title--top { margin-top: 0; margin-bottom: 1.1rem; }

.hero-date {
  font-family: var(--display); font-weight: 600;
  font-size: clamp(1.05rem, 4vw, 1.4rem);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-strong); margin-top: 1rem;
}

/* Countdown */
.countdown {
  display: flex; align-items: flex-start; justify-content: center;
  gap: clamp(.35rem, 2vw, .9rem);
  margin-top: 1.3rem;
}
.cd-unit { min-width: clamp(44px, 13vw, 62px); }
.cd-num {
  display: block; font-family: var(--display); font-weight: 600;
  font-size: clamp(1.35rem, 5.4vw, 2rem);
  color: var(--ink-strong); line-height: 1; font-variant-numeric: tabular-nums;
}
.cd-label {
  display: block; margin-top: .3rem;
  font-size: .54rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--ink-soft);
}
.cd-sep { font-family: var(--display); font-size: clamp(1.1rem, 4vw, 1.6rem); color: var(--accent); line-height: 1; }
.countdown--done { font-family: var(--script); font-size: clamp(1.6rem, 7vw, 2.4rem); color: var(--accent); }

/* Scroll button */
.page-nav-btn {
  position: absolute; bottom: 1.5rem; left: 50%; translate: -50% 0;
  z-index: 30; display: flex; flex-direction: column; align-items: center; gap: .4rem;
  animation: bounce 2.2s ease-in-out infinite;
}
.pnb-ring {
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--hairline);
  display: grid; place-items: center; color: var(--accent);
}
.pnb-ring svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 2; }
.pnb-label { font-size: .56rem; letter-spacing: .26em; text-transform: uppercase; color: var(--ink-soft); }

/* ══ Event pages ═════════════════════════════════════════════ */
.event-inner { position: relative; z-index: 10; max-width: 560px; display: grid; gap: .55rem; justify-items: center; }

.event-tag {
  font-size: .6rem; letter-spacing: .3em; text-transform: uppercase;
  color: var(--accent); margin-bottom: .2rem;
}
.event-name {
  font-family: var(--display); font-weight: 900;
  font-size: clamp(2.4rem, 11vw, 4rem);
  color: var(--ink-strong); line-height: 1; letter-spacing: .02em;
}
.event-subtitle { font-family: var(--script); font-size: clamp(1.3rem, 5.2vw, 1.85rem); color: var(--accent); }

.event-img-frame {
  width: clamp(116px, 32vw, 158px); aspect-ratio: 1; border-radius: 50%;
  padding: 6px; margin: .5rem 0;
  background: linear-gradient(135deg, var(--gold), var(--gold-pale), var(--gold));
  box-shadow: 0 10px 26px -12px rgba(120, 60, 50, .45);
}
.event-img-inner {
  width: 100%; height: 100%; border-radius: 50%; overflow: hidden;
  background: var(--glow-mid); display: grid; place-items: center;
}
.event-img-inner img { width: 100%; height: 100%; object-fit: cover; }
.event-icon { width: 46%; height: 46%; color: var(--accent); opacity: .95; }

.event-desc {
  font-family: var(--serif); font-style: italic;
  font-size: clamp(.94rem, 3.2vw, 1.1rem); line-height: 1.7;
  color: var(--ink); opacity: .92; white-space: pre-line;
  max-width: 34ch;
}

.event-stamp {
  display: grid; gap: .5rem; justify-items: center;
  margin-top: .7rem; padding: 1rem 1.3rem;
  border: 1px solid var(--hairline);
  background: var(--panel);
}
.event-datetime-row { display: flex; align-items: center; gap: .55rem; justify-content: center; }
.edt-icon { font-size: .95rem; line-height: 1; flex-shrink: 0; }
.edt-text { font-family: var(--serif); font-size: clamp(.9rem, 3vw, 1.05rem); color: var(--ink); }
.event-datetime-row a { color: var(--accent); text-decoration: none; border-bottom: 1px solid var(--hairline); }
.event-datetime-row a:hover { border-bottom-color: var(--accent); }

.dress-code { display: grid; gap: .2rem; margin-top: .55rem; }
.dress-label { font-size: .56rem; letter-spacing: .26em; text-transform: uppercase; color: var(--ink-soft); }
.dress-value { font-family: var(--serif); font-size: 1rem; color: var(--accent); }

.event-cal {
  margin-top: .9rem; font-size: .6rem; letter-spacing: .24em; text-transform: uppercase;
  color: var(--accent); text-decoration: none;
  border-bottom: 1px solid var(--hairline); padding-bottom: 2px;
}
.event-cal:hover { border-bottom-color: var(--accent); }

/* ══ Blessings page ══════════════════════════════════════════ */
.blessings-inner { position: relative; z-index: 10; max-width: 880px; width: 100%; }
.blessings-title {
  font-family: var(--display); font-weight: 600;
  font-size: clamp(1.3rem, 5vw, 1.9rem);
  letter-spacing: .08em; color: var(--ink-strong); margin-bottom: 1.6rem;
}
.families-grid { display: grid; gap: 1.1rem; grid-template-columns: 1fr; align-items: stretch; }
@media (min-width: 720px) { .families-grid { grid-template-columns: 1fr auto 1fr; } }

.families-divider { display: grid; place-items: center; font-size: 1.5rem; line-height: 1; }
@media (max-width: 719px) { .families-divider { padding: .2rem 0; } }

.family-col-box {
  border: 1px solid var(--hairline);
  background: var(--panel);
  padding: 1.5rem 1.2rem;
  display: grid; gap: .9rem; align-content: start;
}
.family-col-header {
  font-size: .6rem; letter-spacing: .28em; text-transform: uppercase;
  color: var(--accent);
}
.family-col-sep { height: 1px; background: linear-gradient(90deg, transparent, var(--accent), transparent); }
.pc-name { font-family: var(--serif); font-size: clamp(1rem, 3.4vw, 1.18rem); line-height: 1.5; color: var(--ink); }
.gp-note { display: block; font-size: .8em; color: var(--accent); }

.blessings-footer { margin-top: 1.7rem; display: grid; gap: .5rem; }
.fam-note { font-family: var(--script); font-size: clamp(1.25rem, 4.6vw, 1.7rem); color: var(--accent); }
.blessings-meta { font-family: var(--serif); font-size: clamp(.86rem, 2.9vw, 1rem); color: var(--ink-soft); }

/* ══ Extended family page ════════════════════════════════════ */
.family-page-inner { position: relative; z-index: 10; max-width: 760px; width: 100%; padding-block: 1rem; }
.family-page-title {
  font-family: var(--display); font-weight: 600;
  font-size: clamp(1.25rem, 4.8vw, 1.8rem);
  letter-spacing: .1em; color: var(--ink-strong); margin-bottom: 1.4rem;
}
.fam-section { margin-bottom: 1.5rem; }
.fam-section-head {
  font-size: .64rem; letter-spacing: .26em; text-transform: uppercase;
  color: var(--accent); margin-bottom: .7rem;
  display: flex; align-items: center; gap: .6rem; justify-content: center;
}
.fam-section-head::before, .fam-section-head::after {
  content: ""; flex: 1; max-width: 70px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(140, 60, 60, .45), transparent);
}
.fam-names { display: grid; gap: .35rem; }
.fam-name-row { font-family: var(--serif); font-size: clamp(.92rem, 3.1vw, 1.06rem); color: var(--ink); opacity: .95; }
.fam-kids {
  font-family: var(--serif); font-size: clamp(.88rem, 3vw, 1rem);
  color: var(--accent); opacity: .9; margin-top: .4rem; letter-spacing: .02em;
}

/* ══ RSVP page (optional) ════════════════════════════════════ */
.rsvp-inner { position: relative; z-index: 10; max-width: 480px; width: 100%; }
.rsvp-title {
  font-family: var(--display); font-weight: 600; letter-spacing: .14em;
  font-size: clamp(1.3rem, 5vw, 1.9rem); color: var(--ink-strong);
}
.rsvp-note { font-family: var(--serif); font-size: .96rem; color: var(--ink-soft); margin-top: .4rem; }
.form { display: grid; gap: .9rem; margin-top: 1.4rem; text-align: left; }
.field { display: grid; gap: .3rem; border: 0; }
.field > label, .field legend {
  font-size: .56rem; letter-spacing: .22em; text-transform: uppercase;
  color: var(--ink-soft);
}
.form input[type="text"], .form input[type="email"], .form input[type="tel"],
.form input[type="number"], .form textarea {
  width: 100%; font-family: var(--sans); font-size: .98rem; font-weight: 300;
  color: var(--ink);
  background: rgba(255, 255, 255, .78);
  border: 1px solid var(--hairline); border-radius: 0;
  padding: .65rem .8rem;
}
.form input::placeholder, .form textarea::placeholder { color: rgba(90, 51, 47, .5); }
.form input:focus, .form textarea:focus {
  border-color: var(--accent); outline: none; background: #fff;
}
.form input[aria-invalid="true"] { border-color: #b4342b; }
.radios { display: flex; flex-wrap: wrap; gap: .4rem 1.3rem; padding-top: .2rem; }
.radios label {
  display: flex; align-items: center; gap: .45rem;
  font-size: .95rem; letter-spacing: 0; text-transform: none; color: var(--ink);
}
.radios input { accent-color: var(--accent); }
.err { color: #b4342b; font-size: .78rem; min-height: 1.1em; }
.btn {
  font-size: .64rem; letter-spacing: .24em; text-transform: uppercase;
  padding: .95em 2.4em; border: 1px solid var(--maroon);
  background: var(--maroon); color: var(--ivory); transition: background .3s;
}
.btn:hover { background: var(--deep-red); }
.btn:disabled { opacity: .55; cursor: progress; }
.formstatus { font-size: .9rem; min-height: 1.3em; }
.formstatus.is-ok { color: #2f6b40; }
.formstatus.is-bad { color: #b4342b; }
.rsvp-contacts { margin-top: 1.5rem; padding-top: 1.2rem; border-top: 1px solid var(--hairline); display: grid; gap: .5rem; }
.rsvp-contacts a { color: var(--accent); text-decoration: none; }
.rsvp-contacts strong { font-family: var(--serif); font-weight: 400; color: var(--ink-strong); }

/* ══ Fixed chrome ════════════════════════════════════════════ */
.nav-dots {
  position: fixed; right: 1.1rem; top: 50%; translate: 0 -50%;
  z-index: 1000; display: flex; flex-direction: column; gap: .55rem;
}
.nav-dot {
  width: 8px; height: 8px; border-radius: 50%; padding: 0;
  background: rgba(140, 60, 60, .18);
  border: 1.5px solid var(--accent);
  transition: background .3s, scale .3s;
}
.nav-dot.active { background: var(--accent); scale: 1.4; }

.music-ring {
  position: fixed; left: 1.1rem; bottom: 1.2rem; z-index: 1000;
  display: grid; justify-items: center; gap: .25rem;
  color: var(--accent);
}
.music-ring svg {
  width: 36px; height: 36px; padding: 8px;
  border-radius: 50%; border: 1px solid var(--hairline);
  background: rgba(255, 255, 255, .72);
}
.music-label { font-size: .5rem; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-soft); }
.music-ring[aria-pressed="true"] svg { background: rgba(140, 60, 60, .14); border-color: var(--accent); }

/* Petals */
.petals { position: fixed; inset: 0; z-index: 900; pointer-events: none; overflow: hidden; }
.petal { position: absolute; top: -40px; font-size: .9rem; animation: petalFall linear infinite; }

/* ══ Reveal ══════════════════════════════════════════════════ */
.fade-in { opacity: 0; transform: translateY(22px); transition: opacity .7s ease, transform .7s ease; }
.fade-in.visible { opacity: 1; transform: none; }

/* ══ Animations ══════════════════════════════════════════════ */
@keyframes heartbeat  { 0%, 100% { scale: 1; } 14% { scale: 1.2; } 28% { scale: 1; } 42% { scale: 1.12; } }
@keyframes ganeshGlow {
  0%, 100% { filter: drop-shadow(0 4px 15px rgba(201, 168, 76, .55)); }
  50%      { filter: drop-shadow(0 8px 30px rgba(255, 215, 0, .95)); }
}
@keyframes bounce { 0%, 100% { translate: -50% 0; } 50% { translate: -50% 6px; } }
@keyframes twinkle { 0%, 100% { opacity: .35; } 50% { opacity: .95; } }
@keyframes petalFall {
  0%   { opacity: 0; transform: translateY(-30px) rotate(0deg); }
  10%  { opacity: .55; }
  90%  { opacity: .2; }
  100% { opacity: 0; transform: translateY(110dvh) rotate(360deg); }
}

/* ══ Motion & print ══════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  html, .snap-wrap { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .fade-in { opacity: 1; transform: none; }
  .petals { display: none; }
  /* Dot field holds still rather than pulsing; the bursts are dropped,
     since a frozen burst is just a stray ring of dots. */
  .theme-sangeet .sparkles { opacity: .8; }
  .theme-sangeet::before, .theme-sangeet::after,
  .theme-barat::before, .theme-barat::after,
  .theme-baraat::before, .theme-baraat::after { display: none; }
}

/* Print inverts back to ink on paper — a dark gradient would drink toner. */
@media print {
  .nav-dots, .music-ring, .petals, .page-nav-btn, .form, .pattern-bg, .sparkles,
  .theme-sangeet::after, .theme-sangeet::before,
  .theme-barat::before, .theme-barat::after,
  .theme-baraat::before, .theme-baraat::after { display: none !important; }
  html, body { background: #fff !important; color: var(--text) !important; }
  .snap-wrap { height: auto; overflow: visible; }
  body::before { display: none !important; }
  .page {
    min-height: auto; page-break-after: always; padding: 2rem 1rem;
    background: #fff !important; color: var(--text) !important;
  }
  .hero-name, .event-name, .blessings-title, .family-page-title, .rsvp-title, .cd-num {
    color: var(--maroon) !important; text-shadow: none !important;
  }
  .hero-title, .event-subtitle, .fam-note, .dress-value, .fam-kids,
  .event-datetime-row a, .event-cal { color: var(--deep-red) !important; }
  .hero-lineage, .event-desc, .pc-name, .fam-name-row, .edt-text,
  .blessings-meta, .cd-label, .dress-label { color: var(--text) !important; }
  .event-tag, .family-col-header, .fam-section-head, .hero-badge { color: var(--saffron) !important; }
  .hero-badge, .event-stamp, .family-col-box { background: #fff !important; border-color: rgba(0, 0, 0, .25) !important; }
  .gold-frame, .corner-svg { border-color: rgba(0, 0, 0, .25) !important; }
}

/* ══════════════════════════════════════════════════════════════
   OPENING ENVELOPE
   Full-bleed embossed card. Tapping the wax seal swings the flap
   open on a 3D hinge, the invitation rises out, then the whole
   layer clears to reveal the deck behind it.
   ══════════════════════════════════════════════════════════════ */

.env {
  --paper:       #cf9a9a;
  --paper-dark:  #b87c7c;
  --paper-light: #e3bdbd;
  --env-gold:    #c9a227;

  position: fixed; inset: 0; z-index: 2000;
  overflow: hidden;
  display: grid; place-items: center;
  /* Full-bleed paper at every size, so the envelope fills the window exactly
     like the pages behind it. An earlier version showed it as a centred card
     on a dark surround above 720px, which made it the one non-full-screen
     step in the deck. */
  background: var(--paper);
  transition: opacity .3s ease;
}

/* Embossed botanical tile: one sprig drawn twice, a dark pass nudged
   down and a light pass nudged up, which reads as relief. */
/* Full-bleed by default so it fills any phone exactly, whatever its
   height. Only on a roomy desktop window does it become a centred card. */
.env__card {
  position: relative;
  width: 100%;
  height: 100dvh;
  overflow: hidden;
  perspective: 1400px;
  transform-style: preserve-3d;
  background-color: var(--paper);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='72' height='72' viewBox='0 0 72 72'%3E%3Cg fill='none' stroke-linecap='round'%3E%3Cg stroke='rgba(122,58,58,.34)' stroke-width='1.1' transform='translate(0,.9)'%3E%3Cpath d='M6 64C14 50 25 41 40 34'/%3E%3Cpath d='M15 54c-4-4-4-9-1-12 3 3 4 8 1 12z'/%3E%3Cpath d='M25 46c-5-3-6-8-4-12 4 2 6 8 4 12z'/%3E%3Cpath d='M15 54c4-4 10-4 13-1-4 3-9 4-13 1z'/%3E%3Cpath d='M25 46c4-5 10-6 14-3-4 4-10 6-14 3z'/%3E%3Cpath d='M40 72c7-13 15-20 26-24'/%3E%3Cpath d='M50 62c-3-4-3-9 0-11 3 3 3 8 0 11z'/%3E%3Cpath d='M38 4c8 9 14 20 16 33'/%3E%3Cpath d='M46 16c4-3 9-2 11 1-3 3-8 3-11-1z'/%3E%3C/g%3E%3Cg stroke='rgba(255,238,238,.36)' stroke-width='1.1' transform='translate(0,-.9)'%3E%3Cpath d='M6 64C14 50 25 41 40 34'/%3E%3Cpath d='M15 54c-4-4-4-9-1-12 3 3 4 8 1 12z'/%3E%3Cpath d='M25 46c-5-3-6-8-4-12 4 2 6 8 4 12z'/%3E%3Cpath d='M15 54c4-4 10-4 13-1-4 3-9 4-13 1z'/%3E%3Cpath d='M25 46c4-5 10-6 14-3-4 4-10 6-14 3z'/%3E%3Cpath d='M40 72c7-13 15-20 26-24'/%3E%3Cpath d='M50 62c-3-4-3-9 0-11 3 3 3 8 0 11z'/%3E%3Cpath d='M38 4c8 9 14 20 16 33'/%3E%3Cpath d='M46 16c4-3 9-2 11 1-3 3-8 3-11-1z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
  background-size: 50px 50px;
}

/* Soft sheen, like light across coated paper */
.env__card::after {
  content: ""; position: absolute; inset: 0; z-index: 6; pointer-events: none;
  background:
    radial-gradient(130% 70% at 72% 8%,  rgba(255,255,255,.26), transparent 56%),
    radial-gradient(90% 60% at 10% 96%, rgba(90,30,30,.20),   transparent 60%);
}

/* Dark interior. Clipped to exactly the flap's triangle and sitting
   directly beneath it, so a closed envelope is all paper and the
   interior is only revealed by the flap swinging away. */
.env__inner {
  position: absolute; top: 0; left: 0; right: 0; height: 58%; z-index: 1;
  /* Same pentagon as the flap, so the revealed interior matches its shape */
  -webkit-clip-path: polygon(0 0, 100% 0, 100% 69%, 50% 100%, 0 69%);
          clip-path: polygon(0 0, 100% 0, 100% 69%, 50% 100%, 0 69%);
  background: linear-gradient(170deg, #4a1e21 0%, #2c1114 45%, #190b0d 100%);
  transition: opacity .6s ease 3.3s;
}

/* Cast shadow on the interior. The flap's own drop-shadow rotates away with
   the flap, so it can never fall on the paper below — this stationary layer
   is what actually reads as the flap throwing a shadow as it opens. */
.env__cast {
  position: absolute; top: 0; left: 0; right: 0; height: 58%; z-index: 2;
  -webkit-clip-path: polygon(0 0, 100% 0, 100% 69%, 50% 100%, 0 69%);
          clip-path: polygon(0 0, 100% 0, 100% 69%, 50% 100%, 0 69%);
  background: linear-gradient(180deg,
    rgba(30, 8, 6, 0) 30%, rgba(30, 8, 6, .5) 78%, rgba(30, 8, 6, .72) 100%);
  opacity: 0; pointer-events: none;
}
.env.is-opening .env__cast { animation: castSweep 2.1s ease-out .45s both; }

@keyframes castSweep {
  0%   { opacity: 0; }
  22%  { opacity: 1; }
  100% { opacity: 0; }
}

/* The invitation card. Sized like a real insert: nearly as large as the
   envelope (84% wide, 80% tall), not a small tag. It starts tucked in the
   pocket with its top edge level with the pocket's sides (40%), so the
   only part ever visible before it rises is what shows in the open V. */
.env__letter {
  position: absolute; z-index: 2;
  left: 50%; top: 50%;
  width: min(84vw, 1180px); height: 80dvh;
  translate: -50% -50%;
  transform: translateY(30dvh);    /* tucked: top edge at 40% */
  display: grid; align-content: center; justify-items: center;
  gap: clamp(.4rem, 1.6vh, .9rem);
  text-align: center; padding: 2rem 1.4rem;
  background: linear-gradient(165deg, #fdf0f0, #f4cfcf 60%, #eebcbc);
  border: 1px solid rgba(160,70,70,.42);
  box-shadow: 0 -6px 30px -12px rgba(60,20,20,.35),
              0 30px 70px -30px rgba(90,35,35,.55);
}
.env__letter::before {
  content: ""; position: absolute; inset: 10px;
  border: 1px solid rgba(160,70,70,.3);
}
.env__letter::after {                 /* second, finer rule like a printed card */
  content: ""; position: absolute; inset: 16px;
  border: 1px solid rgba(160,70,70,.16);
}
.env__letter-names {
  font-family: var(--display); font-weight: 600;
  font-size: clamp(1.6rem, 6vw, 3.2rem);
  color: var(--maroon); letter-spacing: .03em; line-height: 1.15;
}
.env__letter-sub {
  font-family: var(--script);
  font-size: clamp(1.8rem, 6.6vw, 3.4rem);
  color: var(--deep-red); opacity: .95; line-height: 1.1;
}
.env__letter-date {
  font-family: var(--display); font-weight: 600;
  font-size: clamp(.8rem, 2.6vw, 1.15rem);
  letter-spacing: .2em; text-transform: uppercase;
  color: #6b2a2a; margin-top: .3rem;
}
.env__letter-date:empty { display: none; }

/* Front pocket. Its top edge dips to a V that the flap apex meets. */
.env__pocket, .env__pocket-edge {
  position: absolute; left: 0; right: 0; bottom: 0;
  -webkit-clip-path: polygon(0 0, 50% 30%, 100% 0, 100% 100%, 0 100%);
          clip-path: polygon(0 0, 50% 30%, 100% 0, 100% 100%, 0 100%);
  transition: opacity .6s ease 3.3s;
}
.env__pocket {
  top: 40%; z-index: 4;
  /* background-color, not the shorthand: the shorthand would be wiped by
     the background-image list below, leaving the panel transparent.
     Flat paper, matching the flap exactly. */
  background-color: var(--paper);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='72' height='72' viewBox='0 0 72 72'%3E%3Cg fill='none' stroke-linecap='round'%3E%3Cg stroke='rgba(122,58,58,.32)' stroke-width='1.1' transform='translate(0,.9)'%3E%3Cpath d='M6 64C14 50 25 41 40 34'/%3E%3Cpath d='M15 54c-4-4-4-9-1-12 3 3 4 8 1 12z'/%3E%3Cpath d='M25 46c-5-3-6-8-4-12 4 2 6 8 4 12z'/%3E%3Cpath d='M40 72c7-13 15-20 26-24'/%3E%3Cpath d='M38 4c8 9 14 20 16 33'/%3E%3C/g%3E%3Cg stroke='rgba(255,238,238,.34)' stroke-width='1.1' transform='translate(0,-.9)'%3E%3Cpath d='M6 64C14 50 25 41 40 34'/%3E%3Cpath d='M15 54c-4-4-4-9-1-12 3 3 4 8 1 12z'/%3E%3Cpath d='M25 46c-5-3-6-8-4-12 4 2 6 8 4 12z'/%3E%3Cpath d='M40 72c7-13 15-20 26-24'/%3E%3Cpath d='M38 4c8 9 14 20 16 33'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
  background-size: 50px 50px;
}
/* Gold V on the pocket itself. Mostly hidden under the closed flap; it keeps
   the seam gold once the flap has lifted away. */
.env__pocket-edge {
  top: calc(40% - 3px); z-index: 3;
  background: linear-gradient(90deg, #8a6a18, var(--env-gold) 50%, #8a6a18);
}

/* ── Flap ────────────────────────────────────────────────────
   Three parts: a rotating wrapper (no clipping), a clipped paper face,
   and an SVG gold edge that sits OUTSIDE the clip. The gold line used to
   be a drop-shadow on the clipped face, which Chrome rendered too faintly
   to see once the flap covered the pocket's own gold strip. As a real
   stroke it is crisp, and because it lives in the rotating wrapper it
   lifts away with the flap — the opening starts at the gold line. */
.env__flap {
  position: absolute; top: 0; left: 0; right: 0; height: 58%;
  z-index: 5;
  transform-origin: 50% 0%;
  transform: rotateX(0deg);
  /* Slow, weighted swing: eases out of the fold, glides, settles */
  transition: transform 1.9s cubic-bezier(.45,.05,.25,1) .45s,
              opacity .6s ease 3.4s;
}

.env__flap-face {
  position: absolute; inset: 0;
  /* Pentagon, not a triangle: the bottom edge runs down the sides to 69% of
     the flap (= 40% of the page) and then into the V apex — exactly tracing
     the pocket's gold edge. As a plain triangle its edges sprang from the top
     corners instead, which drew a second, steeper V that didn't line up. */
  -webkit-clip-path: polygon(0 0, 100% 0, 100% 69%, 50% 100%, 0 69%);
          clip-path: polygon(0 0, 100% 0, 100% 69%, 50% 100%, 0 69%);
  /* Same flat paper as the rest of the envelope — the V is defined by the
     gold stroke, not by a change of colour. */
  background-color: var(--paper);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='72' height='72' viewBox='0 0 72 72'%3E%3Cg fill='none' stroke-linecap='round'%3E%3Cg stroke='rgba(122,58,58,.32)' stroke-width='1.1' transform='translate(0,.9)'%3E%3Cpath d='M6 64C14 50 25 41 40 34'/%3E%3Cpath d='M15 54c-4-4-4-9-1-12 3 3 4 8 1 12z'/%3E%3Cpath d='M25 46c-5-3-6-8-4-12 4 2 6 8 4 12z'/%3E%3Cpath d='M40 72c7-13 15-20 26-24'/%3E%3Cpath d='M38 4c8 9 14 20 16 33'/%3E%3C/g%3E%3Cg stroke='rgba(255,238,238,.34)' stroke-width='1.1' transform='translate(0,-.9)'%3E%3Cpath d='M6 64C14 50 25 41 40 34'/%3E%3Cpath d='M15 54c-4-4-4-9-1-12 3 3 4 8 1 12z'/%3E%3Cpath d='M25 46c-5-3-6-8-4-12 4 2 6 8 4 12z'/%3E%3Cpath d='M40 72c7-13 15-20 26-24'/%3E%3Cpath d='M38 4c8 9 14 20 16 33'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
  background-size: 50px 50px;
  /* Closed: a tight contact shadow, as if resting on the pocket. */
  filter: drop-shadow(0 3px 5px rgba(74, 28, 20, .3));
  transition: filter 1.9s cubic-bezier(.45, .05, .25, 1) .45s;
}
/* Opening: the shadow lofts and softens as the flap swings away from the
   paper, which is what reads as the flap physically lifting. */
.env.is-opening .env__flap-face {
  filter: drop-shadow(0 34px 30px rgba(74, 28, 20, .48));
}

.env__flap-edge {
  position: absolute; inset: 0; width: 100%; height: 100%;
  overflow: visible; pointer-events: none;
}
.env__foil {
  fill: none;
  stroke: url(#envFoil);
  stroke-width: 3;
  stroke-linejoin: miter;
  /* Constant 3px regardless of the non-uniform viewBox scaling */
  vector-effect: non-scaling-stroke;
  /* A tight dark line directly beneath sells the foil as raised off the
     paper rather than printed flat onto it. */
  filter: drop-shadow(0 1px 1px rgba(74, 38, 10, .55));
}
/* No lofting shadow on the foil itself: a wide blur on a 3px stroke that is
   rotating in 3D rasterises into a dotted smear in Chrome. The flap face's
   own shadow and the cast layer already carry the lift. */

/* Wax seal — gold sealing wax, same gold as before. Set envelope.wax in
   config.js to recolour; every highlight and shadow is mixed from it. */
.env {
  --wax: #c4902c;
  --wax-hi:    color-mix(in srgb, var(--wax) 25%, #fffbe8);   /* specular edge */
  --wax-light: color-mix(in srgb, var(--wax) 50%, #fbe7a6);
  --wax-dark:  color-mix(in srgb, var(--wax) 48%, #2a1500);
}
.env__seal {
  position: absolute; z-index: 7;
  left: 50%; top: 58%;
  translate: -50% -50%;
  width: clamp(110px, 30vw, 140px); aspect-ratio: 1;
  margin: 0; padding: 0; border: 0;
  background: none;
  border-radius: 50%;            /* focus ring + hit area follow the disc */
  display: grid; place-items: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .3s ease, opacity .3s ease;
}
.env__seal:focus-visible { outline: 2px solid #fff6d8; outline-offset: 4px; }

.env__wax {
  position: absolute; inset: 0; width: 100%; height: 100%;
  overflow: visible;
  /* Shape-accurate shadow: wax sits proud of the paper */
  filter: drop-shadow(0 5px 6px rgba(70, 40, 10, .45))
          drop-shadow(0 1px 1px rgba(70, 40, 10, .55));
  animation: sealBreathe 3.4s ease-in-out infinite;
}
.wax-stop-hi    { stop-color: var(--wax-hi); }
.wax-stop-light { stop-color: var(--wax-light); }
.wax-stop-base  { stop-color: var(--wax); }
.wax-stop-dark  { stop-color: var(--wax-dark); }
.wax-relief-shadow { stroke: var(--wax-dark); stroke-opacity: .75; }

/* Monogram stamped in relief, like "AUTHENTIC" on the reference:
   gold on gold, made legible by a bright top edge and a dark cast
   shadow below-right. Bold and as large as the inner ring allows. */
.env__seal-mono {
  position: relative; z-index: 1;
  font-family: var(--display); font-weight: 900;
  font-size: clamp(1.6rem, 7vw, 2.1rem);
  letter-spacing: .01em; line-height: 1;
  color: var(--wax);
  text-shadow:
     0   -1px  0   var(--wax-hi),
    -1px -1px  0   color-mix(in srgb, var(--wax-hi) 60%, transparent),
     1px  1.5px 0  var(--wax-dark),
     1.5px 2px 2px color-mix(in srgb, var(--wax-dark) 70%, transparent);
  translate: 0 .05em;            /* optical centring for caps */
  white-space: nowrap;
}

/* Small prompt under the seal, so guests know it's tappable */
.env__seal-hint {
  position: absolute; top: calc(100% + .6rem); left: 50%; translate: -50% 0;
  font-family: var(--serif); font-style: italic;
  font-size: clamp(.8rem, 2.6vw, .92rem); letter-spacing: .04em;
  color: #4a1418; white-space: nowrap;
  text-shadow: 0 1px 0 rgba(255, 235, 235, .35);
  pointer-events: none;
}
/* Centring lives in the `translate` property above; transforms here must
   NOT repeat translate(-50%,-50%) or the two stack and the seal jumps. */
.env__seal:hover { transform: scale(1.05); }
.env__seal:active { transform: scale(.97); }

/* "You are invited" */
.env__invited {
  position: absolute; z-index: 7;
  left: 0; right: 0; bottom: clamp(2.2rem, 7vh, 4rem);
  display: flex; align-items: center; justify-content: center; gap: .8rem;
  font-family: var(--sans); font-size: .72rem;
  letter-spacing: .34em; text-transform: uppercase;
  color: #6b3a36;
  text-shadow: 0 1px 0 rgba(255,238,238,.5);
  transition: opacity .4s ease 1.5s;
}
.env__orn { color: #8a4a44; font-size: .9rem; letter-spacing: 0; }

/* ── Opening sequence ─────────────────────────────────────────
   One class drives it; each part carries its own delay.
   Timeline (~5s):
     0.0–0.7  seal lifts away
     0.45–2.35 flap swings up and TOWARDS the viewer
     1.7–3.4  card slides up out of the pocket
     3.4–4.0  envelope fades from around the card
     4.0–4.4  card held, so the names can be read
     4.4–5.1  card and envelope dissolve into page 1 */
.env.is-opening { pointer-events: none; }
.env.is-opening .env__seal   {
  opacity: 0; transform: scale(.8) rotate(10deg);
  transition: transform .7s ease, opacity .7s ease;
}
/* Positive angle, hinged at the top edge: the point of the flap comes
   up off the paper towards the guest, like a real envelope. (Negative
   swung it backwards, into the screen behind the envelope.) */
.env.is-opening .env__flap   { transform: rotateX(172deg); opacity: 0; }
.env.is-opening .env__letter { animation: letterOut 3.4s cubic-bezier(.4,0,.2,1) 1.7s forwards; }
.env.is-opening .env__pocket,
.env.is-opening .env__pocket-edge,
.env.is-opening .env__inner,
.env.is-opening .env__invited { opacity: 0; }
/* Pocket clears quickly once the card is out, so the card never sits
   behind a half-transparent pocket for long */
.env.is-opening .env__pocket,
.env.is-opening .env__pocket-edge { transition: opacity .45s ease 3.4s; }
.env.is-opening .env__invited { transition: opacity .6s ease .2s; }
.env.is-opening .env__card::after { opacity: 0; transition: opacity .6s ease 3.4s; }
.env.is-done { opacity: 0; transition: opacity .6s ease; }

@keyframes letterOut {
  0%   { transform: translateY(30dvh) scale(1);    opacity: 1; }  /* tucked */
  50%  { transform: translateY(-1dvh) scale(1);    opacity: 1; }  /* risen out */
  62%  { transform: translateY(0)     scale(1);    opacity: 1; }  /* settles */
  80%  { transform: translateY(0)     scale(1.01); opacity: 1; }  /* held */
  100% { transform: translateY(0)     scale(1.06); opacity: 0; }  /* dissolves */
}
/* A slow lift of the shadow — draws the eye to the seal without the
   wax itself looking like it's pulsing. */
@keyframes sealBreathe {
  0%, 100% { filter: drop-shadow(0 5px 6px rgba(70, 40, 10, .45)) drop-shadow(0 1px 1px rgba(70, 40, 10, .55)); }
  50%      { filter: drop-shadow(0 9px 12px rgba(70, 40, 10, .55)) drop-shadow(0 1px 1px rgba(70, 40, 10, .55)); }
}

/* ── Scroll lock + chrome hidden while the envelope is up ───── */
body.is-sealed { overflow: hidden; }
body.is-sealed .snap-wrap { overflow: hidden; }
body.is-sealed .nav-dots,
body.is-sealed .music-ring,
body.is-sealed .petals { opacity: 0; pointer-events: none; }
.nav-dots, .music-ring, .petals { transition: opacity .6s ease .2s; }

/* Short or landscape: shrink the seal and footer so nothing collides */
@media (max-height: 560px) {
  .env__seal { width: clamp(72px, 19vh, 96px); }
  .env__seal-mono { font-size: clamp(1rem, 4.6vh, 1.4rem); }
  .env__seal-hint { top: calc(100% + .3rem); font-size: .72rem; }
  .env__invited { bottom: .9rem; font-size: .6rem; letter-spacing: .24em; }
  .env__letter { padding: 1rem; gap: .2rem; }
  .env__letter-names { font-size: clamp(1.1rem, 6vh, 1.8rem); }
  .env__letter-sub { font-size: clamp(1.2rem, 6.5vh, 2rem); }
  .env__letter-date { font-size: .7rem; }
}

@media (prefers-reduced-motion: reduce) {
  .env__wax { animation: none; }
  .env.is-opening .env__flap,
  .env.is-opening .env__letter { animation: none; transform: none; }
  /* No flap motion, so the lofting shadow and cast sweep have nothing to
     explain — leave the closed contact shadow and skip them. */
  .env.is-opening .env__flap-face,
  .env.is-opening .env__foil { filter: none; }
  .env__cast, .env.is-opening .env__cast { animation: none; opacity: 0; }
  .env.is-opening { opacity: 0; transition: opacity .25s ease; }
}

@media print { .env { display: none !important; } }

/* ══════════════════════════════════════════════════════════════
   VENUE PAGE
   ══════════════════════════════════════════════════════════════ */

/* Deep marigold — swapped over from Haldi, whose dress code is sage */
.theme-venue {
  --glow-mid: #f7d98a; --glow: #ecc251; --glow-deep: #d9a52b;
  --ink: #4a2a06; --ink-strong: #3d1f04; --ink-soft: #54300a; --accent: #5e3004;
}

.venue-inner {
  position: relative; z-index: 10;
  max-width: 540px; width: 100%;
  display: grid; justify-items: center; gap: .55rem;
}

.venue-name {
  font-family: var(--display); font-weight: 600;
  font-size: clamp(1.7rem, 7vw, 2.6rem);
  color: var(--ink-strong); line-height: 1.1; letter-spacing: .02em;
}
.venue-tagline {
  font-family: var(--script);
  font-size: clamp(1.15rem, 4.6vw, 1.6rem);
  color: var(--accent); line-height: 1.3;
}

/* Landscape frame, not the circle the event pages use — a building
   reads badly in a circular crop. */
.venue-photo {
  position: relative; margin: .7rem 0 .2rem;
  width: min(100%, 420px); aspect-ratio: 4 / 3;
  padding: 6px;
  background: linear-gradient(135deg, var(--gold), var(--gold-pale), var(--gold));
  box-shadow: 0 12px 30px -14px rgba(74, 42, 6, .5);
  overflow: hidden;
}
.venue-photo img {
  position: relative; z-index: 1;
  width: 100%; height: 100%; object-fit: cover; display: block;
}
/* Sits under the photo; only seen when the file is missing or fails */
.venue-photo__fallback {
  position: absolute; inset: 6px; z-index: 0;
  display: grid; place-items: center;
  background: var(--glow-mid); color: var(--accent);
}
.venue-photo__fallback svg { width: 34%; height: 34%; opacity: .5; }

.venue-address {
  font-family: var(--serif); font-size: clamp(.95rem, 3.2vw, 1.1rem);
  color: var(--ink); opacity: .9;
}

.venue-map {
  margin-top: .8rem; text-decoration: none;
  background: var(--accent); border-color: var(--accent); color: #fff8ec;
}
.venue-map:hover { background: var(--ink-strong); border-color: var(--ink-strong); }

.venue-notes {
  list-style: none; margin: 1.1rem 0 0; padding: 0;
  display: grid; gap: .45rem; max-width: 42ch;
}
.venue-notes li {
  font-family: var(--serif); font-size: clamp(.88rem, 3vw, 1rem);
  color: var(--ink-soft); line-height: 1.5;
}
.venue-notes li::before {
  content: "✦"; color: var(--accent); margin-right: .5em; font-size: .8em;
}

@media print {
  .venue-map { display: none !important; }
  .venue-name, .venue-tagline { color: var(--maroon) !important; }
  .venue-address, .venue-notes li { color: var(--text) !important; }
}

/* ══════════════════════════════════════════════════════════════
   OUR GALLERY
   Collage of up to five tiles — the first one large — and a
   native <dialog> lightbox for tapping through full size.
   ══════════════════════════════════════════════════════════════ */

/* Dusk lilac — no other page uses it, and it flatters skin tones in
   photos better than the warmer pages either side. */
.theme-gallery {
  --glow-mid: #f3edf5; --glow: #e6dbec; --glow-deep: #d6c6e0;
  --ink: #3f2d4a; --ink-strong: #4a1f4f; --ink-soft: #4d3a58; --accent: #6a2c6e;
  --hairline: rgba(106, 44, 110, .30);
}

.gallery-inner {
  position: relative; z-index: 10;
  width: 100%; max-width: 920px;
  display: grid; justify-items: center; gap: .35rem;
}
.gallery-title {
  font-family: var(--display); font-weight: 600;
  font-size: clamp(1.6rem, 6.4vw, 2.5rem);
  color: var(--ink-strong); line-height: 1.1; letter-spacing: .02em;
}
.gallery-tagline {
  font-family: var(--script);
  font-size: clamp(1.1rem, 4.4vw, 1.5rem);
  color: var(--accent); line-height: 1.3;
}

/* Fixed height with fr rows: tiles always fill the page neatly whatever
   shape the photos are, and object-fit crops them to the cell. */
.gallery-grid {
  list-style: none; margin: .9rem 0 0; padding: 0;
  width: min(100%, 900px);
  height: min(60dvh, 540px);
  display: grid; gap: clamp(6px, 1.2vw, 12px);
  grid-template-columns: 2fr 1fr 1fr;
  grid-template-rows: 1fr 1fr;
}
/* Desktop: hero tile down the left, the rest in a 2×2 block */
.gallery-grid > li:first-child { grid-row: 1 / -1; }
.gallery-grid[data-count="4"] > li:nth-child(4) { grid-column: 2 / -1; }
.gallery-grid[data-count="3"] { grid-template-columns: 3fr 2fr; }
.gallery-grid[data-count="2"] { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr; }
.gallery-grid[data-count="1"] {
  grid-template-columns: 1fr; grid-template-rows: 1fr; width: min(100%, 560px);
}

.gallery-item { position: relative; min-width: 0; min-height: 0; }

.gallery-tile {
  appearance: none; -webkit-appearance: none;
  position: relative; display: block;
  width: 100%; height: 100%;
  margin: 0; padding: 4px; border: 0; border-radius: 3px;
  /* Gold mount, same as the venue photo frame */
  background: linear-gradient(135deg, var(--gold), var(--gold-pale), var(--gold));
  box-shadow: 0 10px 26px -14px rgba(63, 45, 74, .55);
  overflow: hidden; cursor: zoom-in;
  transition: transform .35s ease, box-shadow .35s ease;
}
.gallery-tile img {
  position: relative; z-index: 1;
  width: 100%; height: 100%; display: block;
  object-fit: cover; object-position: 50% 30%;   /* faces sit high in most portraits */
  transition: transform .6s ease;
}
.gallery-tile:hover { transform: translateY(-2px); box-shadow: 0 16px 30px -14px rgba(63, 45, 74, .65); }
.gallery-tile:hover img { transform: scale(1.04); }
.gallery-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Placeholder under the photo — only visible while the file is missing */
.gallery-tile__fallback {
  position: absolute; inset: 4px; z-index: 0;
  display: grid; place-content: center; justify-items: center; gap: .35rem;
  background: var(--glow-mid); color: var(--accent);
  font-family: var(--sans); font-size: .62rem; letter-spacing: .22em; text-transform: uppercase;
}
.gallery-tile__fallback svg { width: clamp(22px, 5vw, 34px); height: auto; opacity: .55; }
.gallery-tile.is-missing { cursor: default; }
.gallery-tile.is-missing:hover { transform: none; }

/* "+N" when there are more photos than tiles */
.gallery-tile__more {
  position: absolute; inset: 4px; z-index: 2;
  display: grid; place-items: center;
  background: rgba(40, 22, 48, .55); color: #fff;
  font-family: var(--display); font-size: clamp(1.4rem, 4vw, 2rem);
}

/* Phones: hero tile across the top, the rest in pairs below */
@media (max-width: 640px) {
  .gallery-grid {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1.35fr 1fr 1fr;
    height: min(62dvh, 560px);
  }
  .gallery-grid > li:first-child { grid-row: auto; grid-column: 1 / -1; }
  .gallery-grid[data-count="4"] > li:nth-child(4) { grid-column: 1 / -1; }
  .gallery-grid[data-count="3"] { grid-template-columns: 1fr 1fr; grid-template-rows: 1.4fr 1fr; }
  .gallery-grid[data-count="2"] { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
}

/* ── Lightbox ─────────────────────────────────────────────── */
.lightbox {
  width: 100vw; height: 100dvh; max-width: none; max-height: none;
  margin: 0; padding: 0; border: 0;
  background: rgba(18, 10, 22, .92);
  color: #fff;
}
.lightbox::backdrop { background: rgba(18, 10, 22, .6); }
.lightbox[open] { display: grid; place-items: center; animation: lbIn .25s ease; }
.lightbox__figure {
  margin: 0; display: grid; justify-items: center; gap: .8rem;
  max-width: min(92vw, 1200px);
}
.lightbox__img {
  display: block;
  max-width: 100%; max-height: 82dvh;
  object-fit: contain;
  border: 4px solid var(--gold-pale);
  box-shadow: 0 20px 60px -20px rgba(0, 0, 0, .8);
}
.lightbox__cap {
  font-family: var(--serif); font-size: .95rem; letter-spacing: .06em;
  color: #eadff0;
}
.lightbox__btn {
  position: absolute;
  display: grid; place-items: center;
  width: 46px; height: 46px; padding: 0;
  border-radius: 50%; border: 1px solid rgba(255, 255, 255, .4);
  background: rgba(255, 255, 255, .12); color: #fff;
  cursor: pointer;
  transition: background .2s ease;
}
.lightbox__btn svg { width: 22px; height: 22px; }
.lightbox__btn:hover { background: rgba(255, 255, 255, .26); }
.lightbox__btn:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
.lightbox__close { top: max(1rem, env(safe-area-inset-top)); right: 1rem; }
.lightbox__prev  { left: 1rem;  top: 50%; translate: 0 -50%; }
.lightbox__next  { right: 1rem; top: 50%; translate: 0 -50%; }
.lightbox__btn[hidden] { display: none; }
@media (max-width: 640px) {
  /* Arrows drop to the bottom on phones so they don't cover the photo */
  .lightbox__prev, .lightbox__next { top: auto; bottom: max(1.2rem, env(safe-area-inset-bottom)); translate: none; }
  .lightbox__img { max-height: 72dvh; }
}
@keyframes lbIn { from { opacity: 0; } to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .gallery-tile, .gallery-tile img { transition: none; }
  .gallery-tile:hover, .gallery-tile:hover img { transform: none; }
  .lightbox[open] { animation: none; }
}

@media print {
  .lightbox { display: none !important; }
  .gallery-title { color: var(--maroon) !important; }
  .gallery-tagline { color: var(--deep-red) !important; }
}
