/* ============================================================
   婚礼请帖 · 韩系白（纯白极简高级）
   纯白底 × 墨色衬线 × 香槟金细线 × 淡金羽毛
   ============================================================ */
:root {
  --bg: #F4F2EE;          /* 页外底色 */
  --panel: #FFFFFF;       /* 主页面：纯白 */
  --card: #FFFFFF;        /* 卡片 */
  --card-2: #FDFCF9;      /* 卡片暗面（极微差） */
  --ink: #1C1A17;         /* 墨色主文字 */
  --mut: #9A948B;         /* 弱化文字 */
  --gold: #B49B6B;        /* 香槟金点缀 */
  --gold-l: #C9B384;      /* 亮香槟 */
  --gold-d: #A89467;      /* 深香槟 */
  --line: #ECE8E1;        /* 分隔线 */

  --serif: 'Palatino', 'Palatino Linotype', 'Book Antiqua', Georgia,
           'Songti SC', 'STSong', 'Noto Serif SC', serif;
  --script: 'Snell Roundhand', 'Savoye LET', 'Brush Script MT',
            'Apple Chancery', 'Lucida Handwriting', cursive;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

/* 桌面端滚动条也走站点色系 */
::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #DAD5CC; border-radius: 999px; border: 3px solid #F4F2EE; }

body {
  font-family: var(--serif);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  color: var(--ink);
  background: var(--bg);
  background-image:
    radial-gradient(600px 500px at 8% 6%, rgba(180, 155, 107, .05), transparent 70%),
    radial-gradient(700px 560px at 94% 22%, rgba(180, 155, 107, .04), transparent 70%),
    radial-gradient(640px 520px at 12% 88%, rgba(175, 170, 160, .06), transparent 70%),
    radial-gradient(700px 560px at 92% 96%, rgba(180, 155, 107, .05), transparent 70%);
  background-attachment: fixed;
  min-height: 100vh;
}

body.locked { overflow: hidden; }

::selection { background: #E7DCC4; color: #2A2724; }

.hidden { display: none !important; }

/* ---------- 主容器：桌面居中呈手机比例 ---------- */
#page {
  position: relative;
  max-width: 520px;
  margin: 0 auto;
  background: linear-gradient(180deg, #FFFFFF 0%, #FEFDFB 100%);
  min-height: 100vh;
  box-shadow:
    0 0 0 1px rgba(60, 52, 40, .05),
    0 0 60px rgba(60, 52, 40, .08),
    0 30px 90px rgba(60, 52, 40, .06);
  opacity: 0;
  transform: scale(.97);
}
/* 纸感颗粒：极淡噪点，出「印在纸上」的细腻质感 */
#page::after {
  content: ''; position: absolute; inset: 0; z-index: 30;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='260'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 260px 260px;
  opacity: .04;
  mix-blend-mode: multiply;
}
body.open #page {
  opacity: 1;
  transform: none;
  transition: opacity .9s ease .15s, transform .9s ease .15s;
}

/* ============================================================
   开启封面 veil
   ============================================================ */
#veil {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  background: #FAF8F4;
  text-align: center;
  overflow: hidden;
  transition: opacity .8s ease, transform .8s ease;
}
/* 手机三倍屏高清版本：保留原片细节，同时避免首屏解码 11MB 原图造成卡顿 */
#veil::before {
  content: ''; position: absolute; inset: 0;
  background: url('assets/veil-mobile-hq.jpg') center / cover no-repeat;
  image-rendering: auto;
  animation: veilZoom 18s cubic-bezier(.16,.7,.24,1) forwards;
  will-change: transform;
}
/* 镜头边缘的轻微暗角让文字与信鸽保持清晰，但不压低原片细节 */
#veil::after {
  content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(ellipse at 50% 47%, transparent 36%, rgba(58,39,23,.08) 100%),
    linear-gradient(180deg, rgba(255,248,235,.02), transparent 45%, rgba(64,42,22,.06));
}
@keyframes veilZoom { from { transform: scale(1.005); } to { transform: scale(1.075); } }

/* 原片头纱的动态延伸层：随风轻摆，营造静态照片中纱摆仍在流动的错觉 */
.veil-breeze {
  position: absolute; z-index: 1; left: -18%; right: -18%; bottom: -9%; height: 54%;
  pointer-events: none; opacity: .34;
  background:
    radial-gradient(ellipse at 35% 100%, rgba(255,255,255,.48), transparent 58%),
    linear-gradient(112deg, transparent 12%, rgba(255,255,255,.18) 36%, rgba(255,248,236,.46) 52%, rgba(255,255,255,.08) 70%, transparent 84%);
  clip-path: polygon(0 58%, 19% 39%, 41% 48%, 60% 20%, 78% 46%, 100% 31%, 100% 100%, 0 100%);
  filter: blur(7px);
  mix-blend-mode: screen;
  transform-origin: 52% 100%;
  animation: veilBreathe 5.8s ease-in-out infinite alternate;
}
@keyframes veilBreathe {
  0% { transform: perspective(900px) rotateZ(-1.2deg) rotateX(1deg) translate3d(-1.5%, 1.5%, 0) scaleX(1.01); opacity: .22; }
  48% { transform: perspective(900px) rotateZ(.7deg) rotateX(-1.4deg) translate3d(1.2%, -1%, 0) scaleX(1.035); opacity: .38; }
  100% { transform: perspective(900px) rotateZ(1.4deg) rotateX(.5deg) translate3d(2.3%, .4%, 0) scaleX(.99); opacity: .28; }
}

/* 前景花瓣经过镜头：尺寸与景深各不相同，避免机械式飘落 */
.veil-petals { position: absolute; inset: 0; z-index: 4; overflow: hidden; pointer-events: none; }
.veil-petals i {
  position: absolute; top: -12%; left: var(--x);
  width: var(--w); aspect-ratio: 1.6 / 1; border-radius: 80% 20% 70% 30%;
  background: radial-gradient(ellipse at 32% 30%, #FFFDF9, #F5E9DC 58%, rgba(222,200,178,.72));
  box-shadow: inset 1px 1px 2px rgba(255,255,255,.86), 0 5px 12px rgba(80,52,30,.16);
  filter: blur(var(--blur)); opacity: 0;
  transform-origin: 70% 50%;
  animation: veilPetalFall var(--dur) linear var(--delay) infinite;
}
.veil-petals i:nth-child(1) { --x: 8%;  --w: 13px; --blur: .2px; --dur: 7.8s; --delay: -1.1s; --drift: 62px; }
.veil-petals i:nth-child(2) { --x: 23%; --w: 20px; --blur: .7px; --dur: 9.4s; --delay: -5.6s; --drift: -44px; }
.veil-petals i:nth-child(3) { --x: 39%; --w: 9px;  --blur: 0; --dur: 8.5s; --delay: -3.2s; --drift: 58px; }
.veil-petals i:nth-child(4) { --x: 55%; --w: 25px; --blur: 1.1px; --dur: 10.6s; --delay: -7.7s; --drift: -72px; }
.veil-petals i:nth-child(5) { --x: 69%; --w: 15px; --blur: .3px; --dur: 7.2s; --delay: -4.4s; --drift: 48px; }
.veil-petals i:nth-child(6) { --x: 82%; --w: 11px; --blur: 0; --dur: 9.8s; --delay: -6.3s; --drift: -55px; }
.veil-petals i:nth-child(7) { --x: 94%; --w: 28px; --blur: 1.8px; --dur: 8.9s; --delay: -2.2s; --drift: -86px; }
.veil-petals i:nth-child(8) { --x: 47%; --w: 17px; --blur: .4px; --dur: 11.2s; --delay: -9.4s; --drift: 76px; }
@keyframes veilPetalFall {
  0% { opacity: 0; transform: translate3d(0,-8vh,0) rotateX(0) rotateZ(0); }
  9% { opacity: .86; }
  50% { transform: translate3d(calc(var(--drift) * .45),55vh,0) rotateX(170deg) rotateZ(195deg); }
  92% { opacity: .72; }
  100% { opacity: 0; transform: translate3d(var(--drift),116vh,0) rotateX(350deg) rotateZ(420deg); }
}

.veil-inner { position: relative; z-index: 3; opacity: 0; }
.veil-script, .veil-names, .veil-date, .veil-mail-hint, .veil-music-hint {
  text-shadow: 0 0 2px rgba(255, 255, 255, .95), 0 1px 8px rgba(255, 255, 255, .85), 0 2px 22px rgba(255, 255, 255, .75);
}
#veil.away { opacity: 0; transform: scale(1.06); pointer-events: none; }
.veil-script { font-family: var(--script); font-size: 34px; color: var(--gold-d); }
.veil-names { font-size: 26px; font-weight: 400; letter-spacing: .14em; margin: 8px 0 6px; color: #2A2724; }
.veil-date { font-size: 13px; color: #6E6A62; letter-spacing: .3em; margin-bottom: 8px; }
/* 信封落定后才开始落笔：先描边、再显影，模拟一笔写出 */
#veil.inked .veil-inner { opacity: 1; }
.veil-inner > * { clip-path: inset(0 100% 0 0); opacity: 0; }
#veil.inked .veil-script { animation: veilInk .9s cubic-bezier(.2,.72,.24,1) .05s forwards; }
#veil.inked .veil-names  { animation: veilInk 1.2s cubic-bezier(.2,.72,.24,1) .62s forwards; }
#veil.inked .veil-date   { animation: veilInk .8s cubic-bezier(.2,.72,.24,1) 1.62s forwards; }
.veil-inner::after {
  content: ''; position: absolute; left: 2%; top: 49%; width: 20%; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(169,132,75,.9), transparent);
  opacity: 0; transform: translateX(0) rotate(-2deg);
  filter: drop-shadow(0 0 3px rgba(255,255,255,.9));
}
#veil.inked .veil-inner::after { animation: inkNib 2.1s ease .12s forwards; }
@keyframes veilInk {
  0% { opacity: .18; clip-path: inset(0 100% 0 0); filter: blur(1.2px); }
  45% { opacity: .7; }
  100% { opacity: 1; clip-path: inset(0 0 0 0); filter: blur(0); }
}
@keyframes inkNib {
  0% { opacity: 0; transform: translateX(0) rotate(-2deg); }
  12% { opacity: .78; }
  84% { opacity: .56; transform: translateX(390%) rotate(1deg); }
  100% { opacity: 0; transform: translateX(410%) rotate(1deg); }
}
/* ============ 白鸽送信 ============
   从远景高处出现，绕弧线逐渐飞近，悬停放信后向右上方离场。 */
.dove {
  position: absolute; left: 0; top: 0; z-index: 2;
  width: 220px; height: 220px; margin: -110px 0 0 -110px;
  pointer-events: none;
  opacity: 0; transform-origin: 50% 50%; perspective: 700px;
  animation: doveFly 5.1s linear .35s both;
  will-change: transform, opacity, filter;
}
.dove-bob { position: relative; width: 100%; height: 100%; animation: doveBob .54s ease-in-out infinite; }
.dove-photo-sprite {
  position: absolute; inset: 0;
  filter: drop-shadow(0 4px 4px rgba(45,35,24,.2)) drop-shadow(0 18px 22px rgba(45,35,24,.22));
  will-change: transform;
}
.dove-pose {
  position: absolute; inset: 0; opacity: 0;
  background-image: url('assets/dove-photoreal-sprite-mobile.png');
  background-repeat: no-repeat; background-size: 300% 100%;
  will-change: opacity, transform;
}
.dove-pose-front   { background-position: 0 50%; animation: dovePoseFront 5.1s ease .35s both; }
.dove-pose-deliver { background-position: 50% 50%; animation: dovePoseDeliver 5.1s ease .35s both; }
.dove-pose-away    { background-position: 100% 50%; animation: dovePoseAway 5.1s ease .35s both; }
@keyframes dovePoseFront {
  0% { opacity: 1; transform: translateY(3px) rotate(-1deg) scale(.96); }
  18% { transform: translateY(-3px) rotate(1deg) scale(1.02); }
  34% { opacity: 1; transform: translateY(1px) rotate(-.5deg) scale(.99); }
  45%,100% { opacity: 0; transform: translateY(-2px) rotate(1deg) scale(1.04); }
}
@keyframes dovePoseDeliver {
  0%,32% { opacity: 0; transform: translateX(9px) translateY(3px) rotate(2deg) scale(.94); }
  44% { opacity: 1; transform: translateX(0) translateY(-2px) rotate(-1deg) scale(1.01); }
  58% { transform: translateX(-2px) translateY(2px) rotate(.8deg) scale(.99); }
  70% { opacity: 1; transform: translateX(1px) translateY(-3px) rotate(-.8deg) scale(1.02); }
  80%,100% { opacity: 0; transform: translateX(6px) translateY(-4px) rotate(-3deg) scale(.98); }
}
@keyframes dovePoseAway {
  0%,68% { opacity: 0; transform: translateX(-8px) rotate(4deg) scale(.95); }
  78% { opacity: 1; transform: translateX(0) rotate(-2deg) scale(1.02); }
  90% { transform: translateX(3px) translateY(-3px) rotate(1deg) scale(.99); }
  100% { opacity: 1; transform: translateX(7px) translateY(-6px) rotate(-3deg) scale(1.03); }
}
.dove-bob > svg {
  display: none;
}
/* 近翼比远翼稍有延迟，避免机械式同步扑动 */
.dove .wing-near { transform-box: view-box; transform-origin: 0 0; animation: flapNear .46s cubic-bezier(.42,0,.38,1) infinite; }
.dove .wing-far  { transform-box: view-box; transform-origin: 0 0; animation: flapFar .49s cubic-bezier(.46,0,.42,1) -.07s infinite; }
@keyframes flapNear {
  0%,100% { transform: translate(88px,50px) rotate(27deg) scaleY(.96) translate(-88px,-50px); }
  44%     { transform: translate(88px,50px) rotate(-31deg) scaleY(1.06) translate(-88px,-50px); }
  62%     { transform: translate(88px,50px) rotate(-23deg) scaleY(1.03) translate(-88px,-50px); }
}
@keyframes flapFar {
  0%,100% { transform: translate(80px,46px) rotate(19deg) scaleY(.97) translate(-80px,-46px); }
  46%     { transform: translate(80px,46px) rotate(-34deg) scaleY(1.05) translate(-80px,-46px); }
  65%     { transform: translate(80px,46px) rotate(-25deg) translate(-80px,-46px); }
}
@keyframes doveBob {
  0%,100% { transform: translateY(2px) rotate(.5deg); }
  45% { transform: translateY(-2.5px) rotate(-.8deg); }
}
@keyframes doveFly {
  0% { opacity: 0; filter: blur(2.8px); transform: translate(84vw, -10vh) scale(.07) rotateZ(-13deg) rotateY(28deg); animation-timing-function: cubic-bezier(.22,.66,.36,1); }
  10% { opacity: .72; filter: blur(1.8px); transform: translate(71vw, 4vh) scale(.2) rotateZ(-9deg) rotateY(20deg); }
  25% { opacity: 1; filter: blur(.7px); transform: translate(51vw, 23vh) scale(.48) rotateZ(-5deg) rotateY(12deg); }
  44% { opacity: 1; filter: blur(0); transform: translate(25vw, 37vh) scale(.72) rotateZ(5deg) rotateY(-6deg) rotateX(3deg); animation-timing-function: cubic-bezier(.33,.05,.28,1); }
  61% { transform: translate(calc(50vw - 55px), calc(44vh - 42px)) scale(.88) rotateZ(-2deg) rotateY(-9deg) rotateX(2deg); }
  68% { transform: translate(calc(50vw - 52px), calc(44vh - 48px)) scale(.92) rotateZ(1deg) rotateY(-5deg) rotateX(-2deg); }
  73% { transform: translate(calc(50vw - 48px), calc(44vh - 50px)) scale(.88) rotateZ(-3deg) rotateY(-12deg) rotateX(3deg); animation-timing-function: cubic-bezier(.45,.02,.66,.45); }
  88% { opacity: 1; filter: blur(.2px); transform: translate(91vw, 24vh) scale(.62) rotateZ(-12deg) rotateY(-26deg) rotateX(4deg); }
  100% { opacity: 0; filter: blur(1.2px); transform: translate(132vw, 2vh) scale(.52) rotateZ(-17deg) rotateY(-38deg) rotateX(7deg); }
}
/* 衔在喙下的信封：抵达画面中心后松口 */
.dove-mail {
  display: none;
}
.dove-mail svg { display: block; filter: drop-shadow(0 3px 5px rgba(46,38,28,.2)); }
@keyframes mailSway { from { transform: rotate(-5deg); } to { transform: rotate(4.5deg); } }
@keyframes mailHide { 0%, 67.5% { opacity: 1; } 68.2%, 100% { opacity: 0; } }

/* 落定的请帖信封（开启钮）：掉落回弹 -> 悬停 + 金晕呼吸 */
.veil-mail {
  position: absolute; left: 50%; top: 66%; z-index: 3;
  width: 180px; height: 120px; margin: -60px 0 0 -90px;
  padding: 0; border: none; background: none; cursor: pointer;
  opacity: 0; will-change: transform; transform-style: preserve-3d;
  -webkit-tap-highlight-color: transparent;
  transition: transform .7s ease, opacity .6s ease;
  animation: mailFall .78s linear 3.82s forwards, mailFloat 3.4s ease-in-out 4.66s infinite alternate;
}
.veil-mail > svg {
  display: none;
}
.veil-mail-photo {
  display: block; position: relative; z-index: 1;
  width: 100%; height: 100%; object-fit: contain;
  filter: drop-shadow(0 4px 7px rgba(46,38,28,.2)) drop-shadow(0 20px 28px rgba(46,38,28,.3));
  transition: transform .25s ease; transform-style: preserve-3d;
  user-select: none; pointer-events: none;
}
.veil-mail:active > .veil-mail-photo { transform: scale(.96); }
.veil-mail:focus-visible { outline: 1px solid var(--gold); outline-offset: 8px; border-radius: 10px; }
.veil-mail::after {
  content: ''; position: absolute; left: 50%; top: 50%; z-index: 0;
  width: 200px; height: 160px; margin: -80px 0 0 -100px;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(201,174,114,.34), rgba(201,174,114,.12) 55%, transparent 72%);
  opacity: 0;
  animation: mailGlow 2.6s ease-in-out 4.72s infinite alternate;
}
.mail-ripple {
  position: absolute; left: 50%; top: 50%; z-index: 0;
  width: 138px; height: 94px; margin: -47px 0 0 -69px;
  border: 1.5px solid rgba(201,174,114,.6); border-radius: 18px;
  opacity: 0; transform: scale(.55);
  animation: mailRipple .9s ease-out 4.35s both;
}
@keyframes mailFall {
  0%   { opacity: 1; transform: perspective(680px) translateY(-20vh) rotateX(62deg) rotateY(-18deg) rotateZ(-9deg) scale(.7); animation-timing-function: cubic-bezier(.42,0,.78,.48); }
  38%  { transform: perspective(680px) translateY(-4vh) rotateX(28deg) rotateY(12deg) rotateZ(5deg) scale(.88); }
  60%  { opacity: 1; transform: perspective(680px) translateY(3px) rotateX(-8deg) rotateY(5deg) rotateZ(1.6deg) scale(1); animation-timing-function: ease-out; }
  78%  { transform: perspective(680px) translateY(-8px) rotateX(-4deg) rotateY(-3deg) rotateZ(-1.2deg) scale(1.01); animation-timing-function: ease-out; }
  100% { opacity: 1; transform: perspective(680px) translateY(0) rotateX(-12deg) rotateY(8deg) rotateZ(-.8deg); }
}
@keyframes mailFloat {
  from { transform: perspective(680px) translateY(0) rotateX(-12deg) rotateY(8deg) rotateZ(-.8deg); }
  to { transform: perspective(680px) translateY(-6px) rotateX(-9deg) rotateY(-5deg) rotateZ(.7deg); }
}
@keyframes mailGlow  { from { opacity: .18; } to { opacity: .6; } }
@keyframes mailRipple { 0% { opacity: .65; transform: scale(.55); } 100% { opacity: 0; transform: scale(1.3); } }

.veil-mail-hint, .veil-music-hint {
  position: absolute; left: 0; right: 0; z-index: 3; text-align: center;
  opacity: 0; animation: hintIn .9s ease 6.55s forwards;
}
.veil-mail-hint  { top: calc(66% + 70px); font-size: 12px; color: #5E5A52; letter-spacing: .22em; }
.veil-music-hint { top: calc(66% + 92px); font-size: 11px; color: #6E6A62; letter-spacing: .1em; animation-delay: 6.75s; }
@keyframes hintIn { to { opacity: .92; } }

/* 开启离场：信封轻轻上托淡出，提示随封面一起走 */
#veil.away .veil-mail { animation: none; opacity: 0; transform: translateY(-30px) scale(1.08); }
#veil.away .veil-mail-hint, #veil.away .veil-music-hint { animation: none; opacity: 0; }

/* ============================================================
   全新爱情故事开场：相遇 → 心动 → 牵手 → 领取邀请函
   ============================================================ */
#veil {
  background: #f6f0e7;
  perspective: 1200px;
}
#veil::before {
  background:
    radial-gradient(circle at 18% 12%, rgba(231,198,143,.28), transparent 34%),
    radial-gradient(circle at 82% 76%, rgba(185,128,97,.18), transparent 38%),
    linear-gradient(145deg, #fbf8f2 0%, #f0e5d5 55%, #e6d2bb 100%);
  animation: loveBackground 9s ease-in-out both;
}
#veil::after {
  z-index: 1;
  background:
    linear-gradient(90deg, rgba(255,255,255,.18), transparent 20%, transparent 80%, rgba(255,255,255,.14)),
    radial-gradient(ellipse at center, transparent 42%, rgba(62,43,24,.13) 115%);
}
@keyframes loveBackground {
  0% { transform: scale(1.08); filter: saturate(.82) brightness(.98); }
  100% { transform: scale(1); filter: saturate(1) brightness(1.02); }
}

/* 旧照片、信鸽与信封只保留在源码中作回退，不再参与加载和显示 */
#veil > .veil-breeze, #veil > .veil-petals, #veil > .veil-inner,
#veil > .dove, #legacyOpenBtn, #veil > .veil-mail-hint, #veil > .veil-music-hint {
  display: none !important;
}

.love-story {
  position: absolute; inset: 0; z-index: 3;
  overflow: hidden; color: #2c241d;
  transition: opacity .72s ease, transform .82s cubic-bezier(.18,.72,.24,1), filter .72s ease;
}
.love-aurora {
  position: absolute; left: 50%; top: 37%; width: 86vw; max-width: 450px; aspect-ratio: 1;
  transform: translate(-50%,-50%); border-radius: 50%; opacity: .45;
  background: radial-gradient(circle, rgba(255,249,232,.92) 0%, rgba(224,185,118,.18) 44%, transparent 70%);
  filter: blur(8px); animation: loveAurora 3.4s ease-in-out infinite alternate;
}
@keyframes loveAurora { from { transform: translate(-50%,-50%) scale(.92); opacity: .3; } to { transform: translate(-50%,-50%) scale(1.08); opacity: .58; } }

.love-stars { position: absolute; inset: 0; pointer-events: none; }
.love-stars i {
  position: absolute; width: 4px; height: 4px; border-radius: 50%; opacity: 0;
  background: #c4a05f; box-shadow: 0 0 9px rgba(190,145,75,.7);
  animation: loveStar 3.2s ease-in-out infinite;
}
.love-stars i:nth-child(1) { left:12%; top:17%; animation-delay:.1s; }
.love-stars i:nth-child(2) { left:27%; top:31%; animation-delay:1.2s; transform:scale(.65); }
.love-stars i:nth-child(3) { left:77%; top:20%; animation-delay:.7s; }
.love-stars i:nth-child(4) { left:88%; top:38%; animation-delay:1.9s; transform:scale(.55); }
.love-stars i:nth-child(5) { left:18%; top:62%; animation-delay:2.3s; transform:scale(.7); }
.love-stars i:nth-child(6) { left:72%; top:61%; animation-delay:1.5s; }
.love-stars i:nth-child(7) { left:36%; top:12%; animation-delay:2.8s; transform:scale(.5); }
.love-stars i:nth-child(8) { left:61%; top:34%; animation-delay:2.1s; transform:scale(.65); }
@keyframes loveStar { 0%,100% { opacity:0; transform:translateY(7px) scale(.45); } 44% { opacity:.85; transform:translateY(0) scale(1); } }

.love-scene {
  position: absolute; left: 50%; top: -1%; width: min(100vw, 430px); height: auto;
  transform: translateX(-50%); overflow: visible;
}
.meeting-line { stroke-dasharray: 430; stroke-dashoffset: 430; animation: meetingDraw 3.5s ease .45s forwards; }
@keyframes meetingDraw { to { stroke-dashoffset: 0; } }
.heart-line { stroke-dasharray: 320; stroke-dashoffset: 320; animation: heartDraw 1.45s cubic-bezier(.35,.05,.2,1) 3.75s forwards; }
@keyframes heartDraw { 0% { stroke-dashoffset:320; opacity:.1; } 100% { stroke-dashoffset:0; opacity:1; } }

.story-person { opacity: 0; transform-box: view-box; will-change: transform, opacity, filter; }
.person-left { transform-origin: 151px 320px; animation: personMeetLeft 4.2s cubic-bezier(.18,.7,.2,1) .4s forwards, personSoftFade .8s ease 5.2s forwards; }
.person-right { transform-origin: 239px 320px; animation: personMeetRight 4.2s cubic-bezier(.18,.7,.2,1) .4s forwards, personSoftFade .8s ease 5.2s forwards; }
@keyframes personMeetLeft {
  0% { opacity:0; transform:translateX(-178px) scale(.78); }
  12% { opacity:1; }
  72% { transform:translateX(-12px) scale(.97); }
  88% { transform:translateX(2px) scale(1.01); }
  100% { opacity:1; transform:translateX(0) scale(1); }
}
@keyframes personMeetRight {
  0% { opacity:0; transform:translateX(178px) scale(.78); }
  12% { opacity:1; }
  72% { transform:translateX(12px) scale(.97); }
  88% { transform:translateX(-2px) scale(1.01); }
  100% { opacity:1; transform:translateX(0) scale(1); }
}
@keyframes personSoftFade { to { opacity:.42; filter:blur(0); transform:scale(.985) translateY(-1px); } }
.walk-leg { transform-box: view-box; transform-origin: center top; animation: loveWalkLeg .42s ease-in-out .5s 8 alternate; }
.walk-leg-b { animation-direction: alternate-reverse; }
@keyframes loveWalkLeg { from { transform:rotate(-5deg); } to { transform:rotate(5deg); } }
.bride-dress { transform-box:view-box; transform-origin:239px 305px; animation:dressSway .58s ease-in-out .5s 6 alternate; }
@keyframes dressSway { from { transform:skewX(-1.4deg); } to { transform:skewX(1.4deg); } }
.hand-left { transform-box:view-box; transform-origin:158px 244px; animation:handReachLeft 1.2s ease 3.25s forwards; }
.hand-right { transform-box:view-box; transform-origin:231px 244px; animation:handReachRight 1.2s ease 3.25s forwards; }
@keyframes handReachLeft { to { transform:rotate(-9deg) translateX(2px); } }
@keyframes handReachRight { to { transform:rotate(9deg) translateX(-2px); } }
.joined-light { opacity:0; transform-box:view-box; transform-origin:center; animation:joinedGlow 1.4s ease 4.15s forwards; }
@keyframes joinedGlow { 0% { opacity:0; transform:scale(.2); } 45% { opacity:1; transform:scale(1.35); } 100% { opacity:.72; transform:scale(.7); } }

.story-copy { position:absolute; left:20px; right:20px; top:46.8%; height:62px; }
.story-line {
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  margin:0; font-family:'Kaiti SC','STKaiti','KaiTi',var(--serif); font-size:17px;
  letter-spacing:.14em; color:#59483a; opacity:0; filter:blur(5px); transform:translateY(9px);
}
.story-line-1 { animation:storySentence 2.05s ease .25s both; }
.story-line-2 { animation:storySentence 2.05s ease 2.05s both; }
.story-line-3 { animation:storySentence 2.05s ease 3.85s both; }
@keyframes storySentence { 0% { opacity:0; filter:blur(5px); transform:translateY(9px); } 22%,72% { opacity:1; filter:blur(0); transform:none; } 100% { opacity:0; filter:blur(3px); transform:translateY(-7px); } }

.story-finale {
  position:absolute; left:18px; right:18px; top:50%; opacity:0; transform:translateY(14px);
  animation:finaleArrive 1.05s cubic-bezier(.2,.72,.25,1) 5.35s forwards;
}
@keyframes finaleArrive { to { opacity:1; transform:none; } }
.finale-en { margin:0 0 10px; font-size:9px; letter-spacing:.42em; text-indent:.42em; color:#9c7c4e; }
.story-finale h1 { display:flex; align-items:center; justify-content:center; gap:12px; margin:0; font-size:25px; font-weight:400; letter-spacing:.12em; }
.story-finale h1 i { font-family:var(--script); font-size:28px; font-weight:400; color:#b28b50; }
.finale-invite { margin:11px 0 5px; font-size:13px; letter-spacing:.2em; color:#5f5145; }
.finale-date { margin:0; font-size:11px; letter-spacing:.32em; color:#9d825b; }

.love-claim {
  position:absolute; z-index:5; left:50%; bottom:max(72px, calc(56px + env(safe-area-inset-bottom)));
  width:min(76vw, 286px); height:82px; padding:13px 54px 12px 24px;
  border:1px solid rgba(151,112,57,.46); border-radius:7px; overflow:hidden;
  background:linear-gradient(145deg, rgba(255,253,247,.96), rgba(236,218,187,.94));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9), 0 18px 38px rgba(78,53,27,.2), 0 3px 8px rgba(78,53,27,.12);
  color:#372a20; text-align:left; opacity:0; transform:translate(-50%,28px) rotateX(14deg) scale(.92);
  animation:claimRise .9s cubic-bezier(.18,.8,.25,1) 6.3s forwards;
  cursor:pointer; -webkit-tap-highlight-color:transparent; transform-style:preserve-3d;
}
.love-claim:disabled { cursor:default; }
@keyframes claimRise { 0% { opacity:0; transform:translate(-50%,28px) rotateX(14deg) scale(.92); } 70% { opacity:1; transform:translate(-50%,-3px) rotateX(-2deg) scale(1.015); } 100% { opacity:1; transform:translate(-50%,0) rotateX(0) scale(1); } }
.claim-en { display:block; font-size:8px; letter-spacing:.26em; color:#9b794a; margin-bottom:7px; }
.love-claim strong { display:block; font-family:'Songti SC','STSong',var(--serif); font-size:17px; font-weight:400; letter-spacing:.2em; }
.claim-arrow { position:absolute; right:21px; top:50%; transform:translateY(-50%); font-size:25px; color:#9c7743; animation:claimArrow 1.1s ease-in-out 7.1s infinite; }
@keyframes claimArrow { 0%,100% { transform:translate(-3px,-50%); } 50% { transform:translate(4px,-50%); } }
.claim-shine { position:absolute; inset:-50% auto -50% -35%; width:30%; background:linear-gradient(90deg,transparent,rgba(255,255,255,.72),transparent); transform:skewX(-18deg); animation:claimShine 2.8s ease 7s infinite; }
@keyframes claimShine { 0%,56% { left:-35%; } 82%,100% { left:122%; } }
.love-claim:not(:disabled):active { transform:translate(-50%,2px) scale(.97); }
.love-music-note { position:absolute; left:0; right:0; bottom:max(36px, calc(24px + env(safe-area-inset-bottom))); margin:0; opacity:0; font-size:10px; letter-spacing:.16em; color:#8a765e; animation:noteAppear .8s ease 6.9s forwards; }
@keyframes noteAppear { to { opacity:.8; } }
#veil.story-ready .love-claim { border-color:rgba(151,112,57,.68); }
#veil.away { transform:scale(.985); }
#veil.away .love-story { opacity:0; transform:scale(1.045); filter:blur(2px); }

/* ============================================================
   电影感爱情序章 · 命运金线 / 双手相遇 / 立体邀请函
   ============================================================ */
#veil {
  background:#100d10;
}
#veil::before {
  background:
    radial-gradient(ellipse at 50% 34%, rgba(119,60,55,.36) 0%, rgba(39,21,27,.28) 38%, transparent 68%),
    radial-gradient(circle at 18% 80%, rgba(166,105,60,.15), transparent 38%),
    linear-gradient(155deg,#0d0b0e 0%,#1a1117 48%,#0d0b0f 100%);
  animation:cinemaBackdrop 9s cubic-bezier(.22,.6,.3,1) both;
}
#veil::after {
  z-index:1;
  background:
    linear-gradient(90deg,rgba(0,0,0,.52),transparent 19%,transparent 81%,rgba(0,0,0,.52)),
    radial-gradient(ellipse at center,transparent 33%,rgba(0,0,0,.54) 112%);
}
@keyframes cinemaBackdrop { from { transform:scale(1.12); filter:saturate(.72) brightness(.72); } to { transform:scale(1.015); filter:saturate(1) brightness(1); } }

.cinematic-love { color:#f7ead3; isolation:isolate; }
.cinema-backdrop { position:absolute; inset:0; overflow:hidden; }
.silk { position:absolute; display:block; border-radius:50%; opacity:.18; filter:blur(34px); mix-blend-mode:screen; }
.silk-a { width:96vw; height:48vw; left:-30%; top:19%; background:linear-gradient(100deg,transparent,#b07456 48%,transparent); transform:rotate(-18deg); animation:silkDriftA 8s ease-in-out infinite alternate; }
.silk-b { width:92vw; height:54vw; right:-38%; top:42%; background:linear-gradient(120deg,transparent,#6d3442 45%,#d3a069 72%,transparent); transform:rotate(22deg); animation:silkDriftB 9s ease-in-out infinite alternate; }
.silk-c { width:56vw; height:56vw; left:22%; top:24%; background:radial-gradient(circle,#bf895f,transparent 68%); opacity:.09; animation:silkPulse 4.5s ease-in-out infinite alternate; }
@keyframes silkDriftA { to { transform:translate3d(14%,8%,0) rotate(-10deg) scale(1.12); opacity:.28; } }
@keyframes silkDriftB { to { transform:translate3d(-13%,-6%,0) rotate(14deg) scale(1.08); opacity:.24; } }
@keyframes silkPulse { to { transform:scale(1.28); opacity:.18; } }

.cinema-stars { position:absolute; inset:0; pointer-events:none; }
.cinema-stars i { position:absolute; width:2px; height:2px; border-radius:50%; background:#efca87; opacity:0; box-shadow:0 0 8px rgba(238,191,112,.85); animation:cinemaStar 3.4s ease-in-out infinite; }
.cinema-stars i:nth-child(1){left:8%;top:18%;animation-delay:.3s}.cinema-stars i:nth-child(2){left:23%;top:34%;animation-delay:1.7s}
.cinema-stars i:nth-child(3){left:38%;top:11%;animation-delay:2.4s}.cinema-stars i:nth-child(4){left:68%;top:21%;animation-delay:.9s}
.cinema-stars i:nth-child(5){left:86%;top:37%;animation-delay:2.1s}.cinema-stars i:nth-child(6){left:14%;top:58%;animation-delay:2.8s}
.cinema-stars i:nth-child(7){left:77%;top:63%;animation-delay:1.2s}.cinema-stars i:nth-child(8){left:91%;top:76%;animation-delay:3s}
.cinema-stars i:nth-child(9){left:31%;top:72%;animation-delay:.5s}.cinema-stars i:nth-child(10){left:57%;top:84%;animation-delay:2.2s}
@keyframes cinemaStar { 0%,100% { opacity:0; transform:translateY(7px) scale(.4); } 48% { opacity:.9; transform:translateY(0) scale(1.35); } }

.film-grain { position:absolute; inset:-40%; opacity:.055; pointer-events:none; background:repeating-radial-gradient(circle at 37% 41%,#fff 0 1px,transparent 1px 4px); background-size:7px 9px; animation:grainShift .24s steps(2) infinite; mix-blend-mode:soft-light; }
@keyframes grainShift { 0%{transform:translate(0,0)}25%{transform:translate(2%,-1%)}50%{transform:translate(-1%,2%)}75%{transform:translate(1%,1%)}100%{transform:translate(-2%,-2%)} }
.cinema-border { position:absolute; inset:13px; border:1px solid rgba(231,194,132,.14); box-shadow:inset 0 0 44px rgba(0,0,0,.28); pointer-events:none; }
.cinema-border::before,.cinema-border::after { content:''; position:absolute; left:50%; width:34px; height:1px; margin-left:-17px; background:linear-gradient(90deg,transparent,#d7aa67,transparent); opacity:.55; }
.cinema-border::before{top:-1px}.cinema-border::after{bottom:-1px}

.fate-scene { position:absolute; z-index:2; left:50%; top:7.5%; width:min(100vw,430px); height:auto; overflow:visible; transform:translateX(-50%); }
.fate-orbit,.fate-heart { fill:none; stroke:url(#fateGold); stroke-linecap:round; }
.fate-orbit { stroke-width:.85; opacity:.34; stroke-dasharray:520; stroke-dashoffset:520; }
.fate-orbit-a { animation:fateDraw 2.9s cubic-bezier(.24,.67,.28,1) .25s forwards; }
.fate-orbit-b { animation:fateDraw 3.1s cubic-bezier(.24,.67,.28,1) .65s forwards; opacity:.18; }
@keyframes fateDraw { to { stroke-dashoffset:0; } }
.fate-heart { stroke-width:1.7; stroke-dasharray:340; stroke-dashoffset:340; opacity:0; filter:url(#cinemaGlow); animation:premiumHeart 1.75s cubic-bezier(.35,.05,.2,1) 3.72s forwards; }
@keyframes premiumHeart { 0%{opacity:0;stroke-dashoffset:340} 18%{opacity:.85} 100%{opacity:.94;stroke-dashoffset:0} }

.fate-hand { will-change:transform,opacity; }
.fate-hand-left { opacity:0; transform:translate(-145px,22px) rotate(-5deg); transform-origin:155px 260px; animation:handEnterLeft 3.75s cubic-bezier(.17,.72,.22,1) .45s forwards; }
.fate-hand-right { opacity:0; transform:translate(145px,22px) rotate(5deg); transform-origin:235px 260px; animation:handEnterRight 3.75s cubic-bezier(.17,.72,.22,1) .65s forwards; }
@keyframes handEnterLeft { 0%{opacity:0;transform:translate(-145px,22px) rotate(-5deg)}16%{opacity:.28}72%{opacity:.88;transform:translate(-10px,2px) rotate(-.7deg)}100%{opacity:1;transform:none} }
@keyframes handEnterRight { 0%{opacity:0;transform:translate(145px,22px) rotate(5deg)}16%{opacity:.28}72%{opacity:.88;transform:translate(10px,2px) rotate(.7deg)}100%{opacity:1;transform:none} }
.hand-body { fill:url(#handIvory); stroke:url(#fateGold); stroke-width:1.3; stroke-linejoin:round; filter:drop-shadow(0 0 5px rgba(220,166,92,.16)); }
.hand-detail { fill:none; stroke:#f6dab0; stroke-width:.86; stroke-linecap:round; opacity:.82; }
.hand-cuff { fill:none; stroke:#d2a35f; stroke-width:1.15; opacity:.58; }
.touch-halo { opacity:0; transform-origin:195px 244px; animation:touchHalo 1.5s ease 3.95s forwards; mix-blend-mode:screen; }
.touch-core { opacity:0; animation:touchCore 1.5s ease 4.02s forwards; }
@keyframes touchHalo { 0%{opacity:0;transform:scale(.05)}42%{opacity:.9;transform:scale(1)}100%{opacity:.32;transform:scale(.7)} }
@keyframes touchCore { 0%{opacity:0}40%{opacity:1}100%{opacity:.78} }

.story-chapters { position:absolute; z-index:4; left:24px; right:24px; top:10.5%; height:108px; text-align:center; }
.story-chapter { position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; opacity:0; transform:translateY(12px); filter:blur(7px); }
.story-chapter span { display:block; margin-bottom:12px; font-size:8px; letter-spacing:.43em; text-indent:.43em; color:#d7ad70; }
.story-chapter h2 { margin:0; font-family:'Songti SC','STSong',var(--serif); font-size:22px; line-height:1.58; font-weight:300; letter-spacing:.16em; text-indent:.16em; text-shadow:0 3px 18px rgba(0,0,0,.46); }
.chapter-one { animation:chapterStory 2.35s ease .18s both; }
.chapter-two { animation:chapterStory 2.35s ease 2.12s both; }
.chapter-three { animation:chapterStory 2.4s ease 4.02s both; }
@keyframes chapterStory { 0%{opacity:0;transform:translateY(12px);filter:blur(7px)}18%,72%{opacity:1;transform:none;filter:blur(0)}100%{opacity:0;transform:translateY(-9px);filter:blur(4px)} }

.final-invitation { position:absolute; z-index:4; left:20px; right:20px; top:51.8%; text-align:center; opacity:0; transform:translateY(18px); filter:blur(6px); animation:finalInvitation 1.2s cubic-bezier(.18,.76,.23,1) 5.62s forwards; }
@keyframes finalInvitation { to { opacity:1; transform:none; filter:blur(0); } }
.final-invitation p { margin:0 0 13px; font-size:8px; letter-spacing:.5em; text-indent:.5em; color:#d8ac6d; }
.final-invitation h1 { display:flex; justify-content:center; align-items:center; gap:12px; margin:0; color:#fff8eb; font-family:'Songti SC','STSong',var(--serif); font-size:26px; font-weight:300; letter-spacing:.11em; text-shadow:0 5px 22px rgba(0,0,0,.72); }
.final-invitation h1 i { color:#d8ad70; font-family:var(--script); font-size:29px; font-weight:400; }
.final-invitation em { display:block; margin:13px 0 8px; color:#d7c2a7; font-size:12px; font-style:normal; letter-spacing:.22em; }
.final-invitation strong { display:block; color:#b98952; font-size:10px; font-weight:400; letter-spacing:.42em; }

.premium-claim { position:absolute; z-index:6; left:50%; bottom:max(69px,calc(52px + env(safe-area-inset-bottom))); width:min(78vw,302px); height:100px; padding:0; border:1px solid rgba(237,204,151,.58); border-radius:5px; color:#38251e; text-align:left; overflow:hidden; cursor:pointer; opacity:0; transform:translate(-50%,32px) perspective(800px) rotateX(14deg) scale(.92); transform-style:preserve-3d; background:linear-gradient(135deg,#fffaf0 0%,#ead7b9 57%,#c9a271 100%); box-shadow:inset 0 1px 0 rgba(255,255,255,.92),inset 0 -1px 0 rgba(94,55,33,.22),0 26px 55px rgba(0,0,0,.48),0 5px 14px rgba(0,0,0,.35); animation:premiumClaimRise 1.05s cubic-bezier(.17,.82,.23,1) 6.48s forwards; -webkit-tap-highlight-color:transparent; }
.premium-claim::before { content:''; position:absolute; inset:6px; border:1px solid rgba(105,66,42,.24); pointer-events:none; }
@keyframes premiumClaimRise { 0%{opacity:0;transform:translate(-50%,32px) perspective(800px) rotateX(14deg) scale(.92)}68%{opacity:1;transform:translate(-50%,-4px) perspective(800px) rotateX(-2deg) scale(1.012)}100%{opacity:1;transform:translate(-50%,0) perspective(800px) rotateX(0) scale(1)} }
.premium-claim-copy { position:absolute; left:25px; top:17px; right:74px; bottom:14px; display:flex; flex-direction:column; justify-content:center; }
.premium-claim-copy small { margin-bottom:7px; color:#92663e; font-size:7px; letter-spacing:.32em; }
.premium-claim-copy strong { color:#34231c; font-family:'Songti SC','STSong',var(--serif); font-size:19px; line-height:1.1; font-weight:400; letter-spacing:.22em; }
.premium-claim-copy em { margin-top:7px; color:#9d7b59; font-size:6px; font-style:normal; letter-spacing:.24em; }
.premium-seal { position:absolute; right:20px; top:50%; width:42px; height:42px; margin-top:-21px; display:grid; place-items:center; border-radius:50%; color:#f8e8ca; font-family:'STKaiti','KaiTi',serif; font-size:20px; background:radial-gradient(circle at 34% 27%,#d3a15e,#986137 58%,#5d3326); border:1px solid rgba(96,48,31,.52); box-shadow:inset 0 2px 4px rgba(255,241,205,.45),inset 0 -3px 5px rgba(60,27,21,.34),0 4px 9px rgba(62,31,22,.3); }
.premium-claim-shine { position:absolute; top:-65%; bottom:-65%; left:-42%; width:30%; background:linear-gradient(90deg,transparent,rgba(255,255,255,.72),transparent); transform:skewX(-18deg); animation:premiumShine 2.8s ease 7.25s infinite; }
@keyframes premiumShine { 0%,58%{left:-42%}84%,100%{left:125%} }
.premium-claim:not(:disabled):active { transform:translate(-50%,2px) scale(.975); }
#veil.story-ready .premium-claim { border-color:rgba(255,222,165,.86); box-shadow:inset 0 1px 0 rgba(255,255,255,.94),0 0 0 1px rgba(211,165,95,.12),0 27px 58px rgba(0,0,0,.5),0 0 35px rgba(196,130,62,.13); }
.premium-note { bottom:max(34px,calc(21px + env(safe-area-inset-bottom))); color:#a88d74; animation:premiumNoteIn .7s ease 7s forwards; }
@keyframes premiumNoteIn { to { opacity:.72; } }

@media (max-width:360px) {
  .story-chapter h2 { font-size:20px; }
  .final-invitation h1 { font-size:23px; gap:9px; }
  .premium-claim { width:284px; }
}

@media (max-height:700px) {
  .fate-scene { top:1.5%; width:min(92vw,365px); }
  .story-chapters { top:7%; }
  .final-invitation { top:48%; }
  .premium-claim { bottom:max(44px,calc(33px + env(safe-area-inset-bottom))); height:88px; }
  .premium-claim-copy { top:12px; bottom:10px; }
  .premium-note { display:none; }
}

@media (prefers-reduced-motion:reduce) {
  .cinema-backdrop,.cinema-stars,.film-grain { animation:none!important; }
  .story-chapter { display:none; }
  .fate-orbit,.fate-heart { stroke-dashoffset:0; opacity:.46; }
  .fate-hand { opacity:.84; transform:none; }
  .touch-halo { opacity:.28; transform:scale(.7); }
  .touch-core { opacity:.75; }
  .final-invitation { opacity:1; transform:none; filter:none; }
  .premium-claim { opacity:1; transform:translate(-50%,0); }
  .premium-note { opacity:.72; }
}

@media (max-height: 700px) {
  .love-scene { top:-8%; width:min(91vw,365px); }
  .story-copy { top:43%; }
  .story-finale { top:46%; }
  .love-claim { bottom:max(50px, calc(38px + env(safe-area-inset-bottom))); height:74px; }
  .love-music-note { display:none; }
}

/* ============================================================
   音乐按钮 · 立体黑胶唱片
   分层：按钮持静止投影 / .disc 转动(沟槽+反光扇面+标签) / ::after 静止压盘缘光
   （偏移阴影与顶缘高光若放转动层会绕盘打转，故拆开）
   ============================================================ */
#musicBtn {
  position: fixed; top: 16px; right: 16px; z-index: 60;
  width: 56px; height: 56px; border-radius: 50%;
  border: none; padding: 0; background: none; cursor: pointer;
  box-shadow:
    0 3px 0 rgba(18, 15, 10, .5),
    0 10px 22px rgba(28, 24, 18, .30),
    0 2px 6px rgba(28, 24, 18, .16);
  transition: transform .25s ease, filter .35s ease;
}
#musicBtn:not(.playing) { filter: brightness(.9) saturate(.92); }
#musicBtn:hover { transform: translateY(-2px); }
#musicBtn:active { transform: scale(.95); }
#musicBtn .disc {
  position: absolute; inset: 0; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background:
    conic-gradient(from 215deg at 50% 50%,
      transparent 0deg, rgba(255, 255, 255, .13) 15deg, transparent 52deg,
      transparent 176deg, rgba(255, 255, 255, .09) 195deg, transparent 232deg),
    repeating-radial-gradient(circle at 50% 50%,
      #272219 0px, #191510 1.6px, #221D15 3.2px),
    #16130E;
}
#musicBtn::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  box-shadow: inset 0 1px 1px rgba(255, 255, 255, .16), inset 0 -2px 5px rgba(0, 0, 0, .5);
  pointer-events: none;
}
.disc-note {
  width: 22px; height: 22px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 50% 32%, #EBDAB2, var(--gold) 62%, var(--gold-d));
  color: #4A3D26; font-size: 11px; line-height: 1;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .38),
    inset 0 1px 2px rgba(255, 255, 255, .55),
    inset 0 -1px 2px rgba(0, 0, 0, .2);
  pointer-events: none;
}
#musicBtn.playing .disc { animation: spin 6s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ============================================================
   ① 封面 hero
   ============================================================ */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  padding: 60px 20px 70px;
}
.hero-inner { text-align: center; position: relative; z-index: 2; }

.eyebrow {
  font-size: 11px; letter-spacing: .5em; text-indent: .5em;
  color: var(--gold-d); margin-bottom: 18px;
}

/* 主照片：贴内框满列（左右留 24px 白边，无框无卡纸，2:3 与源图一致不裁切） */
.hero-photo {
  width: 100%; margin: 26px 0 18px;
}
.hero-photo img {
  display: block; width: 100%;
  aspect-ratio: 2 / 3; object-fit: cover;
  cursor: zoom-in;
}

/* 姓名主标：宋体栈（安卓以 Noto Serif SC 兜底） */
.names, .veil-names {
  font-family: 'Songti SC', 'STSong', 'Noto Serif SC', 'Source Han Serif SC', 'SimSun', var(--serif);
}
.names {
  font-size: clamp(30px, 9vw, 38px); font-weight: 400; letter-spacing: .12em;
  color: var(--ink);
}
.names .amp, .veil-names .amp {
  font-family: var(--script); font-size: .72em; color: var(--gold);
  margin: 0 .18em; font-weight: 400; position: relative; top: 2px;
}
.hero-date {
  margin-top: 18px; font-size: 14px; color: var(--mut);
  letter-spacing: .22em;
  display: flex; align-items: center; justify-content: center; gap: 14px;
}
.hero-date::before, .hero-date::after {
  content: ''; width: 34px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(180, 155, 107, .55));
}
.hero-date::after { background: linear-gradient(90deg, rgba(180, 155, 107, .55), transparent); }

/* 飘落羽毛：外层管下落，::before 管摇曳（淡香槟金，白底上可见） */
#petals { position: absolute; inset: 0; z-index: 1; pointer-events: none; overflow: hidden; }
.petal {
  position: absolute; top: -10vh; opacity: 0;
  animation: fall var(--t, 18s) linear infinite;
  animation-delay: var(--d, 0s);
  will-change: transform;
}
.petal::before {
  content: ''; display: block; width: 100%; height: 100%;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 64'%3E%3Cdefs%3E%3ClinearGradient id='fg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%23D8C7A2' stop-opacity='.9'/%3E%3Cstop offset='1' stop-color='%23D8C7A2' stop-opacity='.35'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M16 3 C25 12 28 30 18 51 C7 34 6 14 16 3 Z' fill='url(%23fg)'/%3E%3Cpath d='M16 3 C17 20 18 36 20 61' fill='none' stroke='url(%23fg)' stroke-width='1.3' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
  filter: drop-shadow(0 1px 3px rgba(120, 100, 60, .15));
  animation: sway var(--s, 3.4s) ease-in-out infinite alternate;
}
@keyframes fall {
  0%   { transform: translate3d(0, -10vh, 0) rotate(0deg); opacity: 0; }
  7%   { opacity: var(--o, .5); }
  93%  { opacity: var(--o, .5); }
  100% { transform: translate3d(var(--dx, 30px), 112vh, 0) rotate(46deg); opacity: 0; }
}
@keyframes sway {
  from { transform: rotate(-26deg) translateX(-7px); }
  to   { transform: rotate(20deg) translateX(7px); }
}

.scroll-hint {
  position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%);
  z-index: 2; animation: hint 1.8s ease-in-out infinite;
}
@keyframes hint { 0%,100% { transform: translate(-50%, 0); opacity: .9; } 50% { transform: translate(-50%, 8px); opacity: .45; } }

/* ============================================================
   区块通用
   ============================================================ */
.section { padding: 72px 24px 6px; }

.sec-head { text-align: center; margin-bottom: 36px; }
.sec-en { font-size: 10px; letter-spacing: .5em; text-indent: .5em; color: var(--gold-d); margin-bottom: 9px; }
.sec-zh { font-size: 22px; font-weight: 400; letter-spacing: .3em; text-indent: .3em; color: var(--ink); }

.sprig { display: flex; align-items: center; justify-content: center; gap: 10px; margin-top: 14px; }
.sprig-line { width: 46px; height: 1px; background: linear-gradient(90deg, transparent, rgba(180, 155, 107, .55)); }
.sprig .sprig-line:last-child { background: linear-gradient(90deg, rgba(180, 155, 107, .55), transparent); }

.card {
  background: linear-gradient(180deg, var(--card) 0%, var(--card-2) 100%);
  border: 1px solid var(--line);
  border-radius: 22px;
  padding: 30px 24px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .8),
    0 1px 2px rgba(60, 52, 40, .03),
    0 18px 48px rgba(60, 52, 40, .06);
}

/* 滚动渐入 */
.reveal { opacity: 0; transform: translateY(24px); transition: opacity .8s ease, transform .8s ease; }
.reveal.in { opacity: 1; transform: none; }
/* 同区块里第二个元素晚半拍进场，出错落感 */
.reveal + .reveal { transition-delay: .13s; }

/* ============================================================
   ② 邀请函
   ============================================================ */
/* 新人双照：照片不集中在一处，邀请函区也有 */
.twin { display: flex; align-items: center; justify-content: center; gap: 16px; margin-bottom: 34px; }
.twin-fig { width: calc((100% - 16px) / 2); }   /* 双图精确二等分内框列宽 */
.twin-img { }
.twin-img img { display: block; width: 100%; aspect-ratio: 2 / 3; object-fit: cover; cursor: zoom-in; }
.twin-fig figcaption { margin-top: 12px; text-align: center; }
.twin-fig figcaption b {
  display: block; font-weight: 400; font-size: 15px; letter-spacing: .16em; color: var(--ink);
  font-family: 'Songti SC', 'STSong', 'Noto Serif SC', 'Source Han Serif SC', 'SimSun', var(--serif);
}
.twin-fig figcaption i {
  display: block; font-style: normal; font-size: 9px;
  letter-spacing: .3em; text-indent: .3em; color: var(--mut); margin-top: 5px;
}
.twin-amp { font-family: var(--script); font-size: 30px; color: var(--gold); transform: translateY(-14px); }

/* ============================================================
   邀请函 · 信封开启 + 钢笔逐字书写
   ============================================================ */
.invite-stage { position: relative; }
.letter {
  position: relative;
  opacity: 0; transform: translateY(18px) scale(.97);
  transition: opacity .65s ease, transform .65s ease;
  font-family: 'Kaiti SC', 'STKaiti', 'KaiTi', 'Songti SC', 'Noto Serif SC', 'SimSun', var(--serif);
}
.invite-stage.open .letter { opacity: 1; transform: none; }
.invite-lead {
  text-align: center; font-size: 16px; color: var(--gold-d);
  letter-spacing: .12em; margin-bottom: 16px;
}
.invite-p { font-size: 15px; line-height: 2.1; text-align: justify; margin-bottom: 12px; }
#inviteP1, #inviteP2 { text-align: center; }
.invite-sign { text-align: right; margin-top: 20px; }
.invite-sign p { font-size: 17px; letter-spacing: .1em; }
.sign-sub { font-size: 12px; color: var(--mut); margin-top: 5px !important; letter-spacing: .15em; }
.letter .ch {
  display: inline-block; opacity: 0; filter: blur(3px); transform: translateY(3px);
  transition: opacity .26s ease, filter .26s ease, transform .26s ease;
}
.letter .ch.on { opacity: 1; filter: blur(0); transform: none; }
.letter-skip {
  text-align: center; font-size: 10px; color: var(--mut);
  letter-spacing: .22em; margin: 16px 0 -8px; opacity: 0; transition: opacity .5s ease;
}
.invite-stage.open .letter-skip { opacity: .85; }
.letter-skip.off { opacity: 0 !important; }

/* 钢笔（笔尖在 96 视窗的 (9,89)，按 84px 缩放即 (8,78)；双层投影出金属悬浮感） */
.pen {
  position: absolute; left: 0; top: 0; width: 84px; height: 84px;
  pointer-events: none; z-index: 6; opacity: 0;
  filter: drop-shadow(0 2px 2px rgba(46,38,28,.16)) drop-shadow(0 8px 13px rgba(46,38,28,.22));
  transition: opacity .45s ease, transform .07s linear;
  will-change: transform;
}
.pen.on { opacity: 1; }

/* 信封（绝对居中盖在信纸上，开启后淡出） */
.envelope {
  position: absolute; left: 50%; top: 50%;
  width: min(78vw, 310px); height: 200px;
  transform: translate(-50%, -50%);
  z-index: 3; padding: 0; border: none; background: none;
  perspective: 760px; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity .55s ease, transform .55s ease;
}
.envelope:focus-visible { outline: 1px solid var(--gold); outline-offset: 6px; border-radius: 12px; }
.env-back {
  position: absolute; inset: 0; border-radius: 12px;
  background: linear-gradient(180deg, #FBFAF6, #F3EFE8);
  box-shadow: 0 18px 44px rgba(60, 52, 40, .12), inset 0 1px 0 #fff;
}
.env-hint {
  position: absolute; left: 7%; right: 7%; top: 13%; bottom: 13%;
  background: #FFFEFB; border: 1px solid #F0EDE6; border-radius: 3px;
  box-shadow: 0 1px 3px rgba(60, 52, 40, .05);
  transition: transform .5s ease;
}
.env-hint::before {
  content: ''; position: absolute; left: 15%; right: 15%; top: 32%;
  height: 42px; opacity: .55;
  background: repeating-linear-gradient(180deg, #E9E4DB 0 2px, transparent 2px 12px);
}
.env-front {
  position: absolute; inset: 0; z-index: 2; border-radius: 12px;
  background: linear-gradient(180deg, #FDFCF9 0%, #F5F2EB 100%);
  clip-path: polygon(0 0, 50% 46%, 100% 0, 100% 100%, 0 100%);
}
.env-flap {
  position: absolute; left: 1px; right: 1px; top: 0; height: 56%; z-index: 4;
  background: linear-gradient(180deg, #F6F3EC, #FBF9F4);
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  transform-origin: 50% 0;
  transition: transform .64s cubic-bezier(.65, .05, .3, 1);
}
.envelope.open .env-flap { transform: rotateX(-178deg); }
.envelope.open .env-hint { transform: translateY(-9px); }
.env-seal {
  position: absolute; left: 50%; top: 47%; z-index: 5;
  width: 46px; height: 46px; margin: -23px 0 0 -23px;
  border-radius: 47% 53% 50% 50% / 52% 48% 55% 45%;
  background: radial-gradient(circle at 38% 32%, #EBD8AE, var(--gold) 58%, var(--gold-d) 96%);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 10px rgba(122, 98, 55, .35), inset 0 2px 3px rgba(255, 255, 255, .5), inset 0 -2px 4px rgba(90, 70, 40, .3);
  transition: transform .32s ease, opacity .32s ease;
}
.env-seal span {
  font-size: 17px; color: #57431F; transform: rotate(-4deg);
  font-family: 'Songti SC', 'STSong', 'SimSun', var(--serif);
}
.envelope.broke .env-seal { transform: scale(.5) rotate(12deg); opacity: 0; }
.envelope.gone { opacity: 0; transform: translate(-50%, -56%) scale(.93); pointer-events: none; }
/* 钢笔书写时笔杆可能探出卡片右缘，页面横向裁掉防抖动 */
html, body { overflow-x: clip; }

/* ============================================================
   ③ 倒计时
   ============================================================ */
.cd-label { text-align: center; font-size: 13px; color: var(--mut); letter-spacing: .2em; margin-bottom: 14px; }

/* ---------- 倒计时：黑面板 = 左黑白日历(圈婚期) + 右黑底白字滚动数字 ---------- */
.cd-panel {
  display: flex; gap: 14px; align-items: stretch;
  background: #14110C;
  border-radius: 18px; padding: 16px 14px;
  box-shadow: 0 20px 44px rgba(28, 24, 16, .24), inset 0 1px 0 rgba(255, 255, 255, .06);
}
.cd-cal { flex: none; width: 148px; padding: 2px 6px 0; }
.cal-month {
  font-size: 10px; letter-spacing: .3em; text-indent: .3em; text-align: center;
  color: #C9AE72; margin-bottom: 9px; font-weight: 500;
}
.cal-week { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; margin-bottom: 5px; }
.cal-week span { font-size: 8px; color: #7E786C; text-align: center; letter-spacing: 0; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cal-grid span { font-size: 9.5px; color: #D8D1C4; text-align: center; line-height: 20px; height: 20px; }
.cal-grid span.mark {          /* 婚期：金圈圈起来 */
  width: 19px; height: 19px; line-height: 17px; margin: 0 auto;
  border: 1.3px solid #C9AE72; border-radius: 50%;
  color: #F2E7CC; font-weight: 600;
  box-shadow: 0 0 8px rgba(201, 174, 114, .35);
}
.cd-grid { flex: 1; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.cd-cell {
  text-align: center; padding: 11px 4px 9px;
  background: #211D15;
  border: 1px solid rgba(255, 255, 255, .06); border-radius: 12px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .05);
}
.cd-cell b {
  display: block; position: relative; overflow: hidden;
  font-size: 24px; font-weight: 500; color: #FFFFFF; line-height: 1.2;
  font-variant-numeric: tabular-nums; perspective: 200px;
}
.cd-cell b > span { display: block; }
.cd-cell b span.out { position: absolute; inset: 0; }
.cd-cell b span.in { animation: cdIn .5s cubic-bezier(.22, .9, .3, 1) both; }
.cd-cell b span.out { animation: cdOut .5s cubic-bezier(.55, .05, .6, 1) both; }
/* 数字窗口上下渐暗，转轮质感 */
.cd-cell b::before, .cd-cell b::after {
  content: ''; position: absolute; left: 0; right: 0; height: 7px; z-index: 2; pointer-events: none;
}
.cd-cell b::before { top: 0; background: linear-gradient(180deg, rgba(0, 0, 0, .55), transparent); }
.cd-cell b::after { bottom: 0; background: linear-gradient(0deg, rgba(0, 0, 0, .55), transparent); }
.cd-cell i { display: block; font-style: normal; font-size: 10px; color: #8F897C; margin-top: 3px; letter-spacing: .24em; text-indent: .24em; }
/* 数字向下转动（旧值向下滚出、新值自上滚入） */
@keyframes cdIn  { from { transform: translateY(-108%) rotateX(-34deg); opacity: .2; } to { transform: none; opacity: 1; } }
@keyframes cdOut { from { transform: none; opacity: 1; } to { transform: translateY(108%) rotateX(34deg); opacity: 0; } }

/* ---------- 时光一帧：贴内框照片带（左右各留 20px 白边，2:3 不裁切） ---------- */
.moment {
  width: calc(100% - 40px); margin: 58px auto 0;
}
.moment img { display: block; width: 100%; aspect-ratio: 2 / 3; object-fit: cover; cursor: zoom-in; }
.moment figcaption {
  display: flex; justify-content: space-between; align-items: center;
  padding: 12px 2px 0;
  font-size: 9px; letter-spacing: .34em; color: var(--mut);
}

/* ============================================================
   ④ 婚宴信息
   ============================================================ */
.detail-row { display: flex; gap: 14px; align-items: flex-start; padding: 18px 0; }
.detail-row + .detail-row { border-top: 1px dashed #E6E1D8; }
.detail-ico {
  flex: none; width: 38px; height: 38px; border-radius: 50%;
  background: linear-gradient(180deg, #FCFBF8, #F5F2EC);
  border: 1px solid rgba(180, 155, 107, .35);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .8);
  display: flex; align-items: center; justify-content: center;
}
.detail-k { font-size: 11px; color: var(--mut); letter-spacing: .22em; margin-bottom: 5px; }
.detail-v { font-size: 15px; line-height: 1.75; }
.detail-actions { display: flex; gap: 10px; margin-top: 18px; }

/* ---------- 按钮：韩系极简，墨色主钮 ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: none; border-radius: 999px; padding: 11px 24px;
  font-family: var(--serif); font-size: 14px; letter-spacing: .14em; text-indent: .14em;
  cursor: pointer; text-decoration: none;
  transition: transform .15s ease, box-shadow .15s ease, opacity .15s ease;
}
.btn:active { transform: scale(.97); }
.btn-solid {
  background: linear-gradient(180deg, #262421 0%, #171512 100%);
  color: #F6F4EF;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .1),
    0 10px 24px rgba(28, 26, 23, .22);
}
.btn-solid:hover {
  transform: translateY(-1px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .1),
    0 14px 30px rgba(28, 26, 23, .3);
}
.btn-ghost {
  background: transparent; border: 1px solid #CFCAC2; color: #4A463F;
}
.btn-ghost:hover { background: rgba(60, 52, 40, .04); }
.btn-wide { width: 100%; }
.detail-actions .btn { flex: 1; }

/* ============================================================
   ⑤ 相册
   ============================================================ */
/* ---------- 我们的时光：书本翻页相册 ---------- */
@property --turn {
  syntax: '<number>';
  inherits: false;
  initial-value: 0;
}
.book {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  perspective: 2100px;
  perspective-origin: 48% 48%;
  transform-style: preserve-3d;
  background: #E5DED2;
  border-radius: 3px 8px 8px 3px;
  box-shadow:
    -7px 2px 13px rgba(43, 37, 28, .12),
    3px 7px 0 #D5CDBF,
    5px 10px 0 #C6BDAE,
    9px 24px 42px rgba(48, 41, 31, .25);
  overflow: visible;
  touch-action: pan-y;               /* 横向拖拽交给翻页，纵向正常滚屏 */
  user-select: none; -webkit-user-select: none;
  cursor: grab;
}
.book::before {
  content: ''; position: absolute; z-index: 5; pointer-events: none;
  left: 0; top: 0; bottom: 0; width: 15px;
  border-radius: 3px 0 0 3px;
  background: linear-gradient(90deg,
    rgba(43,35,25,.32) 0%, rgba(255,255,255,.32) 18%,
    rgba(41,34,25,.2) 48%, rgba(255,255,255,.12) 72%, transparent 100%);
  box-shadow: 4px 0 10px rgba(35,29,20,.13);
  opacity: .78;
}
.book::after {
  content: ''; position: absolute; z-index: -1; pointer-events: none;
  left: 8px; right: -7px; bottom: -8px; height: 13px;
  border-radius: 0 0 7px 4px;
  background: repeating-linear-gradient(0deg,
    #D8D0C3 0 1px, #F7F3EB 1px 2px, #C9C0B2 2px 3px);
  transform: rotateX(-62deg); transform-origin: top;
  box-shadow: 0 9px 16px rgba(45,37,27,.22);
}
.book:active { cursor: grabbing; }
.book .page {
  --turn: 0;
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  border-radius: 2px 7px 7px 2px;
}
.book .under { z-index: 0; }
.book .cur   { z-index: 1; }
.book .flip {
  z-index: 4; transform-origin: 9px center;
  will-change: transform, filter;
  filter: drop-shadow(calc(5px + var(--turn) * 8px) 7px calc(5px + var(--turn) * 7px) rgba(35,29,20,.28));
}

.face {
  position: absolute; inset: 0; overflow: hidden;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  background: #F5F2EC; border-radius: 2px 7px 7px 2px;
  box-shadow: inset 0 0 0 1px rgba(74,62,45,.07);
}
.face.front { transform: translateZ(.65px); }
.face.back {
  transform: rotateY(180deg) translateZ(.65px);
  background:
    radial-gradient(ellipse at 24% 45%, rgba(255,255,255,.55), transparent 48%),
    linear-gradient(105deg, #D8D0C2 0%, #F8F4EC 15%, #EFE8DC 67%, #D9D0C2 100%);
}
.face img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  opacity: 0; filter: blur(12px); transform: scale(1.045);
  transition: opacity .8s ease, filter .8s ease, transform 1.1s ease;
}
.face img.ld { opacity: 1; filter: blur(0); transform: scale(1); }
/* 书页正面右缘：纸页厚度感 */
.face.front::after {
  content: ''; position: absolute; top: 0; bottom: 0; right: 0; width: 10px;
  background: linear-gradient(270deg, rgba(28, 24, 16, .16), rgba(28, 24, 16, 0));
  pointer-events: none;
}
.flip .face.front::before {
  content: ''; position: absolute; z-index: 3; inset: 0; pointer-events: none;
  background: linear-gradient(90deg,
    rgba(22,18,13,calc(.12 + var(--turn) * .2)) 0%,
    rgba(255,255,255,calc(.06 + var(--turn) * .18)) 38%,
    rgba(26,21,15,calc(.04 + var(--turn) * .15)) 100%);
  mix-blend-mode: soft-light;
}
/* 翻页中页面的柔影 */
.face.back::before {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(90deg, rgba(29,23,16,.2), transparent 15%),
    linear-gradient(105deg, rgba(28,24,16,calc(.08 + var(--turn) * .2)), rgba(255,255,255,.14) 46%, rgba(28,24,16,.08));
  pointer-events: none;
}

/* 照片占位（未放真实照片时） */
.ph {
  width: 100%; height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
}
.ph svg { opacity: .8; }
.book .page:nth-child(4n+1) .ph { background: linear-gradient(160deg, #F7F4EF, #EDE8E0); }
.book .page:nth-child(4n+2) .ph { background: linear-gradient(160deg, #F5F3ED, #E9E4D9); }
.book .page:nth-child(4n+3) .ph { background: linear-gradient(160deg, #F6F4F0, #ECE8E1); }
.book .page:nth-child(4n+4) .ph { background: linear-gradient(160deg, #F8F5F0, #EFEAE2); }

.ph-cap {
  position: absolute; bottom: 12px; left: 50%; transform: translateX(-50%);
  max-width: 86%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: 12px; color: #3A362F;
  background: rgba(255, 255, 255, .8); backdrop-filter: blur(4px);
  border: 1px solid rgba(60, 52, 40, .08);
  padding: 4px 14px; border-radius: 999px;
}

.dots { display: flex; justify-content: center; gap: 6px; margin-top: 14px; }
.dot { width: 6px; height: 6px; border-radius: 999px; background: #DDD8CF; transition: all .35s ease; cursor: pointer; }
.dot.on { width: 20px; background: #1A1916; }
.gallery-tip { text-align: center; font-size: 11px; color: var(--mut); margin-top: 10px; letter-spacing: .12em; }

/* ============================================================
   ⑥ 出席回执
   ============================================================ */
.rsvp-lead { text-align: center; font-size: 14px; color: var(--mut); margin-bottom: 20px; letter-spacing: .06em; }

.field { display: block; margin-bottom: 15px; }
.field-k { display: block; font-size: 12.5px; margin-bottom: 7px; letter-spacing: .08em; }
.field-k i { font-style: normal; color: var(--gold-d); }
.field-k em { font-style: normal; font-size: 10.5px; color: var(--mut); }

.field input, .field select, .field textarea {
  width: 100%;
  font-family: var(--serif); font-size: 15px; color: var(--ink);
  background: #FCFBF9;
  border: 1px solid #E4E0D9; border-radius: 12px;
  padding: 10px 13px;
  transition: border-color .2s, box-shadow .2s;
  -webkit-appearance: none; appearance: none;
}
.field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23A89467' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center;
}
.field textarea { resize: none; line-height: 1.7; }
.field input::placeholder, .field textarea::placeholder { color: #C5C0B6; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: #1A1916;
  box-shadow: 0 0 0 3px rgba(26, 25, 22, .07);
}

.seg { display: flex; background: #F4F2EE; border: 1px solid var(--line); border-radius: 999px; padding: 3px; gap: 3px; }
.seg-btn {
  flex: 1; border: none; background: transparent; border-radius: 999px;
  padding: 9px 0; font-family: var(--serif); font-size: 14px; color: var(--mut);
  cursor: pointer; transition: all .25s ease; letter-spacing: .1em; text-indent: .1em;
}
.seg-btn.on {
  background: #1A1916; color: #F6F4EF;
  box-shadow: 0 4px 12px rgba(28, 26, 23, .22);
}

#countField.off { opacity: .35; pointer-events: none; }

.rsvp-stats { text-align: center; font-size: 12px; color: var(--mut); margin-top: 13px; letter-spacing: .05em; }

.rsvp-done { text-align: center; }
.done-script { font-family: var(--script); font-size: 38px; color: var(--gold-d); }
.done-zh { font-size: 15px; margin: 10px 0 20px; letter-spacing: .06em; }

/* ============================================================
   ⑦ 祝福墙
   ============================================================ */
.wish-wall { display: grid; gap: 12px; margin-bottom: 22px; }
.wish-row {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
}
.wish-track {
  display: flex; gap: 12px; width: max-content;
  animation: marq var(--dur, 42s) linear infinite;
}
.wish-track.rev { animation-direction: reverse; }
.wish-row:hover .wish-track { animation-play-state: paused; }
@keyframes marq { to { transform: translateX(-50%); } }

.wish-card {
  flex: none; max-width: 250px;
  background: linear-gradient(180deg, #FFFFFF, #FDFCF9);
  border: 1px solid var(--line); border-radius: 16px;
  padding: 11px 15px 12px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .8), 0 8px 22px rgba(60, 52, 40, .05);
}
.wish-name { font-size: 12.5px; color: var(--gold-d); margin-bottom: 4px; letter-spacing: .06em; }
.wish-name::before { content: '✦ '; color: var(--gold); font-size: 10px; }
.wish-msg { font-size: 13px; line-height: 1.65; word-break: break-all; }

.wish-form-wrap { text-align: center; }
.wish-form { margin-top: 14px; text-align: left; }

/* ============================================================
   ⑧ 温馨提示
   ============================================================ */
.tips { margin-top: 6px; }
.tip {
  display: flex; gap: 15px; align-items: flex-start;
  padding: 19px 2px;
  border-top: 1px solid var(--line);
}
.tip:last-child { border-bottom: 1px solid var(--line); }
.tip-ico {
  flex: none; width: 38px; height: 38px; border-radius: 50%;
  background: #FAF7F1; border: 1px solid #F0EBE1;
  display: flex; align-items: center; justify-content: center;
}
.tip-k { font-size: 13px; font-weight: 500; color: var(--ink); letter-spacing: .14em; margin-bottom: 6px; }
.tip-k span { font-size: 9px; color: var(--gold-d); letter-spacing: .24em; margin-left: 8px; font-weight: 400; }
.tip-t { font-size: 12.5px; color: var(--mut); line-height: 1.95; letter-spacing: .04em; }

/* ============================================================
   ⑨ 结尾
   ============================================================ */
.ending {
  padding: 74px 20px 96px; text-align: center;
  background: linear-gradient(180deg, transparent 0%, rgba(180, 155, 107, .05) 100%);
}
/* 结尾垂下一缕金线，收束全篇 */
.ending::before {
  content: ''; display: block; width: 1px; height: 44px;
  margin: 0 auto 28px;
  background: linear-gradient(180deg, transparent, rgba(180, 155, 107, .6));
}
.end-photo {
  width: 100%; margin: 4px 0 30px;
}
.end-photo img { display: block; width: 100%; aspect-ratio: 2 / 3; object-fit: cover; cursor: zoom-in; }
.end-script { font-family: var(--script); font-size: 42px; color: var(--gold-d); }
.end-zh { font-size: 15px; letter-spacing: .32em; text-indent: .32em; margin-top: 12px; }
.end-mono { font-size: 18px; color: var(--gold-d); letter-spacing: .3em; text-indent: .3em; margin-top: 22px; }
.end-date { font-size: 12px; color: var(--mut); letter-spacing: .35em; text-indent: .35em; margin-top: 7px; }

/* ============================================================
   放大查看 / 轻提示
   ============================================================ */
#lightbox {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(28, 26, 23, .88);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  display: flex; align-items: center; justify-content: center;
  cursor: zoom-out;
  animation: lbIn .3s ease;
}
#lightbox img {
  max-width: 94vw; max-height: 88vh; border-radius: 12px;
  box-shadow: 0 30px 80px rgba(20, 18, 15, .5);
  animation: lbZoom .38s cubic-bezier(.22, .61, .36, 1);
}
@keyframes lbIn { from { opacity: 0; } }
@keyframes lbZoom { from { transform: scale(.93); opacity: .35; } }

#toast {
  position: fixed; left: 50%; bottom: 44px; transform: translateX(-50%);
  z-index: 99; max-width: 82vw;
  background: rgba(28, 26, 23, .92); color: #F6F4EF;
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  font-size: 13px; letter-spacing: .05em;
  padding: 10px 20px; border-radius: 999px;
  box-shadow: 0 10px 26px rgba(28, 26, 23, .3);
  text-align: center;
  opacity: 0; pointer-events: none;
  transition: opacity .3s ease, transform .3s ease;
}
#toast.show { opacity: 1; transform: translateX(-50%) translateY(-4px); }

/* ============================================================
   歌词条（跟音乐同步逐句显示）
   ============================================================ */
#lyricBar {
  position: fixed; left: 50%; bottom: calc(20px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 60; max-width: 80vw;
  background: rgba(255, 255, 255, .85);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid rgba(60, 52, 40, .08);
  color: #4A463F;
  font-size: 13px; letter-spacing: .12em;
  padding: 8px 20px; border-radius: 999px;
  box-shadow: 0 6px 20px rgba(60, 52, 40, .12);
  text-align: center; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  opacity: 0; pointer-events: none;
  transition: opacity .5s ease;
}
#lyricBar.show { opacity: 1; }

/* ============================================================
   歌词小舞台：乐队踩在歌词条上沿，不再遮挡正文和表单
   ============================================================ */
#bandScene {
  position: fixed; left: 14px; right: auto;
  bottom: calc(17px + env(safe-area-inset-bottom));
  width: 78px; height: 45px; z-index: 61; pointer-events: none;
  opacity: 0; transform: translateY(8px);
  transition: opacity .6s ease, transform .6s ease;
}
#bandScene::after {
  display: none;
}
#bandScene.show { opacity: .92; transform: translateY(0); }
.band-left {
  position: absolute; left: 2px; bottom: 0;
  display: flex; align-items: flex-end;
  transform: scale(.56); transform-origin: left bottom;
}
.band-dance {
  display: none;
}
@media (max-width: 359px) {
  #bandScene { left: 10px; width: 72px; }
  .band-left { transform: scale(.51); }
}

/* --- 立体双人芭蕾：屈膝蓄力、双人腾跃、转圈、阿拉贝斯克、下腰谢幕 --- */
#bandScene .couple {
  transform-box: view-box; transform-origin: 73px 101px;
  animation: balletPhrase 7.2s cubic-bezier(.42,0,.3,1) infinite;
}
@keyframes balletPhrase {
  0%,100% { transform: translate(0,0) rotate(0); }
  10% { transform: translate(0,4px) scaleY(.95); }
  21% { transform: translate(0,-14px) scaleY(1.025); }
  28% { transform: translate(1px,-18px) scaleY(1.02); }
  36% { transform: translate(0,1px) scaleY(.97); }
  49% { transform: translate(-2px,-5px) rotate(-1deg); }
  60% { transform: translate(2px,-13px) rotate(1deg); }
  67% { transform: translate(2px,-16px) rotate(1deg); }
  75% { transform: translate(0,0) scaleY(.97); }
  87% { transform: translate(-1px,2px) rotate(-3deg); }
  95% { transform: translate(0,-5px) scaleY(1.02); }
}
#bandScene .fig-m {
  transform-box: view-box; transform-origin: 40px 100px;
  animation: danseurBallet 7.2s ease-in-out infinite;
}
@keyframes danseurBallet {
  0%,100% { transform: translate(0,0) rotate(0); }
  10% { transform: translate(0,3px) rotate(-4deg); }
  21% { transform: translate(-4px,-1px) rotate(-7deg); }
  28% { transform: translate(-7px,-3px) rotate(-10deg); }
  36% { transform: translate(-2px,2px) rotate(3deg); }
  49% { transform: translate(3px,-2px) rotate(8deg); }
  60% { transform: translate(6px,-2px) rotate(10deg); }
  67% { transform: translate(8px,-3px) rotate(12deg); }
  75% { transform: translate(2px,1px) rotate(-3deg); }
  87% { transform: translate(8px,3px) rotate(15deg); }
  95% { transform: translate(1px,-3px) rotate(-2deg); }
}
#bandScene .fig-w {
  transform-box: view-box; transform-origin: 101px 101px;
  animation: ballerinaTurn 7.2s ease-in-out infinite;
}
@keyframes ballerinaTurn {
  0%,10%,100% { transform: translate(0,0) rotate(0) scaleX(1); }
  21% { transform: translate(5px,-2px) rotate(7deg) scaleX(1); }
  28% { transform: translate(9px,-4px) rotate(10deg) scaleX(1); }
  36% { transform: translate(2px,2px) rotate(-3deg) scaleX(1); }
  45% { transform: translate(0,-3px) rotate(-2deg) scaleX(.55); }
  51% { transform: translate(0,-6px) rotate(1deg) scaleX(.12); }
  57% { transform: translate(1px,-7px) rotate(2deg) scaleX(-.78); }
  63% { transform: translate(1px,-5px) rotate(-1deg) scaleX(-.12); }
  70% { transform: translate(0,-2px) rotate(-3deg) scaleX(1); }
  78% { transform: translate(-4px,-2px) rotate(-11deg) scaleX(1); }
  87% { transform: translate(-9px,5px) rotate(-25deg) scaleX(1); }
  95% { transform: translate(-2px,-4px) rotate(4deg) scaleX(1); }
}
#bandScene .leg-kick {
  transform-box: view-box; transform-origin: 45px 55px;
  animation: danseurTendu 7.2s ease-in-out infinite;
}
@keyframes danseurTendu {
  0%,10%,38%,48%,76%,100% { transform: rotate(0); }
  21%,28% { transform: rotate(-66deg) translateY(-2px); }
  34% { transform: rotate(-22deg); }
  60%,67% { transform: rotate(-52deg) translateY(-2px); }
  72% { transform: rotate(-15deg); }
  87% { transform: rotate(10deg); }
}
#bandScene .leg-w {
  transform-box: view-box; transform-origin: 105px 58px;
  animation: ballerinaArabesque 7.2s ease-in-out infinite;
}
@keyframes ballerinaArabesque {
  0%,10%,38%,48%,74%,100% { transform: rotate(0); }
  21%,28% { transform: rotate(-72deg) translateY(-2px); }
  34% { transform: rotate(-20deg); }
  60%,67% { transform: rotate(-58deg) translateY(-2px); }
  78% { transform: rotate(-66deg) translateY(-2px); }
  87% { transform: rotate(-78deg) translateY(-3px); }
  95% { transform: rotate(-10deg); }
}
#bandScene .leg-kick-hi { transform-box: view-box; transform-origin: 45px 55px; animation: danseurTendu 7.2s ease-in-out infinite; }
#bandScene .leg-w-hi { transform-box: view-box; transform-origin: 105px 58px; animation: ballerinaArabesque 7.2s ease-in-out infinite; }
#bandScene .leg-m-base, #bandScene .leg-m-base-hi,
#bandScene .leg-w-base, #bandScene .leg-w-base-hi { transform-box: view-box; animation: pointeRise 7.2s ease-in-out infinite; }
@keyframes pointeRise { 0%,100% { transform: translateY(0); } 18%,30%,48%,70%,95% { transform: translateY(-3px); } 10%,36%,75%,87% { transform: translateY(1px); } }
#bandScene .skirt { transform-box: view-box; transform-origin: 101px 49px; animation: tutuSpin 7.2s ease-in-out infinite; }
@keyframes tutuSpin { 0%,18%,38%,74%,100% { transform: scaleX(1); } 24%,65% { transform: scaleX(1.22) rotate(-3deg); } 48% { transform: scaleX(.48); } 57% { transform: scaleX(1.32); } 63% { transform: scaleX(.4); } 87% { transform: scaleX(1.13) rotate(7deg); } }
#bandScene .arm-up-m { transform-box: view-box; transform-origin: 46px 31px; animation: balletArmM 7.2s ease-in-out infinite; }
@keyframes balletArmM { 0%,100% { transform: rotate(8deg); } 10% { transform: rotate(20deg); } 21%,28% { transform: rotate(-35deg); } 49% { transform: rotate(-12deg); } 60%,67% { transform: rotate(-40deg); } 87% { transform: rotate(22deg); } }
#bandScene .m-arm-front { transform-box: view-box; transform-origin: 47px 35px; animation: balletArmFrontM 7.2s ease-in-out infinite; }
@keyframes balletArmFrontM { 0%,100% { transform: rotate(0); } 21%,28% { transform: rotate(28deg); } 60%,67% { transform: rotate(-18deg); } 87% { transform: rotate(25deg); } }
#bandScene .m-arm-back { transform-box: view-box; transform-origin: 35px 34px; animation: balletArmBackM 7.2s ease-in-out infinite; }
@keyframes balletArmBackM { 0%,100% { transform: rotate(0); } 21%,28% { transform: rotate(-24deg); } 60%,67% { transform: rotate(22deg); } 87% { transform: rotate(-10deg); } }
#bandScene .arm-up-w { transform-box: view-box; transform-origin: 104px 30px; animation: balletArmW 7.2s ease-in-out infinite; }
@keyframes balletArmW { 0%,100% { transform: rotate(-8deg); } 21%,28% { transform: rotate(30deg); } 49% { transform: rotate(52deg); } 60%,67% { transform: rotate(-36deg); } 78% { transform: rotate(20deg); } 87% { transform: rotate(-24deg); } }
#bandScene .w-arm-front { transform-box: view-box; transform-origin: 97px 31px; animation: balletArmFrontW 7.2s ease-in-out infinite; }
@keyframes balletArmFrontW { 0%,100% { transform: rotate(0); } 21%,28% { transform: rotate(-30deg); } 49% { transform: rotate(18deg); } 60%,67% { transform: rotate(25deg); } 87% { transform: rotate(-15deg); } }
#bandScene .w-arm-back { transform-box: view-box; transform-origin: 101px 32px; animation: balletArmBackW 7.2s ease-in-out infinite; }
@keyframes balletArmBackW { 0%,100% { transform: rotate(0); } 21%,28% { transform: rotate(25deg); } 60%,67% { transform: rotate(-28deg); } 87% { transform: rotate(18deg); } }
#bandScene .dancer-shadow { transform-box: fill-box; transform-origin: center; animation: dancerShadow 7.2s ease-in-out infinite; }
@keyframes dancerShadow { 0%,10%,36%,75%,100% { transform: scale(1); opacity: .18; } 21%,28%,60%,67% { transform: scale(.56); opacity: .07; } }

/* --- 钢琴师：双手交替按键 + 颔首 --- */
#bandScene .p-hands { transform-box: view-box; transform-origin: 21px 27px; animation: pPlay .42s ease-in-out infinite alternate; }
@keyframes pPlay { from { transform: rotate(-4deg); } to { transform: rotate(5deg); } }
#bandScene .p-head { transform-box: view-box; animation: pNod .84s ease-in-out infinite; }
@keyframes pNod { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(.9px); } }

/* --- 小提琴手：弓来回推拉 + 身体轻摆 --- */
#bandScene .v-bow { transform-box: view-box; animation: bowMove .62s ease-in-out infinite alternate; }
@keyframes bowMove { from { transform: translate(-3.4px, -2.2px); } to { transform: translate(3.4px, 2.2px); } }
#bandScene .fig-v { transform-box: view-box; transform-origin: 18px 68px; animation: swayV 1.24s ease-in-out infinite; }
@keyframes swayV { 0%, 100% { transform: rotate(2.4deg); } 50% { transform: rotate(-2.4deg); } }

/* ============================================================
   动效减弱
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .petal, .petal::before, .veil-petals i, .veil-breeze, .wish-track, #musicBtn.playing .disc, .scroll-hint, #veil::before { animation: none !important; }
  .envelope, .env-flap, .env-hint, .env-seal, .letter, .letter .ch, .pen { transition: none !important; }
  /* 白鸽送信降级：不飞，信封直接在场可点 */
  .dove { display: none; }
  .veil-mail { animation: none; opacity: 1; }
  .veil-mail::after { animation: none; opacity: .3; }
  .mail-ripple { animation: none; opacity: 0; }
  .veil-mail-hint, .veil-music-hint { animation: none; opacity: .92; }
  .veil-inner, .veil-inner > * { animation: none !important; opacity: 1; clip-path: none; }
  .love-story *, .love-story *::before, .love-story *::after { animation: none !important; transition: none !important; }
  .love-scene { opacity: .2; }
  .story-person { opacity: .35; transform: none; }
  .meeting-line, .heart-line { stroke-dashoffset: 0; }
  .story-copy { display: none; }
  .story-finale { opacity: 1; transform: none; top: 48%; }
  .love-claim { opacity: 1; transform: translate(-50%,0); }
  .love-music-note { opacity: .8; }
  .petal { opacity: .4; }
  .reveal { transition: none; opacity: 1; transform: none; }
  .face img { transition: none; opacity: 1; filter: none; transform: none; }
  #lightbox, #lightbox img { animation: none; }
  /* 倒计时滚动数字降级：直接切换 */
  .cd-cell b span.in, .cd-cell b span.out { animation: none !important; }
  .cd-cell b span.out { display: none; }
  /* 书页翻动降级：瞬时换页 */
  .book .flip, .book .page { transition: none !important; }
  /* 乐队小黑人降级：静态剪影 */
  #bandScene .couple, #bandScene .fig-m, #bandScene .fig-w, #bandScene .skirt,
  #bandScene .arm-up-m, #bandScene .arm-up-w, #bandScene .m-arm-front, #bandScene .m-arm-back,
  #bandScene .w-arm-front, #bandScene .w-arm-back, #bandScene .dancer-shadow,
  #bandScene .p-hands, #bandScene .p-head, #bandScene .leg-m-base, #bandScene .leg-m-base-hi,
  #bandScene .leg-w-base, #bandScene .leg-w-base-hi, #bandScene .leg-kick, #bandScene .leg-kick-hi,
  #bandScene .leg-w, #bandScene .leg-w-hi,
  #bandScene .v-bow, #bandScene .fig-v { animation: none !important; }
}

/* ============================================================
   双向奔赴 · 高质感卡通角色八帧动画
   ============================================================ */
#veil > .cinematic-love { display:none!important; }
#veil { background:#2a1c35; }
#veil::before {
  background:linear-gradient(160deg,#24162d 0%,#5a3450 44%,#d98975 100%);
  animation:none;
}
#veil::after { z-index:4; background:radial-gradient(ellipse at center,transparent 45%,rgba(20,12,24,.34) 118%); }

.cartoon-love { z-index:3; color:#fffaf3; background:#33213d; text-align:center; }
.cartoon-loading { position:absolute; inset:0; z-index:20; display:grid; place-items:center; padding:28px; background:rgba(35,19,39,.58); -webkit-backdrop-filter:blur(12px); backdrop-filter:blur(12px); opacity:1; visibility:visible; transition:opacity .5s ease,visibility .5s ease; }
#veil.story-loaded .cartoon-loading { opacity:0; visibility:hidden; pointer-events:none; }
.cartoon-loading-card { width:min(78vw,300px); padding:30px 25px 24px; border:1px solid rgba(255,226,174,.38); border-radius:15px; background:linear-gradient(145deg,rgba(48,27,49,.88),rgba(80,42,57,.76)); box-shadow:inset 0 1px 0 rgba(255,255,255,.12),0 24px 60px rgba(20,10,24,.42); }
.cartoon-loading-ring { position:relative; display:block; width:52px; height:52px; margin:0 auto 18px; border:1px solid rgba(255,225,175,.22); border-radius:50%; }
.cartoon-loading-ring::before { content:'♥'; position:absolute; inset:0; display:grid; place-items:center; color:#ffe0a6; font-size:17px; text-shadow:0 0 12px rgba(255,202,126,.5); }
.cartoon-loading-ring i { position:absolute; inset:-1px; border:1.5px solid transparent; border-top-color:#ffd999; border-right-color:rgba(255,217,153,.45); border-radius:50%; animation:cartoonLoadingSpin 1.05s linear infinite; }
@keyframes cartoonLoadingSpin { to{transform:rotate(360deg)} }
.cartoon-loading-card p { margin:0 0 10px; font-family:'Songti SC','STSong',var(--serif); font-size:17px; letter-spacing:.13em; }
.cartoon-loading-card strong { display:block; color:#ffdda2; font-size:11px; font-weight:400; letter-spacing:.16em; }
.cartoon-loading-card small { display:block; margin-top:8px; color:rgba(255,244,226,.7); font-size:9px; letter-spacing:.08em; }
.cartoon-load-track { display:block; width:100%; height:2px; margin-top:20px; overflow:hidden; border-radius:2px; background:rgba(255,255,255,.13); }
.cartoon-load-track i { display:block; width:0; height:100%; border-radius:inherit; background:linear-gradient(90deg,#bd7c68,#ffe09c); box-shadow:0 0 10px rgba(255,210,137,.48); transition:width .22s ease; }
.cartoon-loading.is-ready .cartoon-loading-ring i { animation-duration:.42s; }
.cartoon-movie,.cartoon-frame { position:absolute; inset:0; }
.cartoon-movie { overflow:hidden; background:#2b1a33; }
.cartoon-frame { z-index:0; margin:0; overflow:hidden; opacity:0; will-change:opacity,transform; }
.cartoon-frame::before { content:''; position:absolute; inset:-30px; z-index:0; background-image:var(--frame); background-size:cover; background-position:center; filter:blur(22px) saturate(.92) brightness(.72); transform:scale(1.14); }
.cartoon-frame img { position:absolute; inset:0; z-index:1; width:100%; height:100%; object-fit:contain; object-position:center; filter:saturate(1.03) contrast(1.02) drop-shadow(0 10px 20px rgba(26,13,25,.22)); transform:scale(1.002); }
.cartoon-frame-1 { opacity:1; }
#veil.story-playing .cartoon-frame-1 { animation:cartoonFirstFrame .98s ease .05s both; }
#veil.story-playing .cartoon-frame-2,
#veil.story-playing .cartoon-frame-3,
#veil.story-playing .cartoon-frame-4,
#veil.story-playing .cartoon-frame-5,
#veil.story-playing .cartoon-frame-6,
#veil.story-playing .cartoon-frame-7 { animation:cartoonMiddleFrame .98s ease var(--delay) both; }
#veil.story-playing .cartoon-frame-8 { animation:cartoonLastFrame 1.02s ease var(--delay) forwards; }
@keyframes cartoonFirstFrame { 0%,72%{opacity:1;transform:scale(1.01)}100%{opacity:0;transform:scale(1.025)} }
@keyframes cartoonMiddleFrame { 0%{opacity:0;transform:scale(1.025)}16%,78%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(1.012)} }
@keyframes cartoonLastFrame { 0%{opacity:0;transform:scale(1.02)}22%,100%{opacity:1;transform:scale(1)} }
.cartoon-vignette { position:absolute; inset:0; z-index:2; pointer-events:none; background:linear-gradient(180deg,rgba(27,14,30,.52) 0%,transparent 25%,transparent 64%,rgba(25,13,27,.48) 100%),linear-gradient(90deg,rgba(25,13,29,.2),transparent 22%,transparent 78%,rgba(25,13,29,.2)); }

.cartoon-story-copy { position:absolute; z-index:6; left:22px; right:22px; top:7%; height:110px; pointer-events:none; }
.cartoon-line { position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; margin:0; opacity:0; transform:translateY(12px); filter:blur(6px); text-shadow:0 3px 18px rgba(33,15,30,.82); }
.cartoon-line small { margin-bottom:11px; color:#ffe1a6; font-size:8px; letter-spacing:.46em; text-indent:.46em; }
.cartoon-line strong { font-family:'Songti SC','STSong',var(--serif); font-size:21px; line-height:1.45; font-weight:400; letter-spacing:.15em; text-indent:.15em; }
#veil.story-playing .cartoon-line-1 { animation:cartoonSentence 2.15s ease .18s both; }
#veil.story-playing .cartoon-line-2 { animation:cartoonSentence 2.15s ease 2s both; }
#veil.story-playing .cartoon-line-3 { animation:cartoonSentence 2.15s ease 3.82s both; }
@keyframes cartoonSentence { 0%{opacity:0;transform:translateY(12px);filter:blur(6px)}18%,75%{opacity:1;transform:none;filter:blur(0)}100%{opacity:0;transform:translateY(-8px);filter:blur(4px)} }

.cartoon-finale { position:absolute; z-index:7; left:18px; right:18px; top:5.8%; opacity:0; transform:translateY(14px); filter:blur(5px); text-shadow:0 3px 18px rgba(34,16,29,.85); }
#veil.story-playing .cartoon-finale { animation:cartoonFinaleIn 1.05s cubic-bezier(.18,.76,.22,1) 5.58s forwards; }
@keyframes cartoonFinaleIn { to{opacity:1;transform:none;filter:blur(0)} }
.cartoon-finale p { margin:0 0 9px; color:#ffe0a0; font-size:8px; letter-spacing:.42em; text-indent:.42em; }
.cartoon-finale h1 { display:flex; justify-content:center; align-items:center; gap:11px; margin:0; font-family:'Songti SC','STSong',var(--serif); font-size:25px; line-height:1.1; font-weight:400; letter-spacing:.1em; }
.cartoon-finale h1 i { color:#ffe0a0; font-family:var(--script); font-size:28px; font-weight:400; }
.cartoon-finale > strong { display:block; margin-top:9px; color:#ffe4ae; font-size:10px; font-weight:400; letter-spacing:.36em; }

.cartoon-claim { position:absolute; z-index:8; left:50%; bottom:max(48px,calc(34px + env(safe-area-inset-bottom))); width:min(78vw,304px); height:82px; padding:0 58px 0 23px; overflow:hidden; border:1px solid rgba(255,231,186,.86); border-radius:9px; color:#4b2a2c; text-align:left; cursor:pointer; opacity:0; transform:translate(-50%,26px) perspective(700px) rotateX(13deg) scale(.94); background:linear-gradient(135deg,rgba(255,253,245,.98),rgba(244,218,179,.97) 60%,rgba(213,163,111,.97)); box-shadow:inset 0 1px 0 rgba(255,255,255,.96),inset 0 -1px 0 rgba(119,65,43,.2),0 23px 48px rgba(36,16,30,.43),0 4px 12px rgba(36,16,30,.26); -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px); -webkit-tap-highlight-color:transparent; }
.cartoon-claim::before { content:''; position:absolute; inset:5px; border:1px solid rgba(116,66,44,.18); border-radius:5px; pointer-events:none; }
#veil.story-playing .cartoon-claim { animation:cartoonClaimIn .95s cubic-bezier(.17,.82,.23,1) 6.27s forwards; }
@keyframes cartoonClaimIn { 0%{opacity:0;transform:translate(-50%,26px) perspective(700px) rotateX(13deg) scale(.94)}70%{opacity:1;transform:translate(-50%,-3px) perspective(700px) rotateX(-2deg) scale(1.012)}100%{opacity:1;transform:translate(-50%,0) perspective(700px) rotateX(0) scale(1)} }
.cartoon-claim-text { position:relative; z-index:2; display:flex; height:100%; flex-direction:column; justify-content:center; }
.cartoon-claim-text small { margin-bottom:6px; color:#a16c45; font-size:7px; letter-spacing:.28em; }
.cartoon-claim-text strong { font-family:'Songti SC','STSong',var(--serif); font-size:18px; font-weight:400; letter-spacing:.21em; }
.cartoon-claim-arrow { position:absolute; z-index:2; right:23px; top:50%; width:32px; height:32px; margin-top:-16px; display:grid; place-items:center; border-radius:50%; color:#fff4da; font-size:21px; background:linear-gradient(145deg,#c9865d,#7e4350); box-shadow:inset 0 1px 2px rgba(255,255,255,.42),0 4px 9px rgba(76,39,42,.26); }
.cartoon-claim-shine { position:absolute; z-index:1; top:-60%; bottom:-60%; left:-40%; width:28%; background:linear-gradient(90deg,transparent,rgba(255,255,255,.76),transparent); transform:skewX(-18deg); }
#veil.story-ready .cartoon-claim-shine { animation:cartoonClaimShine 2.7s ease infinite; }
@keyframes cartoonClaimShine { 0%,58%{left:-40%}84%,100%{left:126%} }
.cartoon-claim:not(:disabled):active { transform:translate(-50%,2px) scale(.975); }
#veil.story-ready .cartoon-claim { border-color:#ffe3ad; box-shadow:inset 0 1px 0 rgba(255,255,255,.98),0 0 0 1px rgba(255,224,162,.2),0 24px 52px rgba(36,16,30,.46),0 0 30px rgba(255,205,132,.18); }
.cartoon-music-note { position:absolute; z-index:8; left:0; right:0; bottom:max(20px,calc(10px + env(safe-area-inset-bottom))); margin:0; color:#fff0d4; font-size:9px; letter-spacing:.14em; opacity:0; text-shadow:0 2px 10px rgba(36,16,30,.7); }
#veil.story-playing .cartoon-music-note { animation:cartoonNoteIn .6s ease 6.75s forwards; }
@keyframes cartoonNoteIn { to{opacity:.82} }

@media (max-height:700px) {
  .cartoon-story-copy { top:4%; }
  .cartoon-finale { top:3.5%; }
  .cartoon-line strong { font-size:19px; }
  .cartoon-claim { bottom:max(30px,calc(20px + env(safe-area-inset-bottom))); height:72px; }
  .cartoon-music-note { display:none; }
}
@media (max-width:360px) {
  .cartoon-line strong { font-size:19px; }
  .cartoon-finale h1 { font-size:22px; gap:8px; }
  .cartoon-claim { width:286px; }
}
@media (prefers-reduced-motion:reduce) {
  .cartoon-frame { display:none; opacity:0; }
  .cartoon-frame-8 { display:block; opacity:1; transform:none; }
  .cartoon-story-copy { display:none; }
  .cartoon-finale { opacity:1; transform:none; filter:none; }
  .cartoon-claim { opacity:1; transform:translate(-50%,0); }
  .cartoon-music-note { opacity:.82; }
}

/* 连续角色精灵动画：四姿势循环 + 双向位移，不再逐张播放整页图片 */
.runner-movie { position:absolute; inset:0; z-index:0; overflow:hidden; background:#65455f; }
.runner-background { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:center; transform:scale(1.035); filter:saturate(.96) contrast(1.02); }
#veil.story-playing .runner-background { animation:runnerGardenPush 7.2s cubic-bezier(.2,.65,.25,1) forwards; }
@keyframes runnerGardenPush { from{transform:scale(1.055)}to{transform:scale(1.015)} }
.runner-glow { position:absolute; z-index:1; left:50%; top:52%; width:min(92vw,430px); height:42%; transform:translate(-50%,-50%); border-radius:50%; background:radial-gradient(ellipse,rgba(255,232,183,.22),transparent 70%); filter:blur(18px); pointer-events:none; }
.runner-preload { position:absolute!important; width:1px!important; height:1px!important; left:-10px!important; top:-10px!important; opacity:.001; pointer-events:none; }

.runner { position:absolute; z-index:3; left:50%; top:43%; width:min(48vw,190px); aspect-ratio:3/4; opacity:0; will-change:transform,opacity; filter:drop-shadow(0 11px 13px rgba(47,25,39,.26)); }
.runner-sprite { position:absolute; inset:0; display:block; background-repeat:no-repeat; background-size:400% 100%; background-position:0 0; will-change:background-position,transform; }
.runner-groom .runner-sprite { background-image:url('assets/cartoon-groom-run-v1.webp'); }
.runner-bride { width:min(50vw,198px); }
.runner-bride .runner-sprite { background-image:url('assets/cartoon-bride-run-v1.webp'); }
.runner-shadow { position:absolute; z-index:-1; left:22%; right:18%; bottom:1.5%; height:5%; border-radius:50%; background:rgba(74,42,51,.25); filter:blur(5px); transform:scaleX(.75); }
#veil.story-playing .runner-sprite { animation:runnerStep .56s linear infinite,runnerBodyBounce .28s ease-in-out infinite alternate; }
@keyframes runnerStep {
  0%,24.99%{background-position:0 0}
  25%,49.99%{background-position:33.333% 0}
  50%,74.99%{background-position:66.667% 0}
  75%,100%{background-position:100% 0}
}
@keyframes runnerBodyBounce { from{transform:translateY(1.5px) rotate(-.35deg)}to{transform:translateY(-2px) rotate(.35deg)} }

.runner-groom { transform:translate3d(calc(-50vw - 112%),34px,0) scale(.58); transform-origin:50% 100%; }
.runner-bride { transform:translate3d(calc(50vw + 12%),34px,0) scale(.58); transform-origin:50% 100%; }
#veil.story-playing .runner-groom { animation:groomRunsToLove 5.12s cubic-bezier(.2,.68,.24,1) .18s forwards; }
#veil.story-playing .runner-bride { animation:brideRunsToLove 5.12s cubic-bezier(.2,.68,.24,1) .3s forwards; }
@keyframes groomRunsToLove {
  0%{opacity:0;transform:translate3d(calc(-50vw - 112%),34px,0) scale(.58)}
  8%{opacity:1}
  26%{transform:translate3d(calc(-50vw - 36%),18px,0) scale(.73)}
  54%{transform:translate3d(-145%,6px,0) scale(.9)}
  76%,88%{opacity:1;transform:translate3d(-92%,0,0) scale(1)}
  100%{opacity:0;transform:translate3d(-88%,0,0) scale(1.015)}
}
@keyframes brideRunsToLove {
  0%{opacity:0;transform:translate3d(calc(50vw + 12%),34px,0) scale(.58)}
  8%{opacity:1}
  26%{transform:translate3d(calc(50vw - 35%),18px,0) scale(.73)}
  54%{transform:translate3d(45%,6px,0) scale(.9)}
  76%,88%{opacity:1;transform:translate3d(-8%,0,0) scale(1)}
  100%{opacity:0;transform:translate3d(-12%,0,0) scale(1.015)}
}

.runner-final { position:absolute; inset:0; z-index:4; overflow:hidden; opacity:0; transform:scale(1.025); will-change:opacity,transform; }
.runner-final::before { content:''; position:absolute; inset:-28px; z-index:0; background-image:var(--final); background-size:cover; background-position:center; filter:blur(22px) saturate(.9) brightness(.76); transform:scale(1.12); }
.runner-final img { position:absolute; inset:0; z-index:1; width:100%; height:100%; object-fit:contain; object-position:center; filter:saturate(1.03) contrast(1.02); }
#veil.story-playing .runner-final { animation:runnerFinalReveal 1.08s ease 4.85s forwards; }
@keyframes runnerFinalReveal { 0%{opacity:0;transform:scale(1.025)}100%{opacity:1;transform:scale(1)} }

@media (max-height:700px) {
  .runner { top:40%; width:min(43vw,164px); }
  .runner-bride { width:min(46vw,174px); }
}
@media (prefers-reduced-motion:reduce) {
  .runner,.runner-background { animation:none!important; }
  .runner { display:none; }
  .runner-final { opacity:1; transform:none; }
}

/* v28 · 高帧动作版：8 + 8 帧奔跑，12 帧从西装内袋取出邀请函 */
.runner-sprite {
  background-size:800% 100%;
  image-rendering:auto;
}
.runner-groom .runner-sprite { background-image:url('assets/cartoon-groom-run-v2.webp'); }
.runner-bride .runner-sprite { background-image:url('assets/cartoon-bride-run-v2.webp'); }
#veil.story-playing .runner-sprite {
  animation:runnerStep8 .64s linear infinite,runnerBodyBounce .32s ease-in-out infinite alternate;
}
@keyframes runnerStep8 {
  0%,12.49%{background-position:0 0}
  12.5%,24.99%{background-position:14.2857% 0}
  25%,37.49%{background-position:28.5714% 0}
  37.5%,49.99%{background-position:42.8571% 0}
  50%,62.49%{background-position:57.1429% 0}
  62.5%,74.99%{background-position:71.4286% 0}
  75%,87.49%{background-position:85.7143% 0}
  87.5%,100%{background-position:100% 0}
}

#veil.story-playing .runner-groom {
  animation:groomRunsToLove 4.28s cubic-bezier(.2,.68,.24,1) .18s forwards;
}
#veil.story-playing .runner-bride {
  animation:brideRunsToLove 4.28s cubic-bezier(.2,.68,.24,1) .28s forwards;
}

.runner-pocket {
  position:absolute;
  z-index:4;
  left:50%;
  top:0;
  bottom:0;
  width:min(100vw,39.4vh);
  opacity:0;
  transform:translateX(-50%) scale(1.015);
  transform-origin:52% 58%;
  background:url('assets/cartoon-pocket-invite-v1.webp') 0 0 / 1200% 100% no-repeat;
  filter:saturate(1.04) contrast(1.025) drop-shadow(0 0 24px rgba(38,18,37,.28));
  box-shadow:inset 18px 0 24px -20px rgba(25,12,29,.8),inset -18px 0 24px -20px rgba(25,12,29,.8);
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 3.2%,#000 96.8%,transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 3.2%,#000 96.8%,transparent 100%);
  will-change:background-position,opacity,transform;
}
#veil.story-playing .runner-pocket {
  animation:runnerPocketReveal .42s ease 4.14s forwards,
            runnerPocketFrames 3.05s steps(11,end) 4.34s forwards,
            runnerPocketBreath 3.05s cubic-bezier(.2,.62,.26,1) 4.34s both;
}
@keyframes runnerPocketReveal {
  from{opacity:0;filter:saturate(.94) contrast(1.01) blur(2px) drop-shadow(0 0 24px rgba(38,18,37,.2))}
  to{opacity:1;filter:saturate(1.04) contrast(1.025) blur(0) drop-shadow(0 0 24px rgba(38,18,37,.28))}
}
@keyframes runnerPocketFrames {
  from{background-position:0 0}
  to{background-position:100% 0}
}
@keyframes runnerPocketBreath {
  from{transform:translateX(-50%) scale(1.015)}
  to{transform:translateX(-50%) scale(1.035)}
}

.runner-final { display:none!important; }
#veil.story-playing .cartoon-line-1 { animation:cartoonSentence 2.08s ease .18s both; }
#veil.story-playing .cartoon-line-2 { animation:cartoonSentence 2.08s ease 1.82s both; }
#veil.story-playing .cartoon-line-3 { animation:cartoonSentence 2.08s ease 3.36s both; }
#veil.story-playing .cartoon-line-4 { animation:cartoonSentence 2.2s ease 5.25s both; }
#veil.story-playing .cartoon-finale {
  animation:cartoonFinaleIn 1.05s cubic-bezier(.18,.76,.22,1) 7.38s forwards;
}
#veil.story-playing .cartoon-claim {
  animation:pocketClaimIn 1.12s cubic-bezier(.16,.82,.2,1) 7.72s forwards;
}
@keyframes pocketClaimIn {
  0%{opacity:0;transform:translate(-50%,-31vh) perspective(760px) rotateX(17deg) rotateZ(-2deg) scale(.12)}
  58%{opacity:1;transform:translate(-50%,-7px) perspective(760px) rotateX(-3deg) rotateZ(.35deg) scale(1.025)}
  100%{opacity:1;transform:translate(-50%,0) perspective(760px) rotateX(0) rotateZ(0) scale(1)}
}
#veil.story-playing .cartoon-music-note { animation:cartoonNoteIn .6s ease 8.38s forwards; }

@media (prefers-reduced-motion:reduce) {
  .runner-pocket {
    opacity:1;
    transform:translateX(-50%);
    background-position:100% 0;
    animation:none!important;
  }
}

/* v29 · 预渲染 90fps 电影封面：整段缓冲后仅做视频解码，不再实时拼帧 */
.film-poster-preload {
  position:absolute;
  inset:0;
  z-index:0;
  width:100%;
  height:100%;
  object-fit:cover;
  object-position:center;
  filter:saturate(1.02) contrast(1.02);
}
.love-story-film {
  position:absolute;
  inset:0;
  z-index:1;
  display:block;
  width:100%;
  height:100%;
  border:0;
  object-fit:cover;
  object-position:center;
  opacity:0;
  background:#39243f;
  transform:translateZ(0);
  backface-visibility:hidden;
  transition:opacity .42s ease;
  will-change:opacity;
}
#veil.story-playing .love-story-film { opacity:1; }
.runner-glow,.runner,.runner-pocket,.runner-preload,.runner-background { display:none!important; }

@media (max-width:360px) {
  .cartoon-loading-card strong { font-size:10px; letter-spacing:.1em; }
}

/* v30 · 双人同框递邀请函，删除奔跑段后重新压缩为 4.7 秒 */
#veil.story-playing .cartoon-line-1 { animation:cartoonSentence 1.82s ease .18s both; }
#veil.story-playing .cartoon-line-2 { animation:cartoonSentence 1.9s ease 1.62s both; }
#veil.story-playing .cartoon-finale {
  animation:cartoonFinaleIn .92s cubic-bezier(.18,.76,.22,1) 3.08s forwards;
}
#veil.story-playing .cartoon-claim {
  animation:pocketClaimIn 1.02s cubic-bezier(.16,.82,.2,1) 3.48s forwards;
}
#veil.story-playing .cartoon-music-note { animation:cartoonNoteIn .5s ease 4.18s forwards; }

/* v32 · 免费实时矢量递信：连续变换，不再播放静态补帧视频 */
.film-poster-preload,.love-story-film { display:none!important; }
.vector-scene {
  position:absolute;
  inset:-1.8%;
  z-index:0;
  width:103.6%;
  height:103.6%;
  object-fit:cover;
  object-position:center;
  filter:saturate(1.05) contrast(1.025) brightness(.94);
  transform:scale(1.025) translateZ(0);
  backface-visibility:hidden;
  will-change:transform,filter;
}
#veil.story-playing .vector-scene { animation:vectorCamera 6.2s cubic-bezier(.18,.66,.22,1) both; }
@keyframes vectorCamera {
  0%{transform:scale(1.055) translate3d(0,4px,0);filter:saturate(.98) contrast(1.01) brightness(.88)}
  44%{transform:scale(1.035) translate3d(0,0,0);filter:saturate(1.04) contrast(1.025) brightness(.94)}
  100%{transform:scale(1.015) translate3d(0,-2px,0);filter:saturate(1.07) contrast(1.035) brightness(.97)}
}
.vector-warmth { position:absolute; inset:0; z-index:1; pointer-events:none; background:radial-gradient(circle at 48% 44%,rgba(255,220,160,.2),transparent 33%),linear-gradient(180deg,rgba(34,17,43,.16),transparent 31%,transparent 73%,rgba(35,17,35,.26)); mix-blend-mode:screen; }
.vector-rig { position:absolute; inset:0; z-index:3; width:100%; height:100%; overflow:visible; pointer-events:none; }
.veil-lines path { fill:none; stroke:url(#veilGlow); stroke-width:1.7; stroke-linecap:round; stroke-dasharray:4 13; opacity:.12; }
#veil.story-playing .veil-lines path { animation:veilLiving 4.8s ease-in-out infinite alternate; }
.veil-lines path:nth-child(2){animation-delay:-1.15s!important}.veil-lines path:nth-child(3){animation-delay:-2.25s!important}
@keyframes veilLiving { 0%{opacity:.08;stroke-dashoffset:0;transform:translateX(-2px)}100%{opacity:.62;stroke-dashoffset:-38;transform:translateX(5px)} }
.vector-arm { opacity:0; transform-box:view-box; transform-origin:116px 332px; will-change:transform,opacity; }
.arm-seam,.finger-line { fill:none; stroke:rgba(255,255,255,.2); stroke-width:1.2; stroke-linecap:round; }
.finger-line { stroke:rgba(112,57,45,.35); stroke-width:.9; }
#veil.story-playing .vector-arm { animation:vectorArmOffer 4.35s cubic-bezier(.2,.68,.18,1) .72s both; }
@keyframes vectorArmOffer {
  0%,8%{opacity:0;transform:translate3d(-17px,18px,0) rotate(-34deg) scale(.48)}
  18%{opacity:1;transform:translate3d(-11px,12px,0) rotate(-26deg) scale(.64)}
  42%{opacity:1;transform:translate3d(-6px,7px,0) rotate(-17deg) scale(.78)}
  68%{opacity:1;transform:translate3d(-3px,4px,0) rotate(-10deg) scale(.92)}
  86%{opacity:1;transform:translate3d(-1px,2px,0) rotate(-5deg) scale(1.04)}
  100%{opacity:1;transform:translate3d(0,0,0) rotate(-2deg) scale(1.12)}
}
.hero-envelope {
  position:absolute;
  z-index:5;
  left:45.8%;
  top:47.2%;
  width:104px;
  height:72px;
  opacity:0;
  border:1px solid rgba(126,77,53,.48);
  border-radius:3px;
  transform-style:preserve-3d;
  transform-origin:18% 64%;
  backface-visibility:hidden;
  will-change:transform,opacity;
  filter:drop-shadow(0 12px 13px rgba(38,18,29,.37));
}
.hero-envelope-face { position:absolute; inset:0; border-radius:2px; background:linear-gradient(142deg,#fffdf5 0%,#f5dfbb 52%,#dab58a 100%); box-shadow:inset 0 1px 0 rgba(255,255,255,.95),inset 0 -2px 4px rgba(118,69,42,.18); }
.hero-envelope-flap { position:absolute; z-index:2; left:2px; right:2px; top:1px; height:56%; clip-path:polygon(0 0,100% 0,50% 100%); background:linear-gradient(170deg,#fffaf0,#e9c99e); filter:drop-shadow(0 1px 0 rgba(117,70,47,.3)); }
.hero-envelope-fold { position:absolute; z-index:1; bottom:0; width:62%; height:66%; background:linear-gradient(145deg,rgba(255,252,241,.82),rgba(218,179,135,.84)); }
.hero-envelope-fold-left { left:0; clip-path:polygon(0 0,100% 100%,0 100%); }
.hero-envelope-fold-right { right:0; clip-path:polygon(100% 0,100% 100%,0 100%); }
.hero-envelope-seal { position:absolute; z-index:4; left:50%; top:43%; width:22px; height:22px; margin:-11px 0 0 -11px; display:grid; place-items:center; border-radius:50%; color:#f8d7ad; font-family:'Songti SC',serif; font-size:10px; font-weight:700; background:radial-gradient(circle at 36% 28%,#c96d60,#7f2732 68%,#4c1723); border:1px solid rgba(82,20,29,.72); box-shadow:inset 0 1px 2px rgba(255,212,177,.42),0 2px 4px rgba(79,28,30,.34); }
.hero-envelope-edge { position:absolute; inset:-1px; z-index:5; border:1px solid rgba(255,255,255,.48); border-radius:3px; box-shadow:inset 0 0 0 1px rgba(105,60,42,.12); pointer-events:none; }
#veil.story-playing .hero-envelope { animation:vectorEnvelopeOffer 4.18s cubic-bezier(.18,.7,.16,1) 1.02s both; }
@keyframes vectorEnvelopeOffer {
  0%,9%{opacity:0;transform:translate3d(-42px,8px,0) perspective(850px) rotateY(-48deg) rotateX(16deg) rotateZ(-18deg) scale(.13)}
  20%{opacity:1;transform:translate3d(-35px,-5px,0) perspective(850px) rotateY(-32deg) rotateX(12deg) rotateZ(-12deg) scale(.32)}
  43%{opacity:1;transform:translate3d(-21px,-18px,0) perspective(850px) rotateY(-19deg) rotateX(8deg) rotateZ(-8deg) scale(.58)}
  66%{opacity:1;transform:translate3d(3px,-6px,0) perspective(850px) rotateY(-9deg) rotateX(5deg) rotateZ(-3deg) scale(.86)}
  84%{opacity:1;transform:translate3d(30px,25px,0) perspective(850px) rotateY(3deg) rotateX(-2deg) rotateZ(1deg) scale(1.18)}
  100%{opacity:1;transform:translate3d(43px,42px,0) perspective(850px) rotateY(0) rotateX(0) rotateZ(0) scale(1.34)}
}
.vector-sparkles { position:absolute; inset:0; z-index:4; pointer-events:none; }
.vector-sparkles i { position:absolute; width:4px; height:4px; border-radius:50%; opacity:0; background:#fff1ba; box-shadow:0 0 12px 4px rgba(255,218,140,.42); }
.vector-sparkles i:nth-child(1){left:31%;top:31%}.vector-sparkles i:nth-child(2){left:68%;top:27%;width:3px;height:3px}.vector-sparkles i:nth-child(3){left:76%;top:48%}.vector-sparkles i:nth-child(4){left:22%;top:57%;width:3px;height:3px}.vector-sparkles i:nth-child(5){left:58%;top:61%;width:2px;height:2px}.vector-sparkles i:nth-child(6){left:84%;top:69%;width:3px;height:3px}
#veil.story-playing .vector-sparkles i { animation:vectorSparkle 2.25s ease-in-out infinite; }
.vector-sparkles i:nth-child(2){animation-delay:-.45s!important}.vector-sparkles i:nth-child(3){animation-delay:-1.1s!important}.vector-sparkles i:nth-child(4){animation-delay:-1.55s!important}.vector-sparkles i:nth-child(5){animation-delay:-.8s!important}.vector-sparkles i:nth-child(6){animation-delay:-1.85s!important}
@keyframes vectorSparkle { 0%,100%{opacity:0;transform:scale(.25)}48%{opacity:.92;transform:scale(1.25)} }
#veil.story-playing .cartoon-line-1 { animation:cartoonSentence 2s ease .22s both; }
#veil.story-playing .cartoon-line-2 { animation:cartoonSentence 2s ease 2.12s both; }
#veil.story-playing .cartoon-finale { animation:cartoonFinaleIn .9s cubic-bezier(.18,.76,.22,1) 4.15s forwards; }
#veil.story-playing .cartoon-claim { animation:pocketClaimIn 1s cubic-bezier(.16,.82,.2,1) 4.8s forwards; }
#veil.story-playing .cartoon-music-note { animation:cartoonNoteIn .5s ease 5.42s forwards; }

@media (prefers-reduced-motion:reduce) {
  .vector-scene{animation:none!important;transform:scale(1.015)}
  .vector-arm{opacity:1;animation:none!important;transform:rotate(-2deg) scale(1.12)}
  .hero-envelope{opacity:1;animation:none!important;transform:translate3d(43px,42px,0) scale(1.34)}
  .veil-lines path,.vector-sparkles i{animation:none!important}
}

/* v37 · 只保留高清最终递信画面，不播放任何分镜或递信动画 */
.vector-rig,.vector-warmth,.hero-envelope,.vector-sparkles { display:none!important; }
.vector-scene,
#veil.story-playing .vector-scene {
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
  object-position:center;
  transform:none;
  filter:saturate(1.015) contrast(1.015);
  animation:none!important;
}
.cartoon-story-copy { display:none!important; }
.cartoon-finale,
#veil.story-playing .cartoon-finale {
  opacity:1;
  transform:none;
  filter:none;
  animation:none!important;
}
.cartoon-claim,
#veil.story-playing .cartoon-claim {
  opacity:1;
  transform:translate(-50%,0);
  animation:none!important;
}
.cartoon-music-note,
#veil.story-playing .cartoon-music-note {
  opacity:.82;
  animation:none!important;
}
