/* WEMI M1 —— 玫红主色 #d53f8c，聊天区零广告位 */
:root { --accent:#d53f8c; --bg:#f6f7f9; --card:#fff; --text:#1a1a1a; --sub:#8a919c; --line:#ececf0; }
* { margin:0; padding:0; box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
/* 2026-09-30 手机底部黑边修复：html 背景兜底（WebView 未画到的手势条区域不再是黑色），
   容器高度加视口单位渐进增强（vh 兜底，避免旧机不支持）。 */
/* ⚠️ 2026-10-15 老板反馈「随着页面内的滚动，尺寸自动被撑高」：
   100dvh 是动态视口——滚动时浏览器工具栏收起/展开，dvh 每变一次 body/#v-main
   就被撑高/缩回一次，整个页面跟着呼吸（style.css 里 #v-chat 早就因此弃用 dvh，
   但 body/#v-main 漏改了）。改用 100svh（静态小视口，滚动期间恒定）；
   不支持 svh 的旧内核回退 dvh/vh。html 背景同色，svh 比可视区矮的部分无缝兜底。 */
html { background:#f6f7f9; }
body { font-family:-apple-system,"PingFang SC","Microsoft YaHei",sans-serif; background:var(--bg); color:var(--text);
       max-width:480px; margin:0 auto;
       min-height:100vh; min-height:100dvh; min-height:100svh; }
.hidden { display:none !important; }
button { border:none; cursor:pointer; font-family:inherit; }
input { border:1px solid var(--line); border-radius:10px; padding:12px 14px; font-size:15px; width:100%; outline:none; }
input:focus { border-color:var(--accent); }

/* 登录 */
#v-auth { display:flex; align-items:center; justify-content:center; min-height:100vh; padding:24px; }
.auth-box { width:100%; text-align:center; }
.logo-bell { font-size:52px; }
.logo-mark { width:72px; height:72px; display:block; margin:0 auto 6px; }
.auth-box h1 { font-size:26px; margin:6px 0 2px; color:var(--accent); }
.slogan { color:var(--sub); font-size:13px; margin-bottom:26px; }
.auth-box input, .code-row { margin-bottom:12px; }
.code-row { display:flex; gap:8px; }
.code-row input { flex:1; }
.code-row button { white-space:nowrap; padding:0 14px; border-radius:10px; background:#f3e8f0; color:var(--accent); font-size:13px; }
.primary { background:var(--accent); color:#fff; border-radius:10px; padding:13px; font-size:16px; width:100%; margin-top:4px; }
.tip { color:var(--sub); font-size:12px; min-height:18px; margin-top:10px; }

/* 顶栏 */
.topbar { display:flex; align-items:center; height:52px; padding:0 14px; background:var(--card);
          border-bottom:1px solid var(--line); position:sticky; top:0; z-index:5; }
.tb-title { font-size:17px; font-weight:600; flex:1; }
.tb-title.center { text-align:center; }
.tb-act { font-size:22px; color:var(--accent); background:none; padding:4px 8px; }
.tb-back { background:none; font-size:26px; color:var(--text); width:32px; text-align:left; }

/* 页面骨架 */
#v-main { display:flex; flex-direction:column;
          min-height:100vh; min-height:100dvh; min-height:100svh; }
.page { flex:1; padding-bottom:64px; }
.tabbar { position:fixed; bottom:0; left:50%; transform:translateX(-50%); width:100%; max-width:480px;
          display:flex; background:var(--card); border-top:1px solid var(--line); height:58px;
          padding-bottom:env(safe-area-inset-bottom); z-index:10; }
.tab { flex:1; background:none; color:#b9bec7; display:flex; align-items:center; justify-content:center; position:relative; }
.tab.active { color:var(--accent); }
.badge { position:absolute; top:8px; right:calc(50% - 22px); background:#e53e3e; color:#fff; font-size:11px;
         border-radius:9px; padding:1px 5px; min-width:17px; text-align:center; }

/* 会话列表 */
.list { padding:6px 0; }
.conv { display:flex; align-items:center; gap:12px; padding:12px 16px; background:var(--card);
        border-bottom:1px solid var(--line); cursor:pointer; }
.avatar { width:44px; height:44px; border-radius:10px; color:#fff; display:flex; align-items:center;
          justify-content:center; font-size:17px; flex-shrink:0; }
.avatar.big { width:56px; height:56px; font-size:22px; border-radius:14px; }
/* WEMI 品牌标（共享组件·2026-10-23）：中央键换新图案后，所有位置的 WEMI 图案
   统一走这一张图——换标只替换 img/wemi_mark.png，别在别处写死第二份。 */
.avatar.luca-mark { background:transparent url("img/wemi_mark.png") center/contain no-repeat; }
.conv-main { flex:1; min-width:0; }
.conv-title { font-size:16px; font-weight:500; }
.conv-last { font-size:13px; color:var(--sub); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.conv-side { display:flex; flex-direction:column; align-items:flex-end; gap:5px; flex-shrink:0; }
.conv-time { font-size:12px; color:#b9bec7; line-height:1; }
.conv-unread { display:inline-block; background:#e53e3e; color:#fff; font-size:11px; border-radius:9px;
               padding:1px 6px; min-width:18px; }
.conv-unread.mention { background:#e53e3e; font-weight:700; }

/* 置顶会话（2026-11-03 老板定）：图钉 + 极淡底色，扫一眼就知道哪条被钉住了。
   长按/右键弹的菜单在 app.js 的 openConvMenu。 */
.conv.pinned { background: linear-gradient(0deg, rgba(213,63,140,.035), rgba(213,63,140,.035)), var(--card); }
.pin-ico { display:inline-block; margin-right:4px; vertical-align:-1px; opacity:.5; }
.conv-menu { position:fixed; z-index:9999; min-width:140px; padding:5px;
             background:var(--card); border:1px solid var(--line); border-radius:12px;
             box-shadow:0 10px 30px rgba(0,0,0,.16); }
.conv-menu-item { display:flex; align-items:center; gap:9px; width:100%; padding:10px 12px;
                  border:0; border-radius:9px; background:transparent; cursor:pointer;
                  font-size:14px; color:#1f2937; text-align:left; font-family:inherit; }
.conv-menu-item:hover { background:rgba(0,0,0,.05); }
.conv-menu-item svg { flex:0 0 auto; opacity:.65; }

/* 聊天页（dvh 兜底：iOS 键盘弹起时输入栏不被顶出屏幕） */
/* ⚠️ 2026-09-30 再次修正：别用 100dvh。
   dvh＝「动态视口高度」，会随浏览器工具栏收起/展开而变 —— 用它做容器高度，滚动过程中
   高度每变一次就整页重排一次，手感就是一跳一跳。vh 是静态的，滚动期间不变，这里要的就是静态。*/
#v-chat { display:flex; flex-direction:column; height:100vh; }
#v-stock { display:flex; flex-direction:column; height:100vh; background:var(--bg,#f6f7f9); }
/* overscroll-behavior:contain = 滚到底/顶时不把滚动"传染"给外层（防整页跟着抖）。
   ⚠️ 不再写 -webkit-overflow-scrolling:touch：那是 iOS 私有属性、现代版已默认惯性滚动，
   在安卓 WebView 上反而会拖慢滚动。
   transform:translateZ(0) = 把滚动容器提成独立合成层，交给 GPU 合成 ——
   安卓 WebView 上提升滚动流畅度最直接的一招。 */
.msg-list { flex:1 1 0; height:0; overflow-y:auto; min-height:0; padding:14px 12px;
            overscroll-behavior:contain; -webkit-overflow-scrolling:auto;
            transform:translateZ(0);
            /* contain:layout = 列表内部怎么变都不触发外层重排，滚动只算自己这一块 */
            contain:layout paint; }
/* ⚠️ 2026-09-30 移除 content-visibility:auto。
   它是给「几百上千条」的长列表用的（屏外行跳过布局）。咱们实际一个会话才几十条，
   收益为零；而 contain-intrinsic-size 的估值(56px)和真实气泡高度差太多，
   行进出视口时估算高度来回变 → 滚动条长度和位置跳动 → 正是"不顺畅"的手感。
   结论：短列表宁可老老实实全渲染。 */
.mrow { display:flex; margin-bottom:12px; gap:8px; }
.mrow.mine { flex-direction:row-reverse; }
.bubble { max-width:72%; padding:10px 13px; border-radius:14px; background:var(--card);
          font-size:15px; line-height:1.45; word-break:break-word; position:relative; }
.mine .bubble { background:var(--accent); color:#fff; }
.bubble .reply-tag { font-size:12px; color:inherit; opacity:.65; border-left:2px solid currentColor;
                     padding-left:6px; margin-bottom:4px; }
.bubble.system { background:transparent; color:var(--sub); font-size:12px; text-align:center; max-width:100%; }
.bubble .sender { font-size:12px; color:var(--sub); margin-bottom:2px; }
.mrow.mention .bubble { box-shadow:0 0 0 2px #f6c3dd; }
.revoked { color:var(--sub); font-size:12px; text-align:center; width:100%; }
/* AI 生成内容显式标识（标识办法第4条 / GB 45438-2025 5.6）：气泡下方小字角标 */
.ai-tag { font-size:9px; color:var(--sub); opacity:.85; margin-top:3px; }
.bubble .ai-tag { margin-top:5px; }
.card-wrap { display:flex; flex-direction:column; align-items:flex-start; max-width:100%; }
.card-wrap .card { flex-shrink:1; }

/* 回执卡片 */
.card { width:290px; max-width:80%; background:var(--card); border:1px solid var(--line);
        border-radius:14px; overflow:hidden; }
.card-hd { background:linear-gradient(135deg,#d53f8c,#b03070); color:#fff; padding:10px 14px;
           font-size:14px; font-weight:600; }
.card-bd { padding:10px 14px; }
.card-sum { font-size:15px; font-weight:600; margin-bottom:8px; }
.card-fields { display:grid; grid-template-columns:1fr 1fr; gap:6px; margin-bottom:8px; }
.cf label { font-size:11px; color:var(--sub); display:block; }
.cf input, .cf span { font-size:14px; }
.cf input { padding:5px 8px; border-radius:7px; }
.card-ft { display:flex; gap:8px; padding:0 14px 12px; }
.card-ft button { flex:1; padding:9px; border-radius:8px; font-size:14px; }
.btn-ok { background:var(--accent); color:#fff; }
.btn-no { background:#f1f2f4; color:var(--sub); }
.card.done .card-hd { background:linear-gradient(135deg,#2f9e44,#237032); }
.card.cancel .card-hd { background:linear-gradient(135deg,#adb5bd,#868e96); }
.card .locked { color:var(--sub); font-size:12px; text-align:center; padding-bottom:10px; }
/* 生活记账一句话回执（2026-10-08 老板定稿）：零输入框、无「录单回执」头、
   不出现抬头/品名/数量/单价等会计词。整张卡就是一句话 + 两个按钮。 */
.card.life { width:auto; max-width:100%; }
.card.life .card-bd { padding:14px; }
.life-line { font-size:15.5px; line-height:1.6; font-weight:600; color:var(--text); }
.card.life .card-ft { padding:12px 0 0; }

/* 输入栏（始终显示，任何状态都不隐藏） */
.inputbar { display:flex; gap:8px; padding:10px 12px; background:var(--card); flex-shrink:0;
            border-top:1px solid var(--line); padding-bottom:calc(10px + env(safe-area-inset-bottom)); }
.inputbar input { flex:1; }
.inputbar .primary { width:auto; padding:0 18px; margin:0; }
/* 2026-10-11 老板拍板（像微信）：空输入时发送键中性灰，有内容才玫红。
   纯 CSS：input 有 placeholder 且值为空时 :placeholder-shown 命中 → 键灰；
   输入任意内容立即变玫红，发送清空后自动回灰，零 JS。 */
.inputbar #msg-send { background:#c9cbce; }
.inputbar #msg-input:not(:placeholder-shown) + #msg-send { background:var(--accent); }

/* 我的 */
.me-card { display:flex; align-items:center; gap:14px; background:var(--card); padding:18px 16px;
           border-bottom:1px solid var(--line); }
.me-name { font-size:18px; font-weight:600; }
.me-sub { font-size:13px; color:var(--sub); }
/* 2026-10-11 老板：我的页里那行手机号（189…）不要显示 */
#me-phone { display:none; }
.me-row { display:flex; align-items:center; justify-content:space-between; gap:10px;
          background:var(--card); padding:15px 16px; cursor:pointer; }
.me-row:active { background:var(--card-press, #f4f4f6); }
.mr-label { font-size:15px; color:var(--text); }
.mr-val { font-size:15px; color:var(--sub); flex:1; text-align:right; margin-right:6px;
          overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.mr-arrow { font-size:20px; color:var(--sub); }
.ledger-card { margin:14px 16px; background:linear-gradient(135deg,#fdf0f8,#fce8f3);
               border:1px solid #f3c6e2; border-radius:14px; padding:16px; cursor:pointer; }
.lc-title { font-size:16px; font-weight:600; }
.lc-sub { font-size:13px; color:var(--sub); margin:4px 0 8px; }
.lc-enter { color:var(--accent); font-size:13px; font-weight:600; }
.danger { display:block; margin:20px 16px; width:calc(100% - 32px); background:#fff; color:#e53e3e;
          border:1px solid #fbd5d5; border-radius:10px; padding:12px; font-size:15px; }

/* 账本列表 */
.led { display:flex; align-items:center; gap:10px; background:var(--card); padding:13px 16px;
       border-bottom:1px solid var(--line); }
.led .dir { font-size:12px; color:#fff; border-radius:6px; padding:2px 7px; flex-shrink:0; }
.dir.purchase { background:#1f6feb; } .dir.sale { background:#e8590c; }
.led-main { flex:1; } .led-party { font-size:15px; font-weight:500; }
.led-detail { font-size:12px; color:var(--sub); }
.led-amount { font-weight:700; font-size:15px; }

/* M3 期初开账 */
.op-tip { background:var(--accent-soft, #fce8f3); border-left:3px solid var(--accent); border-radius:0 8px 8px 0; padding:10px 14px; margin:12px 14px; color:var(--sub); font-size:13px; line-height:1.7; }
.op-tip b { color:var(--accent); }
.op-cut { display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding:6px 16px 14px; }
.op-cut-label { font-size:14px; font-weight:600; }
.op-date { border:1px solid var(--line); border-radius:8px; padding:8px 10px; font-size:14px; font-family:inherit; background:var(--card); color:var(--text); }
.op-cut-hint { color:var(--sub); font-size:12px; }
.op-card { background:var(--card); border-top:1px solid var(--line); padding:14px 0 6px; }
.op-card-head { display:flex; align-items:center; justify-content:space-between; padding:0 16px 8px; }
.op-card-title { font-size:15px; font-weight:700; }
.op-card-title span { font-weight:400; color:var(--sub); font-size:12.5px; margin-left:4px; }
.op-add { border:1px dashed var(--line); background:none; color:var(--sub); border-radius:7px; padding:5px 12px; font-size:13px; cursor:pointer; }
.op-add:active { border-color:var(--accent); color:var(--accent); }
.op-tbl { width:100%; border-collapse:collapse; }
.op-tbl th { font-size:12px; font-weight:600; color:var(--sub); padding:6px 8px; text-align:center; }
.op-tbl td { border-top:1px solid var(--line); padding:4px 6px; text-align:center; }
.op-tbl td .op-in { width:100%; border:1px solid var(--line); border-radius:7px; padding:8px 8px; font-size:14px; font-family:inherit; background:var(--card); color:var(--text); box-sizing:border-box; }
.op-tbl td .op-in.num { text-align:right; }
.op-tbl td:first-child .op-in { text-align:left; }
.op-tbl .op-amt { font-variant-numeric:tabular-nums; font-weight:600; color:var(--num, #b7791f); }
.op-del { width:34px; color:#c9c2bb; font-size:15px; cursor:pointer; }
.op-del:active { color:#e53e3e; }
.op-tbl tfoot td { background:#faf7f1; font-weight:700; padding:9px 8px; }
.op-tbl tfoot td.num { color:var(--num, #b7791f); text-align:right; }
.op-bottom { display:flex; align-items:center; justify-content:flex-end; gap:12px; padding:18px 16px 24px; }
.op-hint { color:var(--sub); font-size:12px; margin-right:auto; }
.op-btn { border-radius:9px; padding:11px 24px; font-size:14px; cursor:pointer; }
.op-draft { border:1px solid var(--line); background:var(--card); color:var(--text); }
.op-draft:active { border-color:var(--accent); color:var(--accent); }
.op-open { border:none; background:var(--accent); color:#fff; font-weight:600; letter-spacing:2px; box-shadow:0 4px 14px var(--accent-shadow, rgba(213,63,140,.3)); }
.op-open:active { filter:brightness(1.06); }
.op-ov { position:fixed; inset:0; background:rgba(0,0,0,.35); display:none; align-items:center; justify-content:center; z-index:99; }
.op-ov.show { display:flex; }
.op-modal { width:88%; max-width:420px; background:#fff; border-radius:14px; padding:22px 24px; box-shadow:0 12px 40px rgba(0,0,0,.18); }
.op-modal h3 { font-size:16px; margin-bottom:12px; }
.op-sum-line { display:flex; justify-content:space-between; padding:7px 0; font-size:13px; border-bottom:1px dashed var(--line); }
.op-sum-line b { font-variant-numeric:tabular-nums; }
.op-modal p { color:var(--sub); font-size:12.5px; line-height:1.8; margin:12px 0 16px; }
.op-mbtns { display:flex; justify-content:flex-end; gap:10px; }
.op-lockinfo { padding:16px; font-size:14px; background:var(--card); border-top:1px solid var(--line); }
.op-lockinfo b { color:var(--accent); }
.op-summary { padding:6px 16px 14px; background:var(--card); }
.op-sum-row { display:flex; justify-content:space-between; padding:11px 0; font-size:14px; border-bottom:1px solid var(--line); }
.op-sum-row b { font-variant-numeric:tabular-nums; }
.op-sum-row.net { border-bottom:none; font-weight:700; }
.op-sum-row.net b { color:var(--accent); }

/* M3-2 账本页三块：往来 / 库存 / 流水 */
.lb-sec { background:var(--card); margin:12px 0; border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
.lb-sec-h { font-size:15px; font-weight:700; padding:14px 16px 4px; }
.lb-sub { font-size:11.5px; color:var(--sub); line-height:1.6; padding:0 16px 8px; }
.lb-note { font-size:11.5px; color:var(--sub); line-height:1.6; padding:8px 16px 14px; }
.lb-empty { padding:22px 16px; text-align:center; color:var(--sub); font-size:13px; }
.lb-scroll { overflow-x:auto; -webkit-overflow-scrolling:touch; padding:0 0 6px; }
.lb-tbl { width:100%; border-collapse:collapse; font-size:12.5px; min-width:360px; }
.lb-tbl th { position:sticky; top:0; background:#fafafa; color:var(--sub); font-weight:600; padding:9px 8px; text-align:right; white-space:nowrap; border-bottom:1px solid var(--line); }
.lb-tbl th:first-child, .lb-tbl td:first-child { text-align:left; }
.lb-tbl td { padding:9px 8px; text-align:right; border-bottom:1px solid var(--line); white-space:nowrap; font-variant-numeric:tabular-nums; }
.lb-tbl tfoot td { font-weight:700; background:#fafafa; border-top:1px solid var(--line); border-bottom:none; }
.lb-party { color:var(--text); max-width:120px; overflow:hidden; text-overflow:ellipsis; }
.lb-tbl .num { font-variant-numeric:tabular-nums; }
.lb-tbl .pos { color:#e53e3e; font-weight:700; }      /* 应收/别人欠我们=红(涨) */
.lb-tbl .neg { color:#2f9e44; font-weight:700; }      /* 应付/我们欠别人=绿(跌) */
.lb-sale { color:#e53e3e; font-weight:600; font-size:11.5px; }
.lb-buy { color:#2f9e44; font-weight:600; font-size:11.5px; }

/* M3-3 汇总报表：毛利 / 账龄 */
.rp-total { display:flex; flex-wrap:wrap; padding:8px 10px 4px; }
.rp-tcell { flex:1 1 40%; padding:8px 6px; text-align:center; }
.rp-tcell span { display:block; font-size:11px; color:var(--sub); margin-bottom:3px; }
.rp-tcell b { font-size:15px; font-variant-numeric:tabular-nums; }
.rp-tcell.hl b { color:var(--accent); }
.rp-h { font-size:13px; font-weight:700; padding:12px 16px 4px; color:var(--sub); }
.rp-age { display:flex; flex-wrap:wrap; padding:6px 10px; }
.rp-agecell { flex:1 1 18%; text-align:center; padding:8px 4px; }
.rp-agecell span { display:block; font-size:11px; color:var(--sub); margin-bottom:3px; }
.rp-agecell b { font-size:13px; font-variant-numeric:tabular-nums; }
.rp-agecell b.pos { color:#e53e3e; font-weight:700; }
.rp-agesum { padding:6px 16px 14px; font-size:13px; text-align:right; color:var(--sub); }
.rp-agesum b { color:#e53e3e; font-variant-numeric:tabular-nums; }

/* 长按菜单 */
.menu { position:fixed; background:#fff; border-radius:10px; box-shadow:0 4px 20px rgba(0,0,0,.15);
        padding:4px; z-index:50; }
.menu button { display:block; width:100%; text-align:left; padding:10px 18px; background:none; font-size:14px; }

/* 通用文本弹窗 */
.modal { position:fixed; inset:0; z-index:50; display:flex; align-items:center; justify-content:center; }
.modal-mask { position:absolute; inset:0; background:rgba(0,0,0,.45); }
.modal-box { position:relative; width:80%; max-width:320px; background:var(--bg,#fff); border-radius:14px; padding:18px; box-sizing:border-box; }
.modal-title { font-size:15px; font-weight:600; margin-bottom:12px; }
.modal-box input { width:100%; box-sizing:border-box; padding:10px 12px; border:1px solid var(--line,#e3d6df); border-radius:10px; font-size:15px; margin-bottom:14px; }
.modal-ft { display:flex; gap:10px; }
.modal-ft button { flex:1; padding:10px; border-radius:10px; font-size:15px; }
.modal-ft .primary { background:var(--accent,#d53f8c); color:#fff; }
.modal-ft .ghost { background:#f0e6ee; color:#555; }
.menu button:active { background:#f6f7f9; }

/* ===== M2 ===== */
.searchbar { padding:8px 12px; background:var(--card); border-bottom:1px solid var(--line); }
/* 2026-10-11 老板拍板：搜索图标弃彩色 emoji，换普通灰色线性放大镜（flex 对齐） */
.search-entry { display:flex; align-items:center; gap:6px; padding:9px 12px; font-size:14px; background:var(--bg); border-radius:18px; color:var(--sub); }
.search-entry svg { flex-shrink:0; }
.search-entry:active { background:#eceff1; }
.tb-search { flex:1; padding:8px 12px; font-size:14px; background:var(--bg); border:none; border-radius:18px; }
.s-hint { padding:26px 18px; text-align:center; color:var(--sub); font-size:13px; }

/* 媒体消息 */
.bubble.media { padding:4px; background:var(--bg); }
.bubble.media img { max-width:220px; max-height:280px; border-radius:10px; display:block; cursor:zoom-in; }
.bubble.media video { max-width:240px; border-radius:10px; display:block; }
.voice-btn { display:flex; align-items:center; gap:8px; background:none; padding:6px 4px; min-width:86px; }
.voice-btn .vplay { width:30px; height:30px; border-radius:50%; background:var(--accent); color:#fff;
                    display:flex; align-items:center; justify-content:center; font-size:13px; flex-shrink:0; }
.mine .voice-btn .vplay { background:#fff; color:var(--accent); }
.voice-btn .vdur { font-size:14px; color:var(--text); }
.mine .voice-btn .vdur { color:#fff; }
.vtrans { font-size:11px; opacity:.75; margin-top:3px; border-top:1px dashed rgba(0,0,0,.15); padding-top:3px; }
.mine .vtrans { border-top-color:rgba(255,255,255,.4); }
/* 2026-10-06 发文件：📎 文件名（a 标签 download） */
.file-btn { display:flex; align-items:center; gap:6px; font-size:14px; color:var(--text);
            text-decoration:none; padding:6px 4px; max-width:220px; }
.file-btn:hover { opacity:.8; }
/* 语音没发出去：气泡留着（本地还能播），给个「重发」 */
.vfail { color:#ffd9d9; opacity:1; }
.vfail .vretry { color:#fff; font-weight:500; text-decoration:underline; margin-left:6px; }

/* 在线/输入中 */
.presence { width:9px; height:9px; border-radius:50%; background:#2f9e44; flex-shrink:0; }
.typing { padding:4px 16px 6px; font-size:12px; color:var(--sub); background:transparent; }

/* 输入栏扩展 */
.ib-act { background:none; font-size:21px; padding:0 6px; }
#btn-emoji { color:var(--sub); display:flex; align-items:center; }  /* 线性表情图标：灰、与语音键同骨架 */
/* 独立录音键：玫红波形图标（非话筒/非回形针），按住说话 */
#btn-voice { color:var(--sub); display:flex; align-items:center; -webkit-user-select:none; user-select:none; -webkit-touch-callout:none; touch-action:none; } /* 2026-10-11 老板拍板：未点击时跟表情键一样灰，不显玫红；补 touch-action:none 防触屏上滑被抢做滚动 */
#btn-voice:active { opacity:.6; }
.emoji-panel { position:fixed; bottom:64px; left:50%; transform:translateX(-50%); width:100%; max-width:480px;
               background:var(--card); border-top:1px solid var(--line); padding:10px; z-index:20;
               display:grid; grid-template-columns:repeat(8,1fr); gap:4px; max-height:180px; overflow-y:auto; }
.emoji-panel button { font-size:22px; background:none; padding:4px; }
.img-choice { display:flex; align-items:center; gap:8px; padding:8px 12px; background:var(--card);
              border-top:1px solid var(--line); font-size:13px; color:var(--sub); }
.chip { padding:6px 12px; border-radius:14px; background:var(--accent); color:#fff; font-size:13px; }
.chip.alt { background:#1f6feb; }
.chip.ghost { background:#f1f2f4; color:var(--sub); }

/* 截图按钮（桌面客户端才有，浏览器里默认 hidden 由 JS 控制显隐） */
#chat-screenshot { font-size:22px; color:var(--accent); background:none; padding:4px 8px; }
/* 老板定稿：剪刀竖着摆（原横向），旋转 90° 即得竖版 */
#chat-screenshot svg { transform: rotate(90deg); }

/* 拖拽文件进聊天时的全窗提示层 */
.drop-hint { position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
             background:rgba(20,20,30,.42); z-index:55; pointer-events:none; }
.dh-box { border:2px dashed #D53F8C; color:#fff; background:rgba(213,63,140,.92);
          padding:14px 24px; border-radius:12px; font-size:15px; font-weight:600;
          box-shadow:0 6px 20px rgba(0,0,0,.25); }

/* 录音大面板（A 方案：DeepSeek 式——按住话筒，整块输入栏变玫红录音面，上滑取消） */
.inputbar { position:relative; }
.rec-bar { position:absolute; inset:0; background:var(--accent); color:#fff;
  display:flex; align-items:center; justify-content:center; gap:10px;
  font-size:17px; font-weight:600; letter-spacing:.3px; z-index:30; cursor:pointer;
  touch-action:none; -webkit-user-select:none; user-select:none; -webkit-touch-callout:none;
  box-shadow:0 0 0 2px rgba(255,255,255,.25) inset; }
.rec-bar.hidden { display:none; }
.rec-dot { width:11px; height:11px; border-radius:50%; background:#fff; animation:blink 1s infinite; }
#rec-time { font-variant-numeric:tabular-nums; }
/* 波形条动画（2026-10-11 老板拍板：录音面板加视频同款波形，纯 CSS 无 JS） */
.rec-wave { display:inline-flex; align-items:center; gap:3px; height:18px; }
.rec-wave i { width:3px; border-radius:2px; background:#fff; animation:recwave 1s ease-in-out infinite; }
.rec-wave i:nth-child(2){animation-delay:.12s}.rec-wave i:nth-child(3){animation-delay:.24s}
.rec-wave i:nth-child(4){animation-delay:.36s}.rec-wave i:nth-child(5){animation-delay:.48s}
.rec-wave i:nth-child(6){animation-delay:.60s}.rec-wave i:nth-child(7){animation-delay:.72s}
.rec-wave i:nth-child(8){animation-delay:.84s}
@keyframes recwave { 0%,100%{height:4px} 50%{height:17px} }
.rec-bar.cancel .rec-wave i { animation-duration:1.6s; } /* 取消态波形放缓，弱化"还在录"的感知 */
.rec-bar.cancel { background:rgba(110,116,128,.97); }
.rec-bar.cancel #rec-tip { color:#fff; }
/* 转文字中（2026-11-01 客户端）：录音已停，波形收掉，只留"正在转成文字…"，鼠标穿透不挡输入 */
.rec-bar.busy { cursor:default; }
.rec-bar.busy .rec-wave, .rec-bar.busy .rec-dot { display:none; }

/* 转账/收款按钮 + 面板 + 支付卡片（2026-10-11 支付 MVP） */
.pay-ico { font-size:20px; font-weight:700; color:var(--accent); line-height:1; }
.pay-panel { position:fixed; inset:0; background:rgba(0,0,0,.35); display:flex; align-items:center;
             justify-content:center; z-index:80; }
.pay-card-box { width:320px; background:var(--card); border-radius:18px; padding:22px 20px;
                box-shadow:0 12px 40px rgba(0,0,0,.22); }
.pay-title { font-size:17px; font-weight:700; text-align:center; margin-bottom:16px; }
.pay-dir { display:flex; gap:10px; margin-bottom:16px; }
.pay-dir-btn { flex:1; padding:10px 0; border:1px solid var(--line); background:var(--card);
               border-radius:12px; font-size:15px; cursor:pointer; color:var(--txt); }
.pay-dir-btn.active { background:var(--accent); color:#fff; border-color:var(--accent); font-weight:600; }
.pay-amt-in { display:flex; align-items:center; gap:6px; border-bottom:2px solid var(--accent);
              padding:6px 2px; margin-bottom:14px; }
.pay-amt-in span { font-size:26px; color:var(--accent); font-weight:700; }
.pay-amt-in input { flex:1; border:none; outline:none; font-size:30px; font-weight:700;
                    background:transparent; color:var(--txt); width:100%; }
.pay-amt-in input::-webkit-outer-spin-button, .pay-amt-in input::-webkit-inner-spin-button { -webkit-appearance:none; margin:0; }
#pay-note { width:100%; border:1px solid var(--line); border-radius:10px; padding:10px 12px;
            font-size:14px; outline:none; margin-bottom:18px; box-sizing:border-box; }
.pay-actions { display:flex; gap:10px; }
.pay-cancel-btn, .pay-ok-btn { flex:1; padding:11px 0; border-radius:12px; font-size:15px; cursor:pointer; border:none; }
.pay-cancel-btn { background:#f1f2f4; color:var(--txt); }
.pay-ok-btn { background:var(--accent); color:#fff; font-weight:600; }
.pay-ok-btn:disabled { opacity:.5; cursor:not-allowed; }

/* 聊天里的支付卡片 */
.bubble.pay-card { min-width:210px; padding:16px 18px; }
.pay-amt { font-size:26px; font-weight:700; color:var(--accent); }
.pay-amt .cur { font-size:16px; margin-right:2px; }
.pay-note { font-size:13px; color:var(--sub); margin:4px 0 10px; word-break:break-all; }
.pay-status { font-size:12px; color:var(--sub); margin-bottom:10px; }
.pay-act { width:100%; padding:9px 0; border:none; border-radius:12px; font-size:15px;
           font-weight:600; cursor:pointer; background:var(--accent); color:#fff; }
.pay-act.cancel { background:#f1f2f4; color:var(--txt); }
.pay-act:disabled { background:#f1f2f4; color:var(--sub); cursor:default; }
@keyframes blink { 50% { opacity:.2; } }
/* 录音时输入框轻微高亮（输入框始终可见，不切换形态） */
.inputbar.rec input { border-color:var(--accent); background:#fff7fb; }

/* 搜索结果 */
.sres { padding:12px 16px; background:var(--card); border-bottom:1px solid var(--line); cursor:pointer; }
.sres .s-conv { font-size:12px; color:var(--accent); margin-bottom:3px; }
.sres .s-text { font-size:14px; }
.sres .s-time { font-size:11px; color:var(--sub); margin-top:3px; }

/* 图片查看器 */
.viewer { position:fixed; inset:0; background:rgba(0,0,0,.88); z-index:100; display:flex;
          align-items:center; justify-content:center; cursor:zoom-out; }
.viewer img { max-width:96vw; max-height:92vh; }

/* M4 成员管理 */
.mm-list { margin-top:8px; }
.mm-row { display:flex; align-items:center; gap:10px; padding:10px 4px; border-bottom:1px solid var(--line); }
.mm-av { width:36px; height:36px; border-radius:50%; color:#fff; display:flex; align-items:center;
         justify-content:center; font-size:15px; font-weight:600; flex:none; }
.mm-main { flex:1; min-width:0; }
.mm-name { font-size:15px; }
.mm-self { font-size:12px; color:var(--sub); }
.mm-phone { font-size:12px; color:var(--sub); }
.mm-role { font-size:12px; padding:3px 10px; border-radius:12px; background:#f1f2f4; color:var(--sub); flex:none; }
.mm-role.mm-admin { background:#e7f0ff; color:#1f6feb; }
.mm-act { display:flex; align-items:center; gap:6px; flex:none; }
.mm-sel { padding:5px 6px; border:1px solid var(--line); border-radius:8px; font-size:13px; background:var(--card); }
.mm-rm { padding:5px 10px; border:1px solid #ffd0e0; border-radius:8px; font-size:13px;
         background:#fff0f6; color:#c2255c; }
.mm-invite { display:flex; gap:8px; align-items:center; margin-top:14px; }
.mm-inp { flex:1; padding:9px 10px; border:1px solid var(--line); border-radius:9px; font-size:14px; }

/* ===== M4 PWA 壳 · 安装引导条 ===== */
.pwa-tip { display:flex; align-items:center; justify-content:space-between; gap:10px;
           margin:8px 10px 0; padding:9px 12px; border-radius:11px;
           background:linear-gradient(135deg,#fdf0f7,#fce4f0); border:1px solid #f3c4de;
           font-size:13px; color:#9c2f6b; }
.pwa-tip-acts { display:flex; gap:8px; align-items:center; flex-shrink:0; }
.pt-ok { border:none; background:var(--acc,#d53f8c); color:#fff; font-size:13px;
         padding:6px 14px; border-radius:8px; }
.pt-x { border:none; background:none; color:#c99; font-size:14px; padding:4px 6px; }



/* ---------- M5-② 对账单卡片 ---------- */
.lb-stmt { display:inline-block; margin-left:6px; padding:1px 7px; font-size:11px;
           border-radius:8px; background:#f9eef5; color:var(--accent); vertical-align:middle; }
.st-card { background:var(--card); border-radius:14px; padding:16px 14px; margin:12px;
           box-shadow:0 2px 10px rgba(0,0,0,.06); }
.st-head { display:flex; align-items:center; gap:8px; padding-bottom:10px; border-bottom:1px dashed var(--line); }
.st-bell { font-size:26px; }
.st-ht { flex:1; line-height:1.25; }
.st-ht b { font-size:15px; display:block; }
.st-ht span { font-size:11px; color:var(--accent); }
.st-date { font-size:10px; color:var(--sub); }
.st-party { margin:12px 0 6px; font-size:14px; }
.st-rows { max-height:46vh; overflow-y:auto; }
.st-row.st-open { display:flex; justify-content:space-between; padding:8px 2px; font-size:13px; color:var(--sub);
                  border-bottom:1px solid var(--bg); }
.st-line { padding:9px 2px; border-bottom:1px solid var(--bg); }
.st-l1 { display:flex; justify-content:space-between; align-items:center; }
.st-item { font-size:14px; font-weight:600; }
.st-cum { font-size:11px; color:var(--sub); }
.st-l2 { display:flex; justify-content:space-between; margin-top:2px; font-size:12px; color:var(--sub); }
.st-amt { color:var(--text); font-weight:600; }
.st-empty { padding:14px 2px; font-size:13px; color:var(--sub); text-align:center; }
.st-close { display:flex; justify-content:space-between; align-items:center; margin-top:12px; padding:12px;
            background:#fdf2f8; border-radius:10px; }
.st-close span { font-size:13px; }
.st-close b { font-size:20px; color:var(--accent); }
.st-other { margin-top:8px; font-size:11px; color:var(--sub); text-align:right; }
.st-foot { display:flex; align-items:center; gap:12px; margin-top:14px; padding-top:12px; border-top:1px dashed var(--line); }
.st-qr { width:92px; height:92px; flex:none; background:#fff; }
.st-qr img, .st-qr canvas { width:92px !important; height:92px !important; }
.st-promo { font-size:11px; color:var(--sub); line-height:1.7; }
.st-hint { margin:0 14px 16px; font-size:11px; color:var(--sub); text-align:center; }
/* ---------- 开账预览卡（acc.opening_preview，2026-10-08） ---------- */
.op-sec { margin-bottom:10px; }
.op-hd { font-size:11px; color:var(--sub); margin-bottom:4px; }
.op-row { font-size:13px; padding:4px 0; border-bottom:1px dashed var(--bg); line-height:1.6; }
.op-raw { font-size:11px; color:var(--sub); }
.op-sum { margin-top:8px; font-size:12px; color:var(--sub); }
.op-note { margin-top:6px; font-size:11px; color:var(--sub); }
/* ---------- 下拉应用页（2026-10-08 手机视口；桌面不启用） ---------- */
#v-pulldown { position:fixed; inset:0; z-index:60; display:flex; flex-direction:column;
              background:linear-gradient(180deg,#1d1420 0%,#241a26 45%,#26262a 100%);
              animation:pd-drop .28s ease-out; }
#v-pulldown.hidden { display:none; }
@keyframes pd-drop { from { transform:translateY(-100%); } to { transform:translateY(0); } }
#pd-stars { position:absolute; inset:0; width:100%; height:100%; }
.pd-inner { position:relative; flex:1; display:flex; flex-direction:column; align-items:center;
            padding:18px 22px 26px; overflow:auto; }
.pd-handle { color:rgba(255,255,255,.55); font-size:12px; padding:8px 18px; cursor:pointer;
             border:1px solid rgba(255,255,255,.18); border-radius:999px; background:rgba(255,255,255,.06); }
.pd-title { color:#fff; font-size:20px; font-weight:700; margin:26px 0 16px; align-self:flex-start; }
.pd-grid { width:100%; display:grid; grid-template-columns:1fr 1fr; gap:14px; }
.pd-card { display:flex; flex-direction:column; align-items:flex-start; gap:6px; padding:18px 16px;
           background:rgba(255,255,255,.07); border:1px solid rgba(214,63,140,.35);
           border-radius:16px; cursor:pointer; text-align:left; }
.pd-card:active { background:rgba(214,63,140,.22); }
.pd-ico { font-size:30px; }
.pd-card b { color:#fff; font-size:16px; }
.pd-card small { color:rgba(255,255,255,.6); font-size:11px; }
.pd-foot { margin-top:auto; padding-top:26px; color:rgba(255,255,255,.4); font-size:11px; }

/* ==========================================================================
   桌面视口（≥768px）微信式双栏（2026-10-08 老板拍板）
   铁律三条，勿破：
   1) 桌面 = 纯聊天工作台。不加下拉层、不加动画层（手机视口的满天星下拉页桌面永不启用）。
   2) 手机视口（<768px）行为零变化——本块之外的一切规则对手机照旧。
   3) 左栏 320px 真分栏（通栏到底），不是卡片也不是浮层。
   ========================================================================== */

/* 左栏底部「我的」入口 / 右栏容器 / 品牌占位：手机视口默认全部不参与布局 */
.rail-me { display:none; }
#desk-right { display:contents; }
.desk-empty { display:none; }

/* 老板指出的排版问题：会话列表项原来垂直居中 → 顶对齐（照微信会话列表）。
   标题/副标题/时间戳三行顶齐，视觉重心在左上。 */
.conv { align-items:flex-start; }
.conv-side { align-items:flex-end; }

/* 2026-11-03：断点 768 → 700。桌面小窗按微信物理尺寸对齐后是 725 逻辑宽，
   卡在 768 会塌成单栏；700 是「还能放下左栏+右聊」的下限。手机端（<700）行为不变。 */
@media (min-width: 700px) {
  html, body { height:100%; }
  /* 桌面不限宽（原来是 max-width:480px 的手机条） */
  body { max-width:none; overflow:hidden; }

  .auth-box { max-width:340px; margin:0 auto; }

  /* 主壳改成左右两栏：左=会话列表，右=内容区 */
  #v-main { flex-direction:row; height:100vh; }
  .tabbar { display:none; }          /* 桌面无双 tab，「我的」挪到左栏底部 */
  .page { padding-bottom:0; }

  /* 左栏：320px 通栏，从顶到底。2026-10-11 老板：左栏太刺眼 → 改成柔和浅灰
     （微信桌面版同款：浅灰底 + 白色会话行，不再是大白底） */
  /* 2026-11-03 老板：右栏 +2mm（≈8px）→ 左栏从 264px 收到 29.8%，并改成**百分比**，
     窗口随屏幕等比放大时左右栏跟着等比例走，不再写死像素。
     min/max 只做兜底：太窄别挤成一条，太宽别吃掉聊天区。 */
  #page-chatlist { flex:0 0 29.8%; width:29.8%; min-width:232px; max-width:400px;
                   height:100vh; display:flex; flex-direction:column;
                   background:#f2f3f5; border-right:1px solid #e6e7ea; }
  #page-chatlist .topbar { position:static; flex-shrink:0; background:#f2f3f5; border-bottom:1px solid #e6e7ea; }
  #conv-list { flex:1; min-height:0; overflow-y:auto; overscroll-behavior:contain; }

  /* 左栏底部「我的」入口（微信桌面版同款：左下角头像行） */
  .rail-me { display:flex; align-items:center; gap:10px; flex-shrink:0;
             padding:10px 14px; border-top:1px solid var(--line); cursor:pointer; }
  .rail-me:hover { background:#f4f4f6; }
  .rail-me .avatar { width:38px; height:38px; border-radius:8px; font-size:15px; }
  .rm-main { flex:1; min-width:0; }
  .rm-name { font-size:15px; font-weight:500; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .rm-sub { font-size:11.5px; color:var(--sub); margin-top:1px; }
  .rm-arrow { font-size:19px; color:var(--sub); }

  /* 2026-11-03 老板：输入框太扁（实测 47px，微信约 130px）→ 桌面加高，手机端不动 */
  .inputbar { padding:12px 14px; gap:10px; align-items:flex-end; }
  #msg-input { min-height:44px; padding:12px 14px; border-radius:12px; }
  .inputbar .primary { min-height:44px; border-radius:12px; }

  /* 右栏：占位 / 我的 / 聊天共用这一格 */
  #desk-right { display:flex; flex-direction:column; flex:1; min-width:0; height:100vh; }
  #page-me { height:100%; overflow-y:auto; }

  /* 未选中会话：静态品牌占位（2026-10-10 老板定：风格与左栏一致，浅色、无胶囊、无深空） */
  .desk-empty { display:block; position:relative; flex:1; min-height:0; overflow:hidden;
                background:var(--bg); }
  .de-inner { position:relative; height:100%; display:flex; flex-direction:column;
              align-items:center; justify-content:center; text-align:center; padding:24px; }
    /* LOGO 横排锁（2026-10-11 老板定稿图一）：WEMI 字标 + 声波条 + 你说，我来做 */
  .de-lock { display:flex; align-items:flex-end; gap:14px; }
  .de-word { color:#d53f8c; font-size:64px; font-weight:900; letter-spacing:8px; line-height:.9;
             font-family:"Arial Black",Arial,sans-serif; }
  .de-bars { display:flex; align-items:flex-end; gap:7px; padding-bottom:4px; }
  .de-bars i { display:block; width:9px; border-radius:5px; }
  .de-bars i:nth-child(1) { height:34px; background:#ED93B1; }
  .de-bars i:nth-child(2) { height:56px; background:#B23A7C; }
  .de-bars i:nth-child(3) { height:74px; background:#D53F8C; }
  .de-bars i:nth-child(4) { height:46px; background:#F4C0D1; }
  .de-rule { width:340px; height:1.5px; background:rgba(213,63,140,.35); margin:18px auto 0; }
  .de-say { color:#3C3489; font-size:30px; font-weight:800; letter-spacing:3px; margin-top:14px; }
  .de-sub { color:var(--text); font-size:14px; font-weight:600; letter-spacing:5px; margin-top:10px; }
  .de-hint { color:var(--sub); opacity:.7; font-size:12px; margin-top:34px; }

  /* 聊天页：桌面不再全屏独占，钉在右栏（微信桌面版同款） */
  #v-chat { position:fixed; top:0; left:29.8%; right:0; bottom:0; height:100vh; max-height:100vh; z-index:30;
            background:var(--bg); border-left:1px solid var(--line); }
  #v-chat .topbar { background:var(--card); }

  /* 输入栏扩展件跟着聊天区走，别飘到左栏上面 */
  .emoji-panel { left:auto; right:8px; bottom:64px; transform:none;
                 width:min(420px, 42vw); max-width:none; }
  /* 2026-10-11 删掉老的 .rec-bar left:calc(50%+160px) 覆盖：面板挂在 footer 里天然只盖聊天区，
     那条老规则反而把桌面录音面板削成右半条（话筒键不在面板上=上滑取消看不到面板/丢事件的真因） */
  /* 2026-10-11 老板拍板：客户端（桌面视口）输入条去掉 ¥ 转账键（手机视口保留） */
  #btn-pay { display:none; }
  /* 2026-10-11 二轮修正：撤掉 app-region 拖拽区——禁用 GPU 加速的壳里，
     drag 区域是 Electron 已知雷区（内容冻结不重绘=聊天窗「死掉」、顶栏图标被盖住）。
     改用 JS+IPC 拖窗（app.js bindShellDrag），交互零损失。
     右侧仍留 150px 给系统 最小化/最大化/关闭 浮钮 */
  /* ⚠️ 22:5x 修正：容器是 id #v-chat（类是 view），之前误写 .v-chat 两条规则从未生效
     ——这才是「附件/截图按钮看不见（被系统钮盖住）」「‹ 还在」的真因 */
  /* 2026-11-03 老板：「顶栏不是空的嘛」——右侧那 150px 是给**旧版独立窗口**的
     系统钮（最小化/最大化/关闭）让位用的。合并版聊天跑在外壳 iframe 里，
     系统钮在页签栏那一层，顶栏不需要让位，留白反而把附件/截图按钮挤到中间。
     ⇒ 默认窄内边距；只有旧版（html.in-shell，独立无边框窗口）才留 150px。 */
  #v-chat .topbar { padding-right: 14px; }
  html.in-shell #v-chat .topbar { padding-right: 150px; }   /* 旧版独立窗口才留 150px 给系统钮 */
  #v-chat .tb-back { display:none; }

  /* 桌面绝不出现下拉应用层（正常路径已由 pdEnabled() 拦住，这里是尺寸切换的兜底） */
  #v-pulldown { display:none !important; }

  /* 账本/选股/搜索等子页桌面仍走独立整屏（带自己的返回键），但内容居中限宽免得拉太散 */
  #v-ledger, #v-search, #v-stmt, #v-stock { max-width:900px; margin:0 auto; width:100%; }
}

/* ---------- 思考外显（2026-10-13 流式统一一套规则） ---------- */
.bot-think { color:var(--sub); font-size:12px; white-space:pre-wrap; word-break:break-all;
  max-height:72px; overflow:hidden; margin:2px auto 2px 44px; max-width:78%;
  background:var(--chip-bg, #f4f4f6); border-radius:10px; padding:6px 9px; }
.bot-think.folded { cursor:pointer; max-height:none; }
.bot-think.folded.open { white-space:pre-wrap; }
.bot-stream-bubble { font-size:15px; white-space:pre-wrap; word-break:break-word;
  background:#fff; border:1px solid #eee; border-radius:12px; padding:8px 11px;
  margin:2px auto 2px 44px; max-width:78%; box-shadow:0 1px 2px rgba(0,0,0,.05); }

/* ---------- WEMI 正在思考（占位动画 A · 2026-10-29 老板选型） ----------
   老板定："凡是用到大模型的地方，必须上占位动画，让人看见 WEMI 在思考，
   这样能避免他在思考时人以为他没反应了。"（全局规则）
   方案 A = 思考中 + 三点跳动（经典「正在输入」，最克制不抢戏）。
   ⚠️ 为什么需要它：服务端推 bot_thinking 是**有增量才有**——
     模型正在推理、还没吐出第一个字时，前端一个事件都收不到 ⇒
     界面完全静止 ⇒ 用户以为没反应。
     这个占位条在**发出消息后立刻出现**，直到收到任何 bot 事件才撤。 */
.bot-thinking {
  display:flex; align-items:center; gap:8px;
  margin:2px auto 2px 44px; max-width:78%; width:fit-content;
  background:var(--chip-bg, #f4f4f6); border-radius:12px; padding:8px 12px;
  color:var(--sub); font-size:13px; line-height:1;
}
.bot-thinking .bt-label { white-space:nowrap; }
/* 三点跳动：三点依次起落，1.4s 一轮 */
.bot-thinking .bt-dots { display:inline-flex; gap:4px; align-items:center; }
.bot-thinking .bt-dots i {
  width:5px; height:5px; border-radius:50%;
  background:currentColor; opacity:.35;
  animation:bt-dot 1.4s infinite ease-in-out;
}
.bot-thinking .bt-dots i:nth-child(2) { animation-delay:.18s; }
.bot-thinking .bt-dots i:nth-child(3) { animation-delay:.36s; }
@keyframes bt-dot {
  0%, 60%, 100% { opacity:.3; transform:translateY(0); }
  30%           { opacity:1;  transform:translateY(-3px); }
}
/* 尊重系统的"减少动态效果"设置 —— 前庭敏感用户不该被晃到 */
@media (prefers-reduced-motion: reduce) {
  .bot-thinking .bt-dots i { animation:none; opacity:.6; }
}

/* PIPL 14 登录勾选行（2026-10-17 合规整改） */
.agree-row { display:flex; align-items:flex-start; gap:8px; margin-top:12px;
  font-size:12.5px; color:var(--sub,#888); text-align:left; line-height:1.6; }
.agree-row input[type=checkbox] { margin-top:2px; accent-color:#d53f8c; }
.agree-row a { color:#d53f8c; text-decoration:none; }

/* ── 个人账卡：极简两行 + 一键落账（2026-10-29 老板定稿）───────────────
   第一行 = 内容（纯要素 + 金额）
   第二行 = 「收入」「支出」「不记了」→ 点方向 = 审核+确认+落账，一个动作完成
   判断与落库都在核心（各端共用一套大脑、一本账），这里只管显示与转发。 */
.pe-card { width:auto; min-width:210px; max-width:82%; background:var(--card);
  border:1px solid var(--line); border-radius:12px; padding:11px 13px; }
.pe-row1 { display:flex; align-items:baseline; gap:10px; flex-wrap:wrap;
  font-size:15px; font-weight:600; color:var(--text); line-height:1.35; }
.pe-item { flex:1 1 auto; word-break:break-word; }
.pe-amt { font-weight:700; white-space:nowrap; font-variant-numeric:tabular-nums; }
.pe-btns { display:flex; gap:7px; margin-top:10px; }
.pe-b { border:1px solid var(--line); background:transparent; color:var(--text);
  border-radius:9px; padding:7px 12px; font-size:13.5px; cursor:pointer; }
.pe-b:hover { background:#fdf2f8; }
.pe-dir { flex:1 1 0; min-width:64px; font-weight:600; text-align:center; }
/* 模型猜的那个方向：淡边框提示（不是强制，两个都能点） */
.pe-dir.guess { border-color:var(--accent); color:var(--accent); background:#fdf2f8; }
.pe-del { color:var(--sub); font-size:12.5px; }
.pe-done { font-size:12.5px; color:var(--sub); margin-top:8px; }

/* 前端有新版本时的顶栏提示（2026-11-01）：点了就整页刷新，不自动刷（怕冲掉正在录的音/打的字） */
#ver-bar { position:fixed; left:50%; transform:translateX(-50%); top:10px; z-index:9999;
  background:#1f2937; color:#fff; font-size:13px; line-height:1; padding:10px 16px;
  border-radius:999px; box-shadow:0 6px 20px rgba(0,0,0,.28); cursor:pointer; }
#ver-bar:hover { background:#111827; }
