/* Invitation page (index.html): backdrop, envelope intro, the card, and the page it lands on.
   Shared tokens and fonts live in base.css. */

:root {
  /* Envelope paper */
  --env-back-1: #B6A8BE;
  --env-back-2: #CBBFD2;
  --env-side-1: #DFD6E4;
  --env-side-2: #D1C6D8;
  --env-bottom-1: #E9E2ED;
  --env-bottom-2: #DCD2E2;
  --env-flap-1: #EEE8F0;
  --env-flap-2: #DDD4E3;
  --liner-1: #F7EEF3;
  --liner-2: #EAD9E5;
  --liner-dot: #D2B9CB;

  /* One size for the card everywhere: inside the envelope it is only scaled down, so it
     lands at exactly 1× in its slot. svh keeps it steady while the mobile URL bar moves. */
  --card-w: max(240px, min(92vw, 440px, calc((100vh - 210px) * 0.714)));
  --card-h: calc(var(--card-w) * 1600 / 1143);        /* the printed card is 1143 × 1600 */
  --env-w: min(88vw, 420px);
  --env-h: calc(var(--env-w) / 1.4);
  --seal: calc(var(--env-w) * 0.24);
}
@supports (height: 100svh) {
  :root { --card-w: max(240px, min(92vw, 440px, calc((100svh - 210px) * 0.714))); }
}

html { scrollbar-gutter: stable; }
body {
  font: 500 1.1875rem/1.55 var(--font-serif);
  -webkit-tap-highlight-color: transparent;
}
.amp { font-family: var(--font-script); color: var(--lilac); }


/* =========================================================
   Backdrop: soft light, paper grain, line-art sprigs
   ========================================================= */
.backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  background:
    url("../images/paper-grain.svg"),
    radial-gradient(120% 65% at 50% -8%, #FFFFFF 0%, rgba(255, 255, 255, 0) 62%),
    radial-gradient(70% 45% at 100% 100%, rgba(241, 220, 229, 0.75), transparent 70%),
    radial-gradient(65% 40% at 0% 80%, rgba(220, 211, 225, 0.8), transparent 70%),
    var(--bg);
}
.sprig {
  position: absolute;
  width: min(28vw, 230px);           /* narrow enough that the two top sprigs never meet */
  height: auto;
  opacity: 0.6;
}
/* The sprig grows from its bottom-left corner; turn it (and mirror it) so it grows out of the
   two top corners, framing the names. The lower corners belong to the envelope's florals. */
.sprig-tl { left: -6%; top: -4%; transform: rotate(90deg); }
.sprig-tr { right: -6%; top: -4%; transform: scaleX(-1) rotate(90deg); }


/* =========================================================
   Envelope intro (only while html.intro-on)
   ========================================================= */
.intro { display: none; }
.intro-on .intro { display: block; }
html.intro-on { overflow: hidden; }

.intro {
  position: fixed;
  inset: 0;
  z-index: 20;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  transition: opacity 250ms linear;
}
.intro.is-opening { overflow: hidden; }     /* the card's path is measured when it starts */
.intro.is-leaving { opacity: 0; }

.intro-inner {
  min-height: 100%;
  display: grid;
  grid-template-areas: "head" "env" "hint";
  justify-items: center;
  align-content: center;
  gap: 28px;
  padding: max(28px, env(safe-area-inset-top)) 16px max(28px, env(safe-area-inset-bottom));
  text-align: center;
}
.intro-head { grid-area: head; }
.intro-head > p { margin: 0; }
.intro-head > .intro-greeting {
  margin-bottom: 6px;
  font-size: 1.375rem;
  font-style: italic;
}
.intro-kicker, .intro-date {
  font: 500 0.8125rem/1.6 var(--font-sans);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  text-wrap: balance;
  color: var(--ink-muted);
}
.intro-head > .intro-names {
  margin-top: 2px;
  font: 400 clamp(3.25rem, 15vw, 4.75rem)/1.15 var(--font-script);
  color: var(--ink);
}
.intro-names .amp { font-size: 0.8em; padding: 0 0.06em; }

.intro-hint {
  grid-area: hint;
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 1.1875rem;
  font-style: italic;
  color: var(--ink-muted);
}
.intro-hint::before, .intro-hint::after {
  content: "";
  width: 28px;
  height: 1px;
  background: var(--lilac);
}
.intro-head, .intro-hint { transition: opacity 400ms var(--ease-out), transform 400ms var(--ease-out); }
.intro.is-opening .intro-head { opacity: 0; transform: translateY(-12px); }
.intro.is-opening .intro-hint { opacity: 0; transform: translateY(8px); }

/* Arrival, while the sprigs grow (their animation lives in sprig.svg): the words rise in, the
   envelope drifts down like a sheet of paper and settles, the card's florals swing in from beyond
   the screen edges, the seal fades in, then the hint appears and the seal starts pulsing.
   Everything eases to rest (no scaling up, no bounce), and it plays once: constant motion
   would compete with the one thing to tap. */
@keyframes rise-in { from { opacity: 0; transform: translateY(14px); } }
@keyframes envelope-in {
  from { opacity: 0; transform: translateY(-22px) rotate(-2.5deg); }
  45% { opacity: 1; }
  to { opacity: 1; transform: none; }
}
@keyframes seal-in { from { opacity: 0; transform: translate(-50%, -50%) scale(1.08); } }
.intro-head > * { animation: rise-in 1000ms var(--ease-out) backwards; }
.intro-head > .intro-kicker { animation-delay: 100ms; }
.intro-head > .intro-names { animation-delay: 250ms; }
.intro-head > .intro-date { animation-delay: 400ms; }
.envelope { animation: envelope-in 1400ms cubic-bezier(0.22, 0.61, 0.36, 1) 300ms backwards; }
.seal { animation: seal-in 800ms var(--ease-out) 1300ms backwards; }
.intro-hint { animation: rise-in 700ms var(--ease-out) 1800ms backwards; }
/* Tapped before the arrival finished: jump to the end so the card's path is measured from rest */
.intro.is-opening .intro-head > *,
.intro.is-opening .envelope,
.intro.is-opening .env-floral,
.intro.is-opening .seal,
.intro.is-opening .intro-hint { animation: none; }


/* =========================================================
   The envelope. Not a stacking context, so the card can sit
   between the back (z 1) and the pocket (z 3).
   ========================================================= */
.envelope {
  grid-area: env;
  position: relative;
  width: var(--env-w);
  height: var(--env-h);
  cursor: pointer;
  touch-action: manipulation;
}
.env-back,
.env-pocket,
.env-flap {
  transition: transform 650ms var(--ease-in), opacity 650ms var(--ease-in);
}

/* Florals from the printed card (one cluster and its mirror image), tucked under the envelope's
   bottom corners, where a phone has room for them (z -1: behind the envelope and the text).
   Each pivots on its outer bottom corner: it swings in from beyond the screen edge as the
   envelope arrives, and swings back out when the envelope falls away. */
.env-floral {
  position: absolute;
  bottom: -52%;
  z-index: -1;
  width: 48%;
  height: auto;
  opacity: 0.9;
  pointer-events: none;
  animation: 1600ms cubic-bezier(0.25, 0.8, 0.3, 1) 300ms backwards;
  transition: transform 700ms var(--ease-in), opacity 700ms var(--ease-in);
}
.env-floral-left {
  left: -24%;
  transform-origin: 0 100%;
  animation-name: floral-in-left;
}
.env-floral-right {
  right: -24%;
  transform-origin: 100% 100%;
  animation-name: floral-in-right;
}
@keyframes floral-in-left {
  from { opacity: 0; transform: translateX(-45%) rotate(-30deg); }
  70% { transform: rotate(2deg); }
}
@keyframes floral-in-right {
  from { opacity: 0; transform: translateX(45%) rotate(30deg); }
  70% { transform: rotate(-2deg); }
}
.envelope.is-dropping .env-floral { opacity: 0; }
.envelope.is-dropping .env-floral-left { transform: translateX(-45%) rotate(-30deg); }
.envelope.is-dropping .env-floral-right { transform: translateX(45%) rotate(30deg); }
.env-back {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: 8px;
  background:
    radial-gradient(circle, rgba(255, 255, 255, 0.28) 0 1.2px, transparent 1.7px) 0 0 / 12px 12px,
    linear-gradient(180deg, var(--env-back-1), var(--env-back-2));
  box-shadow:
    0 30px 50px -24px rgba(var(--shadow-rgb) / 0.55),
    0 6px 14px -6px rgba(var(--shadow-rgb) / 0.25);
}
.env-pocket {
  position: absolute;
  inset: 0;
  z-index: 3;
  width: 100%;
  height: 100%;
  overflow: visible;
  clip-path: inset(0 round 8px);
  pointer-events: none;
}
.s-side-1 { stop-color: var(--env-side-1); }
.s-side-2 { stop-color: var(--env-side-2); }
.s-bot-1 { stop-color: var(--env-bottom-1); }
.s-bot-2 { stop-color: var(--env-bottom-2); }
.s-flap-1 { stop-color: var(--env-flap-1); }
.s-flap-2 { stop-color: var(--env-flap-2); }
.s-liner-1 { stop-color: var(--liner-1); }
.s-liner-2 { stop-color: var(--liner-2); }
.liner-dot { fill: var(--liner-dot); }

/* Flap: two faces (paper outside, dotted liner inside) that fold back over the top edge */
.env-flap {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 4;
  width: 100%;
  height: 62%;
  perspective: 1100px;
  pointer-events: none;
  transition: z-index 0s linear 530ms, transform 650ms var(--ease-in), opacity 650ms var(--ease-in);
}
.flap-inner {
  position: absolute;
  inset: 0;
  transform-origin: 50% 0;
  transform-style: preserve-3d;
  transition: transform 720ms cubic-bezier(0.5, 0, 0.3, 1) 170ms;
}
.flap-face {
  position: absolute;
  inset: 0;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}
.flap-face svg { display: block; width: 100%; height: 100%; overflow: visible; }
.flap-out svg { clip-path: inset(0 0 -20% 0 round 8px 8px 0 0); }
.flap-in { transform: rotateX(180deg); }

/* Opening: the flap folds back (and drops behind the card halfway through) */
.envelope.is-open .env-flap { z-index: 1; }
.envelope.is-open .flap-inner { transform: rotateX(180deg); }
/* The card is out: the envelope falls away */
.envelope.is-dropping .env-back,
.envelope.is-dropping .env-pocket,
.envelope.is-dropping .env-flap { transform: translateY(80px) scale(0.96); opacity: 0; }


/* =========================================================
   Wax seal: one piece; when tapped it swells a little and lifts off the flap
   ========================================================= */
.seal {
  position: absolute;
  left: 50%;
  top: 56%;
  z-index: 5;
  width: var(--seal);
  height: var(--seal);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  transform: translate(-50%, -50%);
  touch-action: manipulation;
  transition: transform 250ms var(--ease-out);
}
.seal::after {          /* "tap me" ring */
  content: "";
  position: absolute;
  inset: -4%;
  border-radius: 50%;
  border: 2px solid rgba(91, 66, 96, 0.45);
  opacity: 0;
  animation: seal-pulse 2.8s var(--ease-out) 2500ms infinite;   /* starts once the seal is on */
  pointer-events: none;
}
@keyframes seal-pulse {
  0% { transform: scale(0.95); opacity: 0.75; }
  70%, 100% { transform: scale(1.4); opacity: 0; }
}
@media (hover: hover) {
  .envelope:hover .seal { transform: translate(-50%, -50%) scale(1.05); }
}
.seal:active { transform: translate(-50%, -50%) scale(0.95); }
.seal img {
  width: 100%;
  height: 100%;
  filter: drop-shadow(0 3px 4px rgba(40, 24, 44, 0.38));
}
.intro.is-opening .seal { pointer-events: none; }
.intro.is-opening .seal::after { animation: none; opacity: 0; }
.intro.is-opening .seal img { animation: seal-lift 600ms var(--ease-out) forwards; }
@keyframes seal-lift {
  35% { transform: scale(1.1); opacity: 1; }
  100% { transform: translateY(-12%) scale(1.16); opacity: 0; }
}


/* =========================================================
   The card: one element that travels from the envelope to its slot
   ========================================================= */
.card {
  position: relative;
  width: var(--card-w);
  height: var(--card-h);
  outline: none;
}
.card:focus-visible { outline: 2px solid var(--focus); outline-offset: 6px; border-radius: 8px; }
.card.is-traveling {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 2;
  pointer-events: none;
}
.card.is-out { z-index: 6; }

/* Turning is animated by invitation.js in two halves (to edge-on, swap faces, back to flat),
   so only one face is ever shown and nothing depends on backface-visibility. */
.card-flip {
  position: relative;
  width: 100%;
  height: 100%;
  touch-action: manipulation;
}
.card.is-ready .card-flip { cursor: pointer; }
.card-back,
.card.is-turned .card-front { visibility: hidden; }
.card.is-turned .card-back { visibility: visible; }

.card-face {
  position: absolute;
  inset: 0;
  margin: 0;
  overflow: hidden;
  border-radius: 6px;
  background: var(--paper);
  box-shadow:
    0 34px 60px -32px rgba(var(--shadow-rgb) / 0.55),
    0 10px 22px -12px rgba(var(--shadow-rgb) / 0.3),
    0 0 0 1px rgba(var(--shadow-rgb) / 0.06);
}
.card-face picture, .card-face img { width: 100%; height: 100%; }
.card-front img { object-fit: cover; }

/* One soft light sweep across the paper when the card lands */
.card-front::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(110deg, transparent 32%, rgba(255, 255, 255, 0.7) 48%, transparent 64%);
  transform: translateX(-120%);
  pointer-events: none;
}
.card.is-landed .card-front::after { animation: sheen 1400ms var(--ease-out) 120ms both; }
@keyframes sheen { to { transform: translateX(120%); } }

/* Back of the card: the couple photo, like a print with a caption */
.card-back {
  display: flex;
  flex-direction: column;
  padding: 5.5% 5.5% 0;
  text-align: center;
}
.card-back .photo {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  border-radius: 3px;
  background: var(--bg-deep);
}
.card-back .photo img { object-fit: cover; object-position: 50% 36%; }
.photo-names {
  margin: 3% 0 0;
  font: 400 calc(var(--card-w) * 0.1)/1.2 var(--font-script);
  color: var(--ink);
}
.photo-date {
  margin: 0 0 5.5%;
  font: 500 max(11px, calc(var(--card-w) * 0.03))/1.4 var(--font-sans);
  letter-spacing: 0.3em;
  color: var(--ink-muted);
}


/* =========================================================
   The page the card lands on
   ========================================================= */
.page {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: 100vh;
  padding: max(16px, env(safe-area-inset-top)) 16px max(40px, env(safe-area-inset-bottom));
  overflow-x: hidden;               /* the glow behind the card is wider than a phone */
  overflow-x: clip;
}
.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
}
.hero::before {          /* soft glow behind the card */
  content: "";
  position: absolute;
  left: 50%;
  top: calc(var(--card-h) / 2);
  z-index: -1;
  width: calc(var(--card-w) * 2.2);
  height: calc(var(--card-w) * 2.2);
  background: radial-gradient(closest-side, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0));
  transform: translate(-50%, -50%);
  transition: opacity 900ms var(--ease-out);
  pointer-events: none;
}
.intro-on .hero::before { opacity: 0; }
.card-slot {
  width: var(--card-w);
  height: var(--card-h);
}
.intro-on .card-slot > .card { visibility: hidden; }   /* until JS tucks it into the envelope */

/* Everything except the card fades in after it lands, one after another */
.reveal {
  transition:
    opacity 700ms var(--ease-out) var(--d, 0ms),
    transform 700ms var(--ease-out) var(--d, 0ms);
}
.intro-on .reveal { opacity: 0; transform: translateY(16px); visibility: hidden; }
.turn { --d: 80ms; }
.actions { --d: 180ms; }
.details { --d: 300ms; }
.foot { --d: 360ms; }
.no-anim, .no-anim *, .no-anim *::before, .no-anim *::after { transition: none !important; animation: none !important; }

.turn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  margin-top: 14px;
  padding: 0 18px;
  border: 0;
  border-radius: 999px;
  background: none;
  font: italic 500 1.1875rem/1 var(--font-serif);
  color: var(--ink);
  cursor: pointer;
  touch-action: manipulation;
  transition:
    background-color 200ms var(--ease-out),
    opacity 700ms var(--ease-out) var(--d),
    transform 700ms var(--ease-out) var(--d);
}
.turn .icon { width: 20px; height: 20px; color: var(--plum); transition: transform 700ms var(--ease-out); }
.turn.is-turned .icon { transform: rotate(-360deg); }
@media (hover: hover) { .turn:hover { background: rgba(255, 255, 255, 0.7); } }

.actions {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  width: min(100%, 440px);
  margin-top: 10px;
}
.action {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 78px;
  padding: 10px 6px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.75);
  color: var(--ink);
  font: 500 0.875rem/1.25 var(--font-sans);
  letter-spacing: 0.02em;
  text-align: center;
  text-decoration: none;
  touch-action: manipulation;
  transition: border-color 200ms var(--ease-out), background-color 200ms var(--ease-out), transform 150ms var(--ease-out);
}
.action .icon { color: var(--plum); }
@media (hover: hover) { .action:hover { border-color: var(--lilac); background: var(--paper); } }
.action:active { transform: scale(0.97); }

.details {
  width: min(100%, 560px);
  margin-top: 56px;
  text-align: center;
}
.ornament {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  color: var(--lilac);
}
.ornament::before, .ornament::after {
  content: "";
  width: 64px;
  height: 1px;
  background: currentColor;
}
.ornament svg { width: 14px; height: 14px; fill: currentColor; }
.names {
  margin: 18px 0 0;
  font: 400 clamp(2.5rem, 11vw, 3.5rem)/1.15 var(--font-script);
  color: var(--ink);
}
.names > span { display: block; }
.names .amp { font-size: 0.75em; line-height: 1; }
.lede {
  margin: 14px auto 0;
  max-width: 30ch;
  font-size: 1.3125rem;
  font-style: italic;
  line-height: 1.45;
  color: var(--ink-muted);
}
.label {
  display: block;
  font: 500 0.75rem/1.6 var(--font-sans);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.facts {
  display: grid;
  gap: 12px;
  margin: 32px 0 0;
}
.fact {
  padding: 22px 20px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.7);
}
.fact dt { margin-bottom: 6px; }
.fact dd { margin: 0; }
.fact strong { display: block; font-size: 1.375rem; font-weight: 600; line-height: 1.3; }
.families {
  display: grid;
  gap: 14px;
  margin-top: 32px;
}
.families p { margin: 0; }
.foot {
  margin-top: 48px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
}
.sign { margin: 0; font: 400 2rem/1.2 var(--font-script); color: var(--ink); }
.replay {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 16px;
  border: 0;
  border-radius: 999px;
  background: none;
  font: 500 0.875rem/1 var(--font-sans);
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: var(--lilac);
  text-underline-offset: 4px;
}
@media (hover: hover) { .replay:hover { color: var(--ink); } }
.replay .icon { width: 18px; height: 18px; }

@media (min-width: 640px) {
  .facts { grid-template-columns: 1fr 1fr; }
  .families { grid-template-columns: 1fr 1fr; }
}


/* =========================================================
   Petals: one shower after the card lands (created by JS)
   ========================================================= */
.petals {
  position: fixed;
  inset: 0;
  z-index: 30;
  overflow: hidden;
  pointer-events: none;
}
/* Dusty rose, lilac and blush: soft like the card, but deep enough to show on it and the page */
.petal {
  --light: #F3E1E8;
  --deep: #C99AAE;
  position: absolute;
  top: -30px;
  left: var(--x);
  width: var(--size);
  height: calc(var(--size) * 0.8);
  border-radius: 100% 0 100% 0 / 100% 0 100% 0;
  background: linear-gradient(135deg, var(--light), var(--deep));
  box-shadow: 0 1px 3px rgb(var(--shadow-rgb) / 0.18);
  opacity: 0;
  animation: petal-fall var(--fall) cubic-bezier(0.35, 0.1, 0.6, 1) var(--delay) 1 both;
}
.petal:nth-child(3n + 2) { --light: #E8DEEE; --deep: #A894B6; }
.petal:nth-child(3n + 3) { --light: #F7E8EC; --deep: #D8AFBD; }
@keyframes petal-fall {
  0% { opacity: 0; transform: translate3d(0, 0, 0) rotate(0deg); }
  10% { opacity: 0.95; }
  80% { opacity: 0.85; }
  100% { opacity: 0; transform: translate3d(var(--drift), 108vh, 0) rotate(var(--spin)); }
}


/* =========================================================
   Background music toggle (bottom-right, after the envelope)
   ========================================================= */
.music {
  position: fixed;
  right: max(16px, env(safe-area-inset-right));
  bottom: max(16px, env(safe-area-inset-bottom));
  z-index: 25;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.85);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  box-shadow: 0 6px 18px rgb(var(--shadow-rgb) / 0.14);
  color: var(--ink-muted);
  cursor: pointer;
  touch-action: manipulation;
  transition: color 200ms var(--ease-out), border-color 200ms var(--ease-out), transform 150ms var(--ease-out), opacity 400ms var(--ease-out), visibility 0s;
}
.music[hidden] { display: none; }
.music .icon { width: 20px; height: 20px; }
@media (hover: hover) { .music:hover { border-color: var(--lilac); color: var(--plum); } }
.music:active { transform: scale(0.94); }
.intro-on .music { opacity: 0; visibility: hidden; transition-delay: 0s, 0s, 0s, 0s, 400ms; }

/* Muted: a line through the note */
.music::after {
  content: "";
  position: absolute;
  width: 26px;
  height: 1.6px;
  border-radius: 1px;
  background: currentColor;
  transform: rotate(-45deg);
  transition: transform 200ms var(--ease-out);
}
/* Playing: plum note, a slow ring breathing around the button */
.music[aria-pressed="true"] { color: var(--plum); border-color: var(--lilac); }
.music[aria-pressed="true"]::after { transform: rotate(-45deg) scaleX(0); }
.music::before {
  content: "";
  position: absolute;
  inset: -1px;
  border: 1px solid var(--lilac);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
}
.music[aria-pressed="true"]::before { animation: music-ring 2.8s var(--ease-out) infinite; }
@keyframes music-ring {
  0% { opacity: 0.7; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.45); }
}

/* Shown for a few seconds once the music starts, so guests know where to turn it off */
.music-hint {
  position: absolute;
  right: calc(100% + 10px);
  padding: 7px 12px;
  border-radius: 999px;
  background: var(--plum);
  color: var(--paper);
  font: 500 0.8125rem/1.2 var(--font-sans);
  letter-spacing: 0.02em;
  white-space: nowrap;
  opacity: 0;
  transform: translateX(6px);
  pointer-events: none;
  transition: opacity 300ms var(--ease-out), transform 300ms var(--ease-out);
}
.music.show-hint .music-hint { opacity: 1; transform: none; }


/* =========================================================
   Short landscape phones: text beside the envelope
   ========================================================= */
@media (orientation: landscape) and (max-height: 540px) {
  :root { --env-w: min(46vw, 400px, calc((100vh - 110px) * 1.4)); }
  @supports (height: 100svh) {
    :root { --env-w: min(46vw, 400px, calc((100svh - 110px) * 1.4)); }
  }
  .intro-inner {
    grid-template-areas: "head env" "head hint";
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 32px;
    row-gap: 16px;
    align-items: center;
  }
  .env-floral { width: 34%; bottom: -36%; }   /* keep clear of the names beside the envelope */
}


/* Deliberately no prefers-reduced-motion rules: the page looks and moves the same on every phone.
   Many phones switch that setting on to save battery, and opening the envelope is the whole point
   of the page. The motion is short and gentle, and most of it starts from the guest's own tap. */
