/* =====================================================================
   Wedding invitation — styles
   Colours come from the dress code + the celadon watercolour.
   ===================================================================== */

/* ---------- Fonts (self-hosted, SIL Open Font License) ----------
   English titles & names: Herr Von Muellerhoff (signature script)
   English text: Ovo · buttons: Century Gothic / Didact Gothic
   Chinese: the phone's own system font — no download needed */
@font-face { font-family: "Signature"; src: url(../assets/fonts/signature-latin.woff2) format("woff2");
  font-display: swap; }
@font-face { font-family: "Corinthia"; src: url(../assets/fonts/corinthia-latin.woff2) format("woff2");
  font-display: swap; }
@font-face { font-family: "Ovo"; src: url(../assets/fonts/ovo-latin.woff2) format("woff2");
  font-display: swap; }
/* Buttons: Century Gothic if the device has it (it's a paid font, so we can't
   ship it), otherwise the free look-alike Didact Gothic, served from our server */
@font-face { font-family: "Gothic";
  src: local("Century Gothic"), local("CenturyGothic"), url(../assets/fonts/gothic-latin.woff2) format("woff2");
  font-display: swap; }

:root {
  --ink: #1F2421;
  --grey: #5E625F;
  --celadon: #A9C4A6;
  --bamboo: #C6A77A;
  --gold: #B8975A;
  --gold-deep: #8E6A2C;
  --paper: #F5F1E8;
  --white: #FDFCF8;

  --zh: "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Source Han Sans SC", "Microsoft YaHei", sans-serif;
  --text: "Ovo", var(--zh);              /* invite text: Ovo for English, system font for Chinese */
  --script: "Signature", "Snell Roundhand", cursive;    /* guest's name on the envelope */
  --title: "Corinthia", "Snell Roundhand", cursive;    /* cursive titles */
  --button: "Gothic", var(--zh);         /* button text */

  /* Phone safe areas (iPhone notch / home bar) */
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);

  /* Subtle paper grain, drawn by the browser (no image download) */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .35 0 0 0 0 .32 0 0 0 0 .25 0 0 0 .07 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");

  /* Metallic gold paper (envelope lining): fine shimmer + soft light band */
  --metal-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='.55'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23m)'/%3E%3C/svg%3E");
  --metal-gold: linear-gradient(118deg, #7E5E2C 0%, #A9833F 18%, #D2B26E 34%, #FFF0C4 45%, #D9BA78 53%, #A98340 70%, #8A6830 86%, #B08B48 100%);

  /* Set by app.js once layout is measured */
  --ew: 300px;   /* envelope width  */
  --eh: 399px;   /* envelope height */
  --ex: 0px;
  --ey: 0px;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; overflow: hidden; }
body {
  margin: 0;
  font-family: var(--text); font-weight: 400;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  -webkit-user-select: none; user-select: none;
}
button { font: inherit; color: inherit; cursor: pointer; }
[hidden] { display: none !important; }

/* ---------- Background: paper + watercolour ---------- */
#paper { position: fixed; inset: 0; background: var(--paper) var(--grain); }
#paper::after {                         /* the finished watercolour, shown after the reveal */
  content: ""; position: absolute; inset: 0;
  background: var(--wash-img) center / cover no-repeat;
  opacity: 0;
}
#paper.washed::after { opacity: 1; }
#wash { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; }

/* ---------- Shared bits ---------- */
.rule { display: block; width: 44px; height: 1px; margin: 22px auto; background: var(--gold); opacity: .7; }

.btn {
  min-width: 118px; height: 46px; padding: 0 22px;
  border: 1px solid var(--gold); border-radius: 999px;
  background: rgba(255, 255, 255, .45);
  font-family: var(--button); font-size: 15px; font-weight: 400; letter-spacing: .08em; color: var(--ink);
  transition: background .3s, color .3s, transform .2s;
}
.btn:active { transform: scale(.97); background: var(--gold); color: #fff; }
.btn.solid { background: var(--gold); color: #fff; }
.btn.solid:active { background: var(--gold-deep); }

.btn.lang-zh { font-family: var(--zh); font-size: 16px; letter-spacing: .3em; padding-left: 28px; }
.btn.lang-en { letter-spacing: .1em; }
.hint { margin: 6px 0; font-size: 13px; letter-spacing: .06em; color: var(--grey); }

/* =====================================================================
   Screen 2: the envelope.
   app.js adds classes to #scene in order (s-env, s-label, s-name …);
   each class below describes what changes at that moment.
   ===================================================================== */
#scene { position: fixed; inset: 0; z-index: 10; pointer-events: none; }
#scene.instant, #scene.instant * { transition: none !important; animation: none !important; }

.envelope {
  position: absolute; left: var(--ex); top: var(--ey); width: var(--ew); height: var(--eh);
  perspective: 1600px;
  opacity: 0; transform: translateY(26px) rotate(-1.5deg) scale(.97);
  transition: opacity 1.5s ease, transform 1.8s cubic-bezier(.2, .7, .2, 1);
}
.s-env .envelope { opacity: 1; transform: rotate(-1.5deg); }   /* lies slightly askew, like on a table */
.s-flip .envelope { transform: none; }

.flipper { position: absolute; inset: 0; transform-style: preserve-3d; -webkit-transform-style: preserve-3d; }
.s-flip .flipper { animation: flip 1.6s cubic-bezier(.6, 0, .3, 1) forwards; }
@keyframes flip {
  0%   { transform: rotateY(0); }
  50%  { transform: rotateY(90deg) scale(1.05); }
  100% { transform: rotateY(180deg); }
}
/* After the flip we swap to a flat, non-3D back so the flap can open cleanly */
.s-flat .flipper { animation: none; transform: none; }
.s-flat .front { display: none; }
/* Halfway through the turn (envelope edge-on) the front is switched off and the back on.
   Some phones (WeChat on iPhone) ignore "backface-visibility", which made the stamps
   show through mirrored; switching visibility directly is reliable everywhere. */
.back { visibility: hidden; }
.s-half .back { visibility: visible; }
.s-half .front, .s-half .front * { visibility: hidden; }
/* iPhone: keep everything on the envelope front hidden while it faces away during the flip
   (without this, the stamps can flicker through) */
.front > *, .stamps img { -webkit-backface-visibility: hidden; backface-visibility: hidden; }
.front { transform: translateZ(1px); }
.s-flat .back { transform: none; }

.face {
  position: absolute; inset: 0; border-radius: 2px;
  -webkit-backface-visibility: hidden; backface-visibility: hidden;
}
/* Layered shadow: contact shadow + soft lift, like paper resting on a surface */
.front, .back {
  box-shadow:
    0 0 0 .5px rgba(120, 110, 90, .18),
    0 1px 1px rgba(31, 36, 33, .08),
    0 6px 12px -4px rgba(31, 36, 33, .16),
    0 26px 44px -20px rgba(31, 36, 33, .45);
}

/* ----- Front: warm cotton paper with a soft fall of light ----- */
.front {
  background-color: #FAF7F0;
  background-image:
    linear-gradient(128deg, rgba(255, 255, 255, .75) 0%, rgba(255, 255, 255, 0) 45%, rgba(90, 80, 60, .05) 100%),
    var(--grain);
}
.front::after {                         /* faint ridge where the flap is folded behind */
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px; border-radius: 2px 2px 0 0;
  background: linear-gradient(rgba(90, 80, 60, .07), rgba(90, 80, 60, 0));
}

.stamps { position: absolute; right: 4.5%; top: 7%; width: calc(var(--ew) * .3); height: calc(var(--ew) * .22); }
.stamps img { position: absolute; filter: drop-shadow(0 1px 1px rgba(31, 36, 33, .22)); }
.stamp-big   { right: 0; top: 0; width: calc(var(--ew) * .15); height: calc(var(--ew) * .1875); transform: rotate(3.5deg); }
.stamp-small { right: calc(var(--ew) * .135); top: calc(var(--ew) * .05); z-index: 1;
               width: calc(var(--ew) * .1); height: calc(var(--ew) * .125); transform: rotate(-7deg); }

.postmark {
  position: absolute; z-index: 2; width: calc(var(--ew) * .25);
  left: calc(var(--ew) * .585); top: calc(var(--ew) * .035);
  opacity: 0; transform: scale(1.25) rotate(-8deg);
  transition: opacity .35s ease, transform .45s cubic-bezier(.3, 1.4, .6, 1);
}
.s-postmark .postmark { opacity: .85; transform: rotate(-8deg); }

/* "To", name, line and date: centred as a group in the middle of the envelope */
.address { position: absolute; left: 8%; right: 8%; top: 50%; transform: translateY(-50%); text-align: center; }
.to-label {
  margin: 0 0 .4em; font-size: calc(var(--ew) * .032); letter-spacing: .1em; color: var(--grey);
  opacity: 0; transition: opacity 1s ease;
}
.s-label .to-label { opacity: 1; }

.name-wrap { position: relative; display: inline-block; max-width: 100%; }

/* The name: gold ink, revealed left→right by a moving soft-edged mask */
.guest-name {
  display: block; line-height: 1.4; padding: .12em .45em .3em; margin: -.12em -.45em -.3em;
  font-size: var(--name-size, 32px);
  -webkit-mask-image: linear-gradient(90deg, #000 46%, transparent 54%);
          mask-image: linear-gradient(90deg, #000 46%, transparent 54%);
  -webkit-mask-size: 220% 100%; mask-size: 220% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: 100% 0; mask-position: 100% 0;
  filter: drop-shadow(0 .5px .5px rgba(110, 80, 30, .25));
}
.guest-name.script { font-family: var(--script); word-spacing: .3em; }   /* the script font's own spaces are very narrow */
.guest-name.brush  { font-family: var(--zh); font-weight: 300; letter-spacing: .14em; }   /* Chinese names */
.guest-name .ink {
  background: linear-gradient(100deg, #8E6A2C 0%, #C9A55E 22%, #A27A36 42%, #DDBF7C 58%, #9A7232 78%, #C9A55E 100%);
  background-size: 200% 100%;
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
  /* Script letters (J, f, y…) swing outside their box; padding gives the gold room to paint them */
  display: inline-block; padding: .12em .4em .3em; margin: -.12em -.4em -.3em;
}
.s-name .guest-name { animation: write var(--write-dur, 3s) cubic-bezier(.42, .08, .58, .95) forwards; }
@keyframes write {
  from { -webkit-mask-position: 100% 0; mask-position: 100% 0; }
  to   { -webkit-mask-position: 0 0;    mask-position: 0 0; }
}
.s-written .guest-name { -webkit-mask-image: none; mask-image: none; }
.s-written .guest-name .ink { animation: shimmer 7s ease-in-out 1s infinite; }
@keyframes shimmer { 50% { background-position: 100% 0; } }


.address .rule { width: 26%; margin: .7em auto .6em; opacity: 0; transition: opacity 1.2s ease; }
.env-date { margin: 0; font-size: calc(var(--ew) * .03); letter-spacing: .14em; color: var(--grey); opacity: 0; transition: opacity 1.2s ease .6s; }   /* date follows the line */
.s-written .address .rule { opacity: .6; }
.s-written .env-date { opacity: 1; }

/* ----- Back: liner, card, pocket (side + bottom flaps), top flap with wax seal ----- */
.back { transform: rotateY(180deg); background: #E8E4DA; perspective: 1200px; }

/* Metallic gold lining, seen when the flap opens. A band of light glides across it
   as the flap lifts, like light catching foil paper. */
.liner, .flap-in::after {
  background-image: var(--metal-grain), var(--metal-gold);
  background-size: 160px 160px, 260% 100%;
  background-position: 0 0, 100% 0;
  background-blend-mode: overlay, normal;
}
.s-open .liner, .s-open .flap-in::after { animation: foil-shine 3.2s cubic-bezier(.4, 0, .3, 1) .2s forwards; }
@keyframes foil-shine { from { background-position: 0 0, 100% 0; } to { background-position: 0 0, 38% 0; } }
.liner {
  position: absolute; left: 4%; right: 4%; top: 4%; bottom: 0;
  box-shadow: inset 0 2px 4px rgba(60, 40, 10, .25);
}

/* The card lies sideways inside the landscape envelope and turns upright as it comes out.
   Its box is portrait (5 : 7); app.js animates translate → rotate → scale. */
.card {
  position: absolute; z-index: 2;
  width: calc(var(--eh) * .88); height: calc(var(--eh) * .88 * 1.4);
  left: calc(50% - var(--eh) * .44); top: calc(53% - var(--eh) * .616);
  transform: translate(0, 0) rotate(-90deg) scale(1);
  transform-origin: 50% 50%;
  box-shadow: 0 1px 4px rgba(31, 36, 33, .15);
  border-radius: 2px;
}
.card img { display: block; width: 100%; height: 100%; border-radius: 2px; }
.card.settled {                        /* final resting place on screen (positioned by app.js) */
  z-index: 5;
  box-shadow: 0 28px 50px -22px rgba(31, 36, 33, .55), 0 6px 16px rgba(31, 36, 33, .12);
  transition: box-shadow 1s ease;
}

/* Side flaps (left + right), each shaded as if light comes from the top left */
.pocket-shadow { position: absolute; inset: 0; z-index: 3; pointer-events: none;
  filter: drop-shadow(0 -1px 1.5px rgba(60, 55, 45, .22)); }
.pocket-shadow::before, .pocket-shadow::after { content: ""; position: absolute; inset: 0; }
.pocket-shadow::before {
  background: linear-gradient(90deg, #F2EEE6, #FAF7F1 70%), var(--grain);
  background-blend-mode: multiply;
  clip-path: polygon(0 0, 53% 52%, 0 100%); -webkit-clip-path: polygon(0 0, 53% 52%, 0 100%);
}
.pocket-shadow::after {
  background: linear-gradient(270deg, #ECE8DF, #F7F4ED 70%);
  clip-path: polygon(100% 0, 47% 52%, 100% 100%); -webkit-clip-path: polygon(100% 0, 47% 52%, 100% 100%);
}
/* Bottom flap, overlapping the side flaps, with a softly rounded tip */
.pocket { position: absolute; inset: 0; filter: drop-shadow(0 -1.5px 1.5px rgba(60, 55, 45, .18)); }
.pocket::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(0deg, #FCFAF6, #F5F1E9), var(--grain);
  background-blend-mode: multiply;
  clip-path: polygon(0 100%, 45% 50.5%, 47.5% 48.6%, 50% 48%, 52.5% 48.6%, 55% 50.5%, 100% 100%);
  -webkit-clip-path: polygon(0 100%, 45% 50.5%, 47.5% 48.6%, 50% 48%, 52.5% 48.6%, 55% 50.5%, 100% 100%);
}

/* Top flap */
.flap {
  position: absolute; left: 0; right: 0; top: 0; height: 60%; z-index: 4;
  transform-origin: 50% 0;
  transform-style: preserve-3d; -webkit-transform-style: preserve-3d;
  transition: transform 1.3s cubic-bezier(.5, 0, .3, 1);
}
.s-open .flap { transform: rotateX(180deg); }
.s-flapback .flap { z-index: 1; }

.flap-out, .flap-in { position: absolute; inset: 0; -webkit-backface-visibility: hidden; backface-visibility: hidden; }
.flap-out { filter: drop-shadow(0 2px 2px rgba(60, 55, 45, .25)); }
.flap-out::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, #FDFBF7 0%, #F6F2EA 100%), var(--grain);
  background-blend-mode: multiply;
  clip-path: polygon(0 0, 100% 0, 55% 91%, 52.5% 95%, 50% 96%, 47.5% 95%, 45% 91%);
  -webkit-clip-path: polygon(0 0, 100% 0, 55% 91%, 52.5% 95%, 50% 96%, 47.5% 95%, 45% 91%);
}
.flap-in { transform: rotateX(180deg); visibility: hidden; }
.s-flat .flap-in { visibility: visible; }
.flap-in::before, .flap-in::after { content: ""; position: absolute; inset: 0; }
.flap-in::before {
  background: #ECE8DF;
  clip-path: polygon(0 100%, 100% 100%, 55% 9%, 52.5% 5%, 50% 4%, 47.5% 5%, 45% 9%);
  -webkit-clip-path: polygon(0 100%, 100% 100%, 55% 9%, 52.5% 5%, 50% 4%, 47.5% 5%, 45% 9%);
}
.flap-in::after {                      /* gold lining on the inside of the flap */
  clip-path: polygon(5% 97%, 95% 97%, 50% 14%); -webkit-clip-path: polygon(5% 97%, 95% 97%, 50% 14%);
}

/* Gold wax seal (pre-rendered image, so the shading stays smooth) */
.seal {
  position: absolute; left: 50%; top: 96%;
  width: calc(var(--ew) * .19); height: calc(var(--ew) * .19);
  transform: translate(-50%, -52%);
  -webkit-backface-visibility: hidden; backface-visibility: hidden;
  filter: drop-shadow(0 1px 1px rgba(60, 40, 15, .35)) drop-shadow(0 3px 5px rgba(31, 36, 33, .18));
  transition: opacity .7s ease, transform .7s ease;
}
.seal img { display: block; width: 100%; height: 100%; }
.s-seal .seal { opacity: 0; transform: translate(-50%, -52%) scale(1.15); }

/* ---------- Language choice (under the envelope) and buttons (under the card) ---------- */
.lang-choice {                         /* sits just under the envelope (top set by app.js) */
  position: absolute; left: 0; right: 0; top: var(--lang-top, 70%); z-index: 6;
  display: flex; flex-direction: column; align-items: center; gap: 12px; text-align: center;
  opacity: 0; transform: translateY(10px); pointer-events: none;
  transition: opacity 1s ease, transform 1s ease;
}
.lang-choice .row { display: flex; gap: 14px; }
.lang-choice .hint {                    /* soft backing so it reads over the watercolour */
  margin: 0; padding: 5px 14px; border-radius: 999px;
  background: rgba(253, 252, 248, .78); color: var(--ink);
}
.lang-choice .btn, .card-actions .btn:not(.solid) { background: rgba(253, 252, 248, .78); }
.link { border-radius: 999px; }
.s-lang .card-actions .link { background: rgba(253, 252, 248, .6); }
.s-ask .lang-choice { opacity: 1; transform: none; pointer-events: auto; }
.s-lang .lang-choice { opacity: 0; transform: translateY(-6px); pointer-events: none; transition-duration: .5s; }

.card-actions {
  position: absolute; left: 0; right: 0; bottom: calc(var(--safe-b) + 20px); z-index: 6;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  opacity: 0; transform: translateY(10px); pointer-events: none;
  transition: opacity 1s ease, transform 1s ease;
}
.s-done .card-actions { opacity: 1; transform: none; pointer-events: auto; }
.card-actions .btn.main { width: min(300px, 80vw); height: 48px; }
/* "Skip to details": deliberately small, so the album is the obvious choice */
.card-actions .skip-link, .s-lang .card-actions .skip-link,
.card-actions #btn-replay, .s-lang .card-actions #btn-replay { padding: 3px 10px; font-size: 12px; color: #7A7E7A; background: none; }
:lang(zh) .card-actions .btn { letter-spacing: .25em; }
.link { background: none; border: 0; padding: 8px 12px; font-family: var(--button); font-size: 14px; letter-spacing: .04em; color: var(--grey); }

.skip {
  position: absolute; right: 18px; bottom: calc(var(--safe-b) + 18px); z-index: 7;
  background: rgba(253, 252, 248, .6); border: 1px solid rgba(94, 98, 95, .25); border-radius: 999px;
  padding: 6px 16px; font-family: var(--button); font-size: 13px; letter-spacing: .04em; color: var(--grey);
  opacity: 0; pointer-events: none; transition: opacity .8s ease;
}
.skip.show { opacity: 1; pointer-events: auto; }
.s-done .skip { opacity: 0; pointer-events: none; }

/* ---------- Music button ---------- */
.mute {
  position: fixed; z-index: 50; top: calc(var(--safe-t) + 12px); right: 12px;
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid rgba(184, 151, 90, .7); background: rgba(253, 252, 248, .7);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  display: flex; align-items: flex-end; justify-content: center; gap: 3px; padding-bottom: 12px;
}
.mute span { width: 2px; height: 12px; border-radius: 1px; background: var(--gold); transform-origin: bottom;
  animation: eq 1.4s ease-in-out infinite; }
.mute span:nth-child(2) { animation-delay: -.5s; }
.mute span:nth-child(3) { animation-delay: -.9s; }
@keyframes eq { 0%, 100% { transform: scaleY(.35); } 50% { transform: scaleY(1); } }
.mute.muted span { animation: none; transform: scaleY(.17); }
/* Not started yet (the phone is waiting for a tap): a gently pulsing note instead of bars */
.mute .note { display: none; position: absolute; inset: 0; align-items: center; justify-content: center;
  font-style: normal; font-size: 19px; line-height: 1; color: var(--gold); }
.mute.waiting span { display: none; }
.mute.waiting .note { display: flex; }
.mute.waiting { animation: notePulse 1.8s ease-in-out infinite; }
@keyframes notePulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(184, 151, 90, .45); } 60% { box-shadow: 0 0 0 9px rgba(184, 151, 90, 0); } }
.music-hint {
  position: fixed; z-index: 50; top: calc(var(--safe-t) + 19px); right: 58px;
  padding: 4px 11px; border-radius: 999px; background: rgba(253, 252, 248, .85);
  font-family: var(--button); font-size: 12px; letter-spacing: .04em; color: var(--gold-deep); white-space: nowrap;
  opacity: 0; transform: translateX(6px); pointer-events: none; transition: opacity .6s ease, transform .6s ease;
}
.music-hint.show { opacity: 1; transform: none; }
.mute.muted::after {                   /* diagonal strike when muted */
  content: ""; position: absolute; left: 9px; right: 9px; top: 50%; height: 1px;
  background: var(--grey); transform: rotate(-45deg);
}

/* ---------- Small message bubble ---------- */
.toast {
  position: fixed; left: 50%; bottom: calc(var(--safe-b) + 140px); z-index: 60;
  transform: translate(-50%, 10px); opacity: 0; pointer-events: none;
  background: rgba(31, 36, 33, .82); color: #fff; padding: 10px 18px; border-radius: 999px;
  font-family: var(--button); font-size: 13px; letter-spacing: .06em; white-space: nowrap;
  transition: opacity .4s ease, transform .4s ease;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }

/* Helper used to read the phone's safe-area sizes from JavaScript */
#safe-probe { position: fixed; visibility: hidden; pointer-events: none;
  padding: env(safe-area-inset-top, 0px) 0 env(safe-area-inset-bottom, 0px); }


/* =====================================================================
   Stage 2 — details page, Flip gallery, videos, RSVP, overlays
   ===================================================================== */
a.btn { display: inline-flex; align-items: center; justify-content: center; text-decoration: none; }
.btn:disabled { opacity: .6; }
.btn.wide { width: 100%; height: 50px; }
.amp { font-family: var(--text); font-size: .42em; margin: 0 .3em; vertical-align: .45em; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ----- Details page: slides up over the card ----- */
.page {
  position: fixed; inset: 0; z-index: 30; overflow-y: auto; -webkit-overflow-scrolling: touch;
  background: var(--paper) var(--grain);
  transform: translateY(100%); transition: transform .7s cubic-bezier(.3, .7, .2, 1);
}
.page.open { transform: none; }
.page::before {                          /* watercolour wash fading out behind the names */
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 460px; pointer-events: none;
  background: var(--wash-img) center / cover no-repeat; opacity: .38;
  -webkit-mask-image: linear-gradient(#000 30%, transparent); mask-image: linear-gradient(#000 30%, transparent);
}
.page-back {
  position: fixed; z-index: 35; top: calc(var(--safe-t) + 12px); left: 12px;
  height: 38px; padding: 0 16px; border-radius: 999px;
  border: 1px solid rgba(184, 151, 90, .7); background: rgba(253, 252, 248, .8);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  font-family: var(--button); font-size: 13px; letter-spacing: .06em; color: var(--ink);
}
.page-inner {
  position: relative; max-width: 520px; margin: 0 auto; text-align: center;
  padding: calc(var(--safe-t) + 74px) 24px calc(var(--safe-b) + 64px);
}

.page-lang { margin: 0 0 30px; font-family: var(--button); font-size: 12px; color: var(--grey); }
.page-lang button { background: none; border: 0; padding: 4px 6px; font: inherit; color: var(--grey); }
.page-lang button.on { color: var(--ink); text-decoration: underline; text-decoration-color: var(--gold); text-underline-offset: 4px; }
.hero .eyebrow { margin: 0 auto; font-size: min(14px, 3.6vw); line-height: 1.7; letter-spacing: .02em; white-space: nowrap; color: var(--grey); }   /* one line, shrinks on small phones */
.hero-names {
  margin: .2em 0 0; padding: 0 .25em; font-family: var(--title); font-weight: 400;
  font-size: clamp(44px, 13vw, 72px); line-height: 1.15; color: var(--gold); white-space: nowrap;
}
.hero-zh { margin: 22px 0 0; font-family: var(--zh); font-weight: 300; font-size: 17px; letter-spacing: .35em; padding-left: .35em; }
.hero-date { margin: 0; font-size: 16px; letter-spacing: .04em; }

.sec { position: relative; margin-top: 60px; padding-top: 46px; }
.sec::before {                           /* small gold diamond between sections */
  content: ""; position: absolute; top: 0; left: 50%; width: 7px; height: 7px;
  border: 1px solid var(--gold); transform: translateX(-50%) rotate(45deg);
}
.sec-title { margin: 0 0 22px; font-weight: 400; }
.sec-title.en { font-family: var(--title); font-size: 50px; line-height: 1.2; color: var(--gold); padding: 0 .2em; }
.sec-title.zh { font-family: var(--zh); font-size: 20px; letter-spacing: .4em; padding-left: .4em; color: var(--gold-deep); }
.big { margin: 0 0 6px; font-size: 20px; }
.venue { margin: 0 0 10px; font-size: 17px; color: var(--gold-deep); }
.addr {
  margin: 0 auto 22px; max-width: 320px; font-size: 14px; line-height: 1.75; color: var(--grey);
  -webkit-user-select: text; user-select: text;
}
.sec-buttons { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }
.note { margin: 20px 0 0; font-size: 13px; color: var(--grey); }

/* The day: a fine gold timeline */
.timeline { position: relative; list-style: none; margin: 0 auto; padding: 0; max-width: 340px; text-align: left; }
.timeline::before { content: ""; position: absolute; left: 112px; top: 8px; bottom: 8px; width: 1px; background: rgba(184, 151, 90, .5); }
.timeline li { position: relative; display: flex; gap: 30px; padding: 10px 0; }
.timeline li::before {
  content: ""; position: absolute; left: 109px; top: 18px; width: 7px; height: 7px; border-radius: 50%;
  background: var(--paper); border: 1px solid var(--gold);
}
.timeline .time { flex: none; width: 96px; padding-top: 2px; text-align: right; font-size: 14px; line-height: 1.5; color: var(--grey); }
.timeline .what { font-size: 17px; line-height: 1.5; }
.timeline small { display: block; font-size: 13px; color: var(--grey); }
.timeline small.note-line { margin-top: 4px; font-size: 12px; line-height: 1.5; font-style: italic; color: var(--gold-deep); }

/* Dress code swatches */
.swatches { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; list-style: none; margin: 0 auto; padding: 0; max-width: 360px; }
.swatch {
  display: block; width: 54px; height: 54px; margin: 0 auto 10px; border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .06), 0 6px 12px -6px rgba(31, 36, 33, .4);
}
.sw-name { display: block; font-size: 13px; }
.swatches small { display: block; font-size: 11px; color: var(--grey); }

/* Menu tabs */
.tabs { display: inline-flex; margin: 0 0 28px; padding: 3px; border: 1px solid var(--gold); border-radius: 999px; }
.tab { border: 0; background: none; padding: 8px 18px; border-radius: 999px; font-family: var(--button); font-size: 14px; color: var(--grey); }
.tab.on { background: var(--gold); color: #fff; }
.menu { max-width: 380px; margin: 0 auto; }
.course { margin: 0 0 22px; }
.course h4 { margin: 0 0 8px; font-family: var(--button); font-weight: 400; font-size: 12px; letter-spacing: .22em; color: var(--gold); }
.course ul { list-style: none; margin: 0; padding: 0; }
.course li { margin: 0 0 9px; font-size: 16px; line-height: 1.5; }
.course li.or { margin: 2px 0 10px; font-family: var(--title); font-size: 36px; line-height: 1; color: var(--gold); }
:lang(zh) .course li.or { font-family: var(--zh); font-size: 14px; letter-spacing: .3em; }
.course small { display: block; font-size: 12.5px; line-height: 1.5; color: var(--grey); }

/* RSVP */
.deadline { margin: 0 0 16px; font-size: 15px; color: var(--gold-deep); }
.film-link {
  margin: 0 0 30px; padding: 4px 2px; background: none; border: 0; border-bottom: 1px solid var(--gold);
  font-family: var(--button); font-size: 14px; letter-spacing: .04em; color: var(--ink);
}
.rsvp-form { max-width: 380px; margin: 0 auto; text-align: left; }
.field { display: block; margin: 0 0 24px; }
.field > span { display: block; margin: 0 0 8px; font-size: 13px; letter-spacing: .04em; color: var(--grey); }
.field input, .field textarea {
  width: 100%; padding: 8px 2px; border: 0; border-bottom: 1px solid rgba(184, 151, 90, .6); border-radius: 0;
  background: transparent; font: inherit; font-size: 17px; color: var(--ink); -webkit-appearance: none;
  -webkit-user-select: text; user-select: text; resize: none;
}
.field input:focus, .field textarea:focus { outline: none; border-bottom-color: var(--gold); }
.choice { display: flex; gap: 10px; }
.choice button {
  flex: 1; height: 44px; border: 1px solid rgba(184, 151, 90, .6); border-radius: 999px;
  background: rgba(255, 255, 255, .5); font-family: var(--button); font-size: 14px; color: var(--grey);
}
.choice button.on { background: var(--gold); border-color: var(--gold); color: #fff; }
.counts { margin: 0 0 24px; border-top: 1px solid rgba(184, 151, 90, .25); }
.step { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 0; border-bottom: 1px solid rgba(184, 151, 90, .25); }
.step-label { font-size: 15px; line-height: 1.4; }
.step-label small { display: block; margin-top: 2px; font-size: 12px; color: var(--grey); }
.ctrl { display: flex; flex: none; align-items: center; gap: 4px; }
.ctrl button { width: 36px; height: 36px; border: 1px solid var(--gold); border-radius: 50%; background: none; font-size: 18px; line-height: 1; color: var(--gold-deep); }
.ctrl output { width: 30px; text-align: center; font-size: 18px; }
.decline-note {
  margin: -6px 0 26px; text-align: center; font-size: 15px; line-height: 1.75; color: var(--gold-deep);
  font-style: italic; animation: fadeUp .8s ease both;
}
.video-wish {
  margin: -10px 0 26px; padding: 14px 16px; text-align: center; border: 1px solid rgba(184, 151, 90, .35); border-radius: 12px;
  background: rgba(253, 252, 248, .6); animation: fadeUp .8s ease .2s both;
}
.video-wish p { margin: 0 0 6px; font-size: 14px; line-height: 1.75; color: var(--ink); }
.video-wish .link { font-size: 13px; color: var(--gold-deep); text-decoration: underline; text-underline-offset: 3px; }
.meals-head { margin: 22px 0 0; padding: 0 0 8px; font-size: 13px; letter-spacing: .04em; color: var(--grey); border-bottom: 1px solid rgba(184, 151, 90, .25); }
.meals-head small { display: block; margin-top: 2px; font-size: 12px; }
.form-error { display: none; margin: 0 0 14px; font-size: 14px; line-height: 1.6; color: #9A4B3C; }
.form-error.show { display: block; }
.rsvp-done p { margin: 0 0 8px; font-size: 18px; }

.page-foot { margin-top: 72px; }
.page-foot img { width: 64px; height: 64px; }
.page-foot p { margin: 12px 0 0; font-size: 15px; color: var(--grey); }

/* ----- Full-screen layers: gallery, film, thank-you ----- */
.overlay {
  position: fixed; inset: 0; z-index: 40;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: calc(var(--safe-t) + 64px) 16px calc(var(--safe-b) + 36px);
  background: rgba(245, 241, 232, .97); opacity: 0; transition: opacity .6s ease;
}
.overlay.open { opacity: 1; }
.overlay::before { content: ""; position: absolute; inset: 0; pointer-events: none; background: var(--wash-img) center / cover no-repeat; opacity: .18; }
.overlay > * { position: relative; }
.overlay-close {
  position: absolute; z-index: 2; top: calc(var(--safe-t) + 12px); left: 12px;
  height: 38px; padding: 0 16px; border-radius: 999px;
  border: 1px solid rgba(184, 151, 90, .7); background: rgba(253, 252, 248, .85);
  font-family: var(--button); font-size: 13px; letter-spacing: .06em; color: var(--ink);
}

/* Photo album: a cinematic slideshow (built by js/gallery.js) */
.overlay.gallery { display: block; padding: 0; background: var(--paper) var(--grain); }
.slides { position: absolute; inset: 0; overflow: hidden; touch-action: pan-y; }
.slide {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  padding: calc(var(--safe-t) + 60px) 10px calc(var(--safe-b) + 50px);
  opacity: 0; visibility: hidden; transition: opacity 1.3s ease, visibility 0s linear 1.3s;
}
.slide.on { opacity: 1; visibility: visible; transition: opacity 1.3s ease; }
.slide.film .vframe { width: min(100%, 720px); }
.slide.film { flex-direction: column; }
/* Film slide: content starts in the upper part of the screen (not floating mid-screen) */
.slide.film { justify-content: flex-start; padding-top: calc(var(--safe-t) + 70px + 7vh); }
.slide.end  { padding-bottom: calc(var(--safe-b) + 50px + 14vh); }
/* Film titles: English above the film, Chinese below, both in gold, fading in line by line */
.film-title { margin: 0; font-weight: 400; text-align: center; color: var(--gold-deep); }
.film-title.en { margin-bottom: 22px; font-family: var(--text); font-size: clamp(15px, 4.2vw, 19px); line-height: 1.6; letter-spacing: .02em; }
.film-title.zh { margin-top: 22px; font-family: var(--zh); font-size: 16px; line-height: 1.9; letter-spacing: .2em; }
.film-title .line { display: block; opacity: 0; animation: fadeUp 1.8s ease .5s forwards; }
.film-title .line:nth-child(2) { animation-delay: 1.3s; }
.film-title.zh .line { animation-delay: 2.1s; }
.film-title.zh .line:nth-child(2) { animation-delay: 2.9s; }
/* Blurred, faded copy of the photo filling the screen behind it */
.slide .backdrop {
  position: absolute; inset: -40px; background: center / cover no-repeat;
  filter: blur(24px) saturate(.95); opacity: .8; transform: scale(1.1);
}
.slide .backdrop::after { content: ""; position: absolute; inset: 0; background: rgba(245, 241, 232, .22); }
.print {                                 /* the whole photo — never cropped */
  position: relative; margin: 0; max-width: 100%; max-height: 100%; display: flex;
  box-shadow: 0 24px 50px -22px rgba(31, 36, 33, .55), 0 2px 8px rgba(31, 36, 33, .1);
}
.print picture { display: flex; max-width: 100%; max-height: 100%; }
.print img {
  display: block; max-width: 100%; width: auto; height: auto;
  max-height: calc(100vh - var(--safe-t) - var(--safe-b) - 112px);
}
/* Wide photos: trimmed to a tall 2 : 3 frame that fits an upright phone */
.print.crop {
  --h: min(calc(100vh - var(--safe-t) - var(--safe-b) - 112px), calc((100vw - 20px) * 1.5));
  height: var(--h); width: calc(var(--h) / 1.5);
}
.print.crop picture { width: 100%; height: 100%; }
.print.crop img { width: 100%; height: 100%; max-height: none; object-fit: cover; }
.slide.on .print { animation: slowZoom 7s ease-out forwards; }      /* gentle "Ken Burns" drift */
@keyframes slowZoom { from { transform: scale(1); } to { transform: scale(1.045); } }
.end-card { display: flex; flex-direction: column; align-items: center; gap: 14px; text-align: center; }
.end-title { margin: 0 0 8px; font-size: 20px; color: var(--gold-deep); }
:lang(en) .end-title { font-family: var(--title); font-size: 48px; color: var(--gold); }
.quiet-link { font-size: 13px; color: #7A7E7A; }
.progress {                              /* thin gold progress line */
  position: absolute; left: 50%; bottom: calc(var(--safe-b) + 18px); width: min(160px, 40vw); height: 1px;
  transform: translateX(-50%); background: rgba(184, 151, 90, .25);
}
.progress span { display: block; height: 100%; width: 0; background: var(--gold); transition: width 1.2s ease; }
.count {
  position: absolute; left: 0; right: 0; bottom: calc(var(--safe-b) + 26px); text-align: center;
  font-family: var(--text); font-size: 12px; letter-spacing: .12em; color: var(--gold-deep);
  text-shadow: 0 0 8px rgba(253, 252, 248, .9);
}
.arrow {                               /* just a faded gold chevron, no circle */
  position: absolute; top: 50%; z-index: 2; width: 44px; height: 72px; margin-top: -36px; padding: 0;
  border: 0; background: none; font-family: var(--text); font-size: 40px; line-height: 1;
  color: var(--gold); opacity: .75; transition: opacity .4s;
  text-shadow: 0 0 10px rgba(253, 252, 248, .9), 0 0 3px rgba(253, 252, 248, .9);
}
.arrow:active { opacity: .9; }
.arrow.prev { left: 2px; } .arrow.next { right: 2px; }
.arrow.hide { opacity: 0; pointer-events: none; }
.dot { width: 6px; height: 6px; border-radius: 50%; background: rgba(184, 151, 90, .35); transition: background .4s; }
.dot.film { width: 14px; border-radius: 3px; }
.dot.on { background: var(--gold); }

/* Video: landscape frame, poster, round play button */
.vframe {
  position: relative; width: 100%; overflow: hidden; border-radius: 3px; background: #1F2421;
  box-shadow: 0 14px 30px -14px rgba(31, 36, 33, .55);
}
.vframe::before { content: ""; display: block; padding-top: 56.25%; }   /* 16 : 9 */
.vframe video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: #000; }
.vposter { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: #000; pointer-events: none; transition: opacity .5s ease; }
.vframe.playing .vposter { opacity: 0; }
.vplay {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: flex; align-items: center; justify-content: center; gap: 10px;
  min-width: 62px; height: 62px; padding: 0 0 0 5px; border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .85); background: rgba(31, 36, 33, .4);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  color: #fff; font-family: var(--button); font-size: 14px; letter-spacing: .04em; white-space: nowrap;
  transition: opacity .4s;
}
.vplay i { display: block; border-style: solid; border-width: 11px 0 11px 17px; border-color: transparent transparent transparent #fff; }
.vplay.labeled { height: 46px; padding: 0 20px 0 18px; }
.vplay.labeled i { border-width: 8px 0 8px 12px; }
.vframe.playing .vplay { opacity: 0; pointer-events: none; }

.film-box, .thanks-box { width: min(92vw, 720px); text-align: center; }
.thanks-msg { margin: 0 0 26px; font-size: 20px; opacity: 0; animation: fadeUp 1.2s ease .3s forwards; }
.thanks-film { opacity: 0; animation: fadeUp 1s ease 1.6s forwards; }
.see-you { margin: 30px 0 0; opacity: 0; transition: opacity 1.8s ease; }
.see-you.en { font-family: var(--title); font-size: 60px; line-height: 1.2; color: var(--gold); }
.see-you.zh { font-family: var(--zh); font-size: 26px; letter-spacing: .3em; padding-left: .3em; color: var(--gold-deep); }
.thanks.ended .see-you { opacity: 1; }
