/* === Festival animation layer ===
 * Full-screen overlay activated by Festival.play() / Festival.triggerKeyword().
 * Mounted on <div id="festival-layer">.
 */

#festival-layer {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9000;
  pointer-events: none;
  background: transparent;
  overflow: hidden;
  display: none;
  color: #fff;
  font-family: -apple-system, 'PingFang SC', 'Microsoft YaHei', sans-serif;
}

#festival-layer.active {
  display: block;
}


/* ========== 动画层 ========== */
.animation-layer {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}

.animation-wrapper {
    position: relative;
    width: 100%;
    height: 100%;
    opacity: 0;
    animation: wrapperFadeIn 0.6s ease forwards;
}

@keyframes wrapperFadeIn {
    to { opacity: 1; }
}

.animation-wrapper.fade-out {
    animation: wrapperFadeOut 1.2s ease forwards;
}

@keyframes wrapperFadeOut {
    to { opacity: 0; }
}

/* Lottie容器 */
.lottie-container {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 500px;
    height: 500px;
    z-index: 5;
    pointer-events: none;
}

lottie-player {
    width: 100%;
    height: 100%;
    filter: drop-shadow(0 0 20px rgba(255,255,255,0.3));
}

/* 节日标题 */
.festival-header {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    z-index: 10;
    opacity: 0;
    animation: headerReveal 0.8s ease 0.3s forwards;
}

@keyframes headerReveal {
    0% { opacity: 0; transform: translate(-50%, -50%) scale(0.9); }
    100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

.festival-header h2 {
    font-size: 56px;
    font-weight: 200;
    letter-spacing: 12px;
    margin-bottom: 12px;
    text-shadow: 0 0 80px currentColor;
}

.festival-header .subtitle {
    font-size: 14px;
    letter-spacing: 4px;
    opacity: 0.5;
}

/* 控制栏 */
.controls {
    position: absolute;
    bottom: 30px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 12px;
    z-index: 100;
    pointer-events: auto;
}

.ctrl-btn {
    padding: 10px 24px;
    border: 1px solid rgba(255,255,255,0.15);
    border-radius: 24px;
    background: rgba(0,0,0,0.4);
    backdrop-filter: blur(10px);
    color: rgba(255,255,255,0.8);
    font-size: 13px;
    cursor: pointer;
    transition: all 0.2s;
}

.ctrl-btn:hover {
    background: rgba(255,255,255,0.1);
    border-color: rgba(255,255,255,0.25);
    color: #fff;
}

/* ========== 动画效果库 ========== */

/* 通用粒子 */
.particle {
    position: absolute;
    pointer-events: none;
}

/* ----- 春节/鞭炮 ----- */
.spring .firecracker-chain {
    position: absolute;
    top: 8%;
    left: 50%;
    transform: translateX(-50%);
}

.spring .fc-rope {
    width: 4px;
    height: 30px;
    background: linear-gradient(#8B4513, #D2691E);
    margin: 0 auto;
    border-radius: 2px;
}

.spring .fc-item {
    width: 32px;
    height: 52px;
    background: linear-gradient(90deg, #b30000, #ff0000 30%, #ff3333 50%, #ff0000 70%, #b30000);
    border-radius: 5px;
    margin: 3px auto;
    position: relative;
    box-shadow:
        inset 2px 2px 4px rgba(255,255,255,0.2),
        inset -2px -2px 4px rgba(0,0,0,0.3),
        0 2px 8px rgba(0,0,0,0.3);
}

.spring .fc-item::before {
    content: '';
    position: absolute;
    top: -10px;
    left: 50%;
    transform: translateX(-50%);
    width: 2px;
    height: 12px;
    background: linear-gradient(#333, #666);
}

.spring .fc-item::after {
    content: '福';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: #FFD700;
    font-size: 18px;
    font-weight: bold;
    text-shadow: 0 1px 2px rgba(0,0,0,0.5);
}

.spring .fc-item.boom {
    animation: fcBoom 0.25s ease-out forwards;
}

@keyframes fcBoom {
    0% { transform: scale(1); filter: brightness(1); }
    30% { transform: scale(1.3); filter: brightness(2); background: #fff; }
    100% { transform: scale(0); opacity: 0; }
}

.spring .spark {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: radial-gradient(#fff, #FFD700);
    box-shadow: 0 0 10px #FFD700, 0 0 20px #ff6600;
}

.spring .ember {
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: #ff4500;
    box-shadow: 0 0 6px #ff4500;
}

/* ----- 情人节/520/七夕 心形 ----- */
.love .heart {
    font-size: 30px;
    animation: heartFloat 4s ease-in-out forwards;
    filter: drop-shadow(0 0 10px currentColor);
}

@keyframes heartFloat {
    0% { transform: translateY(20px) scale(0); opacity: 0; }
    20% { transform: translateY(0) scale(1); opacity: 1; }
    100% { transform: translateY(-120px) scale(0.6); opacity: 0; }
}

.love .heart-burst {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.love .heart-center {
    font-size: 100px;
    animation: heartPulse 0.6s ease-in-out infinite;
    filter: drop-shadow(0 0 30px #ff6b9d);
}

@keyframes heartPulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.15); }
}

/* ----- 中秋/月亮 ----- */
.midautumn .moon {
    position: absolute;
    top: 12%;
    left: 50%;
    transform: translateX(-50%);
    width: 180px;
    height: 180px;
    border-radius: 50%;
    background:
        radial-gradient(circle at 35% 35%, #fffef0, #ffeaa7 40%, #fdcb6e 70%, #f39c12);
    box-shadow:
        0 0 80px rgba(253, 203, 110, 0.5),
        0 0 160px rgba(253, 203, 110, 0.3),
        inset -20px -20px 40px rgba(0,0,0,0.1);
    animation: moonGlow 4s ease-in-out infinite;
}

@keyframes moonGlow {
    0%, 100% { box-shadow: 0 0 80px rgba(253,203,110,0.5), 0 0 160px rgba(253,203,110,0.3); }
    50% { box-shadow: 0 0 120px rgba(253,203,110,0.7), 0 0 240px rgba(253,203,110,0.4); }
}

.midautumn .crater {
    position: absolute;
    border-radius: 50%;
    background: rgba(0,0,0,0.08);
}

.midautumn .cloud {
    position: absolute;
    background: linear-gradient(180deg, rgba(255,255,255,0.1), transparent);
    border-radius: 100px;
    animation: cloudDrift 25s linear infinite;
}

@keyframes cloudDrift {
    from { transform: translateX(-100%); }
    to { transform: translateX(100vw); }
}

.midautumn .rabbit {
    position: absolute;
    bottom: 18%;
    left: 50%;
    transform: translateX(-50%);
    font-size: 70px;
    animation: rabbitJump 1.2s ease-in-out infinite;
}

@keyframes rabbitJump {
    0%, 100% { transform: translateX(-50%) translateY(0); }
    50% { transform: translateX(-50%) translateY(-25px); }
}

/* ----- 国庆/烟花 ----- */
.national .firework-shell {
    position: absolute;
    width: 6px;
    height: 20px;
    background: linear-gradient(to top, transparent, #fff);
    border-radius: 3px;
    animation: shellRise 1s ease-out forwards;
}

@keyframes shellRise {
    0% { opacity: 1; }
    100% { opacity: 0; }
}

.national .firework-particle {
    position: absolute;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    animation: particleBurst 1.5s ease-out forwards;
}

@keyframes particleBurst {
    0% { transform: translate(0, 0) scale(1); opacity: 1; }
    100% { transform: translate(var(--tx), var(--ty)) scale(0); opacity: 0; }
}

.national .flag {
    position: absolute;
    bottom: 8%;
    left: 50%;
    transform: translateX(-50%);
    font-size: 90px;
    animation: flagWave 2s ease-in-out infinite;
}

@keyframes flagWave {
    0%, 100% { transform: translateX(-50%) rotate(-3deg); }
    50% { transform: translateX(-50%) rotate(3deg); }
}

/* ----- 儿童节 ----- */
.children .balloon {
    position: absolute;
    animation: balloonUp 7s ease-out forwards;
}

@keyframes balloonUp {
    0% { transform: translateY(100vh); opacity: 0; }
    10% { opacity: 1; }
    100% { transform: translateY(-150px); opacity: 0.9; }
}

.children .balloon-body {
    width: 55px;
    height: 70px;
    border-radius: 50% 50% 50% 50%;
    position: relative;
    box-shadow:
        inset -15px -10px 30px rgba(0,0,0,0.15),
        inset 15px 15px 30px rgba(255,255,255,0.4);
}

.children .balloon-body::after {
    content: '';
    position: absolute;
    bottom: -10px;
    left: 50%;
    transform: translateX(-50%);
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
    border-top: 14px solid currentColor;
}

.children .balloon-string {
    position: absolute;
    bottom: -70px;
    left: 50%;
    width: 1px;
    height: 60px;
    background: linear-gradient(to bottom, currentColor, transparent);
}

.children .rainbow {
    position: absolute;
    top: 5%;
    left: 50%;
    transform: translateX(-50%);
    width: 350px;
    height: 175px;
    border-radius: 175px 175px 0 0;
    background: conic-gradient(from 180deg at 50% 100%,
        rgba(255,0,0,0.4),
        rgba(255,127,0,0.4),
        rgba(255,255,0,0.4),
        rgba(0,255,0,0.4),
        rgba(0,127,255,0.4),
        rgba(75,0,130,0.4),
        rgba(148,0,211,0.4));
    opacity: 0;
    animation: rainbowIn 1s ease 0.5s forwards;
}

@keyframes rainbowIn {
    to { opacity: 0.6; }
}

/* ----- 元旦/新年 ----- */
.newyear .countdown-num {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 200px;
    font-weight: 100;
    opacity: 0;
    animation: countNum 1s ease-in-out forwards;
}

@keyframes countNum {
    0% { transform: translate(-50%, -50%) scale(0.5); opacity: 0; }
    30% { transform: translate(-50%, -50%) scale(1.1); opacity: 1; }
    100% { transform: translate(-50%, -50%) scale(1); opacity: 0.3; }
}

.newyear .confetti {
    position: absolute;
    animation: confettiFall 3.5s linear forwards;
}

@keyframes confettiFall {
    0% { transform: translateY(-30px) rotate(0deg); opacity: 1; }
    100% { transform: translateY(100vh) rotate(720deg); opacity: 0.4; }
}

/* ----- 圣诞节 ----- */
.christmas .snow {
    position: absolute;
    color: #fff;
    animation: snowDrift 6s linear forwards;
    text-shadow: 0 0 5px rgba(255,255,255,0.5);
}

@keyframes snowDrift {
    0% { transform: translateY(-30px) rotate(0deg); opacity: 0; }
    10% { opacity: 1; }
    100% { transform: translateY(100vh) rotate(360deg); opacity: 0.3; }
}

.christmas .tree {
    position: absolute;
    bottom: 10%;
    left: 50%;
    transform: translateX(-50%);
    font-size: 120px;
    animation: treeGlow 2s ease-in-out infinite;
}

@keyframes treeGlow {
    0%, 100% { filter: drop-shadow(0 0 20px rgba(0,255,100,0.3)); }
    50% { filter: drop-shadow(0 0 40px rgba(255,215,0,0.5)); }
}

.christmas .star {
    position: absolute;
    color: #FFD700;
    animation: starSparkle 1.5s ease-in-out infinite;
}

@keyframes starSparkle {
    0%, 100% { transform: scale(1); opacity: 0.7; }
    50% { transform: scale(1.3); opacity: 1; }
}

/* ----- 万圣节 ----- */
.halloween .pumpkin {
    position: absolute;
    font-size: 80px;
    animation: pumpkinBob 2s ease-in-out infinite;
}

@keyframes pumpkinBob {
    0%, 100% { transform: translateY(0) rotate(-5deg); }
    50% { transform: translateY(-15px) rotate(5deg); }
}

.halloween .bat {
    position: absolute;
    font-size: 30px;
    animation: batFly 4s ease-in-out infinite;
}

@keyframes batFly {
    0%, 100% { transform: translate(0, 0) scaleX(1); }
    25% { transform: translate(30px, -20px) scaleX(-1); }
    50% { transform: translate(60px, 0) scaleX(-1); }
    75% { transform: translate(30px, 20px) scaleX(1); }
}

.halloween .ghost {
    position: absolute;
    font-size: 50px;
    animation: ghostFloat 3s ease-in-out infinite;
    opacity: 0.8;
}

@keyframes ghostFloat {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-30px); }
}

/* ----- 母亲节/父亲节/教师节 花朵 ----- */
.flowers .bloom {
    position: absolute;
    font-size: 50px;
    opacity: 0;
    animation: flowerBloom 1s ease forwards;
}

@keyframes flowerBloom {
    0% { transform: scale(0) rotate(-180deg); opacity: 0; }
    100% { transform: scale(1) rotate(0deg); opacity: 1; }
}

.flowers .petal-fall {
    position: absolute;
    font-size: 25px;
    animation: petalDrift 5s linear forwards;
}

@keyframes petalDrift {
    0% { transform: translateY(-30px) rotate(0deg); opacity: 0; }
    10% { opacity: 1; }
    100% { transform: translateY(100vh) rotate(360deg); opacity: 0.2; }
}

/* ----- 双11/双12 购物 ----- */
.shopping .coin {
    position: absolute;
    font-size: 35px;
    animation: coinRain 3s linear forwards;
}

@keyframes coinRain {
    0% { transform: translateY(-50px) rotateY(0deg); opacity: 0; }
    10% { opacity: 1; }
    100% { transform: translateY(100vh) rotateY(720deg); opacity: 0.5; }
}

.shopping .gift {
    position: absolute;
    font-size: 45px;
    animation: giftBounce 1.5s ease-in-out infinite;
}

@keyframes giftBounce {
    0%, 100% { transform: translateY(0) rotate(-5deg); }
    50% { transform: translateY(-20px) rotate(5deg); }
}

.shopping .sale-tag {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 100px;
    font-weight: bold;
    color: #ff4757;
    text-shadow: 0 0 40px rgba(255, 71, 87, 0.5);
    animation: saleFlash 0.5s ease-in-out infinite;
}

@keyframes saleFlash {
    0%, 100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
    50% { opacity: 0.8; transform: translate(-50%, -50%) scale(1.05); }
}

/* ----- 感恩节 ----- */
.thanksgiving .leaf {
    position: absolute;
    font-size: 30px;
    animation: thankLeafFall 5s linear forwards;
}

@keyframes thankLeafFall {
    0% { transform: translateY(-50px) rotate(0deg); opacity: 0; }
    10% { opacity: 1; }
    100% { transform: translateY(100vh) rotate(360deg); opacity: 0.3; }
}

/* ----- 清明/雨 ----- */
.qingming .rain {
    position: absolute;
    width: 2px;
    height: 25px;
    background: linear-gradient(to bottom, transparent, rgba(150, 200, 230, 0.6));
    animation: rainDown 0.8s linear infinite;
}

@keyframes rainDown {
    0% { transform: translateY(-30px); }
    100% { transform: translateY(100vh); }
}

.qingming .willow {
    position: absolute;
    top: 0;
    width: 3px;
    background: linear-gradient(to bottom, #556B2F, transparent);
    border-radius: 0 0 3px 3px;
    transform-origin: top;
    animation: willowSway 3s ease-in-out infinite;
}

@keyframes willowSway {
    0%, 100% { transform: rotate(-8deg); }
    50% { transform: rotate(8deg); }
}

/* ----- 端午/龙舟 ----- */
.dragon .water-bg {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 35%;
    background: linear-gradient(180deg,
        rgba(30, 100, 160, 0.2),
        rgba(20, 80, 140, 0.4));
}

.dragon .wave-line {
    position: absolute;
    bottom: 33%;
    left: 0;
    width: 200%;
    height: 50px;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 120'%3E%3Cpath fill='rgba(100,180,220,0.25)' d='M0,60 C150,120 350,0 600,60 C850,120 1050,0 1200,60 L1200,120 L0,120 Z'/%3E%3C/svg%3E");
    background-size: 600px 50px;
    animation: waveScroll 2.5s linear infinite;
}

@keyframes waveScroll {
    from { transform: translateX(0); }
    to { transform: translateX(-600px); }
}

.dragon .boat {
    position: absolute;
    bottom: 30%;
    animation: boatGo 5s ease-in-out forwards;
}

@keyframes boatGo {
    0% { left: -15%; }
    100% { left: 105%; }
}

.dragon .boat-emoji {
    font-size: 70px;
    transform: scaleX(-1);
}

/* ----- 元宵/孔明灯 ----- */
.lantern .sky-lantern {
    position: absolute;
    animation: lanternAscend 9s ease-out forwards;
}

@keyframes lanternAscend {
    0% { transform: translateY(100vh); opacity: 0; }
    10% { opacity: 1; }
    100% { transform: translateY(-100px); opacity: 0.2; }
}

.lantern .lantern-body {
    width: 70px;
    height: 90px;
    background: linear-gradient(180deg,
        rgba(255, 200, 100, 0.9),
        rgba(255, 150, 50, 0.95),
        rgba(255, 100, 30, 0.9));
    border-radius: 50% 50% 45% 45%;
    box-shadow:
        0 0 50px rgba(255, 150, 50, 0.6),
        inset 0 0 40px rgba(255, 255, 200, 0.3);
    position: relative;
}

.lantern .lantern-body::before {
    content: '';
    position: absolute;
    bottom: -18px;
    left: 50%;
    transform: translateX(-50%);
    width: 35px;
    height: 18px;
    background: linear-gradient(180deg, rgba(139, 69, 19, 0.7), transparent);
    border-radius: 0 0 50% 50%;
}

.lantern .lantern-glow {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 25px;
    height: 35px;
    background: radial-gradient(ellipse, rgba(255,255,220,0.9) 0%, transparent 70%);
    animation: innerGlow 1.2s ease-in-out infinite;
}

@keyframes innerGlow {
    0%, 100% { opacity: 0.7; }
    50% { opacity: 1; }
}

/* ----- 冬至/雪+饺子 ----- */
.dongzhi .snowflake {
    position: absolute;
    color: #fff;
    text-shadow: 0 0 5px rgba(255,255,255,0.5);
    animation: snowDown 5s linear forwards;
}

@keyframes snowDown {
    0% { transform: translateY(-30px) rotate(0deg); opacity: 0; }
    10% { opacity: 0.9; }
    100% { transform: translateY(100vh) rotate(360deg); opacity: 0.2; }
}

.dongzhi .dumpling {
    position: absolute;
    bottom: 20%;
    left: 50%;
    transform: translateX(-50%);
    font-size: 90px;
}

.dongzhi .steam {
    position: absolute;
    bottom: 35%;
    left: 50%;
    transform: translateX(-50%);
}

.dongzhi .steam-line {
    position: absolute;
    width: 3px;
    height: 40px;
    background: linear-gradient(to top, rgba(255,255,255,0.4), transparent);
    border-radius: 3px;
    animation: steamWave 2s ease-in-out infinite;
}

@keyframes steamWave {
    0%, 100% { transform: translateY(0) scaleY(1); opacity: 0.6; }
    50% { transform: translateY(-20px) scaleY(1.3); opacity: 0; }
}

/* === Keyword animations — 22 个独立动画，统一"上半渐变 → 下半透明"风格 === */

/* ----- Reusable keyframes (only used by keyword anims) ----- */
@keyframes kwFadeIn {
  0% { opacity: 0; transform: translateY(20px); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes kwPopIn {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }
  60% { opacity: 1; transform: translate(-50%, -50%) scale(1.15); }
  100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@keyframes kwTwinkle {
  0%, 100% { opacity: 0.2; transform: scale(0.7); }
  50% { opacity: 1; transform: scale(1.4); }
}
@keyframes kwBob {
  0%, 100% { transform: translateX(-50%) translateY(0) rotate(-3deg); }
  50% { transform: translateX(-50%) translateY(-18px) rotate(3deg); }
}
@keyframes kwHeartFloat {
  0% { transform: translateY(20px) scale(0); opacity: 0; }
  20% { transform: translateY(0) scale(1); opacity: 1; }
  100% { transform: translateY(-120px) scale(0.6); opacity: 0; }
}
@keyframes kwFloatUp {
  0% { transform: translateY(110vh) scale(0.6) rotate(0deg); opacity: 0; }
  15% { opacity: 1; }
  85% { opacity: 0.95; }
  100% { transform: translateY(-25vh) scale(1.1) rotate(360deg); opacity: 0; }
}
@keyframes kwFlyAcross {
  0% { transform: translate(-15vw, 0) scale(0.8); opacity: 0; }
  10% { opacity: 1; }
  90% { opacity: 0.9; }
  100% { transform: translate(115vw, -80px) scale(1); opacity: 0; }
}
@keyframes kwFall {
  0% { transform: translateY(-60px) rotate(0deg); opacity: 0; }
  15% { opacity: 1; }
  100% { transform: translateY(80vh) rotate(540deg); opacity: 0; }
}
@keyframes kwSway {
  0%, 100% { transform: rotate(-8deg); }
  50% { transform: rotate(8deg); }
}

/* === 1. 早上好 — morning === */
.morning {
  background: linear-gradient(to bottom,
    rgba(255,210,155,0.75) 0%, rgba(255,210,155,0.45) 30%,
    rgba(255,210,155,0.15) 55%, transparent 70%);
}
.morning .sun {
  position: absolute; width: 160px; height: 160px; border-radius: 50%;
  background: radial-gradient(circle at 50% 55%, #fff8d8, #ffd16a 45%, #ff8c1a 80%, rgba(255,140,26,0) 100%);
  box-shadow:
    0 0 80px rgba(255,184,80,0.6),
    0 0 180px rgba(255,160,60,0.4),
    0 0 280px rgba(255,140,40,0.25);
  top: 65%; left: -200px; opacity: 0;
  animation: sunRiseLeft 5.5s cubic-bezier(.25,.8,.35,1) forwards;
}
@keyframes sunRiseLeft {
  0%   { left: -200px; top: 70%; opacity: 0; }
  15%  { opacity: 1; }
  100% { left: calc(50% - 80px); top: 12%; opacity: 1; }
}
.morning .bird {
  position: absolute; font-size: 28px;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,0.15));
  animation: kwFlyAcross 7s linear forwards;
}
.morning .cloud-soft {
  position: absolute; font-size: 60px; opacity: 0;
  filter: drop-shadow(0 4px 8px rgba(120,140,160,0.2));
  animation: cloudPass 14s linear forwards;
}
@keyframes cloudPass {
  0% { transform: translateX(-20vw); opacity: 0; }
  15% { opacity: 0.8; } 85% { opacity: 0.8; }
  100% { transform: translateX(120vw); opacity: 0; }
}

/* === 2. 午安 — noon === */
.noon {
  background: linear-gradient(to bottom,
    rgba(255,240,180,0.7) 0%, rgba(255,240,180,0.3) 35%, transparent 65%);
}
.noon .tea-cup {
  position: absolute; top: 22%; left: 50%; transform: translateX(-50%);
  font-size: 110px;
  filter: drop-shadow(0 8px 14px rgba(180,120,40,0.3));
  animation: kwFadeIn 1s ease forwards;
}
.noon .steam {
  position: absolute; width: 6px; height: 50px;
  background: linear-gradient(to top, rgba(255,255,255,0.7), transparent);
  border-radius: 6px; filter: blur(2px);
  animation: steamRise 3s ease-in infinite;
}
@keyframes steamRise {
  0% { transform: translateY(0) scaleY(0.8); opacity: 0; }
  30% { opacity: 0.85; }
  100% { transform: translateY(-70px) scaleY(1.4); opacity: 0; }
}
.noon .sun-fleck {
  position: absolute; width: 14px; height: 14px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,235,150,0.9), transparent 70%);
  animation: kwTwinkle 2.2s ease-in-out infinite;
}

/* === 3. 晚安 — goodnight === */
.goodnight {
  background: linear-gradient(to bottom,
    rgba(60,40,110,0.7) 0%, rgba(60,40,110,0.35) 35%, transparent 65%);
}
.goodnight .moon-quiet {
  position: absolute; top: 10%; left: 50%; transform: translateX(-50%);
  width: 120px; height: 120px; border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, #fffdf5, #e8d99a 55%, #b3964a 100%);
  box-shadow: 0 0 50px rgba(255,230,150,0.5), 0 0 120px rgba(255,220,140,0.3);
  opacity: 0; animation: kwFadeIn 2s ease forwards;
}
.goodnight .zzz {
  position: absolute; font-size: 64px; font-weight: 800;
  color: #fff; font-family: serif; opacity: 0;
  text-shadow: 0 4px 16px rgba(180,160,255,0.5);
  animation: zzzRise 4s ease-out forwards;
}
@keyframes zzzRise {
  0% { opacity: 0; transform: translateY(40px) scale(0.6); }
  20% { opacity: 0.95; transform: translateY(0) scale(1); }
  100% { opacity: 0; transform: translateY(-160px) scale(1.4); }
}
.goodnight .bed {
  position: absolute; bottom: 22%; left: 50%; transform: translateX(-50%);
  font-size: 80px; filter: drop-shadow(0 6px 12px rgba(0,0,0,0.25));
  opacity: 0; animation: kwFadeIn 1.2s ease 0.6s forwards;
}

/* === 4. 明天见 — night === */
.night {
  background: linear-gradient(to bottom,
    rgba(20,30,70,0.65) 0%, rgba(20,30,70,0.35) 35%, transparent 65%);
}
.night .moon-soft {
  position: absolute; top: 12%; left: 50%; transform: translateX(-50%);
  width: 130px; height: 130px; border-radius: 50%;
  background: radial-gradient(circle at 38% 36%, #fffdf5 0%, #f3e8b0 50%, #d4b96b 100%);
  box-shadow: 0 0 60px rgba(255,240,180,0.6), 0 0 140px rgba(255,230,150,0.35);
  opacity: 0; animation: kwFadeIn 2s ease forwards;
}
.night .twinkle {
  position: absolute; width: 4px; height: 4px; background: #fff; border-radius: 50%;
  box-shadow: 0 0 8px rgba(255,255,255,0.95), 0 0 16px rgba(180,200,255,0.5);
  animation: kwTwinkle 2.4s ease-in-out infinite;
}
.night .shooting-star {
  position: absolute; width: 120px; height: 2px;
  background: linear-gradient(to left, #fff, rgba(255,255,255,0.4) 30%, transparent 100%);
  border-radius: 2px; filter: drop-shadow(0 0 6px rgba(255,255,255,0.9));
  transform: rotate(20deg); opacity: 0;
  animation: shoot 1.6s ease-out forwards;
}
@keyframes shoot {
  0% { transform: translate(-200px, -50px) rotate(20deg); opacity: 0; }
  10% { opacity: 1; }
  100% { transform: translate(60vw, 30vh) rotate(20deg); opacity: 0; }
}

/* === 5. 回家了 — home === */
.home {
  background: linear-gradient(to bottom,
    rgba(255,170,100,0.6) 0%, rgba(255,170,100,0.3) 35%, transparent 65%);
}
.home .house {
  position: absolute; top: 24%; left: 50%; transform: translateX(-50%);
  font-size: 110px; filter: drop-shadow(0 10px 20px rgba(120,60,20,0.3));
  animation: kwFadeIn 1.2s ease forwards;
}
.home .smoke {
  position: absolute; font-size: 30px; opacity: 0;
  animation: smokeUp 4s ease-in infinite;
}
@keyframes smokeUp {
  0% { opacity: 0; transform: translateY(0) scale(0.8); }
  20% { opacity: 0.85; }
  100% { opacity: 0; transform: translateY(-200px) scale(1.6); }
}
.home .luggage {
  position: absolute; bottom: 25%; font-size: 50px; opacity: 0;
  animation: luggageWalk 3.5s ease-out forwards;
}
@keyframes luggageWalk {
  0% { left: 0; opacity: 0; }
  15% { opacity: 1; }
  85% { opacity: 1; }
  100% { left: 100%; opacity: 0; }
}
.home .lamp-light {
  position: absolute; width: 70px; height: 70px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,220,120,0.65), transparent 70%);
  animation: kwTwinkle 2s ease-in-out infinite;
}

/* === 6. 爱你 — loveyou (big beating heart + small float) === */
.loveyou {
  background: linear-gradient(to bottom,
    rgba(255,130,160,0.55) 0%, rgba(255,130,160,0.25) 35%, transparent 60%);
}
.loveyou .heart-big {
  position: absolute; top: 30%; left: 50%; transform: translate(-50%, -50%);
  font-size: 130px;
  filter: drop-shadow(0 0 30px rgba(255,107,157,0.7));
  animation: heartBigBeat 0.55s ease-in-out infinite;
}
@keyframes heartBigBeat {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  30% { transform: translate(-50%, -50%) scale(1.18); }
  60% { transform: translate(-50%, -50%) scale(0.95); }
}
.loveyou .heart-small {
  position: absolute; font-size: 32px;
  filter: drop-shadow(0 0 8px rgba(255,120,160,0.5));
  animation: kwHeartFloat 4s ease-out forwards;
}

/* === 7. 喜欢 — xihuan (sakura + pink hearts) === */
.xihuan {
  background: linear-gradient(to bottom,
    rgba(255,200,220,0.55) 0%, rgba(255,200,220,0.25) 35%, transparent 60%);
}
.xihuan .petal {
  position: absolute; font-size: 30px;
  animation: petalDance 6s linear forwards;
}
@keyframes petalDance {
  0% { transform: translate(0, -50px) rotate(0deg); opacity: 0; }
  15% { opacity: 1; }
  100% { transform: translate(var(--dx, 100px), 100vh) rotate(720deg); opacity: 0; }
}
.xihuan .pink-heart {
  position: absolute; font-size: 36px;
  animation: kwHeartFloat 4.5s ease-out forwards;
}

/* === 8. 想你 — missyou ("想" giant char + hearts rising) === */
.missyou {
  background: linear-gradient(to bottom,
    rgba(255,100,140,0.55) 0%, rgba(255,100,140,0.25) 35%, transparent 60%);
}
.missyou .xiang {
  position: absolute; top: 28%; left: 50%;
  transform: translate(-50%, -50%) scale(0.5);
  font-size: 220px; font-weight: 900; color: #fff;
  text-shadow: 0 0 60px rgba(255,80,130,0.8), 0 0 120px rgba(255,80,130,0.4);
  opacity: 0;
  animation: kwPopIn 0.8s cubic-bezier(.4,1.6,.5,1) forwards;
}
.missyou .heart-up {
  position: absolute; bottom: 0; font-size: 30px;
  animation: heartUp 4s ease-out forwards;
}
@keyframes heartUp {
  0% { transform: translateY(0) scale(0.6); opacity: 0; }
  20% { opacity: 1; transform: translateY(-100px) scale(1); }
  100% { transform: translateY(-100vh) scale(0.5); opacity: 0; }
}

/* === 9. 想我了吗 — wonder (giant ?, finger emoji) === */
.wonder {
  background: linear-gradient(to bottom,
    rgba(255,200,215,0.55) 0%, rgba(255,200,215,0.25) 35%, transparent 60%);
}
.wonder .finger {
  position: absolute; top: 25%; left: 50%; transform: translate(-50%, -50%);
  font-size: 90px;
  filter: drop-shadow(0 4px 12px rgba(255,100,140,0.4));
  animation: fingerWiggle 1.2s ease-in-out infinite;
}
@keyframes fingerWiggle {
  0%, 100% { transform: translate(-50%, -50%) rotate(-10deg); }
  50% { transform: translate(-50%, -50%) rotate(10deg); }
}
.wonder .qmark {
  position: absolute; font-size: 70px; font-weight: 800;
  color: #ff6b9d; text-shadow: 0 4px 16px rgba(255,107,157,0.4);
  opacity: 0;
  animation: qmarkBounce 3s ease-out forwards;
}
@keyframes qmarkBounce {
  0% { opacity: 0; transform: scale(0) rotate(-30deg); }
  30% { opacity: 1; transform: scale(1.2) rotate(0deg); }
  60% { transform: scale(0.95); }
  100% { opacity: 0.8; transform: scale(1) translateY(-20px); }
}

/* === 10. 宝贝 — baby (teddy bear + candies + sparkles) === */
.baby {
  background: linear-gradient(to bottom,
    rgba(255,220,230,0.55) 0%, rgba(255,220,230,0.25) 35%, transparent 60%);
}
.baby .bear {
  position: absolute; top: 25%; left: 50%; transform: translateX(-50%);
  font-size: 130px;
  filter: drop-shadow(0 6px 14px rgba(190,140,160,0.3));
  animation: kwBob 1.6s ease-in-out infinite;
}
.baby .candy {
  position: absolute; font-size: 40px;
  animation: kwFloatUp 5s ease-out forwards;
}
.baby .baby-sparkle {
  position: absolute; font-size: 28px;
  animation: kwTwinkle 1.8s ease-in-out infinite;
}

/* === 11. 亲爱的 — dear (roses falling + butterflies) === */
.dear {
  background: linear-gradient(to bottom,
    rgba(200,60,100,0.5) 0%, rgba(200,60,100,0.22) 35%, transparent 60%);
}
.dear .rose {
  position: absolute; font-size: 38px;
  animation: kwFall 5.5s linear forwards;
}
.dear .butterfly {
  position: absolute; font-size: 38px;
  filter: drop-shadow(0 4px 8px rgba(0,0,0,0.2));
  animation: butterflyFly 7s ease-in-out forwards;
}
@keyframes butterflyFly {
  0% { transform: translate(-12vw, 20vh); opacity: 0; }
  10% { opacity: 1; }
  50% { transform: translate(50vw, 5vh); }
  90% { opacity: 1; }
  100% { transform: translate(112vw, 15vh); opacity: 0; }
}

/* === 12. 抱抱 — hug (big hug emoji + orbit hearts) === */
.hug {
  background: linear-gradient(to bottom,
    rgba(255,180,200,0.55) 0%, rgba(255,180,200,0.25) 35%, transparent 60%);
}
.hug .hug-emoji {
  position: absolute; top: 28%; left: 50%; transform: translate(-50%, -50%);
  font-size: 150px;
  filter: drop-shadow(0 0 30px rgba(255,150,180,0.5));
  animation: hugSqueeze 1.4s ease-in-out infinite;
}
@keyframes hugSqueeze {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  50% { transform: translate(-50%, -50%) scale(1.1); }
}
.hug .orbit {
  position: absolute; top: 28%; left: 50%; font-size: 30px;
  transform-origin: center -130px;
  animation: orbitRound 3.5s linear infinite;
}
@keyframes orbitRound {
  0% { transform: translate(-50%, -50%) rotate(var(--start, 0deg)); }
  100% { transform: translate(-50%, -50%) rotate(calc(var(--start, 0deg) + 360deg)); }
}

/* === 13. 加油 — cheer (fist pump + bursts) === */
.cheer {
  background: linear-gradient(to bottom,
    rgba(255,110,60,0.6) 0%, rgba(255,110,60,0.25) 35%, transparent 60%);
}
.cheer .fist {
  position: absolute; top: 26%; left: 50%; transform: translate(-50%, -50%);
  font-size: 130px;
  filter: drop-shadow(0 0 24px rgba(255,100,50,0.55));
  animation: fistPump 0.6s ease-in-out infinite;
}
@keyframes fistPump {
  0%, 100% { transform: translate(-50%, -50%) translateY(0) rotate(-5deg); }
  50% { transform: translate(-50%, -50%) translateY(-30px) rotate(5deg); }
}
.cheer .firework-p {
  position: absolute; width: 6px; height: 6px; border-radius: 50%;
  animation: particleBurst 1.5s ease-out forwards;
}

/* === 14. 辛苦了 — tired (coffee + steam + stars) === */
.tired {
  background: linear-gradient(to bottom,
    rgba(180,130,80,0.55) 0%, rgba(180,130,80,0.25) 35%, transparent 60%);
}
.tired .coffee {
  position: absolute; top: 24%; left: 50%; transform: translate(-50%, -50%);
  font-size: 130px;
  filter: drop-shadow(0 8px 18px rgba(80,40,20,0.35));
  animation: kwFadeIn 1.2s ease forwards;
}
.tired .coffee-steam {
  position: absolute; width: 6px; height: 50px;
  background: linear-gradient(to top, rgba(255,255,255,0.7), transparent);
  border-radius: 6px; filter: blur(2px);
  animation: steamRise 2.5s ease-in infinite;
}
.tired .star-thanks {
  position: absolute; font-size: 28px;
  animation: kwTwinkle 2s ease-in-out infinite;
}

/* === 15. 厉害 — awesome (fire + claps) === */
.awesome {
  background: linear-gradient(to bottom,
    rgba(255,70,60,0.55) 0%, rgba(255,70,60,0.25) 35%, transparent 60%);
}
.awesome .fire {
  position: absolute; bottom: 30%; font-size: 90px;
  animation: fireFlick 0.3s ease-in-out infinite;
}
@keyframes fireFlick {
  0%, 100% { transform: scale(1) rotate(-5deg); }
  50% { transform: scale(1.18) rotate(5deg); }
}
.awesome .clap {
  position: absolute; font-size: 50px; opacity: 0;
  animation: clapBurst 2.4s ease-out forwards;
}
@keyframes clapBurst {
  0% { opacity: 0; transform: scale(0); }
  30% { opacity: 1; transform: scale(1.4); }
  100% { opacity: 0; transform: scale(1) translateY(-100px); }
}

/* === 16. 好棒 — great (thumbs up + gold sparkles) === */
.great {
  background: linear-gradient(to bottom,
    rgba(255,215,0,0.55) 0%, rgba(255,215,0,0.25) 35%, transparent 60%);
}
.great .thumbs {
  position: absolute; top: 26%; left: 50%; transform: translate(-50%, -50%);
  font-size: 140px;
  filter: drop-shadow(0 0 28px rgba(255,200,40,0.6));
  animation: thumbsUp 1.2s cubic-bezier(.4,1.6,.5,1) forwards;
}
@keyframes thumbsUp {
  0% { opacity: 0; transform: translate(-50%, 60%) scale(0.4) rotate(-20deg); }
  100% { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(0deg); }
}
.great .gold-sparkle {
  position: absolute; font-size: 32px; color: #ffd700;
  animation: kwTwinkle 1.4s ease-in-out infinite;
}

/* === 17. 太牛了 — bull (charging bull + lightning) === */
.bull {
  background: linear-gradient(to bottom,
    rgba(180,30,50,0.6) 0%, rgba(180,30,50,0.25) 35%, transparent 60%);
}
.bull .bull-emoji {
  position: absolute; top: 26%; left: 50%; transform: translate(-50%, -50%);
  font-size: 130px;
  filter: drop-shadow(0 0 20px rgba(255,180,50,0.5));
  animation: bullCharge 1s cubic-bezier(.5,0,.5,1) forwards;
}
@keyframes bullCharge {
  0% { opacity: 0; transform: translate(-150%, -50%) scale(0.6); }
  100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
.bull .lightning {
  position: absolute; font-size: 60px; opacity: 0;
  animation: lightningFlash 1.5s ease-out forwards;
}
@keyframes lightningFlash {
  0% { opacity: 0; transform: scale(0.3) rotate(-15deg); }
  20% { opacity: 1; transform: scale(1.2) rotate(0deg); }
  100% { opacity: 0; transform: scale(1) rotate(15deg); }
}

/* === 18. 笑死 — lol (laughing emoji shake + HAHA bouncing text) === */
.lol {
  background: linear-gradient(to bottom,
    rgba(255,220,80,0.6) 0%, rgba(255,220,80,0.25) 35%, transparent 60%);
}
.lol .laugh {
  position: absolute; font-size: 80px;
  animation: laughShake 0.35s ease-in-out infinite, kwFloatUp 5s ease-out forwards;
}
@keyframes laughShake {
  0%, 100% { transform: translateX(0) rotate(-5deg); }
  50% { transform: translateX(8px) rotate(5deg); }
}
.lol .haha-text {
  position: absolute; font-size: 56px; font-weight: 900;
  color: #ff9500; text-shadow: 0 4px 12px rgba(255,140,0,0.4);
  opacity: 0;
  animation: hahaBounce 2.5s ease-out forwards;
}
@keyframes hahaBounce {
  0% { opacity: 0; transform: translateY(50px) rotate(-10deg) scale(0.5); }
  20% { opacity: 1; transform: translateY(0) rotate(0deg) scale(1.2); }
  40% { transform: translateY(-10px) scale(1); }
  100% { opacity: 0; transform: translateY(-100px) rotate(10deg) scale(0.8); }
}

/* === 19. 生日快乐 — birthday (cake + balloons + confetti) === */
.birthday {
  background: linear-gradient(to bottom,
    rgba(255,130,180,0.55) 0%, rgba(255,130,180,0.25) 35%, transparent 60%);
}
.birthday .cake {
  position: absolute; top: 28%; left: 50%; transform: translate(-50%, -50%);
  font-size: 150px;
  filter: drop-shadow(0 10px 24px rgba(190,80,120,0.4));
  animation: cakeIn 1.4s cubic-bezier(.4,1.6,.5,1) forwards;
}
@keyframes cakeIn {
  0% { opacity: 0; transform: translate(-50%, 50%) scale(0); }
  100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
.birthday .balloon-up {
  position: absolute; font-size: 42px; opacity: 0;
  animation: balloonFly 6s ease-out forwards;
}
@keyframes balloonFly {
  0% { transform: translateY(100vh); opacity: 0; }
  15% { opacity: 1; }
  100% { transform: translateY(-150px); opacity: 0.85; }
}
.birthday .bday-confetti {
  position: absolute; width: 10px; height: 14px; border-radius: 2px;
  animation: confettiFall 4s linear forwards;
}

/* === 20. 周末快乐 — weekend (beach scene) === */
.weekend {
  background: linear-gradient(to bottom,
    rgba(120,200,230,0.55) 0%, rgba(255,235,180,0.3) 35%, transparent 60%);
}
.weekend .beach-sun {
  position: absolute; top: 18%; left: 50%; transform: translateX(-50%);
  font-size: 90px;
  filter: drop-shadow(0 0 30px rgba(255,200,100,0.5));
  animation: kwFadeIn 1s ease forwards;
}
.weekend .palm {
  position: absolute; bottom: 30%; font-size: 90px;
  filter: drop-shadow(0 4px 10px rgba(0,80,40,0.2));
  transform-origin: bottom center;
  animation: kwSway 4s ease-in-out infinite;
}
.weekend .cocktail {
  position: absolute; font-size: 60px;
  filter: drop-shadow(0 4px 10px rgba(0,0,0,0.2));
  animation: cocktailBob 2s ease-in-out infinite;
}
@keyframes cocktailBob {
  0%, 100% { transform: translateY(0) rotate(-4deg); }
  50% { transform: translateY(-12px) rotate(4deg); }
}
.weekend .wave-h {
  position: absolute; bottom: 35%; left: 0; width: 100%; height: 30px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 60'%3E%3Cpath fill='rgba(100,180,220,0.3)' d='M0,30 C150,60 350,0 600,30 C850,60 1050,0 1200,30 L1200,60 L0,60 Z'/%3E%3C/svg%3E");
  background-size: 400px 30px;
  animation: waveScroll 3s linear infinite;
}

/* === 21. 下班了 — offwork (briefcase toss + party emoji + confetti) === */
.offwork {
  background: linear-gradient(to bottom,
    rgba(255,200,60,0.6) 0%, rgba(255,200,60,0.25) 35%, transparent 60%);
}
.offwork .briefcase {
  position: absolute; top: 28%; font-size: 90px; opacity: 0;
  animation: briefcaseToss 2.5s ease-out forwards;
}
@keyframes briefcaseToss {
  0% { opacity: 0; left: 50%; transform: translateX(-50%) rotate(0deg); top: 28%; }
  20% { opacity: 1; }
  100% { left: 110%; transform: translateX(0) rotate(720deg); top: 80%; opacity: 0; }
}
.offwork .party {
  position: absolute; font-size: 60px; opacity: 0;
  animation: partyPop 3s ease-out forwards;
}
@keyframes partyPop {
  0% { opacity: 0; transform: scale(0); }
  20% { opacity: 1; transform: scale(1.5); }
  100% { opacity: 0; transform: scale(1) translateY(-120px); }
}
.offwork .off-confetti {
  position: absolute; width: 10px; height: 14px;
  animation: confettiFall 4s linear forwards;
}

/* === 22. 下课了 — school (backpack jump + flying books + bell) === */
.school {
  background: linear-gradient(to bottom,
    rgba(120,180,230,0.55) 0%, rgba(120,180,230,0.25) 35%, transparent 60%);
}
.school .bag {
  position: absolute; bottom: 30%; left: 50%; font-size: 100px; opacity: 0;
  animation: bagJump 1.4s cubic-bezier(.4,1.6,.5,1) forwards;
}
@keyframes bagJump {
  0% { opacity: 0; transform: translateX(-50%) translateY(80px) scale(0.5); }
  60% { opacity: 1; transform: translateX(-50%) translateY(-40px) scale(1.2); }
  100% { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}
.school .book {
  position: absolute; font-size: 50px;
  animation: bookFly 3.5s ease-out forwards;
}
@keyframes bookFly {
  0% { transform: translate(0, 80vh) rotate(0deg); opacity: 0; }
  20% { opacity: 1; }
  100% { transform: translate(var(--dx, 100px), -30vh) rotate(720deg); opacity: 0; }
}
.school .bell {
  position: absolute; top: 18%; left: 50%; transform: translate(-50%, -50%);
  font-size: 80px;
  filter: drop-shadow(0 4px 14px rgba(80,40,20,0.3));
  animation: bellRing 0.18s ease-in-out 6, kwFadeIn 0.6s ease forwards;
}
@keyframes bellRing {
  0%, 100% { transform: translate(-50%, -50%) rotate(-15deg); }
  50% { transform: translate(-50%, -50%) rotate(15deg); }
}

/* === Fallback (preserved for safety / new festivals not yet mapped) === */
.fallback .sparkle {
  position: absolute; font-size: 36px;
  filter: drop-shadow(0 4px 10px rgba(0,0,0,0.2));
  animation: kwFloatUp 4.5s ease-out forwards;
}


/* === 23. 在干嘛 — whatdoing (好奇张望的大眼睛 + 思考泡泡 + 问号) === */
.whatdoing {
  background: linear-gradient(to bottom,
    rgba(216,191,255,0.55) 0%, rgba(216,191,255,0.25) 35%, transparent 60%);
}
.whatdoing .eyes {
  position: absolute; top: 22%; left: 50%;
  font-size: 96px;
  filter: drop-shadow(0 6px 14px rgba(140,100,220,0.35));
  animation: kwPopIn 0.6s ease-out forwards, eyesDart 2.2s ease-in-out 0.6s infinite;
}
@keyframes eyesDart {
  0%, 18% { transform: translate(-50%, -50%) translateX(-26px); }
  32%, 58% { transform: translate(-50%, -50%) translateX(26px); }
  72%, 100% { transform: translate(-50%, -50%) translateX(-26px); }
}
.whatdoing .bubble {
  position: absolute; opacity: 0;
  animation: bubblePop 3.2s ease-out forwards;
}
@keyframes bubblePop {
  0% { opacity: 0; transform: scale(0.3) translateY(10px); }
  25% { opacity: 1; transform: scale(1.1) translateY(0); }
  55% { transform: scale(1) translateY(-14px); }
  100% { opacity: 0; transform: scale(0.9) translateY(-46px); }
}
.whatdoing .qm {
  position: absolute; font-weight: 800; color: #8e5cf7;
  text-shadow: 0 4px 14px rgba(142,92,247,0.35); opacity: 0;
  animation: qmFloat 3s ease-out forwards;
}
@keyframes qmFloat {
  0% { opacity: 0; transform: translateY(16px) scale(0.4) rotate(-18deg); }
  25% { opacity: 1; transform: translateY(0) scale(1.05) rotate(0deg); }
  100% { opacity: 0; transform: translateY(-90px) scale(0.85) rotate(12deg); }
}

/* === 24. 跑步去了 — running (奔跑者从右向左冲刺 + 尘土 + 速度线) === */
.running {
  background: linear-gradient(to bottom,
    rgba(170,225,255,0.55) 0%, rgba(170,225,255,0.22) 40%, transparent 65%);
}
.running .runner {
  position: absolute; bottom: 26%; left: 0; font-size: 84px;
  filter: drop-shadow(0 6px 12px rgba(40,120,200,0.3));
  animation: runDash 3s linear forwards;
}
.running .runner.second {
  bottom: 42%; font-size: 54px; opacity: 0.85;
  animation-duration: 2.4s;
}
/* 🏃 emoji 朝左，所以从右往左跑 */
@keyframes runDash {
  0%   { transform: translateX(112vw) translateY(0); opacity: 0; }
  8%   { opacity: 1; }
  25%  { transform: translateX(78vw) translateY(-12px); }
  50%  { transform: translateX(48vw) translateY(0); }
  75%  { transform: translateX(16vw) translateY(-12px); }
  95%  { opacity: 1; }
  100% { transform: translateX(-20vw) translateY(0); opacity: 0; }
}
.running .dust {
  position: absolute; bottom: 24%; font-size: 34px; opacity: 0;
  animation: dustPuff 1.6s ease-out forwards;
}
@keyframes dustPuff {
  0%   { opacity: 0; transform: scale(0.4) translate(0, 0); }
  25%  { opacity: 0.85; transform: scale(1) translate(12px, -6px); }
  100% { opacity: 0; transform: scale(1.6) translate(46px, -26px); }
}
.running .speedline {
  position: absolute; height: 3px; border-radius: 2px;
  background: linear-gradient(to left, rgba(255,255,255,0), rgba(120,190,255,0.9), rgba(255,255,255,0));
  opacity: 0;
  animation: lineZip 1.1s linear forwards;
}
@keyframes lineZip {
  0%   { transform: translateX(115vw); opacity: 0; }
  15%  { opacity: 1; }
  100% { transform: translateX(-30vw); opacity: 0; }
}

/* === 25. 睡的好吗 — sleepwell (睡脸呼吸 + 云朵枕头 + 飘走的💤 + 星星) === */
.sleepwell {
  background: linear-gradient(to bottom,
    rgba(108,99,255,0.30) 0%, rgba(150,130,255,0.18) 40%, transparent 70%);
}
.sleepwell .face {
  position: absolute; top: 30%; left: 50%;
  font-size: 110px;
  filter: drop-shadow(0 8px 20px rgba(90,80,200,0.35));
  animation: kwPopIn 0.8s ease-out forwards, breathe 3s ease-in-out 0.8s infinite;
}
@keyframes breathe {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  50% { transform: translate(-50%, -50%) scale(1.06); }
}
.sleepwell .pillow {
  position: absolute; top: 42%; left: 50%; transform: translateX(-50%);
  font-size: 70px; opacity: 0;
  animation: kwFadeIn 1.2s ease-out 0.4s forwards;
}
.sleepwell .zz {
  position: absolute; font-size: 32px; opacity: 0;
  animation: zzDrift 3.4s ease-out forwards;
}
@keyframes zzDrift {
  0%   { opacity: 0; transform: translate(0, 0) scale(0.5); }
  20%  { opacity: 1; }
  100% { opacity: 0; transform: translate(46px, -130px) scale(1.25) rotate(14deg); }
}
.sleepwell .star {
  position: absolute; width: 5px; height: 5px; border-radius: 50%;
  background: #fff; box-shadow: 0 0 8px 2px rgba(190,180,255,0.8);
  animation: kwTwinkle 2.2s ease-in-out infinite;
}

/* === 26. 周几见 — whenmeet (日历摆动 + 星期药丸升起 + 小心心) === */
.whenmeet {
  background: linear-gradient(to bottom,
    rgba(255,214,170,0.6) 0%, rgba(255,214,170,0.28) 35%, transparent 62%);
}
.whenmeet .cal {
  position: absolute; top: 26%; left: 50%;
  font-size: 100px;
  filter: drop-shadow(0 8px 18px rgba(230,120,60,0.35));
  animation: kwPopIn 0.7s ease-out forwards, calTick 1.6s ease-in-out 0.7s infinite;
}
@keyframes calTick {
  0%, 100% { transform: translate(-50%, -50%) rotate(-4deg); }
  50% { transform: translate(-50%, -50%) rotate(4deg); }
}
.whenmeet .day-pill {
  position: absolute; bottom: 18%;
  padding: 8px 18px; border-radius: 999px;
  background: rgba(255,255,255,0.92); color: #e8743a;
  font-weight: 700; font-size: 21px;
  box-shadow: 0 4px 14px rgba(230,120,60,0.25);
  opacity: 0;
  animation: pillRise 3.2s ease-out forwards;
}
@keyframes pillRise {
  0%   { opacity: 0; transform: translateY(40px) scale(0.6); }
  18%  { opacity: 1; transform: translateY(0) scale(1.05); }
  30%  { transform: translateY(-8px) scale(1); }
  100% { opacity: 0; transform: translateY(-46vh) scale(0.9); }
}
.whenmeet .mini-heart {
  position: absolute; font-size: 30px; opacity: 0;
  animation: kwHeartFloat 2.8s ease-out forwards;
}

/* === 27. 敷衍 — perfunctory (翻白眼 + 慢悠悠飘落的"哦/嗯/呵呵"气泡) === */
.perfunctory {
  background: linear-gradient(to bottom,
    rgba(176,184,196,0.55) 0%, rgba(176,184,196,0.25) 40%, transparent 68%);
}
.perfunctory .roll {
  position: absolute; top: 24%; left: 50%;
  font-size: 100px;
  filter: drop-shadow(0 6px 14px rgba(90,100,120,0.35));
  animation: kwPopIn 0.6s ease-out forwards, eyeRoll 2.4s ease-in-out 0.7s infinite;
}
@keyframes eyeRoll {
  0%, 100% { transform: translate(-50%, -50%) rotate(0deg); }
  30% { transform: translate(-50%, -50%) rotate(-14deg) translateY(-8px); }
  60% { transform: translate(-50%, -50%) rotate(10deg); }
}
.perfunctory .meh {
  position: absolute; top: -60px;
  padding: 8px 20px; border-radius: 18px 18px 18px 4px;
  background: rgba(255,255,255,0.95); color: #5d6878;
  font-size: 22px; font-weight: 600;
  box-shadow: 0 4px 12px rgba(80,90,110,0.2);
  opacity: 0;
  animation: mehFall 4.2s linear forwards;
}
@keyframes mehFall {
  0%   { transform: translateY(0) rotate(0deg); opacity: 0; }
  12%  { opacity: 1; }
  50%  { transform: translateY(40vh) rotate(-5deg); }
  100% { transform: translateY(88vh) rotate(6deg); opacity: 0; }
}

/* === 28. 漏回信息/忘记回了 — missedreply (手机狂震 + 红色角标弹出 + 🙈道歉) === */
.missedreply {
  background: linear-gradient(to bottom,
    rgba(255,170,170,0.5) 0%, rgba(255,190,180,0.22) 38%, transparent 65%);
}
.missedreply .phone {
  position: absolute; top: 28%; left: 50%;
  font-size: 100px;
  filter: drop-shadow(0 8px 18px rgba(220,80,80,0.35));
  animation: kwPopIn 0.5s ease-out forwards, phoneBuzz 0.5s linear 0.7s 6;
}
@keyframes phoneBuzz {
  0%, 100% { transform: translate(-50%, -50%) rotate(0); }
  20% { transform: translate(calc(-50% - 5px), -50%) rotate(-5deg); }
  40% { transform: translate(calc(-50% + 5px), -50%) rotate(5deg); }
  60% { transform: translate(calc(-50% - 4px), -50%) rotate(-4deg); }
  80% { transform: translate(calc(-50% + 4px), -50%) rotate(3deg); }
}
.missedreply .badge {
  position: absolute; min-width: 34px; height: 34px; padding: 0 9px;
  border-radius: 17px; background: #ff3b30; color: #fff;
  font-size: 17px; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 12px rgba(255,59,48,0.45);
  opacity: 0;
  animation: badgePop 2.6s ease-out forwards;
}
@keyframes badgePop {
  0%   { opacity: 0; transform: scale(0); }
  20%  { opacity: 1; transform: scale(1.25); }
  32%  { transform: scale(1); }
  80%  { opacity: 1; }
  100% { opacity: 0; transform: scale(0.85) translateY(-14px); }
}
.missedreply .sorry {
  position: absolute; bottom: 24%; left: 50%;
  font-size: 84px; opacity: 0;
  filter: drop-shadow(0 6px 14px rgba(180,80,80,0.3));
  animation: sorryRise 1s ease-out forwards;
}
@keyframes sorryRise {
  0%   { opacity: 0; transform: translateX(-50%) translateY(36px) scale(0.6); }
  60%  { opacity: 1; transform: translateX(-50%) translateY(-6px) scale(1.08); }
  100% { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}

/* === 29. 先忙 — busynow (埋头敲键盘 + 文件横飞 + 忙碌中挂牌) === */
.busynow {
  background: linear-gradient(to bottom,
    rgba(150,180,200,0.5) 0%, rgba(150,180,200,0.22) 40%, transparent 66%);
}
.busynow .worker {
  position: absolute; top: 26%; left: 50%;
  font-size: 100px;
  filter: drop-shadow(0 8px 18px rgba(60,90,120,0.35));
  animation: kwPopIn 0.6s ease-out forwards, workType 0.55s ease-in-out 0.7s infinite;
}
@keyframes workType {
  0%, 100% { transform: translate(-50%, -50%) translateY(0); }
  50% { transform: translate(-50%, -50%) translateY(-6px) rotate(-2deg); }
}
.busynow .flydoc {
  position: absolute; left: 0; opacity: 0;
  filter: drop-shadow(0 3px 8px rgba(60,90,120,0.25));
  animation: docFly 3s linear forwards;
}
@keyframes docFly {
  0%   { transform: translateX(-15vw) rotate(0deg); opacity: 0; }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { transform: translateX(115vw) rotate(35deg); opacity: 0; }
}
.busynow .busy-sign {
  position: absolute; bottom: 22%; left: 50%; transform: translateX(-50%);
  padding: 10px 24px; border-radius: 999px;
  background: rgba(255,255,255,0.94); color: #46627e;
  font-size: 20px; font-weight: 700;
  box-shadow: 0 6px 18px rgba(60,90,120,0.28);
  opacity: 0;
  animation: signSwing 1s ease-out forwards;
}
@keyframes signSwing {
  0%   { opacity: 0; transform: translateX(-50%) translateY(30px) rotate(-6deg); }
  55%  { opacity: 1; transform: translateX(-50%) translateY(-6px) rotate(3deg); }
  100% { opacity: 1; transform: translateX(-50%) translateY(0) rotate(0deg); }
}

/* ============================================================
   节假日场景重构（中元/重阳/腊八/妇女/劳动/教师/愚人/七夕）
   背景渐变由 play() 按节日主题色内联生成，这里只做场景元素
   ============================================================ */

/* 共用：从地面长出来的绽放（重阳菊花/妇女节郁金香/教师节苹果） */
@keyframes bloomUp {
  0%   { opacity: 0; transform: scale(0) rotate(-20deg); }
  70%  { opacity: 1; transform: scale(1.15) rotate(5deg); }
  100% { opacity: 1; transform: scale(1) rotate(0deg); }
}

/* === 中元节 — 河灯顺流而下 + 烛火余烬 + 薄雾 === */
.zhongyuan .lotus {
  position: absolute; bottom: 16%; left: 0; opacity: 0;
  animation: lotusDrift 9s linear forwards;
}
.zhongyuan .lotus .lotus-inner {
  display: block; font-size: 46px;
  filter: drop-shadow(0 0 16px rgba(255,180,80,0.85));
  animation: lotusBob 2.6s ease-in-out infinite;
}
@keyframes lotusDrift {
  0%   { transform: translateX(108vw); opacity: 0; }
  8%   { opacity: 1; }
  90%  { opacity: 1; }
  100% { transform: translateX(-15vw); opacity: 0; }
}
@keyframes lotusBob {
  0%, 100% { transform: translateY(0) rotate(-4deg); }
  50% { transform: translateY(-7px) rotate(4deg); }
}
.zhongyuan .ember {
  position: absolute; width: 4px; height: 4px; border-radius: 50%;
  background: #ffc46b; box-shadow: 0 0 8px 2px rgba(255,170,60,0.7);
  opacity: 0; animation: emberRise 4.5s ease-out forwards;
}
@keyframes emberRise {
  0%   { opacity: 0; transform: translate(0, 0); }
  15%  { opacity: 0.9; }
  100% { opacity: 0; transform: translate(16px, -45vh); }
}
.zhongyuan .mist {
  position: absolute; width: 46vw; height: 60px; border-radius: 50%;
  background: rgba(220,225,235,0.16); filter: blur(18px);
  opacity: 0; animation: mistDrift 8s linear forwards;
}
@keyframes mistDrift {
  0%   { transform: translateX(-30vw); opacity: 0; }
  15%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { transform: translateX(85vw); opacity: 0; }
}

/* === 重阳节 — 远山 + 菊花次第盛开 + 秋叶飘落 === */
.chongyang .mount {
  position: absolute; bottom: 12%; left: 50%; font-size: 120px; opacity: 0;
  filter: drop-shadow(0 8px 20px rgba(120,90,40,0.35));
  animation: mountRise 1s ease-out forwards;
}
@keyframes mountRise {
  0%   { opacity: 0; transform: translateX(-50%) translateY(40px) scale(0.7); }
  100% { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}
.chongyang .bloom {
  position: absolute; bottom: 14%; opacity: 0;
  transform-origin: bottom center;
  filter: drop-shadow(0 4px 10px rgba(180,140,30,0.3));
  animation: bloomUp 1s ease-out forwards;
}
.chongyang .leaf {
  position: absolute; top: -50px; opacity: 0;
  animation: leafFloat 5.5s linear forwards;
}
@keyframes leafFloat {
  0%   { opacity: 0; transform: translate(0, 0) rotate(0deg); }
  10%  { opacity: 1; }
  50%  { transform: translate(-44px, 40vh) rotate(160deg); }
  100% { opacity: 0; transform: translate(32px, 86vh) rotate(360deg); }
}

/* === 腊八节 — 大碗腊八粥 + 食材飞入 + 升腾热气 === */
.laba .bowl {
  position: absolute; top: 46%; left: 50%; font-size: 110px;
  filter: drop-shadow(0 10px 22px rgba(140,80,30,0.4));
  animation: kwPopIn 0.7s ease-out forwards;
}
.laba .steam-line {
  position: absolute; width: 10px; height: 46px; border-radius: 8px;
  background: rgba(255,255,255,0.78); filter: blur(6px);
  opacity: 0; animation: steamUp2 2.2s ease-in-out infinite;
}
@keyframes steamUp2 {
  0%   { opacity: 0; transform: translateY(12px) scaleY(0.7); }
  35%  { opacity: 0.8; }
  100% { opacity: 0; transform: translateY(-48px) scaleY(1.3); }
}
.laba .ingr {
  position: absolute; top: 44%; left: 50%; font-size: 34px; opacity: 0;
  animation: ingrIn 1.3s cubic-bezier(.3,.7,.4,1) forwards;
}
@keyframes ingrIn {
  0%   { opacity: 0; transform: translate(var(--fx, -40vw), var(--fy, -30vh)) scale(0.7) rotate(0deg); }
  20%  { opacity: 1; }
  82%  { opacity: 1; transform: translate(0, 0) scale(1) rotate(330deg); }
  100% { opacity: 0; transform: translate(0, 12px) scale(0.3) rotate(360deg); }
}

/* === 妇女节 — 花束 + 郁金香列队盛开 + 花瓣雨 + 蝴蝶 === */
.womens .bouquet {
  position: absolute; top: 30%; left: 50%; font-size: 100px;
  filter: drop-shadow(0 8px 20px rgba(220,80,140,0.4));
  animation: kwPopIn 0.7s ease-out forwards, kwBob 3s ease-in-out 0.8s infinite;
}
.womens .tulip {
  position: absolute; bottom: 12%; opacity: 0;
  transform-origin: bottom center;
  filter: drop-shadow(0 4px 10px rgba(220,80,140,0.25));
  animation: bloomUp 0.9s ease-out forwards;
}
.womens .petalfall {
  position: absolute; top: -40px; opacity: 0;
  animation: kwFall 5s linear forwards;
}
.womens .bfly {
  position: absolute; font-size: 30px;
  filter: drop-shadow(0 3px 8px rgba(160,80,200,0.3));
  animation: kwFlyAcross 6s linear forwards;
}

/* === 劳动节 — 工人抡锤 + 旋转齿轮 + 火花四溅 === */
.labor .builder {
  position: absolute; top: 32%; left: 44%; font-size: 96px;
  filter: drop-shadow(0 8px 18px rgba(160,90,30,0.35));
  animation: kwPopIn 0.6s ease-out forwards;
}
.labor .hammer {
  position: absolute; top: 24%; left: 56%; font-size: 58px;
  transform-origin: 85% 85%;
  filter: drop-shadow(0 4px 12px rgba(80,60,30,0.4));
  animation: hammerSwing 0.7s ease-in-out 0.6s infinite;
}
@keyframes hammerSwing {
  0%, 100% { transform: rotate(-38deg); }
  45% { transform: rotate(22deg); }
  58% { transform: rotate(18deg); }
}
.labor .gear {
  position: absolute; opacity: 0.85;
  filter: drop-shadow(0 4px 10px rgba(60,70,90,0.3));
  animation: gearSpin 5s linear infinite;
}
.labor .gear.rev { animation-direction: reverse; animation-duration: 3.6s; }
@keyframes gearSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
.labor .impact {
  position: absolute; font-size: 32px; opacity: 0;
  animation: impactPop 0.5s ease-out forwards;
}
@keyframes impactPop {
  0%   { opacity: 0; transform: scale(0.3); }
  40%  { opacity: 1; transform: scale(1.35); }
  100% { opacity: 0; transform: scale(1.8); }
}

/* === 教师节 — 黑板粉笔字逐字写出 + 讲台苹果 + 文具飘起 === */
.teacher .board {
  position: absolute; top: 24%; left: 50%; transform: translateX(-50%);
  width: min(74vw, 420px); padding: 28px 18px;
  border-radius: 14px; background: #2e4d3a;
  border: 10px solid #8b5a2b;
  box-shadow: 0 12px 32px rgba(0,0,0,0.35), inset 0 0 40px rgba(0,0,0,0.25);
  text-align: center; opacity: 0;
  animation: kwFadeIn 0.7s ease-out forwards;
}
.teacher .chalk-char {
  display: inline-block; color: #fff; font-size: 36px; font-weight: 700;
  margin: 0 3px; opacity: 0;
  text-shadow: 0 0 8px rgba(255,255,255,0.45);
  animation: chalkIn 0.4s ease-out forwards;
}
@keyframes chalkIn {
  0%   { opacity: 0; transform: translateY(10px) rotate(-8deg) scale(0.7); }
  100% { opacity: 1; transform: translateY(0) rotate(0deg) scale(1); }
}
.teacher .apple-pop {
  position: absolute; font-size: 54px; opacity: 0;
  transform-origin: bottom center;
  filter: drop-shadow(0 5px 12px rgba(180,40,40,0.4));
  animation: bloomUp 0.8s ease-out forwards;
}
.teacher .floaty {
  position: absolute; opacity: 0;
  filter: drop-shadow(0 4px 10px rgba(40,80,50,0.25));
  animation: kwFloatUp 5s ease-out forwards;
}

/* === 愚人节 — 变脸小丑 + 翻滚的扑克牌 + 彩屑 === */
.aprilfool .joker {
  position: absolute; top: 28%; left: 50%; font-size: 100px;
  filter: drop-shadow(0 8px 18px rgba(140,60,180,0.4));
  animation: kwPopIn 0.5s ease-out forwards, jokerWobble 1s ease-in-out 0.6s infinite;
}
@keyframes jokerWobble {
  0%, 100% { transform: translate(-50%, -50%) rotate(-8deg) scale(1); }
  50% { transform: translate(-50%, -50%) rotate(8deg) scale(1.08); }
}
.aprilfool .card {
  position: absolute; font-size: 40px; opacity: 0;
  animation: cardTumble 3.2s linear forwards;
}
@keyframes cardTumble {
  0%   { transform: translate(-12vw, 0) rotate(0deg); opacity: 0; }
  10%  { opacity: 1; }
  90%  { opacity: 1; }
  100% { transform: translate(112vw, -70px) rotate(720deg); opacity: 0; }
}
.aprilfool .conf {
  position: absolute; width: 8px; height: 14px; top: -20px; opacity: 0;
  animation: confettiFall 3.5s linear forwards;
}

/* === 七夕 — 星河 + 喜鹊搭桥 + 双星相会迸出爱心 === */
.qixi .tw {
  position: absolute; width: 4px; height: 4px; border-radius: 50%;
  background: #fff; box-shadow: 0 0 7px 2px rgba(255,220,255,0.75);
  animation: kwTwinkle 2.4s ease-in-out infinite;
}
.qixi .magpie {
  position: absolute; font-size: 26px; opacity: 0;
  filter: drop-shadow(0 0 8px rgba(180,200,255,0.5));
  animation: magpiePop 0.5s ease-out forwards;
}
@keyframes magpiePop {
  0%   { opacity: 0; transform: scale(0) translateY(14px); }
  70%  { opacity: 1; transform: scale(1.2) translateY(-3px); }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}
.qixi .lover {
  position: absolute; top: 30%; font-size: 52px; opacity: 0;
}
.qixi .lover.left {
  left: 7%;
  filter: drop-shadow(0 0 18px rgba(255,215,80,0.9));
  animation: loverMeetL 3s ease-in-out forwards;
}
.qixi .lover.right {
  right: 7%;
  filter: drop-shadow(0 0 18px rgba(255,120,200,0.9));
  animation: loverMeetR 3s ease-in-out forwards;
}
@keyframes loverMeetL {
  0%   { opacity: 0; transform: translateX(0); }
  18%  { opacity: 1; }
  100% { opacity: 1; transform: translateX(37vw); }
}
@keyframes loverMeetR {
  0%   { opacity: 0; transform: translateX(0); }
  18%  { opacity: 1; }
  100% { opacity: 1; transform: translateX(-37vw); }
}
.qixi .meet {
  position: absolute; top: 27%; left: 50%; font-size: 84px; opacity: 0;
  filter: drop-shadow(0 0 24px rgba(255,140,200,0.9));
  animation: meetBurst 1.2s ease-out forwards;
}
@keyframes meetBurst {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.2); }
  45%  { opacity: 1; transform: translate(-50%, -50%) scale(1.35); }
  70%  { transform: translate(-50%, -50%) scale(0.95); }
  100% { opacity: 1; transform: translate(-50%, -50%) scale(1.05); }
}
.qixi .heart-spark {
  position: absolute; top: 30%; left: 50%; font-size: 24px; opacity: 0;
  animation: heartSpray 1.5s ease-out forwards;
}
@keyframes heartSpray {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.4); }
  25%  { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--tx, 0px)), calc(-50% + var(--ty, -80px))) scale(1); }
}

/* ===== 天气动画 ===== */
/* 天气动画背景：iOS 动态毛玻璃 —— backdrop-filter 把身后聊天真实模糊+提饱和，
   再叠一层按天气情绪上色的半透明材质。聊天被磨砂化、动画浮在玻璃上，层次清楚，7s 后随动画淡出。 */
.animation-wrapper.weather {
  overflow: hidden;
  backdrop-filter: blur(22px) saturate(160%);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
}
.animation-wrapper.w-night   { background: linear-gradient(to bottom, rgba(16,24,60,0.58),   rgba(16,24,60,0.34)); }
.animation-wrapper.w-sunny   { background: linear-gradient(to bottom, rgba(110,180,255,0.44), rgba(255,222,150,0.3)); }
.animation-wrapper.w-cloudy  { background: linear-gradient(to bottom, rgba(120,140,160,0.5),  rgba(150,165,180,0.32)); }
.animation-wrapper.w-rainy   { background: linear-gradient(to bottom, rgba(58,78,108,0.54),   rgba(70,90,120,0.34)); }
.animation-wrapper.w-snowy   { background: linear-gradient(to bottom, rgba(150,175,205,0.5),  rgba(182,202,226,0.32)); }
.animation-wrapper.w-thunder { background: linear-gradient(to bottom, rgba(38,38,68,0.6),     rgba(56,56,88,0.38)); }
.animation-wrapper.w-foggy   { background: linear-gradient(to bottom, rgba(150,160,170,0.52), rgba(178,188,198,0.36)); }
/* 夕阳 / 日出（暖色霞光毛玻璃）*/
.animation-wrapper.w-sunset  { background: linear-gradient(to bottom, rgba(255,138,80,0.5), rgba(126,70,130,0.36)); }
.animation-wrapper.w-dawn    { background: linear-gradient(to bottom, rgba(255,184,140,0.46), rgba(130,165,205,0.32)); }
/* 低空大太阳 + 光晕；夕阳下沉、日出上升 */
.weather-bigsun {
  position: absolute;
  left: 50%;
  bottom: 20%;
  width: 96px;
  height: 96px;
  margin-left: -48px;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 42%, #fff7da, #ffd070 45%, #ff9a3c 74%, rgba(255,154,60,0) 100%);
  box-shadow: 0 0 70px 24px rgba(255,170,80,0.5);
}
.w-sunset .weather-bigsun { animation: sunSet 6s ease-in forwards; }
.w-dawn .weather-bigsun { animation: sunRise 6s ease-out forwards; }
@keyframes sunSet { from { transform: translateY(-34px); opacity: 1; } to { transform: translateY(22px); opacity: 0.85; } }
@keyframes sunRise { from { transform: translateY(46px); opacity: 0.55; } to { transform: translateY(-12px); opacity: 1; } }
.weather-cloud.dusk { filter: brightness(0.8) sepia(0.4) hue-rotate(-15deg); }
.weather-cloud.dawn { filter: brightness(1.05) sepia(0.25); }

/* 繁星流星（晴 + 夜）*/
.animation-wrapper.w-meteor { background: linear-gradient(to bottom, rgba(12,18,46,0.64), rgba(22,30,70,0.42)); }
.weather-meteor {
  position: absolute;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 6px 2px rgba(255,255,255,0.9);
  animation: meteorShoot 1.4s ease-in forwards;
}
.weather-meteor::after {
  content: '';
  position: absolute;
  right: 3px; top: 50%;
  width: 110px; height: 2px;
  transform: translateY(-50%) rotate(33deg);
  transform-origin: right center;
  background: linear-gradient(to left, rgba(255,255,255,0.85), transparent);
}
@keyframes meteorShoot {
  0% { transform: translate(0,0); opacity: 0; }
  12% { opacity: 1; }
  100% { transform: translate(-200px, 130px); opacity: 0; }
}
/* 烈日炎炎（晴 + 白天 + 高温）*/
.animation-wrapper.w-scorching { background: linear-gradient(to bottom, rgba(255,168,58,0.5), rgba(255,118,40,0.34)); }
.weather-bigsun.hot {
  background: radial-gradient(circle at 50% 45%, #fffbe6, #ffd84d 40%, #ff7a1c 75%, rgba(255,122,28,0) 100%);
  box-shadow: 0 0 90px 34px rgba(255,140,40,0.55);
  animation: hotPulse 2.2s ease-in-out infinite;
}
@keyframes hotPulse { 0%,100% { transform: scale(1); filter: brightness(1); } 50% { transform: scale(1.06); filter: brightness(1.15); } }
.heat-shimmer {
  position: absolute;
  bottom: 0; width: 3px; height: 52%;
  background: linear-gradient(to top, rgba(255,255,255,0.18), transparent);
  filter: blur(2px);
  animation: heatShimmer 1.6s ease-in-out infinite;
}
@keyframes heatShimmer { 0%,100% { transform: translateX(0) scaleY(1); opacity: .5; } 50% { transform: translateX(6px) scaleY(1.08); opacity: .9; } }
/* 晴间多云 */
.animation-wrapper.w-partly { background: linear-gradient(to bottom, rgba(120,185,255,0.44), rgba(200,225,255,0.3)); }
/* 雨后彩虹 */
.animation-wrapper.w-rainbow { background: linear-gradient(to bottom, rgba(120,160,210,0.46), rgba(192,212,236,0.3)); }
.weather-rainbow {
  position: absolute;
  left: 50%; bottom: 8%;
  width: 460px; height: 230px;
  margin-left: -230px;
  overflow: hidden;
  opacity: 0;
  animation: rainbowIn 1.4s ease forwards;
}
.weather-rainbow::before {
  content: '';
  position: absolute;
  left: 0; top: 0;
  width: 460px; height: 460px;
  background: radial-gradient(circle at 50% 50%,
    transparent 0 63%,
    rgba(154,107,255,0.8) 63% 66%,
    rgba(77,184,255,0.8) 66% 69%,
    rgba(90,214,90,0.8) 69% 72%,
    rgba(255,227,77,0.8) 72% 75%,
    rgba(255,167,51,0.8) 75% 78%,
    rgba(255,77,77,0.8) 78% 81%,
    transparent 81%);
}
@keyframes rainbowIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 0.9; transform: translateY(0); } }
.weather-fall {
  position: absolute;
  top: -8%;
  will-change: transform;
  animation: weatherFall linear forwards;
  pointer-events: none;
}
@keyframes weatherFall {
  0%   { transform: translateY(0); opacity: 0; }
  10%  { opacity: 1; }
  90%  { opacity: 1; }
  100% { transform: translateY(115vh); opacity: 0; }
}
.weather-sun {
  position: absolute;
  top: 14%;
  left: 50%;
  transform: translateX(-50%);
  font-size: 90px;
  filter: drop-shadow(0 0 24px rgba(255,200,90,0.6));
  animation: weatherPulse 3s ease-in-out infinite;
}
@keyframes weatherPulse {
  0%, 100% { transform: translateX(-50%) scale(1); }
  50%      { transform: translateX(-50%) scale(1.08); }
}
.weather-star {
  position: absolute;
  animation: weatherTwinkle 1.8s ease-in-out infinite;
  pointer-events: none;
}
@keyframes weatherTwinkle {
  0%, 100% { opacity: 0.25; }
  50%      { opacity: 1; }
}
.weather-cloud {
  position: absolute;
  left: -20%;
  will-change: transform;
  animation: weatherDrift linear infinite;
  opacity: 0.9;
  pointer-events: none;
}
@keyframes weatherDrift {
  0%   { transform: translateX(0); }
  100% { transform: translateX(140vw); }
}
.weather-fog {
  position: absolute;
  left: -30%;
  width: 60%;
  height: 80px;
  background: radial-gradient(ellipse at center, rgba(220,225,230,0.55) 0%, transparent 70%);
  filter: blur(8px);
  animation: weatherDrift linear infinite;
  pointer-events: none;
}
.weather-flash {
  position: absolute;
  inset: 0;
  background: rgba(255,255,255,0.85);
  animation: weatherFlash 0.6s ease-out forwards;
  pointer-events: none;
}
@keyframes weatherFlash {
  0%   { opacity: 0; }
  8%   { opacity: 1; }
  16%  { opacity: 0.2; }
  24%  { opacity: 0.9; }
  100% { opacity: 0; }
}

/* 尊重系统「减弱动态效果」:节日/天气全屏装饰动画收敛为瞬时到位、不循环闪烁(仍显示画面,只是不动) */
@media (prefers-reduced-motion: reduce) {
  #festival-layer, #festival-layer * {
    animation-duration: 0.001s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001s !important;
  }
}
