/* =====================================================================
   Charly & Guitta — swipe invitation
   ---------------------------------------------------------------------
   Every page is drawn inside .stage, an 810 x 1440 design box that is the
   PDF's artboard. All `top` / `left` values below are the PDF's own
   coordinates, converted with var(--u) (= one design pixel). app.js sizes
   each [data-fit-w] line to the PDF's measured text width, so the layout
   holds even when a different font is substituted.
   ===================================================================== */

/* The PDF's own typefaces, lifted out of it — Angsana New for the text and
   Warm Script for the flourishes. Both were embedded as subsets, so they
   carry every glyph the invitation prints; Cormorant Garamond stays behind
   them in the stack to cover the few characters the website adds. */
@font-face{font-family:AngsanaNew;src:url(/fonts/AngsanaNew.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:AngsanaNew;src:url(/fonts/AngsanaNewBold.woff2) format("woff2");font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:AngsanaNew;src:url(/fonts/AngsanaNewItalic.woff2) format("woff2");font-weight:400;font-style:italic;font-display:swap}
@font-face{font-family:AngsanaNew;src:url(/fonts/AngsanaNewBoldItalic.woff2) format("woff2");font-weight:700;font-style:italic;font-display:swap}
@font-face{font-family:WarmScript;src:url(/fonts/WarmScript.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}

@font-face{font-family:Brigovin;src:url(/fonts/Brigovin.otf) format("opentype");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:OldMoney;src:url(/fonts/OldMoney-Script.otf) format("opentype");font-weight:400;font-style:normal;font-display:swap}

:root{
  --ink:#624a44;          /* body brown, sampled from the PDF */
  --gold:#ad8330;         /* map pins, connector rules, the small labels */
  --cream:#fef9ef;        /* the PDF's off-white — type on the dark pages */
  --paper:#f7f5f1;        /* the flat pages: schedule and gift */
  --sand: transparent;         /* the torn paper's top edge, carried on upward */

  --font-serif:"AngsanaNew","Cormorant Garamond",Georgia,"Times New Roman",serif;
  --font-script:"WarmScript","Brigovin","OldMoney","Pinyon Script",cursive;
  /* The PDF embedded Angsana New as subsets — every glyph the invitation
     prints, and no more. Text the website adds (the dropdown, the guest's
     name, the confirmation) can contain letters those subsets never saw, so
     it is set in the fallback face instead of coming out a letter-by-letter
     patchwork. Drop in a complete Angsana New and these two can merge. */
  --font-ui:"Cormorant Garamond",Georgia,"Times New Roman",serif;

  /* one design pixel: the 9:16 stage, fitted to the viewport.
     --vph is maintained by app.js and holds the viewport height *ignoring*
     the on-screen keyboard, so focusing a field on the RSVP page doesn't
     resize the whole design. It falls back to the CSS unit before JS runs. */
  --vph:100vh;
  /* height of the card itself — the full screen on a phone, inset a little
     on desktop so it reads as an invitation held in the middle of the page */
  --frame-h:var(--vph);
  --u:calc(min(100vw, var(--frame-h) * 0.5625) / 810);
  /* empty band above/below the 9:16 stage on a taller screen; 0 otherwise */
  --letterbox:calc((var(--frame-h) - 1440 * var(--u)) / 2);
}
@supports (height:100dvh){
  :root{ --vph:100dvh; }
}
/* Anything wider than 9:16 — i.e. a desktop or tablet window */
@media (min-aspect-ratio: 9/16){
  :root{ --frame-h:calc(var(--vph) - 56px); }
}
/* Anything narrower than 9:16 — real phones are commonly taller than the
   9:16 design (e.g. 19.5:9, 20:9). Basing --u on height instead of width
   here fills the screen edge to edge with no letterbox band top and
   bottom; the sliver of extra width it produces is simply cropped by
   .slide's overflow:hidden, same as a background-size:cover crop. */
@media (max-aspect-ratio: 9/16){
  :root{ --u:calc(var(--frame-h) * 0.5625 / 810); }
}

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

/* class-level display rules below would otherwise beat the UA's
   [hidden]{display:none} — e.g. the RSVP form after it is submitted */
[hidden]{display:none !important}

html,body{
  height:100%;margin:0;padding:0;overflow:hidden;
  background:var(--paper);color:var(--ink);
  font-family:var(--font-serif);
  /* Cormorant defaults to old-style figures — the PDF sets the dates, the
     account numbers and the IBAN as lining ones. */
  font-variant-numeric:lining-nums;
  font-feature-settings:"lnum" 1;
  -webkit-font-smoothing:antialiased;
  -webkit-tap-highlight-color:transparent;
  overscroll-behavior:none;
}

/* ---------------------------------------------------------------- deck */
/* The card is exactly the 9:16 column: full-bleed on a phone, centred in
   the window on desktop with the backdrop showing around it. */
.deck{
  position:fixed;top:50%;left:50%;
  translate:-50% -50%;
  width:min(100vw, calc(var(--frame-h) * 0.5625));
  height:var(--frame-h);
  overflow:hidden;
  background:var(--paper);
  touch-action:pan-y;
  cursor:grab;
}
.deck.is-dragging{cursor:grabbing}

@media (min-aspect-ratio: 9/16){
  body{
    background:
      radial-gradient(120% 88% at 50% 0%, #f7f4ed 0%, #ece7dd 52%, #ded7ca 100%);
  }
  .deck{
    border-radius:6px;
    box-shadow:0 26px 70px rgba(70,52,45,.24), 0 2px 10px rgba(70,52,45,.10);
  }
}

.deck__track{
  display:flex;height:100%;
  will-change:transform;
  transition:transform .62s cubic-bezier(.22,.61,.36,1);
}
.deck.is-dragging .deck__track{transition:none}

.slide{
  position:relative;flex:0 0 100%;width:100%;height:100%;
  display:flex;align-items:center;justify-content:center;
  overflow:hidden;
  user-select:none;-webkit-user-select:none;
}
.slide--paper{background:var(--paper)}
.slide--schedule{background:#f8f6f2}
.slide--cover{background:var(--cream)}
.slide--rsvp{background:var(--ink)}
.slide--closing{background:var(--cream)}

/* Background photographs. One still per page by default; app.js turns a
   page into a cross-fading slideshow as soon as its SLIDESHOW list has
   more than one file in it. */
.slide__bg{
  position:absolute;inset:0;
  background-size:cover;background-position:center;background-repeat:no-repeat;
}
.slide__bg--cover{      background-image:url("/bg/cover.jpg")}
.slide__bg--invitation{ background-image:url("/bg/invitation.jpg")}
.slide__bg--rsvp{       background-image:url("/bg/rsvp.jpg")}
.slide__bg--closing{    background-image:url("/bg/closing.jpg")}

/* One photograph of a background slideshow. app.js builds these layers and
   cross-fades them; the gentle scale drift keeps a still photo alive. */
.slide__frame{
  position:absolute;inset:0;
  background-size:cover;background-position:center;background-repeat:no-repeat;
  opacity:0;transform:scale(1);
  transition:opacity 1.6s ease-in-out, transform 7s ease-out;
  will-change:opacity, transform;
}
.slide__frame.is-on{opacity:1;transform:scale(1.06)}
/* real photographs are in — drop the placeholder gradient behind them */
.slide__bg.has-slideshow{background-image:none}
@media (prefers-reduced-motion: reduce){
  .slide__frame{transition:opacity 1.6s ease-in-out}
  .slide__frame.is-on{transform:none}
}

/* Cream wash that keeps the type legible over the invitation photograph.
   The stops match the PDF's own veil, measured off the artwork: an even
   ~0.84 with the top quarter carried a little further. Raise --wash to
   fade the photo more, lower it to let it through. The cover, the RSVP
   and the closing pages carry no wash at all, exactly as in the PDF. */
.slide__wash{
  --wash:.86;
  position:absolute;inset:0;
  background:linear-gradient(180deg,
    rgba(247,245,239,calc(var(--wash) * 1.02)) 0%,
    rgba(247,245,239,calc(var(--wash) * 1.08)) 25%,
    rgba(247,245,239,calc(var(--wash) * 0.96)) 42%,
    rgba(247,245,239,calc(var(--wash) * 0.97)) 100%);
}

/* --------------------------------------------------------------- stage */
.stage{
  position:relative;
  width:calc(810 * var(--u));
  height:calc(1440 * var(--u));
  /* .slide is a flex container, which by default lets its flex-item children
     shrink below their own width to fit — exactly what must NOT happen here
     on a phone taller than 9:16, where .stage is deliberately wider than the
     viewport so it can overflow and get cropped by .slide's overflow:hidden
     instead of leaving a gap. Without this, the browser silently shrank
     .stage back down to the viewport width and every absolute calc(N*var(--u))
     child position was computed against a canvas wider than what actually
     rendered. */
  flex-shrink:0;
}
.stage > *{
  position:absolute;left:50%;
  translate:-50% -50%;
  margin:0;
  text-align:center;
  line-height:1;
  color:var(--ink);
  white-space:nowrap;
}
/* One line of a multi-line block. width:fit-content makes the box hug the
   glyphs so app.js can measure it; the inherited text-indent cancels the
   trailing letter-space so the line still optically centres. */
.line{
  display:block;width:fit-content;margin-inline:auto;
  white-space:nowrap;
}

/* ------------------------------------------------------ entrance anim */
.anim{
  opacity:0;transform:translateY(calc(18 * var(--u)));
  transition:opacity .85s ease, transform .85s cubic-bezier(.22,.61,.36,1);
  transition-delay:calc(var(--d,0) * .085s + .12s);
}
.slide.is-active .anim{opacity:1;transform:none}

/* ===================================================================== */
/* PAGE 1 — the cover                                                    */
/* ===================================================================== */
.p0-names{
  top:calc(127.5 * var(--u));
  font-size:calc(77.8 * var(--u));
  font-weight:400;text-transform:uppercase;
  letter-spacing:-.0237em;text-indent:-.0237em;
}
.p0-quote{
  top:calc(209.5 * var(--u));
  font-size:calc(26.8 * var(--u));
  font-weight:700;font-style:italic;text-transform:uppercase;
  letter-spacing:.1517em;text-indent:.1517em;
}
.p0-verse{
  top:calc(257 * var(--u));
  font-family:var(--font-script);
  font-size:calc(66.6 * var(--u));
  font-weight:400;
  letter-spacing:.0148em;text-indent:.0148em;
}

/* The double chevron at the foot of the cover. It is also the swipe
   affordance, so it drifts to draw the eye and leaves once the guest has
   turned a page. */
.p0-chevron{
  top:calc(1323.2 * var(--u));
  left:calc(692.3 * var(--u));
  width:calc(71.8 * var(--u));height:calc(71.7 * var(--u));
  color:#4a2c2a;
  animation:chevron-drift 2.6s ease-in-out infinite;
}
.p0-chevron svg{
  display:block;width:100%;height:100%;
  fill:none;stroke:currentColor;stroke-width:11;
  stroke-linecap:butt;stroke-linejoin:round;
}
@keyframes chevron-drift{
  0%,100%{translate:-50% -50%}
  50%{translate:calc(-50% + 7 * var(--u)) -50%}
}
/* wins over `.slide.is-active .anim` — same specificity, declared later */
.deck.has-moved .p0-chevron{opacity:0}

/* ===================================================================== */
/* PAGE 2 — the invitation                                               */
/* ===================================================================== */
.p1-families{
  top:calc(194.8 * var(--u));
  font-size:calc(35.7 * var(--u));
  font-weight:700;text-transform:uppercase;
  letter-spacing:.2565em;text-indent:.2565em;
}
.p1-surnames{
  top:calc(248.5 * var(--u));
  font-size:calc(53.6 * var(--u));
  font-weight:700;text-transform:uppercase;
  letter-spacing:.1434em;text-indent:.1434em;
}
.p1-request{
  top:calc(428.7 * var(--u));
  font-size:calc(35.7 * var(--u));
  line-height:calc(44.5 * var(--u));   /* the PDF's line pitch */
  font-weight:700;text-transform:uppercase;
  letter-spacing:.2567em;text-indent:.2567em;
}
.p1-name{
  font-weight:400;text-transform:uppercase;
  letter-spacing:.1439em;text-indent:.1439em;
}
.p1-name--groom{top:calc(651.2 * var(--u));font-size:calc(114.5 * var(--u))}
.p1-name--bride{top:calc(859.1 * var(--u));font-size:calc(124.3 * var(--u))}

.p1-and{
  top:calc(754.2 * var(--u));
  left:calc(403.45 * var(--u));
  width:calc(328.3 * var(--u));
  height:calc(65.6 * var(--u));
  background:url("/bg/and.svg") center / 100% 100% no-repeat;
}

.p1-date{
  top:calc(1138.6 * var(--u));
  font-size:calc(49.5 * var(--u));
  font-weight:700;text-transform:uppercase;
  letter-spacing:.1444em;text-indent:.1444em;
}
.p1-date sup{
  font-size:.6em;vertical-align:.56em;
  letter-spacing:.1444em;
}
.p1-venue{
  top:calc(1220.5 * var(--u));
  font-size:calc(38.3 * var(--u));
  font-weight:400;text-transform:uppercase;
  letter-spacing:.1434em;text-indent:.1434em;
}

/* ===================================================================== */
/* PAGE 3 — the schedule                                                 */
/* ===================================================================== */
/* The torn band is the PDF's own artwork, 383 design-px tall. The box it
   sits in reaches 600 px above the stage so the flat paper colour still
   meets the top of a letterboxed screen; .slide's overflow clips it. */
.torn{
  top:calc(-600 * var(--u));left:0;translate:none;
  width:100%;height:calc(983 * var(--u));
  background:var(--sand) url("/bg/torn-paper.webp")
             bottom center / 100% calc(383 * var(--u)) no-repeat;
  pointer-events:none;
}

.p2-the{
  top:calc(83.5 * var(--u));
  font-size:calc(87.3 * var(--u));
  font-weight:400;
}
.p2-schedule{
  top:calc(159.5 * var(--u));
  font-family:var(--font-script);
  font-size:calc(175.6 * var(--u));
  font-weight:400;
}

/* The two gold connectors are one PNG holding both, so each rule shows its
   own slice of it: the artwork is 26 x 1188, its segments start at row 90
   and row 921, and each is 268 tall — the PDF's own length. `left` puts the
   1px ink core (12.5px into the image) on the PDF's centre line. The top of
   the upper one fades under the torn paper, exactly as in the artwork. */
.p2-rule{
  translate:none;
  width:calc(26 * var(--u));
  height:calc(268 * var(--u));
  background-image:url("/bg/vertical-shape.png");
  background-repeat:no-repeat;
  background-size:calc(26 * var(--u)) calc(1188 * var(--u));
}
.p2-rule--top{
  top:calc(171.3 * var(--u));
  left:calc(395.75 * var(--u));
  background-position:0 calc(-90 * var(--u));
}
.p2-rule--bottom{
  top:calc(793.7 * var(--u));
  left:calc(392.5 * var(--u));
  background-position:0 calc(-921 * var(--u));
}

.p2-time{
  font-family:var(--font-script);
  font-size:calc(132.7 * var(--u));
  font-weight:400;
}
.p2-time--first{top:calc(443.9 * var(--u))}
.p2-time--second{top:calc(1089.3 * var(--u))}

.p2-place{
  font-size:calc(47.3 * var(--u));
  font-weight:400;text-transform:uppercase;
  letter-spacing:.1444em;text-indent:.1444em;
}
.p2-place--bride{top:calc(544.3 * var(--u))}
.p2-place--groom{top:calc(727.3 * var(--u))}
.p2-place--ceremony{top:calc(1174.5 * var(--u))}

/* Map pins, on the PDF's own coordinates — the artwork sets them left of
   the centre line, each one slightly differently, so `left` is given per
   pin rather than inherited from the centred default. */
.pin{
  display:block;
  width:calc(40 * var(--u));height:calc(56 * var(--u));
  color:var(--gold);
  cursor:pointer;
  transition:scale .25s ease, opacity .25s ease;
}
.pin svg{display:block;width:100%;height:100%;
  fill:none;stroke:currentColor;stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round;vector-effect:non-scaling-stroke}
/* scale (not transform) so the hover lift never fights the entrance anim */
.pin:hover,.pin:focus-visible{scale:1.08;opacity:.78}
.pin.is-static{cursor:default;pointer-events:none}
.pin--bride{    top:calc(619.0 * var(--u)); left:calc(304.1 * var(--u))}
.pin--groom{    top:calc(806.5 * var(--u)); left:calc(304.1 * var(--u))}
.pin--ceremony{ top:calc(1260.5 * var(--u)); left:calc(304.1 * var(--u))}

/* "Google Maps", sitting beside its pin and opening the same place. */
.maplink{
  translate:0 -50%;
  text-align:left;
  font-size:calc(30 * var(--u));
  font-weight:400;text-transform:uppercase;
  letter-spacing:.1444em;
  color:var(--gold);
  text-decoration:underline;
  text-decoration-thickness:max(1px, calc(1.4 * var(--u)));
  text-underline-offset:calc(8 * var(--u));
  cursor:pointer;
  transition:opacity .25s ease;
}
.maplink:hover,.maplink:focus-visible{opacity:.7}
.maplink:focus-visible{outline:max(1px, calc(2 * var(--u))) solid var(--gold);
  outline-offset:calc(6 * var(--u))}
.maplink.is-static{display:none}
.maplink--bride{    top:calc(619.0 * var(--u)); left:calc(338.1 * var(--u))}
.maplink--groom{    top:calc(806.5 * var(--u)); left:calc(338.1 * var(--u))}
.maplink--ceremony{ top:calc(1260.5 * var(--u)); left:calc(338.1 * var(--u))}

/* ===================================================================== */
/* PAGE 4 — the gift details                                             */
/* ===================================================================== */
/* Three photographs butted together across the top. The seams are the
   PDF's: 264.5 and 539.1 of the 810-px artboard. */
/* The band runs up into the letterbox so the photographs still reach the
   top of the screen when it is taller than 9:16 — the same trick the torn
   header plays on the schedule page. */
.gift__band{
  top:calc(0px - var(--letterbox));left:0;translate:none;
  display:flex;
  width:100%;height:calc(635.5 * var(--u) + var(--letterbox));
}
.gift__shot{
  display:block;height:100%;
  background-size:cover;background-position:center;background-repeat:no-repeat;
}
.gift__shot--1{width:calc(264.5 * var(--u));background-image:url("/bg/gift-1.jpg")}
.gift__shot--2{width:calc(274.6 * var(--u));background-image:url("/bg/gift-2.jpg")}
.gift__shot--3{width:calc(270.9 * var(--u));background-image:url("/bg/gift-3.jpg")}

.gift__body{
  top:calc(741.3 * var(--u));
  font-size:calc(30 * var(--u));
  line-height:calc(33.8 * var(--u));   /* the PDF's line pitch */
  font-weight:700;text-transform:uppercase;
  letter-spacing:.1205em;text-indent:.1205em;
}

/* The two accounts are set against the PDF's left margin rather than
   centred, so they override the stage's centring. */
.gift__bank,.gift__label,.gift__value{
  translate:0 -50%;
  text-align:left;
}
.gift__bank{
  font-size:calc(45 * var(--u));
  font-weight:700;text-transform:uppercase;
  letter-spacing:.081em;
}
.gift__label{
  font-size:calc(31.1 * var(--u));
  font-weight:400;text-transform:uppercase;
  letter-spacing:.1441em;
  color:var(--gold);
}
/* Each value carries its own tracking in the PDF, so they are set one by one
   rather than sharing a figure. */
.gift__value{
  font-size:calc(33.9 * var(--u));
  font-weight:400;text-transform:uppercase;
}
.gift__value--account{font-size:calc(34 * var(--u));letter-spacing:.0732em}
.gift__value--bene{letter-spacing:.0112em}
.gift__value--iban{letter-spacing:.1283em}

.gift__bank--whish{     left:calc(132.7 * var(--u)); top:calc(869.4 * var(--u))}
.gift__label--account{  left:calc(134.6 * var(--u)); top:calc(921.5 * var(--u))}
.gift__value--account{  left:calc(133.2 * var(--u)); top:calc(960.3 * var(--u))}
.gift__bank--doha{      left:calc(128.9 * var(--u)); top:calc(1056.4 * var(--u))}
.gift__label--bene{     left:calc(128.8 * var(--u)); top:calc(1114.7 * var(--u))}
.gift__value--bene{     left:calc(126.9 * var(--u)); top:calc(1151.8 * var(--u))}
.gift__label--iban{     left:calc(129.3 * var(--u)); top:calc(1206.8 * var(--u))}
.gift__value--iban{     left:calc(131.1 * var(--u)); top:calc(1239.1 * var(--u))}

/* The gold heart-and-wave rule that closes the page. The artwork carries a
   heart every 509.8 design-px; it is scaled to that period and slid left so
   that — exactly as in the PDF — one heart lands at x 388 and the wave still
   runs off both edges. */
.gift__rule{
  top:calc(1315 * var(--u));left:0;translate:none;
  width:100%;height:calc(97 * var(--u));
  background:url("/bg/heart_shape.png")
             calc(-385.3 * var(--u)) center / calc(1551.7 * var(--u)) auto no-repeat;
}

/* ===================================================================== */
/* PAGE 5 — RSVP / Be our guest                                          */
/* ===================================================================== */
.slide--rsvp .stage > *{color:var(--cream)}

.p5-title{
  top:calc(167.9 * var(--u));
  font-size:calc(75 * var(--u));
  font-weight:700;text-transform:uppercase;
  letter-spacing:-.0241em;text-indent:-.0241em;
}
.p5-deadline{
  top:calc(296.9 * var(--u));
  font-size:calc(56 * var(--u));
  font-weight:400;
  letter-spacing:-.024em;text-indent:-.024em;
}
/* The guest's name, straight off the invite link. It is set at the PDF's
   size and app.js only shrinks it if a longer name would overrun. Any name
   can arrive here, so it uses --font-ui (see the note at the top). */
.p5-guest{
  top:calc(372 * var(--u));
  font-family:var(--font-ui);
  font-size:calc(70 * var(--u));
  font-weight:500;font-style:italic;
  letter-spacing:-.024em;text-indent:-.024em;
}

/* ------------------------------------------------------------ fields */
/* The form is a full-stage layer so each field can sit on its own PDF
   coordinate. --slot0 is the first label's centre line and --btn the
   button's top edge; both shift when the link carries the guest's name
   and the name field is therefore not needed. The 144-px pitch between
   fields is the PDF's. */
.p5-form,.p5-thanks{
  top:0;left:0;translate:none;
  width:100%;height:100%;
  --slot0:542.3;      /* the name field (--i:0) is not rendered */
  --btn:1045.6;
}
.slide--rsvp:not(.has-guest) .p5-form,
.slide--rsvp:not(.has-guest) .p5-thanks{
  --slot0:614.3;
  --btn:1117.6;
}
/* Answering "yes" opens the seat-count field, so the column needs room for
   one more slot: the first label lifts half a pitch and the button drops the
   other half. Both layouts then land on coordinates the page already uses —
   the named one on the unnamed one's, and the unnamed one level with the
   lowest line on the gift page. */
.slide--rsvp.has-count .p5-form{
  --slot0:470.3;
  --btn:1117.6;
}
.slide--rsvp:not(.has-guest).has-count .p5-form{
  --slot0:542.3;
  --btn:1189.7;
}

.field{
  position:absolute;
  left:calc(156.8 * var(--u));
  top:calc((var(--slot0) + var(--i) * 144 - 25) * var(--u));
  width:calc(498.2 * var(--u));
  text-align:center;
  transition:top .32s cubic-bezier(.22,.61,.36,1);
}
.field > label{
  display:block;height:calc(50 * var(--u));
  font-size:calc(50 * var(--u));line-height:1;
  font-weight:400;
  letter-spacing:-.024em;text-indent:-.024em;
  color:var(--cream);
}

/* One box treatment for every control — the PDF's translucent cream
   panel with a white hairline. */
.control{
  display:block;width:100%;
  height:calc(59.3 * var(--u));
  margin:calc(12.4 * var(--u)) 0 0;
  padding:0 calc(18 * var(--u));
  border:max(1px, calc(4 * var(--u))) solid rgba(255,255,255,.55);
  border-radius:0;
  background:rgba(254,249,239,.52);
  font-family:var(--font-ui);
  font-size:calc(36 * var(--u));
  line-height:1.3;
  letter-spacing:.01em;
  color:var(--cream);
  text-align:center;
  transition:background-color .25s ease, border-color .25s ease;
  -webkit-appearance:none;appearance:none;
  touch-action:auto;                 /* don't let the deck eat the gesture */
}
.control:focus{
  outline:none;
  background:rgba(254,249,239,.66);
  border-color:#fff;
}
.control::placeholder{color:var(--cream);opacity:.6}
.field--tall .control{
  height:calc(118.6 * var(--u));
  padding:calc(12 * var(--u)) calc(18 * var(--u));
  resize:none;overflow-y:auto;
}

/* select — the native arrow replaced with a hairline chevron */
.select{position:relative}
.select::after{
  content:"";position:absolute;right:calc(20 * var(--u));
  top:calc(12.4 * var(--u) + 29.6 * var(--u));
  width:calc(14 * var(--u));height:calc(14 * var(--u));
  margin-top:calc(-11 * var(--u));
  border-right:max(1px, calc(2.4 * var(--u))) solid var(--cream);
  border-bottom:max(1px, calc(2.4 * var(--u))) solid var(--cream);
  transform:rotate(45deg);
  pointer-events:none;
}
select.control{padding-right:calc(46 * var(--u));cursor:pointer}
select.control:invalid{opacity:.72}          /* the "— select —" placeholder */
select.control option{color:#2c2422;background:#f7f5f1}

.field__error{
  position:absolute;left:calc(156.8 * var(--u));
  top:calc((var(--btn) - 46) * var(--u));
  width:calc(498.2 * var(--u));
  margin:0;text-align:center;
  font-family:var(--font-ui);
  font-size:calc(30 * var(--u));
  letter-spacing:.06em;
  color:#ffd9d2;
  transition:top .32s cubic-bezier(.22,.61,.36,1);
}

.p5-submit{
  position:absolute;
  left:calc(325.2 * var(--u));
  top:calc(var(--btn) * var(--u));
  width:calc(159.5 * var(--u));height:calc(60.1 * var(--u));
  padding:0;
  border:max(1px, calc(4 * var(--u))) solid #fff;
  border-radius:calc(9 * var(--u));
  background:var(--cream);
  color:#4a2c2a;
  font-family:var(--font-serif);
  font-size:calc(48 * var(--u));font-weight:400;line-height:1;
  text-transform:uppercase;letter-spacing:-.024em;text-indent:-.024em;
  cursor:pointer;
  transition:background-color .25s ease, opacity .25s ease,
             top .32s cubic-bezier(.22,.61,.36,1);
}
.p5-submit:hover{background:#fff}
.p5-submit:disabled{opacity:.62;cursor:default}

/* ------------------------------------------------------- thank you */
.p5-thanks{
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start;
  padding-top:calc(640 * var(--u));
  text-align:center;
  white-space:normal;
}
.p5-check{
  display:block;
  width:calc(96 * var(--u));height:calc(96 * var(--u));
  margin:0 0 calc(44 * var(--u));
  border:max(1px, calc(2.4 * var(--u))) solid var(--cream);
  border-radius:50%;
  color:var(--cream);
}
.p5-check svg{
  display:block;width:100%;height:100%;
  fill:none;stroke:currentColor;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round;
  vector-effect:non-scaling-stroke;
}
.p5-thanks p{
  margin:0;
  max-width:calc(640 * var(--u));
  font-family:var(--font-ui);
  font-size:calc(43 * var(--u));
  line-height:1.6;
  color:var(--cream);
}

/* ===================================================================== */
/* PAGE 6 — the closing note                                             */
/* ===================================================================== */
.p6-note{
  top:calc(171.25 * var(--u));
  font-size:calc(46.3 * var(--u));
  line-height:calc(43.5 * var(--u));   /* the PDF's line pitch */
  font-weight:700;font-style:italic;
  letter-spacing:-.0256em;text-indent:-.0256em;
}

/* Site credit — a small pill low in the frame, clear of the dots. The
   translucent dark chip (same idea as .control) keeps it legible over
   whichever part of the closing photo lands underneath it. */
.p6-credit{
  top:calc(1352 * var(--u));
  padding:calc(11 * var(--u)) calc(24 * var(--u));
  border:max(1px, calc(1.6 * var(--u))) solid rgba(255,255,255,.4);
  border-radius:999px;
  background:rgba(35,26,22,.4);
  font-family:var(--font-ui);
  font-size:calc(24 * var(--u));
  letter-spacing:.03em;
  color:var(--cream);
  text-decoration:none;
  transition:background-color .25s ease;
}
.p6-credit:hover,.p6-credit:focus-visible{background:rgba(35,26,22,.6)}

/* ===================================================================== */
/* Music toggle — bottom left, clear of the dots and the cover chevron   */
/* ===================================================================== */
.music{
  position:absolute;left:16px;
  bottom:calc(env(safe-area-inset-bottom, 0px) + 16px);
  display:flex;align-items:center;justify-content:center;
  width:38px;height:38px;padding:0;
  border:1px solid rgba(173,131,48,.55);border-radius:50%;
  background:rgba(247,245,241,.62);
  color:var(--gold);
  cursor:pointer;
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  transition:opacity .25s ease, background-color .25s ease, border-color .25s ease;
}
.music:hover{background:rgba(247,245,241,.85)}
.music svg{display:block;width:17px;height:17px}
/* over the dark photographs the disc flips to match the dots */
.deck.is-dark .music{
  border-color:rgba(254,249,239,.5);
  background:rgba(40,30,28,.42);
  color:var(--cream);
}

/* ===================================================================== */
/* Page dots                                                             */
/* ===================================================================== */
.dots{
  position:absolute;left:50%;transform:translateX(-50%);
  bottom:calc(env(safe-area-inset-bottom, 0px) + 22px);
  display:flex;align-items:center;gap:9px;
}
.dots__dot{
  width:7px;height:7px;padding:0;border:0;border-radius:99px;
  background:var(--ink);opacity:.3;cursor:pointer;
  transition:width .35s ease, opacity .35s ease, background-color .35s ease;
}
.dots__dot.is-on{width:26px;opacity:.66}
/* the RSVP and closing photographs are dark — the dots flip to cream */
.deck.is-dark .dots__dot{background:var(--cream);opacity:.42}
.deck.is-dark .dots__dot.is-on{opacity:.9}

/* ===================================================================== */
@media (prefers-reduced-motion: reduce){
  .anim,.pin.anim{transition:none;opacity:1;transform:none}
  .field,.field__error,.p5-submit{transition:none}
  .deck__track{transition:none}
  .p0-chevron{animation:none}
}
