/* H5 版样式。原小程序里用 rpx；H5 用 --rpx 自定义属性映射到 vw。
   基准为屏幕宽 / 750，并轻微放大，让聊天内容更接近真机观感。 */
:root {
  --rpx: calc(0.13333vw * 1.18);
  --green: #95ec69;
  --pink:  #f0d5d5;
  --gray:  #ededed;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* HTML `hidden` 属性默认是 display:none，但会被 .gate { display: flex } 等覆盖。
   显式强制一下，避免锁定/解锁时 gate 隐藏不了的怪 bug。 */
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0;
  width: 100%; height: 100%;
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: calc(28 * var(--rpx));
  color: #1a1a1a;
  overflow: hidden;
  background: var(--gray);
  -webkit-font-smoothing: antialiased;
}

/* ===================== 学习练习页 ===================== */
.study-screen {
  position: fixed;
  inset: 0;
  z-index: 1200;
  overflow-y: auto;
  background:
    linear-gradient(135deg, rgba(253, 246, 224, 0.92), rgba(224, 244, 238, 0.94)),
    #f7f4ea;
  color: #20312d;
}
.study-shell {
  min-height: 100%;
  width: min(100%, 760px);
  margin: 0 auto;
  padding: max(28px, env(safe-area-inset-top, 0px)) 18px max(28px, env(safe-area-inset-bottom, 0px));
  display: grid;
  align-content: center;
  gap: 16px;
}
.study-hero {
  padding: 8px 2px 2px;
}
.study-kicker {
  margin: 0 0 8px;
  color: #2f7d68;
  font-size: 14px;
  font-weight: 700;
}
.study-hero h1 {
  margin: 0;
  font-size: clamp(30px, 8vw, 54px);
  line-height: 1.05;
  letter-spacing: 0;
}
.study-hero p {
  margin: 12px 0 0;
  color: #5b665f;
  font-size: 16px;
  line-height: 1.6;
}
.study-panel,
.study-note {
  background: rgba(255, 255, 255, 0.78);
  border: 1px solid rgba(65, 96, 82, 0.16);
  border-radius: 8px;
  box-shadow: 0 18px 46px rgba(37, 55, 47, 0.12);
}
.study-panel {
  padding: 18px;
}
.study-progress {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  color: #5b665f;
  font-size: 14px;
}
.study-progress strong {
  color: #b4531f;
  font-size: 16px;
}
.study-question {
  min-height: 96px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 10px 0 16px;
  border-radius: 8px;
  background: #fff7dc;
  color: #1f2f2b;
  font-size: 44px;
  font-weight: 800;
  letter-spacing: 0;
}
.study-options {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.study-option {
  min-height: 54px;
  border: 1px solid rgba(32, 49, 45, 0.15);
  border-radius: 8px;
  background: #ffffff;
  color: #20312d;
  font-size: 22px;
  font-weight: 700;
  cursor: pointer;
}
.study-option:active {
  transform: scale(0.98);
}
.study-option.is-correct {
  background: #2f7d68;
  color: #fff;
}
.study-option.is-wrong {
  background: #d9564a;
  color: #fff;
}
.study-feedback {
  min-height: 22px;
  margin-top: 12px;
  color: #5b665f;
  font-size: 14px;
  text-align: center;
}
.study-note {
  padding: 16px 18px;
}
.study-note h2 {
  margin: 0 0 8px;
  font-size: 18px;
}
.study-note p {
  margin: 0;
  color: #5b665f;
  font-size: 15px;
  line-height: 1.7;
}

@media (max-width: 420px) {
  .study-shell {
    align-content: start;
    padding-top: max(22px, env(safe-area-inset-top, 0px));
  }
  .study-question {
    min-height: 86px;
    font-size: 38px;
  }
  .study-options {
    grid-template-columns: 1fr;
  }
}

/* ===================== 密码门：通用风格，无任何提示 ===================== */
.gate {
  position: fixed; inset: 0;
  display: flex; align-items: center; justify-content: center;
  z-index: 1000;
  overflow: hidden;
}
/* 背景：夜空渐变 + 星点装饰，纯审美，不暗示内容 */
.gate-bg {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 60% 80% at 20% 30%, rgba(255,210,230,0.45) 0%, transparent 60%),
    radial-gradient(ellipse 50% 70% at 80% 70%, rgba(180,200,255,0.40) 0%, transparent 60%),
    linear-gradient(180deg, #1f1535 0%, #3a2552 45%, #6a3f6a 100%);
}
/* 用 CSS 画出几粒星 */
.gate-bg::before, .gate-bg::after {
  content: ""; position: absolute; inset: 0;
  background-image:
    radial-gradient(1px 1px at 12% 18%, white, transparent 50%),
    radial-gradient(1px 1px at 28% 65%, white, transparent 50%),
    radial-gradient(1.5px 1.5px at 47% 28%, rgba(255,255,255,0.9), transparent 50%),
    radial-gradient(1px 1px at 68% 12%, white, transparent 50%),
    radial-gradient(1.2px 1.2px at 76% 48%, rgba(255,255,255,0.85), transparent 50%),
    radial-gradient(1px 1px at 88% 78%, white, transparent 50%),
    radial-gradient(2px 2px at 35% 82%, rgba(255,255,255,0.7), transparent 50%),
    radial-gradient(1.5px 1.5px at 58% 90%, white, transparent 50%);
  opacity: 0.85;
  animation: twinkle 4.5s ease-in-out infinite alternate;
}
.gate-bg::after {
  background-image:
    radial-gradient(1px 1px at 18% 78%, white, transparent 50%),
    radial-gradient(1px 1px at 41% 55%, white, transparent 50%),
    radial-gradient(1px 1px at 62% 30%, white, transparent 50%),
    radial-gradient(1.2px 1.2px at 80% 22%, rgba(255,255,255,0.9), transparent 50%),
    radial-gradient(1px 1px at 92% 60%, white, transparent 50%);
  animation-delay: 2s;
  animation-duration: 5.5s;
}
@keyframes twinkle {
  from { opacity: 0.35; }
  to   { opacity: 0.95; }
}

/* 玻璃拟态卡片 */
.gate-card {
  position: relative;
  width: 86%; max-width: 320px;
  padding: 36px 28px 24px;
  border-radius: 24px;
  background: rgba(255,255,255,0.10);
  border: 1px solid rgba(255,255,255,0.18);
  box-shadow:
    0 10px 40px rgba(0,0,0,0.25),
    inset 0 1px 0 rgba(255,255,255,0.15);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  text-align: center;
}

.gate-icon {
  width: 64px; height: 64px;
  margin: 0 auto 20px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: rgba(255,255,255,0.12);
  color: rgba(255,255,255,0.85);
  border: 1px solid rgba(255,255,255,0.18);
}

.gate-card input {
  width: 100%;
  padding: 14px 16px;
  background: rgba(255,255,255,0.10);
  color: white;
  border: 1px solid rgba(255,255,255,0.25);
  border-radius: 12px;
  font-size: 15px;
  outline: none;
  margin-bottom: 14px;
  text-align: center;
  letter-spacing: 0.08em;
  transition: border-color 0.2s, background 0.2s;
}
.gate-card input::placeholder { color: rgba(255,255,255,0.5); letter-spacing: 0; }
.gate-card input:focus {
  background: rgba(255,255,255,0.16);
  border-color: rgba(255,255,255,0.5);
}

.gate-card button {
  width: 100%;
  padding: 14px 16px;
  background: rgba(255,255,255,0.92);
  color: #2a1a3a;
  border: 0;
  border-radius: 12px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.05em;
  cursor: pointer;
  transition: transform 0.1s, background 0.2s;
}
.gate-card button:hover   { background: white; }
.gate-card button:active  { transform: scale(0.98); }
.gate-card button:disabled{ opacity: 0.6; cursor: not-allowed; }

.gate-err     { color: #ffc1c1; font-size: 13px; min-height: 18px; margin-top: 14px; }
.gate-loading { color: rgba(255,255,255,0.7); font-size: 13px; margin-top: 14px; }

/* ===================== 页面 ===================== */
.page {
  width: 100%; height: 100vh;
  position: relative; overflow: hidden;
  background: var(--gray);
}
.page-flipped { background: var(--pink); }

/* ===================== 顶栏 ===================== */
.navbar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  background: var(--gray);   /* 两个视角共用同一灰色顶栏 */
  padding-top: env(safe-area-inset-top, 0);
}
.nav-title {
  height: calc(88 * var(--rpx));
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  font-weight: 600; line-height: 1.15;
  cursor: pointer;
}
.nav-title-text { font-size: calc(30 * var(--rpx)); }
.nav-sub { font-size: calc(20 * var(--rpx)); color: #888; font-weight: 400; margin-top: calc(4 * var(--rpx)); }

/* 跳转面板 */
.jump-panel {
  background: #f7f7f7;
  border-top: 1px solid #e5e5e5;
  padding: calc(16 * var(--rpx)) calc(32 * var(--rpx)) calc(20 * var(--rpx));
}
.jump-row {
  display: flex; align-items: center; gap: calc(16 * var(--rpx));
  background: white;
  border-radius: calc(12 * var(--rpx));
  padding: calc(20 * var(--rpx)) calc(24 * var(--rpx));
  margin-bottom: calc(12 * var(--rpx));
  position: relative;
}
.jump-label { color: #888; font-size: calc(26 * var(--rpx)); }
.jump-value { flex: 1; font-size: calc(30 * var(--rpx)); color: #1a1a1a; }
.jump-arrow { color: #c8c8c8; font-size: calc(36 * var(--rpx)); }
.jump-flip {
  color: #07c160;
  font-size: calc(26 * var(--rpx));
  background: rgba(7, 193, 96, 0.1);
  padding: calc(4 * var(--rpx)) calc(14 * var(--rpx));
  border-radius: calc(6 * var(--rpx));
  cursor: pointer;
}
.jump-tip { margin-top: calc(12 * var(--rpx)); text-align: center; color: #999; font-size: calc(22 * var(--rpx)); }

/* === 搜索 === */
.search-wrap {
  display: flex; align-items: center; gap: calc(12 * var(--rpx));
  background: white;
  border-radius: calc(12 * var(--rpx));
  padding: calc(14 * var(--rpx)) calc(20 * var(--rpx));
  margin-bottom: calc(12 * var(--rpx));
}
.search-wrap input {
  flex: 1;
  border: 0; outline: none;
  font-size: calc(28 * var(--rpx));
  background: transparent;
  color: #1a1a1a;
}
.search-count {
  font-size: calc(22 * var(--rpx));
  color: #888;
  white-space: nowrap;
}
.search-results {
  max-height: calc(560 * var(--rpx));
  overflow-y: auto;
  margin-bottom: calc(12 * var(--rpx));
}
.search-results:empty { margin: 0; }
.search-result {
  background: white;
  border-radius: calc(10 * var(--rpx));
  padding: calc(14 * var(--rpx)) calc(20 * var(--rpx));
  margin-bottom: calc(8 * var(--rpx));
  cursor: pointer;
  transition: background 0.1s;
}
.search-result:active { background: #f0f0f0; }
.search-meta {
  font-size: calc(22 * var(--rpx));
  color: #999;
  margin-bottom: calc(6 * var(--rpx));
}
.search-snippet {
  font-size: calc(26 * var(--rpx));
  color: #1a1a1a;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
.search-snippet mark {
  background: #fff066;
  color: inherit;
  padding: 0 2rpx;
}

/* 搜索跳转后被命中那条消息：闪一下高亮 */
@keyframes searchHit {
  0%   { background: rgba(255, 235, 60, 0.7); }
  100% { background: transparent; }
}
.search-hit .bubble {
  animation: searchHit 2s ease-out;
}

/* 月份选择器：原生 select 盖在 row 上、透明，点击触发系统弹层 */
.month-select {
  position: absolute; inset: 0;
  opacity: 0;
  font-size: 16px;
  appearance: none; -webkit-appearance: none;
}

/* ===================== 主区域 + 内容滚动 ===================== */
.main {
  position: absolute;
  left: 0; right: 0;
  top: calc(env(safe-area-inset-top, 0px) + 88 * var(--rpx));
  /* 让出输入栏空间：内容高度 100rpx + iPhone 底部安全区 */
  bottom: calc(100 * var(--rpx) + env(safe-area-inset-bottom, 0px));
}
.chat-bg {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: 0;
  pointer-events: none;
}
.chat {
  width: 100%; height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  position: relative; z-index: 1;
  /* iOS 弹性滚动 */
  -webkit-overflow-scrolling: touch;
}

.more-tip {
  text-align: center;
  color: #999;
  font-size: calc(22 * var(--rpx));
  padding: calc(24 * var(--rpx)) 0;
}

.time-sep {
  text-align: center;
  padding: calc(24 * var(--rpx)) 0 calc(12 * var(--rpx));
  cursor: pointer;
}
.time-sep span {
  color: #9a9a9a;
  font-size: calc(22 * var(--rpx));
}

.sys {
  text-align: center;
  padding: calc(12 * var(--rpx)) calc(80 * var(--rpx));
}
.sys span {
  color: #9a9a9a;
  font-size: calc(22 * var(--rpx));
}

.row {
  display: flex;
  padding: calc(10 * var(--rpx)) calc(22 * var(--rpx));
  align-items: flex-start;
  gap: calc(14 * var(--rpx));
}
.row-me { flex-direction: row-reverse; }

.avatar {
  width: calc(72 * var(--rpx)); height: calc(72 * var(--rpx));
  border-radius: calc(10 * var(--rpx));
  flex-shrink: 0;
  overflow: hidden;
  background: #eee;
}
.avatar img { width: 100%; height: 100%; display: block; object-fit: cover; }

.bubble-wrap {
  max-width: calc(520 * var(--rpx));
  display: flex;
}
.row-me .bubble-wrap { justify-content: flex-end; }

.bubble {
  display: inline-block;
  padding: calc(14 * var(--rpx)) calc(18 * var(--rpx));
  border-radius: calc(8 * var(--rpx));
  font-size: calc(28 * var(--rpx));
  line-height: 1.45;
  word-break: break-word;
  position: relative;
  max-width: 100%;
}
.bubble-me { background: var(--green); }
.bubble-ta { background: #ffffff; }

/* 语音气泡 */
.voice-bubble {
  cursor: pointer;
  user-select: none;
  display: inline-flex;
  align-items: center;
  gap: calc(14 * var(--rpx));
}
.voice-bubble audio { display: none; }
.voice-play {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: calc(36 * var(--rpx));
  height: calc(36 * var(--rpx));
  font-size: calc(22 * var(--rpx));
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.08);
  flex-shrink: 0;
}
.voice-bubble.bubble-me .voice-play { background: rgba(255, 255, 255, 0.35); }
.voice-bubble.voice-playing .voice-play {
  background: #ff5588;
  color: #fff;
  animation: voice-pulse 1.2s ease-in-out infinite;
}
@keyframes voice-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 85, 136, 0.6); }
  50%      { box-shadow: 0 0 0 calc(8 * var(--rpx)) rgba(255, 85, 136, 0); }
}
.voice-dur {
  font-size: calc(26 * var(--rpx));
  color: #555;
}
.voice-bubble.bubble-me .voice-dur { color: #1f3a1f; }

/* 气泡尖角：用固定 px 避免高 DPR 屏的亚像素渲染缝隙 */
.bubble-me::before, .bubble-ta::before {
  content: '';
  position: absolute;
  top: 10px;
  width: 0; height: 0;
  border: 6px solid transparent;
}
/* 三角底边整体嵌进气泡 2px，颜色同所以看不出，但能彻底消除缝隙 */
.bubble-me::before {
  right: -4px;
  border-left-color: var(--green);
  border-right: 0;
}
.bubble-ta::before {
  left: -4px;
  border-right-color: #ffffff;
  border-left: 0;
}

.bubble-card {
  font-size: calc(24 * var(--rpx));
  color: #555;
  background: #f5f5f5 !important;
  border-left: calc(6 * var(--rpx)) solid #c8c8c8;
}
.bubble-card::before { display: none; }
.bubble-card .quote { display: block; color: #888; margin-bottom: calc(8 * var(--rpx)); }

.sticker img {
  display: block;
  max-width: calc(160 * var(--rpx));
  max-height: calc(160 * var(--rpx));
  background: transparent;
}

/* 真实图片消息：自适应大小，最大宽度限制让长图不会撑爆气泡区 */
.chat-img-wrap {
  display: inline-block;
  max-width: 100%;
}
.chat-img {
  display: block;
  max-width: calc(420 * var(--rpx));
  max-height: calc(560 * var(--rpx));
  width: auto; height: auto;
  border-radius: calc(8 * var(--rpx));
  background: #eee;   /* 加载前的占位色 */
  object-fit: cover;
}

/* 内联表情图 */
.emj {
  width: calc(36 * var(--rpx));
  height: calc(36 * var(--rpx));
  vertical-align: calc(-8 * var(--rpx));
  margin: 0 calc(2 * var(--rpx));
}

/* ===================== 输入栏 ===================== */
.inputbar {
  position: fixed; left: 0; right: 0; bottom: 0;
  background: #f7f7f7;
  border-top: 1px solid #d8d8d8;
  display: flex; align-items: center;
  gap: calc(16 * var(--rpx));
  /* 用 padding 撑高，避免 box-sizing:border-box 把 safe-area 吃掉内容空间 */
  padding: calc(14 * var(--rpx)) calc(20 * var(--rpx));
  padding-bottom: calc(14 * var(--rpx) + env(safe-area-inset-bottom, 0px));
}
.inputbar-ic {
  width: calc(64 * var(--rpx)); height: calc(64 * var(--rpx));
  display: flex; align-items: center; justify-content: center;
  font-size: calc(36 * var(--rpx));
  color: #555;
  flex-shrink: 0;
}
.inputbar-box {
  flex: 1;
  height: calc(72 * var(--rpx));
  background: white;
  border-radius: calc(8 * var(--rpx));
}

/* ===================== 守护温暖 · 动画 ===================== */

/* 点头像后浮起的小爱心：position:fixed 直接锚到点击的视口坐标 */
.love-burst {
  position: fixed;
  z-index: 999;
  font-size: calc(80 * var(--rpx));
  pointer-events: none;
  user-select: none;
  transform: translate(-50%, -50%);
  animation: loveFloat 1.4s cubic-bezier(0.2, 0.7, 0.4, 1) forwards;
  will-change: transform, opacity;
}
@keyframes loveFloat {
  0%   { opacity: 0; transform: translate(-50%, -50%)  scale(0.3); }
  18%  { opacity: 1; transform: translate(-50%, -75%)  scale(1.25); }
  100% { opacity: 0; transform: translate(-50%, -220%) scale(1.6); }
}

/* 表情雨 */
.rain-drop {
  position: fixed;
  top: -40px;
  z-index: 997;
  pointer-events: none;
  user-select: none;
  animation: fallRain linear forwards;
  text-shadow: 0 0 8px rgba(255,200,220,0.4);
}
@keyframes fallRain {
  0%   { transform: translateY(0)     rotate(0deg);   opacity: 0; }
  10%  {                                              opacity: 1; }
  100% { transform: translateY(110vh) rotate(360deg); opacity: 0.4; }
}

/* 每日暖心卡片 */
.greeting-overlay {
  position: fixed;
  inset: 0;
  z-index: 998;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-top: 18vh;
  background: transparent;
  pointer-events: none;
}
.greeting-card {
  pointer-events: auto;
  cursor: pointer;
  min-width: calc(440 * var(--rpx));
  max-width: 84vw;
  max-height: 78vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  background: white;
  border-radius: calc(20 * var(--rpx));
  padding: calc(28 * var(--rpx)) calc(36 * var(--rpx));
  text-align: center;
  box-shadow:
    0 calc(8 * var(--rpx))  calc(30 * var(--rpx)) rgba(255, 110, 140, 0.18),
    0 calc(2 * var(--rpx))  calc(8 * var(--rpx))  rgba(0, 0, 0, 0.06);
  animation: greetIn 0.55s cubic-bezier(0.18, 0.89, 0.32, 1.28);
  will-change: transform, opacity;
}
.greeting-card.fade { animation: greetOut 0.4s ease-in forwards; }
.greeting-heart {
  font-size: calc(56 * var(--rpx));
  line-height: 1;
  margin-bottom: calc(12 * var(--rpx));
}
.greeting-text {
  font-size: calc(30 * var(--rpx));
  color: #4a2638;
  line-height: 1.45;
  white-space: pre-line;
}
.greeting-hint {
  font-size: calc(20 * var(--rpx));
  color: #b58fa0;
  margin-top: calc(14 * var(--rpx));
}
.greeting-subhint {
  margin-top: calc(6 * var(--rpx));
}
/* 长文案（生日长信等）：收紧字号/行距、左对齐，整体更紧凑易读 */
.greeting-card-long {
  max-height: 74vh;
}
.greeting-card-long .greeting-text {
  font-size: calc(26 * var(--rpx));
  line-height: 1.6;
  text-align: left;
}
/* 节日特别版：加点粉/红渐变背景 + 更厚阴影 */
.greeting-card-special {
  background: linear-gradient(135deg, #fff8fa 0%, #ffe5ee 100%);
  box-shadow:
    0 calc(12 * var(--rpx)) calc(40 * var(--rpx)) rgba(255, 80, 120, 0.28),
    0 0 0 1px rgba(255, 120, 150, 0.15);
}

@keyframes greetIn {
  0%   { opacity: 0; transform: translateY(-20px) scale(0.92); }
  100% { opacity: 1; transform: translateY(0)     scale(1);    }
}
@keyframes greetOut {
  0%   { opacity: 1; }
  100% { opacity: 0; transform: translateY(-8px) scale(0.96); }
}

/* 全屏大表情特效 —— 软光晕 + 主表情 + 飘落小粒子 */
.emoji-fx-overlay {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 999;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

/* 软粉色光晕，缓慢扩散淡出 */
.emoji-fx-halo {
  position: absolute;
  width: calc(560 * var(--rpx));
  height: calc(560 * var(--rpx));
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(255, 180, 200, 0.55) 0%,
    rgba(255, 180, 210, 0.25) 30%,
    rgba(255, 200, 220, 0.08) 55%,
    transparent 75%);
  animation: emoji-fx-halo 2.3s cubic-bezier(.22, 1, .36, 1) forwards;
  filter: blur(calc(8 * var(--rpx)));
}
@keyframes emoji-fx-halo {
  0%   { transform: scale(0.5); opacity: 0; }
  25%  { transform: scale(1);   opacity: 1; }
  70%  { transform: scale(1.15); opacity: 0.85; }
  100% { transform: scale(1.5); opacity: 0; }
}

/* 主表情：Unicode 渲染，无 bouncy 弹跳，缓出上浮 */
.emoji-fx-main {
  position: relative;
  font-size: calc(280 * var(--rpx));
  line-height: 1;
  animation: emoji-fx-main 2.3s cubic-bezier(.22, 1, .36, 1) forwards;
  filter: drop-shadow(0 calc(10 * var(--rpx)) calc(28 * var(--rpx)) rgba(255, 110, 150, 0.45));
}
@keyframes emoji-fx-main {
  0%   { transform: scale(0.4) translateY(calc(30 * var(--rpx))); opacity: 0; }
  25%  { transform: scale(1)   translateY(0);                      opacity: 1; }
  65%  { transform: scale(1.02) translateY(calc(-10 * var(--rpx))); opacity: 1; }
  100% { transform: scale(1.06) translateY(calc(-50 * var(--rpx))); opacity: 0; }
}

/* 飘落小粒子（小心心 / 星星 / 花瓣等），错峰升起淡出 */
.emoji-fx-particle {
  position: absolute;
  font-size: calc(60 * var(--rpx));
  opacity: 0;
  animation: emoji-fx-particle 2.2s ease-out forwards;
  filter: drop-shadow(0 calc(4 * var(--rpx)) calc(10 * var(--rpx)) rgba(255, 130, 160, 0.35));
}
@keyframes emoji-fx-particle {
  0%   { transform: translateY(0) scale(0.4) rotate(-10deg); opacity: 0; }
  20%  { opacity: 0.95; }
  60%  { opacity: 0.85; }
  100% { transform: translateY(calc(-260 * var(--rpx))) scale(1.1) rotate(12deg); opacity: 0; }
}

/* 拥抱：两个 PNG 从左右滑入，相遇时叠合 + 微微贴贴 + 飘起 */
.emoji-fx-hug {
  position: absolute;
  width: calc(140 * var(--rpx));
  height: calc(140 * var(--rpx));
  object-fit: contain;
  filter: drop-shadow(0 calc(6 * var(--rpx)) calc(18 * var(--rpx)) rgba(255, 110, 150, 0.4));
  will-change: transform, opacity;
}
.emoji-fx-hug-left {
  animation: emoji-fx-hug-left 2.6s cubic-bezier(.22, 1, .36, 1) forwards;
}
.emoji-fx-hug-right {
  animation: emoji-fx-hug-right 2.6s cubic-bezier(.22, 1, .36, 1) forwards;
}
@keyframes emoji-fx-hug-left {
  0%   { transform: translate(-60vw, 0) scale(0.45) rotate(0deg);   opacity: 0; }
  18%  { opacity: 1; }
  40%  { transform: translate(calc(-40 * var(--rpx)), 0) scale(1) rotate(-8deg); opacity: 1; }
  55%  { transform: translate(calc(-32 * var(--rpx)), calc(-3 * var(--rpx))) scale(1.05) rotate(-12deg); opacity: 1; }
  70%  { transform: translate(calc(-32 * var(--rpx)), calc(-3 * var(--rpx))) scale(1.03) rotate(-12deg); opacity: 1; }
  100% { transform: translate(calc(-32 * var(--rpx)), calc(-50 * var(--rpx))) scale(1.08) rotate(-12deg); opacity: 0; }
}
@keyframes emoji-fx-hug-right {
  0%   { transform: translate(60vw, 0) scale(0.45) rotate(0deg);   opacity: 0; }
  18%  { opacity: 1; }
  40%  { transform: translate(calc(40 * var(--rpx)), 0) scale(1) rotate(8deg); opacity: 1; }
  55%  { transform: translate(calc(32 * var(--rpx)), calc(-3 * var(--rpx))) scale(1.05) rotate(12deg); opacity: 1; }
  70%  { transform: translate(calc(32 * var(--rpx)), calc(-3 * var(--rpx))) scale(1.03) rotate(12deg); opacity: 1; }
  100% { transform: translate(calc(32 * var(--rpx)), calc(-50 * var(--rpx))) scale(1.08) rotate(12deg); opacity: 0; }
}

/* 拥抱中央炸心：相遇时（~0.7s 处）从原点向外辐射 */
.emoji-fx-burst {
  position: absolute;
  left: 50%;
  top: 50%;
  line-height: 1;
  opacity: 0;
  animation: emoji-fx-burst 1.6s cubic-bezier(.22, 1, .36, 1) forwards;
  animation-delay: 0.65s;
  filter: drop-shadow(0 calc(4 * var(--rpx)) calc(12 * var(--rpx)) rgba(255, 110, 150, 0.45));
  /* --dx / --dy 由 JS 设置（cos/sin），radial 距离 = 160rpx */
  --r: calc(160 * var(--rpx));
}
@keyframes emoji-fx-burst {
  0%   { transform: translate(-50%, -50%) scale(0.2); opacity: 0; }
  25%  { transform: translate(calc(-50% + var(--dx) * var(--r) * 0.55), calc(-50% + var(--dy) * var(--r) * 0.55)) scale(1.1); opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx) * var(--r)), calc(-50% + var(--dy) * var(--r))) scale(0.6); opacity: 0; }
}

/* PC 调试时锁定 750 设计稿等效宽度，方便对比小程序效果 */
@media (min-width: 768px) {
  :root { --rpx: calc(min(100vw, 480px) / 750 * 1.18); }
  .gate, .page { max-width: 480px; margin: 0 auto; }
}
