/* =====================================================
   ui-pro.css —— 视觉增强层（UI Pro · 2026-10-05）
   -----------------------------------------------------
   定位：最后加载的纯增量覆盖层。不改动任何 HTML / JS，也不改动
   其它 CSS 的结构逻辑；删掉本文件即可回退到原有视觉。

   本次改动要点：
   1. 统一设计 token：圆角 / 阴影 / 间距 / 过渡时长 / 缓动 / 玻璃拟态 /
      层级 z-index，全部集中在本文件顶部，便于后续整体调风格；
   2. 卡片：多层柔和阴影 + 1px 内描边 + hover 微上浮（只动
      transform / box-shadow，不触发重排）；
   3. 按钮：主按钮渐变 + 内高光 + hover 提亮 + active 缩放 .97；
      次按钮（.btn-ghost）描边式；危险按钮柔和红；统一 focus-visible 焦点环；
   4. 输入框：圆角放大、聚焦主色描边 + 外发光、placeholder 降层级、
      预留图标位（.input-wrap）、统一 16px 防 iOS 聚焦缩放；
   5. 气泡：微信式不对称圆角（对方左上小圆角 / 自己右上小圆角）、
      尾巴挪到顶部、行高 1.6、表情气泡单独放大；
   6. 空状态 .empty 重做 + 新增 .skeleton 骨架屏（只动 background-position）；
   7. Toast：居中偏上、胶囊、毛玻璃、图标位、transform + opacity 进出场；
   8. .sheet-mask 背景模糊 + 内容从底部滑入 + 顶部小把手；
   9. 细滚动条（hover 才显形）、入场动画统一、尊重 prefers-reduced-motion；
   10. 缺陷修复：聊天背景 !important 覆盖用户预设、Toast 层级低于粒子画布、
       beige 我方气泡对比度、dark 下 read-mark / 宠物页硬编码色、
       移动端 44px 触控区与底部安全区。

   兼容：五套主题（pink / blue / retro / beige / dark）全部走 CSS 变量。
   响应式：360 / 768 / 1200 三档。
   ===================================================== */


/* =====================================================
   0. 设计 Token
   -----------------------------------------------------
   注意：派生 token（引用了 --primary / --bg-soft 等的）必须定义在
   body 上而不是 :root 上 —— 自定义属性的 var() 是在"声明它的元素"
   上求值的，写在 :root 上会把默认 pink 主题的值永久烤死进去，
   导致切到 beige / dark 时阴影、玻璃底、聊天背景全是粉色的。
   ===================================================== */
body {
  /* ---- 圆角节奏 ---- */
  --r-xs: 8px;
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 18px;
  --r-xl: 24px;
  --r-pill: 999px;

  /* ---- 阴影：多层柔和叠加，而不是一层生硬的大阴影 ---- */
  --sh-1: 0 1px 2px rgba(17, 12, 20, .04),
          0 2px 6px color-mix(in srgb, var(--primary) 8%, transparent);
  --sh-2: 0 1px 2px rgba(17, 12, 20, .04),
          0 4px 10px rgba(17, 12, 20, .04),
          0 10px 24px color-mix(in srgb, var(--primary) 14%, transparent);
  --sh-3: 0 2px 6px rgba(17, 12, 20, .05),
          0 8px 18px rgba(17, 12, 20, .06),
          0 22px 48px color-mix(in srgb, var(--primary) 20%, transparent);

  /* ---- 间距节奏 ---- */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;

  /* ---- 过渡与缓动 ---- */
  --t-fast: .16s;
  --t-base: .26s;
  --t-slow: .40s;
  --ease-out-soft: cubic-bezier(.22, .61, .36, 1);
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);

  /* ---- 内描边（比 border 更省事，且不影响盒模型） ---- */
  --hairline: inset 0 0 0 1px color-mix(in srgb, var(--line) 80%, transparent);

  /* ---- 玻璃拟态 ---- */
  --glass-bg: color-mix(in srgb, var(--card) 78%, transparent);
  --glass-bg-strong: color-mix(in srgb, var(--card) 88%, transparent);
  --glass-border: color-mix(in srgb, var(--text) 10%, transparent);
  --glass-blur: saturate(1.35) blur(18px);

  /* =====================================================
     层级规范（z-index）
       1   --z-base      普通内容
       10  --z-content   内容层之上（悬浮按钮 40、底栏 20 等）
       20  --z-tabbar    底部 Tab
       40  --z-fab       悬浮操作按钮
       70  --z-page      全屏子页面（.chat-detail）
       90  --z-subpage   带返回的子页面 #subPage
       95  --z-mask      弹层遮罩 .sheet-mask
       100 --z-popup     弹层内容
       300 --z-toast     （保留位）
       999 --z-top       最高业务层
     另有两个 JS 内联写死的层级，必须在规范里显式说明：
       9999  粒子画布 #particleCanvas（core.js 内联，pointer-events:none）
       10000 应用内消息横幅 .msg-popup
     因此 Toast 取 10050（--z-over-particle），保证盖在粒子画布与横幅之上。
     ===================================================== */
  --z-base: 1;
  --z-content: 10;
  --z-tabbar: 20;
  --z-fab: 40;
  --z-page: 70;
  --z-subpage: 90;
  --z-mask: 95;
  --z-popup: 100;
  --z-toast: 300;
  --z-top: 999;
  --z-over-particle: 10050;

  /* ---- 聊天背景（按主题渐变，见第 9 节修复说明） ---- */
  --chat-bg-a: color-mix(in srgb, var(--bg-soft) 72%, var(--card));
  --chat-bg-b: color-mix(in srgb, var(--bg-soft) 40%, var(--bg));
  --chat-bg-c: var(--bg);

  /* ---- 宠物页语义色（原 chat_v9.css 里硬编码 #ffeef4 / #b8456b 等） ---- */
  --pet-bg-1: color-mix(in srgb, var(--bg-soft) 78%, var(--card));
  --pet-bg-2: color-mix(in srgb, var(--bg) 55%, var(--card));
  --pet-bg-3: color-mix(in srgb, var(--bg-soft) 92%, var(--primary) 8%);
  --pet-card: var(--card);
  --pet-line: var(--line);
  --pet-ink: var(--text);
  --pet-title: var(--primary-deep);
  --pet-accent: var(--primary);
  --pet-me: var(--gradient);
}

/* 粉 / 深色两套主题给宠物页单独取值：
   粉色延续原来的甜美奶油粉；深色主题跟随 --card / --line，不再出现
   "亮粉底 + 深粉字"在暗色下刺眼的问题 */
body[data-theme="pink"] {
  --pet-bg-1: #ffeef4;
  --pet-bg-2: #fff7ef;
  --pet-bg-3: #ffe8f0;
  --pet-card: #ffffff;
  --pet-line: #ffd3e0;
  --pet-ink: #7c4a5f;
  --pet-title: #b8456b;
  --pet-accent: #e26d92;
}
body[data-theme="dark"] {
  --pet-bg-1: #241d33;
  --pet-bg-2: #17131f;
  --pet-bg-3: #221b30;
  --pet-card: var(--card);
  --pet-line: var(--line);
  --pet-ink: var(--text);
  --pet-title: var(--text);
  --pet-accent: var(--primary);
}


/* =====================================================
   1. 基础排版与全局质感
   ===================================================== */
body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
/* 所有可点元素去掉浏览器默认焦点框，统一用下面第 2 节的 focus-visible 环 */
button:focus,
input:focus,
textarea:focus,
.tab:focus,
.sheet-opt:focus,
.chip:focus { outline: none; }

/* 统一入场动画工具类：只动 opacity / transform */
.enter-up { animation: uiEnterUp var(--t-slow) var(--ease-out-soft) both; }
@keyframes uiEnterUp {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}


/* =====================================================
   2. 焦点环（可访问性）—— outline 不参与布局，不会抖动
   ===================================================== */
:where(button, a, input, textarea, select, [tabindex],
       .tab, .sheet-opt, .chip, .quick-item, .nav-item):focus-visible {
  outline: 2px solid var(--primary-deep);
  outline-offset: 2px;
}
body[data-theme="dark"] :where(button, a, input, textarea, select, [tabindex],
       .tab, .sheet-opt, .chip, .quick-item, .nav-item):focus-visible {
  outline-color: var(--primary);
}


/* =====================================================
   3. 按钮
   ===================================================== */
.btn-primary,
.chat-send {
  min-height: 48px;
  padding: 12px 18px;
  border-radius: var(--r-md);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: .2px;
  color: #fff;
  background: var(--gradient);
  /* 内高光 + 多层柔和阴影，避免"一片死板的色块" */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .38),
    0 2px 6px rgba(17, 12, 20, .05),
    0 10px 24px color-mix(in srgb, var(--primary) 28%, transparent);
  transition:
    transform var(--t-fast) var(--ease-out-soft),
    box-shadow var(--t-base) var(--ease-out-soft),
    filter var(--t-fast) linear;
}
@media (hover: hover) {
  .btn-primary:hover,
  .chat-send:hover {
    filter: brightness(1.06);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, .45),
      0 4px 10px rgba(17, 12, 20, .06),
      0 16px 34px color-mix(in srgb, var(--primary) 34%, transparent);
  }
}
.btn-primary:active,
.chat-send:active { transform: scale(.97); filter: brightness(.98); }

/* 次按钮：描边式（原来 .btn-ghost 没有任何视觉定义，只是个空壳 class） */
.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 16px;
  border-radius: var(--r-md);
  border: 1.5px solid var(--line);
  background: color-mix(in srgb, var(--card) 70%, transparent);
  color: var(--primary-deep);
  font-size: 14.5px;
  font-weight: 600;
  transition: transform var(--t-fast) var(--ease-out-soft),
              background var(--t-fast) linear,
              box-shadow var(--t-base) var(--ease-out-soft);
}
.btn-ghost:active { transform: scale(.97); background: var(--bg-soft); }
@media (hover: hover) {
  .btn-ghost:hover {
    background: var(--bg-soft);
    box-shadow: var(--sh-1);
  }
}

/* 危险按钮：柔和红，而不是刺眼的正红实心块 */
.btn-danger,
.del-btn,
.op-btn.danger {
  border-radius: var(--r-md);
  font-weight: 700;
}
.btn-danger {
  min-height: 48px;
  padding: 12px 18px;
  color: #fff;
  background: color-mix(in srgb, var(--danger) 88%, #ffffff);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .28),
    0 2px 6px rgba(17, 12, 20, .04),
    0 10px 22px color-mix(in srgb, var(--danger) 26%, transparent);
  transition: transform var(--t-fast) var(--ease-out-soft),
              box-shadow var(--t-base) var(--ease-out-soft),
              filter var(--t-fast) linear;
}
.btn-danger:active { transform: scale(.97); filter: brightness(.98); }
body[data-theme="dark"] .btn-danger {
  background: color-mix(in srgb, var(--danger) 92%, #2a1b26);
}

/* 小胶囊按钮（尺寸 / 宽度 / 橡皮 / 收藏等） */
.chip {
  min-height: 36px;
  padding: 8px 14px;
  border-radius: var(--r-pill);
  border: 1.5px solid transparent;
  background: var(--bg-soft);
  color: var(--muted);
  font-size: 13.5px;
  font-weight: 600;
  transition: transform var(--t-fast) var(--ease-spring),
              background var(--t-fast) linear,
              color var(--t-fast) linear,
              box-shadow var(--t-base) var(--ease-out-soft);
}
.chip.on {
  background: var(--gradient);
  color: #fff;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .3),
    0 6px 16px color-mix(in srgb, var(--primary) 30%, transparent);
}
.chip:active { transform: scale(.96); }


/* =====================================================
   4. 输入框 / 文本域
   ===================================================== */
.input,
textarea.input,
.chat-input,
.pet-inputbar .input,
.pet-inputbar input {
  /* 统一 16px：小于它 iOS 聚焦时会自动放大整页且不会缩回
     （覆盖 style.css 的 15px 与 chat_v9.css 里聊天输入框的 15px） */
  font-size: 16px;
  min-height: 46px;
  padding: 12px 16px;
  border-radius: var(--r-md);
  border: 1.5px solid var(--line);
  background: var(--bg-soft);
  color: var(--text);
  box-shadow: inset 0 1px 2px rgba(17, 12, 20, .03);
  transition: border-color var(--t-fast) linear,
              box-shadow var(--t-base) var(--ease-out-soft),
              background var(--t-fast) linear;
}
.chat-input { font-size: 16px; }
.chat-inputbar-v9 .chat-input { font-size: 16px; }
textarea.input { min-height: 96px; line-height: 1.6; }

/* placeholder 层级降低，不与正文抢注意力 */
.input::placeholder,
.chat-input::placeholder,
textarea.input::placeholder {
  color: color-mix(in srgb, var(--muted) 78%, transparent);
  opacity: 1;
}
.input:focus,
.chat-input:focus,
textarea.input:focus {
  border-color: var(--primary);
  background: var(--card);
  box-shadow:
    0 0 0 4px color-mix(in srgb, var(--primary) 16%, transparent),
    inset 0 1px 2px rgba(17, 12, 20, .02);
}
/* 有图标位的输入框：左侧预留 44px，图标用 .input-wrap > .fi 定位 */
.input-wrap { position: relative; }
.input-wrap > .input { padding-left: 46px; }
.input-wrap > .fi {
  position: absolute; left: 15px; top: 50%;
  transform: translateY(-50%);
  font-size: 17px; line-height: 1;
  pointer-events: none;
  color: var(--muted);
}


/* =====================================================
   5. 卡片 / 列表质感
   ===================================================== */
.card,
.list-card,
.moment-item,
.quick-item,
.menu-list,
.setting-list,
.remark-card,
.draw-panel,
.badge-item,
.play-item,
.watch-item {
  border-radius: var(--r-lg);
  box-shadow: var(--sh-2);
  transition: transform var(--t-base) var(--ease-out-soft),
              box-shadow var(--t-base) var(--ease-out-soft);
}
/* 1px 内描边用 box-shadow inset 表达，不动 border，避免影响任何盒模型 */
.card,
.list-card,
.moment-item,
.quick-item,
.menu-list,
.setting-list,
.remark-card,
.draw-panel,
.badge-item { box-shadow: var(--sh-2), var(--hairline); }

/* hover 微上浮：只在真·指针设备上生效，触屏不会出现"粘住"的悬浮态 */
@media (hover: hover) {
  .card:hover,
  .list-card:hover,
  .moment-item:hover,
  .quick-item:hover,
  .badge-item:hover,
  .play-item:hover,
  .watch-item:hover {
    transform: translateY(-2px);
    box-shadow: var(--sh-3), var(--hairline);
  }
  .conv-item:hover { background: color-mix(in srgb, var(--bg-soft) 45%, var(--card)); }
  .menu-row:hover,
  .setting-row:hover { background: var(--bg-soft); }
}
.quick-item:active,
.play-item:active,
.watch-item:active,
.badge-item:active,
.moment-item:active { transform: scale(.98); }

/* 列表行：更整齐的呼吸感 */
.menu-row,
.setting-row {
  min-height: 52px;
  padding: 14px 18px;
  border-radius: 0;
  transition: background var(--t-fast) linear;
}
.menu-list,
.setting-list { overflow: hidden; }
.anniv-item { padding: 12px 0; }


/* =====================================================
   6. 聊天气泡（微信式不对称圆角）
   ===================================================== */
.chat-body .msg-row { margin-bottom: 14px; }
.chat-body .msg-row .msg {
  /* 最大宽度略放宽：长句少折一次行，读起来更连贯 */
  max-width: min(74%, calc(100% - 56px));
  padding: 10px 14px;
  font-size: 15px;
  line-height: 1.6;
  border-radius: var(--r-lg);
}
/* 对方：左上小圆角；自己：右上小圆角（尾巴同侧，指向头像） */
.chat-body .msg-row.partner .msg {
  border-top-left-radius: 6px;
  border-bottom-left-radius: var(--r-lg);
  box-shadow: 0 1px 2px rgba(17, 12, 20, .04),
              0 6px 16px color-mix(in srgb, var(--text) 8%, transparent);
}
.chat-body .msg-row.me .msg {
  border-top-right-radius: 6px;
  border-bottom-right-radius: var(--r-lg);
  box-shadow: 0 2px 6px rgba(17, 12, 20, .05),
              0 8px 20px color-mix(in srgb, var(--primary) 30%, transparent);
}
/* 尾巴挪到顶部，和上面的小圆角同侧（原来在 bottom，和小圆角不在一边） */
.chat-body .msg-row.partner .msg::before { top: 11px; bottom: auto; }
.chat-body .msg-row.me .msg::before { top: 11px; bottom: auto; }

/* 表情单独发一条时放大、去掉底色，像微信的"大表情" */
.msg.emoji-msg,
.chat-body .msg-row .msg.emoji-msg {
  font-size: 40px;
  line-height: 1.25;
  padding: 2px 6px;
  background: transparent;
  box-shadow: none;
}
/* 引用块：圆角与层级更细 */
.msg .msg-quote {
  border-radius: var(--r-sm);
  padding: 6px 9px;
  font-size: 12px;
}
.msg-row.me .msg-quote { background: rgba(255, 255, 255, .26); }
.chat-body .msg-row .msg .time { margin-top: 4px; font-size: 10.5px; }

/* 已读回执：改为读主题变量（原来写死 rgba(0,0,0,.35)，深色主题几乎看不见） */
.read-mark,
.read-mark-group { color: var(--muted); font-size: 10.5px; }
.read-mark.ok,
.read-mark-group.ok { color: var(--primary-deep); font-weight: 600; }
body[data-theme="dark"] .read-mark,
body[data-theme="dark"] .read-mark-group { color: var(--muted); }
body[data-theme="dark"] .read-mark.ok,
body[data-theme="dark"] .read-mark-group.ok { color: var(--primary); }

/* 顶栏 / 输入栏：统一玻璃拟态（不支持 backdrop-filter 时不降级成半透明） */
@supports ((backdrop-filter: blur(4px)) or (-webkit-backdrop-filter: blur(4px))) {
  .tabbar,
  .chat-head,
  .conv-header,
  .chat-topbar,
  .draw-top,
  .sub-header {
    background: var(--glass-bg);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    border-top-color: var(--glass-border);
    border-bottom-color: var(--glass-border);
  }
  .chat-inputbar,
  .chat-inputbar-v9 { background: var(--glass-bg-strong); }
}


/* =====================================================
   7. 空状态 / 骨架屏
   ===================================================== */
.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 44px 24px;
  color: var(--muted);
  font-size: 13.5px;
  line-height: 1.7;
  text-align: center;
}
/* 插画感的圆形图标底 */
.empty .eicon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 84px; height: 84px;
  margin: 0 auto 14px;
  font-size: 36px;
  line-height: 1;
  border-radius: 50%;
  background: color-mix(in srgb, var(--bg-soft) 70%, var(--card));
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--line) 90%, transparent),
    0 10px 24px color-mix(in srgb, var(--primary) 12%, transparent);
}
/* 次级说明（.muted / <br> 后面的小字） */
.empty .muted,
.empty small {
  display: block;
  margin-top: 6px;
  font-size: 12.5px;
  color: color-mix(in srgb, var(--muted) 88%, transparent);
}
/* 可选行动按钮：不撑满整行 */
.empty .btn-primary,
.empty .btn-ghost {
  width: auto;
  min-width: 136px;
  margin-top: 16px;
  padding: 10px 20px;
}
.conv-empty { padding: 64px 30px; }
.conv-empty .ce {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 84px; height: 84px;
  margin: 0 auto 14px;
  font-size: 36px;
  line-height: 1;
  border-radius: 50%;
  background: color-mix(in srgb, var(--bg-soft) 70%, var(--card));
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--line) 90%, transparent),
    0 10px 24px color-mix(in srgb, var(--primary) 12%, transparent);
}

/* ---- 骨架屏：只动 background-position，不触发重排 ---- */
.skeleton {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-sm);
  background-color: color-mix(in srgb, var(--muted) 14%, var(--bg-soft));
  background-image: linear-gradient(90deg,
      transparent 0%,
      color-mix(in srgb, var(--card) 70%, transparent) 50%,
      transparent 100%);
  background-size: 220% 100%;
  background-repeat: no-repeat;
  animation: skeletonShimmer 1.4s linear infinite;
}
@keyframes skeletonShimmer {
  from { background-position: -110% 0; }
  to   { background-position: 110% 0; }
}
.skeleton.sk-line { display: block; height: 12px; }
.skeleton.sk-line + .skeleton.sk-line { width: 68%; }
.skeleton.sk-title { display: block; height: 16px; width: 42%; }
.skeleton.sk-circle { width: 46px; height: 46px; border-radius: 50%; flex: 0 0 auto; }
.skeleton.sk-block { display: block; height: 84px; border-radius: var(--r-md); }
.skeleton-card {
  display: flex;
  gap: var(--sp-3);
  padding: 16px;
  border-radius: var(--r-lg);
  background: var(--card);
  box-shadow: var(--sh-2), var(--hairline);
  margin-bottom: var(--sp-3);
}
.skeleton-card .sk-body { flex: 1; min-width: 0; }
.skeleton-card .sk-body .skeleton + .skeleton { margin-top: 10px; }


/* =====================================================
   8. Toast / 弹层
   ===================================================== */
.app-toast {
  left: 50%;
  top: calc(84px + env(safe-area-inset-top, 0px));
  bottom: auto;
  /* 必须高于 JS 内联写死的粒子画布(9999)与消息横幅(10000) */
  z-index: var(--z-over-particle);
  display: flex;
  align-items: center;
  gap: 9px;
  max-width: min(86vw, 420px);
  padding: 10px 16px 10px 12px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--text) 84%, transparent);
  color: var(--card);
  border: 1px solid color-mix(in srgb, var(--card) 20%, transparent);
  box-shadow: var(--sh-3);
  font-size: 13.5px;
  line-height: 1.45;
  white-space: normal;
  text-align: left;
  opacity: 0;
  transform: translate(-50%, -14px) scale(.96);
  transition: opacity var(--t-base) linear,
              transform var(--t-slow) var(--ease-out-soft);
}
@supports ((backdrop-filter: blur(4px)) or (-webkit-backdrop-filter: blur(4px))) {
  .app-toast {
    -webkit-backdrop-filter: blur(18px) saturate(1.4);
    backdrop-filter: blur(18px) saturate(1.4);
  }
}
/* 图标位：左侧一个主色圆点，不额外增加 DOM */
.app-toast::before {
  content: "";
  flex: 0 0 auto;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--gradient);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--card) 18%, transparent);
}
.app-toast.show { opacity: 1; transform: translate(-50%, 0) scale(1); }

/* ---- 底部弹窗 ---- */
.sheet-mask {
  z-index: var(--z-mask);
  background: color-mix(in srgb, #000 42%, transparent);
}
@supports ((backdrop-filter: blur(4px)) or (-webkit-backdrop-filter: blur(4px))) {
  .sheet-mask {
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
  }
}
.sheet {
  max-height: 84vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 8px 16px calc(18px + env(safe-area-inset-bottom, 0px));
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  background: var(--card);
  box-shadow: 0 -14px 44px rgba(17, 12, 20, .18);
  animation: sheetUp var(--t-slow) var(--ease-out-soft) both;
}
@keyframes sheetUp {
  from { transform: translateY(100%); opacity: .6; }
  to   { transform: translateY(0); opacity: 1; }
}
/* 顶部小把手 */
.sheet::before {
  content: "";
  display: block;
  width: 38px; height: 4px;
  margin: 6px auto 10px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--muted) 45%, transparent);
}
.sheet-opt {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 50px;
  padding: 12px 14px;
  border-radius: var(--r-md);
  font-size: 15.5px;
  transition: background var(--t-fast) linear,
              transform var(--t-fast) var(--ease-out-soft);
}
.sheet-opt:active { transform: scale(.98); background: var(--bg-soft); }
.emoji-row { gap: 6px; }
.emoji-row .emoji,
.emoji-bar-v9 .emoji { min-width: 44px; }


/* =====================================================
   9. 缺陷修复：聊天背景 / 主题色 / 宠物页硬编码色
   ===================================================== */

/* 9.1 聊天默认背景：
   chat_v9.css 原来是 .chat-body { background: 渐变 !important }，
   applyBg() 写入的内联背景（预设 css / 自定义图片 url）优先级低于 !important，
   导致"换背景"功能完全无效。这里改用 :not(.has-bg):not([data-bg-preset])
   且不带 !important —— 内联样式自然胜出，同时保留默认渐变观感。 */
.chat-body:not(.has-bg):not([data-bg-preset]) {
  background-image: linear-gradient(165deg,
      var(--chat-bg-a) 0%,
      var(--chat-bg-b) 55%,
      var(--chat-bg-c) 100%);
  background-size: cover;
  background-position: center;
}
/* 自定义背景图（.has-bg）：只保证铺满与居中，不再写 background: none
   （那会把 JS 设置的 background-image 一起清掉） */
.chat-body.has-bg {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* 9.2 beige（极简奶白）主题：我方气泡原来"浅奶咖渐变 + 白字"，
   对比度只有约 1.8:1，几乎看不清。这里换成暖米色底 + 深色文字，
   对比度约 10:1，同时保持奶白主题的质感。 */
body[data-theme="beige"] .chat-body .msg-row.me .msg,
body[data-theme="beige"] .msg.me {
  background: linear-gradient(135deg, #efe7db 0%, #ddcebb 100%);
  color: #3a332a;
  box-shadow: 0 2px 6px rgba(120, 100, 80, .08),
              0 10px 22px rgba(185, 165, 140, .22),
              inset 0 0 0 1px rgba(156, 138, 114, .28);
}
body[data-theme="beige"] .chat-body .msg-row.me .msg .time,
body[data-theme="beige"] .msg.me .time { color: rgba(58, 51, 42, .55); }
body[data-theme="beige"] .msg.me .msg-quote {
  background: rgba(0, 0, 0, .06);
  border-left-color: rgba(58, 51, 42, .22);
}
body[data-theme="beige"] .chat-body .msg-row.me .msg::before { border-left-color: #ddcebb; }
body[data-theme="beige"] .read-mark.ok { color: #7d6a52; }
/* 奶白主题的主色渐变偏浅，白字上加一点暗描边提升可读性 */
body[data-theme="beige"] .home-hero,
body[data-theme="beige"] .profile-head,
body[data-theme="beige"] .draw-banner.win,
body[data-theme="beige"] .member-item .mi-tag { text-shadow: 0 1px 2px rgba(0, 0, 0, .28); }
/* 宠物页历史里的"我"气泡同理 */
body[data-theme="beige"] .ph-row.me {
  background: linear-gradient(135deg, #efe7db 0%, #ddcebb 100%);
  color: #3a332a;
}

/* 9.3 宠物页：把 chat_v9.css 里硬编码的 #ffeef4 / #b8456b / #ffd3e0
   全部改成读主题变量（token 在第 0 节定义） */
.pet-overlay {
  background: linear-gradient(180deg,
      var(--pet-bg-1) 0%, var(--pet-bg-2) 55%, var(--pet-bg-3) 100%);
}
.pet-head {
  background: color-mix(in srgb, var(--pet-card) 76%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--pet-line) 85%, transparent);
}
.pet-title { color: var(--pet-title); }
.pet-title small { color: var(--muted); }
.pet-ico { color: var(--pet-accent); }
.pet-dot { background: var(--pet-accent); }
.pet-bubble {
  background: var(--pet-card);
  border: 1.5px solid var(--pet-line);
  box-shadow: var(--sh-2);
}
.pet-bubble-tail { border-top-color: var(--pet-card); }
.pet-bubble-text { color: var(--pet-ink); }
.pet-history {
  background: color-mix(in srgb, var(--pet-card) 70%, transparent);
  border-radius: var(--r-lg);
}
.ph-row { color: var(--muted); }
.ph-row.dog { background: var(--pet-card); color: var(--pet-ink); }
.ph-row.me { background: var(--pet-me); color: #fff; }
.pet-chips button {
  background: var(--pet-card);
  color: var(--pet-title);
  border: 1.5px solid var(--pet-line);
  box-shadow: 0 3px 8px color-mix(in srgb, var(--primary) 12%, transparent);
}
.pet-inputbar {
  background: color-mix(in srgb, var(--pet-card) 84%, transparent);
}
.pet-drag-hint {
  color: var(--muted);
  background: color-mix(in srgb, var(--pet-card) 72%, transparent);
}
/* .pet-av 上游带 !important，这里只能同级别覆盖 */
.pet-av {
  background: linear-gradient(135deg, var(--pet-bg-3), var(--pet-bg-2)) !important;
}

/* 9.4 把剩下几处"动画 box-shadow spread / 布局属性"改成 transform + opacity
   （shimmer 类动画 box-shadow 每帧都要重绘，是掉帧来源之一） */
/* 在线小圆点的呼吸光圈 */
.ch-sub .dot,
.cb-state .dot,
.pet-dot { position: relative; }
.ch-sub .dot.online,
.cb-state .dot.online { animation: none; box-shadow: 0 0 0 3px rgba(53, 208, 127, .18); }
.ch-sub .dot.online::after,
.cb-state .dot.online::after {
  content: "";
  position: absolute; inset: -2px;
  border-radius: 50%;
  border: 2px solid #35d07f;
  opacity: 0; transform: scale(.85);
  animation: uiPulseRing 2.2s ease-in-out infinite;
  pointer-events: none;
}
.pet-dot { animation: none; }
.pet-dot::after {
  content: "";
  position: absolute; inset: -2px;
  border-radius: 50%;
  border: 2px solid var(--pet-accent);
  opacity: 0; transform: scale(.85);
  animation: uiPulseRing 1.6s ease-in-out infinite;
  pointer-events: none;
}
@keyframes uiPulseRing {
  0%   { transform: scale(.85); opacity: .6; }
  70%  { transform: scale(2);   opacity: 0; }
  100% { transform: scale(2);   opacity: 0; }
}
/* 引用跳转高亮：原来是动 box-shadow，改为伪元素描边环的 opacity */
.flash { position: relative; animation: none; }
.flash::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  box-shadow: 0 0 0 3px var(--primary);
  opacity: 0;
  pointer-events: none;
  animation: uiFlashRing 1.2s ease;
}
@keyframes uiFlashRing {
  0%, 60% { opacity: 1; }
  100%    { opacity: 0; }
}
/* 聊天未读角标呼吸：原来动 box-shadow spread，同样改为伪元素光环 */
#chatBadge.show { animation: none; }
#chatBadge.show::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  border: 2px solid color-mix(in srgb, var(--danger) 60%, transparent);
  opacity: 0;
  pointer-events: none;
  animation: uiPulseRing 1.6s ease-out infinite;
}


/* =====================================================
   10. 滚动条：细条 + 圆角，鼠标不在容器上时隐形
   ===================================================== */
.tab-page,
#chatBody,
.chat-body,
#subBody,
.conv-list,
.bead-scroll,
.pet-history,
.sheet,
.img-viewer,
.view-body,
.table-wrap {
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
}
.tab-page:hover,
#chatBody:hover,
.chat-body:hover,
#subBody:hover,
.conv-list:hover,
.bead-scroll:hover,
.pet-history:hover,
.sheet:hover,
.view-body:hover,
.table-wrap:hover {
  scrollbar-color: color-mix(in srgb, var(--muted) 45%, transparent) transparent;
}
.tab-page::-webkit-scrollbar,
#chatBody::-webkit-scrollbar,
.chat-body::-webkit-scrollbar,
#subBody::-webkit-scrollbar,
.conv-list::-webkit-scrollbar,
.bead-scroll::-webkit-scrollbar,
.pet-history::-webkit-scrollbar,
.sheet::-webkit-scrollbar,
.view-body::-webkit-scrollbar,
.table-wrap::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
.tab-page::-webkit-scrollbar-track,
#chatBody::-webkit-scrollbar-track,
.chat-body::-webkit-scrollbar-track,
#subBody::-webkit-scrollbar-track,
.conv-list::-webkit-scrollbar-track,
.bead-scroll::-webkit-scrollbar-track,
.pet-history::-webkit-scrollbar-track,
.sheet::-webkit-scrollbar-track,
.view-body::-webkit-scrollbar-track,
.table-wrap::-webkit-scrollbar-track { background: transparent; }
.tab-page::-webkit-scrollbar-thumb,
#chatBody::-webkit-scrollbar-thumb,
.chat-body::-webkit-scrollbar-thumb,
#subBody::-webkit-scrollbar-thumb,
.conv-list::-webkit-scrollbar-thumb,
.bead-scroll::-webkit-scrollbar-thumb,
.pet-history::-webkit-scrollbar-thumb,
.sheet::-webkit-scrollbar-thumb,
.view-body::-webkit-scrollbar-thumb,
.table-wrap::-webkit-scrollbar-thumb {
  background: transparent;
  border-radius: var(--r-pill);
}
.tab-page:hover::-webkit-scrollbar-thumb,
#chatBody:hover::-webkit-scrollbar-thumb,
.chat-body:hover::-webkit-scrollbar-thumb,
#subBody:hover::-webkit-scrollbar-thumb,
.conv-list:hover::-webkit-scrollbar-thumb,
.bead-scroll:hover::-webkit-scrollbar-thumb,
.pet-history:hover::-webkit-scrollbar-thumb,
.sheet:hover::-webkit-scrollbar-thumb,
.view-body:hover::-webkit-scrollbar-thumb,
.table-wrap:hover::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--muted) 42%, transparent);
}


/* =====================================================
   11. 移动端：44px 触控区 + 底部安全区
   ===================================================== */

/* 11.1 触控区：用伪元素向外扩一圈透明的可点区域，
   不改变任何元素的盒子尺寸，因此不会影响现有布局。
   注意：overflow: hidden 的容器（如 .msg-avatar / .pal-viewport）会裁掉
   这圈扩展，这类元素不在此列，靠自身尺寸保证可点即可。 */
@media (pointer: coarse) {
  .chip,
  .conv-ico,
  .cb-btn,
  .qb-close,
  .pal-arrow,
  .op-btn,
  .emoji-bar-v9 .emoji,
  .emoji-row .emoji,
  .bead-pal .sw,
  .del-btn,
  .mi-del,
  .like-btn,
  .fav-btn { position: relative; }
  .chip::after,
  .conv-ico::after,
  .cb-btn::after,
  .qb-close::after,
  .pal-arrow::after,
  .op-btn::after,
  .emoji-bar-v9 .emoji::after,
  .emoji-row .emoji::after,
  .bead-pal .sw::after,
  .del-btn::after,
  .mi-del::after,
  .like-btn::after,
  .fav-btn::after {
    content: "";
    position: absolute;
    inset: -6px;
    border-radius: inherit;
  }
  /* 尺寸本身就偏小的控件直接补到 44px 下限 */
  .chip { min-height: 40px; }
  .qb-close { min-height: 40px; display: inline-flex; align-items: center; }
}

/* 11.2 底部安全区（iPhone 手势条） */
.tabbar { padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px)); }
.tabbar .tab { min-height: 48px; }
#subBody { padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px)); }
.fab { bottom: calc(92px + env(safe-area-inset-bottom, 0px)); }
.conv-list { padding-bottom: calc(96px + env(safe-area-inset-bottom, 0px)); }
.pet-chips { padding-bottom: var(--sp-2); }


/* =====================================================
   12. 响应式：360 / 768 / 1200
   ===================================================== */

/* ---- 12.1 窄屏 ≤360px：收紧节奏，保证小屏不拥挤 ---- */
@media (max-width: 360px) {
  .card,
  .list-card,
  .moment-item { padding: 14px; border-radius: var(--r-md); }
  .quick-grid { gap: 8px; }
  .quick-item { padding: 12px 4px; border-radius: var(--r-md); }
  .home-hero,
  .profile-head { padding: 20px 14px; border-radius: var(--r-lg); }
  .chat-body .msg-row .msg {
    max-width: min(80%, calc(100% - 48px));
    font-size: 14.5px;
    padding: 9px 12px;
  }
  .empty { padding: 32px 16px; }
  .empty .eicon { width: 68px; height: 68px; font-size: 30px; }
  .app-toast { font-size: 13px; padding: 9px 14px 9px 11px; }
  .btn-primary,
  .chat-send { min-height: 46px; font-size: 15.5px; }
}

/* ---- 12.2 ≥768px（平板 / 大屏手机横屏）：更多留白，气泡限宽 ---- */
@media (min-width: 768px) {
  .tab-page { padding: 20px 20px calc(96px + env(safe-area-inset-bottom, 0px)); }
  .card,
  .list-card,
  .moment-item { padding: 20px; }
  .chat-body .msg-row .msg { max-width: min(66%, 460px); font-size: 15.5px; }
  .quick-grid { gap: 14px; }
  .empty .eicon { width: 96px; height: 96px; font-size: 40px; }
  .sheet { padding-left: 22px; padding-right: 22px; }
}

/* ---- 12.3 ≥1200px（桌面预览）：中间栏略放宽，观感更像成品 App ---- */
@media (min-width: 1200px) {
  #app, .tabbar, #subPage { max-width: 620px; }
  .fab { right: calc(50% - 310px + 24px); }
  .tab-page { padding-left: 24px; padding-right: 24px; }
  .chat-body .msg-row .msg { max-width: min(62%, 520px); }
  .card, .list-card, .moment-item { padding: 22px; }
  .quick-grid { gap: 16px; }
}


/* =====================================================
   13. 减少动态偏好：关闭所有装饰性动画
   ===================================================== */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  /* 装饰动画直接关掉，而不是"跑完一次" */
  .fab::before,
  .fab::after,
  .skeleton,
  .login-bg::before,
  .login-bg::after,
  #loginPage::before,
  #loginPage::after,
  .login-logo,
  .login-logo .mini-heart,
  .ch-sub .dot.online,
  .typing-tip i,
  .love-dot,
  .draw-bigicon,
  .draw-live,
  .capsule-locked,
  .pet-svg,
  .pet-tongue,
  .pet-dot,
  .pet-dot::after,
  .ch-sub .dot.online::after,
  .cb-state .dot.online::after,
  .flash::after,
  #chatBadge.show::after,
  .pet-drag-hint,
  .status-chip.live {
    animation: none !important;
  }
  /* 入场动画只保留最终状态，避免元素停在透明处 */
  .msg,
  .msg-row,
  .card,
  .moment-item,
  .list-card,
  .login-card,
  .sheet,
  .enter-up { animation: none !important; opacity: 1 !important; transform: none !important; }
  /* 悬浮位移也一并取消 */
  .card:hover,
  .list-card:hover,
  .moment-item:hover,
  .quick-item:hover,
  .badge-item:hover,
  .play-item:hover,
  .watch-item:hover { transform: none !important; }
}
