/* Kamal & Hanin — sage green, ivory, dusty rose, champagne, antique gold, soft taupe */

:root {
  --bg: #EFE6D9;          /* ivory */
  --bg-lift: #F6F0E6;
  --paper: #F6F0E6;
  --surface: #FBF8F2;     /* form fields and tiles */
  --ink: #453F38;
  --ink-soft: #6E645A;    /* soft taupe, darkened for reading */
  --accent: #6B6F5C;      /* sage green, deepened just enough for small text */
  --accent-deep: #565A49;
  --sage: #7E816E;
  --rose: #C68F88;        /* dusty rose */
  --champagne: #E2C7A6;
  --gold: #B08A58;        /* antique gold, a shade darker for fine lines */
  --line: rgba(69, 63, 56, .14);

  --ar-display: "Aref Ruqaa", "Amiri", serif;
  --ar-text: "Amiri", serif;
  --script: "Pinyon Script", cursive;
  --serif: "Cormorant Garamond", Georgia, serif;

  --W: 360px;             /* envelope width, set by JS */
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1.1875rem;
  line-height: 1.55;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; height: auto; }
p { margin: 0; }
[hidden] { display: none !important; }

#petals {
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  z-index: 50;
}

/* ---------- 1. Scene ---------- */

.scene { position: relative; }
.scene-pin {
  position: relative;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}

.scene-head {
  position: absolute; left: 0; right: 0;
  bottom: calc(50% + var(--W) * .3127 + clamp(4px, 1vh, 10px));
  padding: 0 16px;
  text-align: center;
}
.scene-intro {
  font-weight: 600;
  font-size: clamp(.8125rem, 2.6vw, 1rem);
  text-transform: uppercase;
  letter-spacing: .22em;
  color: var(--accent);
}
.scene-intro-en {
  margin: clamp(2px, 1vh, 10px) 0 0;
  font-family: var(--script);
  font-weight: 400;
  font-size: clamp(2.5rem, min(12.5vw, 9.5vh), 5rem);
  line-height: 1.15;
  color: var(--ink);
}

/* k = screen px per px of the printed invite, so the flowers keep its proportions */
:root { --k: min(calc(100vw / 1429), calc(100svh / 1500)); }
.flora-wrap { position: absolute; pointer-events: none; }
.flora { display: block; width: 100%; height: auto; user-select: none; }
.flora-tl-wrap { left: 0; top: 0; width: calc(var(--k) * 640); }
.flora-tr-wrap { right: 0; top: 0; width: calc(var(--k) * 369); }
.flora-b-wrap {
  left: 50%; bottom: 0;
  width: calc(var(--k) * 1429);
  margin-left: calc(var(--k) * -714.5);
}
/* on wide screens the bottom row is narrower than the window: let its ends fade */
@media (min-aspect-ratio: 1/1) {
  .flora-b-wrap { -webkit-mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent); mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent); }
}

.env {
  position: absolute;
  left: 50%; top: 50%;
  width: var(--W);
  height: calc(var(--W) * .6254);      /* the photographed envelope's proportions */
  margin-left: calc(var(--W) / -2);
  margin-top: calc(var(--W) * -.3127);
  perspective: 1400px;
}

.env-back {
  position: absolute; inset: 0;
  /* the liner: gold, printed with the invite's flowers */
  background: url(../img/flora-b-rose.webp) center top / 100% auto repeat-y, linear-gradient(180deg, #C6A262, #E6CD96);
  border-radius: 3px;
  box-shadow: 0 26px 44px -24px rgba(80, 66, 48, .5), 0 3px 8px rgba(80, 66, 48, .16);
  z-index: 1;
}

.card-clip {
  position: absolute; inset: 0;
  z-index: 2;
  clip-path: inset(-300vh -100vw 0 -100vw);
}
.card-clip.free { clip-path: none; z-index: 6; }

.card {
  position: absolute;
  left: 50%; top: 0;
  width: calc(var(--W) * .88);
  aspect-ratio: 5 / 7;
  margin-left: calc(var(--W) * -.44);
  background:
    radial-gradient(120% 80% at 50% 0%, #fff 0%, transparent 60%),
    var(--paper);
  border-radius: 2px;
  box-shadow: 0 1px 2px rgba(80, 66, 48, .08), 0 24px 40px -24px rgba(80, 66, 48, .35);
  transform-origin: 50% 50%;
}
.card img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }

.env-front {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  z-index: 3;
  filter: drop-shadow(0 -1px 1px rgba(80, 66, 48, .06));
}

.env-flap {
  position: absolute;
  left: 0; top: 0;
  width: 100%;
  height: 71.11%;
  transform-origin: 50% 0;
  transform-style: preserve-3d;
  z-index: 4;
  filter: drop-shadow(0 1px 1.5px rgba(70, 55, 35, .22));
}
.flap-shape {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
}

.seal {
  position: absolute;
  left: 49.17%; top: 61.68%;
  width: calc(var(--W) * .2);
  height: calc(var(--W) * .2);
  margin: calc(var(--W) * -.1) 0 0 calc(var(--W) * -.1);
  padding: 0;
  border: 0;
  background: none;
  z-index: 5;
  border-radius: 50%;
  -webkit-tap-highlight-color: transparent;
}
/* the wax seal is a photographed seal re-cast in dusty rose; two copies make the halves that crack apart */
.seal-half {
  position: absolute; inset: 0;
  background: url(../img/seal-wax.webp) center / contain no-repeat;
  /* a tight contact shadow so the wax sits on the paper, and a softer one for its height */
  filter: drop-shadow(0 1px 1.2px rgba(70, 40, 36, .55)) drop-shadow(0 5px 7px rgba(80, 48, 44, .28));
}
.seal-l { clip-path: polygon(-20% -20%, 55% -20%, 47% 38%, 57% 62%, 48% 120%, -20% 120%); }   /* 1% overlap hides the seam */
.seal-r { clip-path: polygon(54% -20%, 120% -20%, 120% 120%, 47% 120%, 56% 62%, 46% 38%); }

.scroll-hint {
  position: absolute;
  left: 0; right: 0; bottom: calc(var(--k) * 286 + 6px);
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  font-style: italic;
  font-size: 1.0625rem;
  color: var(--ink-soft);
}
.scroll-hint i {
  width: 2px; height: 40px;
  background: repeating-linear-gradient(to bottom, var(--accent) 0 6px, transparent 6px 11px);
  animation: thread-down 1.6s linear infinite;
}
@keyframes thread-down { to { background-position: 0 11px; } }

/* shown once the invitation is fully open: there is more below */
.scroll-more {
  position: absolute; left: 0; right: 0; bottom: max(14px, 2.5vh);
  z-index: 8;
  width: fit-content; margin: 0 auto;
  display: flex; align-items: center; gap: 12px;
  padding: 9px 20px 9px 22px;
  background: rgba(246, 240, 230, .94);
  border: 1px solid var(--gold);
  border-radius: 999px;
  box-shadow: 0 6px 18px -8px rgba(80, 66, 48, .5);
  font-weight: 600; font-size: 1rem;
  text-transform: uppercase; letter-spacing: .14em;
  color: var(--accent);
  opacity: 0; visibility: hidden;
  pointer-events: none;
}
.scroll-more i {
  width: 9px; height: 9px;
  border-right: 2px solid var(--accent); border-bottom: 2px solid var(--accent);
  transform: translateY(-3px) rotate(45deg);
  animation: nudge 1.4s ease-in-out infinite;
}
@keyframes nudge { 50% { transform: translateY(3px) rotate(45deg); } }

/* ---------- 2. Photo ---------- */

.photo {
  padding: clamp(72px, 14vh, 160px) 16px clamp(80px, 15vh, 170px);
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
}
/* the watercolour of the two of them, mounted like a print: paper mat, fine gold rule, soft shadow */
.photo-frame {
  position: relative;
  margin: 0;
  width: min(88vw, 520px);
  aspect-ratio: 900 / 1195;
}
.photo-img {
  position: absolute; inset: 0;
  padding: clamp(8px, 2.4vw, 14px);
  background: #F6F0E4;
  border-radius: 2px;
  box-shadow: 0 1px 2px rgba(80, 66, 48, .14), 0 26px 44px -22px rgba(80, 66, 48, .5);
}
.photo-img::after {
  content: "";
  position: absolute; inset: clamp(4px, 1.2vw, 7px);
  border: 1px solid var(--gold);
  opacity: .75;
  pointer-events: none;
}
.photo-img img { width: 100%; height: 100%; object-fit: cover; }
.photo-line {
  margin-top: 56px;
  font-family: var(--ar-display);
  font-size: clamp(2rem, 7vw, 2.75rem);
  color: var(--accent);
  line-height: 1.3;
}
.photo-line-en { font-style: italic; color: var(--ink-soft); margin-top: 4px; }

/* ---------- 3. Details ---------- */

.details {
  position: relative;
  max-width: 680px;
  margin: 0 auto;
  padding: 4vh 24px clamp(72px, 12vh, 140px);
}
.thread {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  overflow: visible;
}
#threadPath {
  stroke: var(--gold);
  stroke-width: 1.4;
  stroke-linecap: round;
}

.detail {
  position: relative;
  width: min(100%, 460px);
  padding: 0 0 clamp(88px, 16vh, 170px);
  display: grid;
  grid-template-columns: 56px 1fr;
  column-gap: 22px;
  align-content: start;
}
.detail > * { grid-column: 2; }
.detail[data-side="left"]  { margin-right: auto; }
.detail[data-side="right"] { margin-left: auto; text-align: right; grid-template-columns: 1fr 56px; }
.detail[data-side="right"] > * { grid-column: 1; }
.detail .detail-motif { grid-column: 1; grid-row: 1 / span 4; width: 56px; height: 56px; overflow: visible; display: block; }
.detail[data-side="right"] .detail-motif { grid-column: 2; }
.detail h2 {
  margin: 4px 0 6px;
  font-weight: 400;
  font-style: italic;
  font-size: 1.25rem;
  color: var(--ink-soft);
  display: flex; gap: 12px; align-items: baseline;
}
.detail[data-side="right"] h2 { justify-content: flex-end; }
.detail h2 span {
  font-family: var(--ar-display);
  font-style: normal;
  font-size: 1.5rem;
  color: var(--accent);
}
.detail-main {
  font-size: clamp(1.0625rem, 3.9vw, 1.375rem);
  line-height: 1.35;
  font-weight: 600;
  text-transform: uppercase;      /* the invite sets its details in spaced capitals */
  letter-spacing: .14em;
  color: var(--accent);
  text-wrap: balance;
}
.detail-sub { margin-top: 6px; color: var(--ink-soft); }

.countdown { display: flex; gap: 28px; margin-top: 6px; }
.countdown div { display: flex; flex-direction: column; }
.countdown b {
  font-weight: 500;
  font-size: clamp(2.25rem, 9vw, 3rem);
  line-height: 1;
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--accent);
}
.countdown span { font-style: italic; color: var(--ink-soft); font-size: 1rem; }

.actions {
  position: relative;
  display: flex; flex-wrap: wrap; justify-content: center; gap: 14px;
  text-align: center;
}
.btn {
  position: relative;
  appearance: none;
  border: 0;
  background: var(--accent);
  color: var(--bg);
  font: 500 1.0625rem/1 var(--serif);
  letter-spacing: .02em;
  padding: 17px 28px;
  border-radius: 2px;
  cursor: pointer;
  text-decoration: none;
  transition: background .2s;
}
/* the inner rule */
.btn::after {
  content: "";
  position: absolute; inset: 5px;
  border: 1px solid rgba(255, 255, 255, .5);
  border-radius: 1px;
  pointer-events: none;
}
.btn:hover { background: var(--accent-deep); }
.btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.btn-quiet { background: transparent; color: var(--accent); box-shadow: inset 0 0 0 1.5px var(--accent); }
.btn-quiet::after { border-color: rgba(92, 96, 80, .4); }
.btn-quiet:hover { background: rgba(92, 96, 80, .06); }
.pending { font-style: italic; color: var(--ink-soft); max-width: 30ch; }

/* ---------- 4. Close ---------- */

.close {
  padding: 0 0 0;
  text-align: center;
  display: flex; flex-direction: column; align-items: center;
}
.close-band { width: min(100%, 680px); height: 36px; margin-bottom: 56px; overflow: visible; }
.families {
  font-family: var(--ar-text);
  font-size: 1.375rem;
  color: var(--ink-soft);
}
.close-ar {
  margin-top: 28px;
  font-family: var(--ar-display);
  font-size: clamp(1.75rem, 6.5vw, 2.5rem);
  color: var(--accent);
  line-height: 1.4;
}
.close-en { margin-top: 6px; font-style: italic; color: var(--ink-soft); max-width: 32ch; }
.close-sign {
  margin-top: 40px;
  font-size: clamp(1.625rem, 6.4vw, 2.5rem);
  line-height: 1.2;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--accent);
}

/* ---------- Static fallback (reduced motion / no JS animation) ---------- */

.scene.static .scene-pin { height: auto; overflow: visible; padding: 10vh 16px 0; }
.scene.static .scene-intro,
.scene.static .scene-intro-en,
.scene.static .env-back,
.scene.static .env-front,
.scene.static .env-flap,
.scene.static .seal,
.scene.static .flora-wrap,
.scene.static .scroll-more,
.scene.static .scroll-hint { display: none; }
.scene.static .env { position: relative; left: auto; top: auto; margin: 0 auto; width: min(92vw, 460px); height: auto; --W: min(104vw, 522px); }
.scene.static .card-clip { position: relative; clip-path: none; }
.scene.static .card { position: relative; left: auto; margin: 0 auto; width: 100%; }

/* short screens, e.g. a phone held sideways: keep the heading and hint clear of the flowers */
@media (max-height: 560px) {
  .scroll-hint { gap: 4px; font-size: .9375rem; }
  .scroll-hint i { height: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-hint i { animation: none; }
  .scroll-more i { animation: none; }
}

.close > p { padding: 0 16px; }
.flora-foot-wrap { width: min(100%, 1100px); margin-top: 56px; }
.flora-foot { display: block; width: 100%; height: auto; }
@media (min-width: 1100px) {
  .flora-foot-wrap { -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); }
}

/* ---------- RSVP, thank you, guest list ---------- */

.page { min-height: 100svh; display: flex; flex-direction: column; align-items: center; position: relative; overflow-x: hidden; }
.page .flora-wrap { opacity: .55; z-index: 0; }
.sheet {
  position: relative; z-index: 1;
  width: min(100%, 560px);
  padding: clamp(96px, 20svh, 190px) 24px 64px;
  flex: 1;
}
.sheet-wide { width: min(100%, 960px); padding-top: 48px; }
.sheet-thanks { text-align: center; }
.sheet-title {
  margin: 0;
  font-weight: 600;
  font-size: clamp(1.75rem, 7vw, 2.5rem);
  text-transform: uppercase;
  letter-spacing: .14em;
  line-height: 1.2;
  color: var(--accent);
  text-align: center;
}
.sheet-title span {
  display: block;
  font-family: var(--ar-display);
  font-weight: 400;
  letter-spacing: 0;
  font-size: 1.15em;
  line-height: 1.5;
}
.sheet-sub { margin-top: 14px; text-align: center; color: var(--ink-soft); font-style: italic; }
.sheet-sub a, .sheet-back a { color: var(--accent); }
.sheet-back { margin-top: 36px; text-align: center; display: flex; gap: 24px; justify-content: center; flex-wrap: wrap; }
.thanks-line { margin-top: 28px; font-size: clamp(1.375rem, 5vw, 1.75rem); line-height: 1.35; text-wrap: balance; }

.rsvp { margin-top: 44px; display: grid; gap: 34px; }
.field { margin: 0; padding: 0; border: 0; min-width: 0; }
.field label, .field legend, .field .label {
  display: block; padding: 0;
  font-weight: 600;
  font-size: 1.25rem;
  line-height: 1.3;
  color: var(--accent);
}
.hint { margin-top: 2px; font-size: 1rem; font-style: italic; color: var(--ink-soft); }
.rsvp input[type="text"], .rsvp input[type="number"] {
  width: 100%;
  margin-top: 10px;
  padding: 13px 14px;
  font: 500 1.1875rem/1.3 var(--serif);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid rgba(176, 138, 88, .65);
  border-radius: 2px;
  appearance: none;
}
.rsvp input:focus-visible, .rsvp button:focus-visible, .choice:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }

.field .choice {
  display: flex; align-items: center; gap: 14px;
  margin-top: 10px;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid rgba(176, 138, 88, .65);
  border-radius: 2px;
  cursor: pointer;
  font-weight: 500;
  color: var(--ink);
}
.choice input { appearance: none; flex: none; width: 20px; height: 20px; margin: 0; border: 1.5px solid var(--gold); border-radius: 50%; }
.choice input:checked { border-color: var(--accent); background: radial-gradient(circle, var(--accent) 0 5px, transparent 6px); }
.choice:has(input:checked) { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }

#party { display: grid; gap: 34px; }
.stepper { display: flex; gap: 10px; margin-top: 10px; max-width: 220px; }
.rsvp .stepper input { margin-top: 0; text-align: center; font-size: 1.375rem; font-weight: 600; -moz-appearance: textfield; }
.stepper input::-webkit-outer-spin-button, .stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.stepper button, .guest .remove {
  flex: none;
  width: 50px; min-height: 50px;
  font: 600 1.75rem/1 var(--serif);
  color: var(--accent);
  background: var(--surface);
  border: 1px solid rgba(176, 138, 88, .65);
  border-radius: 2px;
  cursor: pointer;
}
.stepper button:disabled { opacity: .35; cursor: default; }
.guest { display: flex; gap: 10px; align-items: stretch; }
.guest .remove { margin-top: 10px; color: var(--ink-soft); }
.add {
  margin-top: 14px;
  padding: 10px 0;
  font: 600 1.125rem/1 var(--serif);
  color: var(--accent);
  background: none; border: 0;
  cursor: pointer;
  text-decoration: underline; text-underline-offset: 4px;
}
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.rsvp .btn { justify-self: center; min-width: 200px; font-size: 1.1875rem; }
.rsvp .btn:disabled { opacity: .6; }
.form-error { padding: 12px 14px; border: 1px solid var(--accent); background: var(--surface); color: var(--accent); font-weight: 600; }

/* guest list */
.tally { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 40px 0 0; text-align: center; }
.tally div { padding: 18px 8px 16px; border: 1px solid rgba(176, 138, 88, .65); background: var(--surface); }
.tally dd { margin: 0; font-weight: 500; font-size: clamp(2.25rem, 9vw, 3.5rem); line-height: 1; color: var(--accent); font-variant-numeric: lining-nums; }
.tally dt { margin-top: 8px; font-style: italic; color: var(--ink-soft); font-size: 1rem; line-height: 1.25; }
.tally div:first-child { background: var(--accent); border-color: var(--accent); }
.tally div:first-child dd, .tally div:first-child dt { color: var(--bg); }
.list-head {
  margin: 48px 0 0; padding-bottom: 10px;
  font-weight: 600; font-size: 1.125rem;
  text-transform: uppercase; letter-spacing: .14em;
  color: var(--accent);
  border-bottom: 1px solid var(--gold);
}
.replies { list-style: none; margin: 0; padding: 0; }
.reply { display: flex; align-items: flex-start; gap: 16px; padding: 16px 4px; border-bottom: 1px solid var(--line); }
.reply-count {
  flex: none;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border: 1.5px solid var(--gold); border-radius: 50%;
  font-weight: 600; font-size: 1.25rem; line-height: 1;
  color: var(--accent);
  font-variant-numeric: lining-nums;
}
.reply-body { flex: 1; min-width: 0; }
.reply-name { font-weight: 600; font-size: 1.3125rem; line-height: 1.25; overflow-wrap: anywhere; }
.reply-with { margin-top: 2px; color: var(--ink-soft); overflow-wrap: anywhere; }
.reply-when { flex: none; font-style: italic; font-size: 1rem; color: var(--ink-soft); white-space: nowrap; padding-top: 3px; }
.reply.is-new { background: rgba(176, 138, 88, .14); }
.reply.is-new .reply-when { color: var(--accent); font-weight: 600; font-style: normal; }
.replies-quiet .reply-name { font-weight: 500; font-size: 1.1875rem; }
.list-foot { margin-top: 20px; text-align: center; }
@media (max-width: 520px) {
  .reply { flex-wrap: wrap; }
  .reply-when { flex-basis: 100%; padding-left: 60px; margin-top: -8px; }
  .replies-quiet .reply-when { padding-left: 0; }
}

.guestlist .sheet-back { align-items: center; gap: 14px; }
.guestlist .list-links { margin-top: 18px; }

/* the guest list on paper: black on white, no decoration, nothing cut across pages */
@media print {
  .guestlist ~ *, .page .flora-wrap, .guestlist .sheet-back, .guestlist .list-foot { display: none !important; }
  body.page { background: var(--surface); color: #000; display: block; min-height: 0; }
  .guestlist { width: 100%; padding: 0; }
  .guestlist * { color: #000 !important; }
  .guestlist .sheet-title { font-size: 20pt; }
  .tally { margin-top: 14pt; }
  .tally div, .tally div:first-child { background: var(--surface); border: 1px solid #000; padding: 8pt; }
  .tally dd { font-size: 22pt; }
  .list-head { margin-top: 18pt; border-color: #000; break-after: avoid; }
  .reply { padding: 7pt 2pt; border-color: #999; break-inside: avoid; }
  .reply-count { border-color: #000; width: 28pt; height: 28pt; font-size: 12pt; }
  .reply.is-new { background: none; }
}

/* RSVP, calendar and directions sit at the very end, under the sign-off */
.close .actions { margin-top: 44px; padding: 0 16px; }

/* the head count sits centred: question, hint and the − 3 + row */
.field:has(.stepper) { text-align: center; }
.stepper { margin-left: auto; margin-right: auto; }

/* ---------- Arrival ----------
   One sequence when the page opens: the flowers draw in from their corners, the
   heading is written, the envelope rises into place, the seal is pressed on,
   and only then the hint. Pure CSS so it starts with the first paint; each step
   only fills backwards, so the scroll animation owns everything afterwards. */
@property --draw { syntax: '<percentage>'; inherits: false; initial-value: 100%; }
@media (prefers-reduced-motion: no-preference) {
  .scene.arrive:not(.static) .flora {
    -webkit-mask-image: radial-gradient(ellipse farthest-corner at var(--at, 50% 50%), #000 var(--draw), transparent calc(var(--draw) + 24%));
            mask-image: radial-gradient(ellipse farthest-corner at var(--at, 50% 50%), #000 var(--draw), transparent calc(var(--draw) + 24%));
    animation: draw-in 2.8s ease-in-out backwards;
  }
  .scene.arrive:not(.static) .flora-tl { --at: 0% 0%; animation-delay: 0s; }
  .scene.arrive:not(.static) .flora-tr { --at: 100% 0%; animation-delay: .25s; }
  .scene.arrive:not(.static) .flora-b  { --at: 50% 100%; animation-delay: .5s; }

  .scene.arrive:not(.static) .scene-intro { animation: rise-in .9s ease-out .15s backwards; }
  .scene.arrive:not(.static) .scene-intro-en { animation: write-in 1.5s cubic-bezier(.45, 0, .25, 1) .4s backwards; }
  .scene.arrive:not(.static) .env { animation: land 1.1s cubic-bezier(.2, .7, .2, 1) .9s backwards; }
  .scene.arrive:not(.static) .seal { animation: press .55s cubic-bezier(.2, 1.5, .4, 1) 1.9s backwards; }
  .scene.arrive:not(.static) .scroll-hint { animation: rise-in .9s ease-out 2.6s backwards; }
}
@keyframes draw-in { from { --draw: -24%; } to { --draw: 100%; } }
/* these fade with filter, not opacity: the scroll animation reads each element's opacity when it starts */
@keyframes rise-in { from { filter: opacity(0); translate: 0 14px; } to { filter: opacity(1); translate: 0 0; } }
/* the names appear left to right, as if being written */
@keyframes write-in {
  from { clip-path: inset(-25% 100% -25% -6%); filter: opacity(.2); }
  to   { clip-path: inset(-25% -6% -25% -6%); filter: opacity(1); }
}
/* the envelope rises into place from just below, straight and without crossing the heading */
@keyframes land {
  from { opacity: 0; translate: 0 44px; scale: .96; }
  to   { opacity: 1; translate: 0 0; scale: 1; }
}
/* the seal comes down onto the flap */
@keyframes press {
  from { opacity: 0; scale: 1.8; }
  to   { opacity: 1; scale: 1; }
}

/* ---------- Loading ----------
   A short curtain while fonts and pictures arrive: the wax seal, a gold ring
   drawing round it, their names. It lifts by script when the page is ready,
   and by itself after 7 seconds if the script never runs. */
.loader {
  position: fixed; inset: 0; z-index: 100;
  display: grid; place-content: center; justify-items: center; gap: 18px;
  background: var(--bg);
  transition: opacity .7s ease, visibility 0s linear .7s;
  animation: loader-timeout .7s ease 7s forwards;
}
.loader.done { opacity: 0; visibility: hidden; pointer-events: none; }
.loader-mark { position: relative; width: 128px; height: 128px; }
.loader-mark svg { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.loader-ring {
  fill: none; stroke: var(--gold); stroke-width: 1.4; stroke-linecap: round;
  stroke-dasharray: 339.3; stroke-dashoffset: 339.3;
  animation: loader-ring 1.3s ease-in-out forwards;      /* drawn once; the hand-over starts when it closes */
}
.loader-mark img { position: absolute; inset: 20px; width: 88px; height: 88px; animation: loader-pulse 1.7s ease-in-out infinite; }
.loader-names { font-family: var(--script); font-size: 2rem; line-height: 1.2; color: var(--ink); }
@keyframes loader-ring { from { stroke-dashoffset: 339.3; } to { stroke-dashoffset: 0; } }
@keyframes loader-pulse { 50% { scale: .93; } }
@keyframes loader-timeout { to { opacity: 0; visibility: hidden; } }
@media (prefers-reduced-motion: reduce) { .loader { display: none; } }

/* the hand-over: the curtain turns clear, its seal and names fly to their places,
   and the envelope grows in around the seal */
.loader.handoff { background-color: transparent; pointer-events: none; transition: background-color .9s ease, opacity .5s ease, visibility 0s linear .5s; animation: none; }
.loader.handoff .loader-ring { animation: none; stroke-dashoffset: 0; opacity: 0; transition: opacity .35s ease; }
.loader.handoff .loader-mark img { animation: none; }
.loader-mark img { filter: drop-shadow(0 4px 6px rgba(80, 48, 44, .42)); }

.env { transform-origin: 49.17% 61.68%; }      /* the seal's spot, so the envelope grows from under it */
.scene.arrive.from-loader:not(.static) .env { animation: grow-around 1.05s cubic-bezier(.3, .7, .2, 1) backwards; }
.scene.arrive.from-loader:not(.static) .seal,
.scene.arrive.from-loader:not(.static) .scene-intro-en { animation: none; }
.scene.from-loader:not(.landed) .seal { opacity: 0; }
.scene.from-loader:not(.landed) .scene-intro-en { filter: opacity(0); }
.scene.arrive.from-loader:not(.static) .scene-intro { animation-delay: .7s; }
.scene.arrive.from-loader:not(.static) .scroll-hint { animation-delay: 1.5s; }
@keyframes grow-around { from { opacity: 0; scale: .5; } to { opacity: 1; scale: 1; } }

/* the QR page */
.sheet-qr { padding-top: clamp(72px, 14svh, 150px); }
.qr-names { margin: 6px 0 0; font-family: var(--script); font-weight: 400; font-size: clamp(2.5rem, 11vw, 4rem); line-height: 1.15; color: var(--ink); }
.qr-code {
  display: block;
  width: min(72vw, 300px);
  margin: 28px auto 0;
  padding: 10px;
  background: var(--surface);
  border: 1px solid var(--gold);
  box-shadow: 0 22px 40px -22px rgba(80, 66, 48, .5);
}
.qr-code img { width: 100%; height: auto; }
.qr-code:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

.sheet-back a.btn:not(.btn-quiet) { color: var(--bg); text-decoration: none; }
