/* ===========================================================================
   Drashti & Akash — Ram Mandir wedding invitation
   ---------------------------------------------------------------------------
   HOW THIS FILE IS LAID OUT

   The invitation is one tall painting, not a stack of boxes: a temple, a
   mountain range, hanging bells and carved pillars all have to stay in
   register with each other. So the page is drawn on a fixed design canvas
   which assets/js/stage.js scales to fit the window.

     wide canvas    1515 x 12523   (desktops and landscape tablets)
     narrow canvas   394 x  6387   (phones and portrait tablets)

   Whichever canvas is in play is scaled to the *full* width of the window,
   so the painting reaches both edges at every size — a 320px phone, a 768px
   iPad, a 1440px laptop and a 2560px monitor all see the same composition,
   only larger or smaller. Nothing is ever letterboxed into a column with
   the page colour showing down the sides. Section 8 says which canvas is
   chosen where.

   Every length below is therefore a coordinate on that canvas, and the two
   canvases are simply two sets of coordinates for the same markup: the wide
   one throughout, the narrow one in "THE NARROW CANVAS" at the end.

     1. Tokens and reset
     2. The stage
     3. Motion — the reveal vocabulary
     4. Hero
     5. Wedding timeline
     6. Meet the couple
     7. Location, RSVP, things to know, countdown
     8. The narrow canvas
   =========================================================================== */


/* ===========================================================================
   1. TOKENS AND RESET
   =========================================================================== */

:root {
  /* Ink and paint, straight off the original artwork. */
  --ink:        #5F250F;   /* every heading and most body copy */
  --accent:     #AB5626;   /* the parents' names, the pillar titles */
  --script:     rgba(171, 86, 38, .72);  /* the brush-script names */
  --gold:       #DDA45D;   /* the countdown digits, the hairline dividers */
  --tan:        #E4BC83;   /* the address panel under the map */
  --button:     #B37443;   /* the selected location button */
  --cream:      #F7E8D4;   /* the sky behind the hero */
  --gallery-bg: #FFEFE2;   /* behind the photo wheel */
  --whatsapp:   #25D366;

  --font-display: "IvyOra Display", Georgia, "Times New Roman", serif;
  --font-script:  "Miofarin", "Brush Script MT", cursive;
  --font-sign:    "Brother Signature", "Segoe Script", cursive;
  --font-sans:    "Gotham", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-digit:   "Inter", system-ui, sans-serif;

  /* Filled in by assets/js/stage.js; the fallbacks keep the first paint
     sensible if a frame lands before the script runs. */
  --canvas-w: 1515;
  --canvas-h: 12523;
  --scale: calc(100vw / var(--canvas-w));
}

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

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

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-display);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h2, p { margin: 0; }
img { display: block; }

/* The page toggles a few things with the hidden attribute, and several of
   them are flex items, whose display would otherwise win. */
[hidden] { display: none !important; }


/* ===========================================================================
   2. THE STAGE

   .page reserves the scaled height in normal document flow; .stage is the
   design canvas itself, drawn at full size and then scaled down into it.
   =========================================================================== */

.page {
  position: relative;
  width: 100%;
  height: calc(var(--canvas-h) * var(--scale) * 1px);
  overflow: hidden;
}

.stage {
  position: absolute;
  top: 0;
  left: 50%;
  width: calc(var(--canvas-w) * 1px);
  height: calc(var(--canvas-h) * 1px);
  transform: translateX(-50%) scale(var(--scale));
  transform-origin: top center;
}

/* Sections are placed on the canvas by coordinate; the artwork inside each
   one is placed relative to the section. */
.hero,
.timeline,
.couple,
.location {
  position: absolute;
  left: 0;
  width: calc(var(--canvas-w) * 1px);
}


/* ===========================================================================
   3. MOTION — THE REVEAL VOCABULARY

   Anything with a data-reveal attribute starts in the "before" pose written
   here and settles into place the first time it scrolls into view; the class
   is added by assets/js/reveal.js.

   The pose is held in four registered custom properties rather than in
   `transform` directly, so that a scroll parallax can keep writing --py to
   the same element every frame without being caught up in the transition.
   =========================================================================== */

/* All of these are registered rather than left as plain custom properties for
   two reasons: a registered property can be transitioned, and — just as
   important — it can be declared `inherits: false`, so a parallax offset set
   on a group does not silently apply a second time to every child inside it. */
@property --rx { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --ry { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --rs { syntax: "<number>"; inherits: false; initial-value: 1; }
@property --rr { syntax: "<angle>";  inherits: false; initial-value: 0deg; }
@property --rb { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --py { syntax: "<length>"; inherits: false; initial-value: 0px; }

/* --anchor is whatever static centring the element needs; --py is the live
   parallax offset. Both compose with the reveal pose in one transform. */
[data-reveal],
[data-parallax],
[data-hero-title],
.reveal-word {
  --anchor: translateX(0);
  transform:
    var(--anchor)
    translate(var(--rx), calc(var(--py) + var(--ry)))
    scale(var(--rs))
    rotate(var(--rr));
}

[data-reveal],
.reveal-word {
  filter: blur(var(--rb));
  transition:
    opacity  var(--dur, 1.4s) var(--ease, cubic-bezier(.16, 1, .3, 1)) var(--delay, 0s),
    --rx     var(--dur, 1.4s) var(--ease, cubic-bezier(.16, 1, .3, 1)) var(--delay, 0s),
    --ry     var(--dur, 1.4s) var(--ease, cubic-bezier(.16, 1, .3, 1)) var(--delay, 0s),
    --rs     var(--dur, 1.4s) var(--ease, cubic-bezier(.16, 1, .3, 1)) var(--delay, 0s),
    --rr     var(--dur, 1.4s) var(--ease, cubic-bezier(.16, 1, .3, 1)) var(--delay, 0s),
    --rb     var(--dur, 1.4s) var(--ease, cubic-bezier(.16, 1, .3, 1)) var(--delay, 0s);
  will-change: transform, opacity;
}

/* --- the poses ----------------------------------------------------------- */

/* A short lift, with a little overshoot — the invitation wording. */
[data-reveal="rise"]      { opacity: 0; --ry: 24px; --dur: .65s; --ease: cubic-bezier(.34, 1.36, .64, 1); }

/* A longer, calmer lift that also grows a touch — most section content. */
[data-reveal="rise-soft"] { opacity: 0; --ry: 56px; --rs: .94; }

/* In from the left — the timeline pillars. */
[data-reveal="slide"]     { opacity: 0; --rx: -48px; --dur: .9s; --ease: cubic-bezier(.22, 1.1, .36, 1); }

/* Straight fade — the medallions between the pillars. */
[data-reveal="fade"]      { opacity: 0; --dur: 1.1s; --ease: cubic-bezier(.4, 0, .2, 1); }

/* Settling out of a zoom — the mandalas. */
[data-reveal="zoom"]      { opacity: 0; --rs: .9; --dur: 1.3s; }

/* Falling in from far too large — the "Meet the" heading. */
[data-reveal="drop"]      { opacity: 0; --ry: 110px; --rs: 1.35; --dur: 1s; --ease: cubic-bezier(.24, 1.2, .38, 1); }

/* A gentle lift — the photo wheel. */
[data-reveal="lift"]      { opacity: 0; --ry: 48px; --rs: .96; }

/* A short lift with no overshoot — the note on the card. The distance and
   the timing come from the element's own rule. */
[data-reveal="fade-up"]   { opacity: 0; }


/* The layers of the hero painting rise into place on load. Each one carries
   its own --ry, --dur and --delay inline, because the distance and the
   timing are part of how the scene opens rather than a reusable pose. */
[data-reveal="enter"]     { opacity: 1; }
[data-reveal="enter-dim"] { opacity: .2; }

/* The couple's names swing up out of the bottom of the frame. */
[data-reveal="swing"]     { display: inline-block; opacity: 1; --ease: cubic-bezier(.22, 1.1, .3, 1); }

/* Word by word out of a blur — the timeline heading. */
.reveal-word {
  display: inline-block;
  opacity: 0;
  --ry: 90px;
  --rs: 1.5;
  --rb: 12px;
  --dur: .9s;
  --ease: cubic-bezier(.2, 1.15, .4, 1);
}

/* --- arrived ------------------------------------------------------------- */

[data-reveal].is-revealed,
.reveal-word.is-revealed {
  opacity: 1;
  --rx: 0px;
  --ry: 0px;
  --rs: 1;
  --rr: 0deg;
  --rb: 0px;
}

/* ===========================================================================
   4. HERO

   A painted scene in layers: sky, sun, mountain, clouds, the couple's names,
   then the temple in front of them, with the bell beam across the top.
   =========================================================================== */

.hero {
  top: 2px;
  height: 4786px;
  z-index: 1;
  background: var(--cream);
  overflow: clip;
}

.hero > * { position: absolute; }

.hero__sky {
  top: 0; left: 0;
  width: 1515px; height: 1282px;
  object-fit: cover;
  z-index: 0;
}

/* --ry / --dur / --delay are how far and how slowly the layer rises into
   place on load; see section 3. They belong here rather than inline, so
   that .is-revealed can override them when the layer lands. */

.hero__sun {
  top: 318px; left: 43%;
  width: auto; height: 580px;
  --anchor: translateX(-50%);
  --rs: 1.5;              /* the sun is painted at 1.5x on the canvas */
  --ry: 688px; --dur: 2.7s; --delay: 1.1s;
  z-index: 2;
}
.hero__sun.is-revealed { --rs: 1.5; }   /* keeps its painted scale */

.hero__mountain {
  top: 451px; left: 0;
  width: 1515px; height: auto;
  --ry: 688px; --dur: 2.7s; --delay: .5s;
  z-index: 5;
}

.hero__clouds {
  top: -2px; left: 0;
  width: 1515px; height: auto;
  --ry: 864px; --dur: 4s; --delay: .2s;
  z-index: 6;
}

.hero__birds {
  top: -17px; left: 0;
  width: 1515px; height: 814px;
  z-index: 2;
}

/* --- the couple's names on the sky ---------------------------------------
   The wrapper carries the scroll: --py is the parallax drift and --ts/--tr/
   --to are the tilt, shrink and fade written by parallax.js as the reader
   scrolls past. The span inside carries the arrival, so a six-second swing
   on load and a live scroll effect never fight over one transform. */

.hero__title {
  left: 50%;
  /* nowrap, not pre: the name is a single inline-block, and `pre` would turn
     the line breaks around it in the markup into real blank lines. */
  white-space: nowrap;
  color: var(--script);
  line-height: 1.2;
  z-index: 8;
  opacity: var(--to, 1);
  transform:
    translateX(-50%)
    translateY(var(--py, 0px))
    scale(var(--ts, 1))
    rotate(var(--tr, 0deg));
  will-change: transform, opacity;
}

.hero__title--groom { top:  93px; font-family: var(--font-script); font-size: 140px; }
.hero__title--weds  { top: 193px; font-family: var(--font-sign);   font-size: 117px; }
.hero__title--bride { top: 283px; font-family: var(--font-script); font-size: 140px; }

/* Each name swings up from below the fold, tilted, over several seconds. */
.hero__title span            { --dur: 6.5s; --delay: 1s; }
.hero__title--groom span     { --ry: 862px; --rr:  40deg; }
.hero__title--weds  span     { --ry: 785px; --rr:  33deg; --dur: 6.7s; }
.hero__title--bride span     { --ry: 864px; --rr: -40deg; }

/* --- the temple, and the flag on its spire -------------------------------

   The pole stands on the temple's own kalash: the shaft sits on the spire's
   axis (49.835% of the wide canvas) and the foot lands right where the gold
   finial begins, so the two read as one piece rather than as two ornaments
   in the same patch of sky. The cloth hangs off that shaft, so the flag is
   placed by its left edge — the hoist — and not centred on anything. */

.hero__temple {
  top: calc(47.7016% - 1787px);
  left: 0;
  width: 1515px; height: 3574px;
  --ry: 211px; --dur: 1.6s;
  object-fit: contain;
  z-index: 9;
}

.hero__flagpole {
  top: 411px; left: calc(49.835% - 13.3px);
  width: 28.7px; height: 150px;
  --ry: 313px; --dur: 2.6s; --delay: .7s;
  object-fit: contain;
  z-index: 9;
}

.hero__flag {
  top: 420.6px; left: calc(49.835% - 1.7px);
  /* A shade taller than the cloth itself: assets/js/flag.js keeps that much
     room above and below for the wave to travel into. */
  width: 121px; height: 88.9px;
  --ry: 313px; --dur: 2.6s; --delay: .7s;
  z-index: 9;
}

/* --- the bells ------------------------------------------------------------ */

.hero__bell-frame {
  top: 0; left: 50%;
  width: 1513px; height: auto;
  --anchor: translateX(-50%);
  object-fit: contain;
  z-index: 9;
  transform: var(--anchor) scale(var(--rs));
  --rs: 1.6;                                   /* scales down on load */
  transition: --rs 2.1s cubic-bezier(.16, 1, .3, 1) .1s;
}
.hero__bell-frame.is-loaded { --rs: 1; }

.bell {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  cursor: pointer;
  touch-action: manipulation;
  opacity: 0;
  transition: opacity 1.5s ease var(--delay, 1.5s);
}
.bell.is-loaded { opacity: 1; }

/* The pendulum itself. assets/js/bells.js writes --swing. */
.bell img {
  width: 100%; height: 100%;
  object-fit: contain;
  transform-origin: 50% 0%;
  transform: rotate(var(--swing, 0deg));
  user-select: none;
  pointer-events: none;
  will-change: transform;
}

.bell--1 { top: 113px; left: calc(15.9076% - 100px); width: 200px; height: 350px; z-index: 10; --delay: 1.5s; }
.bell--2 { top: 113px; left: calc(83.6304% - 100px); width: 200px; height: 350px; z-index: 10; --delay: 1.5s; }
.bell--3 { top: 185px; left: calc(9.30693% - 76.5px); width: 153px; height: 350px; z-index: 8; --delay: 1.7s; }
.bell--4 { top: 185px; left: calc(90.4951% - 76.5px); width: 153px; height: 350px; z-index: 8; --delay: 1.7s; }
.bell--5 { top: 163px; left: calc(4.68647% - 100px); width: 200px; height: 350px; z-index: 7; --delay: 2s; }
.bell--6 { top: 183px; left: calc(95.7756% - 100px); width: 200px; height: 350px; z-index: 7; --delay: 2s; }

/* --- the invitation wording ---------------------------------------------- */

.invite {
  top: 2139px;
  left: calc(49.967% - 757.5px);
  width: 1515px; height: 1596px;
  z-index: 10;
}

.invite > * {
  position: absolute;
  left: 50%;
  --anchor: translateX(-50%);
  white-space: pre;
  text-align: center;
}

.invite__ganpati-icon { top:  53px; width:  83px; height: auto; aspect-ratio: .725922; object-fit: contain; }
.invite__shri-line    { top: 176px; width: 269px; height: auto; aspect-ratio: 5.13559; object-fit: cover; }

.invite__parents {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 36px;
  line-height: 1.2;
  color: var(--accent);
}
.invite__parents--groom { top: 514px; --anchor: translate(-50%, -50%); }
.invite__parents--bride { top: 54%; --anchor: translate(-50%, -50%); }


.invite__name {
  font-family: var(--font-script);
  color: var(--script);
  line-height: 1.2;
}
.invite__name--groom { top: 262px; font-size: 151px; }
.invite__name--bride { top: 636px; font-size: 129px; }

.invite__and {
  top: 528px;
  left: 2px;
  width: 100%;
  --anchor: translateX(0);
  font-family: var(--font-sign);
  font-size: 128px;
  line-height: 1.2;
  color: var(--script);
}

.invite__label { line-height: 1.2; color: var(--ink); }
/* Each name is followed by "Son of" / "Daughter of" and the parents, at
   the same spacing: the label 23px under the name, the parents 48px under
   the label. */
.invite__label--son      { top: 466px; --anchor: translate(-50%, -50%); font-size: 24px; }
.invite__label--daughter { top: 51%; --anchor: translate(-50%, -50%); font-size: 24px; }
.invite__label--events   { bottom: 487px; font-size: 39px; }

/* --- the scroll cue ------------------------------------------------------- */

.scroll-arrow {
  left: 50%;
  bottom: 1114px;
  width: 50px; height: 165px;
  --anchor: translateX(-50%);
  display: flex;
  justify-content: center;
  align-items: flex-end;
  color: var(--button);
  pointer-events: none;
  z-index: 10;
}
.scroll-arrow svg {
  width: 40px; height: 100%;
  overflow: visible;
  transform: scale(.6);
}


/* ===========================================================================
   5. WEDDING TIMELINE

   Six pillars in a row, each carrying one celebration, on a painted
   peacock backdrop.
   =========================================================================== */

.timeline {
  top: 2228px;
  height: 3835px;
  z-index: 2;
  overflow: clip;
}

.timeline > *,
.timeline__peacock-backdrop > * { position: absolute; }

.timeline__pillar-backdrop {
  top: 141px; left: 50%;
  width: 1515px; height: auto;
  --anchor: translateX(-50%);
  aspect-ratio: .916515;
  object-fit: contain;
  z-index: 0;
}

.timeline__peacock-backdrop {
  position: absolute;
  top: 742px; left: 0;
  width: 1515px; height: 93%;
  z-index: 1;
}
.timeline__peacock-art {
  top: 0; left: 0;
  width: 1515px; height: auto;
  object-fit: contain;
}
.timeline__peacock {
  top: 2237px; left: 50%;
  width: 243px; height: auto;
  transform: translateX(-50%);
  aspect-ratio: 2.54167;
  object-fit: cover;
}

/* Narrow-canvas ornaments; the wide canvas uses the medallions instead. */
.timeline__ornament,
.timeline__edge { display: none; }

.timeline__heading {
  top: 51%; left: 50%;
  --anchor: translate(-50%, -50%);
  width: max-content;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 80px;
  line-height: 1.2;
  text-align: center;
  color: var(--ink);
  z-index: 1;
}

.timeline__subtext {
  top: 2023px; left: 50%;
  --anchor: translateX(-50%);
  --ry: 32px;
  --dur: 1.2s;
  white-space: pre;
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: 23px;
  line-height: 1.2;
  color: var(--ink);
  z-index: 1;
}

.timeline__pillars {
  top: 2016px;
  left: calc(50.033% - 658.5px);
  width: 1317px; height: 523px;
  z-index: 1;
}

.pillars__row {
  position: absolute;
  top: calc(51.6252% - 144.5px);
  left: 0; right: 0;
  height: 289px;
}

/* --- one pillar ----------------------------------------------------------- */

/* Three abreast in two rows, each drawn 1.26x so the row of three fills the
   stage. `scale` is its own property, so it stays clear of the transform the
   slide-in animation writes. Offsets below are for the unscaled 186px box;
   the scale grows it about its centre, 24.2px each side and 37.4px top and
   bottom, which still leaves about 16px between a card and the medallion in
   the gap beside it. */
.pillar {
  position: absolute;
  top: 29px;
  width: 186px; height: auto;
  aspect-ratio: .646883;
  scale: 1.26;
  z-index: 1;
}

.pillar:nth-child(1),
.pillar:nth-child(4) { left: 175.5px; }
.pillar:nth-child(2),
.pillar:nth-child(5) { left: 565.5px; }
.pillar:nth-child(3),
.pillar:nth-child(6) { left: 955.5px; }
.pillar:nth-child(n+4) { top: 429px; }

.pillar__art {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}

/* The six lines are each placed outright. They share .pillar__line so that
   the modifier below it can win on source order rather than specificity.

   The carved frame is not a rectangle, and the sizes below are cut to it.
   Measured off the artwork, as a share of the 186px box: the arch closes the
   panel to 70% at y=52 and only opens to 83% by y=72, so the title sits low
   enough for its capitals to clear the curve; the panel holds 83% down the
   body lines, where "7:30 PM Onwards" is the longest in the sample; and the
   two carved stars pinch it back to 72% between y=180 and y=192, which is
   why the theme line stays at 10px — it has to pass between them. The rule
   the sunburst hangs from is at y=196. */
.pillar__line {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  white-space: pre;
  text-align: center;
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: 15.5px;
  line-height: 1.15;
  color: var(--ink);
}

/* 23px, not larger: "Engagement" already runs to 66% of the box and the arch
   leaves only about 71% at the height its capitals sit at. */
.pillar__title {
  top: 48px;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 23px;
  line-height: 1.2;
  color: var(--accent);
}
/* A two-word title such as "Mandap Muhurat" is too wide for the frame at
   full size, so it is set smaller and dropped to keep the same baseline. */
.pillar__title--long { top: 53px; font-size: 17px; }
.pillar__day   { top:  84px; }
.pillar__date  { top: 105px; font-weight: 500; }
.pillar__place { top: 126px; }
.pillar__time  { top: 147px; font-weight: 500; }
/* Between the two carved stars, so it cannot grow with the lines above. */
.pillar__more  { top: 176px; font-size: 10px; line-height: 1.4; }

/* --- the medallions in the gaps ------------------------------------------- */

.medallion {
  position: absolute;
  width: 124px; height: auto;
  aspect-ratio: 1.00082;
  object-fit: cover;
  z-index: 1;
}

/* One in each gap between the three pillars, level with the middle of each
   row. The row sits 125.5px into .timeline__pillars and each pillar shows
   345px tall, so the row centres are at 298px and 698px. */
.medallion--1-up   { top: 236px; left: 401.5px; }
.medallion--2-up   { top: 236px; left: 791.5px; }
.medallion--1-down { top: 636px; left: 401.5px; }
.medallion--2-down { top: 636px; left: 791.5px; }
.medallion--3-up, .medallion--3-down,
.medallion--4-up, .medallion--4-down,
.medallion--5-up, .medallion--5-down { display: none; }


/* ===========================================================================
   6. MEET THE COUPLE
   =========================================================================== */

/* The section ends right under "Almost time to celebrate" and sits above
   .location, so the photo band below can come up to meet the text without
   its cream top edge covering it. Its backdrop runs on much further, which
   is why the bottom is clipped. Only the bottom: the narrow backdrop starts
   above the section and the mandalas reach past its sides. */
.couple {
  top: 5098px;
  height: 3150px;
  clip-path: inset(-2000px -2000px 0 -2000px);
  z-index: 5;
}

.couple > *,
.couple__backdrop > * { position: absolute; }

.couple__backdrop {
  position: absolute;
  top: 176px; left: 50%;
  width: 1515px; height: auto;
  transform: translateX(-50%);
  aspect-ratio: .26696;
  z-index: 0;
}
.couple__backdrop-art {
  top: 0; left: 0;
  width: 100%; height: 100%;
  object-fit: contain;
}

.couple__mandala {
  top: 380px;
  width: 293px; height: auto;
  aspect-ratio: 1.00082;
  object-fit: cover;
  --anchor: translateX(-50%);
  z-index: 1;
}
.couple__mandala--right { left: 85%; }
.couple__mandala--left  { left: 15%; }

.couple__heading {
  top: 1229px; left: 50%;
  --anchor: translateX(-50%);
  white-space: pre;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 110px;
  line-height: 1.2;
  text-align: center;
  color: var(--ink);
}

.couple__card {
  top: 1557px; left: 50%;
  width: 804px; height: auto;
  transform: translateX(-50%);
  aspect-ratio: .812332;
  z-index: 3;
}
.couple__card-art {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}

.couple__message {
  position: absolute;
  top: 315px; left: 72px;
  width: 661px;
  --ry: 24px;
  --dur: .9s;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 30px;
  line-height: 1.2;
  text-align: center;
  z-index: 1;
}

/* Each word starts faint and warms to full ink as the card scrolls past. */
.couple__message span {
  display: inline-block;
  margin-right: .25em;
  color: rgba(95, 37, 15, .22);
  transition: color .3s linear;
}
.couple__message span.is-lit { color: var(--ink); }

.gallery {
  top: 2583px;
  left: calc(50.033% - 757.5px);
  width: 1515px; height: 567px;
  overflow: hidden;
  background: var(--gallery-bg);
  z-index: 1;
}

/* The wheel is masked away at the bottom so the photographs fade out. */
.gallery__mask {
  position: absolute;
  top: 0; left: 0;
  width: 100%;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 85%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 85%, transparent 100%);
}

.gallery__wheel {
  position: absolute;
  left: 50%;
  transform-origin: center center;
  will-change: transform;
}

.gallery__photo {
  position: absolute;
  overflow: hidden;
  box-shadow: 0 4px 20px rgba(0, 0, 0, .15);
}
.gallery__photo img {
  width: 100%; height: 100%;
  object-fit: cover;
}

.couple__outro {
  top: 3014px; left: 50%;
  transform: translateX(-50%);
  white-space: pre;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 52px;
  line-height: 1.2;
  text-align: center;
  color: var(--ink);
  z-index: 2;
}


/* ===========================================================================
   7. LOCATION, RSVP, THINGS TO KNOW, COUNTDOWN

   All four sit on one long painted scroll (.location__backdrop), so their
   coordinates below are relative to that scroll rather than to the section.
   =========================================================================== */

.location {
  top: 8260px;
  height: 2294px;
  z-index: 4;
}

.location__section-bg {
  position: absolute;
  top: -52px; left: 50%;
  width: 1418px; height: auto;
  transform: translateX(-50%);
  aspect-ratio: 1.5;
  object-fit: cover;
  z-index: -1;
}

.location__backdrop {
  position: absolute;
  top: -57px; left: 0;
  width: 1515px; height: 9148px;
}
.location__backdrop > * { position: absolute; }

.location__backdrop-art {
  top: 0; left: 0;
  width: 100%; height: 100%;
  object-fit: contain;
}

.location__heading {
  top: 1015px; left: 50%;
  --anchor: translateX(-50%);
  white-space: pre;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 60px;
  line-height: 1.2;
  color: var(--ink);
  z-index: 1;
}

/* --- the map -------------------------------------------------------------- */

.location__frame {
  top: 1051px;
  left: calc(49.703% - 548.5px);
  width: 1097px; height: 560px;
  overflow: clip;
}

/* Wide: the map on the left, the address and the location buttons in a
   column beside it. The narrow canvas stacks the three, further down. */
.venue {
  position: absolute;
  top: 94px;
  left: calc(50.3191% - 490px);
  width: 980px; height: 399px;
  transform: scale(1.1);
  display: flex;
  flex-direction: row;
  align-items: stretch;
  gap: 24px;
  font-family: var(--font-sans);
  z-index: 3;
}

.venue__map-wrap {
  position: relative;
  flex: 1 1 50%;
  min-height: 320px;
  border-radius: 16px;
  overflow: hidden;
}
.venue__map { width: 100%; height: 100%; }

.venue__side {
  flex: 1 1 50%;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 16px;
  min-width: 0;
}

/* Leaflet's own panes sit at z-index 400 and below, so the chrome above the
   map has to clear that. */
.venue__hint,
.venue__badge,
.venue__recenter,
.venue__maps-link { z-index: 500; }

.venue__hint {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  padding: 8px 14px;
  border-radius: 20px;
  background: rgba(0, 0, 0, .6);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  pointer-events: none;
  transition: opacity .2s ease-out;
}
.venue__hint[hidden] { display: block !important; opacity: 0; }

.venue__badge {
  position: absolute;
  top: 12px; right: 12px;
  max-width: 45%;
  padding: 8px 14px;
  border-radius: 8px;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  text-align: center;
  line-height: 1.3;
  pointer-events: none;
}

.venue__recenter {
  position: absolute;
  bottom: 12px; left: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px; height: 34px;
  padding: 0;
  border: none;
  border-radius: 8px;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  cursor: pointer;
}
.venue__recenter svg { width: 16px; height: 16px; }

.venue__maps-link {
  position: absolute;
  bottom: 12px; right: 12px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  border-radius: 8px;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
}
.venue__maps-link svg { width: 14px; height: 14px; }

.venue__panel {
  position: relative;
  width: 100%;
  flex: 1;
  padding: 20px 56px 20px 24px;
  border-radius: 16px;
  background: var(--tan);
  color: var(--ink);
  text-align: left;
}
.venue__name    { font-size: 18px; font-weight: 700; margin-bottom: 6px; }
.venue__address { font-size: 14px; opacity: .8; white-space: pre-line; }

.venue__copy {
  position: absolute;
  bottom: 16px; right: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  padding: 0;
  border: none;
  border-radius: 8px;
  background: rgba(255, 255, 255, .35);
  color: var(--ink);
  cursor: pointer;
}
.venue__copy svg { width: 16px; height: 16px; }

/* The two icon buttons on and under the map are drawn about 34 canvas pixels
   across, which on a phone is a smaller target than a fingertip can be asked
   to hit — and smaller still wherever the stage is scaled down. Dividing by
   the live stage scale gives each of them an invisible 44px hit area on the
   actual screen, whatever the canvas is doing, without moving the artwork. */
@media (pointer: coarse) {
  .venue__recenter::after,
  .venue__copy::after {
    content: "";
    position: absolute;
    top: 50%; left: 50%;
    width:  calc(44px / var(--scale));
    height: calc(44px / var(--scale));
    transform: translate(-50%, -50%);
  }
}

.venue__switch {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.venue__button {
  width: 100%;
  padding: 14px 16px;
  border: 1px solid #d0d0d0;
  border-radius: 16px;
  background: #fff;
  color: #111;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.venue__button.is-active {
  border-color: var(--button);
  background: var(--button);
  color: #fff;
}

/* --- the RSVP form -------------------------------------------------------- */

.rsvp {
  top: 1623px;
  left: calc(49.901% - 261.5px);
  width: 523px; height: 246px;
  padding: 20px;
  border-radius: 20px;
  background: #fff;
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-family: var(--font-sans);
  z-index: 10;
}

.rsvp__title {
  font-size: 17px;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.rsvp__input {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid #e0e0e0;
  border-radius: 12px;
  background: #fff;
  color: var(--ink);
  font-family: inherit;
  font-size: 14px;
  outline: none;
}
.rsvp__input::placeholder { color: rgba(0, 0, 0, .4); }
.rsvp__input:focus-visible { border-color: var(--button); }

.rsvp__row { display: flex; gap: 10px; }
.rsvp__events { position: relative; flex: 1; min-width: 0; }
.rsvp__count  { flex: 1; min-width: 0; cursor: pointer; }
.rsvp__count:invalid { color: rgba(0, 0, 0, .4); }

.rsvp__picker {
  display: flex;
  align-items: center;
  justify-content: space-between;
  text-align: left;
  color: rgba(0, 0, 0, .4);
  cursor: pointer;
}
.rsvp__picker.has-selection { color: var(--ink); }
.rsvp__picker span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rsvp__picker svg {
  flex-shrink: 0;
  width: 12px; height: 12px;
  margin-left: 6px;
  transition: transform .15s ease;
}
.rsvp__picker[aria-expanded="true"] svg { transform: rotate(180deg); }

.rsvp__menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0; right: 0;
  max-height: 220px;
  overflow-y: auto;
  border: 1px solid #e0e0e0;
  border-radius: 12px;
  background: #fff;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .12);
  z-index: 1000;
}

.rsvp__option {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 12px;
  border: 0;
  background: none;
  color: var(--ink);
  font-family: inherit;
  font-size: 14px;
  text-align: left;
  cursor: pointer;
}
.rsvp__option:hover { background: rgba(0, 0, 0, .04); }

.rsvp__tick {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 16px; height: 16px;
  border: 1.5px solid #e0e0e0;
  border-radius: 4px;
}
.rsvp__tick svg { width: 10px; height: 10px; visibility: hidden; }
.rsvp__option[aria-selected="true"] .rsvp__tick {
  border-color: var(--whatsapp);
  background: var(--whatsapp);
}
.rsvp__option[aria-selected="true"] .rsvp__tick svg { visibility: visible; }

.rsvp__send {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 14px 16px;
  border-radius: 14px;
  background: var(--whatsapp);
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  text-decoration: none;
  cursor: not-allowed;
  opacity: .5;
}
.rsvp__send svg { width: 18px; height: 18px; }
.rsvp__send.is-ready { cursor: pointer; opacity: 1; }

/* --- things to know ------------------------------------------------------- */

.location__ornament {
  left: 50%;
  width: 524px; height: auto;
  transform: translateX(-50%);
  aspect-ratio: 6.1;
  object-fit: cover;
}
.location__ornament--top    { top: 1977px; }
.location__ornament--bottom { top: 2574px; transform: translateX(-50%) rotate(180deg); }

.info {
  top: 1977px;
  left: 0;
  width: 1515px; height: 683px;
  overflow: clip;
}

.info__content {
  position: absolute;
  top: calc(52.123% - 270px);
  left: 0;
  width: 1515px; height: 540px;
  overflow: clip;
}

.info__heading {
  position: absolute;
  top: 9px; left: 50%;
  --anchor: translateX(-50%);
  white-space: pre;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 60px;
  line-height: 1.2;
  color: var(--ink);
}

.info__subtext {
  position: absolute;
  top: 90px; left: 0;
  width: 1515px; height: 110px;
  padding: 0 200px;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 28px;
  letter-spacing: -.02em;
  line-height: 1.3;
  text-align: center;
  color: var(--ink);
}

.info__row {
  position: absolute;
  bottom: 62px; left: 0;
  width: 1515px; height: 220px;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 20px;
}

.info__item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 220px; height: 220px;
  flex: none;
}

.info__icon {
  width: 100px; height: 100px;
  object-fit: cover;
}

.info__title {
  margin-top: 5px;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 26px;
  line-height: 1.2;
  text-align: center;
  color: var(--ink);
}

.info__text {
  width: 200px;
  margin-top: 6px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 13px;
  line-height: 1.3;
  text-align: center;
  color: var(--ink);
}

.info__divider {
  flex: none;
  width: 3px; height: 225px;
  background: var(--gold);
}

/* --- the countdown -------------------------------------------------------- */

.countdown {
  top: 2778px;
  left: calc(49.967% - 449.5px);
  width: 899px; height: 477px;
}
.countdown > * { position: absolute; }

/* The flowering border behind the clock. It is much wider than the countdown
   block itself and reaches up past the top of it. */
.countdown__backdrop {
  top: -222px;
  left: calc(50% - 757.5px);
  width: 1515px; height: auto;
  aspect-ratio: .808;
  object-fit: contain;
}

.countdown__heading {
  top: 0; left: 50%;
  --anchor: translateX(-50%);
  white-space: pre;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 93px;
  line-height: 1.2;
  color: var(--ink);
}

.countdown__intro {
  top: 112px;
  left: calc(49.8332% - 354px);
  width: 708px; height: 133px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 30px;
  line-height: 1.48;
  text-align: center;
  color: var(--ink);
}

.countdown__divider {
  left: 50%;
  bottom: 178px;
  width: 623px; height: auto;
  --anchor: translateX(-50%);
  aspect-ratio: 17.8235;
  object-fit: cover;
}

/* The clock is drawn at its natural type size and then blown up, exactly as
   the original does — so the digit slots below stay in whole pixels. */
.countdown__clock {
  left: 50%;
  bottom: 35px;
  --anchor: translateX(-50%);
  --rs: 1.855;                        /* 1.974 x the .94 it rises out of */
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: 39px;
  font-family: var(--font-digit);
  font-weight: 700;
  color: var(--gold);
}
.countdown__clock.is-revealed { --rs: 1.974; }

.clock__group {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.clock__digits { display: flex; justify-content: center; }

/* One digit slot. The old digit slides out as the new one drops in. */
.clock__digit {
  position: relative;
  width: 26.65px; height: 45.1px;
  overflow: hidden;
  display: flex;
  justify-content: center;
}
.clock__digit span {
  position: absolute;
  font-size: 41px;
  line-height: 1;
  color: var(--gold);
  animation: digit-in .42s cubic-bezier(.2, .9, .3, 1) both;
}
.clock__digit span.is-leaving { animation: digit-out .42s cubic-bezier(.4, 0, .8, .2) both; }

@keyframes digit-in {
  from { transform: translateY(-60%); opacity: 0; filter: blur(6px); }
  to   { transform: none;             opacity: 1; filter: blur(0); }
}
@keyframes digit-out {
  from { transform: none;            opacity: 1; filter: blur(0); }
  to   { transform: translateY(60%); opacity: 0; filter: blur(6px); }
}

.clock__label {
  margin-top: 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  text-align: center;
  color: #888;
}

/* ===========================================================================
   7a. BACKGROUND MUSIC TOGGLE

   Fixed to the window, not the stage, so it keeps the same real size on every
   screen. Sizes here are ordinary CSS pixels, not canvas ones.
   =========================================================================== */

.music-toggle {
  position: fixed;
  bottom: 18px;
  right: 18px;
  z-index: 2000;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  padding: 0;
  border: 2px solid var(--gold);
  border-radius: 50%;
  background: var(--ink);
  color: var(--cream);
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -4px rgba(0, 0, 0, .1);
  cursor: pointer;
  transition: transform .15s cubic-bezier(.4, 0, .2, 1), box-shadow .2s ease;
}

.music-toggle:hover { transform: scale(1.08); box-shadow: 0 25px 50px -12px rgba(0, 0, 0, .25); }
.music-toggle:active { transform: scale(.92); }

.music-toggle__ring {
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 1px solid rgba(221, 164, 93, .7);
  opacity: 0;
  animation: music-ring 2.4s ease-out infinite;
}
.music-toggle:not(.is-muted) .music-toggle__ring { opacity: 1; }

.music-toggle__disc {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  animation: music-spin 3.2s linear infinite;
  animation-play-state: paused;
}
.music-toggle:not(.is-muted) .music-toggle__disc { animation-play-state: running; }

.music-toggle__icon { width: 21px; height: 21px; transition: opacity .2s ease; }

.music-toggle__slash {
  position: absolute;
  z-index: 1;
  width: 21px;
  height: 21px;
  opacity: 0;
  transform: scale(.5) rotate(-15deg);
  transition: opacity .2s ease, transform .2s cubic-bezier(.34, 1.56, .64, 1);
}
.music-toggle.is-muted .music-toggle__slash { opacity: 1; transform: scale(1) rotate(0deg); }
.music-toggle.is-muted .music-toggle__disc { opacity: .5; }

@keyframes music-ring {
  0%   { scale: .85; opacity: .65; }
  100% { scale: 1.4;  opacity: 0; }
}
@keyframes music-spin { to { transform: rotate(360deg); } }

@media (min-width: 640px) {
  .music-toggle { bottom: 24px; right: 24px; width: 50px; height: 50px; }
}

@media (prefers-reduced-motion: reduce) {
  .music-toggle__ring, .music-toggle__disc { animation: none; }
}

/* ===========================================================================
   8. THE NARROW CANVAS

   On a phone or a portrait tablet the same markup is re-laid onto the
   394 x 6387 canvas. Only the coordinates change; colours, fonts and motion
   all carry over.

   The query below is the same string as `stage.narrowQuery` in
   assets/js/config.js, which assets/js/stage.js hands to matchMedia — edit
   one and you must edit the other, or the script will scale to one canvas
   while these coordinates describe the other.

   Read it as: every phone and small tablet, plus anything held in portrait
   up to a large tablet. A landscape tablet is wide enough for the desktop
   composition and keeps the wide canvas.
   =========================================================================== */

@media (max-width: 1023.98px), (orientation: portrait) and (max-width: 1179.98px) {

  :root { --canvas-w: 394; --canvas-h: 6387; }

  /* --- hero -------------------------------------------------------------- */

  .hero        { top: 0; height: 1782px; }
  .hero__sky   { top: -1px; width: 394px; height: 802px; }
  .hero__sun   { top: 302px; height: 149px; }
  .hero__mountain { top: 336px; left: -39px; width: 474px; }
  .hero__clouds   { top: 90px; left: 0; width: 395px; }
  .hero__birds    { top: -1px; left: 0; width: 394px; height: 499px; }

  .hero__title--groom { top:  94px; font-size: 86px; }
  .hero__title--weds  { top: 156px; font-size: 71px; }
  .hero__title--bride { top: 211px; font-size: 86px; }

  .hero__temple {
    top: 348px; left: -1px;
    width: 396px; height: auto;
    aspect-ratio: .274386;
    content: url("../media/hero-temple-narrow.webp");
  }

  .hero__flagpole { top: 293.5px; left: calc(49.941% - 6.8px); width: 14.5px; height: 76px; }
  .hero__flag     { top: 299px;   left: calc(49.941% - .9px);  width: 54px;   height: 39.7px; }

  .hero__bell-frame {
    top: 0; left: -6px;
    width: 406px; height: auto;
    --anchor: translateX(0);
    aspect-ratio: 1.95759;
    content: url("../media/hero-bell-frame-narrow.webp");
  }
  .hero__bell-frame { --rs: 2.3; }

  .bell--1 { top:  -1px; left: calc(83.5897% - 26px); width: 52px; height: 181px; }
  .bell--2 { top:  -1px; left: 36px; width: 43px; height: 181px; }
  .bell--3 { top:   0;   left: 12px; width: 37px; height: 137px; }
  .bell--4 { top:  15px; left: calc(89.4872% - 23px); width: 46px; height: 121px; }
  .bell--5,
  .bell--6 { display: none; }

  .invite {
    top: 850px;
    left: calc(50.2564% - 195px);
    width: 390px; height: 500px;
  }
  .invite__ganpati-icon { top:  31px; width: 47px; }
  .invite__shri-line    { top: 105px; width: 195px; }

  /* 12px, not 13px: the card's lower half sits over the timeline section's
     foliage, which reaches in from both sides, and .invite's parallax slides
     the wording across that band as you scroll. At 13px the line is wide
     enough that its first and last words disappear into the leaves. */
  .invite__parents { font-size: 12px; }
  .invite__parents--groom { top: 284px; --anchor: translateX(-50%); }
  .invite__parents--bride { top: auto; bottom: 42px; --anchor: translateX(-50%); }


  .invite__name--groom { top: 170px; font-size: 86px; --anchor: translateX(-50%); }
  .invite__name--bride { top: auto; bottom: 69px; font-size: 86px; }
  /* Pulled up 41px along with the shorter card above, so "and" keeps its
     gap to Hetvi instead of drifting into it. Without this, the bride's
     parents line (bottom:42px) sits low enough to fall behind the
     timeline section's peacock artwork, which overlaps the bottom of the
     hero section at this breakpoint and swallows the start/end of the
     line — see .invite's height. */
  .invite__and         { top: 270px; left: .5%; width: 99%; font-size: 73px; }

  .invite__label--son      { top: 263px; font-size: 13px; --anchor: translateX(-50%); }
  .invite__label--daughter { top: auto; bottom: 63px; font-size: 13px; --anchor: translateX(-50%); }
  .invite__label--events   { bottom: -22px; left: 49%; font-size: 20px; }

  .scroll-arrow { top: 1467px; bottom: auto; }

  /* --- timeline ----------------------------------------------------------- */

  .timeline { top: 938px; height: 2445px; }

  .timeline__pillar-backdrop {
    top: 231px; left: -1px;
    width: 396px; height: auto;
    --anchor: translateX(0);
    aspect-ratio: .9167;
    content: url("../media/timeline-pillar-backdrop-narrow.webp");
  }

  .timeline__peacock-backdrop { top: 329px; left: -1px; width: 396px; height: auto; }
  .timeline__peacock-art {
    position: relative;
    width: 396px;
    content: url("../media/timeline-peacock-backdrop-narrow.webp");
  }
  .timeline__peacock { top: 1778px; width: 166px; }

  .timeline__heading {
    top: 949px;
    --anchor: translateX(-50%);
    font-weight: 700;
    font-size: 28px;
  }
  .timeline__subtext { top: 996px; font-size: 13px; }

  /* The pillars go two abreast, and the medallions give way to the carved
     ornaments that the narrow artwork uses instead. */
  .timeline__pillars { top: 0; left: 0; width: 394px; height: 2445px; }
  .pillars__row { position: static; height: auto; }

  /* Every pillar is centred on its column here, including the fifth, which
     on the wide canvas is centred vertically instead. */
  .pillar { width: 148px; scale: none; }
  .pillar:nth-child(1),
  .pillar:nth-child(2),
  .pillar:nth-child(3),
  .pillar:nth-child(4),
  .pillar:nth-child(5),
  .pillar:nth-child(6) { --anchor: translateX(-50%); left: 26%; right: auto; }

  .pillar:nth-child(1) { top: 1040px; }
  .pillar:nth-child(2) { top: 1040px; left: 74%; }
  .pillar:nth-child(3) { top: 1300px; }
  .pillar:nth-child(4) { top: 1300px; left: 74%; }
  .pillar:nth-child(5) { top: 1560px; }
  .pillar:nth-child(6) { top: 1560px; left: 74%; }

  /* A smaller pillar, so the six lines sit closer together. The card is
     148px here and the frame's clear panel is 83% of that, which puts
     "7:30 PM Onwards" at 13px within a couple of pixels of as wide as a
     line can go — width, not height, is what caps these. */
  .pillar__line  { font-size: 13px; line-height: 1.2; }
  .pillar__title { top:  38px; font-size: 18px; line-height: 1.2; }
  .pillar__title--long { top: 40px; font-size: 13.5px; }
  .pillar__day   { top:  66px; }
  .pillar__date  { top:  85px; }
  .pillar__place { top: 104px; }
  .pillar__time  { top: 123px; }
  /* Level with the two stars in the frame, and small enough to clear them —
     they close the panel to 72% here, so this line alone cannot grow. */
  .pillar__more  { top: 142px; font-size: 8px; line-height: 1.45; }

  .medallion { display: none; }

  .timeline__ornament,
  .timeline__edge { display: block; z-index: 1; }

  .timeline__ornament {
    left: 50%;
    width: 140px; height: auto;
    transform: translateX(-50%);
    aspect-ratio: 1.00082;
    object-fit: cover;
  }
  /* Both centred on the space between two rows of pillar frames. The frames
     carry a drop shadow below, so this sits a little above the middle of the
     gap between the boxes. */
  .timeline__ornament--1 { top: 1275px; transform: translate(-50%, -50%); }
  .timeline__ornament--2 { top: 1535px; transform: translate(-50%, -50%); }
  /* Small enough to sit wholly in the open space between the four frames,
     so none of them cuts across it. */
  .timeline__ornament--1,
  .timeline__ornament--2 { width: 90px; }

  .timeline__edge {
    width: 71px; height: auto;
    transform: translateY(-50%);
    aspect-ratio: .693576;
    object-fit: cover;
  }
  .timeline__edge--l1 { top: 1275px; left: 0; }
  .timeline__edge--l2 { top: 1535px; left: 0; }
  .timeline__edge--l3 { top: 75%; left: 0; }
  .timeline__edge--r1 { top: 1275px; right: 0; width: 70px; }
  .timeline__edge--r2 { top: 1535px; right: 0; width: 70px; }
  .timeline__edge--r3 { top: 75%; right: 0; width: 70px; }

  /* --- meet the couple ---------------------------------------------------- */

  .couple { top: 2952px; height: 1150px; }

  .couple__backdrop {
    top: -155px; left: -1px;
    width: 396px;
    transform: none;
    content: url("../media/couple-backdrop-narrow.webp");
  }
  .couple__mandala { display: none; }

  .couple__heading { top: 363px; bottom: auto; font-size: 34px; }

  .couple__card { top: 482px; width: 337px; }
  .couple__message {
    top: 50%; left: 50%;
    width: 275px;
    font-size: 13px;
    --anchor: translate(-50%, -50%);
  }

  .gallery { top: 897px; left: -3px; width: 400px; height: 332px; }

  .couple__outro { top: 1099px; font-size: 20px; }

  /* --- location, RSVP, things to know, countdown -------------------------- */

  .location { top: 4168px; height: 2219px; }

  /* Too narrow to bleed edge to edge without cropping the couple: the
     photo shows whole (4:3) in a cream mat with a gold hairline frame. */
  .location__section-bg {
    top: -52px; left: 50%;
    width: 328px;
    transform: translateX(-50%);
    aspect-ratio: 4 / 3;
    padding: 6px;
    background: var(--gallery-bg);
    border: 1.5px solid var(--gold);
    border-radius: 14px;
    outline: 1px solid rgba(221, 164, 93, .55);
    outline-offset: 4px;
    box-shadow: 0 10px 24px rgba(95, 37, 15, .18);
    object-fit: cover;
  }

  .location__backdrop { top: -75px; left: 0; width: 394px; height: 5200px; }
  .location__backdrop-art { content: url("../media/location-backdrop-narrow.webp"); }

  .location__heading { top: 295px; font-size: 21px; }

  /* No outer frame on the narrow canvas — the map sits on the scroll. */
  .location__frame {
    top: 348px;
    left: calc(49.8741% - 171.5px);
    width: 343px; height: 560px;
    overflow: visible;
  }
  /* Too narrow to sit side by side: map, address and buttons stack. */
  .venue {
    top: 0; left: 0;
    width: 343px; height: 560px;
    transform: none;
    flex-direction: column;
    gap: 16px;
  }
  .venue__map-wrap { flex: none; height: 296px; min-height: 0; }
  .venue__side { display: contents; }
  .venue__panel { flex: none; }
  .venue__switch {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
  }
  /* An odd one out takes a full-width row of its own. */
  .venue__button:last-child:nth-child(odd) { grid-column: 1 / -1; }

  /* Everything from here down sits 258px lower than it used to, which is
     what the two-by-two "things to know" grid above needs over the single
     shrunken row it replaced. */
  .rsvp {
    top: 1512px; left: 50%;
    width: 340px; height: auto;
    --anchor: translateX(-50%);
  }

  .location__ornament { width: 341px; }
  .location__ornament--top    { top: 1768px; }
  .location__ornament--bottom { top: 1432px; }

  .info { top: 906px; left: 0; width: 394px; height: 442px; overflow: visible; }
  .info__content { position: static; width: 394px; height: auto; overflow: visible; }

  .info__heading { top: 0; font-size: 31px; }
  .info__subtext {
    top: 51px; left: 0;
    width: 394px; height: 50px;
    padding: 0 24px;
    font-size: 12px;
  }

  /* Four 220px tiles will not fit across a phone in a single row. Shrinking
     the wide row to fit would put the body copy at about five pixels and
     push the outer two tiles off both edges, so the four are re-flowed two
     by two instead and keep a size that can be read. */
  .info__row {
    top: 124px; bottom: auto;
    left: 0;
    width: 394px; height: 318px;
    padding: 0 16px;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 18px 14px;
    align-items: start;
  }

  .info__item  { width: auto; height: 150px; justify-content: flex-start; }
  .info__icon  { width: 56px; height: 56px; }
  .info__title { margin-top: 4px; font-size: 18px; }
  .info__text  { width: 100%; margin-top: 4px; font-size: 11px; line-height: 1.35; }

  /* The gold rules between the tiles belong to the single row; a grid of
     four has nothing for them to divide. */
  .info__divider { display: none; }

  .countdown {
    top: 1839px; left: 0;
    width: 394px; height: 220px;
  }
  .countdown__backdrop {
    top: -71px;
    left: 50%;
    width: 453px;
    transform: translateX(-50%);
  }
  .countdown__heading { top: 0; left: 50%; font-size: 24px; }
  .countdown__intro {
    top: 35px; left: calc(49.1139% - 200px);
    width: 400px; height: 43px;
    font-size: 11px;
  }
  .countdown__divider { top: 88px; bottom: auto; width: 197px; }
  .countdown__clock   { top: 96px; bottom: auto; gap: 14px; }

  /* Same clock, scaled down for the phone canvas instead of re-sized. */
  .countdown__clock              { gap: 22px; --rs: .58; }
  .countdown__clock.is-revealed  { --rs: .62; }
}


/* ===========================================================================
   9. THE PHONE CANVAS — 394 x 6469

   Phones share the narrow canvas above, with the timeline pillars drawn
   1.15x so their text reads comfortably at phone size. They stay two
   abreast, so the page grows by only 82px: the timeline takes the extra
   room and everything after it moves down by the same amount.
   stage.js switches to this canvas's height through `stage.phoneQuery` in
   config.js — the same query as the one below, so edit both together.
   =========================================================================== */

@media (max-width: 599.98px) {

  :root { --canvas-h: 6469; }

  .timeline { height: 2527px; }
  .timeline__peacock { top: 1860px; }

  /* Still centred on the 26% and 74% columns, now 175px wide on screen. The
     scale adds 21px above and below the 229px box, which the tops allow
     for, and the rows are 284px apart instead of 260px. 1.18 is about as far
     as it goes: past that the two columns close on each other and on the
     edges of the canvas.

     Centring can't be left to `left: 26%; transform: translateX(-50%)`
     here: browsers resolve that -50% against the box's scaled size when
     the `scale` property is also set, which drags every pillar ~11px
     left of its column and throws the left/right margins out of balance.
     Baking the half-width into `left` with calc() instead, and zeroing
     --anchor so translateX(-50%) doesn't also fire, sidesteps that. */
  .pillar:nth-child(1),
  .pillar:nth-child(2),
  .pillar:nth-child(3),
  .pillar:nth-child(4),
  .pillar:nth-child(5),
  .pillar:nth-child(6) { scale: 1.18; }

  .pillar:nth-child(1),
  .pillar:nth-child(3),
  .pillar:nth-child(5) { --anchor: translateX(0); left: calc(26% - 74px); }

  .pillar:nth-child(2),
  .pillar:nth-child(4),
  .pillar:nth-child(6) { --anchor: translateX(0); left: calc(74% - 74px); }

  .pillar:nth-child(1),
  .pillar:nth-child(2) { top: 1057px; }
  .pillar:nth-child(3),
  .pillar:nth-child(4) { top: 1341px; }
  .pillar:nth-child(5),
  .pillar:nth-child(6) { top: 1625px; }

  /* The ornaments stay centred on the space between the rows of frames,
     which moves with the larger pillars. */
  .timeline__ornament--1 { top: 1302.5px; }
  .timeline__ornament--2 { top: 1586.5px; }
  .timeline__ornament--1,
  .timeline__ornament--2 { width: 100px; }
  .timeline__edge--l1, .timeline__edge--r1 { top: 1302.5px; }
  .timeline__edge--l2, .timeline__edge--r2 { top: 1586.5px; }
  .timeline__edge--l3, .timeline__edge--r3 { top: 1916px; }

  .couple { top: 3034px; }
  .location { top: 4250px; }
}
