/* 移动优先：同事基本都在手机上用，字号/点击区域按手指设计，不做多列布局。 */
* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
  /* 输入框字号小于 16px 时 iOS 聚焦会整页放大，所以正文与控件都不小于 16px */
  font-size: 16px;
  color: #1f2937;
  background: #eef1f5;
}

/* ---------- 聊天页 ---------- */
/* 纵向三段：顶部栏 / 消息流 / 底部输入区。消息流自己滚动，底部输入区永远在屏幕底部，
   也不用 position: fixed（软键盘弹出时 fixed 会被顶出可视区）。 */
body.chat { height: 100vh; height: 100dvh; display: flex; flex-direction: column; }

#stream {
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 12px;
}

.bubble {
  /* 88% 在宽屏（或浏览器缩放后视口很大）上会变成一条横贯全屏的细杠，所以再压一道上限 */
  max-width: min(88%, 760px);
  margin: 0 0 10px;
  padding: 10px 12px;
  border-radius: 12px;
  line-height: 1.5;
  word-break: break-word;
  white-space: pre-wrap;
}

.bubble.user {
  margin-left: auto;
  background: #1a6fd4;
  color: #fff;
  border-bottom-right-radius: 4px;
}

.bubble.system {
  margin-right: auto;
  background: #fff;
  border: 1px solid #dfe4ea;
  border-bottom-left-radius: 4px;
}

.bubble.system.error {
  background: #fff2f0;
  border-color: #ffc7c2;
  color: #b42318;
}

/* ---------- 确认卡片 ---------- */
.card {
  /* 宽屏上把整张卡片收成一个正常宽度的一列并居中：不然门店/客户名输入框、缩略图网格
     会跟着屏幕一起拉宽（用户放大屏 + 浏览器缩放 50% 时，卡片宽 3147px、网格却只有
     704px，右边一大片空白，输入框成了一条横贯全屏的杠） */
  max-width: 1200px;
  margin: 0 auto 14px;
  padding: 12px;
  background: #fff;
  border: 1px solid #dfe4ea;
  border-radius: 14px;
}

.card-title { margin-bottom: 10px; font-size: 16px; font-weight: 600; }

.fields .row { display: block; margin-bottom: 10px; }
.fields .label { display: block; margin-bottom: 4px; font-size: 13px; color: #5b6572; }

.fields select,
.fields input {
  width: 100%;
  height: 42px;
  padding: 0 10px;
  font-size: 16px;
  color: #1f2937;
  background: #fff;
  border: 1px solid #cbd3dd;
  border-radius: 10px;
}

/* 字段之间的说明（例：卡片上「补传靠哪些字段认成同一卷」那句） */
.fields-hint {
  margin: -4px 0 10px;
  font-size: 12px;
  line-height: 1.5;
  color: #7a8594;
}

.needs-input { border-color: #e5484d !important; background: #fff8f8 !important; }

/* 缩略图网格：默认 3 列（620-759px 的窄窗/平板），电脑 4 列，手机 2 列（见文末窄屏块）。
   每格的高度＝缩略图 + 一行结论 + 最多两行检查说明 + 材料下拉框，所以说明文字必须截断，
   否则一格 500px 高、其中 226px 全是小字（实测）。 */
.items {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* 每格按自己内容的高度走，别被同排最高的那格拉齐 —— 存疑那格有两行理由，
     拉齐会让整排留下大片空白 */
  align-items: start;
  gap: 10px;
  margin: 4px 0 12px;
}

@media (min-width: 760px) {
  .items { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.item {
  min-width: 0;
  padding: 6px;
  border: 1px solid #dfe4ea;
  border-radius: 10px;
}

.item.suspect { border-color: #f0a020; background: #fffaf0; }
.item.pending { border-color: #cbd3dd; background: #f7f9fc; }

/* 点 ✕ 去掉的格子：灰掉但不挪位置 —— 布局不跳，误触了还能点 ↩ 恢复 */
.item.removed { background: #f1f3f6; border-style: dashed; }
.item.removed img { opacity: .35; filter: grayscale(1); }

.thumb { position: relative; }

.item img {
  display: block;
  width: 100%;
  /* 四边完整优先：contain 不裁角（证件照最怕看不见四角），统一比例让网格不参差 */
  aspect-ratio: 4 / 3;
  object-fit: contain;
  border-radius: 8px;
  background: #eef1f5;
  cursor: zoom-in;
}

/* 右上角的 ✕：压在缩略图角上，外沿齐格子的边 */
.item .del {
  position: absolute;
  top: -4px;
  right: -4px;
  width: 30px;
  height: 30px;
  padding: 0;
  font-size: 15px;
  line-height: 1;
  color: #fff;
  background: rgba(31, 41, 55, .78);
  border: 2px solid #fff;
  border-radius: 50%;
}

.item.removed .del { background: #1a6fd4; }

.no-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 3;
  margin-bottom: 6px;
  padding: 6px;
  font-size: 12px;
  line-height: 1.4;
  color: #7a8594;
  text-align: center;
  background: #f7f9fc;
  border: 1px dashed #cbd3dd;
  border-radius: 8px;
}

.badge {
  display: block;
  margin-bottom: 6px;
  padding: 4px 8px;
  font-size: 13px;
  line-height: 1.35;
  background: #eef1f5;
  border-radius: 6px;
}

.item.suspect .badge { background: #fdefd5; color: #96601a; }

/* 检查说明只显示两行（DeepSeek 一次能回 150+ 字）：格子里看不到全文，点图放大里能看到 */
.reason {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  max-height: 2.9em;
  margin-bottom: 6px;
  font-size: 12px;
  line-height: 1.45;
  color: #96601a;
}

/* 「展开全文」开关默认藏起来：电脑端格子宽、结论两行看得下，不摆这个多余按钮。
   只有手机那块媒体查询里才会把它放出来（见 <=620px 的 .item .reason-toggle.shown）。 */
.reason-toggle { display: none; }

/* 存疑的二选一在窄格里竖着排，不然两个按钮会把字挤成两行半 */
.item .actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
  margin-top: 6px;
}

.item .actions button {
  padding: 7px 4px;
  font-size: 13px;
  color: #1f2937;
  background: #fff;
  border: 1px solid #cbd3dd;
  border-radius: 8px;
}

.item .actions button.selected { color: #14508f; background: #e8f1fd; border-color: #1a6fd4; }

.item .actions .chosen { font-size: 11px; line-height: 1.35; color: #5b6572; }

/* 格子里的材料栏：能打字的输入框 + 右边一个「▾」候选按钮。清单只当省打字的候选，
   清单里没有的名字（「购置税完税证明」…）直接打在中间那个框里就行。
   输入框字号仍 16px：小于 16px 时 iOS 聚焦会整页放大。 */
.item .material-picker {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

/* flex-basis 定成 90px（而不是 auto）：不然输入框自带的宽度会把“▾”挤到第二行去。
   屏幅真的太窄（620px 以下那两列）时才让它换行，那时输入框占整行更好打字。 */
.item .material-input {
  flex: 1 1 90px;
  min-width: 0;
  height: 34px;
  padding: 0 8px;
  font-size: 16px;
  color: #1f2937;
  background: #fff;
  border: 1px solid #cbd3dd;
  border-radius: 8px;
}

.item .material-more {
  flex: none;
  width: 40px;
  height: 34px;
  padding: 0;
  font-size: 14px;
  line-height: 1;
  color: #1f2937;
  background: #f7f9fc;
  border: 1px solid #cbd3dd;
  border-radius: 8px;
}

.item .material-input:disabled,
.item .material-more:disabled { color: #9aa3ad; background: #f1f3f6; }

/* 「已按图片识别，可改」占满一行，跟在输入框下面 */
.item .material-hint { flex: 1 0 100%; font-size: 12px; line-height: 1.35; color: #1a6fd4; }

/* 候选清单浮在卡片上面（不占格子高度），项多了一屏内滚动 */
.item .material-menu {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  z-index: 20;
  max-height: 270px;   /* 6 项（5 个材料 + 其他类型）一屏放下，不用在浮层里再滚一次 */
  overflow-y: auto;
  background: #fff;
  border: 1px solid #cbd3dd;
  border-radius: 8px;
  box-shadow: 0 6px 16px rgba(31, 41, 55, .18);
}

/* 下面放不下就往上弹（靠 #stream 底部的那几格不至于被裁掉） */
.item .material-menu.drop-up {
  top: auto;
  bottom: calc(100% + 2px);
}

.item .material-option {
  display: block;
  width: 100%;
  padding: 9px 10px;
  font-size: 15px;
  text-align: left;
  color: #1f2937;
  background: #fff;
  border: 0;
  border-bottom: 1px solid #eef1f5;
}

.item .material-option:last-child { color: #1a6fd4; border-bottom: 0; }

/* 必填为空时红框要落在能打字的那个框上（挂在栏位上看不出来） */
.material-picker.needs-input .material-input {
  border-color: #e5484d !important;
  background: #fff8f8 !important;
}

/* 缩略图下的一行说明：同材料多张、补传整组替换、点图放大、✕ 的语义 */
.items-hint { margin: 0 0 10px; font-size: 13px; line-height: 1.5; color: #7a8594; }

/* 手机上的缩略图（<=620px）：3 列时每格只有 108px 宽，竖拍的证件照放进 4:3 的框里
   只占中间一块（实测图只有 95x71，左右两条灰底），✕ 还探出格子外 4px 像是单独飘着，
   说明文字一行放不下几个字（见 2026-09-24 手机截图）。做法：窄屏换 2 列 + 方图（竖拍
   和横拍的截图都不浪费），✕ 收小并贴到图片角上。
   620-759px 的 3 列与 >=760px 的 4 列都不受影响 —— 这组规则只在 <=620px 生效。 */
@media (max-width: 620px) {
  .items { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }

  .item { padding: 5px; }

  /* 方图：竖拍证件（最常见）不再被 4:3 的横框削掉一半 */
  .item img,
  .no-thumb { aspect-ratio: 1 / 1; }

  /* ✕ 从「探出格子的 30px 圆」改成「压在图片右上角里的 28px 圆」 */
  .item .del {
    top: 2px;
    right: 2px;
    width: 28px;
    height: 28px;
    font-size: 14px;
  }

  /* 说明文字在手机上放大一档：2 列之后一行能多放几个字 */
  .reason { font-size: 13px; }

  /* 结论原文实测 79~156 字（DeepSeek 逐项写原因），2 列下一整条要占 8~12 行、一格比一屏
     还高。所以格子里先收成 4 行（约 55 字），底下跟一个「展开全文」，点一下原地摊开 ——
     不再用「…」把话吞掉。开关只在手机上出现（基础规则里 .reason-toggle 是 display:none）。 */
  .item .reason { -webkit-line-clamp: 4; max-height: 5.8em; }
  .item .reason.open { display: block; max-height: none; overflow: visible; }
  .item .reason-toggle {
    margin: 0 0 6px;
    padding: 3px 0;
    font-size: 13px;
    line-height: 1.4;
    color: #1a6fd4;
    text-align: left;
    text-decoration: underline;
    background: none;
    border: 0;
  }
  .item .reason-toggle.shown { display: inline-block; }

  /* 材料栏和两个按钮都按手指高度给足 */
  .item .material-input,
  .item .material-more { height: 38px; }
  .item .material-option { padding: 11px 10px; }
  .item .actions button { padding: 9px 4px; font-size: 14px; }
}

/* ---------- 点图放大（全屏浮层） ---------- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 12px;
  background: rgba(15, 23, 42, .9);
}

.lightbox.open { display: flex; flex-direction: column; gap: 10px; }

.lightbox img {
  max-width: 100%;
  max-height: 100%;
  min-height: 0;
  border-radius: 8px;
  background: #fff;
}

/* 完整结论 + 检查说明：格子里只显示两行，全文在这里看（复核的人也看 /view 里的全文） */
.lightbox-caption {
  flex: none;
  max-width: min(760px, 100%);
  max-height: 32vh;
  overflow-y: auto;
  padding: 10px 12px;
  font-size: 14px;
  line-height: 1.6;
  color: #e5e7eb;
  background: rgba(255, 255, 255, .1);
  border-radius: 10px;
}

.lightbox-caption:empty { display: none; }

.lightbox-close {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top));
  right: 12px;
  width: 44px;
  height: 44px;
  font-size: 18px;
  color: #fff;
  background: rgba(255, 255, 255, .22);
  border: 0;
  border-radius: 50%;
}

.card-error { font-size: 14px; line-height: 1.5; color: #b42318; }
.card-error:empty { display: none; }

button.primary {
  display: block;
  width: 100%;
  height: 48px;
  margin-top: 12px;
  font-size: 17px;
  font-weight: 600;
  color: #fff;
  background: #1a6fd4;
  border: 0;
  border-radius: 12px;
}

button.primary:disabled { background: #9db8d8; }

/* ---------- 底部输入区 ---------- */
body.chat footer {
  flex: none;
  /* 两行：第一行「拍照 / 选文件」，第二行「备注 + 发送」。
     行用 div 包住是必要的 —— 直接铺在 flex-wrap 里，两个按钮（basis 0）会和备注挤在同一行。 */
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px 10px;
  padding-bottom: calc(8px + env(safe-area-inset-bottom));
  background: #fff;
  border-top: 1px solid #dfe4ea;
}

.pick-row,
.send-row { display: flex; align-items: center; gap: 8px; }

/* 原生「选择文件」控件藏起来：安卓/苹果上它长得又丑又说不清，换成两个中文按钮 */
.pick-input { display: none; }

.pick-row button {
  flex: 1 1 0;
  height: 44px;
  font-size: 16px;
  color: #14508f;
  background: #e8f1fd;
  border: 1px solid #b9d4f2;
  border-radius: 10px;
}

.send-row #note-input { flex: 1 1 auto; }

/* 已选几张（拍照 + 选文件可以分几次凑）＋一个「清空」 */
.picked {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 13px;
  line-height: 1.4;
  color: #5b6572;
}

.picked:empty { display: none; }

.picked button {
  flex: none;
  height: 30px;
  padding: 0 10px;
  font-size: 13px;
  color: #14508f;
  background: #e8f1fd;
  border: 1px solid #b9d4f2;
  border-radius: 8px;
}

#note-input {
  flex: 1 1 auto;
  min-width: 0;
  height: 44px;
  padding: 0 12px;
  font-size: 16px;
  border: 1px solid #cbd3dd;
  border-radius: 10px;
}

#send-button {
  flex: none;
  height: 44px;
  padding: 0 22px;
  font-size: 16px;
  font-weight: 600;
  color: #fff;
  background: #1a6fd4;
  border: 0;
  border-radius: 10px;
}

#send-button:disabled { background: #9db8d8; }

/* ---------- 登录页 ---------- */
body.login {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  min-height: 100dvh;
  padding: 20px;
}

body.login form {
  width: 100%;
  max-width: 360px;
  padding: 22px;
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 6px 24px rgba(15, 40, 80, .08);
}

body.login h1 { margin: 0 0 16px; font-size: 20px; text-align: center; }

body.login label { display: block; margin-bottom: 12px; font-size: 14px; color: #5b6572; }

body.login input {
  width: 100%;
  height: 46px;
  margin-top: 6px;
  padding: 0 12px;
  font-size: 16px;
  border: 1px solid #cbd3dd;
  border-radius: 10px;
}

body.login .error { margin: 0 0 10px; font-size: 14px; color: #b42318; }

/* ---------- 查看页 ---------- */
/* 同样按手机优先：搜索框/按钮 48px 高、结果卡整块可点、详情里图片不超屏宽。 */
body.view { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }

body.view main { flex: 1 1 auto; padding: 12px 12px calc(12px + env(safe-area-inset-bottom)); }

.search-bar { display: flex; gap: 8px; margin-bottom: 10px; }

.search-bar input {
  flex: 1 1 auto;
  min-width: 0;
  height: 48px;
  padding: 0 12px;
  font-size: 16px;
  border: 1px solid #cbd3dd;
  border-radius: 10px;
}

.search-bar button {
  flex: none;
  height: 48px;
  padding: 0 20px;
  font-size: 16px;
  font-weight: 600;
  color: #fff;
  background: #1a6fd4;
  border: 0;
  border-radius: 10px;
}

.hint { margin: 0 0 10px; font-size: 14px; line-height: 1.5; color: #5b6572; }
.hint.error { color: #b42318; }

.result-card {
  margin-bottom: 10px;
  padding: 12px;
  background: #fff;
  border: 1px solid #dfe4ea;
  border-radius: 12px;
}

.result-card .title { margin-bottom: 4px; font-size: 17px; font-weight: 600; }
.result-card .meta { font-size: 14px; line-height: 1.6; color: #5b6572; }

/* 存疑要醒目：下载/复核的人一眼能挑出哪些需要人工过一遍 */
.mark-suspect { color: #b42318; font-weight: 600; }
/* 人工复核结论（Plan B Task 1）：跟审查状态并排，绿色=已确认可用、红色=要求重传 */
.mark-manual { font-weight: 600; }
.mark-manual.ok { color: #067647; }
.mark-manual.retake { color: #b42318; }

.detail-head {
  margin-bottom: 10px;
  padding: 12px;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.6;
  background: #fff;
  border: 1px solid #dfe4ea;
  border-radius: 12px;
}

.detail-head .meta { font-size: 14px; font-weight: 400; color: #5b6572; }

.doc-row {
  display: flex;
  gap: 10px;
  margin-bottom: 10px;
  padding: 10px;
  background: #fff;
  border: 1px solid #dfe4ea;
  border-radius: 12px;
}

.doc-row.suspect { border-color: #f0a020; background: #fffaf0; }

.doc-row img {
  flex: none;
  width: 96px;
  height: 96px;
  object-fit: cover;
  background: #eef1f5;
  border-radius: 8px;
}

/* 缩略图生成失败时占住同样的位置，别把右侧信息挤变形 */
.doc-row .no-thumb {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 96px;
  height: 96px;
  margin: 0;
  padding: 6px;
  font-size: 13px;
  line-height: 1.4;
}

.doc-info { flex: 1 1 auto; min-width: 0; font-size: 15px; line-height: 1.6; }
.doc-info .name { font-weight: 600; }
.doc-info .reason { font-size: 13px; color: #96601a; }
.doc-info .meta { font-size: 13px; color: #7a8594; }

.doc-actions a,
.doc-actions button {
  /* 手指点的东西：至少 44px 高（搜索框、打包按钮都是 48px），别做成 30px 的小药丸 */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  margin: 8px 8px 0 0;
  padding: 0 16px;
  font-size: 16px;
  color: #14508f;
  text-decoration: none;
  background: #e8f1fd;
  border: 1px solid #b9d4f2;
  border-radius: 10px;
}

.doc-actions button.danger { color: #b42318; background: #fff2f0; border-color: #ffc7c2; }

/* 卷宗页：补传入口（只有带「上传资料」权限的账号才看得到） */
.detail-head .case-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }

.detail-head .case-actions button {
  min-height: 44px;
  padding: 0 16px;
  font-size: 16px;
  color: #fff;
  background: #1a6fd4;
  border: 0;
  border-radius: 10px;
}

/* 卷宗页：删掉某一张的二次确认（就地展开，不用弹窗 —— 内嵌浏览器会拦） */
.doc-del-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
.doc-del-row[hidden] { display: none; }
.doc-del-row .warn { flex: 1 1 100%; font-size: 13px; line-height: 1.5; color: #b42318; }
.doc-del-row button {
  min-height: 44px;
  padding: 0 16px;
  font-size: 16px;
  color: #14508f;
  background: #e8f1fd;
  border: 1px solid #b9d4f2;
  border-radius: 10px;
}
.doc-del-row button.danger { color: #b42318; background: #fff2f0; border-color: #ffc7c2; }

/* 补传模式：确认卡片顶上那条「给谁补传」的说明 */
.locked-case {
  margin: 0 0 10px;
  padding: 10px 12px;
  font-size: 14px;
  line-height: 1.6;
  color: #14508f;
  background: #eef4fb;
  border: 1px solid #cfe0f2;
  border-radius: 10px;
}

.empty {
  padding: 14px;
  font-size: 15px;
  color: #7a8594;
  text-align: center;
  background: #fff;
  border: 1px dashed #cbd3dd;
  border-radius: 12px;
}

.zip-button {
  display: block;
  width: 100%;
  height: 48px;
  margin-top: 4px;
  font-size: 17px;
  font-weight: 600;
  line-height: 48px;
  color: #fff;
  text-align: center;
  text-decoration: none;
  background: #1a6fd4;
  border: 0;
  border-radius: 12px;
}

/* ---------- 页面外壳：左侧一级菜单 + 右侧内容区 ---------- */
/* 业主 2026-09-30：「一级菜单可以放到工具左侧竖向排列」。
   所以三个页面（上传 / 查看 / 后台）共用同一副外壳：左边一列常驻菜单，
   右边是这一页的内容。各页自己的 DOM 与 JS 一行都不动 —— 只换外壳。
   （2026-09-30 晚些业主又否掉了「人人先进独立首页」：没必要，进来就直接进操作页）
   手机上（<=620px）竖排菜单会把 393px 的内容区挤成一条，
   所以窄屏把它收进抽屉（左上角 ☰ 拉开，点遮罩或按 Esc 关）。 */
.shell { flex: 1 1 auto; min-height: 0; display: flex; align-items: stretch; }

.side {
  flex: none;
  /* 常驻：页面很长的时候（后台）菜单不跟着滚走，一直在眼前；菜单自己太长时在侧栏内部滚。
     手机上这一条被下面的媒体查询改成 position: fixed（抽屉）。 */
  position: sticky;
  top: 0;
  align-self: flex-start;
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  width: 216px;
  background: #123a66;
  color: #fff;
}

/* 侧栏头部：手机上留出刘海 / 状态栏那一条的高度 */
.side-head {
  flex: none;
  padding: 16px 16px 12px;
  padding-top: calc(16px + env(safe-area-inset-top));
}

.side-title { display: block; font-size: 17px; font-weight: 600; }
.side-sub { display: block; margin-top: 2px; font-size: 12px; color: #a9c2e0; }

.side-nav { flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px; padding: 4px 10px; overflow-y: auto; }

/* 手指点得中：每个菜单项 44px 高 */
.side-link {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  font-size: 15px;
  color: #dbe7f6;
  text-decoration: none;
  border-radius: 10px;
}

.side-link:hover { background: rgba(255, 255, 255, .10); }
.side-link.current { color: #fff; font-weight: 600; background: #1a6fd4; }

.side-foot {
  flex: none;
  padding: 10px 16px;
  padding-bottom: calc(12px + env(safe-area-inset-bottom));
  border-top: 1px solid rgba(255, 255, 255, .15);
}

.side-user { display: block; font-size: 14px; font-weight: 600; }
.side-role { display: block; margin-top: 2px; font-size: 12px; color: #a9c2e0; }

.side-out {
  width: 100%;
  min-height: 44px;
  margin-top: 8px;
  font-size: 14px;
  color: #fff;
  background: rgba(255, 255, 255, .18);
  border: 0;
  border-radius: 8px;
}

/* 窄屏才用的遮罩：PC 上不占位置 */
.side-scrim { display: none; }

.page { flex: 1 1 auto; min-width: 0; min-height: 0; display: flex; flex-direction: column; }

/* 页头只留「页面标题 + 手机上的 ☰」；PC 上高度和改造前的 header 差不多（~44px） */
.topbar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  padding-top: calc(10px + env(safe-area-inset-top));
  background: #1a6fd4;
  color: #fff;
}

.topbar-title {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 17px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.nav-toggle {
  display: none;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-left: -6px;
  font-size: 20px;
  line-height: 1;
  color: #fff;
  background: rgba(255, 255, 255, .18);
  border: 0;
  border-radius: 10px;
}

/* 手机上：侧栏收进抽屉（不挤内容）。这组只在 <=620px 生效，PC 一行都不动。 */
@media (max-width: 620px) {
  .side {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 40;
    width: 236px;
    max-width: 82vw;
    transform: translateX(-100%);
    transition: transform .2s ease;
  }

  body.nav-open .side { transform: translateX(0); }

  .side-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 30;
    background: rgba(15, 23, 42, .45);
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease;
  }

  body.nav-open .side-scrim { opacity: 1; pointer-events: auto; }

  .nav-toggle { display: inline-flex; }
}

/* ---------- 后台：账号管理 ---------- */
body.admin { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }

body.admin main {
  flex: 1 1 auto;
  width: 100%;
  max-width: 1100px;
  margin: 0 auto;
  padding: 12px 12px calc(12px + env(safe-area-inset-bottom));
}

/* 操作结果贴着屏幕顶端显示：账号多的时候列表要滚，提示不能跟着滚不见 */
body.admin #hint {
  position: sticky;
  top: 0;
  z-index: 5;
  margin: 0 0 10px;
  padding: 8px 2px;
  font-size: 14px;
  line-height: 1.5;
  color: #14508f;
  background: #eef1f5;
}

body.admin #hint.error { color: #b42318; }
body.admin #hint:empty { display: none; }

.panel {
  margin-bottom: 12px;
  padding: 12px;
  background: #fff;
  border: 1px solid #dfe4ea;
  border-radius: 14px;
}

.panel h2 { margin: 0 0 6px; font-size: 16px; }
.panel .hint { margin: 0 0 10px; }

.new-user { display: grid; grid-template-columns: 1fr; gap: 10px; }

@media (min-width: 760px) {
  .new-user { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* 宽屏上按钮不拉满整行：一条横幅那么宽的蓝杠看着不像按钮 */
  .new-user button.primary {
    grid-column: 1 / -1;
    width: auto;
    margin-top: 0;
    padding: 0 28px;
    justify-self: start;
  }
}

.field { display: block; min-width: 0; }
.field > span { display: block; margin-bottom: 4px; font-size: 13px; color: #5b6572; }

.field input,
.field select {
  width: 100%;
  height: 42px;
  padding: 0 10px;
  font-size: 16px;
  color: #1f2937;
  background: #fff;
  border: 1px solid #cbd3dd;
  border-radius: 10px;
}

.user-card {
  margin-bottom: 10px;
  padding: 10px 12px;
  border: 1px solid #dfe4ea;
  border-radius: 12px;
}

.user-card.disabled { background: #f7f9fc; border-style: dashed; }

.user-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}

.user-name { font-size: 16px; font-weight: 600; word-break: break-all; }

.user-status {
  flex: none;
  padding: 3px 8px;
  font-size: 12px;
  color: #14508f;
  background: #e8f1fd;
  border-radius: 6px;
}

.user-status.off { color: #7a8594; background: #eef1f5; }

/* ---------- 后台：材料清单 ---------- */
/* 一排一个材料：序号、名字、已归档几张、↑ ↓ 删除。手机上会自动换行（名字长的先占一行），
   所以每行的元素都给了 flex 基准宽度，不做固定列宽。 */
.mat-card {
  margin-bottom: 12px;
  padding: 10px 12px;
  border: 1px solid #dfe4ea;
  border-radius: 12px;
}

.mat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
}

.mat-type { font-size: 15px; font-weight: 600; }

.mat-count {
  flex: none;
  padding: 3px 8px;
  font-size: 12px;
  color: #14508f;
  background: #e8f1fd;
  border-radius: 6px;
}

.mat-item { border-top: 1px solid #eef1f5; }

.mat-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
}

.mat-no { flex: none; width: 20px; font-size: 13px; color: #7a8594; }

.mat-name {
  flex: 1 1 120px;
  min-width: 0;
  font-size: 15px;
  line-height: 1.4;
  word-break: break-all;
}

.mat-archived { flex: none; font-size: 12px; color: #7a8594; }

.mat-tools { display: flex; flex: none; gap: 6px; }

.mat-tools button {
  /* 手指点的东西：至少 44px 高（和账号那一排按钮同一套尺寸） */
  min-height: 44px;
  min-width: 44px;
  padding: 0 10px;
  font-size: 15px;
  color: #14508f;
  background: #e8f1fd;
  border: 1px solid #b9d4f2;
  border-radius: 10px;
}

.mat-tools button.danger { color: #b42318; background: #fff2f0; border-color: #ffc7c2; }
.mat-tools button:disabled { color: #9aa3ae; background: #f1f3f6; border-color: #dfe4ea; }

.mat-add { margin-top: 10px; }

.mat-tag {
  flex: none;
  padding: 3px 8px;
  font-size: 12px;
  color: #96601a;
  background: #fdf3e3;
  border-radius: 6px;
}

/* ---------- 后台：车型库（标签框） ---------- */
/* 「输入一个车型 → 变成一个标签 → 标签上的 ✕ 删掉」：这是业主点名要的形态
   （「类似于很多互联网社交软件给自己选标签的那种选择框」）。 */
.tag-box {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-height: 48px;
  padding: 6px;
  background: #fbfcfe;
  border: 1px dashed #cbd3dd;
  border-radius: 10px;
}

.tag {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding-left: 12px;
  min-height: 38px;
  font-size: 14px;
  line-height: 1;
  color: #14508f;
  background: #e8f1fd;
  border: 1px solid #b9d4f2;
  border-radius: 999px;
}

.tag-x {
  width: 36px;
  height: 36px;
  padding: 0;
  font-size: 13px;
  line-height: 1;
  color: #6b7d92;
  background: none;
  border: 0;
  border-radius: 999px;
}

.tag-x:hover { color: #b42318; background: #d7e6f8; }

.tag-empty {
  padding: 8px 6px;
  font-size: 13px;
  color: #7a8594;
}

/* 材料标签（2026-09-29：清单改成和车型库同一套标签框 + 拖放排序）。
   序号写在标签里 —— 它就是归档文件名前面的编号：拖一下顺序，编号跟着变。
   必备 = 蓝底（就是上面这套 .tag 的默认长相），非必备 = 灰底虚框（点标签本体切换）。
   touch-action:none = 手机上拖标签时不要顺手把页面滚走（拖的判定在 admin.js 里：
   8px 以内算点一下，超过才当拖动）。 */
.tag-mat { cursor: grab; -webkit-user-select: none; user-select: none; touch-action: none; }
.tag-mat .tag-no { font-size: 12px; color: #6b8ab0; }
.tag-mat.optional {
  color: #5b6673;
  background: #f4f6f8;
  border-color: #cdd5de;
  border-style: dashed;
}
.tag-mat.optional .tag-no { color: #8b95a1; }
.tag-mat.dragging {
  position: relative;
  z-index: 20;
  cursor: grabbing;
  opacity: .92;
  box-shadow: 0 10px 22px rgba(20, 80, 143, .28);
}

/* 松手会落在哪儿：一个虚线空位（宽高在拖动时按被拖的那个标签量出来） */
.tag-slot {
  flex: none;
  border: 1px dashed #9dbde4;
  border-radius: 999px;
  background: #eef5fd;
}

/* 手机上手指点得中：标签和 ✕ 都撑到 44px */
@media (max-width: 620px) {
  .tag { min-height: 44px; }
  .tag-x { width: 44px; height: 44px; }
}

/* ---------- 后台：审查提示词 ---------- */
.prompt-ver {
  flex: none;
  min-width: 34px;
  font-size: 14px;
  font-weight: 600;
  color: #14508f;
}

/* 提示词正文：16px 是 iOS 不会自动放大输入框的字号 */
.prompt-text {
  display: block;
  width: 100%;
  box-sizing: border-box;
  min-height: 240px;
  margin-top: 6px;
  padding: 10px;
  font-family: inherit;
  font-size: 16px;
  line-height: 1.6;
  color: #1f2937;
  background: #fff;
  border: 1px solid #cbd3dd;
  border-radius: 10px;
  resize: vertical;
}

/* 「看内容」展开的历史版本正文：只读，长句子要能折行 */
.prompt-view {
  margin: 0 0 8px;
  padding: 10px;
  font-size: 13px;
  line-height: 1.6;
  color: #3b4657;
  background: #f7f9fc;
  border: 1px solid #e3e8ef;
  border-radius: 10px;
  white-space: pre-wrap;
  word-break: break-all;
}
.prompt-view[hidden] { display: none; }

/* 手机上（窄屏）：版本历史那一行挤不下（说明 + 日期 + 两个按钮），
   让「说明」自己占一行，日期和按钮掉到下一行 —— 否则 v1 那条会折成三行、看着像错位。 */
@media (max-width: 620px) {
  #prompts .mat-row .mat-name { flex: 1 1 100%; }
}

/* ---------- 后台：归档体检 ---------- */
.health-ok {
  margin: 0 0 8px;
  padding: 8px 10px;
  font-size: 14px;
  line-height: 1.5;
  color: #17603a;
  background: #eaf7ef;
  border-radius: 10px;
}

.health-bad {
  margin: 0 0 8px;
  padding: 8px 10px;
  font-size: 14px;
  line-height: 1.5;
  color: #b42318;
  background: #fff2f0;
  border-radius: 10px;
}

.health-count { margin: 0 0 6px; font-size: 14px; font-weight: 600; color: #96601a; }

.health-fix {
  margin: 0 0 8px;
  font-size: 13px;
  line-height: 1.6;
  color: #5b6572;
}

.health-item {
  margin-bottom: 8px;
  padding: 8px 10px;
  border: 1px solid #dfe4ea;
  border-radius: 10px;
}

.health-what { font-size: 14px; font-weight: 600; line-height: 1.4; word-break: break-all; }
/* pre-line：明细里的案卷/路径/原因是用 \n 分行的，默认会把它们挤成一行 */
.health-where {
  margin-top: 2px;
  font-size: 12px;
  line-height: 1.5;
  color: #7a8594;
  word-break: break-all;
  white-space: pre-line;
}

.user-card .field { max-width: 320px; margin-bottom: 6px; }
.user-card .meta { font-size: 13px; color: #7a8594; }
.user-perms { margin-top: 6px; font-size: 13px; line-height: 1.5; color: #7a8594; }

.user-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }

.user-actions button {
  /* 手指点的东西：至少 44px 高，别做成 30px 的小药丸 */
  min-height: 44px;
  padding: 0 16px;
  font-size: 15px;
  color: #14508f;
  background: #e8f1fd;
  border: 1px solid #b9d4f2;
  border-radius: 10px;
}

.user-actions button.danger { color: #b42318; background: #fff2f0; border-color: #ffc7c2; }
.user-actions button:disabled { color: #9aa3ae; background: #f1f3f6; border-color: #dfe4ea; }

.card-note { margin-top: 8px; font-size: 14px; line-height: 1.5; color: #14508f; }
.card-note.error { color: #b42318; }
.card-note:empty { display: none; }

body.login .login-hint {
  margin: 12px 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: #7a8594;
  text-align: center;
}
/* 卡片里就地展开的一行（重置密码 / 删除确认）：不用弹窗，手机上看得清在改哪个账号 */
.inline-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.inline-row[hidden] { display: none; }
.inline-row .warn { flex: 1 1 100%; font-size: 14px; color: #b42318; }

.inline-row input {
  flex: 1 1 160px;
  min-width: 0;
  height: 42px;
  padding: 0 10px;
  font-size: 16px;
  color: #1f2937;
  background: #fff;
  border: 1px solid #cbd3dd;
  border-radius: 10px;
}

.inline-row button {
  min-height: 44px;
  padding: 0 16px;
  font-size: 15px;
  color: #14508f;
  background: #e8f1fd;
  border: 1px solid #b9d4f2;
  border-radius: 10px;
}

.inline-row button.primary { width: auto; margin-top: 0; color: #fff; background: #1a6fd4; border: 0; }
.inline-row button.danger { color: #b42318; background: #fff2f0; border-color: #ffc7c2; }

/* ---------- 后台：门店 / 业务类型 ---------- */
/* 一排一条：名字、已归入几卷、可用状态、停用/启用、删除 —— 复用材料清单那一套尺寸，
   手机上自动换行。停用的那一条压暗，一眼能看出来它只是「暂时不出现」。 */
.mat-item.off { background: #f7f9fc; }
.mat-item.off .mat-name { color: #7a8594; }

/* 业务类型多一行「归档年月来源」：发票日期 / 上传日期 两选一 */
.seg-row { padding-top: 0; }
.seg-label { flex: none; font-size: 12px; color: #7a8594; }

.seg {
  display: inline-flex;
  flex: none;
  overflow: hidden;
  border: 1px solid #cbd3dd;
  border-radius: 10px;
}

.seg button {
  /* 手指点的东西：至少 44px 高（和这一页其它按钮同一套尺寸） */
  min-height: 44px;
  padding: 0 12px;
  font-size: 14px;
  color: #14508f;
  background: #fff;
  border: 0;
  border-left: 1px solid #dfe4ea;
}

.seg button:first-child { border-left: 0; }
.seg button.selected { color: #fff; background: #1a6fd4; }
/* 材料清单的「必备 / 非必备」：2026-09-29 起不再是一颗按钮，改成标签本体
   （蓝底实心 = 必备，灰底虚框 = 非必备），样式在上面 .tag-mat 那一块。
   「说明」的编辑入口也从界面上撤了（业主选极简；说明与审查逻辑无关，
   接口 /api/admin/materials/{id}/note 与上传卡片上的展示都还留着）。 */

/* 配置版本历史（Plan B Task 7）：面板底下那个「历史版本」，默认收起 */
.hist-box { margin-top: 12px; }
.hist-toggle { min-height: 44px; }
.hist-list {
  margin-top: 8px;
  border-top: 1px solid #eef1f5;
}
.hist-item .mat-name { flex: 1 1 160px; }
.hist-item .mat-row { gap: 10px; }

/* 上传卡片：材料名对上后台写的说明时显示这一行（平时是空的，不占高度） */
.item .material-note { flex: 1 0 100%; font-size: 12px; line-height: 1.35; color: #7a8594; }
.item .material-note[hidden] { display: none; }
/* 「导出 Excel」那一条：搜索结果上方（Plan B Task 4）。尺寸和「搜索」按钮同一套，
   手机上手指点得中。 */
.export-bar { display: flex; gap: 8px; margin-bottom: 10px; }

.export-bar button {
  min-height: 44px;
  padding: 0 16px;
  font-size: 15px;
  color: #14508f;
  background: #e8f1fd;
  border: 1px solid #b9d4f2;
  border-radius: 10px;
}

.export-bar button:disabled { color: #9aa3ae; background: #f1f3f6; border-color: #dfe4ea; }

/* ---- 操作日志（Plan B Task 5）：只读的筛选 + 卡片式列表 ----
   2026-09-29 起日志默认**收起来**（业主：「操作日志太长，不需要展示，下载查看或者点击查看即可」）：
   面板上只留说明和一颗「点开查看日志」，点开才拉数据 —— 打开后台不再铺一屏日志。 */
.log-toggle-row { margin-bottom: 10px; }
.log-toggle-row button {
  flex: 0 0 auto;
  min-height: 44px;
  padding: 0 22px;
}
.log-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: flex-end;
  margin-bottom: 12px;
}
.log-filters .field { flex: 1 1 140px; min-width: 130px; }
.log-filters button {
  /* button.primary 默认是整行宽的（上传页那个「发送」）。这里是一排筛选条件里的
     一颗按钮，跟着输入框走就行，不然 PC 上会变成一条 1000px 宽的蓝条。 */
  flex: 0 0 auto;
  width: auto;
  margin-top: 0;
  min-height: 44px;
  height: 44px;
  padding: 0 22px;
}
.log-row {
  border: 1px solid #e3e7ee;
  border-radius: 8px;
  padding: 8px 10px;
  margin-bottom: 8px;
  background: #fff;
}
.log-row:last-child { margin-bottom: 0; }
.log-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.log-action {
  font-size: 13px;
  color: #14508f;
  background: #e8f1fd;
  border: 1px solid #b9d4f2;
  border-radius: 999px;
  padding: 2px 9px;
  white-space: nowrap;
}
.log-who { font-size: 14px; font-weight: 600; }
.log-time { font-size: 13px; color: #5b6572; font-variant-numeric: tabular-nums; }
.log-where { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 5px; }
.log-target {
  font-size: 13px;
  color: #333;
  font-family: Consolas, "Courier New", monospace;
  word-break: break-all;
}
.log-ip { font-size: 12px; color: #8a929d; }
.log-detail { font-size: 14px; color: #333; margin-top: 4px; word-break: break-word; }
.log-pager { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 12px; }
.log-pager button { min-height: 44px; min-width: 88px; }
.log-pager button:disabled { color: #9aa3ae; background: #f1f3f6; border-color: #dfe4ea; }
.log-pager span { font-size: 14px; color: #5b6572; }

/* ---- 一键备份 / 重建索引（Plan B Task 6）：一排操作按钮 ---- */
.op-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 10px; }
.op-row button {
  /* 和筛选栏那颗一样：button.primary 默认整行宽，这里要跟着内容走 */
  flex: 0 0 auto;
  width: auto;
  max-width: 100%;
  margin-top: 0;
}

/* ---- 审查设置：严格度三选一 + 用样图试跑（Plan B Task 8） ----
   「松紧」沿用业务类型那一套 .seg（44px 高，手机上点得中）。试跑结果比照「查看下载」的
   字号，手机上要能一行行读清楚；没结果时不占高度。 */
.try-result { margin-top: 12px; }
.try-result:empty { display: none; }
.try-result .reason { font-size: 14px; line-height: 1.5; color: #96601a; }
.try-result .hint { margin: 6px 0 0; }
/* 试跑那一排：「拍照 / 选一张图」不是主按钮，但必须是 44px 的手指点击区 ——
   手机端实测这两颗只有 23px 高（够不着）。「开始试跑」保持主按钮的样子。 */
#review-settings .op-row button {
  min-height: 44px;
  padding: 0 16px;
  font-size: 15px;
  color: #14508f;
  background: #e8f1fd;
  border: 1px solid #b9d4f2;
  border-radius: 10px;
}
#review-settings .op-row button.primary {
  color: #fff;
  background: #1a6fd4;
  border: 0;
}
#review-settings .try-note { margin-top: 10px; }
/* 「设置」面板里卡片内的警示句（例如「老图不会自己搬过去」）：红字，和 .hint 同一段落感 */
#review-settings .warn { margin: 0 0 10px; font-size: 14px; line-height: 1.5; color: #b42318; }
#review-settings .inline-row .seg-label { flex: none; }

