/* ==========================================================================
   微信聊天仿真界面 —— 样式（v2：按参考项目 weixin-chat 的真实数值重建）
   --------------------------------------------------------------------------
   设计基准：390 × 844（iPhone X 逻辑尺寸）
   参考项目原始数值均为 3 倍图，本文件已统一 ÷3，注释里给出换算来源：
     · 机身 1170×2532 → 390×844
     · 状态栏高 132 → 44 ，左内边距 95 → 31.67 ，右 43 → 14.33
     · 标题栏高 132 → 44 ，左右内边距 50 → 16.67
     · 标题字号 51 → 17 ，状态栏时间 45 → 15（字重 600）
     · 未读角标 72×72/r36 → 24×24/r12 ，底色 #d5d5d5
     · 聊天区 padding 36 → 12 ，消息行间距 50 → 16.67
     · 头像 123 → 41 ，圆角 15 → 5 ，底色 #f1f1f1
     · 气泡字号 48 → 16 ，内边距 28/38 → 9.33/12.67 ，圆角 15 → 5 ，最小高 123 → 41
     · 自己气泡 #98e970（不是网上常见的 #95EC69）
     · 气泡尖角 24×24 旋转 45° → 8×8 ，距顶 50 → 16.67 ，偏移 → -4
     · 时间/系统提示 36 → 12 ，颜色 #a6a6a6
     · 带底色提示 hsla(0,0%,100%,.5) / 字色 #151414 / padding 3.33,5.67 / r5
     · 红包·转账卡片 宽 700 → 233 ，内容高 192 → 64 ，图标 120 → 40
       主文案 48 → 16 ，副文案 36 → 12 ，分隔线 #f0b36f ，底栏高 71 → 23.67
       底栏字 12 / #faecda ；已收款态 #f8e2c6 + 分隔线 #f9e7d1
     · 图片气泡 border 1px #d5d5d5 ，最大 420 → 140
     · 语音条喇叭图标 34×49 → 11.33×16.33 ，时长 42 → 14 ，未读点 25 → 8.33 / #e75e58
     · 输入栏总高 167 → 55.67 ，底部条 102 → 34 ，输入框高 120 → 40 / r5 / 左右 10.67
     · 输入栏图标 80 → 26.67
   ==========================================================================
   v3 校准（2026-09-19）：按两张 1216px 宽的真实微信长截图逐像素实测修订
   （截图 × 0.3207 ≈ 本项目 px；原机 360dp 宽、密度 3.378，换算见 jiaoduijietu/校对报告.md）
     · 自己气泡 #98e970 → **#AAEA7A**（实测 56 万像素点绝对主导，三个参考项目都错了）
     · 气泡最小高 41 → 45；字号 16 → 17（实测字距 55px）；行高 1.4 → 1.41
     · 内边距 9.33/12.67 → 10.3/13.3；圆角 5 → 4（实测 10~12px）
     · 尖角：8×8 旋转方块 → 三角形，突出 4.8px、高 9px、距顶 14.5px（实测突出 15px/高 28px/峰位 dy60）
     · 头像 41 → 42，圆角 5 → 4
     · 同发送者连续气泡间距与普通行距一致（实测 52~54px，无紧堆）
     · 引用：真实微信是气泡下方的独立灰条 #E1E1E1（文字 #656565、字号 13.5、
       与气泡同侧对齐、上间隙 4.2px），不再是气泡内左线样式
     · 语音条宽度实测：宽 ≈ 88 + 2.2×秒数（本项目 px）
   ========================================================================== */

/* 内嵌鸿蒙字体（华为官方 HarmonyOS Sans SC，全字形，可免费商用）
   与真机字体同源 → 换行位置/字宽与真实截图一致 */
@font-face {
  font-family: "HarmonyOS Sans SC";
  src: url(../assets/fonts/HarmonyOS_Sans_SC_Regular.woff2) format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "HarmonyOS Sans SC";
  src: url(../assets/fonts/HarmonyOS_Sans_SC_Medium.woff2) format("woff2");
  font-weight: 500 700;
  font-display: swap;
}

:root {
  --w: 390px;
  --h: 844px;

  --bg: #ededed;
  --top-bg: #ededed;
  --text: #191919;
  --text-weak: #a6a6a6;
  --line: #d5d5d5;

  --self-bubble: #aaea7a;
  --other-bubble: #ffffff;

  --avatar: 42px;
  --avatar-radius: 4px;
  --bubble-radius: 4px;
  --bubble-font: 17.6px;   /* 实测字距 55px×0.3207=17.64，决定换行位置，别取整 */
  --row-gap: 16.67px;
  --content-pad: 12px;

  --trans-bg: #f79c46;
  --trans-done-bg: #f8e2c6;

  --bar-h: 44px;
  --nav-h: 44px;
  --bottom-chat-h: 55.67px;
  --bottom-bar-h: 34px;

  --font: "HarmonyOS Sans SC", -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue",
          "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", sans-serif;
}

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

html, body {
  margin: 0; padding: 0; height: 100%; overflow: hidden;
  background: #d0d0d0;
  font-family: var(--font);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}

/* ============================ 机身 ============================ */
.phone {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  max-width: var(--w);
  margin: 0 auto;
  background: var(--bg);
  overflow: hidden;
}

/* 电脑上预览时套一个手机边框（与参考项目的宣传图一致）
   v3.2：边框改用 box-shadow 画（不占布局）——内部版式宽度恒等于 var(--w)，
   和校对模式、真机全屏完全同源，不会再出现"边框偷 18px 导致气泡越界"的问题 */
@media (min-width: 440px) and (min-height: 700px) {
  body { background: #c8c8c8; padding: 18px 0; display: flex; }
  .phone {
    width: var(--w);
    height: min(var(--h), calc(100vh - 36px));
    flex: none;
    border: none;
    border-radius: 46px;
    box-shadow:
      0 0 0 9px #1b1b1d,
      inset 0 0 0 1.5px #3a3a3d,
      0 18px 50px rgba(0, 0, 0, .35);
  }
}

/* ============================ 顶部区 ============================ */
.phone-top {
  flex: none;
  position: relative;
  background: var(--top-bg);
  z-index: 5;
}
.phone-top::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0;
  height: .5px; background: var(--line);
}

/* 状态栏 */
.phone-bar {
  display: flex;
  align-items: center;
  height: var(--bar-h);
  padding: 0 14.33px 0 31.67px;
}
.phone-time {
  flex: 1;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .2px;
  color: var(--text);
}
.phone-signal { display: flex; align-items: center; }

.ico { display: inline-block; background-repeat: no-repeat; background-size: contain; background-position: center; }
.ico-sig { width: 21px; height: 15px; }
.ico-wifi { width: 20px; height: 15px; margin-left: 5px; background-image: url(../assets/icons/wifi.png); }
.ico-battery {
  position: relative;
  width: 25px; height: 12px; margin-left: 5px;
  background-image: url(../assets/icons/battery.png);
}
.ico-battery .batt-fill {
  position: absolute;
  left: 2.4px; top: 1.9px; bottom: 1.9px;
  width: 50%;
  background: #000;
  border-radius: 1.33px;
}
.ico-battery.charging .batt-fill { background: #65c466; }

/* 标题栏 */
.phone-nav {
  position: relative;
  display: flex;
  align-items: center;
  height: var(--nav-h);
  padding: 0 16.67px;
}
.phone-nav-left { position: relative; width: 50px; display: flex; align-items: center; }
.nav-back { width: 10px; height: 18px; color: #191919; display: block; }
.nav-back svg { display: block; }
.nav-badge {
  min-width: 24px; height: 24px; line-height: 24px;
  margin-left: 12px; padding: 0 8px;
  border-radius: 12px;
  background: #d5d5d5;
  font-size: 12px; font-weight: 600; text-align: center; color: #191919;
}
.phone-nav-center { flex: 1; display: flex; justify-content: center; min-width: 0; }
.phone-nav-center span {
  font-size: 17px; font-weight: 500;
  max-width: 66%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.phone-nav-right { width: 50px; display: flex; justify-content: flex-end; }
.nav-more { width: 22px; height: 6px; color: #191919; display: block; }
.nav-more svg { display: block; }
.phone.dark .nav-back, .phone.dark .nav-more { color: #ededed; }

/* ============================ 聊天滚动区 ============================ */
.phone-body {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  background: var(--bg);
  background-size: cover;
  background-position: center;
  /* v3.2：滚动条彻底不占布局！真实微信没有可见滚动条；
     若让实体滚动条占 17px，右对齐的宽绿泡会整体左移、左缘越过白泡左缘 */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.phone-body::-webkit-scrollbar { width: 0; height: 0; display: none; }
.phone-body::-webkit-scrollbar-thumb { background: transparent; }

.wechat-content {
  display: flex;
  flex-direction: column;
  padding: var(--content-pad);
  min-height: 100%;
  justify-content: flex-end;
}

/* ============================ 消息行 ============================ */
.wechat-dialog {
  position: relative;
  display: flex;
  align-items: flex-start;
  margin-bottom: var(--row-gap);
  content-visibility: auto;
  contain-intrinsic-size: auto 62px;
}
.wechat-dialog.same-sender { margin-bottom: var(--row-gap); }
/* 自己发的消息：头像在最右侧，气泡在头像左边（row-reverse 让第一个子元素先贴右） */
.wechat-dialog-right { flex-direction: row-reverse; }

/* 头像 */
.wechat-dialog-face {
  flex: none;
  width: var(--avatar);
  height: var(--avatar);
  border-radius: var(--avatar-radius);
  background: #f1f1f1;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.wechat-dialog-face img { width: 100%; height: 100%; object-fit: cover; display: block; }

.wechat-dialog-main { display: flex; flex-direction: column; max-width: calc(100% - var(--avatar) - 34px); }
.wechat-dialog-main { margin-left: 11px; }
.wechat-dialog-right .wechat-dialog-main { align-items: flex-end; margin-left: 0; margin-right: 11px; }

.dialog-name {
  font-size: 12px; color: #9a9a9a;
  margin: 0 0 3px 3px; display: none;
}
.wechat-content.show-names .dialog-name { display: block; }

.dialog-line { display: flex; align-items: center; gap: 6.67px; }
.wechat-dialog-right .dialog-line { flex-direction: row-reverse; }

/* 气泡本体 */
.wechat-dialog-text {
  position: relative;
  display: inline-block;
  min-height: 45px;
  padding: 10.3px 13.3px;
  border-radius: var(--bubble-radius);
  background: var(--other-bubble);
  font-size: var(--bubble-font);
  line-height: 1.41;
  word-break: break-word;
  white-space: pre-wrap;
  /* 宽度上限 v3.1：真实实测 63.1%，但鸿蒙字体在网页里拉丁/括号略宽 2~3px，
     为让原图首行（如「…GEO客户话」）能放下，放宽到 64.3%（≈251px） */
  max-width: calc(var(--w) * 0.643);
}
.wechat-dialog-right .wechat-dialog-text { background: var(--self-bubble); }

/* 气泡尖角（v3 按真实截图实测：三角形，突出 4.8px、高 9px、峰位距顶约 19px） */
.wechat-dialog-text::after {
  content: "";
  position: absolute;
  width: 0; height: 0;
  top: 14.5px;
  left: -4.7px;
  border-top: 4.6px solid transparent;
  border-bottom: 4.6px solid transparent;
  border-right: 4.8px solid var(--other-bubble);
}
.wechat-dialog-right .wechat-dialog-text::after {
  left: auto; right: -4.7px;
  border-right: none;
  border-left: 4.8px solid var(--self-bubble);
}
.wechat-dialog-text.no-tail::after { display: none; }

/* 气泡内网址：真实截图实测为微信链接蓝（非正文黑） */
.txt-link { color: #576b95; }

/* ---------- 时间分隔 / 系统提示 / 撤回 / 通话 ---------- */
.wechat-dialog-notice {
  display: flex;
  justify-content: center;
  flex: 1;
  font-size: 12px;
  color: var(--text-weak);
  margin: 6px 0 12px;
}
.wechat-dialog-notice > span {
  display: flex;
  align-items: center;
  padding: 3.33px 6px;
  line-height: 1.5;
  text-align: center;
}
.wechat-dialog-notice .has-bg {
  background: hsla(0, 0%, 100%, .5);
  color: #151414;
  padding: 3.33px 5.67px;
  border-radius: 5px;
}
.wechat-dialog-notice .sys { padding: 3.33px 10px; }
.wechat-dialog-notice em { font-style: normal; color: #ef9d49; }
.notice-recall { display: flex; align-items: center; gap: 4px; }
.notice-recall .re-edit { color: #576b95; }
.notice-rp {
  width: 15px; height: 17px; margin-right: 5px;
  background: url(../assets/icons/rp-small.png) no-repeat center/contain;
}
.notice-call svg { margin-right: 5px; }

/* 通话记录 */
.call-pill {
  display: flex; align-items: center; gap: 5px;
  background: hsla(0, 0%, 100%, .5);
  color: #151414;
  border-radius: 5px;
  padding: 4px 8px;
  font-size: 12px;
}

/* ---------- 图片 ---------- */
.wechat-dialog-image {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--bubble-radius);
  background: transparent;
  overflow: hidden;
  line-height: 0;
  max-width: 70%;
}
.wechat-dialog-image img { display: block; max-width: 148px; }
.wechat-dialog-image .ph-img {
  display: flex; align-items: center; justify-content: center;
  width: 140px; height: 105px;
  color: #fff; font-size: 12px; text-align: center; padding: 0 8px;
  line-height: 1.35;
}
.wechat-dialog-image.no-border { border: none; }

/* 图片占位 */
.ph-img.ph-a { background: linear-gradient(135deg, #8ab4f8, #5c7cfa); }
.ph-img.ph-b { background: linear-gradient(135deg, #f6a5c0, #e56b8b); }
.ph-img.ph-c { background: linear-gradient(135deg, #9ad6a0, #4fae6a); }
.ph-img.ph-d { background: linear-gradient(135deg, #ffd479, #f0a638); }
.ph-img.ph-e { background: linear-gradient(135deg, #a5b4fc, #6d76e8); }
.ph-img.ph-f { background: linear-gradient(135deg, #b0bec5, #78909c); }

/* 视频 */
.video-wrap { position: relative; width: 168px; height: 126px; overflow: hidden; }
.video-wrap .ph-img { width: 100%; height: 100%; }
.video-wrap img { width: 100%; height: 100%; object-fit: cover; display: block; }
.video-wrap .play-btn {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 44px; height: 44px; border-radius: 50%;
  background: rgba(0, 0, 0, .45);
  display: flex; align-items: center; justify-content: center;
}
.video-wrap .play-btn svg { margin-left: 3px; }
.video-wrap .dur {
  position: absolute; right: 5px; bottom: 5px;
  background: rgba(0, 0, 0, .5); color: #fff;
  font-size: 11px; padding: 1px 4px; border-radius: 2px;
  line-height: 1.4;
}

/* ---------- 语音条 ---------- */
.wechat-dialog-voice {
  display: flex;
  align-items: center;
  min-height: 45px;
  padding: 10.3px 13.3px;
  border-radius: var(--bubble-radius);
  background: var(--other-bubble);
  position: relative;
}
.wechat-dialog-right .wechat-dialog-voice { background: var(--self-bubble); }
.wechat-dialog-voice::after {
  content: "";
  position: absolute; width: 0; height: 0;
  top: 14.5px; left: -4.7px;
  border-top: 4.6px solid transparent;
  border-bottom: 4.6px solid transparent;
  border-right: 4.8px solid var(--other-bubble);
}
.wechat-dialog-right .wechat-dialog-voice::after {
  left: auto; right: -4.7px;
  border-right: none;
  border-left: 4.8px solid var(--self-bubble);
}
.voice-ico { flex: none; width: 11.33px; height: 16.33px; background-repeat: no-repeat; background-size: contain; background-position: center; }
.voice-ico.left { background-image: url(../assets/icons/voice-left.png); }
.voice-ico.right { background-image: url(../assets/icons/voice-right.png); }
.wechat-dialog-voice .dur { font-size: 15px; color: #1a1a1a; }
.wechat-dialog-right .wechat-dialog-voice .dur { color: #2f3b2f; }
.wechat-dialog-voice .dur-l { padding-right: 6.67px; }
.wechat-dialog-voice .dur-r { padding-left: 6.67px; }
.voice-unread {
  position: absolute; right: -20px; top: 50%; margin-top: -4.17px;
  width: 8.33px; height: 8.33px; border-radius: 50%; background: #e75e58;
}
/* 语音转文字泡（v3.2 按 2x 真实截图实测 722px/360dp 设备）：
   · 语音条正下方，间距 8px@2x ≈ 4.3px
   · 恒为白色气泡（自己发的绿语音条，转写泡也是白的！）
   · 恒为左对齐、接近全宽（实测宽 458px@2x = 247px，文字与普通气泡同号同色）
   · 圆角/内边距同普通气泡 */
.voice-transcript {
  margin-top: 4.3px;
  align-self: flex-start;
  width: fit-content;
  max-width: 248px;
  font-size: var(--bubble-font); color: var(--text); line-height: 1.41;
  background: var(--other-bubble);
  border-radius: var(--bubble-radius);
  padding: 10.3px 13.3px;
  word-break: break-word;
  white-space: pre-wrap;
}
.wechat-dialog-right .voice-transcript { background: var(--other-bubble); }

/* ---------- 引用 ----------
   v3 实测（真实截图）：引用是气泡下方的独立灰条，与气泡同侧对齐（自己发的靠右），
   底色 #E1E1E1、文字 #656565、字号 13.5px、圆角 4px、上间隙 4.2px、内边距同气泡 */
.quote-strip {
  margin-top: 4.2px;
  padding: 8.6px 13.3px;
  background: #e1e1e1;
  border-radius: var(--bubble-radius);
  font-size: 13.5px;
  color: #656565;
  line-height: 1.5;
  align-self: flex-start;
  width: fit-content;
  /* 引用条可比气泡更宽：实测最宽 818px/1216 = 屏宽 67.2% */
  max-width: calc(var(--w) * 0.672);
  word-break: break-word;
  white-space: pre-wrap;
  text-align: left;
  /* v3.3：超长引用两行截断 + 省略号（308 实测 166px=53.3 高 → 行高 18） */
  line-height: 18px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.wechat-dialog-right .quote-strip { align-self: flex-end; }
.quote-strip .q-name { color: #656565; }
/* 图片缩略引用条（v3.3 按 308 实测）：条高 45.6、昵称大字 20px、
   右侧白卡缩略 28.9×32 垂直居中、右缘距条右 16 */
.quote-thumb-strip {
  display: flex; align-items: center;
  min-height: 45.6px;
  padding: 6.8px 16px 6.8px 8.3px;
}
.quote-thumb-strip .qt-name {
  font-size: 20px; color: #8a8a8a; flex: 1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.quote-thumb-strip .qt-img {
  flex: none; width: 28.9px; height: 32px;
  border-radius: 2px; overflow: hidden; background: #fff;
}
.quote-thumb-strip .qt-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.quote {
  background: rgba(0, 0, 0, .045);
  border-left: 2px solid #c9c9c9;
  border-radius: 3px;
  padding: 4.67px 8px;
  margin-bottom: 6px;
  font-size: 13.5px;
  color: #7a7a7a;
  line-height: 1.4;
}
.quote .q-name { color: #576b95; margin-right: 4px; }

/* ---------- 红包 / 转账（照参考项目数值） ---------- */
/* 宽度：网页版 CSS 写的是 700px@3x = 233px，但安卓版成品截图实测为 259px
   —— 两个产品（网页基础版 / 安卓版）本就不同，这里采用安卓版实测值，与截图观感一致 */
.wechat-dialog-trans {
  width: 259px;
  max-width: 100%;
  border-radius: 5px;
  overflow: hidden;
  background: var(--trans-bg);
  line-height: normal;
}
.wechat-dialog-trans-content {
  display: flex;
  align-items: center;
  height: 64px;
  position: relative;
  padding: 0 14px;
}
.wechat-dialog-trans-content::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 1px; background: #f0b36f;
}
.wechat-dialog-trans-content i {
  flex: none;
  width: 40px; height: 40px;
  background: url(../assets/icons/trans.png) no-repeat center/contain;
}
.wechat-dialog-trans-content.redp i { background-image: url(../assets/icons/rp-large.png); }
.wechat-dialog-trans-content > div {
  flex: 1;
  display: flex; flex-direction: column;
  margin-left: 10px;
  overflow: hidden;
}
.wechat-dialog-trans-content > div span {
  font-size: 16px; color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.wechat-dialog-trans-content > div font {
  font-size: 12px; color: #fff; margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.wechat-dialog-trans-bottom {
  height: 23.67px;
  display: flex; align-items: center;
  padding: 0 14px;
}
.wechat-dialog-trans-bottom span { font-size: 12px; color: #faecda; }

/* ---------- 视频消息（v3.3 锚点实测：缩略 292×404px = 93.6×129.6、
   播放白圈居中 Ø54.5、时长右下白字 13 带阴影；内容 cover 裁剪不保比例） ---------- */
.video-thumb {
  position: relative; width: 93.6px; height: 129.6px;
  border-radius: 4px; overflow: hidden; background: #000;
}
.video-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.video-play {
  position: absolute; left: 50%; top: 50%;
  width: 54.5px; height: 54.5px; margin: -27.25px 0 0 -27.25px;
  border: 2.6px solid rgba(255, 255, 255, .92); border-radius: 50%;
  box-sizing: border-box;
}
.video-play::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  transform: translate(-36%, -50%);
  border-left: 19px solid #fff;
  border-top: 11.5px solid transparent;
  border-bottom: 11.5px solid transparent;
}
.video-dur {
  position: absolute; right: 8px; bottom: 7px;
  color: #fff; font-size: 13px;
  text-shadow: 0 1px 4px rgba(0, 0, 0, .75);
}
.video-cap { font-size: var(--bubble-font); color: #191919; margin-top: 6px; }

/* 已收款 / 已领取态（参考项目：换成浅色底 + 对勾图标） */
.wechat-dialog-trans-get { background: var(--trans-done-bg); }
.wechat-dialog-trans-get .wechat-dialog-trans-content i { background-image: url(../assets/icons/trans-done.png); }
.wechat-dialog-trans-get .wechat-dialog-trans-content::after { background: #f9e7d1; }
.wechat-dialog-trans-get .wechat-dialog-trans-bottom span { color: #fff; }

/* ---------- 文件卡片（v3.3 终版B：锚点网格图精读定案，308 原图 Word 卡）
   卡 711×301px = 228×96.5；标题两行 17.6/行距24.7、左内边距 8；
   灰字 13 #B0B0B0、标题墨底→灰字墨顶 13.1；顶部留白 13.8、底部 19.9；
   图标 132×202px = 42.3×64.8，右缘溢出卡右 7.7、顶距卡顶 9.9；
   文字→图标 15.7；标题每行约 10 个汉字 ---------- */
.file-card {
  display: flex; align-items: flex-start;
  width: 228px; max-width: 100%;
  background: var(--other-bubble);
  border: none;
  border-radius: 4px;
  padding: 9.7px 0 10.5px 3.8px;
  position: relative;
  box-sizing: border-box;
}
.file-ico {
  flex: none; width: 40px; height: 40px; border-radius: 5px;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 10.5px; font-weight: 700; letter-spacing: .2px;
}
.file-ico-img {
  flex: none; width: 42.3px; height: 64.8px;
  margin-left: 13px; margin-top: 0.2px; margin-right: -7.7px;
  object-fit: contain; display: block;
}
.file-meta { min-width: 0; flex: 1; }
.file-name {
  font-size: var(--bubble-font); color: #191919; line-height: 24.7px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; word-break: break-all;
}
.file-sub { font-size: 13px; color: #b0b0b0; margin-top: 9px; }
.file-sub.expired { color: #fa5151; }
.file-card.has-foot { padding-bottom: 26px; }
.file-foot {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 22px; display: flex; align-items: center; gap: 5px;
  padding: 0 12px;
  border-top: 1px solid rgba(0, 0, 0, .06);
  font-size: 11px; color: var(--text-weak);
}
.file-foot svg { flex: none; }

/* ---------- 消息合并（聊天记录卡片） ---------- */
.merge-card {
  width: 233px; max-width: 100%;
  background: var(--other-bubble);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 11px 12px 0;
}
.merge-title {
  font-size: 15px; color: #191919; line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.merge-line {
  font-size: 12px; color: #9a9a9a; margin-top: 5px; line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.merge-line .m-name { color: #b0b0b0; margin-right: 3px; }
.merge-foot {
  margin-top: 9px; padding: 6px 0;
  border-top: 1px solid rgba(0, 0, 0, .06);
  font-size: 11.5px; color: var(--text-weak);
}

/* ---------- 通话记录（气泡样式，v3.3 原图实测：
   图标 = 抠图 call-phone.png 形状做 CSS mask，颜色跟随文字（绿白泡统一黑）；
   尺寸 24.4×10.3；泡→图标 白泡16.0/绿泡13.1（在泡 padding 13.3 基础上白泡补 2.7）；
   图标→文字 8.7；侧别由 DOM 顺序控制 ---------- */
.call-text { display: inline-flex; align-items: center; }
.call-ico-inline {
  display: inline-block; width: 24.4px; height: 10.3px;
  background: currentColor;
  -webkit-mask: url(../assets/icons/call-phone.png) no-repeat center / contain;
  mask: url(../assets/icons/call-phone.png) no-repeat center / contain;
  margin-right: 8.7px;
}
.wechat-dialog-left .call-text .call-ico-inline:first-child { margin-left: 2.7px; }
.call-text .call-ico-inline:last-child { margin-right: 0; margin-left: 8.7px; }

/* ---------- 被对方拒收：红色圆形感叹号 ---------- */
.reject-badge {
  flex: none;
  width: 18px; height: 18px; border-radius: 50%;
  background: #fa5151;
  display: inline-flex; align-items: center; justify-content: center;
}

/* ---------- 链接卡片（v3.3 锚点网格定案B，深色截图测结构同浅色）
   卡 829×432px = 265.9×138.5、白底圆角4；
   结构：标题全宽两行(17.6/24.7)在上，下部 = 描述(17/20.8 灰,3行) + 缩略；
   缩略正方 169×169px = 54.2×54.2 白底、右距卡右 17.6、顶对齐描述区；
   标题墨左距卡左 9.9、顶距卡顶 13.8、标题→描述 11.9、卡底留白 18.9 ---------- */
.link-card {
  display: flex; flex-direction: column;
  width: 265.9px; max-width: 100%;
  background: var(--other-bubble);
  border: none;
  border-radius: 4px;
  padding: 9.7px 17.6px 18.9px 8px;
  box-sizing: border-box;
}
.link-title {
  font-size: var(--bubble-font); line-height: 24.7px; color: #191919;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.link-lower { display: flex; gap: 9.9px; margin-top: 7.7px; }
.link-desc {
  flex: 1; min-width: 0;
  font-size: var(--bubble-font); line-height: 20.8px; color: #7f7f7f;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.link-src { font-size: 11.5px; color: #b8b8b8; margin-top: 5px; }
.link-thumb {
  flex: none; align-self: flex-start;
  width: 54.2px; height: 54.2px; border-radius: 4px; overflow: hidden;
  background: #fff;
  display: flex; align-items: center; justify-content: center;
}
.link-thumb img { width: 100%; height: 100%; object-fit: cover; }
.link-thumb .ph-img { width: 46px; height: 46px; font-size: 10px; border-radius: 4px; padding: 0 3px; }

/* ---------- 位置：名称+地址在上，地图在下（依据参考截图实测结构） ---------- */
.loc-card {
  width: 213px; max-width: 100%;
  background: var(--other-bubble);
  border: 1px solid var(--line);
  border-radius: 5px; overflow: hidden;
}
.loc-body { padding: 10px 11px 9px; }
.loc-name {
  font-size: 15px; color: #191919; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.loc-addr { font-size: 12px; color: var(--text-weak); margin-top: 3px; line-height: 1.35; }
.loc-map { height: 104px; position: relative; background: #eef0e9; }
.loc-map img { width: 100%; height: 100%; object-fit: cover; display: block; }
.loc-map .map-svg { display: block; width: 100%; height: 100%; }

/* ---------- 个人名片（结构依据 wechat-online 的 PersonalCard 实现） ---------- */
.card-card {
  width: 240px; max-width: 100%;
  background: var(--other-bubble);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 8px 10px 0;
}
.card-top {
  display: flex; align-items: center; gap: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(0, 0, 0, .05);
}
.card-top .face {
  width: 40px; height: 40px; border-radius: 4px; overflow: hidden; flex: none; background: #f1f1f1;
}
.card-top .face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.card-txt { min-width: 0; }
.card-name { font-size: 16px; color: #191919; }
.card-desc { font-size: 12px; color: var(--text-weak); margin-top: 2px; }
.card-foot {
  padding: 6px 0 7px;
  font-size: 12px; color: rgba(0, 0, 0, .4);
}

/* ---------- 表情包 ---------- */
.sticker-img {
  width: 122px; height: 122px;
  display: flex; align-items: center; justify-content: center;
  font-size: 58px; line-height: 1;
}
.sticker-img img { width: 100%; height: 100%; object-fit: contain; }
/* 表情名字没匹配上时的占位提示 */
.emoji-miss {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 92px; height: 92px; border: 1px dashed #c9c9c9; border-radius: 8px;
  color: #b0b0b0; font-size: 12px; line-height: 1.5; text-align: center;
}

/* 文字消息里的内联表情图（微信表情素材，约 1.25 倍字号） */
.emoji-inline {
  width: 20px; height: 20px;
  vertical-align: -4px;
  margin: 0 1px;
  display: inline-block;
}

/* ---------- 正在输入 ---------- */
.typing-row {
  display: flex; align-items: center; gap: 8px;
  padding: 0 16px 14px;
  font-size: 12px; color: var(--text-weak);
}
.typing-dots { display: inline-flex; gap: 3px; }
.typing-dots i {
  width: 5px; height: 5px; border-radius: 50%; background: #b8b8b8;
  animation: blink 1.3s infinite both;
}
.typing-dots i:nth-child(2) { animation-delay: .2s; }
.typing-dots i:nth-child(3) { animation-delay: .4s; }
@keyframes blink { 0%, 80%, 100% { opacity: .35; } 40% { opacity: 1; } }

/* ============================ 底部区 ============================ */
.phone-bottom {
  flex: none;
  background: #f6f6f6;
  border-top: .5px solid var(--line);
}
.phone-bottom-chat { height: var(--bottom-chat-h); }

.wechat-bottom {
  display: flex;
  align-items: center;
  height: 100%;
  /* v3.3 间距按 1216 原图实测：右缘留 12.5、表情→加号视觉间隙 18.5、加号本体 24.6 */
  padding: 0 12.5px;
}
.wechat-bottom-icon {
  flex: none;
  width: 27.3px; height: 27.3px;
  background-repeat: no-repeat; background-size: contain; background-position: center;
}
.ib-voice { background-image: url(../assets/icons/input-voice.png); }
.ib-emoji { background-image: url(../assets/icons/input-emoji.png); width: 27.3px; }
/* v3.3：麦克风（306 实测重抠：框内右侧 13.8×17.3，透明底；
   输入框→麦克风 15、麦克风→表情 17.3） */
.ib-mic {
  width: 13.8px; height: 17.3px; margin: 0 17.3px 0 0;
  background-image: url(../assets/icons/input-mic.png);
}
.ib-plus {
  width: 24.6px; height: 24.6px; margin-left: 18.5px;
  background-image: url(../assets/icons/input-plus.png);
}
.wechat-input {
  height: 40px;
  /* 输入框→麦克风间距 15（306 实测 903→950） */
  margin: 0 15px 0 10px;
  flex: 1;
  background: #fff;
  border-radius: 5px;
  display: flex;
  align-items: center;
  padding: 0 12px;
  color: #b2b2b2;
  font-size: 16px;
  position: relative;
}
.wechat-input .caret {
  width: 1.5px; height: 19px;
  background: #07c160;
  animation: caret 1.05s steps(1) infinite;
}
@keyframes caret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

/* 系统导航栏 */
.phone-bottom-bar {
  height: var(--bottom-bar-h);
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f6f6f6;
}
.home-bar {
  width: 134px; height: 5px; border-radius: 2.5px;
  background: #000; opacity: .28;
}
.android-nav { display: none; align-items: center; gap: 34px; color: #5b5b5b; }
.android-nav svg { display: block; }

/* 苹果 / 安卓 两套外观 */
.phone.platform-ios .android-nav { display: none; }
.phone.platform-ios .home-bar { display: block; }
.phone.platform-android .home-bar { display: none; }
.phone.platform-android .android-nav { display: flex; }

.phone.platform-android {
  --bar-h: 28px;
  --nav-h: 48px;
  --bottom-bar-h: 40px;
}
.phone.platform-android .phone-bar { padding: 0 12px; }
.phone.platform-android .phone-time { font-size: 13px; font-weight: 500; }
.phone.platform-android .phone-nav { padding: 0 12px; }
.phone.platform-android .phone-bottom-bar { background: #ececec; }

/* ============================ 回到最新 ============================ */
.jump-latest {
  position: absolute; right: 12px;
  bottom: calc(var(--bottom-chat-h) + var(--bottom-bar-h) + 10px);
  border: none;
  border-radius: 14px;
  background: rgba(255, 255, 255, .96);
  color: #576b95;
  font-size: 12px;
  font-family: var(--font);
  padding: 5px 10px;
  display: inline-flex; align-items: center; gap: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .14);
}
.jump-latest[hidden] { display: none; }

/* ============================ 深色模式 ============================ */
/* 底色用纯黑（依据参考截图 img/2.png 的深色模式实测） */
.phone.dark {
  --bg: #000000;
  --top-bg: #1e1e1e;
  --text: #ededed;
  --text-weak: #9a9a9a;
  --line: #2c2c2e;
  --self-bubble: #3eb575;
  --other-bubble: #2c2c2e;
}
.phone.dark .phone-time, .phone.dark .phone-nav-center span { color: #ededed; }
.phone.dark .ico-battery .batt-fill { background: #fff; }
.phone.dark .wechat-dialog-text { color: #ededed; }
.phone.dark .wechat-dialog-voice .dur { color: #d0d0d0; }
.phone.dark .phone-bottom, .phone.dark .phone-bottom-bar { background: #1c1c1e; }
.phone.dark .wechat-input { background: #2c2c2e; }
.phone.dark .home-bar { background: #fff; opacity: .35; }
.phone.dark .android-nav { color: #b0b0b0; }
.phone.dark .file-card, .phone.dark .link-card, .phone.dark .loc-card,
.phone.dark .card-card, .phone.dark .merge-card {
  background: var(--other-bubble); border-color: #3a3a3c;
}
.phone.dark .file-name, .phone.dark .link-title, .phone.dark .loc-name,
.phone.dark .card-name, .phone.dark .merge-title { color: #ededed; }
.phone.dark .file-foot, .phone.dark .card-top, .phone.dark .merge-foot { border-color: rgba(255, 255, 255, .08); }
.phone.dark .card-foot { color: rgba(255, 255, 255, .4); }
.phone.dark .quote, .phone.dark .quote-strip { background: rgba(255, 255, 255, .07); color: #a8a8a8; }
.phone.dark .voice-transcript { color: #a8a8a8; }
.phone.dark .wechat-dialog-notice .has-bg,
.phone.dark .call-pill { background: rgba(255, 255, 255, .08); color: #c8c8c8; }
.phone.dark .call-pill { color: #c8c8c8; }
.phone.dark .jump-latest { background: rgba(60, 60, 60, .95); color: #d0d0d0; }
.phone.dark .call-ico-inline { color: #d0d0d0; }
.phone.dark .wechat-dialog-right .call-ico-inline { color: #12301c; }

/* ============================ 控制面板 ============================ */
.panel-toggle {
  position: fixed; right: 14px; top: 14px; z-index: 40;
  width: 40px; height: 40px; border-radius: 50%;
  border: none; background: rgba(30, 30, 30, .62); color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 3px 10px rgba(0, 0, 0, .22);
  cursor: pointer;
}
.panel-toggle.hidden { display: none; }

.panel {
  position: fixed; right: 12px; top: 12px; bottom: 12px; z-index: 50;
  width: min(340px, calc(100vw - 24px));
  background: #fff; border-radius: 14px;
  box-shadow: 0 14px 44px rgba(0, 0, 0, .28);
  padding: 16px 16px 20px;
  overflow-y: auto;
  font-size: 14px;
  color: #191919;
}
.panel[hidden] { display: none; }
.panel-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.panel-head strong { font-size: 16px; }
.panel-close {
  border: none; background: #f0f0f0; width: 28px; height: 28px;
  border-radius: 50%; font-size: 19px; line-height: 1; color: #666; cursor: pointer;
}
.panel-sec { padding: 13px 0; border-top: 1px solid #f0f0f0; }
.panel-sec:first-of-type { border-top: none; padding-top: 0; }
.panel-label { display: block; font-weight: 600; margin-bottom: 8px; color: #333; }
.panel-select, .panel-input {
  width: 100%; padding: 8px 10px; border: 1px solid #dcdcdc; border-radius: 8px;
  font-size: 14px; font-family: var(--font); background: #fff; color: #222;
}
.panel-input { margin-bottom: 8px; }
.panel-btn {
  width: 100%; padding: 9px 12px; border: none; border-radius: 8px;
  background: #07c160; color: #fff; font-size: 14px; font-weight: 500;
  margin-bottom: 8px; cursor: pointer; font-family: var(--font);
}
.panel-btn.ghost { background: #f0f0f0; color: #444; margin-bottom: 0; }
.panel-hint { font-size: 12.5px; color: #999; line-height: 1.5; margin: 8px 0 0; }
.panel-radios { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 8px; }
.panel-radios label { display: inline-flex; align-items: center; gap: 5px; font-size: 13.5px; color: #444; }
.panel-check { display: flex; align-items: center; gap: 7px; font-size: 13.5px; color: #444; margin-top: 8px; }

.toast {
  position: fixed; left: 50%; bottom: 84px; transform: translateX(-50%);
  z-index: 60; background: rgba(0, 0, 0, .78); color: #fff;
  padding: 9px 16px; border-radius: 8px; font-size: 13.5px;
  max-width: 84vw; text-align: center; line-height: 1.45;
}
.toast[hidden] { display: none; }
