/* 标题页樱花 */
.title-petals i {
  animation: title-petal-fall var(--fall-duration, 10s) linear var(--fall-delay, 0s) infinite;
}

.title-petals i:nth-child(1) { left: 3%; --fall-duration: 10.8s; --fall-delay: -7.4s; --drift: 80px; }
.title-petals i:nth-child(2) { left: 11%; --fall-duration: 8.6s; --fall-delay: -2.2s; --drift: -54px; }
.title-petals i:nth-child(3) { left: 21%; --fall-duration: 12.4s; --fall-delay: -10.1s; --drift: 64px; }
.title-petals i:nth-child(4) { left: 31%; --fall-duration: 9.2s; --fall-delay: -5.6s; --drift: -86px; }
.title-petals i:nth-child(5) { left: 42%; --fall-duration: 11.7s; --fall-delay: -1.4s; --drift: 72px; }
.title-petals i:nth-child(6) { left: 51%; --fall-duration: 8.9s; --fall-delay: -7.8s; --drift: -48px; }
.title-petals i:nth-child(7) { left: 59%; --fall-duration: 13.1s; --fall-delay: -3.5s; --drift: 94px; }
.title-petals i:nth-child(8) { left: 68%; --fall-duration: 10.2s; --fall-delay: -9.1s; --drift: -74px; }
.title-petals i:nth-child(9) { left: 76%; --fall-duration: 9.8s; --fall-delay: -4.7s; --drift: 52px; }
.title-petals i:nth-child(10) { left: 84%; --fall-duration: 12.8s; --fall-delay: -11.6s; --drift: -62px; }
.title-petals i:nth-child(11) { left: 91%; --fall-duration: 8.4s; --fall-delay: -6.2s; --drift: 78px; }
.title-petals i:nth-child(12) { left: 97%; --fall-duration: 11.2s; --fall-delay: -1.9s; --drift: -88px; }

@keyframes title-petal-fall {
  0% {
    opacity: 0;
    transform: translate3d(0, -8vh, 0) rotate(0deg) rotateY(0deg);
  }
  10% { opacity: 0.94; }
  35% { transform: translate3d(calc(var(--drift) * 0.45), 36vh, 0) rotate(150deg) rotateY(85deg); }
  68% { transform: translate3d(calc(var(--drift) * -0.2), 72vh, 0) rotate(310deg) rotateY(180deg); }
  94% { opacity: 0.82; }
  100% {
    opacity: 0;
    transform: translate3d(var(--drift), 116vh, 0) rotate(540deg) rotateY(260deg);
  }
}

/* 标题页阶梯贴纸 */
.title-subtitle span {
  opacity: 0;
  animation: title-sticker-in 560ms cubic-bezier(0.18, 0.86, 0.3, 1.12) forwards;
}

.title-subtitle span:nth-child(1) { animation-delay: 180ms; }
.title-subtitle span:nth-child(2) { animation-delay: 340ms; }
.title-subtitle span:nth-child(3) { animation-delay: 500ms; }

#game-title {
  animation: title-name-float 3.2s ease-in-out 760ms infinite;
}

@keyframes title-sticker-in {
  from { opacity: 0; transform: translate3d(-22px, 8px, 0) rotate(var(--sticker-rotate)); }
  to { opacity: 1; transform: translate3d(0, 0, 0) rotate(var(--sticker-rotate)); }
}

@keyframes title-name-float {
  0%, 100% { transform: translate3d(0.04em, 0, 0); }
  50% { transform: translate3d(0.04em, -0.035em, 0); }
}

/* 标题页拼贴 KV 动画 */
.title-sprite {
  animation: kv-sprite-in 720ms cubic-bezier(0.18, 0.82, 0.3, 1) 120ms both;
}

@keyframes kv-sprite-in {
  from { opacity: 0; transform: translate3d(6%, 2%, 0); }
  to { opacity: 1; transform: translate3d(0, 0, 0); }
}

.kv-slogan-unlock { animation: kv-sway-a 3.4s ease-in-out 900ms infinite; }
.kv-slogan-ending { animation: kv-sway-b 3.9s ease-in-out 1.2s infinite; }
.kv-slogan-max { animation: kv-sway-a 3.6s ease-in-out 1.5s infinite; }
.kv-shekong { animation: kv-sway-b 3.2s ease-in-out 700ms infinite; }
.kv-bubble { animation: kv-bob 2.8s ease-in-out 600ms infinite; }
.kv-tag { animation: kv-bob 3.3s ease-in-out 1s infinite; }
.kv-affection { animation: kv-bob 4.2s ease-in-out 1.4s infinite; }
.kv-status { animation: kv-bob 4.6s ease-in-out 1.8s infinite; }

@keyframes kv-sway-a {
  0%, 100% { transform: rotate(var(--kv-r, -5deg)) translateY(0); }
  50% { transform: rotate(calc(var(--kv-r, -5deg) + 1.6deg)) translateY(-4px); }
}

@keyframes kv-sway-b {
  0%, 100% { transform: rotate(var(--kv-r, 7deg)) translateY(0); }
  50% { transform: rotate(calc(var(--kv-r, 7deg) - 1.8deg)) translateY(4px); }
}

@keyframes kv-bob {
  0%, 100% { transform: rotate(var(--kv-r, 0deg)) translateY(0); }
  50% { transform: rotate(var(--kv-r, 0deg)) translateY(-5px); }
}

.kv-heart,
.kv-star {
  animation: kv-twinkle 2.6s ease-in-out var(--kv-delay, 0s) infinite;
}

.kv-heart-1 { --kv-delay: 0.2s; }
.kv-heart-2 { --kv-delay: 1.1s; }
.kv-heart-3 { --kv-delay: 0.6s; }
.kv-heart-4 { --kv-delay: 1.6s; }
.kv-star-1 { --kv-delay: 0.9s; }
.kv-star-2 { --kv-delay: 1.9s; }
.kv-star-3 { --kv-delay: 0.4s; }

@keyframes kv-twinkle {
  0%, 100% { opacity: 0.55; transform: scale(0.88); }
  50% { opacity: 1; transform: scale(1.12); }
}

/* 打字机光标与翻页提示 */
#textbox.typing::after,
#textbox.typewriter::after,
#textbox .cursor {
  display: inline-block;
  width: 0.12em;
  height: 1em;
  margin-left: 0.2em;
  content: "";
  vertical-align: -0.12em;
  border-radius: 999px;
  background: var(--pink-deep);
  animation: cursor-blink 780ms steps(1, end) infinite;
}

.dialog-next {
  animation: next-cue 1.1s ease-in-out infinite;
}

@keyframes cursor-blink {
  0%, 46% { opacity: 1; }
  47%, 100% { opacity: 0; }
}

@keyframes next-cue {
  0%, 100% { opacity: 0.4; transform: translateY(-2px); }
  50% { opacity: 1; transform: translateY(3px); }
}

/* 立绘动作 */
#sprite.slide-in,
.slide-in {
  animation: sprite-slide-in 620ms cubic-bezier(0.18, 0.82, 0.3, 1) both;
}

#sprite.shake,
.shake {
  animation: sprite-shake 430ms ease-in-out both;
}

#sprite.bounce,
.bounce {
  animation: sprite-bounce 620ms cubic-bezier(0.24, 0.8, 0.3, 1) both;
}

@keyframes sprite-slide-in {
  from { opacity: 0; transform: translate3d(24%, 2%, 0); }
  to { opacity: 1; transform: translate3d(0, 0, 0); }
}

@keyframes sprite-shake {
  0%, 100% { transform: translateX(0) rotate(0); }
  18% { transform: translateX(-2.2%) rotate(-1.1deg); }
  36% { transform: translateX(2%) rotate(0.9deg); }
  54% { transform: translateX(-1.4%) rotate(-0.6deg); }
  72% { transform: translateX(1%) rotate(0.4deg); }
}

@keyframes sprite-bounce {
  0% { transform: translateY(0) scale(1); }
  32% { transform: translateY(-6%) scale(1.015); }
  55% { transform: translateY(0) scale(0.99); }
  74% { transform: translateY(-2.4%) scale(1.008); }
  100% { transform: translateY(0) scale(1); }
}

/* 心跳、加载与 START 呼吸 */
.heartbeat,
.heart.heartbeat,
.heart.pop {
  animation: heartbeat 1.55s ease-in-out infinite;
}

.loading-heart {
  animation: heartbeat 1.3s ease-in-out infinite;
}

#start-button {
  animation: start-breathe 2.3s ease-in-out infinite;
}

#start-button::before {
  animation: start-shimmer 3.8s ease-in-out infinite;
}

@keyframes heartbeat {
  0%, 40%, 100% { transform: scale(1); }
  12% { transform: scale(1.14); }
  22% { transform: scale(1); }
  30% { transform: scale(1.09); }
}

#affection-bar.affection-loss {
  animation: affection-loss 620ms ease both;
}

@keyframes affection-loss {
  0%, 100% { filter: grayscale(0); transform: translateX(0); }
  18% { filter: grayscale(0.8); transform: translateX(-7px) rotate(-1deg); }
  34% { transform: translateX(6px) rotate(1deg); }
  50% { filter: grayscale(0.9); transform: translateX(-5px); }
  68% { transform: translateX(3px); }
  84% { filter: grayscale(0.35); transform: translateX(-1px); }
}

@keyframes start-breathe {
  0%, 100% { transform: scale(1); filter: brightness(1); }
  50% { transform: scale(1.035); filter: brightness(1.08); }
}

@keyframes start-shimmer {
  0%, 20% { left: -32%; opacity: 0; }
  34% { opacity: 0.9; }
  48%, 100% { left: 116%; opacity: 0; }
}

/* 背景交叉淡入淡出 */
.fade-in {
  animation: bg-fade-in 1s ease both;
}

.fade-out {
  animation: bg-fade-out 1s ease both;
}

@keyframes bg-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes bg-fade-out {
  from { opacity: 1; }
  to { opacity: 0; }
}

/* 选项逐项上浮 */
#choices:not(:empty) > button,
#choices.is-visible > button,
#choices.show > button {
  opacity: 0;
  animation: choice-rise 460ms cubic-bezier(0.2, 0.76, 0.3, 1) forwards;
}

#choices > button:nth-child(1) { animation-delay: 60ms; }
#choices > button:nth-child(2) { animation-delay: 140ms; }
#choices > button:nth-child(3) { animation-delay: 220ms; }
#choices > button:nth-child(4) { animation-delay: 300ms; }
#choices > button:nth-child(5) { animation-delay: 380ms; }

@keyframes choice-rise {
  from { opacity: 0; transform: translateY(18px) scale(0.97); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

/* 成就卡滑入 */
#toast {
  transition: opacity 320ms ease, transform 520ms cubic-bezier(0.2, 0.9, 0.25, 1.12);
}

#toast.show .toast-medal,
#toast.is-visible .toast-medal,
#toast[data-visible="true"] .toast-medal {
  animation: medal-spark 700ms ease both;
}

@keyframes medal-spark {
  0% { opacity: 0; transform: rotate(-40deg) scale(0.35); }
  65% { opacity: 1; transform: rotate(8deg) scale(1.14); }
  100% { transform: rotate(0) scale(1); }
}

/* 舞台粒子共享参数 */
.fx-particle:nth-child(1) { --x: 4%; --dx: 8vw; --hx: -60vmin; --hy: -8vmin; --delay: 0s; --duration: 3.8s; --hue: #ff6ca9; --spin: 460deg; }
.fx-particle:nth-child(2) { --x: 10%; --dx: -5vw; --hx: -51vmin; --hy: -30vmin; --delay: 0.28s; --duration: 4.6s; --hue: #f5c75b; --spin: 620deg; }
.fx-particle:nth-child(3) { --x: 17%; --dx: 6vw; --hx: -40vmin; --hy: 24vmin; --delay: 0.7s; --duration: 4.2s; --hue: #b79ce0; --spin: 390deg; }
.fx-particle:nth-child(4) { --x: 24%; --dx: -7vw; --hx: -30vmin; --hy: -43vmin; --delay: 0.12s; --duration: 5.1s; --hue: #fff2f7; --spin: 730deg; }
.fx-particle:nth-child(5) { --x: 31%; --dx: 10vw; --hx: -24vmin; --hy: 38vmin; --delay: 1.05s; --duration: 4.7s; --hue: #ff94c1; --spin: 520deg; }
.fx-particle:nth-child(6) { --x: 38%; --dx: -4vw; --hx: -12vmin; --hy: -50vmin; --delay: 0.44s; --duration: 3.9s; --hue: #f8d477; --spin: 680deg; }
.fx-particle:nth-child(7) { --x: 45%; --dx: 7vw; --hx: -8vmin; --hy: 46vmin; --delay: 1.3s; --duration: 5.4s; --hue: #cfbbed; --spin: 410deg; }
.fx-particle:nth-child(8) { --x: 52%; --dx: -9vw; --hx: 4vmin; --hy: -42vmin; --delay: 0.18s; --duration: 4.4s; --hue: #ff7fb3; --spin: 780deg; }
.fx-particle:nth-child(9) { --x: 58%; --dx: 4vw; --hx: 12vmin; --hy: 48vmin; --delay: 0.82s; --duration: 5s; --hue: #fff1ad; --spin: 570deg; }
.fx-particle:nth-child(10) { --x: 64%; --dx: -8vw; --hx: 22vmin; --hy: -48vmin; --delay: 1.5s; --duration: 4.1s; --hue: #ba9cdd; --spin: 660deg; }
.fx-particle:nth-child(11) { --x: 70%; --dx: 6vw; --hx: 29vmin; --hy: 36vmin; --delay: 0.36s; --duration: 5.3s; --hue: #ff5f9f; --spin: 430deg; }
.fx-particle:nth-child(12) { --x: 76%; --dx: -5vw; --hx: 38vmin; --hy: -38vmin; --delay: 1.12s; --duration: 4.5s; --hue: #f6d56f; --spin: 810deg; }
.fx-particle:nth-child(13) { --x: 82%; --dx: 9vw; --hx: 44vmin; --hy: 24vmin; --delay: 0.58s; --duration: 3.7s; --hue: #f9a7cc; --spin: 540deg; }
.fx-particle:nth-child(14) { --x: 88%; --dx: -6vw; --hx: 50vmin; --hy: -25vmin; --delay: 1.68s; --duration: 5.2s; --hue: #c4abe4; --spin: 700deg; }
.fx-particle:nth-child(15) { --x: 94%; --dx: 5vw; --hx: 58vmin; --hy: 8vmin; --delay: 0.22s; --duration: 4.8s; --hue: #fff6cf; --spin: 470deg; }
.fx-particle:nth-child(16) { --x: 98%; --dx: -10vw; --hx: 33vmin; --hy: 50vmin; --delay: 0.96s; --duration: 4s; --hue: #ff81b5; --spin: 750deg; }

/* 撒花 */
#stage.confetti #fx-layer .fx-particle {
  top: -8%;
  left: var(--x);
  display: block;
  width: clamp(5px, 0.8vmin, 9px);
  height: clamp(11px, 1.7vmin, 19px);
  border-radius: 2px;
  background: var(--hue);
  box-shadow: 0 0 4px rgba(255, 255, 255, 0.5);
  animation: confetti-fall var(--duration) cubic-bezier(0.15, 0.7, 0.35, 1) var(--delay) both;
}

@keyframes confetti-fall {
  0% { opacity: 0; transform: translate3d(0, -12vh, 0) rotate(0) rotateY(0); }
  8% { opacity: 1; }
  100% { opacity: 0.9; transform: translate3d(var(--dx), 116vh, 0) rotate(var(--spin)) rotateY(720deg); }
}

/* 舞台樱花雨 */
#stage.sakura #fx-layer .fx-particle {
  top: -10%;
  left: var(--x);
  display: block;
  width: clamp(8px, 1.25vmin, 15px);
  height: clamp(11px, 1.7vmin, 20px);
  opacity: 0;
  border-radius: 72% 28% 68% 32%;
  background: linear-gradient(145deg, #fff8fb, #ffb7d4 58%, #ee81b2);
  box-shadow: 0 0 6px rgba(255, 255, 255, 0.72);
  animation: fx-sakura-fall var(--duration) linear var(--delay) infinite;
}

@keyframes fx-sakura-fall {
  0% { opacity: 0; transform: translate3d(0, -10vh, 0) rotate(0) rotateY(0); }
  12% { opacity: 0.95; }
  48% { transform: translate3d(calc(var(--dx) * -0.45), 50vh, 0) rotate(240deg) rotateY(130deg); }
  100% { opacity: 0.5; transform: translate3d(var(--dx), 116vh, 0) rotate(var(--spin)) rotateY(320deg); }
}

/* 心形闪光 */
#stage.flash-heart::after {
  position: absolute;
  z-index: 45;
  top: 50%;
  left: 50%;
  content: "♥";
  color: rgba(255, 255, 255, 0.92);
  font-size: min(40vw, 64vh);
  line-height: 1;
  text-shadow: 0 0 20px #fff, 0 0 46px rgba(255, 97, 164, 0.95), 0 0 90px rgba(255, 176, 211, 0.9);
  pointer-events: none;
  animation: heart-flash 1.05s ease-out both;
}

#stage.flash-heart #fx-layer .fx-particle {
  top: 50%;
  left: 50%;
  display: block;
}

#stage.flash-heart #fx-layer .fx-particle::before {
  display: block;
  content: "♥";
  color: var(--hue);
  font-size: clamp(12px, 2.4vmin, 28px);
  filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.9));
  animation: heart-spark 1.25s cubic-bezier(0.12, 0.7, 0.25, 1) var(--delay) both;
}

@keyframes heart-flash {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.15); }
  28% { opacity: 0.92; transform: translate(-50%, -50%) scale(1.06); }
  58% { opacity: 0.55; transform: translate(-50%, -50%) scale(0.88); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.5); }
}

@keyframes heart-spark {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.2) rotate(0); }
  18% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--hx), var(--hy)) scale(1.1) rotate(var(--spin)); }
}

/* 结局页 */
#ending-screen:not([hidden]) {
  animation: ending-fade-in 900ms ease both;
}

#ending-screen:not([hidden]) .ending-card {
  animation: ending-card-rise 760ms cubic-bezier(0.18, 0.82, 0.3, 1) 120ms both;
}

@keyframes ending-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes ending-card-rise {
  from { opacity: 0; transform: translateY(28px) scale(0.97); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

/* 竖屏旋转提示 */
@media (orientation: portrait) {
  .phone-rotate {
    animation: phone-turn 2.2s ease-in-out infinite;
  }
}

@keyframes phone-turn {
  0%, 18%, 100% { transform: rotate(0); }
  52%, 72% { transform: rotate(90deg); }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
}
