* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: #fff;
  color: #1a1a1a;
  font: 14px/1.5 -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', 'PingFang SC', Arial, sans-serif;
}

.hidden {
  display: none !important;
}

.spacer {
  flex: 1;
}

.mono {
  font-family: Consolas, Menlo, monospace;
}

.num {
  text-align: right;
}

.muted {
  color: #666;
}

.bad {
  color: #b00020;
}

/* 涨价绿, 降价红, 没动灰 */
.up {
  color: #0a7d33;
}

.down {
  color: #b00020;
}

/* ---------- 表单控件 ---------- */
input[type='text'],
input[type='password'],
input[type='email'],
input[type='number'],
input[type='time'] {
  width: 100%;
  padding: 5px 7px;
  border: 1px solid #bbb;
  background: #fff;
  color: #1a1a1a;
  font: inherit;
}

input:focus {
  outline: none;
  border-color: #1a1a1a;
}

input:disabled {
  background: #f0f0f0;
  color: #999;
}

input[type='checkbox'] {
  width: 14px;
  height: 14px;
  vertical-align: middle;
}

/* 上面那条基础规则是按 input[type=...] 列的, textarea 进不去, 单独补一份一样的外观 */
.field textarea {
  display: block;
  width: 100%;
  padding: 5px 7px;
  border: 1px solid #bbb;
  background: #fff;
  color: #1a1a1a;
  font: inherit;
  resize: vertical;
}

.field textarea:focus {
  outline: none;
  border-color: #1a1a1a;
}

.btn {
  padding: 5px 12px;
  border: 1px solid #bbb;
  background: #f5f5f5;
  color: #1a1a1a;
  font: inherit;
  cursor: pointer;
  white-space: nowrap;
}

.btn:hover:not(:disabled) {
  background: #e8e8e8;
}

.btn:disabled {
  color: #aaa;
  cursor: not-allowed;
}

.btn-primary {
  background: #1a1a1a;
  border-color: #1a1a1a;
  color: #fff;
}

.btn-primary:hover:not(:disabled) {
  background: #383838;
}

.btn-primary:disabled {
  background: #aaa;
  border-color: #aaa;
  color: #eee;
}

.btn-danger {
  color: #b00020;
  border-color: #c98c95;
}

.btn-sm {
  padding: 2px 8px;
  font-size: 13px;
}

.btn-block {
  width: 100%;
  padding: 7px;
  margin-top: 4px;
}

.btn-lg {
  padding: 9px 24px;
  font-size: 16px;
  font-weight: 600;
}

/* ---------- 登录页 ---------- */
.login-wrap {
  width: 320px;
  margin: 90px auto;
}

.login-wrap h1 {
  font-size: 17px;
  margin: 0 0 2px;
}

.login-wrap .sub {
  color: #666;
  font-size: 13px;
  margin: 0 0 18px;
}

.field {
  margin-bottom: 10px;
}

.field label {
  display: block;
  font-size: 13px;
  color: #666;
  margin-bottom: 3px;
}

.form-error {
  margin-top: 10px;
  padding: 6px 8px;
  border: 1px solid #c98c95;
  color: #b00020;
  font-size: 13px;
}

/* 公告文案由管理员随手写, 原样保留换行和空格, 长邮箱地址也别把卡片撑破 */
.login-notice {
  margin-bottom: 16px;
  padding: 8px 10px;
  border: 1px solid #e0c088;
  background: #fdf6e3;
  font-size: 13px;
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

.login-note {
  margin-top: 18px;
  padding-top: 12px;
  border-top: 1px solid #ddd;
  color: #666;
  font-size: 13px;
}

/* ---------- 顶栏 ---------- */
.topbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 18px;
  padding: 8px 14px;
  border-bottom: 1px solid #ddd;
  background: #f5f5f5;
}

.topbar .title {
  font-weight: 600;
}

.topbar .item {
  color: #666;
  font-size: 13px;
}

.topbar .item b {
  color: #1a1a1a;
}

.topbar .item.closed,
.topbar .item.closed b {
  color: #b00020;
}

/* 客户端的截止倒计时: 客户最容易错过的就是这个, 顶栏里单独做大做粗.
   等宽 + tabular-nums, 否则每秒变数字时整段宽度会来回抖 */
.topbar .item.countdown {
  padding: 2px 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  background: #fff;
  font-size: 14px;
}

.topbar .item.countdown b {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
  font-size: 21px;
  font-weight: 700;
  letter-spacing: 1px;
}

/* 最后 30 分钟转橙, 最后 5 分钟转红 */
.topbar .item.countdown.soon {
  border-color: #e8a33d;
  background: #fff8ec;
}

.topbar .item.countdown.soon b {
  color: #a05a00;
}

.topbar .item.countdown.urgent {
  border-color: #b00020;
  background: #fdeaee;
}

.topbar .item.countdown.urgent b,
.topbar .item.countdown.ended b {
  color: #b00020;
}

.topbar .item.countdown.ended {
  border-color: #b00020;
  background: #fdeaee;
}

/* 倒计时走到 0 才是公布的截止时间, 实际会更早停. 不写明白的话客户会以为系统坏了 */
.topbar .item.early-note {
  color: #b00020;
  font-weight: 600;
  margin-left: -10px;
}

/* 字号加减: 顶栏各项之间是 18px, 这一组三个控件得自己收紧, 否则散得像三项 */
.topbar .zoom {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

/* 百分比读数定宽, 不然 90% 跳到 100% 会把两边按钮推来推去 */
.topbar .zoom b {
  min-width: 42px;
  text-align: center;
}

/* ---------- 标签页 ---------- */
.tabs {
  display: flex;
  border-bottom: 1px solid #ddd;
  background: #fafafa;
}

.tab {
  padding: 7px 14px;
  border: none;
  border-right: 1px solid #ddd;
  background: none;
  color: #444;
  font: inherit;
  cursor: pointer;
}

.tab:hover {
  background: #efefef;
}

.tab.on {
  background: #fff;
  color: #1a1a1a;
  font-weight: 600;
}

/* ---------- 布局 ---------- */
main {
  padding: 14px;
}

.cols {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.cols .left {
  width: 300px;
  flex: none;
}

.cols .right {
  flex: 1;
  min-width: 0;
}

.panel {
  border: 1px solid #ddd;
  margin-bottom: 14px;
}

.panel > h2 {
  margin: 0;
  padding: 6px 10px;
  border-bottom: 1px solid #ddd;
  background: #f5f5f5;
  font-size: 13px;
  font-weight: 600;
}

.panel > h2 span {
  font-weight: 400;
  color: #666;
  margin-left: 8px;
}

.panel-body {
  padding: 10px;
}

/* ---------- 概况条 ---------- */
.summary {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 36px;
  padding: 8px 12px;
  border: 1px solid #ddd;
  margin-bottom: 14px;
}

.summary .k {
  color: #666;
  margin-right: 5px;
}

.summary .v {
  font-weight: 600;
}

/* 每一档的位置直接混在概况这一行里, 靠 display:contents 让每档单独吃 gap */
.summary .mypos {
  display: contents;
}

.summary .mypos span {
  font-weight: 600;
}

/* ---------- 工具条 ---------- */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid #ddd;
}

.toolbar label {
  color: #666;
}

.toolbar input[type='number'],
.toolbar input[type='time'] {
  width: 90px;
}

/* 搜索框不给宽度的话会吃到全局的 width:100%, 把整条工具栏挤成一行一个控件 */
.toolbar input[type='text'] {
  width: 130px;
}

.toolbar select {
  padding: 5px 7px;
  border: 1px solid #bbb;
  background: #fff;
  color: #1a1a1a;
  font: inherit;
}

.toolbar .hint {
  color: #666;
  font-size: 13px;
}

/* 「已选 N (含 M 位不在当前筛选内)」: 这句决定的是这次会改动多少位, 必须一眼看见 */
.toolbar #selCount {
  color: #b00020;
  font-size: 16px;
  font-weight: 700;
}

/* ---------- 表格 ---------- */
table {
  width: 100%;
  border-collapse: collapse;
}

th,
td {
  padding: 4px 10px;
  border-bottom: 1px solid #eee;
  text-align: left;
  white-space: nowrap;
}

th {
  background: #fafafa;
  border-bottom: 1px solid #ddd;
  color: #666;
  font-weight: 600;
  position: sticky;
  top: 0;
}

tbody tr:hover td {
  background: #f7f7f7;
}

td.num,
th.num {
  text-align: right;
}

.col-check {
  width: 30px;
}

.scroll {
  max-height: 70vh;
  overflow: auto;
}

.empty {
  padding: 20px 10px;
  color: #666;
}

/* ---------- 导入区 ---------- */
.drop {
  border: 1px dashed #bbb;
  padding: 24px;
  text-align: center;
  color: #666;
  cursor: pointer;
}

.drop:hover,
.drop.over {
  border-color: #1a1a1a;
  background: #fafafa;
}

.note {
  color: #666;
  font-size: 13px;
}

.note code {
  background: #f0f0f0;
  padding: 0 3px;
}

.row-flex {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: flex-end;
}

.row-flex .field {
  margin: 0;
  width: 130px;
}

/* 账号开关: 关着的整行压暗, 扫一眼就知道今天开了哪几个.
   开关按钮自己有 .btn 的 color, 不会被这条带灰 */
.acc-off td {
  color: #999;
}

/* 备注最长 500 字, 原样铺开会把整张表撑到要横向拖. 截断显示, 全文挂在 title 上.
   套一层定宽的块元素才裁得掉: 表格按内容自动算列宽, 只给 td 设 max-width 拦不住 */
.acc-note {
  overflow: hidden;
  width: 220px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.btn-on {
  border-color: #0a7d33;
  color: #0a7d33;
  font-weight: 600;
}

.acc-online {
  color: #0a7d33;
  font-weight: 600;
}

/* 合车档位一行一档, 挨着排要留点缝 */
.tier-row {
  margin-bottom: 6px;
}

/* ---------- 账单 ---------- */
/* date 没进上面那条基础输入框规则, 单独补齐外观, 否则和旁边的格子长得两样 */
input[type='date'] {
  width: 100%;
  padding: 5px 7px;
  border: 1px solid #bbb;
  background: #fff;
  color: #1a1a1a;
  font: inherit;
}

/* .field 默认 130px, 装不下 "2026-08-28" 加上日历图标 */
.row-flex .field.wide {
  width: 152px;
}

.toolbar input[type='date'] {
  width: 140px;
}

/* 价位行末尾的小计. 同行的输入框有内边距, 这里补一点让基线对上 */
.bill-sub,
.bill-total {
  color: #666;
  font-size: 13px;
  padding-bottom: 6px;
}

.bill-total {
  font-weight: 600;
  color: #1a1a1a;
}

/* 只记总金额那种记法: 价位和约成两列整列收起来. 表头和单元格带同一个类,
   一条规则把两边一起藏掉 —— 分开管的话迟早有一天两边对不上, 整张表错位 */
.bill-total-only .bill-col-lines,
.bill-total-only .bill-col-count {
  display: none;
}

/* 汇总表最后那行合计, 和上面的客户行拉开 */
#billSumFoot td {
  border-top: 2px solid #ddd;
  font-weight: 600;
}

.log {
  max-height: 400px;
  overflow: auto;
  font-family: Consolas, Menlo, monospace;
  font-size: 13px;
}

.log div {
  padding: 1px 0;
  white-space: pre-wrap;
  word-break: break-all;
}

/* ---------- 我的资料 ---------- */
/* 号关着时客户端整个 main 就剩这一块. 刻意一个数字都不给 —— 客户看不到全场总数、
   家数、价格档位, 也就无从反推那些虚拟名额 */
.off-view {
  max-width: 560px;
  margin: 60px auto;
  padding: 26px 28px;
  border: 1px solid #e0c088;
  background: #fdf6e3;
  text-align: center;
}

.off-view h2 {
  margin: 0 0 10px;
  font-size: 18px;
}

.off-view p {
  margin: 0 0 18px;
  color: #555;
}

.off-view .note {
  margin: 16px 0 0;
  color: #7a6a48;
  font-size: 13px;
}

.profile-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  padding: 7px 10px;
  border: 1px solid #e0c088;
  background: #fdf6e3;
  font-size: 13px;
}

.profile-bar span {
  flex: 1;
}

.btn.warn {
  border-color: #d08a00;
  color: #a05f00;
}

/* 挡住整页的遮罩. z-index 要压过聊天面板 (20), 否则从聊天里点开的资料框会被它盖住 */
.modal {
  position: fixed;
  inset: 0;
  z-index: 25;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow: auto;
  padding: 40px 12px;
  background: rgba(0, 0, 0, 0.35);
}

.modal-card {
  width: 420px;
  max-width: 100%;
  border: 1px solid #999;
  background: #fff;
  box-shadow: 0 2px 16px rgba(0, 0, 0, 0.25);
}

.modal-head {
  display: flex;
  align-items: center;
  padding: 8px 10px;
  border-bottom: 1px solid #ddd;
  background: #f5f5f5;
}

.modal-body {
  padding: 12px 14px 16px;
}

.modal-body h3 {
  margin: 18px 0 4px;
  font-size: 14px;
}

.modal-body h3:first-child {
  margin-top: 0;
}

.modal-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
}

.modal-foot .hint {
  flex: 1;
  color: #b00020;
  overflow-wrap: break-word;
}

.req {
  color: #b00020;
  font-weight: bold;
}

/* ---------- 提示 ---------- */
.toasts {
  position: fixed;
  right: 12px;
  bottom: 12px;
  z-index: 30;
  width: 320px;
}

.toast {
  margin-top: 6px;
  padding: 7px 10px;
  border: 1px solid #bbb;
  background: #fff;
  font-size: 13px;
  white-space: pre-wrap;
}

.toast.err,
.toast.warn {
  border-color: #c98c95;
  color: #b00020;
}

/* ---------- 客服聊天 ---------- */
/* 客户端是右下角抽屉, 管理端是标签页里的两栏. 气泡和输入区两边共用, 只有外壳不同 */
/* 顶栏里最该被一眼看到的就是这颗: 号关着的时候它是客户唯一能做的事, 平时也是
   出问题时的求助入口. 周围全是灰底描边的小按钮, 所以这里直接上实心色加大字号 */
.chat-btn {
  position: relative;
  padding: 5px 16px;
  border-color: #0a7d33;
  background: #0a7d33;
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 1px;
}

.chat-btn:hover:not(:disabled) {
  background: #0c9a3e;
}

/* 号关着时这颗按钮是整页唯一的动作入口, 再放大一号并闪一下, 免得埋在一排灰按钮里 */
.chat-btn-loud {
  padding: 7px 20px;
  font-size: 16px;
  animation: chat-pulse 1.6s ease-in-out infinite;
}

@keyframes chat-pulse {
  50% { box-shadow: 0 0 0 5px rgba(10, 125, 51, 0.35); }
}

/* 有未读就整颗转红. 只改描边的话在一排按钮里根本看不出来 */
.chat-btn.has-unread {
  border-color: #b00020;
  background: #b00020;
  color: #fff;
}

.chat-btn.has-unread:hover:not(:disabled) {
  background: #cc0025;
}

/* 红底上再放个红角标就糊成一团了, 反过来做 */
.chat-btn.has-unread .chat-badge {
  background: #fff;
  color: #b00020;
}

.chat-badge {
  display: inline-block;
  min-width: 16px;
  margin-left: 5px;
  padding: 0 4px;
  border-radius: 8px;
  background: #b00020;
  color: #fff;
  font-size: 12px;
  line-height: 16px;
  text-align: center;
}

.chat-presence {
  font-size: 12px;
}

.chat-presence.on {
  color: #0a7d33;
}

.chat-presence.off {
  color: #666;
}

.chat-panel {
  position: fixed;
  right: 12px;
  bottom: 12px;
  z-index: 20;
  display: flex;
  flex-direction: column;
  width: 380px;
  height: 520px;
  max-height: calc(100vh - 24px);
  border: 1px solid #bbb;
  background: #fff;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.18);
}

.chat-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-bottom: 1px solid #ddd;
  background: #f5f5f5;
  font-size: 13px;
}

/* 客户端的抽屉可以按住标题栏拖走. 管理端那份聊天嵌在标签页里, 没有 #chatHead */
#chatHead {
  cursor: move;
  user-select: none;
  touch-action: none; /* 手指按住标题栏是拖窗口, 不是滚页面 */
}

/* 拖动中挂在 body 上: 光标划过正文时不要选中文字, 也不要在别处变成 I 形 */
body.dragging,
body.dragging * {
  cursor: move !important;
  user-select: none !important;
}

.chat-msgs {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
}

/* 搜索条和结果. 结果盖在对话上面 (两块都是 flex:1, 同时只有一块不带 hidden) */
.chat-search {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border-bottom: 1px solid #eee;
  background: #fafafa;
}

.chat-search input[type='search'] {
  flex: 1;
  min-width: 0;
  padding: 4px 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-size: 13px;
}

.chat-all {
  display: flex;
  align-items: center;
  gap: 3px;
  white-space: nowrap;
  color: #555;
  font-size: 12px;
}

.hit-count {
  margin-bottom: 8px;
  color: #666;
  font-size: 12px;
}

.hit {
  margin-bottom: 8px;
  padding: 6px 8px;
  border-left: 3px solid #ddd;
  background: #fafafa;
  border-radius: 0 4px 4px 0;
}

.hit-jump {
  cursor: pointer;
}

.hit-jump:hover {
  border-left-color: #1a73e8;
  background: #f0f6ff;
}

.hit-head {
  display: flex;
  gap: 8px;
  margin-bottom: 3px;
  color: #888;
  font-size: 11px;
}

.hit-peer {
  color: #1a73e8;
}

.hit-body {
  font-size: 13px;
  line-height: 1.5;
  word-break: break-word;
  white-space: pre-wrap;
}

.chat-empty {
  padding: 12px 4px;
  color: #666;
  font-size: 13px;
}

.msg {
  display: flex;
  margin-bottom: 10px;
}

.msg.mine {
  justify-content: flex-end;
}

.msg-body {
  max-width: 78%;
  padding: 6px 9px;
  border: 1px solid #ddd;
  background: #fff;
}

.msg.mine .msg-body {
  border-color: #1a1a1a;
  background: #1a1a1a;
  color: #fff;
}

/* 对方发什么都只是字: 保留换行, 长串强制断行, 不撑破气泡 */
.msg-text {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.msg-body img {
  display: block;
  max-width: 100%;
  height: auto;
}

.msg-file {
  display: flex;
  align-items: center;
  gap: 8px;
  color: inherit;
}

.msg-file-name {
  overflow-wrap: anywhere;
}

.msg-file-size,
.msg-at {
  color: #888;
  font-size: 12px;
}

.msg.mine .msg-file-size,
.msg.mine .msg-at {
  color: #bbb;
}

.msg-at {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 3px;
}

/* 已读 / 未读. 只挂在自己发的气泡上, 而那是深色底, 所以颜色只按深色底调.
   「已读」是常态, 跟时间戳一个分量就行; 要看的是「未读」那个状态 */
.msg-read {
  font-size: 12px;
}

.msg-read.no {
  color: #ffd28a;
}

/* 引用按钮平时藏起来: 每个气泡都常驻一个按钮会把对话搞得很吵 */
.msg-quote {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  opacity: 0;
  text-decoration: underline;
}

.msg:hover .msg-quote,
.msg-quote:focus {
  opacity: 0.75;
}

/* 气泡里的引文. 左边一道竖线, 一眼看出这段是别人说过的话而不是本条内容.
   整块是个按钮, 点了跳回被引用的那条 */
.msg-reply {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 6px;
  margin-bottom: 4px;
  padding: 3px 7px;
  border: 0;
  border-left: 3px solid #999;
  background: #f0f0f0;
  color: #555;
  font: inherit;
  font-size: 12px;
  line-height: 1.5;
  cursor: pointer;
  text-align: left;
}

.msg.mine .msg-reply {
  border-left-color: #888;
  background: #333;
  color: #ccc;
}

.msg-reply:hover {
  background: #e6e6e6;
}

.msg.mine .msg-reply:hover {
  background: #444;
}

/* .msg-body img 那条把 height 设成了 auto, 缩略图要固定成小方块得压过它 */
.msg-reply .msg-reply-img {
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 2px;
  object-fit: cover;
}

.msg-reply-who {
  flex: none;
  font-weight: 600;
}

.msg-reply-text {
  overflow: hidden;
  overflow-wrap: anywhere;
}

/* 跳过去之后闪一下. 不闪的话滚到位了人也不知道该看哪一条 */
.msg-flash .msg-body {
  animation: msg-flash 1.6s ease-out;
}

@keyframes msg-flash {
  0%,
  55% {
    box-shadow: 0 0 0 3px #e8a33d;
  }

  100% {
    box-shadow: 0 0 0 3px rgba(232, 163, 61, 0);
  }
}

/* 高危附件: 红得让人停一下. 自己发的气泡是深色底, 单独配一套 */
.msg-risk {
  margin-bottom: 4px;
  padding: 3px 7px;
  background: #fdecea;
  color: #b3261e;
  font-size: 12px;
  font-weight: 600;
}

.msg.mine .msg-risk {
  background: #4a1512;
  color: #ffb4ab;
}

.msg-file.risky .msg-file-name {
  color: #b3261e;
  text-decoration-color: #b3261e;
}

.msg.mine .msg-file.risky .msg-file-name {
  color: #ffb4ab;
}

/* 大附件的 24 小时时效. 过期后是既成事实, 不是警告, 所以灰着而不是红着 */
.msg-ttl {
  margin-top: 3px;
  color: #888;
  font-size: 11px;
}

.msg-ttl.gone {
  color: #b3261e;
}

.msg.mine .msg-ttl {
  color: #9aa0a6;
}

.msg.mine .msg-ttl.gone {
  color: #ffb4ab;
}

.chat-send {
  border-top: 1px solid #ddd;
}

/* 待发送的引用, 贴在输入框上面 */
.chat-reply {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  border-bottom: 1px solid #eee;
  background: #f7f7f7;
}

/* 里面可能放一张缩略图 + 一行字, 省略号交给里面那行 */
.chat-reply-text {
  display: flex;
  overflow: hidden;
  flex: 1;
  align-items: center;
  gap: 6px;
  color: #555;
  font-size: 12px;
}

.chat-reply-img {
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 2px;
  object-fit: cover;
}

.chat-reply-line {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 待发区: 挑好还没发出去的附件排在这儿, 可以接着加、也可以单个撤掉 */
.chat-pend {
  display: flex;
  padding: 6px 8px;
  border-bottom: 1px solid #eee;
  background: #f7f7f7;
  flex-wrap: wrap;
  gap: 6px;
}

.pend {
  display: flex;
  max-width: 100%;
  align-items: center;
  gap: 6px;
  padding: 3px 4px 3px 6px;
  border: 1px solid #ddd;
  background: #fff;
  font-size: 12px;
}

/* 压缩包正在被拆开看. 边框换个颜色就够了 —— 这一步通常一两秒就过去,
   加个转圈动画反而在屏幕上闪一下 */
.pend.checking {
  border-color: #f0a020;
  background: #fffaf0;
}

/* 本地没查成的 (库读不动 / 包太碎): 传完才由服务器判. 标出来, 不然客户
   眼看着进度条走完再被顶回来, 会以为前面那道检查是摆设 */
.pend.unchecked {
  border-style: dashed;
  border-color: #f0a020;
}

.pend.unchecked .pend-size {
  color: #b26a00;
}

.pend-img {
  display: block;
  width: 40px;
  height: 40px;
  border-radius: 2px;
  object-fit: cover;
}

.pend-name {
  overflow: hidden;
  max-width: 150px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pend-size {
  flex: none;
  color: #888;
}

.pend-x {
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  background: none;
  color: #888;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  flex: none;
}

.pend-x:hover {
  color: #b3261e;
}

/* 表情面板. 高度写死是为了别把消息区顶掉一半, 装不下就自己滚 */
.emoji-panel {
  display: flex;
  max-height: 132px;
  padding: 4px;
  border-top: 1px solid #eee;
  background: #fafafa;
  overflow-y: auto;
  flex-wrap: wrap;
  gap: 2px;
}

.emoji-panel .emoji {
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  background: none;
  font-size: 19px;
  line-height: 1;
  cursor: pointer;
}

.emoji-panel .emoji:hover {
  background: #e8e8e8;
}

.chat-send textarea {
  display: block;
  width: 100%;
  padding: 7px 9px;
  border: 0;
  font: inherit;
  resize: none;
}

.chat-send textarea:focus {
  outline: none;
}

.chat-tools {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  border-top: 1px solid #eee;
}

.chat-tools .hint {
  overflow: hidden;
  color: #666;
  font-size: 12px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- 管理端: 客户列表 + 聊天窗 ---------- */
.chat-two {
  display: flex;
  height: 560px;
}

.chat-side {
  display: flex;
  overflow-y: auto;
  flex-direction: column;
  width: 240px;
  border-right: 1px solid #ddd;
}

.chat-side .empty {
  padding: 12px 10px;
}

.chat-peer {
  padding: 7px 10px;
  border-bottom: 1px solid #eee;
  cursor: pointer;
}

.chat-peer:hover {
  background: #f5f5f5;
}

.chat-peer.on {
  background: #1a1a1a;
  color: #fff;
}

.chat-peer-top {
  display: flex;
  align-items: center;
  gap: 6px;
}

.chat-peer-name {
  overflow: hidden;
  flex: 1;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chat-peer-last {
  overflow: hidden;
  color: #888;
  font-size: 12px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chat-peer.on .chat-peer-last {
  color: #bbb;
}

.chat-main {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
}
