/* =====================================================
   beautify.css —— UI 美化增强层（v1 · 2026-10-02）
   纯增量覆盖：不修改 style.css，删除本文件引用即可完全还原
   全部基于主题 CSS 变量，五套主题自动适配
   ===================================================== */

/* ---------- 登录页：氛围光斑 ---------- */
.login-bg { opacity: 1; background: var(--bg); overflow: hidden; }
.login-bg::before,
.login-bg::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
  opacity: .55;
  animation: blobFloat 9s ease-in-out infinite alternate;
}
.login-bg::before {
  width: 62vw; height: 62vw;
  left: -18vw; top: -14vh;
  background: radial-gradient(circle at 30% 30%, var(--primary), transparent 70%);
}
.login-bg::after {
  width: 56vw; height: 56vw;
  right: -16vw; bottom: -12vh;
  background: radial-gradient(circle at 60% 60%, var(--accent), transparent 70%);
  animation-delay: -4.5s;
}
@keyframes blobFloat {
  from { transform: translate(0, 0) scale(1); }
  to   { transform: translate(6vw, 4vh) scale(1.15); }
}

/* 漂浮爱心（纯 CSS，两层错速） */
#loginPage::before,
#loginPage::after {
  content: "♥";
  position: absolute;
  left: 12%;
  bottom: -8vh;
  font-size: 18px;
  color: var(--primary);
  opacity: 0;
  pointer-events: none;
  text-shadow: 22vw -6vh 0 var(--accent), 46vw 4vh 0 var(--primary),
               68vw -10vh 0 var(--accent), 84vw 2vh 0 var(--primary);
  animation: heartRise 11s linear infinite;
  z-index: 0;
}
#loginPage::after { font-size: 13px; animation-duration: 15s; animation-delay: -6s; opacity: 0; }
@keyframes heartRise {
  0%   { transform: translateY(0) rotate(0deg); opacity: 0; }
  10%  { opacity: .5; }
  85%  { opacity: .35; }
  100% { transform: translateY(-105vh) rotate(24deg); opacity: 0; }
}

/* ---------- 登录卡片：玻璃拟态 ---------- */
.login-card {
  position: relative;
  z-index: 1;
  background: rgba(255, 255, 255, .68);
  backdrop-filter: blur(22px) saturate(1.4);
  -webkit-backdrop-filter: blur(22px) saturate(1.4);
  border: 1px solid rgba(255, 255, 255, .65);
  border-radius: 26px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, .10), var(--shadow);
  animation: cardIn .55s cubic-bezier(.22, 1.2, .36, 1) both;
}
body[data-theme="dark"] .login-card {
  background: rgba(38, 30, 48, .62);
  border-color: rgba(255, 255, 255, .10);
}
@keyframes cardIn {
  from { opacity: 0; transform: translateY(26px) scale(.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Logo：心跳 + 光环 */
.login-logo {
  box-shadow: 0 0 0 8px color-mix(in srgb, var(--primary) 14%, transparent), var(--shadow);
  animation: logoBeat 1.6s ease-in-out infinite;
}
.login-logo .mini-heart { animation: heartBeat 1.6s ease-in-out infinite; }
@keyframes logoBeat {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.05); }
}
@keyframes heartBeat {
  0%, 100% { transform: scale(1); }
  14%      { transform: scale(1.22); }
  28%      { transform: scale(1); }
  42%      { transform: scale(1.18); }
  56%      { transform: scale(1); }
}

/* 标题：渐变字 */
.login-title {
  background: var(--gradient);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--primary-deep); /* 兜底：不支持 background-clip 时仍可见 */
}

/* ---------- 输入框：聚焦微交互 ---------- */
.input {
  transition: border-color .25s, box-shadow .25s, transform .25s;
}
.input:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary) 16%, transparent);
  transform: translateY(-1px);
}

/* ---------- 主按钮：流光 + 按压反馈 ----------
   性能说明（本次改动）：
   · gradientShift 只动 background-position（合成友好），并把频率从 5s 降到 12s，
     大面积渐变重绘明显减少；
   · 扫光 ::after 原来动 left（每帧触发布局），改为只动 transform。 */
.btn-primary, .chat-send {
  position: relative;
  overflow: hidden;
  background-size: 160% 160%;
  animation: gradientShift 12s ease-in-out infinite;
  transition: transform .15s, box-shadow .25s, filter .25s;
}
.btn-primary:active, .chat-send:active {
  transform: scale(.95);
  filter: brightness(1.06);
  box-shadow: 0 4px 14px color-mix(in srgb, var(--primary) 40%, transparent);
}
/* 扫光：只动 transform（translate3d），不再动 left —— left 每帧都会触发
   布局与重排，是移动端掉帧的主要来源；视觉观感保持完全一致 */
.btn-primary::after {
  content: "";
  position: absolute;
  top: 0; left: -80%;
  width: 50%; height: 100%;
  background: linear-gradient(105deg, transparent, rgba(255,255,255,.45), transparent);
  transform: translate3d(0, 0, 0) skewX(-20deg);
  will-change: transform;
  animation: shine 3.6s ease-in-out infinite;
}
@keyframes shine {
  0%, 55%  { transform: translate3d(0, 0, 0) skewX(-20deg); }
  85%, 100% { transform: translate3d(440%, 0, 0) skewX(-20deg); }
}
@keyframes gradientShift {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}

/* 登录/注册切换链接 */
.login-switch b {
  position: relative;
  transition: color .2s;
}
.login-switch b::after {
  content: "";
  position: absolute;
  left: 0; bottom: -2px;
  width: 100%; height: 1.5px;
  background: var(--gradient);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .28s cubic-bezier(.4, 0, .2, 1);
}
.login-switch b:hover::after { transform: scaleX(1); transform-origin: left; }

/* ---------- 聊天气泡：入场动画 ---------- */
.msg { animation: msgIn .34s cubic-bezier(.22, 1.15, .36, 1) both; }
.msg.me {
  background-size: 160% 160%;
  box-shadow: 0 4px 14px color-mix(in srgb, var(--primary) 30%, transparent);
}
@keyframes msgIn {
  from { opacity: 0; transform: translateY(12px) scale(.94); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* 输入栏：玻璃拟态 */
.chat-inputbar {
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  background: color-mix(in srgb, var(--card) 82%, transparent);
}

/* ---------- Toast：弹入 + 毛玻璃 ---------- */
.app-toast {
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  transition: opacity .3s, transform .35s cubic-bezier(.22, 1.3, .36, 1);
}

/* ---------- 底部 Tab：按压反馈 ---------- */
.tabbar .tab { transition: transform .18s cubic-bezier(.34, 1.56, .64, 1); }
.tabbar .tab:active { transform: scale(.86); }
.tabbar .tab.active { transform: translateY(-2px); }

/* ---------- 通用卡片悬浮感 ---------- */
.card, .anniv-item, .moment-item {
  transition: transform .25s, box-shadow .25s;
}
.card:hover, .anniv-item:hover, .moment-item:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 28px color-mix(in srgb, var(--primary) 18%, transparent);
}

/* ---------- 无障碍：减少动态偏好 ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}


/* =====================================================
   v2 追加（2026-10-02）：聊天头像、手机端角度适配
   仍为纯增量层，删掉本段即可还原
   ===================================================== */

/* 头像与气泡同排：气泡底角朝向头像，形成"谁说的"指向感 */
.msg-row { animation: bubbleIn .22s ease; }
.msg-row.me .msg { border-bottom-right-radius: 5px; border-bottom-left-radius: 16px; }
.msg-row.partner .msg { border-bottom-left-radius: 5px; border-bottom-right-radius: 16px; }
.msg-avatar { transition: transform .18s ease, box-shadow .18s ease; }
.msg-avatar:active { transform: scale(.88); }
.msg-avatar:hover { box-shadow: 0 3px 12px rgba(0,0,0,.18); }

/* 输入栏本身不叠加安全区内边距：它在底部 Tab 之上，
   再算一次 env() 会在刘海机上让输入框下方凭空多出约 34px 空白；
   安全区已由 .tabbar 与 .tab-page 的留白统一处理 */
.chat-send { min-height: 44px; }

/* 内容区底部留白同样跟随安全区 */
.tab-page { padding-bottom: calc(90px + env(safe-area-inset-bottom)); }

/* ---- 窄屏（≤360px，老机型/小屏安卓）收紧字与间距 ---- */
@media (max-width: 360px) {
  body { font-size: 14px; }
  .tab-page { padding-left: 12px; padding-right: 12px; }
  .love-days-num { font-size: 32px; }
  .home-hero { padding: 20px 14px; }
  .quick-grid { gap: 8px; }
  .quick-item { padding: 10px 4px; }
  .quick-item .qi { font-size: 22px; }
  .quick-item .qn { font-size: 11px; }
  .msg { font-size: 13.5px; padding: 9px 12px; }
  .msg-avatar { flex-basis: 32px; width: 32px; height: 32px; }
  .card { padding: 14px; }
}

/* ---- 横屏 / 矮视口：压缩装饰区，把高度让给聊天内容 ---- */
@media (orientation: landscape) and (max-height: 560px) {
  .home-hero { padding: 14px 16px; }
  .love-days-num { font-size: 26px; margin-top: 6px; }
  .love-days-label { margin-top: 2px; }
  .quick-grid { grid-template-columns: repeat(6, 1fr); gap: 6px; }
  .quick-item .qn { font-size: 10px; }
  .couple-avatars .avatar { width: 44px; height: 44px; }
  .tab-page { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
  .tabbar { padding-top: 2px; }
  .tab-icon { font-size: 18px; }
  .msg { max-width: min(56%, calc(100% - 46px)); }
}

/* ---- 平板 / 桌面：把内容约束在中间一栏，避免拉成大横幅 ---- */
@media (min-width: 600px) {
  #app, .tabbar, #subPage { left: 50%; right: auto; transform: translateX(-50%); width: 100%; max-width: 560px; }
  .tabbar { transform: translateX(-50%); }
  #subPage { transform: translateX(-50%) translateX(100%); }
  #subPage.open { transform: translateX(-50%); }
  .fab { right: calc(50% - 280px + 18px); }
}

/* ---- 长内容不撑破布局 ---- */
.msg, .list-card, .moment-content, .comment-list { overflow-wrap: anywhere; }
.chat-input, .input { min-width: 0; }


/* =====================================================
   v5 增量：在线点呼吸、聊天顶栏毛玻璃、拼豆与徽章质感
   纯增量，删掉本段即可还原
   ===================================================== */
.chat-head {
  backdrop-filter: blur(10px);
  background: color-mix(in srgb, var(--card) 86%, transparent);
  position: sticky; top: 0; z-index: 3;
}
.ch-avatar { border: 2px solid var(--card); box-shadow: 0 2px 8px rgba(0, 0, 0, .12); }
/* 在线点的呼吸光圈改由 ui-pro.css 用伪元素环实现（只动 transform/opacity） */
.typing-tip { backdrop-filter: blur(6px); animation: bubbleIn .2s ease; }

.play-item { border: 1px solid var(--line); background: var(--card); }
.play-item:hover { box-shadow: var(--shadow); transform: translateY(-2px); }
.pl-live { letter-spacing: .5px; }

.wi-icon {
  width: 44px; height: 44px; border-radius: 14px; background: var(--bg-soft);
  display: flex; align-items: center; justify-content: center; font-size: 22px;
}
.bead-grid { box-shadow: var(--shadow); }
.badge-item.unlocked:hover { transform: translateY(-2px); transition: transform .16s ease; }
.badge-item.unlocked .bi { animation: heartPop .5s ease; }

/* 小屏：一起玩的两个入口与徽章保持两列，但收紧内边距 */
@media (max-width: 360px) {
  .play-grid, .badge-grid { gap: 8px; }
  .play-item { padding: 11px; }
  .pl-name { font-size: 14px; }
  .badge-item { padding: 11px 8px; }
  .bead-pal .sw { width: 24px; height: 24px; }
  .chat-head { padding: 8px 10px; }
  .ch-avatar { flex-basis: 34px; width: 34px; height: 34px; }
}

/* 横屏矮视口：聊天顶栏变紧凑，把高度留给消息区 */
@media (orientation: landscape) and (max-height: 560px) {
  .chat-head { padding: 6px 10px; }
  .ch-avatar { flex-basis: 30px; width: 30px; height: 30px; }
  .ch-name { font-size: 14px; }
  .badge-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  .ch-sub .dot.online, .typing-tip i { animation: none; }
}

/* =====================================================
   v6 新增（2026-10-03）：应用内消息弹窗 / 聊天加号 / 媒体气泡 / 你画我猜
   ===================================================== */

/* ---------- 应用内消息弹窗（顶部横幅） ---------- */
.msg-popup {
  position: fixed;
  top: calc(12px + env(safe-area-inset-top, 0px));
  left: 12px; right: 12px;
  z-index: 10000;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 18px;
  background: rgba(255, 255, 255, .82);
  backdrop-filter: blur(18px) saturate(1.4);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  border: 1px solid rgba(255, 255, 255, .6);
  box-shadow: 0 12px 32px rgba(0, 0, 0, .14), var(--shadow);
  cursor: pointer;
  opacity: 0;
  transform: translateY(-24px) scale(.96);
  pointer-events: none;
  transition: opacity .3s, transform .4s cubic-bezier(.22, 1.3, .36, 1);
}
body[data-theme="dark"] .msg-popup {
  background: rgba(40, 32, 50, .82);
  border-color: rgba(255, 255, 255, .10);
}
.msg-popup.show { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
.msg-popup .mp-avatar { width: 38px; height: 38px; border-radius: 50%; overflow: hidden; flex: 0 0 auto;
  background: var(--gradient); display: flex; align-items: center; justify-content: center; }
.msg-popup .mp-avatar img { width: 100%; height: 100%; object-fit: cover; }
.msg-popup .mp-avatar .ph { color: #fff; font-weight: 700; font-size: 16px; }
.msg-popup .mp-body { flex: 1; min-width: 0; }
.msg-popup .mp-name { font-size: 13px; font-weight: 800; color: var(--text); }
.msg-popup .mp-text { font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.msg-popup .mp-go { color: var(--primary); font-size: 20px; font-weight: 700; }

/* ---------- 聊天加号按钮 ---------- */
.chat-plus {
  flex: 0 0 auto;
  width: 38px; height: 38px;
  border-radius: 50%;
  border: 1.5px solid var(--line);
  background: var(--card);
  color: var(--primary-deep);
  font-size: 20px;
  font-weight: 700;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform .2s cubic-bezier(.34, 1.56, .64, 1), background .2s, color .2s;
}
.chat-plus:active { transform: scale(.86) rotate(90deg); background: var(--gradient); color: #fff; border-color: transparent; }

/* ---------- 媒体气泡 ---------- */
.msg.media { padding: 4px; background: var(--card); border-radius: 14px; max-width: 74%; }
.msg.me.media { background: var(--card); }
.msg-img {
  display: block;
  max-width: 100%;
  max-height: 300px;
  border-radius: 10px;
  cursor: zoom-in;
  object-fit: cover;
}
.msg-video {
  display: block;
  max-width: 100%;
  max-height: 320px;
  border-radius: 10px;
  background: #000;
}
.msg.emoji-msg { font-size: 34px; line-height: 1.2; background: none; box-shadow: none; }
.msg.media .time { padding: 2px 6px 0; }

/* 全屏看图 */
.img-viewer {
  position: fixed; inset: 0; z-index: 10001;
  background: rgba(0, 0, 0, .92);
  display: flex; align-items: center; justify-content: center;
  cursor: zoom-out;
  animation: fadeIn .2s ease;
}
.img-viewer img { max-width: 96vw; max-height: 92vh; object-fit: contain; border-radius: 6px; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

/* ---------- 你画我猜 ---------- */
.draw-lobby { text-align: center; padding: 26px 18px; }
.draw-bigicon { font-size: 52px; animation: logoBeat 1.8s ease-in-out infinite; }
.draw-title { font-size: 22px; font-weight: 800; margin-top: 6px;
  background: var(--gradient); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.draw-sub { color: var(--muted); font-size: 13px; margin-top: 8px; line-height: 1.7; }
.draw-wordbar { font-size: 14px; margin-bottom: 10px; color: var(--text); }
.draw-wordbar b { color: var(--primary-deep); font-size: 17px; letter-spacing: 2px; }
.draw-mask { letter-spacing: 3px; }
.draw-live { color: var(--primary-deep); font-weight: 700; animation: pulse 1.6s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .45; } }
.draw-canvas-wrap {
  border-radius: 14px;
  overflow: hidden;
  border: 2px solid var(--line);
  box-shadow: var(--shadow);
  touch-action: none;          /* 关键：不然手机上画一笔页面跟着滚 */
  background: #fff;
}
.draw-canvas { display: block; width: 100%; cursor: crosshair; touch-action: none; }
.draw-canvas.ro { cursor: default; }
.draw-tools { margin-top: 10px; }
.draw-pal { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.draw-pal .sw {
  width: 30px; height: 30px; border-radius: 50%;
  border: 2px solid rgba(0, 0, 0, .08);
  cursor: pointer;
  transition: transform .18s cubic-bezier(.34, 1.56, .64, 1), box-shadow .18s;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; color: var(--muted);
}
.draw-pal .sw.on { transform: scale(1.18); box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 35%, transparent); }
.draw-pal .sw.eraser { background: #fff; }
.draw-waiting { margin-top: 10px; text-align: center; color: var(--muted); font-size: 13px; }
.draw-hist .head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.draw-guess-item {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 4px; border-bottom: 1px dashed var(--line);
  font-size: 13px; color: var(--muted);
}
.draw-guess-item:last-child { border-bottom: none; }
.draw-guess-item b { flex: 1; color: var(--text); }
.draw-guess-item.ok b { color: var(--primary-deep); }
