/* ------------------------------------------------------------------
   Tokens. Every size in the scaled sections is written in "design px"
   against a 1024px-wide canvas: calc(N * var(--u)).
   ------------------------------------------------------------------ */
:root {
  color-scheme: light;
  --blush: #f2d6d3;          /* header */
  --rose: #b9757c;           /* buttons, focus, strip date */
  --rose-deep: #9c5a62;
  --ink: #261911;            /* dark brown text */
  --wine: #3d0c10;           /* header text, Save The Date */
  --cream: #fdf8f2;          /* page background */
  --paper: #fffaf5;          /* photo paper, cards */
  --taupe: #8a706a;          /* secondary text */
  --line: #ead7d0;           /* borders, dividers */
  --white: #ffffff;
  --backdrop: var(--blush);  /* outside the page on wide screens: same pink as the header */

  --serif: "Marcellus", "Cormorant Garamond", Georgia, serif;
  --script: "Pinyon Script", "Snell Roundhand", "Apple Chancery", cursive;
  --mono: "Cutive Mono", "Courier New", Courier, monospace;
  --sans: "Montserrat", "Helvetica Neue", Arial, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }
body {
  margin: 0;
  background: var(--backdrop);
  color: var(--ink);
  font-family: var(--serif);
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
[hidden] { display: none !important; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--wine); outline-offset: 3px; }

/* ---------------- 0. Cover ----------------
   Pinned full-screen photo. main.js sets --p from 0 to 1 as the first
   screen scrolls away; the photo zooms and dims while the sheet slides over. */
.cover {
  --p: 0;
  position: sticky;
  top: 0;
  z-index: 0;
  height: 100vh;
  height: 100svh;
  min-height: 520px;
  overflow: clip;
  display: grid;
  place-items: end center;
  background: #1b1513;
  color: var(--white);
  text-align: center;
}
.cover__media {
  position: absolute; inset: 0;
  transform: scale(calc(1 + var(--p) * .08));
  transform-origin: 50% 40%;
  will-change: transform;
}
.cover__photo {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 54% 36%;
}
.cover__media::after { /* legibility scrim, deepens as you scroll */
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(to top, rgba(20,12,10,.62) 0%, rgba(20,12,10,.18) 38%, rgba(20,12,10,0) 60%),
    rgba(20,12,10, calc(var(--p) * .5));
}
.cover__text {
  position: relative;
  padding: 0 24px clamp(96px, 16vh, 168px);
  opacity: calc(1 - var(--p) * 1.8);
  translate: 0 calc(var(--p) * -80px);
}
.cover__eyebrow, .cover__date {
  margin: 0;
  font: 400 clamp(12px, 1.1vw, 15px)/1.4 var(--sans);
  letter-spacing: .32em;
  text-transform: uppercase;
}
.cover__names {
  margin: clamp(10px, 1.4vw, 18px) 0 clamp(14px, 1.8vw, 22px);
  font: 400 clamp(52px, 9vw, 136px)/1 var(--serif);
  letter-spacing: -.005em;
  text-shadow: 0 2px 30px rgba(20,12,10,.25);
}
.cover__dot { margin-inline: .7em; }
@media (max-width: 560px) {
  .cover__date span { display: block; }
  .cover__date .cover__dot { display: none; }
  .cover__eyebrow, .cover__date { letter-spacing: .26em; line-height: 1.7; }
}
.cover__cue {
  position: absolute;
  left: 50%;
  bottom: clamp(24px, 4vh, 40px);
  translate: -50% 0;
  width: 44px; height: 44px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,.45);
  opacity: calc(1 - var(--p) * 3);
  transition: background .25s ease, border-color .25s ease;
}
.cover__cue:hover { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.8); }
.cover__cue svg { width: 20px; height: 20px; fill: none; stroke: #fff; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* Everything after the cover rides up over it */
.sheet {
  position: relative;
  z-index: 1;
  background: var(--backdrop);
  box-shadow: 0 -24px 60px rgba(20, 12, 10, .28);
}

.page {
  container-type: inline-size;
  --u: calc(100cqw / 1024);
  max-width: 1280px;
  margin-inline: auto;
  background: var(--cream);
  overflow: hidden;
}

/* ---------------- 1. Header ---------------- */
.hero {
  background: var(--blush);
  color: var(--wine);
  text-align: center;
  padding: max(30px, calc(46 * var(--u))) 16px max(28px, calc(44 * var(--u)));
  display: grid;
  justify-items: center;
  gap: max(10px, calc(16 * var(--u)));
}
.hero__title {
  margin: 0;
  font: 400 max(46px, calc(92 * var(--u)))/1.1 var(--script); /* copperplate, like the card and polaroid */
}
.hero__place {
  margin: max(4px, calc(8 * var(--u))) 0 0;
  font: 400 max(18px, calc(39 * var(--u)))/1.1 var(--serif);
  letter-spacing: .04em;
}
.hero__when {
  margin: 0;
  font: 400 max(14px, calc(30 * var(--u)))/1.2 var(--serif);
  letter-spacing: .02em;
}

/* ---------------- 2. Photobooth collage ---------------- */
.booth {
  position: relative;
  aspect-ratio: 1024 / 1125;
  max-width: 100%;
  overflow: hidden;
  isolation: isolate;
  /* Curtain fold shades (mid, light, highlight, light, deep, mid-deep) and how much it darkens toward the bottom */
  --fold-1: #dfb9b5; --fold-2: #ecccc8; --fold-3: #f5dad6; --fold-4: #edcfca; --fold-5: #d1a9a7; --fold-6: #dfbcb8; /* pale blush */
  --curtain-shade: .22;
  /* Photobooth curtain: two offset fold patterns + light falloff */
  background:
    radial-gradient(ellipse 70% 45% at 50% 0%, rgba(255,255,255,.22), transparent 70%),
    linear-gradient(to bottom, rgba(52,30,26,.02) 0%, rgba(52,30,26, calc(var(--curtain-shade) * .43)) 60%, rgba(52,30,26, var(--curtain-shade)) 100%),
    repeating-linear-gradient(90deg,
      rgba(255,255,255,0) 0,
      rgba(255,255,255,.05) calc(23 * var(--u)),
      rgba(52,30,26,.08) calc(41 * var(--u)),
      rgba(255,255,255,0) calc(97 * var(--u))),
    repeating-linear-gradient(90deg,
      var(--fold-1) 0,
      var(--fold-2) calc(14 * var(--u)),
      var(--fold-3) calc(24 * var(--u)),
      var(--fold-4) calc(34 * var(--u)),
      var(--fold-5) calc(46 * var(--u)),
      var(--fold-6) calc(58 * var(--u)),
      var(--fold-1) calc(64 * var(--u)));
}
.booth::before { /* soft vignette at the edges, like a flash photo */
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(ellipse 80% 70% at 50% 45%, transparent 55%, rgba(52,30,26, calc(var(--curtain-shade) * .83)) 100%);
  z-index: -1;
  pointer-events: none;
}
.booth > * { position: absolute; }

/* Photo strip */
.strip {
  left: calc(156 * var(--u));
  top: calc(101 * var(--u));
  width: calc(344 * var(--u));
  height: calc(940 * var(--u));
  padding: calc(30 * var(--u));
  display: flex;
  flex-direction: column;
  gap: calc(13 * var(--u));
  background: linear-gradient(100deg, #fffaf5, #f6ece3);
  box-shadow:
    0 calc(18 * var(--u)) calc(34 * var(--u)) rgba(52,30,26,.45),
    0 calc(2 * var(--u)) calc(4 * var(--u)) rgba(52,30,26,.2);
  transform: rotate(-12deg);
  z-index: 2;
  transition: transform .4s ease;
}
.strip:hover { transform: rotate(-11deg) translateY(calc(-8 * var(--u))); }
/* Reel window: exactly four frames tall. The track holds the frames twice
   and slides up by one set (4 × (frame + gap)), so the loop is seamless. */
.strip__reel {
  height: calc((4 * 182 + 3 * 13) * var(--u));
  flex: none;
  overflow: hidden;
}
.strip__track {
  display: flex;
  flex-direction: column;
  gap: calc(13 * var(--u));
}
.strip__frame {
  width: 100%;
  height: calc(182 * var(--u));
  flex: none;
  object-fit: cover;
  background: #cfcfcf;
  box-shadow: inset 0 0 0 1px rgba(52,30,26,.08);
}
.strip__date {
  flex: 1;
  display: grid;
  place-items: center;
  padding-right: calc(34 * var(--u));
  font: 400 calc(46 * var(--u))/1 var(--serif);
  color: var(--rose);
  letter-spacing: .02em;
}

/* Wax seal */
.seal {
  left: calc(91 * var(--u));
  top: calc(794 * var(--u));
  width: calc(209 * var(--u));
  height: calc(209 * var(--u));
  border-radius: 49% 51% 47% 53% / 52% 47% 53% 48%;
  background: radial-gradient(circle at 34% 28%, #fff4f2 0%, #f4dad6 38%, #e4bab6 72%, #d3a3a0 100%);
  box-shadow:
    0 calc(10 * var(--u)) calc(20 * var(--u)) rgba(52,30,26,.4),
    inset calc(-7 * var(--u)) calc(-9 * var(--u)) calc(16 * var(--u)) rgba(110,50,55,.18),
    inset calc(6 * var(--u)) calc(6 * var(--u)) calc(12 * var(--u)) rgba(255,255,255,.9);
  display: grid;
  place-items: center;
  z-index: 4;
  transform: rotate(-8deg);
}
.seal::before { /* pressed inner disc */
  content: "";
  position: absolute;
  inset: 16%;
  border-radius: 50%;
  background: radial-gradient(circle at 60% 65%, #fbeae7, #efd0cc 70%);
  box-shadow:
    inset calc(5 * var(--u)) calc(6 * var(--u)) calc(10 * var(--u)) rgba(110,50,55,.2),
    inset calc(-4 * var(--u)) calc(-4 * var(--u)) calc(8 * var(--u)) rgba(255,255,255,.95);
}
.seal::after { /* beaded border inside the stamp */
  content: "";
  position: absolute;
  inset: 21%;
  border-radius: 50%;
  border: calc(3 * var(--u)) dotted rgba(150, 80, 85, .28);
}
.seal__mono {
  position: relative;
  z-index: 1;
  font: 400 calc(64 * var(--u))/1 var(--script);
  color: #ecc9c5;
  text-shadow:
    calc(-1.5 * var(--u)) calc(-1.5 * var(--u)) calc(1 * var(--u)) rgba(110,50,55,.35),
    calc(1.5 * var(--u)) calc(1.5 * var(--u)) 0 #ffffff;
  transform: translateY(calc(4 * var(--u)));
}

/* Polaroid */
.polaroid {
  left: calc(482 * var(--u));
  top: calc(96 * var(--u));
  width: calc(446 * var(--u));
  padding: calc(18 * var(--u)) calc(18 * var(--u)) 0;
  background: linear-gradient(170deg, #fffaf4, #f3e8de);
  box-shadow:
    0 calc(22 * var(--u)) calc(40 * var(--u)) rgba(52,30,26,.5),
    0 calc(2 * var(--u)) calc(5 * var(--u)) rgba(52,30,26,.2);
  transform: rotate(3.5deg);
  z-index: 3;
  transition: transform .4s ease;
}
.polaroid:hover { transform: rotate(2deg) translateY(calc(-8 * var(--u))); }
.polaroid__photo {
  width: 100%;
  height: calc(480 * var(--u));
  object-fit: cover;
  object-position: 50% 30%;
  background: #bdbdbd;
}
.polaroid__label {
  height: calc(112 * var(--u));
  margin-inline: calc(-6 * var(--u));
  display: grid;
  place-items: center;
  background: linear-gradient(180deg, #f1e5da 0%, #fbf3ea 40%, #eee1d5 100%);
  box-shadow: inset 0 calc(4 * var(--u)) calc(6 * var(--u)) rgba(52,30,26,.08);
  font: 400 calc(44 * var(--u))/1 var(--script);
  color: var(--ink);
}

/* Silver tray */
.tray {
  left: calc(560 * var(--u));
  top: calc(688 * var(--u));
  width: calc(350 * var(--u));
  height: calc(420 * var(--u));
  border-radius: 50% / 46%;
  background: conic-gradient(from 200deg,
    #a99272, #f4e9d4, #bba684, #fff8e8, #a48d6c, #e8d8bb, #b39e7c, #fbf1de, #a99272);
  box-shadow:
    0 calc(16 * var(--u)) calc(30 * var(--u)) rgba(52,30,26,.5),
    inset 0 0 0 calc(3 * var(--u)) rgba(255,255,255,.4);
  transform: rotate(12deg);
  z-index: 4;
}
.tray::before { /* the plate's well */
  content: "";
  position: absolute;
  inset: 12%;
  border-radius: 50% / 46%;
  background: radial-gradient(ellipse at 38% 30%, #fffaf0, #e8dbc2 58%, #c4b08f);
  box-shadow:
    inset 0 0 calc(18 * var(--u)) rgba(52,30,26,.35),
    0 0 0 calc(3 * var(--u)) #d6c5a5;
}
.tray::after { /* beaded rim */
  content: "";
  position: absolute;
  inset: 4.5%;
  border-radius: 50% / 46%;
  border: calc(6 * var(--u)) dotted rgba(255,255,255,.8);
  filter: drop-shadow(0 calc(1 * var(--u)) 0 rgba(52,30,26,.25));
}

/* Save The Date card */
.std {
  left: calc(546 * var(--u));
  top: calc(796 * var(--u));
  width: calc(328 * var(--u));
  height: calc(264 * var(--u));
  background: var(--paper);
  box-shadow: 0 calc(14 * var(--u)) calc(26 * var(--u)) rgba(52,30,26,.4);
  transform: rotate(12deg);
  z-index: 5;
  display: grid;
  place-items: center;
  text-align: center;
}
.std::before {
  content: "";
  position: absolute;
  inset: calc(12 * var(--u));
  border: 1px solid rgba(61, 12, 16, .35);
}
.std__text {
  margin: 0;
  font: 400 calc(62 * var(--u))/1.12 var(--script); /* copperplate, like the polaroid caption */
  color: var(--wine);
}

/* Florals */
.flowers {
  left: calc(700 * var(--u));
  top: calc(660 * var(--u));
  width: calc(330 * var(--u));
  height: calc(480 * var(--u)); /* viewBox 220 × 320; strands run off the bottom edge */
  z-index: 7;
  filter: drop-shadow(0 calc(6 * var(--u)) calc(8 * var(--u)) rgba(52,30,26,.35));
}

/* ---------------- 3. Countdown + address ---------------- */
.details {
  padding: max(40px, calc(72 * var(--u))) 16px max(48px, calc(64 * var(--u)));
  display: grid;
  justify-items: center;
  text-align: center;
}

.details__follow {
  margin: 0;
  font: 400 max(17px, calc(42 * var(--u)))/1.2 var(--serif);
  letter-spacing: .05em;
  color: var(--ink);
  text-wrap: balance;
}

.countdown {
  margin-top: max(20px, calc(40 * var(--u)));
  display: grid;
  grid-template-columns: repeat(7, auto);
  align-items: end;
  column-gap: max(2px, calc(6 * var(--u)));
  row-gap: max(10px, calc(22 * var(--u)));
  font-variant-numeric: tabular-nums;
}
.countdown__num, .countdown__sep {
  font: 400 max(36px, calc(92 * var(--u)))/1 var(--mono);
  color: var(--ink);
  letter-spacing: .08em;
  margin-right: -.08em;
}
.countdown__sep { letter-spacing: 0; margin-right: 0; }
.countdown__lbl {
  grid-row: 2;
  justify-self: center;
  font: 400 max(12px, calc(31 * var(--u)))/1 var(--sans);
  letter-spacing: .02em;
  color: var(--ink);
}
.countdown__lbl--d { grid-column: 1; }
.countdown__lbl--h { grid-column: 3; }
.countdown__lbl--m { grid-column: 5; }
.countdown__lbl--s { grid-column: 7; }

/* ---------------- Address form ---------------- */
.addr {
  width: 100%;
  max-width: max(340px, calc(520 * var(--u)));
  margin-top: max(48px, calc(88 * var(--u)));
  padding-top: max(40px, calc(64 * var(--u)));
  border-top: 1px solid var(--line);
}
.addr__title {
  margin: 0;
  font: 400 max(19px, calc(30 * var(--u)))/1.2 var(--serif);
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--ink);
  text-wrap: balance;
}
.addr__intro {
  margin: max(10px, calc(12 * var(--u))) 0 0;
  font: 400 max(16px, calc(21 * var(--u)))/1.5 var(--serif);
  color: var(--taupe);
}
.addr__form {
  display: grid;
  gap: max(18px, calc(22 * var(--u)));
  margin-top: max(28px, calc(40 * var(--u)));
  text-align: left;
}
.addr__row { display: grid; grid-template-columns: 1fr 1fr; gap: max(16px, calc(20 * var(--u))); }
.addr__row--3 { grid-template-columns: 1.3fr 1fr .9fr; } /* City | State | ZIP */
.addr label {
  display: block;
  font: 400 max(12px, calc(14 * var(--u)))/1 var(--sans);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--taupe);
}
.addr input, .addr select {
  display: block;
  width: 100%;
  height: max(48px, calc(56 * var(--u)));
  margin-top: max(8px, calc(10 * var(--u)));
  padding: 0 max(14px, calc(16 * var(--u)));
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  font: 400 max(16px, calc(18 * var(--u)))/1 var(--sans);
  color: var(--ink);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.addr input:hover, .addr select:hover { border-color: #dcbdb5; }
.addr input:focus, .addr select:focus { outline: none; border-color: var(--rose); box-shadow: 0 0 0 3px rgba(185, 117, 124, .22); }
.addr select {
  appearance: none;
  padding-right: 40px;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a706a' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 14px center / 16px;
  cursor: pointer;
}
.addr select:invalid { color: #b89d97; } /* "Select" placeholder */
.addr select option { color: var(--ink); }
.addr__submit {
  height: max(52px, calc(60 * var(--u)));
  margin-top: max(8px, calc(12 * var(--u)));
  border: 0;
  border-radius: 8px;
  background: var(--rose);
  color: #fff;
  font: 400 max(14px, calc(16 * var(--u)))/1 var(--sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .2s ease;
}
.addr__submit:hover { background: var(--rose-deep); }
.addr__submit:disabled { opacity: .7; cursor: progress; }
/* Turnstile shares a grid cell with the button so it never adds a row gap. It's usually
   invisible, so it takes no space until Cloudflare actually shows a check
   (main.js adds .is-interactive at that point). */
.addr__send { display: grid; }
.addr__turnstile { display: flex; justify-content: center; }
.addr__turnstile:not(.is-interactive) { height: 0; overflow: hidden; }
.addr__turnstile.is-interactive { margin-bottom: 4px; }
.addr__status { margin: 0; font: 400 max(15px, calc(18 * var(--u)))/1.5 var(--serif); text-align: center; color: #4a3d35; }
@media (max-width: 420px) { .addr__row { grid-template-columns: 1fr; } }

/* Thank-you state (replaces the form after a successful submission) */
.thanks { display: grid; justify-items: center; text-align: center; padding: max(8px, calc(12 * var(--u))) 0 max(8px, calc(16 * var(--u))); outline: none; }
.thanks__mark { width: max(64px, calc(84 * var(--u))); height: auto; overflow: visible; }
.thanks__ring { fill: var(--blush); stroke: var(--rose); stroke-width: 1.5; }
.thanks__heart { fill: none; stroke: var(--wine); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.thanks__title {
  margin: max(14px, calc(18 * var(--u))) 0 0;
  font: 400 max(46px, calc(72 * var(--u)))/1.1 var(--script);
  color: var(--wine);
}
.thanks__text {
  margin: max(10px, calc(12 * var(--u))) 0 0;
  font: 400 max(17px, calc(22 * var(--u)))/1.55 var(--serif);
  color: var(--ink);
  text-wrap: balance;
}
.thanks__note {
  margin: max(10px, calc(12 * var(--u))) 0 0;
  font: 400 max(14px, calc(16 * var(--u)))/1.5 var(--serif);
  color: var(--taupe);
}
.thanks__sign {
  margin: max(22px, calc(30 * var(--u))) 0 0;
  font: 400 max(12px, calc(14 * var(--u)))/1.4 var(--sans);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--rose-deep);
}
.thanks__dot { margin-inline: .7em; }
@media (max-width: 560px) {
  .thanks__sign span { display: block; }
  .thanks__sign .thanks__dot { display: none; }
  .thanks__sign { line-height: 1.9; }
}
.thanks__again {
  margin-top: max(26px, calc(36 * var(--u)));
  padding: 6px 2px;
  border: 0;
  background: none;
  font: 400 max(13px, calc(15 * var(--u)))/1.4 var(--sans);
  color: var(--taupe);
  text-decoration: underline;
  text-decoration-color: var(--line);
  text-underline-offset: 4px;
  cursor: pointer;
  transition: color .2s ease, text-decoration-color .2s ease;
}
.thanks__again:hover { color: var(--rose-deep); text-decoration-color: currentColor; }
@media (max-width: 560px) { /* City on its own line, State + ZIP side by side */
  .addr__row--3 { grid-template-columns: 1fr 1fr; }
  .addr__row--3 > :first-child { grid-column: 1 / -1; }
}

/* ---------------- Motion ----------------
   Only with JS (html.js) and when the visitor hasn't asked for reduced motion.
   main.js adds .is-in when an element scrolls into view. Movement uses the
   standalone translate / scale / rotate properties so it stacks on top of
   each piece's own transform instead of replacing it. */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }

  /* Cover: photo settles and the title rises in on load */
  .cover__photo { animation: settle 2.4s cubic-bezier(.16,1,.3,1) both; }
  .cover__text > * { animation: rise 1.2s cubic-bezier(.16,1,.3,1) both; }
  .cover__eyebrow { animation-delay: .35s; }
  .cover__names   { animation-delay: .5s; }
  .cover__date    { animation-delay: .7s; }
  .cover__cue svg { animation: nudge 2.2s 1.6s ease-in-out infinite; }

  /* Simple fade-up for text blocks */
  .js [data-reveal] {
    opacity: 0;
    translate: 0 32px;
    transition: opacity 1s cubic-bezier(.16,1,.3,1) var(--d, 0s), translate 1.1s cubic-bezier(.16,1,.3,1) var(--d, 0s);
  }
  .js [data-reveal].is-in { opacity: 1; translate: none; }

  /* Collage: pieces wait off-stage until the booth is in view */
  .js .booth:not(.is-in) > * { opacity: 0; }
  .js .booth.is-in .strip    { animation: strip-rise 1.7s .1s cubic-bezier(.16,1,.3,1) both; }
  .js .booth.is-in .polaroid { animation: glide-in 1.4s .45s cubic-bezier(.16,1,.3,1) both; }
  .js .booth.is-in .tray     { animation: lift-in 1.2s .75s cubic-bezier(.16,1,.3,1) both; }
  .js .booth.is-in .std      { animation: lift-in 1.2s .9s cubic-bezier(.16,1,.3,1) both; }
  .js .booth.is-in .seal     { animation: press 0.8s 1.15s cubic-bezier(.2,1.4,.4,1) both; }
  .js .booth.is-in .flowers  { animation: bloom 1.2s 1.25s cubic-bezier(.16,1,.3,1) both; }

  /* Form ↔ thank-you swap */
  .addr__ask.is-leaving { animation: fade-out .35s ease both; }
  .thanks:not([hidden]) > * { animation: rise .9s cubic-bezier(.16,1,.3,1) both; }
  .thanks:not([hidden]) .thanks__title { animation-delay: .15s; }
  .thanks:not([hidden]) .thanks__text  { animation-delay: .3s; }
  .thanks:not([hidden]) .thanks__note  { animation-delay: .38s; }
  .thanks:not([hidden]) .thanks__sign  { animation-delay: .45s; }
  .thanks:not([hidden]) .thanks__again { animation-delay: .6s; }
  .thanks:not([hidden]) .thanks__heart { stroke-dasharray: 94; animation: draw 1.4s .35s cubic-bezier(.6,0,.3,1) both; }

  /* Photo reel: slow continuous loop once the copy is in place; pauses on hover */
  .strip__track.is-looping { animation: reel 22s linear infinite; }
  .strip:hover .strip__track { animation-play-state: paused; }
}
@keyframes settle   { from { scale: 1.08; } to { scale: 1; } }
@keyframes rise     { from { opacity: 0; translate: 0 24px; } to { opacity: 1; translate: none; } }
@keyframes fade-out { to { opacity: 0; translate: 0 -8px; } }
@keyframes draw     { from { stroke-dashoffset: 94; } to { stroke-dashoffset: 0; } }
@keyframes nudge    { 0%, 100% { translate: 0 0; } 50% { translate: 0 5px; } }
@keyframes strip-rise { /* slides up out of the bottom edge, like a photobooth print */
  from { translate: 0 calc(1080 * var(--u)); rotate: 4deg; }
  to   { translate: none; rotate: none; }
}
@keyframes glide-in {
  from { opacity: 0; translate: calc(140 * var(--u)) calc(-30 * var(--u)); rotate: 7deg; }
  to   { opacity: 1; translate: none; rotate: none; }
}
@keyframes lift-in {
  from { opacity: 0; translate: 0 calc(90 * var(--u)); }
  to   { opacity: 1; translate: none; }
}
@keyframes press {
  from { opacity: 0; scale: 1.35; }
  to   { opacity: 1; scale: 1; }
}
@keyframes bloom {
  from { opacity: 0; scale: .85; }
  to   { opacity: 1; scale: 1; }
}
@keyframes reel     { to { translate: 0 calc(-4 * (182 + 13) * var(--u)); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
