:root {
  --paper-ivory: #f5f0e7;
  --paper-cream: #eee4d5;
  --paper-light: #fbf8f1;
  --olive: #696943;
  --olive-deep: #525331;
  --champagne: #cdbd9f;
  --ink: #40372d;
  --ink-muted: #71695d;
  --error: #7f352f;
  --shadow-paper: 0 24px 60px rgb(62 50 34 / 15%);
  --ease-paper: cubic-bezier(.22, 1, .36, 1);
  --content: 74rem;
  --card-progress: 0;
  --card-y: -2%;
  --card-scale: .6;
  /* Upper bound the card scales up to (1 = its full layout size). Landscape
     phones cap this lower so the final card isn't too large on a short screen. */
  --card-scale-max: 1;
  --env-y: 0%;
  --env-opacity: 1;
  --card-shadow-y: 10px;
  --card-shadow-blur: 12px;
  --card-shadow-alpha: .08;
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;
}

html.scroll-locked,
html.scroll-locked body {
  overflow: hidden;
  overscroll-behavior: none;
  scroll-behavior: auto;
}

html.scroll-locked body {
  position: fixed;
  inset: 0;
  width: 100%;
}

html.scroll-locked .skip-link {
  visibility: hidden;
}

body {
  margin: 0;
  min-width: 320px;
  overflow-x: hidden;
  color: var(--ink);
  background: var(--paper-ivory) url("offwhite-textured-background.jpg") center / 42rem repeat;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1rem;
  line-height: 1.65;
}

img {
  display: block;
  max-width: 100%;
}

button,
input,
select,
textarea {
  font: inherit;
}

a {
  color: inherit;
}

main {
  position: relative;
  overflow-x: clip;
}

/* Ambient falling-petal layer over the content sections (behind the content,
   non-interactive). Petals are spawned by JS; each gets randomised --x / --drift
   / --rot / --dur / --delay and is removed when its fall ends. */
.petal-fall {
  position: absolute;
  z-index: 0;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.petal-fall__petal {
  position: absolute;
  top: -8%;
  left: var(--x, 50%);
  width: var(--size, 2.2rem);
  opacity: 0;
  mix-blend-mode: multiply;
  will-change: transform, opacity;
  animation: petal-drift var(--dur, 14s) linear var(--delay, 0s) forwards;
}

@keyframes petal-drift {
  0% { opacity: 0; transform: translateY(0) translateX(0) rotate(0deg); }
  8% { opacity: .5; }
  92% { opacity: .5; }
  100% {
    opacity: 0;
    transform: translateY(108vh) translateX(var(--drift, 4vw)) rotate(var(--rot, 220deg));
  }
}

@media (prefers-reduced-motion: reduce) {
  .petal-fall {
    display: none;
  }
}

:focus-visible {
  outline: 3px solid var(--olive-deep);
  outline-offset: 4px;
}

[hidden] {
  display: none !important;
}

.skip-link {
  position: fixed;
  z-index: 100;
  top: 1rem;
  left: 1rem;
  padding: .7rem 1rem;
  transform: translateY(-160%);
  background: var(--paper-light);
  box-shadow: var(--shadow-paper);
}

.skip-link:focus {
  transform: translateY(0);
}

.section-shell {
  /* Reserve at least the notch/safe-area inset on each side in landscape so
     content never sits under the notch, while section backgrounds stay full-bleed. */
  width: min(
    calc(100% - max(3rem, env(safe-area-inset-left) + env(safe-area-inset-right))),
    var(--content)
  );
  margin-inline: auto;
}

.kicker,
.detail-label {
  margin: 0 0 .75rem;
  color: var(--olive-deep);
  font-family: Arial, Helvetica, sans-serif;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .2em;
  line-height: 1.3;
  text-transform: uppercase;
}

.opening {
  position: relative;
  z-index: 2;
  /* Sticky stays pinned for (height - 100svh) of scroll. The scene completes in
     the first 2x viewport (see updateDesktopProgress); the extra 0.5x here keeps
     the finished, centred card pinned a little longer so the user can't blow
     past it by accident before the content below scrolls in. */
  min-height: calc(var(--vh, 100svh) * 4.5);
  isolation: isolate;
  overflow: clip;
  background:
    radial-gradient(circle at 50% 42%, rgb(255 255 255 / 52%), transparent 48%),
    var(--paper-ivory) url("offwhite-textured-background.jpg") center / 42rem repeat;
}

.opening__sticky {
  position: sticky;
  top: 0;
  display: grid;
  min-height: var(--vh, 100svh);
  place-items: center;
  align-content: center;
  gap: clamp(.8rem, 2vw, 1.5rem);
  overflow: hidden;
  padding: 3rem 1.5rem 2rem;
}

.opening__intro {
  display: grid;
  place-items: center;
  opacity: .82;
  text-align: center;
}

.opening__monogram {
  width: clamp(4.4rem, 7vw, 6.4rem);
  margin-bottom: -.2rem;
  border-radius: 50%;
  mix-blend-mode: darken;
}

.envelope-stage {
  position: relative;
  width: min(49rem, 56vw, var(--vh, 100svh) * .62 * (833 / 504));
  aspect-ratio: 833 / 504;
  perspective: 1200px;
}

.envelope-layer,
.envelope-open-assembly {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
}

.envelope-layer {
  object-fit: contain;
}

.envelope-open-assembly {
  z-index: 2;
  /* During the opening pop-up, clip the bottom at the envelope's bottom edge so
     the tall card (taller than the envelope) cannot protrude below it while
     emerging. Top left open (-200%) so the card rises out freely. The clip is
     lifted once open so the envelope can later slide fully down and out. */
  clip-path: inset(-200% -50% 0 -50%);
}

.opening.is-open .envelope-open-assembly {
  clip-path: none;
}

.envelope-back {
  z-index: 1;
  opacity: var(--env-opacity);
  filter: drop-shadow(0 10px 12px rgb(42 36 24 / 16%));
  transform: translateY(var(--env-y));
}

.invitation-lift {
  position: absolute;
  z-index: 3;
  top: 21%;
  left: 50%;
  /* Rendered at its largest (final) size; the scroll scene only ever scales it
     DOWN (scale <= 1), so the text layer is never upsampled and stays crisp.
     64% (the in-envelope size) x 1.56 (the final zoom) = 100%. */
  width: 100%;
  max-width: none;
  aspect-ratio: 1448 / 1086;
  margin-inline: 0;
  /* Container so the copy can size in cqw and always fit the paper, regardless
     of the card's transform scale through the scroll scene. */
  container-type: inline-size;
  visibility: hidden;
  filter: drop-shadow(
    0
    var(--card-shadow-y)
    var(--card-shadow-blur)
    rgb(60 48 31 / var(--card-shadow-alpha))
  );
  transform: translate(-50%, var(--card-y)) scale(var(--card-scale));
  transform-origin: 50% 50%;
  will-change: filter, transform;
}

.opening.is-opening .invitation-lift {
  visibility: visible;
}

.envelope-front {
  z-index: 4;
  opacity: var(--env-opacity);
  filter: drop-shadow(0 18px 18px rgb(48 41 27 / 18%));
  transform: translateY(var(--env-y));
}

/* Wrapper fills the full stage (same height as front/back) so its translateY %
   resolves against the same basis — keeping all three layers locked together as
   they slide out. The shorter flap art (833x314) is pinned to the wrapper top. */
.envelope-flap-wrap {
  z-index: 5;
  opacity: var(--env-opacity);
  transform: translateY(var(--env-y));
}

/* Inner flap is self-sized to its own aspect, pinned to the wrapper top, and
   handles only the fold (pivoting about its own top hinge). */
.envelope-flap {
  display: block;
  width: 100%;
  aspect-ratio: 833 / 314;
  transform-origin: 50% 0;
  transition: transform 700ms cubic-bezier(.4, 0, .2, 1);
  will-change: transform;
}

.opening.is-folding .envelope-flap {
  transform: scaleY(-1);
}

.opening.is-opened .envelope-flap-wrap {
  z-index: 2;
}

.seal-button {
  position: absolute;
  z-index: 6;
  top: 62.1%;
  left: 50%;
  display: grid;
  width: clamp(6.8rem, 10vw, 8.8rem);
  cursor: pointer;
  place-items: center;
  gap: .45rem;
  padding: 0;
  border: 0;
  color: var(--ink-muted);
  background: transparent;
  filter: drop-shadow(0 10px 12px rgb(49 39 25 / 22%));
  font-family: Arial, Helvetica, sans-serif;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .2em;
  transform: translate(-50%, -50%);
  text-transform: uppercase;
  transition:
    opacity 400ms ease,
    filter 300ms ease,
    transform 400ms var(--ease-paper);
}

.seal-button:hover,
.seal-button:focus-visible {
  filter: drop-shadow(0 14px 16px rgb(49 39 25 / 28%));
  transform: translate(-50%, -53%) scale(1.025);
}

.seal-button__image {
  width: clamp(4.2rem, 7vw, 6rem);
}

.seal-button__label {
  position: absolute;
  top: calc(100% + .45rem);
  left: 50%;
  width: max-content;
  padding: .35rem .55rem;
  color: var(--ink);
  background: rgb(245 240 231 / 82%);
  transform: translateX(-50%);
}

.seal-button.is-breaking {
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(.82);
}

.opening.is-opening .opening__intro,
.opening.is-opening .seal-button {
  opacity: 0;
  pointer-events: none;
  transition: opacity 500ms ease;
}

.opening__scroll-cue {
  position: absolute;
  bottom: 1.4rem;
  left: 50%;
  margin: 0;
  opacity: 0;
  color: var(--ink-muted);
  font-family: Arial, Helvetica, sans-serif;
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  transform: translate(-50%, .5rem);
  transition: opacity 500ms ease, transform 700ms var(--ease-paper);
}

.opening.is-open .opening__scroll-cue {
  opacity: .72;
  transform: translate(-50%, 0);
}

.opening.is-mobile-reveal .opening__scroll-cue {
  display: none;
}

.petal {
  position: absolute;
  z-index: 0;
  width: clamp(4.5rem, 10vw, 8rem);
  pointer-events: none;
  mix-blend-mode: multiply;
  opacity: .68;
}

.petal--opening-left {
  bottom: -1rem;
  left: 2vw;
  transform: rotate(-20deg);
}

.petal--opening-right {
  top: 13%;
  right: 2vw;
  width: clamp(4rem, 8vw, 6rem);
  transform: rotate(34deg);
}

.guest-nav {
  position: fixed;
  z-index: 30;
  top: 1rem;
  left: 50%;
  display: flex;
  align-items: center;
  gap: clamp(.7rem, 2.2vw, 2rem);
  padding: .55rem .7rem .55rem 1.2rem;
  border: 1px solid rgb(83 76 61 / 13%);
  border-radius: 999px;
  opacity: 0;
  background: rgb(249 245 237 / 90%);
  box-shadow: 0 .8rem 2.5rem rgb(61 50 33 / 10%);
  backdrop-filter: blur(12px);
  transform: translate(-50%, -1rem);
  pointer-events: none;
  transition: opacity 500ms ease, transform 600ms var(--ease-paper);
}

.guest-nav.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;
}

.guest-nav a {
  text-decoration: none;
  font-family: Arial, Helvetica, sans-serif;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.guest-nav__rsvp {
  padding: .5rem .9rem;
  border-radius: 999px;
  color: var(--paper-light);
  background: var(--olive);
}

.reveal-ready [data-reveal] {
  opacity: 0;
  translate: 0 18px;
  transition: opacity 800ms var(--ease-paper), translate 900ms var(--ease-paper);
}

.reveal-ready [data-reveal].is-revealed {
  opacity: 1;
  translate: 0 0;
}

.invitation-card__paper,
.invitation-card__paper img {
  width: 100%;
  height: 100%;
}

.invitation-card__paper {
  position: absolute;
  inset: 0;
}

.invitation-card__paper img {
  object-fit: contain;
  mix-blend-mode: multiply;
}

/* Copy is sized in cqw (percent of card width) so it scales with the card and
   always fits inside the printed paper border. */
.invitation-card__copy {
  position: absolute;
  z-index: 2;
  top: 50%;
  left: 50%;
  width: 76%;
  text-align: center;
  transform: translate(-50%, -50%);
}

.monogram {
  width: 14cqw;
  margin: 0 auto .4cqw;
  border-radius: 50%;
  mix-blend-mode: darken;
  opacity: .74;
}

.invitation-card__copy h1 {
  margin: 1cqw 0;
  font-size: 11.4cqw;
  font-style: italic;
  font-weight: 400;
  letter-spacing: -.055em;
  line-height: .94;
}

.invitation-card__copy h1 span {
  display: inline-block;
  margin-inline: .08em;
  font-size: .7em;
  font-style: normal;
}

.invitation-card__copy p {
  margin: 1.1cqw 0;
  font-size: 2.85cqw;
  line-height: 1.4;
}

.invitation-card__family {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 2.1cqw !important;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
}

.invitation-card__date {
  margin-top: 2.4cqw !important;
  font-size: 3.6cqw !important;
}

.invitation-card__venue {
  margin-top: 2cqw !important;
  font-weight: 700;
}

.fine-rule {
  display: block;
  width: 10cqw;
  height: 1px;
  margin: 2.2cqw auto;
  background: var(--champagne);
}

.lace-corner {
  position: absolute;
  z-index: 3;
  width: clamp(6rem, 14vw, 11rem);
  mix-blend-mode: multiply;
  opacity: .42;
}

.lace-corner--top-left { top: 2%; left: 2%; }
.lace-corner--top-right { top: 0; right: 0; }
.lace-corner--bottom-right { right: 2%; bottom: 2%; }

.details-section {
  padding-block: clamp(4rem, 9vw, 8rem);
}

.section-heading {
  max-width: 42rem;
  margin: 0 auto clamp(3rem, 7vw, 5.5rem);
  text-align: center;
}

.section-heading h2,
.schedule-intro h2,
.dress-card h2,
.location-card h2,
.rsvp-card h2,
.closing h2 {
  margin: 0 0 1rem;
  font-size: clamp(2.5rem, 5vw, 4.6rem);
  font-weight: 400;
  letter-spacing: -.04em;
  line-height: 1.05;
}

.section-heading > p:last-child,
.schedule-intro > p:last-child {
  color: var(--ink-muted);
  font-size: 1.08rem;
}

.essential-details {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-block: 1px solid rgb(92 82 63 / 18%);
}

.essential-detail {
  padding: 2.8rem 2rem;
  text-align: center;
}

.essential-detail + .essential-detail {
  border-left: 1px solid rgb(92 82 63 / 18%);
}

.essential-detail img {
  width: 3.8rem;
  margin: 0 auto 1.2rem;
  mix-blend-mode: multiply;
  opacity: .72;
}

.essential-detail h3,
.event-card h3 {
  margin: 0;
  font-size: clamp(1.6rem, 3vw, 2.3rem);
  font-weight: 400;
}

.essential-detail p {
  margin: .2rem 0 0;
  color: var(--ink-muted);
}

.essential-detail .detail-label {
  color: var(--olive-deep);
}

.lace-divider {
  width: min(43rem, 80vw);
  margin: clamp(3.5rem, 8vw, 6.5rem) auto;
  mix-blend-mode: multiply;
  opacity: .46;
}

.event-pair {
  display: grid;
  grid-template-columns: 1fr 1px 1fr;
  gap: clamp(2rem, 7vw, 6rem);
  max-width: 62rem;
  margin-inline: auto;
}

.event-card {
  padding: 2rem 1rem;
  text-align: center;
}

.event-card__time {
  color: var(--olive-deep);
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: .08em;
}

.event-card p:last-child {
  max-width: 24rem;
  margin-inline: auto;
  color: var(--ink-muted);
}

.event-pair__rule {
  background: rgb(92 82 63 / 20%);
}

.schedule-section {
  color: #f4ecdf;
  background:
    linear-gradient(rgb(75 76 44 / 84%), rgb(75 76 44 / 84%)),
    url("green-textured-background.jpg") center / 42rem repeat;
}

.schedule-section__inner {
  display: grid;
  grid-template-columns: .8fr 1.2fr;
  gap: clamp(4rem, 10vw, 9rem);
  align-items: start;
  padding-block: clamp(6rem, 12vw, 10rem);
}

.schedule-intro {
  position: sticky;
  top: 8rem;
}

.schedule-intro .kicker {
  color: #dfd2b9;
}

.schedule-intro > p:last-child {
  color: rgb(255 248 235 / 72%);
}

.timeline {
  margin: 0;
  padding: 0 0 0 2.5rem;
  border-left: 1px solid rgb(239 227 204 / 43%);
  list-style: none;
}

.timeline li {
  position: relative;
  display: grid;
  grid-template-columns: 7rem 1fr;
  gap: 1.4rem;
  padding: .1rem 0 2.8rem;
}

.timeline li::before {
  position: absolute;
  top: .45rem;
  left: calc(-2.5rem - 5px);
  width: 9px;
  height: 9px;
  border: 1px solid #f1e4cc;
  border-radius: 50%;
  background: #77784a;
  box-shadow: 0 0 0 .45rem rgb(100 101 61);
  content: "";
}

.timeline time {
  color: #eadcc4;
  font-family: Arial, Helvetica, sans-serif;
  font-size: .76rem;
  font-weight: 700;
  letter-spacing: .13em;
}

.timeline span {
  font-size: clamp(1.25rem, 2.5vw, 2rem);
  line-height: 1.2;
}

.dress-section {
  padding-block: clamp(5rem, 10vw, 9rem);
}

.dress-card {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2rem;
  align-items: center;
  max-width: 52rem;
  margin-inline: auto;
  overflow: hidden;
  padding: clamp(2rem, 6vw, 4rem);
  border: 1px solid rgb(92 82 63 / 16%);
  background: rgb(251 248 241 / 60%);
  box-shadow: var(--shadow-paper);
}

.dress-card > img:first-child {
  width: clamp(4rem, 8vw, 6rem);
  mix-blend-mode: multiply;
  opacity: .68;
}

.dress-card h2 {
  font-size: clamp(2rem, 4vw, 3.5rem);
}

.dress-card p:last-child {
  margin-bottom: 0;
  color: var(--ink-muted);
}

.dress-card__petal {
  position: absolute;
  right: -3.5rem;
  bottom: -4rem;
  width: 10rem;
  mix-blend-mode: multiply;
  opacity: .4;
  transform: rotate(-25deg);
}

.location-section {
  padding-bottom: clamp(6rem, 12vw, 10rem);
}

.location-card {
  display: grid;
  grid-template-columns: 1fr .8fr;
  min-height: 34rem;
  box-shadow: var(--shadow-paper);
}

.location-card__copy {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  flex-direction: column;
  padding: clamp(2.5rem, 7vw, 6rem);
  background: var(--paper-light) url("cream-textured-background.jpg") center / 38rem;
}

.location-card address {
  margin-bottom: 2rem;
  color: var(--ink-muted);
  font-style: normal;
  font-size: 1.08rem;
}

.location-card__art {
  display: grid;
  place-items: center;
  align-content: center;
  color: #f6eddd;
  text-align: center;
  background:
    linear-gradient(rgb(85 86 50 / 84%), rgb(85 86 50 / 84%)),
    url("green-textured-background.jpg") center / 38rem;
}

.location-card__art img {
  width: 7rem;
  border-radius: 50%;
  filter: invert(1) brightness(1.8) sepia(.4);
  mix-blend-mode: screen;
  opacity: .72;
}

.location-card__art p {
  margin: 1rem 0 0;
  font-size: 2rem;
}

.location-card__art span {
  font-family: Arial, Helvetica, sans-serif;
  font-size: .65rem;
  letter-spacing: .15em;
  opacity: .7;
}

.button {
  display: inline-flex;
  min-height: 3rem;
  align-items: center;
  justify-content: center;
  padding: .8rem 1.5rem;
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  font-family: Arial, Helvetica, sans-serif;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  transition: background-color 250ms ease, color 250ms ease, border-color 250ms ease;
}

.button--secondary {
  border-color: var(--olive);
  color: var(--olive-deep);
  background: transparent;
}

.button--secondary:hover {
  color: var(--paper-light);
  background: var(--olive);
}

.rsvp-section {
  padding-bottom: clamp(6rem, 12vw, 11rem);
}

.rsvp-card {
  position: relative;
  display: grid;
  grid-template-columns: .82fr 1.18fr;
  overflow: hidden;
  min-height: 42rem;
  box-shadow: var(--shadow-paper);
}

.rsvp-card__intro {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  padding: clamp(2.5rem, 6vw, 5rem);
  color: #f5ecdc;
  text-align: center;
  background:
    linear-gradient(rgb(83 84 48 / 86%), rgb(83 84 48 / 86%)),
    url("green-textured-background.jpg") center / 38rem;
}

.rsvp-card__intro > img {
  width: 6.5rem;
  border-radius: 50%;
  filter: invert(1) brightness(1.8) sepia(.3);
  mix-blend-mode: screen;
  opacity: .72;
}

.rsvp-card__intro .kicker {
  margin-top: 1rem;
  color: #dfd2b9;
}

.rsvp-card__intro p:last-child {
  max-width: 24rem;
  color: rgb(255 248 235 / 75%);
}

.rsvp-card__form {
  display: grid;
  align-items: center;
  padding: clamp(2.5rem, 7vw, 6rem);
  background: var(--paper-light) url("cream-textured-background.jpg") center / 38rem;
}

#rsvp-form {
  display: grid;
}

#rsvp-form label {
  margin: 1.05rem 0 .25rem;
  color: var(--ink-muted);
  font-family: Arial, Helvetica, sans-serif;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

#rsvp-form label span {
  font-weight: 400;
  letter-spacing: .04em;
  text-transform: none;
}

#rsvp-form input,
#rsvp-form select,
#rsvp-form textarea {
  width: 100%;
  border: 0;
  border-bottom: 1px solid rgb(76 67 53 / 35%);
  border-radius: 0;
  color: var(--ink);
  background: transparent;
}

#rsvp-form input,
#rsvp-form select {
  min-height: 2.8rem;
}

#rsvp-form textarea {
  padding-block: .65rem;
  resize: vertical;
}

.form-errors,
.field-error {
  color: var(--error);
}

.form-errors {
  padding: .8rem 1rem;
  border-left: 3px solid var(--error);
  background: rgb(127 53 47 / 8%);
}

.field-error {
  margin: .35rem 0 0;
  font-size: .9rem;
}

[aria-invalid="true"] {
  border-color: var(--error) !important;
}

.button--primary {
  width: 100%;
  margin-top: 2rem;
  color: var(--paper-light);
  background: var(--olive);
}

.button--primary:hover {
  background: var(--olive-deep);
}

.rsvp-confirmation {
  text-align: center;
}

.rsvp-confirmation img {
  width: 9rem;
  margin-inline: auto;
  border-radius: 50%;
  mix-blend-mode: darken;
  opacity: .7;
}

.rsvp-confirmation h3 {
  margin: .5rem 0 0;
  font-size: 3rem;
  font-weight: 400;
}

.closing {
  position: relative;
  overflow: hidden;
  padding: 0 1.5rem clamp(7rem, 14vw, 12rem);
  text-align: center;
}

.closing > div {
  max-width: 48rem;
  margin-inline: auto;
}

.closing__monogram {
  width: 9rem;
  margin: 2rem auto .5rem;
  border-radius: 50%;
  mix-blend-mode: darken;
  opacity: .72;
}

.closing > div > p:last-child {
  color: var(--ink-muted);
  font-style: italic;
}

.petal--closing-left {
  bottom: -2rem;
  left: 2vw;
  transform: rotate(25deg);
}

.petal--closing-right {
  right: 2vw;
  bottom: -1rem;
  transform: rotate(-35deg);
}

.no-js .envelope-open-assembly,
.no-js .invitation-lift,
.no-js .seal-button,
.no-js .guest-nav {
  display: none;
}

.no-js .opening {
  min-height: 100svh;
}

.no-js .opening__sticky {
  position: relative;
}

@keyframes quiet-pulse {
  0%,
  100% { opacity: .35; transform: scaleY(.7); }
  50% { opacity: 1; transform: scaleY(1); }
}

@media (max-width: 900px) {
  .envelope-stage {
    width: min(58rem, 92vw);
  }

  .schedule-section__inner,
  .location-card {
    grid-template-columns: 1fr;
  }

  .schedule-intro {
    position: static;
    max-width: 38rem;
  }

  .location-card__art {
    min-height: 20rem;
  }

  .rsvp-card {
    grid-template-columns: 1fr 1.2fr;
  }
}

@media (max-width: 700px) {
  html {
    scroll-padding-top: 4.5rem;
  }

  .section-shell {
    width: min(calc(100% - 2.5rem), var(--content));
  }

  .guest-nav {
    top: auto;
    right: 1rem;
    bottom: 1rem;
    left: auto;
    padding: 0;
    transform: translateY(1rem);
  }

  .guest-nav.is-visible {
    transform: translateY(0);
  }

  .guest-nav a:not(.guest-nav__rsvp) {
    display: none;
  }

  .guest-nav__rsvp {
    min-height: 3rem;
    padding: .8rem 1.1rem;
  }

  .lace-corner {
    width: 6rem;
  }

  .essential-details {
    grid-template-columns: 1fr;
  }

  .essential-detail + .essential-detail {
    border-top: 1px solid rgb(92 82 63 / 18%);
    border-left: 0;
  }

  .event-pair {
    grid-template-columns: 1fr;
    gap: .5rem;
  }

  .event-pair__rule {
    width: 4rem;
    height: 1px;
    margin-inline: auto;
  }

  .schedule-section__inner {
    gap: 3rem;
  }

  .timeline {
    padding-left: 1.8rem;
  }

  .timeline li {
    grid-template-columns: 5.5rem 1fr;
    gap: .8rem;
  }

  .timeline li::before {
    left: calc(-1.8rem - 5px);
  }

  .dress-card {
    grid-template-columns: 1fr;
    text-align: center;
  }

  .dress-card > img:first-child {
    margin-inline: auto;
  }

  .rsvp-card {
    grid-template-columns: 1fr;
  }

  .rsvp-card__intro {
    min-height: 28rem;
  }

  .rsvp-card__form {
    min-height: 35rem;
  }

  .button {
    min-height: 2.875rem;
  }
}

/* Landscape phones: short viewports. Size the envelope by height (95svh, width
   following the aspect ratio) so it fits, then run the same scroll scene as
   desktop. The intro is hidden to reclaim vertical space. */
@media (orientation: landscape) and (max-height: 600px) {
  .opening__sticky {
    padding: 0;
  }

  .opening__intro,
  .opening__scroll-cue {
    display: none;
  }

  .envelope-stage {
    width: auto;
    height: calc(var(--vh, 100svh) * .95);
    aspect-ratio: 833 / 504;
    transform: none;
  }

  /* Keep the envelope full-height but cap the final card smaller on landscape. */
  .opening {
    --card-scale-max: .82;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }

  .petal {
    transform: none !important;
  }
}

/* Mobile (portrait) opening: two envelope flaps cover the screen and part to
   reveal the invitation card. Hidden on desktop/landscape. */
.mobile-curtain {
  display: none;
}

@media (max-width: 700px) and (orientation: portrait) {
  /* The portrait flap experience replaces the desktop envelope entirely. */
  .opening {
    display: none;
  }

  .mobile-curtain {
    position: fixed;
    z-index: 150;
    inset: 0;
    display: block;
    overflow: hidden;
    background: var(--paper-ivory) url("offwhite-textured-background.jpg") center / 42rem repeat;
  }

  /* Once opened, the curtain stops being a fixed overlay and becomes a normal
     one-screen hero (card visible), so the content sections scroll up below it. */
  .mobile-curtain.is-done {
    position: relative;
    z-index: 1;
    height: var(--vh, 100svh);
    background: transparent;
  }

  /* The parted flaps are gone; only the card hero remains in the done state. */
  .mobile-curtain.is-done .mobile-flap,
  .mobile-curtain.is-done .mobile-seal {
    display: none;
  }

  /* Revealed card, centred behind the flaps. A container so the copy overlay
     can size in cqw against the card width, matching the desktop card. */
  .mobile-curtain__card {
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 1;
    width: 84vw;
    aspect-ratio: 714 / 1288;
    container-type: inline-size;
    filter: drop-shadow(0 1.4rem 2rem rgb(62 50 34 / 22%));
    transform: translate(-50%, -50%);
  }

  .mobile-curtain__paper {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    max-width: none;
    object-fit: contain;
    mix-blend-mode: multiply;
  }

  /* Centre the copy overlay on the portrait card. */
  .mobile-curtain__card .invitation-card__copy {
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 2;
    width: 78%;
    text-align: center;
    transform: translate(-50%, -50%);
  }

  /* Two full-height flaps, each just over half the width so they overlap at the
     centre seam (hidden under the seal). */
  .mobile-flap {
    position: absolute;
    top: 0;
    z-index: 2;
    width: 52vw;
    height: 100%;
    max-width: none;
    object-fit: cover;
    transition: transform 900ms var(--ease-paper);
    will-change: transform;
  }

  .mobile-flap--left {
    left: 0;
    filter: drop-shadow(2px 0 10px rgb(42 36 24 / 20%));
  }

  .mobile-flap--right {
    right: 0;
    transform: scaleX(-1);
    filter: drop-shadow(-2px 0 10px rgb(42 36 24 / 20%));
  }

  /* Slide the flaps off their respective edges once opened. */
  .mobile-curtain.is-open .mobile-flap--left {
    transform: translateX(-101%);
  }

  .mobile-curtain.is-open .mobile-flap--right {
    transform: scaleX(-1) translateX(-101%);
  }

  /* Seal sits centred over the seam, on top of both flaps. */
  .mobile-seal {
    position: absolute;
    z-index: 3;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }

  .mobile-seal .seal-button__image {
    width: clamp(5rem, 22vw, 7.5rem);
  }
}
