/* ============================================================
   animation.css —— 全部动画样式
   飘落粒子 / 打字机 / 滚动渐入 / 点击爱心 / 弹窗 / 烟花 /
   爱心碰撞 / 抽签 / 解锁 / 星星 / 孔明灯 / 鹊桥 / 流星 / 音乐旋转
   ============================================================ */

/* ---------- 1. 飘落粒子画布（粉色花瓣 + 浅白爱心，JS 绘制） ---------- */
#fx-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 50;             /* 悬浮按钮(500)/弹窗(1000)之下，内容之上 */
  pointer-events: none;    /* 绝不阻挡任何点击与滑动 */
}

/* ---------- 2. 通用基础关键帧 ---------- */
@keyframes floatY {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(8px); }
}

@keyframes heartbeat {
  0%, 100% { transform: scale(1); }
  12%      { transform: scale(1.22); }
  24%      { transform: scale(1); }
  36%      { transform: scale(1.16); }
  48%      { transform: scale(1); }
}

/* ---------- 3. 打字机光标闪烁 ---------- */
@keyframes caretBlink {
  0%, 45%  { opacity: 1; }
  50%, 95% { opacity: 0; }
}
.caret { animation: caretBlink .9s step-end infinite; }

/* ---------- 4. 滚动渐入出场 ---------- */
.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .75s ease, transform .75s ease;
}
.reveal.in {
  opacity: 1;
  transform: none;
}
/* 交错出场：偶数项稍作延迟，形成波浪感 */
.reveal:nth-child(even) { transition-delay: .08s; }

/* ---------- 5. 点击爱心粒子（点击屏幕任意处迸发） ---------- */
.click-heart {
  position: fixed;
  z-index: 400;
  pointer-events: none;
  font-size: 18px;
  will-change: transform, opacity;
  animation: clickHeartUp 1s ease-out forwards;
}
@keyframes clickHeartUp {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(.4) rotate(0deg);
  }
  18% {
    opacity: 1;
    transform: translate(-50%, -60%) scale(1.05) rotate(var(--rot, 12deg));
  }
  100% {
    opacity: 0;
    transform: translate(calc(-50% + var(--dx, 0px)), calc(-120% + var(--dy, -30px))) scale(.55) rotate(var(--rot, 12deg));
  }
}

/* ---------- 6. 弹窗淡入淡出（visibility 方案保证动画必然触发） ---------- */
.modal-mask { transition: opacity .35s ease, visibility .35s ease; }
.modal-mask .modal {
  transform: scale(.86) translateY(16px);
  opacity: 0;
  transition: transform .38s cubic-bezier(.2, 1.1, .35, 1), opacity .3s ease;
}
.modal-mask.open .modal { transform: none; opacity: 1; }

/* ---------- 7. 信封开启晃动 ---------- */
@keyframes envelopeWiggle {
  0%, 100% { transform: rotate(0deg) scale(1); }
  20%      { transform: rotate(-7deg) scale(1.06); }
  45%      { transform: rotate(6deg) scale(1.06); }
  70%      { transform: rotate(-3deg) scale(1.02); }
}
.envelope-wiggle { animation: envelopeWiggle .55s ease; }

/* ---------- 8. 烟花（canvas 绘制，这里只做余晖遮罩） ---------- */
.fireworks-veil {
  position: fixed;
  inset: 0;
  z-index: 890;
  pointer-events: none;
  background: radial-gradient(circle at 50% 42%, rgba(255, 244, 246, .28), transparent 62%);
  opacity: 0;
  animation: veilGlow 4s ease forwards;
}
@keyframes veilGlow {
  15%  { opacity: 1; }
  80%  { opacity: .85; }
  100% { opacity: 0; }
}

/* ---------- 9. 爱心碰撞动画 ---------- */
/* 两颗大爱心向中间加速靠近 */
.big-heart.l { animation: collideL .9s cubic-bezier(.5, 0, .9, .45) forwards; }
.big-heart.r { animation: collideR .9s cubic-bezier(.5, 0, .9, .45) forwards; }
@keyframes collideL {
  0%   { opacity: 0; left: 8%;  transform: scale(.6); }
  15%  { opacity: 1; }
  100% { opacity: 1; left: 50%; transform: translateX(-100%) scale(1.15); }
}
@keyframes collideR {
  0%   { opacity: 0; right: 8%; transform: scaleX(-.6); }
  15%  { opacity: 1; }
  100% { opacity: 1; right: 50%; transform: translateX(100%) scaleX(-1.15); }
}
/* 相撞后绽开的细碎爱心（--dx/--dy 由 JS 随机注入） */
.burst-heart {
  position: absolute;
  left: 50%;
  top: 50%;
  font-size: 15px;
  pointer-events: none;
  will-change: transform, opacity;
  animation: burstOut .95s ease-out forwards;
}
@keyframes burstOut {
  0% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(.3);
  }
  100% {
    opacity: 0;
    transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1) rotate(var(--rot, 0deg));
  }
}
/* 碰撞瞬间中心闪光 */
.love-flash {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: radial-gradient(circle, #fff 0%, rgba(255, 214, 226, .9) 35%, transparent 70%);
  transform: translate(-50%, -50%);
  pointer-events: none;
  animation: loveFlash .6s ease-out forwards;
}
@keyframes loveFlash {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(.4); }
  25%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(9); }
}

/* ---------- 10. 抽签盒子晃动 ---------- */
@keyframes fortuneShake {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  15% { transform: translate(-6px, 2px) rotate(-3deg); }
  30% { transform: translate(6px, -2px) rotate(3deg); }
  45% { transform: translate(-5px, 1px) rotate(-2deg); }
  60% { transform: translate(5px, -1px) rotate(2deg); }
  80% { transform: translate(-3px, 0) rotate(-1deg); }
}
.fortune-box.shaking { animation: fortuneShake .65s ease; }

/* ---------- 11. 爱心解锁 ---------- */
@keyframes unlockPop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.35) rotate(-8deg); }
  70%  { transform: scale(.92) rotate(5deg); }
  100% { transform: scale(1) rotate(0deg); }
}
.lock-card .lock-icon.unlocking { animation: unlockPop .6s ease; display: inline-block; }

/* ---------- 12. 头部星点闪烁（星河低存在感彩蛋） ---------- */
.hero-star {
  position: absolute;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 6px 1px rgba(255, 235, 240, .9);
  animation: starTwinkle 3.4s ease-in-out infinite;
}
@keyframes starTwinkle {
  0%, 100% { opacity: .18; transform: scale(.8); }
  50%      { opacity: .8;  transform: scale(1.15); }
}
/* 牛郎星 / 织女星（比普通星点略亮，可点击的隐藏彩蛋） */
.hero-star.duo-star {
  width: 5px;
  height: 5px;
  cursor: pointer;
  pointer-events: auto;
  box-shadow: 0 0 10px 2px rgba(255, 224, 232, .95);
  animation-duration: 2.4s;
}
.hero-star.duo-star::after {          /* 星名提示，点击后短暂显示 */
  content: attr(data-name);
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 10px;
  color: var(--rose-gold);
  letter-spacing: 2px;
  white-space: nowrap;
  opacity: 0;
  transition: opacity .4s ease;
}
.hero-star.duo-star.lit::after { opacity: .95; }

/* ---------- 13. 鹊桥（点击牛郎织女两星后出现的低存在感彩蛋） ---------- */
.bridge-dot {
  position: absolute;
  width: 5px;
  height: 3px;
  border-radius: 60% 60% 40% 40%;
  background: rgba(207, 163, 150, .85);
  box-shadow: 0 1px 3px rgba(207, 163, 150, .5);
  animation: bridgeFly 1.4s ease-in-out infinite;
}
@keyframes bridgeFly {
  0%, 100% { transform: translateY(0) rotate(-6deg); }
  50%      { transform: translateY(-3px) rotate(6deg); }
}

/* ---------- 14. 孔明灯（定时升起的隐藏彩蛋） ---------- */
.lantern {
  position: fixed;
  z-index: 60;
  bottom: -70px;
  width: 22px;
  height: 30px;
  border-radius: 45% 45% 42% 42%;
  background: linear-gradient(180deg, #FFE9C9, #F6C89B 60%, rgba(246, 200, 155, .35));
  box-shadow: 0 0 18px 4px rgba(255, 214, 170, .5);
  opacity: 0;
  cursor: pointer;
  touch-action: manipulation;
  animation: lanternRise 13s ease-in forwards;
}
.lantern::after {                    /* 灯芯微光 */
  content: "";
  position: absolute;
  left: 50%;
  bottom: 5px;
  width: 6px;
  height: 6px;
  transform: translateX(-50%);
  border-radius: 50%;
  background: #FFDFA3;
  box-shadow: 0 0 8px 3px rgba(255, 223, 163, .8);
}
@keyframes lanternRise {
  0%   { opacity: 0;   transform: translateY(0) translateX(0) scale(.9); }
  8%   { opacity: .85; }
  50%  { opacity: .7;  transform: translateY(-46vh) translateX(-16px) scale(1); }
  92%  { opacity: .35; }
  100% { opacity: 0;   transform: translateY(-92vh) translateX(-34px) scale(.92); }
}

/* ---------- 15. 流星（三连击天数彩蛋） ---------- */
.meteor {
  position: fixed;
  z-index: 640;
  top: 12vh;
  left: -80px;
  width: 90px;
  height: 2.5px;
  border-radius: 999px;
  background: linear-gradient(90deg, rgba(255, 255, 255, .95), rgba(239, 201, 213, .65), transparent);
  transform: rotate(14deg);
  pointer-events: none;
  animation: meteorFly 1.15s cubic-bezier(.3, .1, .6, 1) forwards;
}
@keyframes meteorFly {
  0%   { transform: translateX(0) rotate(14deg); opacity: 0; }
  12%  { opacity: 1; }
  100% { transform: translateX(118vw) rotate(14deg); opacity: 0; }
}

/* ---------- 16. 散落收集星星（微弱呼吸感，不抢眼） ---------- */
@keyframes eggStarBreath {
  0%, 100% { opacity: .45; text-shadow: 0 0 0 rgba(229, 174, 192, 0); }
  50%      { opacity: .95; text-shadow: 0 0 8px rgba(229, 174, 192, .8); }
}
.egg-star { animation: eggStarBreath 3.8s ease-in-out infinite; }
.egg-star.collected { animation: none; }

/* ---------- 17. 音乐按钮播放时旋转 ---------- */
.music-btn .disc {
  display: block;
  font-size: 22px;
  line-height: 1;
}
.music-btn.playing .disc {
  animation: discSpin 3.2s linear infinite;
}
@keyframes discSpin {
  to { transform: rotate(360deg); }
}

/* ---------- 18. 返回首页按钮轻微呼吸 ---------- */
.back-home-btn { animation: homeBreath 2.6s ease-in-out infinite; }
@keyframes homeBreath {
  0%, 100% { transform: scale(1);    box-shadow: 0 10px 30px rgba(217, 152, 173, .26); }
  50%      { transform: scale(1.06); box-shadow: 0 14px 36px rgba(217, 152, 173, .4); }
}
.back-home-btn:active { animation: none; transform: scale(.9); }

/* ---------- 19. 情话卡片悬停微浮起（桌面端） ---------- */
@media (hover: hover) {
  .quote-card:hover  { transform: translateY(-5px); box-shadow: var(--shadow-hover); }
  .explore-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-hover); }
  .polaroid:hover    { transform: rotate(0deg) scale(1.02); }
}

/* ---------- 20. 减弱动态效果（无障碍） ---------- */
@media (prefers-reduced-motion: reduce) {
  .click-heart, .meteor, .lantern, .bridge-dot { animation-duration: .01s !important; }
  .reveal { transition-duration: .01s; }
}
