/* =========================================================
   Aafrin & Abu · wedding invitation
   Palette: maroon grounds, antique gold, ivory
   ========================================================= */

:root {
  --maroon-900: #2C060D;
  --maroon-800: #3E0A12;
  --maroon-600: #6B1423;
  --maroon-500: #8A2032;

  --gold-600: #A8853A;
  --gold-500: #C9A24B;
  --gold-300: #E8C874;
  --gold-100: #F7E7BE;

  --ivory:     #F6EEDD;
  --ivory-dim: #E3D6BE;

  --terracotta: #B5603B;
  --dustyblue:  #4C6B7A;

  --ink:      #2A1A16;
  --ink-soft: #5C4638;

  --serif-display: "Cinzel", "Trajan Pro", Georgia, serif;
  --serif-body:    "EB Garamond", Georgia, "Times New Roman", serif;
  --serif-italic:  "Cormorant Garamond", "EB Garamond", Georgia, serif;
  --urdu:          "Noto Nastaliq Urdu", "Jameel Noori Nastaleeq", serif;

  --wrap: 70rem;
  --pad: clamp(1.25rem, 5vw, 3rem);

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

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--maroon-900);
  color: var(--ivory);
  font-family: var(--serif-body);
  font-size: clamp(1rem, 0.95rem + 0.35vw, 1.125rem);
  line-height: 1.72;
  overflow-x: hidden;
  text-rendering: optimizeLegibility;
}
body.is-curtained { overflow: hidden; height: 100%; }

img, svg, canvas { max-width: 100%; display: block; }
h1, h2, h3 { font-family: var(--serif-display); font-weight: 500; line-height: 1.18; margin: 0; }
p { margin: 0 0 1em; }
a { color: inherit; }
button { font: inherit; color: inherit; }
::selection { background: var(--gold-500); color: var(--maroon-900); }

:where(a, button):focus-visible {
  outline: 2px solid var(--gold-300);
  outline-offset: 4px;
  border-radius: 2px;
}

.svg-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---------- shared paisley texture ---------- */
.section--dark::before,
.hero__bg::after,
.poem::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140' viewBox='0 0 140 140'%3E%3Cg fill='none' stroke='%23C9A24B' stroke-width='0.9' opacity='0.55'%3E%3Cpath d='M70 26c17 7 24 22 17 36-6 12-22 14-29 5-5-7-1-17 7-18 7-1 12 5 10 11'/%3E%3Ccircle cx='70' cy='70' r='2.4'/%3E%3Cpath d='M0 70h16M124 70h16M70 0v16M70 124v16'/%3E%3Cpath d='M22 22l10 10M118 22l-10 10M22 118l10-10M118 118l-10-10'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 140px 140px;
}

/* ---------- layout ---------- */
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--pad); }
.wrap--narrow { max-width: 46rem; }

.section {
  position: relative;
  padding-block: clamp(4.5rem, 12vw, 8rem);
  text-align: center;
  perspective: 1200px;
  perspective-origin: 50% 40%;
}
.section .wrap { transform-style: preserve-3d; }

.section--dark {
  background: linear-gradient(180deg, var(--maroon-900), var(--maroon-800) 45%, var(--maroon-900));
}
.section--dark::before { content: ""; position: absolute; inset: 0; opacity: 0.07; pointer-events: none; }

.section--light { background: var(--ivory); color: var(--ink); }
.section--light .section__eyebrow { color: var(--gold-600); }
.section--light .section__title  { color: var(--maroon-800); }
.section--light .section__lede   { color: var(--ink-soft); }

.section__eyebrow {
  font-family: var(--serif-display);
  font-size: 0.7rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--gold-500);
  margin-bottom: 0.9rem;
}
.section__title {
  font-size: clamp(1.85rem, 1.25rem + 2.9vw, 3.1rem);
  letter-spacing: 0.06em;
  color: var(--gold-300);
  margin-bottom: 0.8rem;
}
.section--dark .section__title {
  background: linear-gradient(100deg, var(--gold-600), var(--gold-100) 45%, var(--gold-500));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.section__lede {
  max-width: 40rem;
  margin-inline: auto;
  font-family: var(--serif-italic);
  font-size: 1.16rem;
  font-style: italic;
  color: var(--ivory-dim);
}

/* ---------- ornaments ---------- */
.rule { display: flex; align-items: center; justify-content: center; gap: 0.75rem; margin: 1.9rem auto; max-width: 20rem; }
.rule span { flex: 1; height: 1px; background: linear-gradient(90deg, transparent, var(--gold-500)); }
.rule span:last-child { background: linear-gradient(270deg, transparent, var(--gold-500)); }
.rule i { width: 9px; height: 9px; border: 1px solid var(--gold-500); transform: rotate(45deg); flex: none; }

/* corner filigree on the ivory sections */
.corner {
  position: absolute;
  width: clamp(48px, 9vw, 92px);
  aspect-ratio: 1;
  border: 1px solid rgba(168,133,58,0.5);
  pointer-events: none;
}
.corner::after {
  content: "";
  position: absolute;
  inset: 7px;
  border: 1px solid rgba(168,133,58,0.28);
}
.corner--tl { top: clamp(14px, 3vw, 30px); left: clamp(14px, 3vw, 30px); border-right: 0; border-bottom: 0; border-radius: 14px 0 0 0; }
.corner--tr { top: clamp(14px, 3vw, 30px); right: clamp(14px, 3vw, 30px); border-left: 0; border-bottom: 0; border-radius: 0 14px 0 0; }
.corner--bl { bottom: clamp(14px, 3vw, 30px); left: clamp(14px, 3vw, 30px); border-right: 0; border-top: 0; border-radius: 0 0 0 14px; }
.corner--br { bottom: clamp(14px, 3vw, 30px); right: clamp(14px, 3vw, 30px); border-left: 0; border-top: 0; border-radius: 0 0 14px 0; }
.corner--tl::after { border-right: 0; border-bottom: 0; }
.corner--tr::after { border-left: 0; border-bottom: 0; }
.corner--bl::after { border-right: 0; border-top: 0; }
.corner--br::after { border-left: 0; border-top: 0; }

/* line-art strokes used across the page */
.ln { fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.ln--faint { opacity: 0.45; }
.ln--thin  { stroke-width: 0.8; opacity: 0.7; }

/* =========================================================
   SCROLL FURNITURE
   ========================================================= */
.progress { position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 60; pointer-events: none; }
.progress span {
  display: block; height: 100%; width: 0%;
  background: linear-gradient(90deg, var(--gold-600), var(--gold-100), var(--gold-500));
  box-shadow: 0 0 12px rgba(232,200,116,0.6);
}

.dots {
  position: fixed;
  right: clamp(0.6rem, 1.6vw, 1.4rem);
  top: 50%;
  transform: translateY(-50%);
  z-index: 55;
  display: grid;
  gap: 0.85rem;
  opacity: 0;
  transition: opacity 0.5s;
}
.dots.is-ready { opacity: 1; }
.dots a {
  position: relative;
  display: block;
  width: 9px; height: 9px;
  border: 1px solid rgba(201,162,75,0.75);
  transform: rotate(45deg);
  transition: background-color 0.35s, box-shadow 0.35s, transform 0.35s;
}
.dots a:hover, .dots a.is-active { background: var(--gold-300); box-shadow: 0 0 10px rgba(232,200,116,0.7); }
.dots a.is-active { transform: rotate(45deg) scale(1.35); }
.dots__label {
  position: absolute;
  right: 150%;
  top: 50%;
  transform: rotate(-45deg) translate(6px, -50%);
  transform-origin: right center;
  white-space: nowrap;
  font-family: var(--serif-display);
  font-size: 0.58rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-300);
  background: rgba(44,6,13,0.86);
  border: 1px solid rgba(201,162,75,0.35);
  padding: 0.28rem 0.6rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s;
}
.dots a:hover .dots__label, .dots a:focus-visible .dots__label { opacity: 1; }
@media (max-width: 46rem) { .dots__label { display: none; } .dots { gap: 0.7rem; } }

/* =========================================================
   HERO
   ========================================================= */
.hero {
  position: relative;
  min-height: 100svh;
  overflow: hidden;
  isolation: isolate;
  perspective: 1100px;
  perspective-origin: 50% 44%;
}
/* every hero layer sits at its own depth, so the camera can move through them */
.hero__scene {
  position: relative;
  min-height: 100svh;
  display: grid;
  place-items: center;
  transform-style: preserve-3d;
  will-change: transform;
}
/* depth is kept gentle: the layers stay flat and the camera only drifts */
.lampstring-wrap { transform: translateZ(24px) scale(0.9786); }
.hero__dust     { transform: translateZ(40px) scale(0.964); }

.hero__bg {
  position: absolute; inset: 0; z-index: -3;
  background:
    radial-gradient(120% 82% at 50% 6%, rgba(107,20,35,0.95), transparent 60%),
    linear-gradient(180deg, var(--maroon-800), var(--maroon-900));
}
.hero__bg::after { content: ""; position: absolute; inset: 0; opacity: 0.08; }

/* jali lattice glow behind the arch */
.hero__jali {
  position: absolute; inset: -10%; z-index: -2;
  color: var(--gold-500);
  opacity: 0.13;
  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='%23C9A24B' stroke-width='0.9'%3E%3Cpath d='M36 0 72 36 36 72 0 36Z'/%3E%3Cpath d='M36 14 58 36 36 58 14 36Z'/%3E%3Ccircle cx='36' cy='36' r='3.4'/%3E%3Cpath d='M0 0h72v72H0z' opacity='0.3'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 72px 72px;
  -webkit-mask-image: radial-gradient(60% 50% at 50% 45%, #000 20%, transparent 78%);
  mask-image: radial-gradient(60% 50% at 50% 45%, #000 20%, transparent 78%);
}

.hero__dust { position: absolute; inset: 0; z-index: -1; pointer-events: none; }

/* ---------- the lamp string across the top of the hero ---------- */
/* the wrapper does the centring, so the entrance animation is free to use
   transform without knocking the string sideways */
.lampstring-wrap {
  position: absolute;
  /* the wire rises towards its two ends; hang it low enough that the ends
     clear the top edge instead of being shaved off in the corners */
  top: clamp(18px, 1.8vw, 30px);
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  z-index: 1;
  pointer-events: none;
}
.lampstring {
  /* never narrower than the viewport: a string that stops short of the edge
     reads as unfinished. the 88rem cap only keeps the lamps from growing
     absurdly on wide monitors, so let full width win over it */
  width: max(100.5%, min(126%, 88rem));
  flex: none;
  overflow: visible;
}
.lamp__wire {
  fill: none;
  stroke: url(#lampShine);
  stroke-width: 1.2;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.lamp__wire--main { stroke: url(#lampShine); stroke-width: 1.6; }

/* the toran: mango leaves threaded along the wire. the anchor carries the
   position, the inner group carries the sway, so neither overwrites the other */
.toran__leaf { fill: #5F7A54; opacity: 0.88; }
.toran__vein { fill: none; stroke: #86A473; stroke-width: 0.9; opacity: 0.55; }
.leaf {
  transform-box: fill-box;
  transform-origin: center top;
  animation: leafSway var(--sway, 4s) ease-in-out infinite var(--delay, 0s);
}
@keyframes leafSway {
  0%, 100% { rotate: -4deg; }
  50%      { rotate: 5deg; }
}
.lamp__ln {
  fill: none;
  stroke: url(#lampShine);
  stroke-width: 1.4;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.lamp__ln--thin { stroke-width: 0.7; opacity: 0.55; }
.lamp__ring { fill: none; stroke: url(#lampShine); stroke-width: 1.2; vector-effect: non-scaling-stroke; }
.lamp__drop { fill: url(#lampShine); }

/* the light inside, and the warmth it throws */
.lamp__flame {
  fill: rgba(255, 214, 138, 0.85);
  filter: blur(2.5px);
  transform-box: fill-box;
  transform-origin: center bottom;
  animation: lampFlicker var(--flicker, 2.4s) ease-in-out infinite;
}
.lamp__halo {
  fill: rgba(232, 200, 116, 0.13);
  filter: blur(7px);
  animation: lampHalo var(--flicker, 2.4s) ease-in-out infinite;
}
@keyframes lampFlicker {
  0%, 100% { opacity: 0.72; transform: scale(1, 1); }
  22%      { opacity: 1;    transform: scale(1.06, 1.12); }
  41%      { opacity: 0.66; transform: scale(0.95, 0.93); }
  63%      { opacity: 0.98; transform: scale(1.04, 1.09); }
  82%      { opacity: 0.78; transform: scale(0.98, 0.97); }
}
@keyframes lampHalo {
  0%, 100% { opacity: 0.6; }
  30%      { opacity: 1; }
  60%      { opacity: 0.7; }
}

/* each lamp swings on its own wire, on its own clock */
.lamp {
  transform-box: fill-box;
  transform-origin: center top;
  animation: lampSwing var(--period, 5.4s) ease-in-out infinite var(--delay, 0s);
}
@keyframes lampSwing {
  0%, 100% { transform: rotate(-2.4deg); }
  50%      { transform: rotate(2.4deg); }
}
/* the body lags the wire a touch, the way a hanging weight does */
.lamp__body {
  transform-box: fill-box;
  transform-origin: center top;
  animation: lampLag var(--period, 5.4s) ease-in-out infinite calc(var(--delay, 0s) - 0.28s);
}
@keyframes lampLag {
  0%, 100% { rotate: 1.6deg; }
  50%      { rotate: -1.6deg; }
}

@media (max-width: 40rem) {
  .lampstring { width: 190%; }
  .lamp:nth-child(2n) { display: none; }
}

.hero__inner {
  position: relative;
  width: 100%;
  max-width: 44rem;
  padding: clamp(3.5rem, 10vw, 5.5rem) var(--pad) 5.5rem;
  text-align: center;
}

/* ---------- the arch: a cusped frame generated to fit its content ---------- */
.arch__svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}
/* deliberately NOT non-scaling-stroke: with pathLength="1" the dash pattern is
   normalised in user space, while a non-scaling stroke dashes in screen space.
   If the two ever disagree the tail of the path goes undrawn, which shows up as
   a short bottom-right leg. Letting the stroke scale keeps both in one space. */
.arch__path {
  fill: none;
  stroke: url(#wireShineSlow);
  stroke-width: 1.4;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 12px rgba(232,200,116,0.25));
}
.arch__path--inner { stroke-width: 0.7; opacity: 0.5; filter: none; }

.arch {
  position: relative;
  padding: clamp(5rem, 13vw, 8rem) clamp(2rem, 7vw, 3.5rem) clamp(2.5rem, 6vw, 3.5rem);
}
.arch__frame {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(62% 46% at 50% 46%, rgba(232,200,116,0.09), transparent 72%),
    radial-gradient(90% 70% at 50% 55%, rgba(107,20,35,0.55), transparent 76%);
}
/* henna-style mandala, generated by tools/make_ornaments.py */
.arch__mandala {
  position: absolute;
  top: 46%;
  left: 50%;
  width: min(84%, 30rem);
  transform: translate(-50%, -50%);
  opacity: 0.16;
  pointer-events: none;
  animation: turn 90s linear infinite;
}
@keyframes turn { to { transform: translate(-50%, -50%) rotate(360deg); } }

/* crest above the apex */
.arch__crest {
  position: absolute;
  top: 0; left: 50%;
  width: clamp(64px, 16vw, 104px);
  transform: translate(-50%, -58%);
  color: var(--gold-500);
  pointer-events: none;
}
/* small pendants along the top inside of the arch */
.jhalar__drops path { fill: var(--gold-500); opacity: 0.85; }
.garland__drops circle, .garland__drops path { stroke-linecap: round; }
.arch__jhalar {
  position: absolute;
  top: clamp(0.9rem, 3vw, 1.6rem);
  left: 50%;
  width: min(78%, 30rem);
  transform: translateX(-50%);
  color: var(--gold-500);
  opacity: 0.75;
  pointer-events: none;
}

.hero__content { position: relative; }

.bismillah {
  font-family: var(--urdu);
  font-size: clamp(0.95rem, 0.82rem + 0.9vw, 1.4rem);
  line-height: 2.5;
  color: var(--gold-300);
  margin-bottom: 0.1rem;
}
.bismillah__translit {
  font-family: var(--serif-italic);
  font-style: italic;
  font-size: 0.88rem;
  color: rgba(246,238,221,0.58);
  margin-bottom: 1.9rem;
}
.hero__eyebrow {
  font-family: var(--serif-display);
  font-size: 0.62rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: rgba(246,238,221,0.7);
  margin-bottom: 1.3rem;
}

/* The invitation is issued by the parents, so their names carry the weight the
   couple's eyebrow used to. Sentence case and a serif, because this is a
   sentence a guest reads rather than a label above a heading. */
.hero__hosts {
  font-family: var(--serif-display);
  font-size: clamp(0.8rem, 0.72rem + 0.36vw, 0.98rem);
  line-height: 1.9;
  letter-spacing: 0.055em;
  color: var(--gold-300);
  margin-bottom: 0.55rem;
}
/* a person's name is one unit: let the line break at the "&" between two
   names, never in the middle of one. On a phone this is the difference
   between "Mohtarma / Rabia Pettiwala" and two clean lines. */
.hero__host { white-space: nowrap; }
.hero__hosts-join {
  display: block;
  font-family: var(--serif-italic);
  font-style: italic;
  font-size: 0.84em;
  letter-spacing: 0.02em;
  color: rgba(246,238,221,0.5);
}
.hero__request {
  font-family: var(--serif-italic);
  font-style: italic;
  font-size: clamp(0.92rem, 0.86rem + 0.28vw, 1.06rem);
  line-height: 1.6;
  color: var(--ivory-dim);
  /* held to a readable measure so it breaks into two tidy lines, not four */
  max-width: 36ch;
  margin: 0 auto 1.5rem;
  text-wrap: balance;
}

.hero__names {
  display: grid;
  justify-items: center;
  gap: 0.05em;
  font-size: clamp(2.3rem, 1.2rem + 5.4vw, 4.2rem);
  letter-spacing: 0.06em;
  color: var(--ivory);
}
.hero__name { white-space: nowrap; color: var(--ivory); }
.hero__name .char { display: inline-block; animation: charshine 6.5s ease-in-out infinite; }
@keyframes charshine {
  0%, 100% { color: var(--ivory);     text-shadow: 0 0 18px rgba(232,200,116,0.18); }
  45%      { color: var(--gold-100);  text-shadow: 0 0 26px rgba(232,200,116,0.55); }
}
/* if the text never gets split, the whole word shines together */
.hero__name:not(:has(.char)) { animation: charshine 6.5s ease-in-out infinite; }
.hero__amp {
  font-family: var(--serif-italic);
  font-style: italic;
  font-size: 0.52em;
  line-height: 1.1;
  color: var(--gold-300);
}

.hero__invite {
  font-family: var(--serif-italic);
  font-style: italic;
  font-size: 1.16rem;
  color: var(--ivory-dim);
  /* keeps "for the couple" from dropping a single word onto its own line */
  max-width: 32ch;
  margin: 0 auto 1.7rem;
  text-wrap: balance;
}

.hero__dates { display: grid; gap: 1.3rem; margin: 0; }
.hero__date dt {
  font-family: var(--serif-display);
  font-size: 0.64rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--gold-500);
  margin-bottom: 0.3rem;
}
.hero__date dd { margin: 0; display: grid; gap: 0.12rem; }
.hero__date b {
  font-family: var(--serif-display);
  font-weight: 500;
  font-size: 1.1rem;
  letter-spacing: 0.05em;
  color: var(--ivory);
}
.hero__date span { font-size: 0.92rem; color: rgba(246,238,221,0.66); }

@media (min-width: 36rem) {
  .hero__dates { grid-template-columns: 1fr 1fr; gap: 2rem; }
  .hero__date + .hero__date { border-left: 1px solid rgba(201,162,75,0.3); padding-left: 2rem; }
}

.scrollcue {
  position: absolute;
  left: 50%; bottom: clamp(1.1rem, 4vw, 2rem);
  transform: translateX(-50%);
  display: grid; justify-items: center; gap: 0.5rem;
  text-decoration: none;
  color: rgba(246,238,221,0.55);
  font-family: var(--serif-display);
  font-size: 0.58rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  transition: color 0.3s;
  z-index: 2;
}
.scrollcue:hover { color: var(--gold-300); }
.scrollcue svg { width: 14px; fill: none; stroke: currentColor; stroke-width: 1.4; animation: bob 2.6s var(--ease-silk) infinite; }
@keyframes bob {
  0%, 100% { transform: translateY(0); opacity: 0.5; }
  50%      { transform: translateY(6px); opacity: 1; }
}

/* ---------- the hero arrives on plain CSS, never on a script's ticker ---------- */
@keyframes riseIn { from { opacity: 0; translate: 0 18px; }  to { opacity: 1; translate: none; } }
@keyframes dropIn { from { opacity: 0; translate: 0 -22px; } to { opacity: 1; translate: none; } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes swingIn { from { translate: 0 -34px; } to { translate: none; } }
@keyframes popIn  { from { opacity: 0; scale: 0.6; }         to { opacity: 1; scale: none; } }
@keyframes charIn {
  from { opacity: 0; translate: 0 26px; rotate: x -55deg; }
  to   { opacity: 1; translate: none;   rotate: none; }
}

.hero.is-revealed .bismillah           { animation: riseIn 0.7s var(--ease-silk) both 0.10s; }
.hero.is-revealed .bismillah__translit { animation: fadeIn 0.7s ease both 0.26s; }
.hero.is-revealed .hero__eyebrow       { animation: riseIn 0.6s var(--ease-silk) both 0.32s; }
.hero.is-revealed .hero__name          { animation: riseIn 0.7s var(--ease-silk) both 0.40s; }
.hero.is-revealed .hero__name.is-split { animation: none; }
.hero.is-revealed .hero__name.is-split .char { animation: charIn 0.5s var(--ease-silk) both var(--d, 0s); }
.hero.is-revealed .hero__amp           { animation: popIn 0.55s cubic-bezier(0.2, 1.5, 0.4, 1) both 0.58s; }
.hero.is-revealed .rule--gold          { animation: fadeIn 0.7s ease both 0.68s; }
.hero.is-revealed .hero__invite        { animation: riseIn 0.6s var(--ease-silk) both 0.76s; }
.hero.is-revealed .hero__date          { animation: riseIn 0.6s var(--ease-silk) both var(--d, 0.84s); }
.hero.is-revealed .arch__crest         { animation: riseIn 0.9s var(--ease-silk) both 0.12s; }
.hero.is-revealed .arch__jhalar        { animation: dropIn 0.9s var(--ease-silk) both 0.22s; }
.hero.is-revealed .lampstring          { animation: swingIn 1.2s cubic-bezier(0.2, 1.3, 0.4, 1) both 0.04s; }

/* ---------- the cat, bent from one gold wire ---------- */
.cat {
  position: absolute;
  left: 5%;
  bottom: clamp(0.5rem, 4vh, 3.5rem);
  width: clamp(104px, 13vw, 164px);
  opacity: 0;
  z-index: 3;
  pointer-events: none;
  filter: drop-shadow(0 0 9px rgba(232, 200, 116, 0.4));
}
.cat svg { width: 100%; height: auto; overflow: visible; }

/* the wire itself: rounded ends and joins, with a highlight travelling along it */
.cat__ln {
  fill: none;
  stroke: url(#wireShine);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.cat__ln--fine { stroke-width: 1.2; opacity: 0.8; }
.cat__eye { fill: var(--gold-100); stroke: none; }
.cat__nose { fill: #C7622F; stroke: none; }

/* she arrives quietly, already settled, once the curtain opens */
.cat.is-here { opacity: 1; animation: catArrive 1.6s cubic-bezier(0.22, 0.61, 0.36, 1) both 1.1s; }
@keyframes catArrive {
  from { translate: 0 14px; }
  to   { translate: none; }
}

/* the tail is one piece lying along the ground, so the tip stirs as one wire */
.cat__tail {
  transform-box: fill-box;
  transform-origin: left bottom;
  animation: tailStir 7s ease-in-out infinite;
}
@keyframes tailStir {
  0%, 100% { rotate: 0deg; }
  30%      { rotate: -2.6deg; }
  55%      { rotate: -0.8deg; }
  75%      { rotate: -3.2deg; }
}

.cat__eye { transform-box: fill-box; transform-origin: center; animation: blink 6.5s infinite; }
@keyframes blink {
  0%, 93%, 100% { scale: 1 1; }
  95%           { scale: 1 0.08; }
}

@media (max-width: 34rem) { .cat { left: 3%; width: 100px; } }

/* =========================================================
   CURTAIN
   ========================================================= */
.curtain {
  position: absolute;
  inset: 0;
  z-index: 20;
  overflow: hidden;
  touch-action: none;
  perspective: 1500px;
}
.curtain.is-open { pointer-events: none; }

.curtain__panel {
  position: absolute;
  top: 0; bottom: 0;
  width: 52%;
  background: linear-gradient(180deg, #8d2033, var(--maroon-800) 58%, #1e0407);
  box-shadow: 0 0 80px rgba(0,0,0,0.65);
  transform-style: preserve-3d;
  will-change: transform;
}
.curtain__panel--left  { left: 0;  transform-origin: left center; }
.curtain__panel--right { right: 0; transform-origin: right center; }

/* the fabric itself: individual folds that gather as the curtain draws back */
.curtain__folds {
  position: absolute;
  inset: 0;
  overflow: hidden;
  will-change: transform;
}
.curtain__panel--left  .curtain__folds { transform-origin: left center; }
.curtain__panel--right .curtain__folds { transform-origin: right center; }

.fold {
  position: absolute;
  top: -2%;
  bottom: -2%;
  background:
    linear-gradient(90deg,
      rgba(0,0,0,0.62) 0%,
      rgba(0,0,0,0.16) 26%,
      rgba(255,214,222,0.10) 48%,
      rgba(0,0,0,0.20) 72%,
      rgba(0,0,0,0.58) 100%);
  transform-origin: center bottom;
  animation: breathe 7s ease-in-out infinite;
}
/* a warm sheen where the light catches the velvet */
.fold::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(255,180,190,0.10), transparent 42%, rgba(0,0,0,0.35));
  mix-blend-mode: soft-light;
}
@keyframes breathe {
  0%, 100% { transform: scaleX(1)    skewX(0deg); }
  35%      { transform: scaleX(1.05) skewX(0.5deg); }
  70%      { transform: scaleX(0.97) skewX(-0.4deg); }
}

/* the hem pools slightly at the bottom */
.curtain__panel::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 14%;
  background: linear-gradient(180deg, transparent, rgba(0,0,0,0.55));
  pointer-events: none;
}

/* braided gold edging where the panels meet */
.curtain__trim {
  position: absolute;
  top: 0; bottom: 0;
  width: 16px;
  background:
    repeating-linear-gradient(115deg,
      rgba(0,0,0,0.28) 0 3px,
      rgba(232,200,116,0.85) 3px 6px,
      rgba(168,133,58,0.9) 6px 10px),
    linear-gradient(90deg, rgba(0,0,0,0.55), var(--gold-600) 40%, var(--gold-300) 55%, var(--gold-600) 72%, rgba(0,0,0,0.5));
  box-shadow: 0 0 18px rgba(0,0,0,0.55);
}
.curtain__panel--left  .curtain__trim { right: 0; }
.curtain__panel--right .curtain__trim { left: 0; }

.curtain__valance {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: clamp(34px, 6vw, 58px);
  z-index: 3;
  background:
    repeating-linear-gradient(90deg, rgba(0,0,0,0.3) 0 12px, rgba(255,255,255,0.05) 12px 26px),
    linear-gradient(180deg, #8a2032, var(--maroon-900));
  border-bottom: 2px solid var(--gold-600);
  box-shadow: 0 8px 24px rgba(0,0,0,0.55);
}
/* scalloped hem on the valance */
.curtain__valance::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -12px;
  height: 14px;
  background: radial-gradient(circle at 12px -2px, var(--maroon-600) 11px, transparent 12px) repeat-x;
  background-size: 24px 14px;
  filter: drop-shadow(0 2px 3px rgba(0,0,0,0.5));
}

.curtain__prompt {
  position: absolute;
  left: 0; right: 0;
  bottom: clamp(3rem, 12vh, 7rem);
  z-index: 4;
  text-align: center;
  padding-inline: var(--pad);
}
.curtain__kicker {
  font-family: var(--serif-display);
  font-size: clamp(1.1rem, 0.9rem + 1.6vw, 1.9rem);
  letter-spacing: 0.16em;
  color: var(--gold-300);
  margin-bottom: 0.5rem;
}
.curtain__hint {
  font-family: var(--serif-italic);
  font-style: italic;
  font-size: 1rem;
  color: rgba(246,238,221,0.7);
  margin: 0 0 0.9rem;
}
.curtain__meter {
  width: min(180px, 50vw);
  height: 2px;
  margin: 0 auto;
  background: rgba(201,162,75,0.22);
  overflow: hidden;
}
.curtain__meter i { display: block; height: 100%; width: 0%; background: linear-gradient(90deg, var(--gold-600), var(--gold-100)); }

.tassel {
  position: absolute;
  top: 0; left: 50%;
  z-index: 6;
  display: grid;
  justify-items: center;
  padding: 0 1.6rem 1.6rem;
  margin: 0;
  border: 0;
  background: none;
  cursor: grab;
  touch-action: none;
  transform: translateX(-50%);
  transform-origin: top center;
  -webkit-tap-highlight-color: transparent;
}
.tassel:active { cursor: grabbing; }
.tassel__cord {
  width: 4px;
  height: clamp(56px, 12vh, 100px);
  background:
    repeating-linear-gradient(150deg, var(--gold-600) 0 3px, var(--gold-300) 3px 6px);
  border-radius: 2px;
  box-shadow: 0 0 8px rgba(0,0,0,0.5);
}
.tassel__knot {
  width: 20px; height: 20px;
  margin-top: -3px;
  border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, var(--gold-100), var(--gold-500) 62%, #6d5320);
  box-shadow: 0 2px 10px rgba(0,0,0,0.55);
}
.tassel__skirt {
  width: 30px; height: 46px;
  margin-top: -4px;
  border-radius: 5px 5px 15px 15px;
  background: repeating-linear-gradient(90deg, var(--gold-600) 0 2px, var(--gold-300) 2px 4px);
  box-shadow: 0 8px 16px rgba(0,0,0,0.5);
  clip-path: polygon(12% 0, 88% 0, 100% 74%, 92% 100%, 74% 84%, 58% 100%, 42% 84%, 26% 100%, 8% 74%, 0 74%);
}
.curtain:not(.is-open) .tassel:not(.is-dragging) { animation: sway 4.5s ease-in-out infinite; }
@keyframes sway {
  0%, 100% { transform: translateX(-50%) rotate(-2deg); }
  50%      { transform: translateX(-50%) rotate(2deg); }
}

/* =========================================================
   COUNTDOWN
   ========================================================= */
.clock {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.75rem, 2.4vw, 1.5rem);
  list-style: none;
  margin: clamp(2.25rem, 6vw, 3.25rem) auto 0;
  padding: 0;
  max-width: 48rem;
}
@media (min-width: 40rem) { .clock { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.clock__unit { display: grid; justify-items: center; gap: 0.65rem; }
.clock__frame {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 1;
  border: 1px solid rgba(201,162,75,0.45);
  background:
    radial-gradient(80% 80% at 50% 20%, rgba(107,20,35,0.55), transparent 70%),
    rgba(0,0,0,0.22);
  clip-path: polygon(22% 0, 78% 0, 100% 22%, 100% 78%, 78% 100%, 22% 100%, 0 78%, 0 22%);
}
.clock__frame::before {
  content: "";
  position: absolute;
  inset: 7px;
  border: 1px solid rgba(201,162,75,0.22);
  clip-path: polygon(22% 0, 78% 0, 100% 22%, 100% 78%, 78% 100%, 22% 100%, 0 78%, 0 22%);
}
.clock__num {
  font-family: var(--serif-display);
  font-size: clamp(1.9rem, 1rem + 4.4vw, 3.1rem);
  line-height: 1;
  color: var(--gold-300);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 26px rgba(232,200,116,0.28);
}
.clock__label {
  font-family: var(--serif-display);
  font-size: 0.58rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(246,238,221,0.62);
}

.clock__year {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.8rem;
  margin-top: clamp(1.75rem, 5vw, 2.5rem);
  font-family: var(--serif-italic);
  font-style: italic;
  color: rgba(246,238,221,0.66);
}
.clock__ring { display: block; width: min(220px, 50vw); height: 2px; background: rgba(201,162,75,0.25); }
.clock__ring i { display: block; height: 100%; width: 0%; background: linear-gradient(90deg, var(--gold-600), var(--gold-100)); }
.clock__message {
  margin-top: 1.4rem;
  font-family: var(--serif-italic);
  font-style: italic;
  font-size: 1.2rem;
  color: var(--gold-300);
  min-height: 1.4em;
}

/* the two places we studied, kept as faint marks in the background */
.placemark {
  position: absolute;
  margin: 0;
  opacity: 0.5;
  pointer-events: none;
  z-index: 0;
  filter: drop-shadow(0 0 18px rgba(0,0,0,0.5));
}
.placemark--him {
  left: clamp(-2rem, -1vw, 0rem);
  bottom: clamp(1rem, 4vw, 3rem);
  width: clamp(230px, 34vw, 460px);
}
.placemark--her {
  right: clamp(-1rem, 0vw, 1rem);
  bottom: clamp(1rem, 4vw, 3rem);
  width: clamp(120px, 17vw, 230px);
}
.placemark svg, .placemark img { width: 100%; height: auto; }
@media (max-width: 60rem) { .placemark { opacity: 0.3; } .placemark--him { width: 62vw; } .placemark--her { width: 30vw; } }

.events .wrap { position: relative; z-index: 1; }

/* =========================================================
   EVENTS
   ========================================================= */
.events__grid {
  display: grid;
  gap: clamp(1.5rem, 4vw, 2.5rem);
  margin-top: clamp(2.5rem, 7vw, 3.75rem);
}
@media (min-width: 48rem) { .events__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.card { position: relative; perspective: 1000px; }
.card__frame {
  position: relative;
  height: 100%;
  overflow: hidden;
  padding: clamp(1.1rem, 3vw, 1.5rem);
  border: 1px solid rgba(201,162,75,0.55);
  outline: 1px solid rgba(201,162,75,0.18);
  outline-offset: 6px;
  background: linear-gradient(180deg, rgba(107,20,35,0.35), rgba(0,0,0,0.28));
  display: grid;
  align-content: start;
  text-align: left;
  transform-style: preserve-3d;
}
.card__sheen {
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 38%, rgba(247,231,190,0.14) 48%, transparent 58%);
  transform: translateX(-120%);
  pointer-events: none;
}
.card:hover .card__sheen { transform: translateX(120%); transition: transform 1.1s var(--ease-silk); }

.card__art {
  margin: 0 0 1.35rem;
  padding: 5px;
  border: 1px solid rgba(201,162,75,0.45);
  background: linear-gradient(135deg, rgba(201,162,75,0.2), rgba(201,162,75,0.04) 45%, rgba(201,162,75,0.2));
  overflow: hidden;
}
.card__art img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  object-position: center 34%;
  transition: transform 1.4s var(--ease-silk);
}
.card:hover .card__art img { transform: scale(1.055); }

.card__kicker {
  font-family: var(--serif-display);
  font-size: 0.6rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold-500);
  margin-bottom: 0.35rem;
}
.card__title {
  font-size: clamp(1.7rem, 1.2rem + 2.2vw, 2.35rem);
  letter-spacing: 0.08em;
  color: var(--gold-300);
  margin-bottom: 0.6rem;
}
.card__date { margin-bottom: 0.15rem; }
.card__date b { font-family: var(--serif-display); font-weight: 500; letter-spacing: 0.04em; }
.card__time { font-family: var(--serif-italic); font-style: italic; color: rgba(246,238,221,0.6); margin-bottom: 0; }

/* the host line sits with the date and time, above the rule that separates
   the when from the where */
.card__host {
  font-family: var(--serif-italic);
  font-style: italic;
  font-size: 0.88rem;
  line-height: 1.55;
  color: rgba(246,238,221,0.6);
  margin: 0.5rem 0 0;
}

.card__divider {
  width: 64px; height: 1px;
  background: linear-gradient(90deg, var(--gold-500), transparent);
  margin: 1.15rem 0 1.3rem;
}

.card__venue {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: 0.7rem;
  align-items: start;
  color: rgba(246,238,221,0.82);
  margin-bottom: 1.5rem;
  line-height: 1.55;
}
.card__venue b {
  display: block;
  font-family: var(--serif-display);
  font-weight: 500;
  letter-spacing: 0.03em;
  color: var(--ivory);
  margin-bottom: 0.2rem;
}
.pin { width: 22px; height: 22px; margin-top: 3px; fill: none; stroke: var(--gold-500); stroke-width: 1.3; }

.card__actions { display: flex; flex-wrap: wrap; gap: 0.6rem; margin: 0; }

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.62rem 1.25rem;
  border: 1px solid var(--gold-500);
  background: none;
  color: var(--gold-300);
  font-family: var(--serif-display);
  font-size: 0.64rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.35s, color 0.35s, border-color 0.35s;
}
.btn:hover { background: var(--gold-500); color: var(--maroon-900); }
.btn--ghost { border-color: rgba(201,162,75,0.45); color: rgba(246,238,221,0.85); }
.btn--ghost:hover { background: rgba(201,162,75,0.2); color: var(--gold-100); }
.btn.is-done { background: rgba(201,162,75,0.2); color: var(--gold-100); }

[data-tbd] { border-bottom: 1px dashed rgba(201,162,75,0.5); padding-bottom: 1px; }

/* =========================================================
   THE BARAT TRAIN, MUMBAI TO LUCKNOW
   ========================================================= */
.journey { margin-top: clamp(3rem, 8vw, 5rem); }
.journey__kicker {
  font-family: var(--serif-display);
  font-size: 0.62rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold-500);
  margin-bottom: 1.6rem;
}
/* The track and the train are pinned to each other rather than to the box, so
   the wheels stay on the railhead at every width.
     land svg is 150 tall in its viewBox, railhead at y=118, stretched to --land-h
       -> railhead sits 0.21333 * --land-h above the svg's bottom edge
     train svg is 96 tall in its viewBox, wheels bottom out at y=88
       -> wheels sit (8/420) * --train-w above the train box's bottom edge */
.journey__scene {
  --land-h:  clamp(80px, 14vw, 150px);
  --train-w: clamp(190px, 40vw, 420px);
  --rail-up: calc(3.1rem + var(--train-w) / 52.5);   /* railhead, from scene bottom */
  position: relative;
  overflow: hidden;
  min-height: clamp(190px, 27vw, 320px);
  padding-bottom: 3.6rem;
}
.journey__land {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(var(--rail-up) - var(--land-h) * 0.21333);
  width: 100%;
  height: var(--land-h);
  color: var(--gold-500);
  opacity: 0.55;
}
.journey__land .sleepers { opacity: 0.5; }

.journey__train {
  position: absolute;
  left: 0;
  bottom: 3.1rem;
  width: var(--train-w);
  color: var(--gold-300);
  will-change: transform;
}
.journey__train .ln { stroke: url(#wireShineSlow); }
.journey__train svg {
  width: 100%;
  height: auto;
  overflow: visible;
  transform: scaleX(-1);   /* engine at the front, running Mumbai to Lucknow */
}
.train__marigolds circle { fill: #C7622F; }
.garland-line { opacity: 0.8; }
.folk__head { fill: var(--gold-100); stroke: none; }
.folk__veil { fill: none; stroke: #C7622F; stroke-width: 2; stroke-linecap: round; }
.folk__sehra, .folk__wave { fill: none; stroke: var(--gold-300); stroke-width: 1.4; stroke-linecap: round; }
.wheel { stroke-width: 1.2; }

.smoke circle { fill: rgba(246,238,221,0.16); animation: puff 3.2s ease-out infinite; }
.smoke circle:nth-child(2) { animation-delay: 0.35s; }
.smoke circle:nth-child(3) { animation-delay: 0.7s; }
.smoke circle:nth-child(4) { animation-delay: 1.05s; }
@keyframes puff {
  0%   { opacity: 0;    transform: translate(0, 8px) scale(0.5); }
  30%  { opacity: 0.55; }
  100% { opacity: 0;    transform: translate(26px, -34px) scale(1.5); }
}

.journey__station {
  position: absolute;
  bottom: 0.6rem;
  display: grid;
  gap: 0.1rem;
  margin: 0;
  font-size: 0.82rem;
  line-height: 1.3;
}
.journey__station b {
  font-family: var(--serif-display);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-300);
}
.journey__station span { color: rgba(246,238,221,0.55); font-family: var(--serif-italic); font-style: italic; }
.journey__station--from { left: 0; text-align: left; }
.journey__station--to   { right: 0; text-align: right; }
.journey__station::before {
  content: "";
  position: absolute;
  top: -1.5rem;
  width: 9px; height: 9px;
  border: 1px solid var(--gold-500);
  background: var(--maroon-900);
  transform: rotate(45deg);
}
.journey__station--from::before { left: 2px; }
.journey__station--to::before   { right: 2px; }

.journey__note {
  margin: 1.6rem 0 0;
  font-family: var(--serif-italic);
  font-style: italic;
  color: rgba(246,238,221,0.62);
}

/* =========================================================
   THE AYAH
   ========================================================= */
.ayah { text-align: center; }

/* the Arabic is shipped as outlines and hidden from assistive tech, so this
   carries the actual verse for a screen reader. Moved off-screen rather than
   display:none, which would drop it out of the accessibility tree as well. */
.ayah__sr {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.ayah__wire {
  max-width: min(92%, 46rem);
  margin: 1.6rem auto 2rem;
}
.ayah__svg { width: 100%; height: auto; overflow: visible; }

/* thinner than the rest of the line-art: at this size the letterforms carry
   their own weight, and a heavier wire closes up the counters in the script */
.ayah__ln {
  fill: none;
  stroke: url(#ayahShine);
  stroke-width: 1.15;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 9px rgba(232,200,116,0.22));
}

.ayah__translation {
  font-family: var(--serif-italic);
  font-style: italic;
  font-size: clamp(1rem, 0.94rem + 0.3vw, 1.16rem);
  line-height: 1.75;
  color: var(--ivory-dim);
  /* wide enough to sit under the calligraphy rather than in a column beside it */
  max-width: 52ch;
  margin: 0 auto 0.9rem;
  text-wrap: balance;
}
.ayah__ref {
  font-family: var(--serif-display);
  font-size: 0.62rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold-500);
}

@media (max-width: 40rem) {
  /* the verse is the one thing here that must be legible before it is
     beautiful, so it takes more of the screen than the other artwork does */
  .ayah__wire { max-width: 100%; }
  .ayah__ln { stroke-width: 1.4; }
}

/* =========================================================
   POEM
   ========================================================= */
.poem {
  background: radial-gradient(120% 100% at 50% 0%, var(--maroon-800), var(--maroon-900) 70%);
  overflow: hidden;
  padding-block: clamp(5rem, 14vw, 9.5rem);
}
.poem::before { content: ""; position: absolute; inset: 0; opacity: 0.05; pointer-events: none; }
.poem__fireflies { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.poem .wrap { position: relative; z-index: 2; }

/* ---------- the mehfil: a wire bends itself into a stage ---------- */
.mehfil {
  position: absolute;
  right: clamp(0.5rem, 1.5vw, 2.5rem);
  bottom: clamp(2rem, 7vw, 5.5rem);
  width: clamp(230px, 28vw, 420px);
  pointer-events: none;
  z-index: 1;
}
/* the opacity lives on the svg, so the reveal is free to animate the wrapper */
.mehfil__svg { width: 100%; height: auto; overflow: visible; opacity: 0.62; }
.mehfil__ln {
  fill: none;
  stroke: url(#wireShineSlow);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.mehfil__ln--thin { stroke-width: 0.9; opacity: 0.7; }
@media (max-width: 60rem) {
  .mehfil { width: 54vw; right: -6vw; }
  .mehfil__svg { opacity: 0.4; }
}

.poem__text {
  font-family: var(--urdu);
  font-size: clamp(1rem, 0.82rem + 1.3vw, 1.7rem);
  line-height: 2.9;
  color: var(--ivory);
  margin-top: 2.4rem;
}
.poem__text p { margin: 0 0 0.3em; text-shadow: 0 0 30px rgba(232,200,116,0.2); }

/* =========================================================
   GALLERY
   ========================================================= */
.gallery__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.75rem, 2.4vw, 1.5rem);
  list-style: none;
  padding: 0;
  margin: clamp(2.5rem, 7vw, 3.75rem) 0 0;
}
@media (min-width: 48rem) { .gallery__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.frame {
  aspect-ratio: 4 / 5;
  padding: 9px;
  border: 2px solid var(--gold-500);
  background: linear-gradient(135deg, rgba(201,162,75,0.2), rgba(201,162,75,0.04) 42%, rgba(201,162,75,0.2));
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.5);
}
.frame--feature { grid-column: span 2; grid-row: span 2; aspect-ratio: auto; }

.frame__inner {
  position: relative;
  height: 100%;
  width: 100%;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 0.55rem;
  padding: 0;
  border: 1px solid rgba(168,133,58,0.5);
  background: linear-gradient(180deg, #fbf6ea, #f0e5cd);
  overflow: hidden;
}

.frame--photo .frame__inner {
  display: block;
  appearance: none;
  font: inherit;
  color: inherit;
  background: var(--maroon-900);
  cursor: zoom-in;
}
.frame--photo picture, .frame--photo img { display: block; width: 100%; height: 100%; }
.frame--photo img { object-fit: cover; transition: transform 1.6s var(--ease-silk); }
.frame--photo .frame__inner:hover img { transform: scale(1.06); }
.frame--feature img { object-position: center 20%; }

.frame__cap--over {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 2.4rem 0.8rem 0.75rem;
  font-family: var(--serif-italic);
  font-style: italic;
  font-size: clamp(0.8rem, 0.74rem + 0.28vw, 0.98rem);
  line-height: 1.35;
  color: var(--ivory);
  text-align: center;
  background: linear-gradient(180deg, transparent, rgba(44,6,13,0.85) 62%);
}

.frame__mono {
  font-family: var(--serif-display);
  font-size: clamp(1.35rem, 1.1rem + 1.5vw, 2rem);
  letter-spacing: 0.08em;
  color: var(--maroon-600);
}
.frame__mono i { font-family: var(--serif-italic); font-style: italic; color: var(--gold-600); }
.frame__cap {
  font-family: var(--serif-italic);
  font-style: italic;
  font-size: clamp(0.78rem, 0.72rem + 0.28vw, 0.92rem);
  color: var(--ink-soft);
  opacity: 0.75;
  padding-inline: 0.5rem;
  text-align: center;
}

/* =========================================================
   LIGHTBOX
   ========================================================= */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: clamp(0.25rem, 2vw, 1.5rem);
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(20,3,7,0.94);
  backdrop-filter: blur(6px);
}
.lightbox[hidden] { display: none; }
.lightbox__stage { margin: 0; display: grid; justify-items: center; gap: 1rem; min-width: 0; }
.lightbox__stage img {
  max-width: 100%;
  max-height: 76svh;
  width: auto;
  border: 1px solid rgba(201,162,75,0.6);
  padding: 6px;
  background: rgba(201,162,75,0.1);
}
.lightbox__stage figcaption {
  font-family: var(--serif-italic);
  font-style: italic;
  color: var(--ivory-dim);
  text-align: center;
}
.lightbox__nav, .lightbox__close {
  border: 1px solid rgba(201,162,75,0.5);
  background: rgba(0,0,0,0.35);
  color: var(--gold-300);
  width: clamp(38px, 8vw, 48px);
  height: clamp(38px, 8vw, 48px);
  line-height: 1;
  font-size: 1.5rem;
  cursor: pointer;
  transition: background-color 0.3s, color 0.3s;
}
.lightbox__nav:hover, .lightbox__close:hover { background: var(--gold-500); color: var(--maroon-900); }
.lightbox__close { position: absolute; top: clamp(0.75rem, 3vw, 1.5rem); right: clamp(0.75rem, 3vw, 1.5rem); font-size: 1.6rem; }

/* =========================================================
   FOOTER
   ========================================================= */
.footer {
  position: relative;
  background: var(--maroon-900);
  border-top: 1px solid rgba(201,162,75,0.28);
  padding-block: clamp(3.25rem, 9vw, 5.5rem);
  text-align: center;
}
.skyline { margin: 0 auto clamp(1.5rem, 4vw, 2.25rem); max-width: 34rem; }
.skyline .ln--him  { color: var(--terracotta); }
.skyline .ln--her  { color: var(--dustyblue); }
.skyline .ln--gold { color: var(--gold-500); }

.footer__names {
  font-family: var(--serif-display);
  font-size: clamp(1.4rem, 1.1rem + 1.8vw, 2.2rem);
  letter-spacing: 0.09em;
  color: var(--gold-300);
  margin-bottom: 0.4rem;
}
.footer__dates {
  font-family: var(--serif-display);
  font-size: 0.7rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--ivory-dim);
  margin-bottom: 0.25rem;
}
.footer__cities { font-family: var(--serif-italic); font-style: italic; color: rgba(246,238,221,0.58); margin-bottom: 0.5rem; }
.footer__families {
  font-family: var(--serif-italic);
  font-style: italic;
  color: rgba(246,238,221,0.52);
  margin-bottom: 2rem;
}

.footer__rsvp { display: grid; gap: 0.35rem; margin-bottom: 2.25rem; }
/* the grid gap is the only spacing wanted here: paragraph margins on top of it
   pushed the two numbers apart far enough to read as separate blocks */
.footer__rsvp p { margin: 0; }
.footer__rsvp-label {
  font-family: var(--serif-display);
  font-size: 0.6rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--gold-500);
}
.footer__rsvp-value { color: var(--ivory-dim); }
/* guests read this on a phone: the number should be one tap, not something
   to copy out by hand */
.footer__rsvp-value a {
  color: var(--gold-300);
  text-decoration: none;
  border-bottom: 1px solid rgba(201,162,75,0.35);
  padding-bottom: 1px;
  white-space: nowrap;
}
.footer__rsvp-value a:hover,
.footer__rsvp-value a:focus-visible { color: var(--gold-100); border-bottom-color: var(--gold-300); }
.footer__dua { display: grid; gap: 0.6rem; margin: 0; }
.footer__dua span {
  font-family: var(--urdu);
  font-size: clamp(0.85rem, 0.78rem + 0.4vw, 1.05rem);
  line-height: 2.4;
  color: var(--gold-300);
}
.footer__dua em { font-family: var(--serif-italic); font-size: 0.92rem; color: rgba(246,238,221,0.55); }

/* =========================================================
   WEDDING THEMING: garlands, sprigs, monogram, lights
   ========================================================= */
.garland {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: min(115%, 78rem);
  pointer-events: none;
  z-index: 1;
}
.garland--section { top: -0.5rem; opacity: 0.65; }
.garland__cord { fill: none; stroke: var(--gold-600); stroke-width: 1.6; vector-effect: non-scaling-stroke; }
.garland__flowers circle { fill: #C7622F; opacity: 0.92; }
.garland__flowers .garland__pip { fill: var(--gold-300); opacity: 1; }
.garland__leaves path { fill: #5F7A54; opacity: 0.85; }
.garland__drops path { fill: none; stroke: var(--gold-500); stroke-width: 1.2; vector-effect: non-scaling-stroke; }
.garland__drops circle { fill: var(--gold-300); }
.garland__flowers g { transform-box: fill-box; transform-origin: center; animation: bloom 6s ease-in-out infinite; }
.garland__flowers g:nth-child(2n) { animation-delay: -1.6s; }
.garland__flowers g:nth-child(3n) { animation-delay: -3.1s; }
@keyframes bloom {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.07); }
}

.sprig {
  position: absolute;
  width: clamp(56px, 10vw, 108px);
  color: var(--gold-600);
  opacity: 0.55;
  pointer-events: none;
}
.sprig__buds circle { fill: #C7622F; opacity: 0.75; }
.sprig--l { left: clamp(0.5rem, 2.5vw, 2.5rem); bottom: clamp(1rem, 4vw, 3rem); }
.sprig--r { right: clamp(0.5rem, 2.5vw, 2.5rem); bottom: clamp(1rem, 4vw, 3rem); transform: scaleX(-1); }

.wheel { width: clamp(150px, 34vw, 240px); margin: 0 auto clamp(1.5rem, 4vw, 2.25rem); }
.wheel svg { width: 100%; height: auto; overflow: visible; }

.wheel__ln, .wheel__rim, .wheel__spokes, .cabin__box {
  fill: none;
  stroke: var(--gold-500);
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.wheel__ln--thin { stroke-width: 0.8; opacity: 0.6; }
.wheel__rim { stroke-width: 1.6; }
.wheel__rim--thin { stroke-width: 0.8; opacity: 0.6; }
.wheel__spokes { stroke-width: 0.7; opacity: 0.55; }
.wheel__hub { fill: var(--gold-500); stroke: none; }
.wheel__hub--pin { fill: var(--maroon-900); }
.cabin__box { fill: rgba(107,20,35,0.65); }
.cabin--couple .cabin__box { fill: rgba(181,54,75,0.35); stroke: var(--gold-300); }

.wheel__lights circle { fill: var(--gold-300); animation: twinkle 2.8s ease-in-out infinite; }
.wheel__lights circle:nth-child(2n) { animation-delay: -0.9s; }
.wheel__lights circle:nth-child(3n) { animation-delay: -1.7s; }

.rider__head { fill: var(--gold-100); }
.rider__veil { fill: none; stroke: #C7622F; stroke-width: 1.4; stroke-linecap: round; }
.rider__sehra { fill: none; stroke: var(--gold-300); stroke-width: 0.8; stroke-linecap: round; }

/* the wheel turns, and every cabin stays upright as it goes round */
.wheel__spin {
  transform-box: view-box;
  transform-origin: 120px 118px;
  animation: turnwheel 26s linear infinite;
}
.cabin__swing {
  transform-box: fill-box;
  transform-origin: center top;
  animation: turnwheel 26s linear infinite reverse;
}
@keyframes turnwheel { to { transform: rotate(360deg); } }

.wheel__caption {
  margin: 0.75rem 0 0;
  font-family: var(--serif-display);
  font-size: clamp(0.72rem, 0.66rem + 0.4vw, 0.9rem);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-300);
}
.wheel__caption i { font-family: var(--serif-italic); font-style: italic; text-transform: none; color: var(--gold-600); }

/* lit windows, beacons, lamps */
.twinkle circle { fill: var(--gold-300); animation: twinkle 3.4s ease-in-out infinite; }
.twinkle--fast circle { animation-duration: 1.9s; }
.twinkle circle:nth-child(2n)  { animation-delay: -0.7s; }
.twinkle circle:nth-child(3n)  { animation-delay: -1.5s; }
.twinkle circle:nth-child(5n)  { animation-delay: -2.3s; }
.twinkle circle:nth-child(7n)  { animation-delay: -1.1s; }
@keyframes twinkle {
  0%, 100% { opacity: 0.35; }
  40%      { opacity: 1; }
  60%      { opacity: 0.7; }
}
.beacon { fill: var(--gold-100); animation: beacon 4s ease-in-out infinite; }
@keyframes beacon {
  0%, 100% { opacity: 0.4; filter: drop-shadow(0 0 2px rgba(232,200,116,0.5)); }
  50%      { opacity: 1;   filter: drop-shadow(0 0 8px rgba(232,200,116,0.95)); }
}
.lamp-glow { fill: rgba(232,200,116,0.28); animation: glowpulse 5s ease-in-out infinite; }
@keyframes glowpulse {
  0%, 100% { opacity: 0.45; }
  50%      { opacity: 0.95; }
}

/* lantern flames flicker rather than sit still */
.lantern__flame {
  transform-box: fill-box;
  transform-origin: center bottom;
  animation: flicker 3.1s ease-in-out infinite;
}
.lantern--2 .lantern__flame { animation-duration: 2.3s; animation-delay: -0.8s; }
.lantern--3 .lantern__flame { animation-duration: 3.7s; animation-delay: -1.6s; }
.lantern--4 .lantern__flame { animation-duration: 2.7s; animation-delay: -2.2s; }
@keyframes flicker {
  0%, 100% { opacity: 0.55; transform: scale(1, 1); }
  18%      { opacity: 0.95; transform: scale(1.06, 1.1); }
  32%      { opacity: 0.6;  transform: scale(0.96, 0.94); }
  54%      { opacity: 1;    transform: scale(1.05, 1.12); }
  70%      { opacity: 0.7;  transform: scale(0.98, 0.97); }
}

/* fireflies drift over the dark sections */
.jugnu-layer { position: absolute; inset: 0; pointer-events: none; z-index: 1; }

/* =========================================================
   ANIMATION STATES
   Reveals run on plain CSS transitions driven by an
   IntersectionObserver, so nothing can be left invisible if a
   scroll library mismeasures the page.
   ========================================================= */
/* Nothing is hidden by the stylesheet. JS hides only what is below the fold
   at load, so a broken script can never leave the invitation blank. */
.reveal-wait {
  opacity: 0;
  translate: 0 24px;
  transition:
    opacity 0.9s ease var(--reveal-delay, 0s),
    translate 0.9s cubic-bezier(0.22, 0.61, 0.36, 1) var(--reveal-delay, 0s);
}
.reveal-wait.is-in { opacity: 1; translate: none; }

/* the dash is 6% longer than the path: browsers estimate arc lengths, and on
   paths built from many arcs the estimate can fall short, which used to leave
   the right side of the arch undrawn */
.draw-wait {
  stroke-dasharray: 1.06;
  stroke-dashoffset: 1.06;
  transition: stroke-dashoffset 1.7s ease var(--draw-delay, 0s);
}
.draw-wait.is-in { stroke-dashoffset: 0; }

/* =========================================================
   REDUCED MOTION
   ========================================================= */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .reveal-wait { opacity: 1 !important; transform: none !important; }
  .draw-wait { stroke-dashoffset: 0 !important; }
}
