/* 主框架、图标栏、列表栏、聊天、抽屉、弹窗、群聊、主题、响应式分栏。 */
/* ---------- 主框架 ---------- */
#app{position:fixed;inset:0;display:flex}
#list-view{width:100%;height:100%;background:var(--panel);display:flex;flex-direction:column;min-width:0}
#chat-view{position:fixed;inset:0;background:var(--bg);display:flex;flex-direction:column;z-index:10;transform:translateX(100%);transition:transform .24s cubic-bezier(.25,.7,.3,1);will-change:transform}
body.chat-open #chat-view{transform:translateX(0)}
/* 申请记录：移动端整屏滑入，与聊天区同一套转场；桌面端由下方媒体查询改成右栏面板。
   它是右栏的默认内容，未打开会话时不再是一片空白。 */
#req-view{position:fixed;inset:0;background:var(--bg);display:flex;flex-direction:column;z-index:11;transform:translateX(100%);transition:transform .24s cubic-bezier(.25,.7,.3,1);will-change:transform}
body.req-open #req-view{transform:translateX(0)}

.bar{height:58px;padding:0 max(12px,env(safe-area-inset-left)) 0 max(12px,env(safe-area-inset-right));background:var(--glass);backdrop-filter:saturate(1.5) blur(12px);-webkit-backdrop-filter:saturate(1.5) blur(12px);border-bottom:1px solid var(--line);display:flex;align-items:center;gap:8px;flex:none;position:relative;z-index:2}
#list-view .bar{justify-content:space-between}
.brand{display:flex;align-items:center;gap:8px;font-size:16.5px;font-weight:650;min-width:0;flex:1}
.brand-mark{width:26px;height:26px;border-radius:8px;background:linear-gradient(150deg,var(--primary),var(--primary-d));display:flex;align-items:center;justify-content:center;flex:none}
.brand-mark svg{width:15px;height:15px;color:#fff}
.me-name{font-weight:450;color:var(--sub);font-size:13.5px;margin-left:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer;min-width:0}
.bar-actions{display:flex;gap:2px;flex:none}
.icon-btn{width:40px;height:40px;border-radius:12px;border:none;background:transparent;color:var(--txt-2);display:flex;align-items:center;justify-content:center;position:relative;transition:background .15s,color .15s}
.icon-btn:hover{background:var(--fill)}
.icon-btn:active{background:var(--fill-2)}
.icon-btn svg{width:21px;height:21px}
.dot{position:absolute;top:7px;right:7px;width:8px;height:8px;border-radius:50%;background:var(--danger);box-shadow:0 0 0 2px var(--panel);animation:pulse 1.8s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.45}}
.dot.hidden{display:none}

/* ---------- 左侧图标栏（对齐微信：图标栏 + 列表栏 双列结构） ---------- */
#rail{display:none}
#app{--rail-bg:#e7ebf0;--rail-ic:#59616e}
html[data-resolved=dark] #app{--rail-bg:#101419;--rail-ic:#8b94a3}
.rail-btn{position:relative;width:44px;height:44px;border:none;border-radius:14px;background:transparent;color:var(--rail-ic);display:flex;align-items:center;justify-content:center;transition:background .15s,color .15s,transform .12s}
.rail-btn svg{width:23px;height:23px}
.rail-btn:hover{background:var(--fill)}
.rail-btn:active{transform:scale(.92)}
.rail-btn.on{background:var(--primary-l);color:var(--primary-tx)}
.rail-btn .dot{top:6px;right:6px;box-shadow:0 0 0 2px var(--rail-bg)}
/* 头像按钮：与普通图标不同尺寸，单独给一个略小的圆角方形 */
.rail-me{width:38px;height:38px;font-size:16px;border-radius:12px;box-shadow:var(--sh-sm)}
.rail-me .on{display:none}
.rail-sep{width:26px;height:1px;background:var(--line-2);margin:6px 0;flex:none}
.rail-grow{flex:1 1 auto;min-height:8px}

/* ---------- 列表栏顶部的搜索框 ---------- */
/* 默认隐藏，仅桌面端显示（见 720px 媒体查询里的 display:flex）：
   移动端顶栏是「品牌 + 搜索聊天记录 + 更多」，输入框若同时出现，
   顶栏会有两个搜索入口，截图里那个挤在品牌左侧的小框就是它。 */
.list-search{position:relative;flex:1;display:none;align-items:center;min-width:0}
.list-search>svg{position:absolute;left:11px;width:16px;height:16px;color:var(--mut);pointer-events:none}
#ls-q{width:100%;height:34px;border:1px solid transparent;border-radius:11px;background:var(--fill);padding:0 30px 0 33px;font-size:14px;font-family:inherit;color:var(--txt);outline:none;transition:border-color .15s,background .15s,box-shadow .15s}
#ls-q::placeholder{color:var(--mut)}
#ls-q:focus{background:var(--panel);border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-l)}
.ls-clear{position:absolute;right:6px;width:22px;height:22px;border:none;border-radius:50%;background:var(--line-2);color:var(--txt-2);font-size:14px;line-height:1;display:flex;align-items:center;justify-content:center;padding:0}
.ls-clear.hidden{display:none}
/* 桌面端列表栏标题：微信那种「搜索框独占一行，下面直接是列表」 */
.list-title{font-size:14px;font-weight:600;color:var(--txt-2);padding:9px 12px 4px;flex:none;display:none}
/* 无结果提示 */
#ls-none{padding:34px 12px;text-align:center;color:var(--mut);font-size:13.5px;flex:none}
#ls-none.hidden{display:none}

/* ---------- 「更多」下拉菜单：收纳申请/主题/退出 ---------- */
#list-menu{position:fixed;z-index:60;min-width:150px;background:var(--panel);border:1px solid var(--line);border-radius:13px;padding:5px;box-shadow:var(--sh-lg);display:flex;flex-direction:column}
#list-menu.hidden{display:none}
#list-menu button{height:40px;padding:0 13px;border:none;background:none;text-align:left;font-size:14.5px;color:var(--txt);border-radius:9px;display:flex;align-items:center;gap:10px;transition:background .12s}
#list-menu button:hover{background:var(--fill)}
#list-menu button.danger{color:var(--danger)}
#list-menu button svg{width:17px;height:17px;flex:none;opacity:.72}

#req-bar{display:flex;align-items:center;gap:8px;padding:11px 14px;margin:10px 12px 0;background:var(--warn-bg);color:var(--warn-tx);font-size:13.5px;border-radius:12px;cursor:pointer;border:1px solid var(--warn-line);transition:transform .08s}
#req-bar:active{transform:scale(.99)}
#req-bar svg{width:16px;height:16px;flex:none}
#req-bar b{margin-left:auto;font-size:12px;background:var(--danger-d);color:#fff;border-radius:999px;padding:1px 8px}

/* 列表滚动区：通讯录入口行与好友列表一起滚动，不用各自维护滚动位置 */
#list-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:6px 8px 12px;overscroll-behavior:contain;scrollbar-gutter:stable;display:flex;flex-direction:column}
#friends{list-style:none;padding:0;margin:0;flex:none}
#list-tabs{display:flex;gap:6px;padding:9px 12px 6px;flex:none}
#list-tabs button{flex:1;height:34px;border:1px solid var(--line-2);background:var(--panel);border-radius:11px;font-size:13.5px;color:var(--txt-2);cursor:pointer;transition:background .12s,border-color .12s,color .12s}
#list-tabs button.on{background:var(--primary);border-color:var(--primary);color:#fff;font-weight:600}
/* ---------- 通讯录入口行：新的朋友 / 群聊 / 添加朋友 ---------- */
/* 参考微信、QQ：彩色圆角图标 + 名称，右侧箭头；点击进入对应功能 */
#addr-entries{flex:none;margin:0 0 2px}
.addr-row{position:relative;width:100%;display:flex;align-items:center;gap:12px;padding:9px 8px;border:none;background:none;border-radius:15px;text-align:left;font-size:15.5px;color:var(--txt);transition:background .12s,transform .08s}
.addr-row:hover{background:var(--fill)}
.addr-row:active{transform:scale(.99)}
.addr-row.hidden{display:none}
.addr-ic{width:40px;height:40px;border-radius:12px;display:flex;align-items:center;justify-content:center;flex:none;color:#fff;box-shadow:var(--sh-sm)}
.addr-ic svg{width:22px;height:22px}
.addr-ic.c-req{background:linear-gradient(150deg,#f5a742,#e07f28)}
.addr-ic.c-grp{background:linear-gradient(150deg,#3fb378,#2c8f5d)}
.addr-ic.c-ai{background:linear-gradient(150deg,#8b7cf6,#5b46d6)}
.addr-ic.c-add{background:linear-gradient(150deg,#4f95e8,#3577c9)}
.addr-ic.c-back{background:var(--fill);color:var(--txt-2);box-shadow:none}
.addr-k{flex:1;min-width:0;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.addr-n{font-size:13px;color:var(--mut);flex:none}
.addr-ch{width:16px;height:16px;color:var(--mut);flex:none;opacity:.65}
/* 未读圆点在入口行里改为随流布局，不再绝对定位在按钮右上角 */
.addr-row .dot{position:static;flex:none;box-shadow:none}
#addr-sec{flex:none;padding:10px 10px 3px;font-size:12.5px;font-weight:600;color:var(--mut);letter-spacing:.3px}
#addr-sec.hidden{display:none}
#friends li{display:flex;align-items:center;gap:11px;padding:10px 8px;margin-bottom:2px;border-radius:15px;cursor:pointer;transition:background .12s}
#friends li:hover{background:var(--fill)}
#friends li.on{background:var(--primary-l)}
#friends li.on .f-last{color:var(--txt-2)}
#friends li.unread .f-name b{color:var(--primary)}
#friends li.unread .f-name b::after{content:'';display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--primary);margin-left:6px;vertical-align:middle}
.avatar{width:46px;height:46px;border-radius:50%;color:#fff;display:flex;align-items:center;justify-content:center;font-size:19px;font-weight:600;flex:none;position:relative;user-select:none;box-shadow:var(--sh-sm);letter-spacing:.5px}
.avatar .on{position:absolute;right:-1px;bottom:-1px;width:13px;height:13px;border-radius:50%;background:var(--line-2);border:2.5px solid var(--panel);transition:background .2s}
.avatar .on.online{background:var(--online)}
.avatar.sm{width:34px;height:34px;font-size:15px;border-radius:50%}
.f-meta{flex:1;min-width:0}
.f-name{display:flex;justify-content:space-between;align-items:baseline;gap:8px}
.f-name b{font-size:15.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 置顶会话的名字左侧加一枚图钉，不占用未读圆点的位置，两者可以同时出现 */
.f-name .pin{display:inline-block;width:12px;height:12px;margin-right:4px;vertical-align:-1px;color:var(--mut)}
#friends li.pinned .f-name b{font-weight:700}
.f-time{font-size:11.5px;color:var(--mut);font-weight:400;flex:none}
.f-last{font-size:13px;color:var(--sub);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:4px}
.badge{min-width:19px;height:19px;padding:0 5.5px;border-radius:999px;background:var(--danger-d);color:#fff;font-size:11.5px;font-weight:600;line-height:19px;text-align:center;flex:none;box-shadow:0 2px 6px var(--danger-glow)}
.empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;color:var(--mut);font-size:14px;text-align:center;line-height:1.9;padding:0 20px}
.empty svg{width:46px;height:46px;opacity:.5}
.empty.small{flex:none;padding:22px 0}

/* ---------- 聊天 ---------- */
.chat-bar{justify-content:flex-start;gap:10px}
#btn-back{width:34px;height:34px;margin-left:-4px}
#btn-back svg{width:22px;height:22px}
.chat-title{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center}
.chat-title b{font-size:16px;font-weight:650;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#chat-status{font-size:11.5px;color:var(--mut);margin-top:2px}
#chat-status.online{color:var(--primary)}
.conn-lost{background:var(--warn-bg);color:var(--warn-tx);text-align:center;font-size:12.5px;padding:7px;border-bottom:1px solid var(--warn-line);flex:none}

/* 上滑加载历史消息的状态条。
   放在消息区顶部而不是输入框上方：那里是上传进度条的位置，混在一起会让人
   误以为消息没发出去。加载失败也走这里，文案换红，用户才知道要重试。 */
.hist-bar{display:flex;align-items:center;justify-content:center;gap:7px;
  padding:6px 12px;flex:none;font-size:12.5px;color:var(--sub);
  background:var(--panel);border-bottom:1px solid var(--line)}
.hist-bar.fail{color:var(--danger);background:var(--danger-l)}
.hist-spin{width:11px;height:11px;flex:none;border-radius:50%;
  border:2px solid var(--line-2);border-top-color:var(--primary);
  animation:hist-spin .7s linear infinite}
.hist-bar.fail .hist-spin{display:none}
@keyframes hist-spin{to{transform:rotate(360deg)}}
/* 减弱动效偏好下停用旋转：加载状态改由文案本身表达，不依赖动画 */
@media(prefers-reduced-motion:reduce){
  .hist-spin{animation:none;border-top-color:var(--line-2)}
  .hist-bar.fail .hist-spin{border-color:var(--danger);border-top-color:var(--danger);
    border-radius:50%}
}

#msgs{flex:1;overflow-y:auto;padding:14px max(12px,env(safe-area-inset-left)) 6px max(12px,env(safe-area-inset-right));-webkit-overflow-scrolling:touch;overscroll-behavior:contain;scroll-behavior:auto}
.t-div{display:flex;justify-content:center;margin:10px 0 14px}
.t-div span{background:var(--fill-2);color:var(--sub);font-size:11.5px;padding:3px 11px;border-radius:999px}
/* 通话记录：居中的系统条，不套气泡、不带头像朝向（微信同款）。
   不可多选/转发，也没有气泡的投影与底色——它是一条事件提示。 */
.m.call-rec{justify-content:center;align-items:center;gap:0;margin-bottom:10px}
.call-rec-pill{display:inline-flex;align-items:center;gap:7px;max-width:min(86%,460px);
  padding:6px 13px;border-radius:999px;background:var(--fill-2);color:var(--sub);
  font-size:12.5px;line-height:1.5;border:1px solid var(--line);
  -webkit-user-select:none;user-select:none}
.call-rec-pill.can-call{cursor:pointer;transition:transform .12s ease}
.call-rec-pill.can-call:active{transform:scale(.97)}
.call-rec-ico{flex:none;display:inline-flex;width:14px;height:14px;color:var(--mut)}
.call-rec-ico svg{width:14px;height:14px}
.call-rec-tx{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.m{display:flex;margin-bottom:14px;gap:9px;align-items:flex-start;animation:pop .2s ease-out;scroll-margin:10px}
@keyframes pop{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}
.m .avatar{width:36px;height:36px;font-size:15px;border-radius:12px}
.m.out{flex-direction:row-reverse}
.b{max-width:min(64%,480px);padding:10px 13px;border-radius:16px;font-size:15px;line-height:1.55;word-break:break-word;white-space:pre-wrap;box-shadow:var(--sh-sm)}
.m.in .b{background:var(--bub-in);border-top-left-radius:6px}
.m.out .b{background:var(--grad-out);color:#fff;border-top-right-radius:6px}

/* ---------- 卡片消息（位置 / 链接） ---------- */
/* 卡片自带一层底板，不能沿用气泡的配色：发出去的气泡是品牌蓝渐变，
   卡片文字若压在这层渐变上，域名/标题的可读性会随气泡上下位置漂移。
   注意选择器必须比 .m.out .b（0,3,0）更具体，否则背景会被气泡渐变抢走——
   这正是之前发出的卡片变成一块紫色方块的原因。 */
.m .b.card-b{padding:0;background:var(--panel);border:1px solid var(--line);
  overflow:hidden;white-space:normal;color:var(--txt);
  /* 卡片宽度用固定值，不能写百分比：.b 的百分比是相对 .bwrap 解析的，
     而 .bwrap 自身也是内容自适应，两者互相依赖会把卡片压成一条窄缝，
     标题断行、按钮挤成两行。窄屏由 max-width:100% 自然收窄。 */
  width:238px;max-width:100%;box-shadow:var(--sh-sm);
  /* 卡片内部已经有一圈完整的圆角与分隔线，气泡这层若再画边框，
     两层圆角错位就会出现「卡片右侧挂着一块白」的错觉。
     边框统一交给卡片，气泡只负责定位与命中区域。 */
  border-color:transparent}
.m.out .b.card-b{border-top-left-radius:14px;border-top-right-radius:5px}
.m.in .b.card-b{border-top-left-radius:5px;border-top-right-radius:14px}
/* 边框与圆角由卡片自己画（气泡的边框已置为透明，避免两层圆角错位）。
   卡片自带底色，气泡那层只负责定位；两者底色相同，
   暗色模式下也不会出现「边框被同色底吃掉」的情况。 */
.card{border:1px solid var(--line);background:var(--panel);border-radius:inherit}
.m.out .card{border-top-right-radius:5px}
.m.in .card{border-top-left-radius:5px}
html[data-resolved=dark] .m .b.card-b{background:var(--fill)}
html[data-resolved=dark] .card{background:var(--fill)}
/* 卡片比普通气泡需要更大的横向空间：.bwrap 默认封顶 64%，窄屏上只剩 200px 出头，
   卡片固定宽会撑破父级而溢出屏幕。含卡片的行把上限放宽到 90%，
   卡片仍由自身 max-width:100% 兜底，不会挤到头像。 */
.m:has(.card-b) .bwrap{max-width:min(90%,480px)}
/* 图文区：图标与文字横向并排，标题单行、地址最多两行 */
.card{display:flex;flex-direction:column;align-items:stretch;text-align:left;
  /* 卡片根节点是 button（整卡可点），必须清掉按钮的原生外观，
     否则浏览器默认的灰底与内边距会压过 .b.card-b 定好的卡片底板 */
  margin:0;border:none;font:inherit;color:inherit;cursor:pointer;
  background:none;overflow:hidden;
  /* button 默认按内容收缩，不会撑满气泡。父级气泡定的是 238px，
     卡片却只占 209px，右侧空出的一条会露出气泡白底，看起来像卡片缺了一块。
     align-self:stretch 让卡片在交叉轴（宽度）上铺满父级，右侧不留白。
     .m.out .bwrap 的 align-items:flex-end 反而会把它拉伸，所以只这条是重灾区。 */
  align-self:stretch;width:100%}
.loc-top,.lnk-top{display:flex;align-items:flex-start;gap:10px;padding:13px 13px 11px}
.card-ico{width:36px;height:36px;flex:none;border-radius:11px;display:flex;
  align-items:center;justify-content:center;background:var(--primary-l);color:var(--primary-tx)}
.card-ico svg{width:19px;height:19px}
/* 链接卡片的站点 favicon：加载成功后去掉底色，直接展示站点图标 */
.card-ico img{width:24px;height:24px;border-radius:6px;object-fit:contain}
.card-ico.has-img{background:transparent}
/* ---------- 合并转发（微信式「聊天记录」）：独立卡片，不套气泡底色 ---------- */
.merge-card{width:min(100%,280px);padding:12px 13px;cursor:pointer}
.mb-title{font-size:15px;font-weight:600;color:var(--txt);line-height:1.4}
.mb-prev{margin-top:8px;display:flex;flex-direction:column;gap:4px}
.mb-line{font-size:13px;color:var(--sub);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mb-sender{color:var(--sub);margin-right:3px}
.mb-foot{margin-top:10px;padding-top:9px;border-top:1px solid var(--line);font-size:12px;color:var(--mut)}
/* 展开查看器：逐条按原类型渲染，保留发件人与时间 */
#merge-view{position:fixed;inset:0;z-index:88;background:var(--bg);display:flex;flex-direction:column;animation:ciIn .2s ease-out}
#merge-list{flex:1;overflow-y:auto;padding:14px max(12px,env(safe-area-inset-left)) 10px max(12px,env(safe-area-inset-right));display:flex;flex-direction:column}
.mr{padding:12px 14px;border-bottom:1px solid var(--line)}
.mr-meta{display:flex;align-items:baseline;gap:8px;margin-bottom:5px}
.mr-sender{font-size:13.5px;font-weight:600;color:var(--primary)}
.mr-time{font-size:11.5px;color:var(--mut)}
.mr-text{font-size:14.5px;color:var(--txt);line-height:1.5;white-space:pre-wrap;word-break:break-word}
.mr .card{margin:2px 0}
@media(min-width:720px){ #merge-view{margin:0 auto;max-width:min(var(--app-w),100%);box-shadow:0 0 0 1px var(--line)} }
.card-bd{min-width:0;flex:1}
.card-t{font-size:14.5px;font-weight:600;color:var(--txt);line-height:1.38;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.card-s{font-size:12.5px;color:var(--sub);margin-top:3px;line-height:1.45;
  overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  word-break:break-word;font-variant-numeric:tabular-nums}
/* 底部提示条：只说明「点整张卡会发生什么」，本身不可点。
   整卡热区由 .card 这个 button 承担，热区足够大，也不用在卡片上画分隔线找按钮。 */
.card-act{display:flex;align-items:center;gap:7px;align-self:stretch;width:100%;
  padding:10px 13px;border:none;border-top:1px solid var(--line);border-radius:0;
  background:transparent;color:var(--txt-2);font-family:inherit;font-size:13px;
  font-weight:500;white-space:nowrap;text-align:left;transition:background .15s}
.card-act svg{width:15px;height:15px;flex:none;color:var(--primary-tx)}
/* 右端小箭头：提示整卡可点，不额外占用图标位 */
.card-act::after{content:'';width:6px;height:6px;flex:none;margin-left:auto;
  border-right:1.5px solid var(--mut);border-bottom:1.5px solid var(--mut);
  border-radius:1px;transform:rotate(-45deg) translate(-1px,1px);opacity:.65}
/* 悬停/按下反馈落在整张卡上，而不是只有底部条有反应 */
.card:hover{background:var(--fill)}
.card:hover .card-act{border-top-color:var(--line-2)}
.card:active{background:var(--fill-2)}
.card.risk .card-act,.card.risk .card-act svg{color:var(--danger)}
/* 焦点环画在卡片外沿：用 outline 而非 box-shadow，才不会被 .b.card-b 的
   overflow:hidden 裁掉；offset 取负值让环贴着卡片边框，视觉上不脱离圆角 */
.card:focus-visible{outline:2px solid var(--primary);outline-offset:-2px;border-radius:inherit}
#composer{display:flex;gap:9px;padding:10px max(12px,env(safe-area-inset-left)) calc(10px + env(safe-area-inset-bottom)) max(12px,env(safe-area-inset-right));background:var(--glass);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-top:1px solid var(--line);flex:none;align-items:flex-end}
#in-msg{flex:1;min-width:0;font-size:16px;padding:11px 14px;border:1.5px solid transparent;border-radius:14px;resize:none;outline:none;max-height:96px;line-height:1.4;background:var(--fill);font-family:inherit;transition:border-color .15s,background .15s,box-shadow .15s}
#in-msg:focus{border-color:var(--primary);background:var(--panel);box-shadow:0 0 0 3.5px var(--primary-l)}
/* 输入栏右侧的 表情 / 更多 / 发送 三个按钮统一为 44×44、图标 21px、圆角 14px，
   视觉重量一致，不再是「两个小图标 + 一个大按钮」。 */
#composer>#btn-emoji,#composer>#btn-more{width:44px;height:44px;border-radius:14px;flex:none;background:var(--fill);color:var(--txt-2)}
#composer>#btn-emoji svg,#composer>#btn-more svg{width:21px;height:21px}
#btn-send{width:44px;height:44px;border-radius:14px;border:none;background:var(--grad-cta);color:#fff;display:flex;align-items:center;justify-content:center;flex:none;box-shadow:0 4px 12px var(--primary-glow);transition:transform .07s,opacity .15s,box-shadow .15s}
#btn-send svg{width:21px;height:21px;margin-left:-1px}
#btn-send:active{transform:scale(.95)}
#btn-send:disabled{background:var(--fill-2);color:var(--mut);box-shadow:none}
/* 按住说话悬浮面板（QQ 规范）：240×200、圆角 18、rgba(0,0,0,.72)，
   固定在视口中央。上滑取消时整条波形变淡，55 秒起提示转红倒计时。 */
#rec{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);z-index:96;width:240px;height:200px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;padding:14px;border-radius:18px;background:rgba(0,0,0,.72);color:#fff;text-align:center}
#rec.hidden{display:none}
#rec-wave{display:flex;align-items:center;justify-content:center;gap:4px;width:184px;height:70px;transition:height .15s}
#rec.locked #rec-wave{height:48px}
#rec-wave i{flex:1;min-width:3px;height:4px;background:#fff;border-radius:2px;opacity:.92}
#rec-wave.cancel i{opacity:.22}
/* 取不到麦克风音量时的兜底：呼吸动画，不至于一条死直线 */
#rec-wave.fallback i{animation:vi-breathe 1.1s ease-in-out infinite}
#rec-tip{font-size:14px;color:#fff;min-height:18px;line-height:18px}
#rec-tip.danger{color:#ff6b6b}
#rec-time{font-size:16px;color:#fff;font-variant-numeric:tabular-nums;min-height:20px;line-height:20px}
#rec-time.danger{color:#ff6b6b}
#rec-sub{font-size:11px;color:rgba(255,255,255,.6);min-height:14px}
#rec.locked #rec-sub{display:none}
#rec.locked #rec-mic{display:none}
.rec-once{display:flex;align-items:center;gap:5px;font-size:11px;color:rgba(255,255,255,.78);cursor:pointer;-webkit-user-select:none;user-select:none;min-height:16px}
.rec-once input{width:13px;height:13px;accent-color:#fff}
.rec-once.hidden{display:none}
#rec-send{height:30px;padding:0 18px;border:none;border-radius:10px;background:#fff;color:#17181a;font-size:13px;font-weight:600}
#rec-send.hidden{display:none}
#rec-mic{color:rgba(255,255,255,.75)}
#rec-mic svg{width:19px;height:19px}
/* 取消按钮：移动端走「上滑取消」手势不显示，桌面端录音条内常驻 */
#rec-cancel{display:none;height:30px;padding:0 14px;border:none;border-radius:10px;background:rgba(255,255,255,.16);color:#fff;font-size:13px;font-weight:600;cursor:pointer}
#rec-cancel:hover{background:rgba(255,255,255,.26)}

/* 桌面端录音（≥720px）：不用移动端居中大面板，改为贴输入框上沿的紧凑横条。
   交互随之分化：鼠标点击即开始并进入可操作状态（无按住/上滑手势），
   回车或「发送」发出，Esc 或「取消」作废；按住鼠标不会误发送。 */
@media(min-width:720px){
  #composer{position:relative}
  #rec{position:absolute;left:50%;bottom:calc(100% + 10px);top:auto;transform:translateX(-50%);width:auto;max-width:min(560px,92%);height:48px;flex-direction:row;align-items:center;gap:12px;padding:7px 14px;border-radius:12px;white-space:nowrap}
  #rec-wave{width:120px;height:26px;gap:3px;flex:none}
  #rec.locked #rec-wave{height:26px}
  #rec-tip{min-height:0;line-height:normal;font-size:13px;min-width:0;overflow:hidden;text-overflow:ellipsis}
  #rec-time{min-height:0;line-height:normal;font-size:14px}
  #rec-sub,#rec-mic{display:none}
  #rec-cancel{display:inline-block}
  #rec-send{height:28px;padding:0 14px}
}
/* 录音中：麦克风按钮转红，提示用户当前处于录音态 */
#btn-voice.rec-on{color:var(--danger)}
/* 引用回复条 */
#reply-bar{display:flex;align-items:center;gap:10px;padding:8px 14px;background:var(--fill);border-top:1px solid var(--line);flex:none}
#reply-bar.hidden{display:none}
#reply-bar .rb-info{flex:1;min-width:0}
#reply-bar .rb-name{font-size:13px;color:var(--primary);font-weight:600;display:block}
#reply-bar .rb-prev{font-size:12px;color:var(--sub);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}
/* 气泡内的引用块 */
.quote{margin-bottom:6px;padding:6px 9px;border-left:3px solid var(--primary);background:rgba(0,0,0,.05);border-radius:8px;font-size:13px;line-height:1.4;max-width:100%}
.dark .quote{background:rgba(255,255,255,.08)}
.quote .q-name{color:var(--primary);font-weight:600;margin-bottom:2px}
.quote .q-prev{color:var(--sub);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.b.recalled{font-style:italic;color:var(--mut);background:transparent!important;box-shadow:none}
/* 消息操作菜单 */
#msg-menu{position:fixed;z-index:60;min-width:118px;background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:5px;box-shadow:var(--sh-lg);display:flex;flex-direction:column}
#msg-menu.hidden{display:none}
#msg-menu button{height:40px;padding:0 14px;border:none;background:none;text-align:left;font-size:14.5px;color:var(--txt);border-radius:8px;cursor:pointer;transition:background .12s}
#msg-menu button:hover{background:var(--fill)}
#msg-menu button.danger{color:var(--danger)}
/* 会话操作菜单，与消息菜单同一套视觉，只多一行分隔线 */
#conv-menu{position:fixed;z-index:60;min-width:132px;background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:5px;box-shadow:var(--sh-lg);display:flex;flex-direction:column}
#conv-menu.hidden{display:none}
#conv-menu button{height:40px;padding:0 14px;border:none;background:none;text-align:left;font-size:14.5px;color:var(--txt);border-radius:8px;cursor:pointer;transition:background .12s;display:flex;align-items:center;gap:9px}
#conv-menu button:hover{background:var(--fill)}
#conv-menu button.danger{color:var(--danger)}
#conv-menu button svg{width:16px;height:16px;flex:none;opacity:.75}

/* ---------- 抽屉功能区 ---------- */
#drawer{flex:none;max-height:min(44vh,272px);max-height:min(44dvh,272px);overflow-y:auto;background:var(--glass);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-top:1px solid var(--line);padding:14px max(14px,env(safe-area-inset-left)) calc(16px + env(safe-area-inset-bottom)) max(14px,env(safe-area-inset-right));animation:dwup .18s ease-out;overscroll-behavior:contain}
@keyframes dwup{from{opacity:.4;transform:translateY(26px)}to{opacity:1;transform:none}}
#drawer .page{display:none}
#drawer .page.on{display:block}
/* .page.on 的特异性是 id+2类，这里必须同样带上 #drawer 才压得过 display:block */
#drawer #dw-tools.on{display:grid;grid-template-columns:repeat(auto-fit,minmax(64px,1fr));gap:13px 8px}
.tool{display:flex;flex-direction:column;align-items:center;gap:7px;border:none;background:none;padding:0;transition:transform .07s}
.tool:active{transform:scale(.94)}
.tool .ti{width:52px;height:52px;border-radius:17px;background:var(--fill);color:var(--txt-2);display:flex;align-items:center;justify-content:center;transition:background .15s,color .15s}
.tool svg{width:24px;height:24px}
.tool span{font-size:11.5px;color:var(--sub)}
.tool:disabled{opacity:.4}
.tool.on .ti{background:var(--primary-l);color:var(--primary-tx)}
.tool.on span{color:var(--primary-tx)}
#drawer #dw-emoji.on{display:grid;grid-template-columns:repeat(auto-fill,minmax(42px,1fr));gap:2px}
.emo{border:none;background:none;font-size:23px;line-height:1;padding:9px 0;border-radius:11px;cursor:pointer;transition:background .12s,transform .07s}
.emo:hover{background:var(--fill)}
.emo:active{transform:scale(.9)}
.dw-hint{font-size:11.5px;color:var(--mut);text-align:center;margin-top:13px}
#btn-emoji.on,#btn-more.on{color:var(--primary);background:var(--primary-l)}
body.selecting #drawer{display:none}

/* ---------- 弹窗 / 提示 ---------- */
.mask{position:fixed;inset:0;background:var(--mask);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);display:flex;align-items:center;justify-content:center;padding:18px;z-index:50;animation:fadein .16s ease-out}
@keyframes fadein{from{opacity:0}to{opacity:1}}
.modal{width:min(360px,100%);max-height:min(84vh,100%);max-height:min(84dvh,100%);display:flex;flex-direction:column;background:var(--panel);border:1px solid var(--line);border-radius:20px;padding:22px;box-shadow:var(--sh-lg);animation:zoom .2s cubic-bezier(.2,.8,.2,1);overscroll-behavior:contain}
@keyframes zoom{from{opacity:0;transform:scale(.94) translateY(8px)}to{opacity:1;transform:none}}
.modal h3{font-size:16.5px;margin-bottom:16px;font-weight:650;flex:none}
.modal input{width:100%;font-size:16px;padding:11px 13px;border:1.5px solid var(--line);border-radius:12px;outline:none;background:var(--field);transition:border-color .15s,box-shadow .15s}
.modal input:focus{border-color:var(--primary);box-shadow:0 0 0 3.5px var(--primary-l);background:var(--panel)}
.modal-msg{min-height:18px;font-size:13px;color:var(--danger);margin-top:9px;flex:none}
.modal-btns{display:flex;gap:10px;margin-top:16px;flex:none}
.modal-btns button{flex:1;padding:11px 0;font-size:15px;border-radius:12px;border:1px solid var(--line-2);background:var(--fill);color:var(--txt-2);transition:transform .07s,background .15s}
.modal-btns button:active{transform:scale(.98)}
.modal-btns .primary{background:var(--grad-cta);color:#fff;border:none;font-weight:600;box-shadow:0 5px 14px var(--primary-glow)}
.modal p{margin:0;font-size:14.5px;line-height:1.6;color:var(--txt-2);white-space:pre-wrap}
.modal-btns .danger{background:linear-gradient(180deg,var(--cta-hi),var(--cta-lo)),var(--danger-d);color:#fff;border:none;font-weight:600;box-shadow:0 5px 14px var(--danger-glow)}
/* 列表区在弹窗内部滚动，按钮行始终可见（小屏横竖切换都不会顶出视口） */
.modal ul{flex:1 1 auto;min-height:0}
.modal>p,.modal>input{flex:none}
/* 登录失效等全局提示需压过灯箱(80) */
#modal-confirm{z-index:90}
#req-list{list-style:none}
#req-list li{display:flex;align-items:center;gap:11px;padding:12px 0;border-bottom:1px solid var(--line)}
#req-list li:last-child{border-bottom:none}
#req-list .avatar{width:42px;height:42px;font-size:17px;border-radius:50%;flex:none}
#req-list .r-body{flex:1;min-width:0}
#req-list .r-name{font-size:15px;font-weight:550;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#req-list button{padding:8px 15px;border-radius:10px;border:none;font-size:13.5px;font-weight:550;flex:none;transition:transform .07s}
#req-list button:active{transform:scale(.96)}
#req-list .accept{background:var(--grad-cta);color:#fff;box-shadow:0 3px 9px var(--primary-glow)}
#req-list .reject{background:var(--fill);color:var(--txt-2)}
/* 时间用等宽数字，多行对齐后不会左右跳 */
#req-list .sub{font-size:11.5px;color:var(--sub);margin-top:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-variant-numeric:tabular-nums}
/* 处理结果：已处理的行不再给按钮，只留一个状态标记 */
.req-state{flex:none;font-size:12px;font-weight:600;padding:5px 11px;border-radius:9px;white-space:nowrap}
.req-state.accepted{color:var(--primary-tx);background:var(--primary-l)}
.req-state.declined{color:var(--sub);background:var(--fill)}
#req-view .bar{padding-left:6px;padding-right:14px;gap:2px}
.req-title{flex:1;min-width:0;font-size:16px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#req-tabs{margin:14px 0 4px;flex:none}
#req-scroll{flex:1;min-height:0;overflow-y:auto;padding:0 16px 12px;overscroll-behavior:contain}
.req-foot{flex:none;font-size:11.5px;color:var(--mut);text-align:center;padding:10px 16px max(14px,env(safe-area-inset-bottom));line-height:1.6}
#toasts{position:fixed;left:50%;transform:translateX(-50%);bottom:calc(92px + env(safe-area-inset-bottom));z-index:99;display:flex;flex-direction:column;align-items:center;gap:8px;pointer-events:none;width:max-content;max-width:86vw}
.toast{background:var(--toast-bg);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);color:var(--toast-tx);font-size:13.5px;padding:11px 17px;border-radius:13px;max-width:86vw;box-shadow:var(--sh-md);animation:toastin .22s cubic-bezier(.2,.8,.2,1)}
@keyframes toastin{from{opacity:0;transform:translateY(10px) scale(.96)}to{opacity:1;transform:none}}

/* ---------- 搜索聊天记录（整页） ---------- */
.modal.wide{width:min(420px,100%)}
mark{background:var(--mark-bg);color:var(--mark-tx);border-radius:3px;padding:0 1px}
/* 与聊天信息页/设置页/反馈页同为 z-index 88 的整页面板，
   否则它压在聊天区上时层级不统一，Esc 的关闭顺序也会失真。 */
#search-page{position:fixed;inset:0;z-index:88;background:var(--bg);display:flex;flex-direction:column;animation:ciIn .2s ease-out}
/* 搜索条件区不参与滚动：结果列表再长，关键词输入框与范围切换始终可见 */
.sp-fixed{flex:none;padding:10px 12px 0;background:var(--bg);border-bottom:1px solid var(--line)}
.sp-seg{margin-bottom:10px}
.sp-input{display:flex;align-items:center;gap:8px;height:40px;padding:0 12px;border-radius:12px;background:var(--fill);color:var(--mut);transition:box-shadow .15s}
.sp-input:focus-within{box-shadow:inset 0 0 0 1.5px var(--primary)}
.sp-input svg{width:17px;height:17px;flex:none}
.sp-input input{flex:1;min-width:0;border:none;background:transparent;outline:none;font-size:16px;color:var(--txt);font-family:inherit}
.sp-input input::placeholder{color:var(--mut)}
.sp-clear{width:22px;height:22px;flex:none;border:none;border-radius:50%;background:var(--line-2);color:var(--txt-2);font-size:16px;line-height:1;display:flex;align-items:center;justify-content:center;transition:transform .07s}
.sp-clear:active{transform:scale(.9)}
.sp-tip{font-size:12.5px;color:var(--sub);padding:8px 0 9px;text-align:center;line-height:1.5}
/* 结果区自己滚动：页面滚动交给 .ci-scroll，列表不再嵌套滚动容器 */
.sp-scroll{padding-bottom:calc(24px + env(safe-area-inset-bottom))}
#search-list{list-style:none}
#search-list li{padding:12px 14px;border-bottom:1px solid var(--line);cursor:pointer;transition:background .12s}
#search-list li:active{background:var(--fill-2)}
.s-row{display:flex;justify-content:space-between;align-items:baseline;gap:8px;margin-bottom:4px}
.s-row b{font-size:13.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.s-row span{font-size:11.5px;color:var(--mut);flex:none;font-variant-numeric:tabular-nums}
.s-txt{font-size:14px;line-height:1.5;color:var(--txt-2);white-space:pre-wrap;word-break:break-word;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
/* 桌面端贴着应用面板，不铺满整个窗口 */
@media(min-width:720px){
  #search-page{margin:0 auto;max-width:min(var(--app-w),100%);box-shadow:0 0 0 1px var(--line)}
  /* 结果行宽到面板宽度后左右内边距收窄，避免文本离边缘太远 */
  #search-list li{padding-left:18px;padding-right:18px}
}

/* ---------- 添加好友 / 群组（整页） ---------- */
/* 与搜索聊天记录同型的整页面板：z 88，顶栏 + 固定条件区 + 自滚动结果区 */
#add-page{position:fixed;inset:0;z-index:88;background:var(--bg);display:flex;flex-direction:column;animation:ciIn .2s ease-out}
/* 新建群组是整页唯一的确认性操作，收进固定底栏：弹窗里的「关闭」
   由顶栏返回承担，底栏不必再放一个退出按钮 */
.add-foot{flex:none;padding:10px 12px calc(10px + env(safe-area-inset-bottom));background:var(--glass);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-top:1px solid var(--line)}
.add-foot button{width:100%;height:42px;border:none;border-radius:12px;background:var(--grad-cta);color:#fff;font-size:15px;font-weight:600;font-family:inherit;box-shadow:0 5px 14px var(--primary-glow);transition:transform .07s}
.add-foot button:active{transform:scale(.98)}
/* 结果区滚动交给 .ci-scroll，列表不再自带 overflow 与负边距 */
#add-list{list-style:none;margin:0;padding:0}
#add-list li{display:flex;align-items:center;gap:10px;padding:11px 14px;border-bottom:1px solid var(--line)}
#add-list li:last-child{border-bottom:none}
#add-list .avatar{width:38px;height:38px;font-size:16px;border-radius:50%;flex:none}
#add-list .a-body{flex:1;min-width:0}
#add-list .a-name{font-size:15px;font-weight:550;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#add-list .a-sub{font-size:12px;color:var(--sub);margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#add-list button{flex:none;padding:8px 14px;border-radius:10px;border:none;font-size:13.5px;font-weight:550;transition:transform .07s}
#add-list button:active{transform:scale(.96)}
#add-list .go{background:var(--grad-cta);color:#fff;box-shadow:0 3px 9px var(--primary-glow)}
#add-list .wait{background:var(--fill);color:var(--sub)}
#add-list .ghost{background:var(--fill);color:var(--txt-2)}
/* 桌面端贴着应用面板，不铺满整个窗口 */
@media(min-width:720px){
  #add-page{margin:0 auto;max-width:min(var(--app-w),100%);box-shadow:0 0 0 1px var(--line)}
  /* 结果行宽到面板宽度后左右内边距收窄，避免文本离边缘太远 */
  #add-list li{padding-left:18px;padding-right:18px}
}

/* ---------- 多选与转发 ---------- */
.pick{width:20px;height:20px;border-radius:50%;border:1.6px solid var(--line-2);background:var(--panel);flex:none;position:relative;transition:background .12s,border-color .12s}
.m .pick{display:none;margin-top:9px}
body.selecting .m .pick{display:block}
body.selecting #msgs{user-select:none}
body.selecting #pend,body.selecting #composer{display:none}
.m.sel .b{opacity:.72}
.m.sel .pick,.on>.pick{background:var(--primary-d);border-color:var(--primary-d)}
.m.sel .pick::after,.on>.pick::after{content:'';position:absolute;left:6px;top:3px;width:4px;height:8px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(42deg)}
@keyframes flashring{0%{box-shadow:0 0 0 3px rgba(var(--p-rgb),.55)}100%{box-shadow:0 0 0 3px rgba(var(--p-rgb),0)}}
.m.flash .b{animation:flashring 1.7s ease-out}
#sel-bar{flex:none;display:flex;align-items:center;gap:12px;padding:10px max(14px,env(safe-area-inset-left)) calc(10px + env(safe-area-inset-bottom)) max(14px,env(safe-area-inset-right));background:var(--glass);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-top:1px solid var(--line);font-size:14px;color:var(--txt-2)}
#sel-bar>span{flex:1;text-align:center}
#sel-bar b{color:var(--primary);font-variant-numeric:tabular-nums}
#sel-bar button{height:36px;padding:0 16px;border-radius:11px;border:1px solid var(--line-2);background:var(--panel);font-size:14px;color:var(--txt-2);flex:none;transition:transform .07s}
#sel-bar button:active{transform:scale(.97)}
#sel-bar button:disabled{opacity:.45}
#sel-bar #sel-more{padding:0 14px}
#sel-bar .primary{background:var(--grad-cta);color:#fff;border:none;font-weight:600}
#sel-bar .primary:disabled{opacity:.5}
.fwd-sec{font-size:12px;color:var(--sub);margin:14px 0 2px;letter-spacing:.5px;flex:none}
#fwd-friends,#fwd-groups{list-style:none;overflow-y:auto;flex:1 1 auto;margin:0 -4px;padding:0 4px}
#fwd-friends li,#fwd-groups li{display:flex;align-items:center;gap:10px;padding:8px 4px;border-bottom:1px solid var(--line);cursor:pointer;transition:background .12s;border-radius:9px}
#fwd-friends li:last-child,#fwd-groups li:last-child{border-bottom:none}
#fwd-friends li:hover,#fwd-groups li:hover{background:var(--fill)}
#fwd-friends .avatar,#fwd-groups .avatar{width:34px;height:34px;font-size:15px}
#fwd-friends .t-name,#fwd-groups .t-name{flex:1;min-width:0;font-size:14.5px;font-weight:550;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#fwd-friends li.on,#fwd-groups li.on{background:var(--primary-l)}
#modal-fwd .modal-btns{margin-top:16px}
#modal-fwd .modal-btns button{padding:10px 0;font-size:14px}
/* 邀请群成员：与转发弹窗同款列表；已在群里的好友置灰不可选 */
#inv-list{list-style:none;overflow-y:auto;flex:1 1 auto;margin:8px -4px 0;padding:0 4px}
#inv-list li{display:flex;align-items:center;gap:10px;padding:8px 4px;border-bottom:1px solid var(--line);cursor:pointer;transition:background .12s;border-radius:9px}
#inv-list li:last-child{border-bottom:none}
#inv-list li:hover{background:var(--fill)}
#inv-list .avatar{width:34px;height:34px;font-size:15px}
#inv-list .t-name{flex:1;min-width:0;font-size:14.5px;font-weight:550;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#inv-list li.on{background:var(--primary-l)}
#inv-list li.dim{opacity:.45;cursor:not-allowed}
#inv-list li.dim:hover{background:transparent}
#inv-list .t-name i{font-style:normal;font-size:12.5px;color:var(--sub);margin-left:6px}
/* 群公告编辑：多行文本 + 字数统计，设置人信息贴在计数右侧 */
#modal-notice textarea{width:100%;min-height:128px;font-size:15px;line-height:1.6;padding:11px 13px;border:1.5px solid var(--line);border-radius:12px;outline:none;background:var(--field);color:var(--txt);font-family:inherit;resize:none;transition:border-color .15s,box-shadow .15s}
#modal-notice textarea:focus{border-color:var(--primary);box-shadow:0 0 0 3.5px var(--primary-l);background:var(--panel)}
#modal-notice textarea:disabled{opacity:.72;color:var(--txt-2);cursor:default}
.nt-meta{display:flex;justify-content:space-between;align-items:baseline;gap:10px;margin-top:8px;font-size:12px;color:var(--sub);flex:none}
.nt-meta #nt-count{flex:none;font-variant-numeric:tabular-nums}
.nt-meta #nt-by{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:right}
/* 群管理页：与添加好友同型的整页面板，列表行右侧放任命/撤销按钮 */
#group-admins{position:fixed;inset:0;z-index:88;background:var(--bg);display:flex;flex-direction:column;animation:ciIn .2s ease-out}
.ga-tip{font-size:12.5px;color:var(--sub);padding:12px 16px 10px;line-height:1.6}
#ga-list{list-style:none;margin:0;padding:0}
#ga-list li{display:flex;align-items:center;gap:10px;padding:11px 16px;border-bottom:1px solid var(--line)}
#ga-list li:last-child{border-bottom:none}
#ga-list .avatar{width:38px;height:38px;font-size:16px;border-radius:50%;flex:none}
#ga-list .ga-body{flex:1;min-width:0}
#ga-list .ga-name{font-size:15px;font-weight:550;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#ga-list .ga-tag{font-style:normal;display:inline-block;margin-left:6px;padding:1px 7px;border-radius:6px;background:var(--fill);color:var(--sub);font-size:11.5px;font-weight:500;vertical-align:1px}
#ga-list .ga-empty{display:block;padding:20px 16px;font-size:13px;color:var(--sub);text-align:center}
#ga-list button{flex:none;padding:8px 14px;border-radius:10px;border:none;font-size:13.5px;font-weight:550;font-family:inherit;transition:transform .07s}
#ga-list button:active{transform:scale(.96)}
#ga-list button.go{background:var(--grad-cta);color:#fff;box-shadow:0 3px 9px var(--primary-glow)}
#ga-list button.ghost{background:var(--fill);color:var(--txt-2)}
#ga-list button:disabled{opacity:.5}
@media(min-width:720px){
  #group-admins{margin:0 auto;max-width:min(var(--app-w),100%);box-shadow:0 0 0 1px var(--line)}
  #ga-list li{padding-left:18px;padding-right:18px}
}
/* 发送确认卡：微信式「仅查看一次」入口，发送前勾选、仅本次生效 */
#sd-prev{display:flex;align-items:center;justify-content:center;height:180px;background:var(--fill);border-radius:12px;overflow:hidden;margin-bottom:12px}
#sd-thumb{max-width:100%;max-height:100%;object-fit:contain}
#sd-kind{font-size:13px;color:var(--sub)}
#sd-name{font-size:13px;color:var(--sub);text-align:center;margin-bottom:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sd-once{display:flex;align-items:center;gap:8px;cursor:pointer;font-size:14px;-webkit-user-select:none;user-select:none}
.sd-once svg{width:18px;height:18px;flex:none;color:var(--danger)}
.sd-once input{width:16px;height:16px;flex:none;accent-color:var(--primary)}
.sd-tip{font-size:12px;color:var(--sub);margin-top:6px;line-height:1.5}

/* ---------- 群聊 ---------- */
.avatar.grp::after{content:'群';position:absolute;right:-3px;bottom:-3px;width:17px;height:17px;border-radius:50%;background:var(--panel);color:var(--txt-2);font-size:10px;font-weight:600;display:flex;align-items:center;justify-content:center;box-shadow:0 0 0 1px var(--line)}
#chat-av.grp::after{display:none}
.bwrap{display:flex;flex-direction:column;gap:3px;min-width:0;max-width:min(64%,480px)}
.m.out .bwrap{align-items:flex-end}
.bwrap .b{max-width:100%}
.m-from{font-size:11.5px;color:var(--sub);padding:0 5px;max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* ---------- 聊天信息页（微信风） ---------- */
#chat-info{position:fixed;inset:0;z-index:88;background:var(--bg);display:flex;flex-direction:column;animation:ciIn .2s ease-out}
@keyframes ciIn{from{transform:translateX(22px);opacity:.35}to{transform:none;opacity:1}}
.ci-bar{flex:none;display:flex;align-items:center;gap:6px;padding:calc(9px + env(safe-area-inset-top)) 12px 9px;background:var(--glass);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-bottom:1px solid var(--line)}
.ci-bar .ci-title{flex:1;text-align:center;font-size:16px;font-weight:600;color:var(--txt)}
.ci-bar .ci-pad{width:38px;flex:none}
.ci-scroll{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;padding-bottom:calc(26px + env(safe-area-inset-bottom))}
.ci-gsep{margin-top:9px;border-top:1px solid var(--line)}
.ci-search{margin:10px 12px 12px;display:flex;align-items:center;gap:8px;height:37px;padding:0 12px;border-radius:9px;background:var(--fill);color:var(--mut)}
.ci-search svg{width:16px;height:16px;flex:none}
.ci-search input{flex:1;min-width:0;border:none;background:transparent;outline:none;font-size:14px;color:var(--txt);font-family:inherit}
.ci-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:14px 4px;padding:2px 12px 14px}
.ci-grid-friend{grid-template-columns:repeat(2,minmax(0,88px));justify-content:start;padding:14px 12px}
.ci-cell{display:flex;flex-direction:column;align-items:center;gap:6px;background:none;border:none;padding:0;color:inherit;min-width:0}
.ci-cell .ci-av{width:46px;height:46px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:18px;font-weight:600;color:#fff;background:var(--primary);overflow:hidden}
.ci-cell .ci-av svg{width:22px;height:22px}
.ci-cell .ci-nm{font-size:11.5px;color:var(--sub);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ci-cell .ci-av.ci-plus{background:transparent;border:1.4px dashed var(--line-2);color:var(--mut)}
.ci-more{display:flex;align-items:center;justify-content:center;gap:4px;width:100%;padding:2px 0 14px;border:none;background:none;font-size:13px;color:var(--sub);font-family:inherit}
.ci-chev{width:8px;height:8px;border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;transform:rotate(45deg) translateY(-2px);transition:transform .18s}
.ci-more.up .ci-chev{transform:rotate(-135deg) translateY(-1px)}
.ci-row{display:flex;align-items:center;gap:10px;width:100%;padding:13px 16px;background:var(--panel);border:none;border-bottom:1px solid var(--line);font-family:inherit;font-size:15px;color:var(--txt);text-align:left}
.ci-row .ci-k{flex:none}
.ci-row .ci-v{flex:1;min-width:0;text-align:right;color:var(--sub);font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ci-row .ci-arrow{flex:none;color:var(--mut);font-size:19px;line-height:1;margin-left:-4px}
/* 群二维码行的图标靠最右（与「查找聊天内容」的箭头同侧，微信式）。
   该行没有 .ci-v 占位，不加 margin-left:auto 图标会贴在标签旁边。 */
.ci-row .ci-qr{flex:none;color:var(--mut);display:flex;margin-left:auto}
.ci-row .ci-qr svg{width:19px;height:19px}
.ci-row.ci-danger{justify-content:center}
.ci-row.ci-danger .ci-k{color:var(--danger)}
.ci-row:active{background:var(--fill)}
.ci-toggle:active{background:var(--panel)}
/* 开关行：标题吃掉剩余宽度，把开关推到行尾，所有开关统一右对齐 */
.ci-row.ci-toggle .ci-k{flex:1;min-width:0}
.ci-switch{flex:none;position:relative;width:44px;height:26px;display:inline-block}
.ci-switch input{position:absolute;inset:0;opacity:0;width:100%;height:100%;margin:0;cursor:pointer}
.ci-switch i{position:absolute;inset:0;border-radius:999px;background:var(--line-2);transition:background .18s}
.ci-switch i::after{content:'';position:absolute;top:2px;left:2px;width:22px;height:22px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.28);transition:transform .18s}
.ci-switch input:checked+i{background:var(--primary)}
.ci-switch input:checked+i::after{transform:translateX(18px)}
#chat-title.clickable{cursor:pointer}

/* ---------- 设置页 ---------- */
/* 与聊天信息页同层级同风格：同一份 .ci-bar/.ci-row/.ci-switch，
   差别只在分组间距，因此这里只写设置页独有的部分。 */
#settings{position:fixed;inset:0;z-index:88;background:var(--bg);display:flex;flex-direction:column;animation:ciIn .2s ease-out}
.set-scroll{padding-bottom:calc(20px + env(safe-area-inset-bottom))}
/* 分组：圆角卡片 + 组间留白，与微信的「设置」列表一致。
   border 交给子行去画，卡片本身只负责裁圆角，避免相邻行出现双线。 */
.set-sec{background:var(--panel);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.set-sec+.set-sec,.set-gap{margin-top:9px}
.set-sec .ci-row:last-child{border-bottom:none}
/* 副标题：把开关的适用范围写清楚，省掉一段说明文字。
   只作用于设置页——聊天信息页的开关行沿用原来的单行样式。
   宽度由全局 .ci-row.ci-toggle .ci-k 负责，这里只排主副标题。 */
.set-sec .ci-toggle .ci-k{display:flex;flex-direction:column;gap:3px}
.set-sec .ci-toggle .ci-k small{font-size:11.5px;color:var(--sub);font-weight:400;line-height:1.45}
/* 内联控件行：键在上、控件在下，避免「深色模式」四个字被分段控件挤到换行 */
.set-block{flex-direction:column;align-items:stretch;gap:11px;padding:14px 16px}
.set-seg{width:100%}
.set-seg button{flex:1}
.set-block #theme-swatches{justify-content:flex-start;margin:0}
.ci-note{font-size:11.5px;color:var(--sub);padding:10px 16px 12px;line-height:1.6}
/* 服务端未接入时，信誉查询开关置灰：不能点，也看不出「点了也没用」 */
.ci-row.disabled{opacity:.5;cursor:not-allowed}
.ci-row.disabled .ci-switch input{cursor:not-allowed}
.set-danger{justify-content:center;margin-left:0;margin-right:0;border-left:none;border-right:none}
.set-foot{text-align:center;font-size:11.5px;color:var(--mut);padding:20px 16px 0}
/* 桌面端贴着应用面板，不铺满整个窗口 */
@media(min-width:720px){
  #settings{margin:0 auto;max-width:min(var(--app-w),100%);box-shadow:0 0 0 1px var(--line)}
}

/* ---------- 意见反馈（整页） ---------- */
/* 与聊天信息页/设置页同层级：整页面板 + .ci-bar 顶栏，不再用居中弹窗。
   「我的反馈」是它的下一级，z-index 再高一层，两页可叠加而不互相遮挡。 */
#feedback{position:fixed;inset:0;z-index:88;background:var(--bg);display:flex;flex-direction:column;animation:ciIn .2s ease-out}
#fbhis{position:fixed;inset:0;z-index:89;background:var(--bg);display:flex;flex-direction:column;animation:ciIn .2s ease-out}
.fb-scroll{padding:12px 0 calc(24px + env(safe-area-inset-bottom))}
/* 全页只有一张卡片：分类、正文、附件、联系方式都在里面，
   少一层容器就少一道描边和一截留白，页面立刻安静下来。 */
.fb-card{background:var(--panel);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.fb-seg{display:flex;gap:7px;padding:12px 12px 0}
.fb-cat{height:30px;padding:0 13px;border-radius:15px;border:none;background:var(--fill);
  color:var(--sub);font-size:13.5px;transition:background .15s,color .15s}
.fb-cat.on{background:var(--primary);color:#fff;font-weight:600}
/* 正文占满卡片宽度，不画独立输入框边框：卡片本身就是输入容器 */
#feedback textarea{width:100%;display:block;font-family:inherit;font-size:16px;line-height:1.68;
  padding:14px 15px 4px;border:none;border-radius:0;outline:none;background:transparent;color:var(--txt);
  resize:none;min-height:118px}
#feedback textarea::placeholder{color:var(--mut)}
/* 字数与说明并排：字数贴左（视线起点），说明占剩余宽度并右对齐 */
.fb-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;
  font-size:11.5px;color:var(--mut);padding:0 15px 12px}
#fb-count{flex:none;font-variant-numeric:tabular-nums}
#fb-tip{flex:1;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 附件缩略图条：横向滚动，有几屏都不换行，也不把正文挤下去 */
.fb-thumbs{display:flex;gap:8px;padding:0 15px 12px;overflow-x:auto;scrollbar-width:none;
  -webkit-overflow-scrolling:touch}
.fb-thumbs::-webkit-scrollbar{display:none}
.fb-th{position:relative;width:62px;height:62px;flex:none;border-radius:11px;overflow:hidden;
  background:var(--fill);border:1px solid var(--line)}
.fb-th img,.fb-th video{width:100%;height:100%;object-fit:cover;display:block}
/* 视频缩略图压一层暗罩 + 播放键，避免和图片混淆 */
.fb-th.fb-th-vid::after{content:'';position:absolute;inset:0;background:rgba(0,0,0,.24)}
.fb-th-vid .fb-th-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:2;
  width:24px;height:24px;border-radius:50%;background:rgba(0,0,0,.5);color:#fff;
  display:flex;align-items:center;justify-content:center;pointer-events:none}
.fb-th-vid .fb-th-play svg{width:11px;height:11px;margin-left:1.5px}
/* 上传中的格子：转圈提示，别让用户以为已经加上去了 */
.fb-th.fb-th-load::after{content:'';position:absolute;inset:0;background:rgba(0,0,0,.4);
  background-image:radial-gradient(circle at center,rgba(255,255,255,.9) 2.5px,transparent 2.6px);
  background-size:14px 14px;animation:fbSpin .7s linear infinite}
@keyframes fbSpin{to{background-position:14px 0}}
.fb-th-x{position:absolute;top:3px;right:3px;z-index:3;width:19px;height:19px;border:none;
  border-radius:50%;background:rgba(0,0,0,.55);color:#fff;font-size:13px;line-height:1;
  display:flex;align-items:center;justify-content:center;padding:0;transition:transform .07s}
.fb-th-x:active{transform:scale(.88)}
.fb-th-err .fb-th-x{background:var(--danger-d)}
/* 添加按钮与联系方式同处一条底栏，两个入口并排，不单独占一行 */
.fb-bar{display:flex;align-items:center;gap:8px;padding:0 15px 12px}
.fb-add{display:flex;gap:8px;flex:1}
.fb-add-btn{height:33px;padding:0 12px 0 10px;border-radius:10px;border:none;background:var(--fill);
  color:var(--txt-2);font-size:13px;display:flex;align-items:center;gap:6px;transition:background .12s,transform .07s}
.fb-add-btn:active{transform:scale(.97)}
.fb-add-btn svg{width:16px;height:16px;flex:none;color:var(--mut)}
/* 联系方式：卡片内的一条安静的行，图标代替标签 */
.fb-contact{display:flex;align-items:center;gap:9px;padding:11px 15px;border-top:1px solid var(--line)}
.fb-contact svg{width:16px;height:16px;flex:none;color:var(--mut)}
.fb-contact input{flex:1;min-width:0;border:none;background:transparent;outline:none;
  font-size:14.5px;color:var(--txt);font-family:inherit;padding:0}
.fb-contact input::placeholder{color:var(--mut)}
.fb-err:empty{display:none}
.fb-err{padding:10px 15px 0;font-size:12.5px;line-height:1.55;color:var(--danger)}
.fb-actions{padding:16px 15px 0}
.fb-go{width:100%;height:46px;border:none;border-radius:12px;background:var(--grad-cta);color:#fff;
  font-size:15.5px;font-weight:600;font-family:inherit;box-shadow:0 5px 14px var(--primary-glow);
  transition:transform .07s,opacity .15s}
.fb-go:active{transform:scale(.985)}
.fb-go:disabled{opacity:.55;cursor:default}
/* 「我的反馈」入口行：组间留白与上方提交按钮分开 */
.fb-his-row{margin-top:12px;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
/* 历史列表：页面自带滚动，卡片内不再嵌套滚动区 */
.fbhis-scroll{padding:9px 0 calc(24px + env(safe-area-inset-bottom))}
#fbhis-list{list-style:none}
#fbhis-list li{background:var(--panel);padding:12px 16px;border-top:1px solid var(--line)}
#fbhis-list li:last-child{border-bottom:1px solid var(--line)}
.fbh-head{display:flex;justify-content:space-between;align-items:baseline;gap:8px;margin-bottom:5px}
.fbh-head b{font-size:13px;font-weight:600;color:var(--primary-tx);background:var(--primary-l);border-radius:6px;padding:2px 7px}
.fbh-head span{font-size:11.5px;color:var(--mut);flex:none}
.fbh-txt{font-size:14px;line-height:1.6;color:var(--txt);white-space:pre-wrap;word-break:break-word}
.fbh-contact{font-size:11.5px;color:var(--sub);margin-top:5px}
/* 历史里的附件：缩略图横排，同样点开看大图 */
.fbh-media{display:flex;gap:7px;margin-top:9px;overflow-x:auto;scrollbar-width:none}
.fbh-media::-webkit-scrollbar{display:none}
.fbh-media img,.fbh-media video{width:58px;height:58px;flex:none;object-fit:cover;border-radius:9px;
  border:1px solid var(--line);background:var(--fill);display:block}
/* 附件预览层：盖满整屏，压在反馈页与历史页之上 */
#fb-view{position:fixed;inset:0;z-index:95;background:rgba(0,0,0,.92);display:flex;
  align-items:center;justify-content:center;animation:fadein .16s ease-out}
#fb-view-body{max-width:100%;max-height:100%;display:flex;align-items:center;justify-content:center}
#fb-view-body img,#fb-view-body video{max-width:100vw;max-height:100vh;object-fit:contain;display:block}
/* 关闭键浮在预览层右上角，避开刘海与状态栏 */
.fb-view-x{position:absolute;top:calc(14px + env(safe-area-inset-top));right:12px;z-index:2;
  width:38px;height:38px;border:none;border-radius:50%;background:rgba(255,255,255,.16);
  color:#fff;display:flex;align-items:center;justify-content:center;backdrop-filter:blur(8px)}
.fb-view-x svg{width:19px;height:19px}
/* 桌面端贴着应用面板，不铺满整个窗口 */
@media(min-width:720px){
  #feedback,#fbhis{margin:0 auto;max-width:min(var(--app-w),100%);box-shadow:0 0 0 1px var(--line)}
  /* 预览层保持全屏：附件要看清，限宽反而是干扰 */
  #fb-view{margin:0;max-width:none;box-shadow:none}
  .fb-th{width:70px;height:70px}
}

/* ---------- 修改密码 ---------- */
/* 三个输入同宽对齐，圆角统一。autocomplete 给浏览器机会填入旧密码。 */
.pass-fields{display:flex;flex-direction:column;gap:10px}
.pass-fields input{margin:0}
#pw-err:empty{display:none}
#modal-pass .sd-tip{margin-top:12px}

/* ---------- 主题设置 ---------- */
#theme-swatches{display:flex;gap:12px;flex-wrap:wrap;justify-content:center;margin:2px 0 4px}
.swatch{width:42px;height:42px;border-radius:50%;border:2px solid var(--panel);background:linear-gradient(150deg,var(--sc),var(--sc-d));cursor:pointer;position:relative;transition:transform .1s,box-shadow .15s;padding:0;box-shadow:var(--sh-sm)}
.swatch:hover{transform:scale(1.06)}
.swatch.on{box-shadow:0 0 0 2.5px var(--panel),0 0 0 5px var(--sc)}
.swatch.on::after{content:'';position:absolute;inset:0;background:no-repeat center/20px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5 9.5 18 20 6.5'/%3E%3C/svg%3E")}

/* ---------- 桌面端：多断点分栏 ---------- */
@media(min-width:720px){
  #app{left:50%;transform:translateX(-50%);width:min(var(--app-w),100%);box-shadow:0 0 0 1px var(--line),0 20px 60px var(--frame);--rail-w:68px}
  /* 左侧图标栏：与列表栏平齐，窄栏固定，右侧列表宽度不变 */
  #rail{display:flex;flex-direction:column;align-items:center;gap:4px;width:var(--rail-w);flex:none;background:var(--rail-bg);border-right:1px solid var(--line);padding:16px 0 12px}
  #list-view{width:var(--list-w);flex:none;border-right:1px solid var(--line)}
  #chat-view{position:relative;inset:auto;flex:1;transform:none;transition:none;z-index:auto;min-width:0}
  body:not(.chat-open) #chat-view{display:none}
  /* 桌面端申请记录不再是弹窗：它占满右侧整栏，未打开会话时即默认内容 */
  #req-view{position:absolute;top:0;bottom:0;left:calc(var(--rail-w) + var(--list-w));right:0;transform:none;transition:none;z-index:auto;display:none}
  body:not(.chat-open) #req-view,
  body.req-open #req-view{display:flex}
  /* 桌面端右栏没有「返回」语义：切回会话点左侧列表即可 */
  #req-back{display:none}
  #req-view .bar{padding-left:16px}
  /* 与消息列同样居中限宽，宽屏下不会拉成一条长带 */
  #req-tabs,#req-scroll,.req-foot{width:100%;max-width:760px;margin-left:auto;margin-right:auto}
  .req-foot{padding-bottom:18px}
  #btn-back{display:none}
  /* 顶栏在桌面端只承担搜索：品牌与图标按钮让位给图标栏 */
  #list-view .bar{justify-content:stretch;padding:0 12px}
  #list-view .bar .list-search{display:flex}
  #list-view .bar .brand,
  #list-view .bar .bar-actions{display:none}
  /* 分段控件让位给图标栏，只保留一行标题 */
  #list-title{display:block}
  #list-tabs{display:none}
  #req-bar{margin-left:12px;margin-right:12px}
  .chat-bar{padding-left:16px;padding-right:16px}
  /* 消息列居中限宽，大屏不再是一条拉到尽头的长带 */
  #msgs{padding:18px max(22px,calc((100% - 760px)/2)) 8px}
  .b,.bwrap{max-width:min(58%,440px)}
  #composer{padding-left:16px;padding-right:16px}
  #in-msg{max-height:132px}
  #drawer{max-height:min(40vh,280px)}
  /* 信息页在桌面端不再是整屏覆盖：改为停靠在右缘的面板，
     左缘对齐应用面板右边界（应用居中且宽度为 min(--app-w,100%)），
     聊天区同步让出宽度，消息不再被挤成一条窄带。 */
  #chat-info{
    left:auto;top:0;bottom:0;
    right:max(0px,calc(50% - min(var(--app-w),100%) / 2));
    width:340px;z-index:40;
    border-left:1px solid var(--line);
    box-shadow:-10px 0 28px rgba(16,24,40,.07);
    transform:translateX(100%);
    transition:transform .22s cubic-bezier(.25,.7,.3,1);
    animation:none;
  }
  html[data-resolved=dark] #chat-info{box-shadow:-10px 0 28px rgba(0,0,0,.34)}
  body.ci-open #chat-info{transform:none}
  /* 聊天区让出面板宽度；消息列的居中限宽随之重算，不会偏移 */
  #chat-view{transition:margin-right .22s cubic-bezier(.25,.7,.3,1)}
  body.ci-open #chat-view{margin-right:340px}
  /* 面板内的分组行去掉整幅描边，改为贴合面板的分割线 */
  .ci-row{padding-left:18px;padding-right:18px}
  .ci-scroll{padding-bottom:calc(18px + env(safe-area-inset-bottom))}
  .mask{padding:26px}
}
/* --app-w 必须挂在 :root 上：#chat-info 是 #app 的兄弟节点（整屏浮层），
   挂在 #app 上时它会读到 :root 的旧值，导致停靠面板与聊天区错位。 */
@media(min-width:1120px){
  :root{--app-w:1290px;--list-w:350px}
}
@media(min-width:1520px){
  :root{--app-w:1480px;--list-w:380px}
  #msgs{padding:22px max(28px,calc((100% - 880px)/2)) 10px}
}
/* 矮屏（横屏手机、小窗口）优先保住消息区高度 */
@media(max-height:520px){
  .bar{height:50px}
  #drawer{max-height:min(52vh,196px)}
  .tool .ti{width:44px;height:44px;border-radius:14px}
  .tool svg{width:20px;height:20px}
  .modal{padding:18px;max-height:min(94vh,100%)}
  .auth-card{padding:22px 20px 18px}
  .auth-brand{margin-bottom:16px}
  .auth-mark{width:44px;height:44px;border-radius:14px}
  .auth-mark svg{width:24px;height:24px}
  /* 图标栏在小高度下收紧间距，避免底部入口被挤出视口 */
  #rail{padding:10px 0 8px;gap:2px}
  .rail-btn{width:40px;height:40px;border-radius:13px}
  .rail-btn svg{width:21px;height:21px}
  .rail-sep{margin:4px 0}
}
/* 桌面鼠标下会话行更紧凑 */
@media(min-width:720px) and (pointer:fine){
  #friends li{padding:9px 8px}
}

/* ---------- AI 伙伴 ---------- */
/* AI 头像用固定紫色：它是产品内置身份，不是某个真人，
   不该跟 avatarStyle() 生成的按名取色混在一起。 */
.avatar.ai{background:linear-gradient(140deg,#8b7cf6,#5b46d6)}
#chat-av.ai{background:linear-gradient(140deg,#8b7cf6,#5b46d6)}
.f-time.ai-tag{font-size:10.5px;font-weight:700;color:var(--primary-tx);
  background:var(--primary-l);padding:1px 6px;border-radius:5px;flex:none}
/* AI 会话没有置顶、删除、聊天信息这些真人社交操作，入口直接隐藏。
   留着点开会进到一个语义不通的页面，比不显示更糟。 */
body.ai-conv #btn-info,body.ai-conv #btn-more,body.ai-conv #btn-voice{display:none}
/* 欢迎语：AI 会话初始只有一句引导，避免空白让人以为加载失败 */
.ai-hello{display:flex;flex-direction:column;align-items:center;gap:6px;
  padding:56px 24px;color:var(--mut);text-align:center}
.ai-hello b{font-size:16px;color:var(--txt)}
.ai-hello span{font-size:13.5px;line-height:1.6}
/* 思考中三点动画。模型可能十几秒才回，没有它界面像卡死 */
.ai-dots{display:flex;gap:4px;align-items:center;padding:12px 14px}
.ai-dots i{width:6px;height:6px;border-radius:50%;background:var(--mut);animation:aiDot 1.2s infinite}
.ai-dots i:nth-child(2){animation-delay:.18s}
.ai-dots i:nth-child(3){animation-delay:.36s}
@keyframes aiDot{0%,60%,100%{opacity:.28;transform:translateY(0)}30%{opacity:1;transform:translateY(-3px)}}
@media(prefers-reduced-motion:reduce){
  .ai-dots i{animation:none;opacity:.55}
}
/* 失败/异常提示：与气泡区分开，不要伪装成 AI 说的话 */
.ai-notice{margin:10px auto;padding:8px 13px;max-width:82%;border-radius:11px;
  background:var(--fill);color:var(--sub);font-size:13px;text-align:center;line-height:1.5}
