/* ============================================================
   绩效任务台账 · 样式层
   同一套 HTML，两套外壳：
     html[data-layout="mobile"]   手机端（底部标签栏 + 折行列表）
     html[data-layout="desktop"]  电脑端（左侧导航 + 对齐列表）

   设计基调：冷中性灰 + 深品牌蓝。数据型界面，靠「对齐 / 数字等宽 /
   层级用颜色而不是粗细 / 留白有节奏」来获得秩序感，而不是靠装饰。
   ============================================================ */

/* ---------- 1. 设计令牌 ---------- */

:root {
  /* 品牌蓝 */
  --blue: #185FA5;
  --blue-dark: #114A80;
  --blue-fill: #E9F1FA;
  --blue-line: #C3D9EE;

  /* 语义色：每个都配一个浅底 + 一条描边，标签才有形不散 */
  --red: #CF3B3E;
  --red-fill: #FCECEC;
  --red-line: #F2C8C9;

  --amber: #A96A0B;
  --amber-fill: #FCF2E1;
  --amber-line: #EEDAC0;

  --green: #3C7420;
  --green-fill: #EDF5E5;
  --green-line: #CBE1B6;

  /* 中性阶：冷灰。原来的暖米色偏「纸」，数据表格用冷灰更清爽、
     和蓝色也同族，不会互相打架 */
  --text: #1A1F26;
  --text-2: #4B5563;
  --muted: #8B94A0;
  --faint: #AEB6C0;

  --line: #E2E6EB;
  --line-soft: #EEF1F4;
  --bg: #F4F6F8;
  --bg-soft: #F8F9FB;
  --card: #FFFFFF;
  --hover: #F5F8FB;

  /* 形状 */
  --radius-sm: 6px;
  --radius: 10px;
  --radius-lg: 14px;

  --sh-1: 0 1px 2px rgba(16, 24, 40, .05);
  --sh-2: 0 1px 2px rgba(16, 24, 40, .04), 0 12px 28px -18px rgba(16, 24, 40, .18);
  --sh-3: 0 28px 64px -24px rgba(16, 24, 40, .30);

  --sidebar: 232px;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
}

/* ---------- 2. 基础与排版 ---------- */

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

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei",
    "PingFang SC", "Hiragino Sans GB", sans-serif;
  font-size: 14.5px;
  line-height: 1.55;
  /* 数字全部等宽：表格里的 0 / 100% 能一列对齐，扫描时不跳 */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-text-size-adjust: 100%;
}

html[data-layout="mobile"] body { overscroll-behavior-y: contain; }

.hidden { display: none !important; }
.spacer { flex: 1; }
.muted { color: var(--muted); font-size: 13px; }

h1 { font-size: 18px; font-weight: 650; margin: 0 0 3px; letter-spacing: -.01em; }
h2 { font-size: 14.5px; font-weight: 650; margin: 0 0 12px; letter-spacing: -.005em; }
h3 { font-size: 16.5px; font-weight: 650; margin: 0 0 14px; letter-spacing: -.01em; }
.sub { color: var(--muted); font-size: 13px; margin: 0; line-height: 1.5; }

/* 长段落限制每行字数：1440 宽下满行 150+ 字，眼睛会跳行 */
.wrap p, .card > p, .boardctl-tip { max-width: 92ch; }

::selection { background: #CFE2F5; }

/* ---------- 3. 通用组件 ---------- */

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 12px;
}

.field { margin-bottom: 12px; }
.field label { display: block; font-size: 12.5px; color: var(--muted); margin-bottom: 6px; }
.field label .req { color: var(--red); }

input[type=text], input[type=password], input[type=date], input[type=month],
input[type=number], select, textarea {
  width: 100%;
  padding: 8px 11px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-size: 14.5px;
  font-family: inherit;
  background: #fff;
  color: var(--text);
  min-height: 38px;
  transition: border-color .15s, box-shadow .15s, background .15s;
}
input::placeholder, textarea::placeholder { color: var(--faint); }
input:hover, select:hover, textarea:hover { border-color: #D3D9E0; }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(24, 95, 165, .13);
}
textarea { resize: vertical; min-height: 68px; line-height: 1.55; }
input[type=date], input[type=month] { min-height: 38px; }
select {
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238B94A0' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  padding-right: 32px;
}

.row { display: flex; gap: 10px; }
.row > * { flex: 1; min-width: 0; }

button {
  font-family: inherit;
  font-size: 14.5px;
  border-radius: var(--radius-sm);
  padding: 8px 15px;
  cursor: pointer;
  border: 1px solid var(--line);
  background: #fff;
  color: var(--text);
  min-height: 38px;
  transition: background .14s, border-color .14s, color .14s, box-shadow .14s;
}
button:hover { border-color: #D3D9E0; background: var(--bg-soft); }
button:active { transform: translateY(.5px); }
button:disabled { opacity: .5; cursor: not-allowed; }
button:disabled:hover { background: #fff; border-color: var(--line); }

.btn-primary { background: var(--blue); border-color: var(--blue); color: #fff; }
.btn-primary:hover { background: var(--blue-dark); border-color: var(--blue-dark); }
.btn-danger { background: var(--red); border-color: var(--red); color: #fff; }
.btn-danger:hover { background: #B53438; border-color: #B53438; }

.btn-sm { padding: 5px 11px; font-size: 13px; min-height: 30px; }

/* 「不可自审 / 不可自批」：做成「看得出这里本该有个按钮、但它是死的」的样子，
   免得用户以为是渲染漏了。全站只用在自审、自批这两处 */
.btn-off {
  display: inline-flex; align-items: center;
  padding: 5px 10px; min-height: 30px;
  font-size: 12.5px; white-space: nowrap;
  border-radius: var(--radius-sm);
  color: var(--muted); background: var(--bg-soft);
  border: 1px dashed var(--line);
  cursor: not-allowed; user-select: none;
}

.btn-link {
  border: none; background: none; color: var(--blue);
  padding: 3px 5px; font-size: 13px; min-height: 26px;
  border-radius: var(--radius-sm);
}
.btn-link:hover { background: var(--blue-fill); text-decoration: none; }

.btns { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }

/* 标签：加一条同色描边。纯色底的胶囊在浅背景上边界发虚，描边后干净很多 */
.tag {
  display: inline-block;
  font-size: 12px;
  line-height: 18px;
  padding: 0 8px;
  border-radius: 999px;
  white-space: nowrap;
  border: 1px solid transparent;
  font-weight: 500;
}
.tag-late { background: var(--red-fill); color: var(--red); border-color: var(--red-line); }
.tag-soon { background: var(--amber-fill); color: var(--amber); border-color: var(--amber-line); }
.tag-ok { background: var(--blue-fill); color: var(--blue); border-color: var(--blue-line); }
.tag-done { background: var(--green-fill); color: var(--green); border-color: var(--green-line); }
.tag-gray { background: #F2F4F7; color: var(--muted); border-color: #E4E8ED; }

.kv { font-size: 13.5px; margin-top: 8px; word-break: break-word; line-height: 1.6; }
.kv .k { color: var(--muted); }
.kv a { color: var(--blue); text-decoration: none; }
.kv a:hover { text-decoration: underline; }
.kv code {
  font-family: var(--mono); font-size: 12.5px;
  background: var(--bg-soft); border: 1px solid var(--line-soft);
  border-radius: 5px; padding: 1px 5px;
}
.divider { height: 1px; background: var(--line-soft); margin: 14px 0; }

.empty {
  color: var(--muted); text-align: center; padding: 40px 16px; font-size: 13.5px;
  line-height: 1.7;
}
.empty::before {
  content: ""; display: block; width: 34px; height: 34px; margin: 0 auto 12px;
  border: 1.5px dashed var(--line); border-radius: 50%;
}

.warnbox {
  background: var(--amber-fill); color: var(--amber);
  border: 1px solid var(--amber-line);
  border-radius: var(--radius-sm); padding: 10px 12px; font-size: 13px;
  line-height: 1.65; margin-bottom: 12px;
}
/* 派单页的「复制已有任务」条。刻意做得比 warnbox 淡：
   它是省事的入口，不是要读的警示 —— 抢了警告的注意力就本末倒置了 */
.copybar {
  background: var(--bg-soft); border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm); padding: 11px 12px; margin-bottom: 14px;
}
.copybar-row { display: flex; align-items: center; gap: 8px; }
.copybar-row label { flex: none; font-size: 13px; font-weight: 600; color: var(--text-2); }
.copybar-row select { flex: 1; min-width: 0; }
.copybar-row button { flex: none; }
.copybar #f-copyhint { margin: 8px 0 0; line-height: 1.65; }
.copybar #f-copyhint b { color: var(--text); }
/* 手机上 select 和按钮挤在一行会只剩几十像素，改成竖排三行 */
[data-layout="mobile"] .copybar-row { flex-direction: column; align-items: stretch; gap: 6px; }
[data-layout="mobile"] .copybar-row button { width: 100%; }
.errbox {
  background: var(--red-fill); color: var(--red);
  border: 1px solid var(--red-line);
  border-radius: var(--radius-sm); padding: 10px 12px; font-size: 13px;
  line-height: 1.65; margin-bottom: 12px;
}

/* 变更留痕与跨月提示 */
.changebox {
  margin-top: 10px; padding: 9px 12px;
  border-radius: var(--radius-sm); font-size: 13px; line-height: 1.6;
  background: var(--bg-soft); border: 1px solid var(--line-soft);
}
.changebox.pending {
  background: var(--amber-fill); border-color: var(--amber-line);
}
.changebox.pending b { color: var(--amber); }
.chgline { line-height: 1.45; }
.chgcut {
  color: var(--muted); font-size: 12.5px; line-height: 1.5; margin-top: 1px;
  word-break: break-word;
}
.chgfrom { text-decoration: line-through; opacity: .6; }
.chgto { color: var(--green); }
.carrybox {
  margin-top: 10px; padding: 10px 12px;
  border-radius: var(--radius-sm); font-size: 13px; line-height: 1.65;
  background: var(--blue-fill); border: 1px solid var(--blue-line); color: var(--text-2);
}
.carrybox b { color: var(--text); }

/* 任务卡（弹窗/派单页仍在用） */
.task-head { display: flex; align-items: flex-start; gap: 8px; }
.task-head .t { font-weight: 600; flex: 1; }
.owner { color: var(--muted); font-size: 13px; }

/* 验收标准清单：方框 + 文案。打过勾的变绿 */
.accept { margin: 6px 0 0; padding-left: 0; list-style: none; font-size: 13.5px; }
.accept li { padding: 2px 0 2px 18px; position: relative; }
.accept li::before {
  content: ""; position: absolute; left: 2px; top: 8px;
  width: 9px; height: 9px;
  border: 1.5px solid #C6CDD5; border-radius: 3px;
}
.accept li.yes::before { border-color: var(--green); background: var(--green); }

/* 弹窗 / 提示 */
.mask {
  position: fixed; inset: 0; background: rgba(16, 24, 40, .38);
  backdrop-filter: blur(2px);
  display: flex; align-items: center; justify-content: center;
  padding: 16px; z-index: 50;
}
.modal {
  background: #fff; border-radius: var(--radius-lg); padding: 20px;
  width: 100%; max-width: 480px;
  max-height: 88vh; overflow: auto;
  box-shadow: var(--sh-3);
  animation: pop .18s cubic-bezier(.2, .8, .3, 1);
}
@keyframes pop { from { opacity: 0; transform: translateY(10px) scale(.985); } }

.toast {
  position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%);
  background: #1A1F26; color: #fff; padding: 10px 18px;
  border-radius: 999px; font-size: 13.5px; z-index: 99; max-width: 90vw;
  box-shadow: 0 10px 30px -8px rgba(0, 0, 0, .4);
  animation: pop .18s cubic-bezier(.2, .8, .3, 1);
}

/* 表格（电脑端看板） */
table {
  width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px;
}
th, td {
  padding: 9px 10px; text-align: right;
  border-bottom: 1px solid var(--line-soft);
  white-space: nowrap;
}
th:first-child, td:first-child { text-align: left; }
thead th {
  color: var(--muted); font-weight: 500; font-size: 12.5px;
  position: sticky; top: 0; background: var(--card); z-index: 2;
  border-bottom: 1px solid var(--line);
  padding-top: 8px; padding-bottom: 8px;
}
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ---------- 看板大表（18 列）----------
   18 列摊在 1100px 里，默认渲染出来是一片同色的数字墙：
   半数格子是 0，几个关键结论混在中间。这里做三件事 ——
     ① 零值压暗、异常值上色（红色＝超期，琥珀＝延期/返工/补票）
     ② 组与组之间加竖线，把 18 列切成 6 段可读的块
     ③ 姓名列吸附在左侧，横向滚动时始终知道在看谁 */
table.board { font-size: 13px; }
.board td, .board th { border-bottom: 1px solid var(--line-soft); }
.board thead th { background: var(--bg-soft); }
.board th.grp { border-left: 1px solid var(--line); }
.board td.grp { border-left: 1px solid var(--line-soft); }

/* 每行一个不透明底色变量：隔行浅底 / 悬停 / 结论色块都靠它，
   吸附加粗的姓名列才能跟着一起变色 */
.board tbody tr { --row-bg: var(--card); }
.board tbody tr:nth-child(even) { --row-bg: #FBFCFD; }
.board tbody tr:hover { --row-bg: var(--hover); }
.board tbody tr.bad { --row-bg: var(--red-fill); }
.board tbody tr.good { --row-bg: var(--green-fill); }
.board tbody td { background: var(--row-bg); }

.board td.c-name, .board th.c-name {
  position: sticky; left: 0; z-index: 1;
  box-shadow: 1px 0 0 var(--line-soft);
}
.board thead th.c-name { z-index: 3; }

.board .z { color: var(--faint); }
.board .na { color: var(--faint); }
.board .od:not(.z) { color: var(--red); font-weight: 650; }
.board .am:not(.z) { color: var(--amber); font-weight: 650; }

/* 结论区（按期率 / 一次合格率 / 结论）：数字加大加粗，和左边 14 个计数拉开层级 */
.board td.key { font-weight: 650; font-size: 13.5px; }
.board td.key.na { font-weight: 400; font-size: 13px; }
.board td.key .tag { font-weight: 500; font-size: 12px; }
.board th.key { color: var(--text-2); font-weight: 600; }

/* 登录页 */
.loginform .field { margin-bottom: 14px; }
/* 手机上字号低于 16px 会被 iOS 自动放大整页，登录页尤其明显，这里顶到 16 */
.loginform input { font-size: 16px; }

/* 筛选药丸 */
.pill-row {
  display: flex; gap: 6px; margin-bottom: 4px;
  overflow-x: auto; padding-bottom: 4px;
}
.pill-row button {
  padding: 5px 13px; font-size: 13px; border-radius: 999px;
  white-space: nowrap; min-height: 32px; color: var(--text-2);
  border-color: var(--line);
}
.pill-row button:hover { background: var(--bg-soft); }
.pill-row button.on {
  background: var(--blue); color: #fff; border-color: var(--blue);
  font-weight: 500;
}
.pill-row button.on:hover { background: var(--blue-dark); }

.formgrid { display: block; }
.formgrid .field { margin-bottom: 12px; }

/* 看板控制区 */
.bctl-month { margin-bottom: 0; }
.bctl-btns { margin-bottom: 0; }
.inline-btns { display: flex; gap: 8px; }
.inline-btns button { flex: 1; }
.boardctl-tip {
  margin: 14px 0 0;
  padding: 11px 13px;
  background: var(--bg-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  font-size: 12.5px; line-height: 1.7; color: var(--text-2);
}
.boardctl-tip b { color: var(--text); }

/* ---------- 全员台账：筛选条 ---------- */

.ctlcard { padding: 14px 16px; }
.fbar { display: block; }
.fbar .field:last-child { margin-bottom: 0; }
/* 月份只需要放下「本月」两个字，原来给它 .95fr 会撑出一大片空的 */
[data-layout="desktop"] .fbar {
  display: grid;
  grid-template-columns: minmax(150px, .55fr) 132px minmax(260px, 1.6fr) auto;
  gap: 0 14px;
  align-items: end;
}
[data-layout="desktop"] .fbar .field { margin-bottom: 0; }
.fbar .inline-btns { flex-wrap: wrap; }
.fbar .inline-btns button { flex: 0 1 auto; }
[data-layout="desktop"] .fbar-btn .inline-btns button { flex: 1; white-space: nowrap; }
.fbar select, .fbar input { width: 100%; }
.fbar-month .inline-btns select,
.fbar-month .inline-btns input { flex: 1 1 0; min-width: 0; }

/* 手机端：月份与排序并排，搜索和按钮各占一整行 —— 否则筛选区比数据还高 */
[data-layout="mobile"] .fbar {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
[data-layout="mobile"] .fbar .field { margin-bottom: 0; }
[data-layout="mobile"] .fbar-q,
[data-layout="mobile"] .fbar-btn { grid-column: 1 / -1; }
[data-layout="mobile"] .fbar .inline-btns button { flex: 1; }

/* ---------- 全员台账：人名条 ---------- */

.chiptip { margin: 12px 0 8px; font-size: 12.5px; line-height: 1.6; }
.chipbar {
  display: flex; gap: 8px; overflow-x: auto;
  padding: 2px 0 6px;
  scrollbar-width: thin;
}
.chip {
  flex: none; display: flex; flex-direction: column; align-items: flex-start;
  justify-content: center; gap: 2px;
  min-height: 52px; padding: 8px 13px;
  border-radius: var(--radius); background: #fff;
  border: 1px solid var(--line);
  text-align: left; line-height: 1.35;
  transition: border-color .14s, background .14s, box-shadow .14s;
}
.chip:hover { border-color: #C9D5E2; background: var(--hover); }
.chip b { font-size: 13.5px; font-weight: 600; }
.chip-sub { font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.chip.on {
  border-color: var(--blue); background: var(--blue-fill);
  box-shadow: 0 0 0 2px rgba(24, 95, 165, .1);
}
.chip.on b { color: var(--blue); }
.chip .bad { color: var(--red); font-weight: 600; }

/* 汇总条：每个数一段，数字用深色 + 标签用灰，扫的时候先看到数 */
.allsum {
  margin-top: 14px; padding-top: 12px;
  border-top: 1px solid var(--line-soft);
  font-size: 13px; color: var(--muted);
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 2px 0;
}
.allsum b {
  font-size: 14px; color: var(--text); font-weight: 650;
  margin-left: 2px;
}
.allsum b.bad { color: var(--red); }
.allsum .sep { color: #D5DAE1; margin: 0 9px; }
.allsum .st-total b { font-size: 15px; }

.pcard-foot { margin-top: 12px; text-align: right; }
.pcard-name { padding: 0; font-size: 15px; font-weight: 650; color: var(--text); text-align: left; }
.pcard-name:hover { background: none; color: var(--blue); }

/* 看板规则卡：宽屏下两条并排。
   等分 4 列会把「待改进」这类词拆到下一行，2 列让每条独占一行；
   窗口窄了退回单列。 */
.rules-list { display: block; }
[data-layout="desktop"] .rules-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 28px;
}
[data-layout="desktop"] .rules-list .kv { min-width: 0; margin-top: 0; }
@media (max-width: 1200px) {
  [data-layout="desktop"] .rules-list { grid-template-columns: minmax(0, 1fr); }
}

/* 规则条文：左侧一条短竖线，比死板的圆点更贴合数据面板的气质 */
.rules-list .kv {
  position: relative; padding-left: 14px; font-size: 13.5px; line-height: 1.5;
}
.rules-list .kv::before {
  content: ""; position: absolute; left: 0; top: 7px;
  width: 3px; height: 13px; border-radius: 2px; background: var(--line);
}
.rules-list .kv b { color: var(--text); font-weight: 600; }

/* 只在某一端出现的元素 */
[data-layout="mobile"] .hide-mobile { display: none !important; }
[data-layout="desktop"] .hide-desktop { display: none !important; }

/* 界面形态切换 */
.seg {
  display: inline-flex; border: 1px solid var(--line);
  border-radius: var(--radius-sm); overflow: hidden; background: #fff;
}
.seg button {
  border: none; border-radius: 0; background: none;
  padding: 6px 14px; font-size: 13px; color: var(--text-2);
  border-right: 1px solid var(--line); min-height: 34px;
}
.seg button:last-child { border-right: none; }
.seg button:hover { background: var(--bg-soft); }
.seg button.on { background: var(--blue); color: #fff; }
.seg button.on:hover { background: var(--blue-dark); }

/* ============================================================
   4. 电脑端外壳
   ============================================================ */

[data-layout="desktop"] .shell {
  display: flex;
  align-items: stretch;
  min-height: 100vh;
}

[data-layout="desktop"] .sidebar {
  width: var(--sidebar);
  flex: none;
  background: var(--card);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}

[data-layout="desktop"] .brand {
  display: flex; align-items: center; gap: 10px;
  padding: 17px 16px 15px;
  border-bottom: 1px solid var(--line-soft);
  margin-bottom: 10px;
}
[data-layout="desktop"] .brand-mark {
  width: 28px; height: 28px; flex: none;
  border-radius: 8px; background: linear-gradient(160deg, #2075BE, var(--blue-dark));
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 13.5px; font-weight: 650;
  box-shadow: 0 2px 6px -2px rgba(24, 95, 165, .5);
}
[data-layout="desktop"] .brand-text {
  font-weight: 650; font-size: 14px; letter-spacing: -.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

[data-layout="desktop"] .sidenav {
  flex: 1; padding: 0 10px; display: flex; flex-direction: column; gap: 1px;
  overflow-y: auto;
}
[data-layout="desktop"] .sidenav-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%; text-align: left;
  border: none; background: none;
  padding: 9px 11px; border-radius: 8px;
  font-size: 13.5px; color: var(--text-2);
  min-height: 38px;
  position: relative;
  transition: background .13s, color .13s;
}
[data-layout="desktop"] .sidenav-item:hover { background: var(--bg-soft); }
[data-layout="desktop"] .sidenav-item.on {
  background: var(--blue-fill); color: var(--blue); font-weight: 600;
}
[data-layout="desktop"] .sidenav-item .ico { width: 18px; height: 18px; flex: none; }
[data-layout="desktop"] .sidenav-item .badge {
  margin-left: auto; min-width: 18px; padding: 0 5px;
  border-radius: 9px; background: var(--red); color: #fff;
  font-size: 11px; line-height: 18px; text-align: center; font-weight: 500;
}

[data-layout="desktop"] .side-foot {
  border-top: 1px solid var(--line-soft);
  padding: 13px 16px 16px;
  font-size: 13px;
}
[data-layout="desktop"] .side-foot .me { font-weight: 600; }
[data-layout="desktop"] .side-foot .me-role {
  color: var(--muted); font-weight: 400; font-size: 12px; margin-left: 6px;
}
[data-layout="desktop"] .side-btns { display: flex; gap: 12px; margin-top: 6px; }
[data-layout="desktop"] .side-btns .btn-link { padding: 0; min-height: auto; }
[data-layout="desktop"] .side-btns .btn-link:hover { background: none; text-decoration: underline; }

[data-layout="desktop"] .main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
[data-layout="desktop"] .pagehead {
  padding: 19px 28px 15px;
  border-bottom: 1px solid var(--line);
  background: rgba(244, 246, 248, .88);
  backdrop-filter: blur(8px);
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
}
[data-layout="desktop"] .pagehead .ph-text { min-width: 0; }
[data-layout="desktop"] .pagehead h1 { font-size: 19px; margin-bottom: 2px; }

/* 顶部的「刷新」：手动拉一次最新数据，不用去按浏览器的 F5 */
.ph-actions { display: flex; align-items: center; gap: 10px; flex: none; }
.refresh-at { color: var(--muted); font-size: 12.5px; white-space: nowrap; }
.ico-btn {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); background: var(--card); color: var(--text-2);
  border-radius: var(--radius-sm); padding: 6px 11px;
  font-size: 13px; font-family: inherit; line-height: 1; cursor: pointer;
  min-height: 32px;
  transition: border-color .14s, color .14s, background .14s;
}
.ico-btn:hover { border-color: var(--blue-line); color: var(--blue); background: var(--blue-fill); }
.ico-btn .ico { width: 15px; height: 15px; }
.ico-btn .ico-label { white-space: nowrap; }
.ico-btn:disabled { opacity: .6; cursor: default; }
/* 转一圈表示正在拉数据 —— 只在图标上转，文字不动 */
.ico-btn.spin .ico { animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
/* 内容区撑满可用宽度：窗口越宽，右侧越不该留空 */
[data-layout="desktop"] .wrap { padding: 20px 28px 56px; margin: 0; }

/* 设置页整页都是说明性文字，铺满超宽屏会一行一百多字、读起来跳行 ——
   收成阅读栏宽。数据型的台账 / 看板不受影响，仍然铺满。 */
[data-layout="desktop"] #view.view-settings { max-width: 1000px; }

/* 宽屏下表格加大内边距，18 列摊开后数字不至于挤成一团；
   窗口变窄则逐级收紧 —— 表头是 nowrap 的，内边距不改小会撑出横向滚动条。 */
[data-layout="desktop"] th,
[data-layout="desktop"] td { padding: 9px 12px; }
@media (max-width: 1500px) {
  [data-layout="desktop"] th,
  [data-layout="desktop"] td { padding: 9px 8px; }
}
@media (max-width: 1100px) {
  [data-layout="desktop"] table { font-size: 12px; }
  [data-layout="desktop"] th,
  [data-layout="desktop"] td { padding: 8px 6px; }
}
/* 看板那张 18 列的表，在 1280 这类笔记本宽度上只差几十像素就要横向拖动。
   不给它单独收一档，就得让同事左右拉着看 —— 能不滚就不滚。
   （表头是 nowrap 的，能省的地方只有内边距和字号。） */
@media (min-width: 1101px) and (max-width: 1400px) {
  [data-layout="desktop"] table.board { font-size: 12.5px; }
  [data-layout="desktop"] table.board th,
  [data-layout="desktop"] table.board td { padding: 8px 6px; }
  [data-layout="desktop"] .board td.key { font-size: 13px; }
}

[data-layout="desktop"] .formgrid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 0 14px;
}
[data-layout="desktop"] .fg-half { grid-column: span 3; }
[data-layout="desktop"] .fg-third { grid-column: span 2; }
[data-layout="desktop"] .fg-full { grid-column: 1 / -1; }

[data-layout="desktop"] .row.boardctl { align-items: flex-end; }
[data-layout="desktop"] .bctl-month { flex: 0 0 190px; }
[data-layout="desktop"] .bctl-btns { flex: 1; }
[data-layout="desktop"] .inline-btns button { flex: 0 0 auto; }
[data-layout="desktop"] .inline-btns button { min-height: 38px; }

[data-layout="desktop"] .card { box-shadow: var(--sh-1); }
[data-layout="desktop"] .modal { max-width: 520px; }
[data-layout="desktop"] .toast { bottom: 34px; }

/* ============================================================
   5. 手机端外壳
   ============================================================ */

[data-layout="mobile"] .topbar {
  position: sticky; top: 0; z-index: 20;
  background: rgba(255, 255, 255, .94);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
  padding: 8px 14px;
  display: flex; align-items: center; gap: 4px;
  padding-top: calc(8px + env(safe-area-inset-top));
}
[data-layout="mobile"] .topbar .org {
  font-weight: 650; font-size: 15px; letter-spacing: -.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
[data-layout="mobile"] .topbar .who {
  color: var(--muted); font-size: 12.5px;
  max-width: 76px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
[data-layout="mobile"] .topbar .ico-btn {
  border: none; background: none; color: var(--blue);
  padding: 4px; display: flex; align-items: center; justify-content: center;
  width: 40px; min-height: 44px;
}
[data-layout="mobile"] .topbar .ico-btn:hover { background: var(--blue-fill); }
[data-layout="mobile"] .topbar .ico-btn .ico { width: 20px; height: 20px; }
/* 顶栏的「退出」是纯文字链接，默认高度只有 32px —— 手机上点不准，撑到 36px */
[data-layout="mobile"] .topbar .btn-link {
  min-height: 36px;
  display: inline-flex; align-items: center;
  padding: 0 6px;
}

[data-layout="mobile"] .wrap {
  max-width: none;
  padding: 12px 12px calc(92px + env(safe-area-inset-bottom));
}

[data-layout="mobile"] .tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  display: flex;
  background: rgba(255, 255, 255, .97);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
}
[data-layout="mobile"] .tab {
  flex: 1; border: none; background: none;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 8px 2px 7px;
  color: var(--muted); font-size: 11px;
  border-radius: 0;
  min-height: 56px;
}
[data-layout="mobile"] .tab:hover { background: none; }
[data-layout="mobile"] .tab .tab-ico { position: relative; display: flex; }
[data-layout="mobile"] .tab .ico { width: 22px; height: 22px; }
[data-layout="mobile"] .tab.on { color: var(--blue); }
[data-layout="mobile"] .tab.on .tab-label { font-weight: 650; }
[data-layout="mobile"] .tab .badge {
  position: absolute; top: -4px; right: -8px;
  min-width: 16px; padding: 0 4px; border-radius: 8px;
  background: var(--red); color: #fff;
  font-size: 10px; line-height: 16px; text-align: center;
}

/* 手机端：一切单列、加大触控面积 */
[data-layout="mobile"] .row { flex-direction: column; gap: 0; }
[data-layout="mobile"] .row.row-inline { flex-direction: row; gap: 8px; }

[data-layout="mobile"] input[type=text],
[data-layout="mobile"] input[type=password],
[data-layout="mobile"] input[type=date],
[data-layout="mobile"] input[type=month],
[data-layout="mobile"] input[type=number],
[data-layout="mobile"] select,
[data-layout="mobile"] textarea {
  font-size: 16px;          /* iOS 聚焦时不放大页面 */
  padding: 10px 12px;
  min-height: 46px;
}
[data-layout="mobile"] button { min-height: 44px; }
[data-layout="mobile"] .btn-sm { min-height: 38px; }
[data-layout="mobile"] .btn-off { min-height: 34px; }
[data-layout="mobile"] .btn-link { min-height: 36px; }

[data-layout="mobile"] .btns { gap: 8px; }
[data-layout="mobile"] .btns > button { flex: 1; }

[data-layout="mobile"] .card { padding: 14px; border-radius: var(--radius); }
[data-layout="mobile"] .kv { font-size: 14px; }
[data-layout="mobile"] .accept { font-size: 14px; }
[data-layout="mobile"] h1 { font-size: 17px; }
[data-layout="mobile"] h2 { font-size: 14px; }

[data-layout="mobile"] .loginform input { min-height: 46px; }

[data-layout="mobile"] .mask { padding: 0; align-items: flex-end; }
[data-layout="mobile"] .modal {
  max-width: none;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  max-height: 92vh;
  padding: 20px 16px calc(24px + env(safe-area-inset-bottom));
  animation: sheet .22s cubic-bezier(.2, .8, .3, 1);
}
@keyframes sheet { from { transform: translateY(30px); opacity: .6; } }
[data-layout="mobile"] .modal::before {
  content: ""; display: block;
  width: 38px; height: 4px; border-radius: 2px;
  background: #D8DDE4; margin: -8px auto 16px;
}

[data-layout="mobile"] .toast { bottom: calc(88px + env(safe-area-inset-bottom)); }

/* ============================================================
   6. 看板：手机端人物卡
   ============================================================ */

.pcard { padding: 15px; }
.pcard.bad { border-color: var(--red-line); background: #FFFCFC; }
.pcard.good { border-color: var(--green-line); background: #FCFEF9; }

.pcard-head { display: flex; align-items: center; gap: 8px; margin-bottom: 2px; }
.pcard-name { font-weight: 650; flex: 1; }

/* 两个比率是这张卡的主角：给它们一个比周围略深的底，视线先落在这里 */
.rate-row { display: flex; gap: 10px; margin-top: 13px; }
.rate {
  flex: 1; background: var(--bg-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm); padding: 9px 12px;
  display: flex; flex-direction: column; gap: 1px;
}
.rate b {
  font-size: 21px; font-weight: 650; line-height: 1.15; letter-spacing: -.02em;
}
.rate span { color: var(--muted); font-size: 11.5px; }

/* 14 个明细指标：3 列，靠底色交替分组，零值自动变浅 */
.metrics {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 1px; margin-top: 13px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.metric { text-align: center; padding: 8px 4px; background: var(--card); }
.metric b {
  display: block; font-size: 15px; font-weight: 650; line-height: 1.3;
  letter-spacing: -.01em;
}
.metric b.z { color: var(--faint); font-weight: 500; }
.metric span { color: var(--muted); font-size: 11px; }

/* ============================================================
   7. 任务横向列表（核心版式）
   ------------------------------------------------------------
   一条任务占一行。宽屏列与列对齐、内容多的单元格自己撑高；
   窄屏同一行折行、每个单元格自带标签 —— 仍比卡片省一半以上高度。

   这一次的调整重点：把「宽了也没用的列」让给「写得长的列」，
   并给每个单元格的内容设上限 —— 行高由最长的格子决定，
   不设上限的话，4 条验收标准就能把一行撑到 200px。
   ============================================================ */

.card.listcard { padding: 0; overflow: hidden; }
.tlist { font-size: 13.5px; }

.trow {
  display: flex; flex-wrap: wrap;
  gap: 3px 16px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--line-soft);
  align-items: flex-start;
}
.trow:last-child { border-bottom: none; }
.trow.th { display: none; }

.tc { min-width: 0; word-break: break-word; line-height: 1.5; }
.tc.nw { white-space: nowrap; }
.tname { font-weight: 600; }
/* 任务名最多两行：标题再长也不该把整行撑开 */
.tc-t .tname {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
/* 交付物：最多三行，超出省略；完整内容鼠标悬停可看，或打开「修改」 */
.deliv {
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}
.sub2 { display: block; color: var(--muted); font-size: 12.5px; line-height: 1.5; margin-top: 2px; }

/* 验收标准：每条压成一行。8 条标准铺开能撑到 170px，这是行高失控的主因；
   每条一行 + 悬停看全文，行高立刻可控 */
.tc .accept { margin: 0; font-size: 13px; }
.tc .accept li {
  padding: 2px 0 2px 16px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tc .accept li::before { top: 8px; width: 8px; height: 8px; border-radius: 2px; }
.tc .changebox { margin-top: 0; padding: 7px 10px; }
.lk { word-break: break-all; }
.lk a { color: var(--blue); text-decoration: none; }
.lk a:hover { text-decoration: underline; }
.rvline { display: flex; gap: 8px; flex-wrap: wrap; align-items: baseline; }
.rvline b { font-weight: 650; }
/* 审核意见只给一行：这一格是「提交与审核」的摘要，不是正文。
   必须写 display:-webkit-box，否则 -webkit-line-clamp 完全不生效 ——
   少那一行的话，一条 20 字的意见就能把这格从 20px 撑到 147px */
.rvcomment {
  display: -webkit-box;
  -webkit-line-clamp: 1; -webkit-box-orient: vertical;
  overflow: hidden; flex: 1 1 100%; min-width: 0;
}

/* 操作列：按钮两两并排。
   原来列只有 92px，4 个按钮只能一竖溜排下来 —— 光按钮就 110px 高，
   成了整行的地板。给到 136px 后两个一行，降到 ~53px。 */
.tc-act {
  display: flex; flex-wrap: wrap; gap: 3px 5px;
  align-items: center; align-content: flex-start;
}
.tc-act button { flex: 0 0 auto; }
.tc-act .btn-sm { padding: 3px 7px; font-size: 12px; min-height: 25px; }
.tc-act .btn-link { padding: 3px 5px; font-size: 12px; min-height: 25px; }

/* --- 窄屏（手机）：折行 + 单元格自带标签 --- */
@media (max-width: 899px) {
  .trow .tc::before {
    content: attr(data-k) '：';
    color: var(--muted); font-size: 12px; margin-right: 2px;
  }
  .trow .tc-t::before, .trow .tc-act::before { content: none; }
  /* 「状态：」和紧随其后的标签要在同一行 —— 单元格里的标签是块级元素，
     直接放的话标签会另起一行，只剩一个孤零零的「状态：」 */
  .trow .tc.nw { display: flex; flex-wrap: wrap; align-items: baseline; gap: 3px 6px; }
  .trow .tc.nw::before { flex: none; }
  .trow .tc.nw .tagrow { display: flex; flex-wrap: wrap; gap: 4px 5px; margin-bottom: 0; }
  .trow .tc.nw .sub2 { flex: 1 0 100%; margin-top: 1px; }
  /* 长内容独占一行；短值（.nw）并排，省高度 */
  .trow .tc:not(.nw):not(.tc-t):not(.tc-act) { flex: 1 1 100%; }
  /* 手机上按钮竖排、压满整行，指头点得准 */
  .tc-act { flex-direction: column; align-items: stretch; gap: 5px; }
  .tc-act button { width: 100%; }
  /* 手机上不必截断：整页本来就能滚，看全比看齐更重要 */
  .tc-t .tname, .deliv, .tc .accept li { -webkit-line-clamp: none; overflow: visible; white-space: normal; }
  .tc-t .tname { display: block; }
  .deliv { display: block; }
  .trow { gap: 4px 12px; padding: 13px 14px; }
}

/* --- 宽屏（电脑）：列对齐成表格 --- */
@media (min-width: 900px) {
  .trow {
    display: grid; gap: 0 14px;
    padding: 12px 16px; align-items: start;
  }
  /* 隔行浅底 + 悬停高亮：列多的时候靠底色跟住行 */
  .tlist .trow:not(.th) { background: var(--card); }
  .tlist .trow:nth-child(odd):not(.th) { background: #FBFCFD; }
  .tlist .trow:hover:not(.th) { background: var(--hover); }
  .trow .tc::before { content: none; }

  /* 表头 */
  .trow.th {
    display: grid; align-items: center;
    padding: 9px 16px;
    color: var(--muted); font-size: 12.5px; font-weight: 500;
    border-bottom: 1px solid var(--line);
    background: var(--bg-soft);
  }

  /* 列宽：短列给固定值（够放下就够），长列给 fr（窗口越宽长得越多）。
     两个坑：① 原来「变更」拿最大的 1.25fr、「交付物」只有 .85fr，正好给反了；
     ② 「操作」给得太窄，4 个按钮只能一竖溜排下来，成了整行的地板。 */
  .tlist.v-mine .trow {
    grid-template-columns:
      minmax(118px, 1.15fr)       /* 任务 */
      90px                        /* 状态 */
      minmax(92px, .95fr)         /* 交付物 */
      minmax(98px, 1.3fr)         /* 验收标准 */
      minmax(92px, .95fr)         /* 进展 */
      minmax(84px, .85fr)         /* 提交与审核 */
      minmax(76px, .75fr)         /* 变更 */
      136px;                      /* 操作：够两个按钮一行 */
  }
  .tlist.v-all .trow {
    grid-template-columns:
      minmax(106px, 1.05fr)       /* 任务 */
      66px                        /* 责任人 */
      90px                        /* 状态 */
      minmax(86px, .92fr)         /* 交付物 */
      minmax(94px, 1.25fr)        /* 验收标准：最长的列，给最大的权重 */
      minmax(86px, .92fr)         /* 进展 */
      minmax(78px, .8fr)          /* 提交与审核 */
      minmax(74px, .74fr)         /* 变更 */
      136px;                      /* 操作 */
  }
  .tlist.v-change .trow {
    grid-template-columns: minmax(140px, 1.3fr) 80px 82px 86px minmax(170px, 1.5fr)
      minmax(140px, 1.3fr) 96px;
  }
  .tlist.v-brief .trow {
    grid-template-columns: minmax(220px, 1.8fr) 92px 104px 100px 116px;
  }

  /* 窗口窄到摊不开时表格内部会横向滚动 —— 「操作」列吸附在右侧，
     滚动过程中按钮始终看得见、点得到 */
  .tlist .trow .tc-act {
    position: sticky; right: 0; background: inherit; z-index: 1;
  }
  .tlist .trow.th .tc-act { background: var(--bg-soft); }
  /* 单元格里的变更信息不再做成色块：窄列里色块会挤成一条细长条 */
  .tc .changebox {
    padding: 0; background: none; border: none; border-radius: 0; font-size: 12.5px;
  }
  .tc .changebox b { color: var(--text); }
  .tc .changebox.pending b { color: var(--amber); }
  /* 变更信息逐行截断：理由随手动辄二三十个字，不截断单这一格就能撑到 200px */
  .tc .chgline {
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .tc .chgcut { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* 变更审核列表：「原值 → 新值」两行各自最长能到 160 字，原样铺开会单格撑到 190px；
     列表里只看摘要（悬停有全文），完整内容在「处理申请」弹窗里 */
  .tc .chgfrom, .tc .chgto {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-size: 12.5px;
  }
  .tc .chgreason {
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 12.5px;
  }
  .trow .lk { font-size: 12.5px; }
  .trow .accept { font-size: 12.5px; }
}

/* 笔记本宽度（≤1180）再收一档：列宽、字号、间隙全缩一号，
   否则 9 列在这个宽度下必然撑出横向滚动 */
@media (min-width: 900px) and (max-width: 1180px) {
  .tlist { font-size: 12.5px; }
  .trow { gap: 0 9px; padding: 11px 12px; }
  .trow.th { padding: 8px 12px; font-size: 12px; }
  .sub2 { font-size: 11.5px; }
  .tlist.v-mine .trow {
    grid-template-columns: minmax(104px, 1.1fr) 78px minmax(78px, .9fr) minmax(84px, 1.25fr)
      minmax(78px, .9fr) minmax(70px, .8fr) minmax(64px, .72fr) 110px;
  }
  .tlist.v-all .trow {
    grid-template-columns: minmax(92px, 1fr) 58px 78px minmax(72px, .88fr)
      minmax(78px, 1.2fr) minmax(72px, .88fr) minmax(64px, .76fr) minmax(60px, .7fr) 110px;
  }
  .tlist.v-change .trow {
    grid-template-columns: minmax(120px, 1.3fr) 72px 74px 76px minmax(140px, 1.5fr)
      minmax(120px, 1.3fr) 88px;
  }
  .tc-act .btn-sm, .tc-act .btn-link { font-size: 11.5px; padding: 3px 5px; }
}

/* 电脑端隐藏移动端专用块，反之亦然 */
[data-layout="desktop"] .only-mobile { display: none !important; }
[data-layout="mobile"] .only-desktop { display: none !important; }

/* ============================================================
   8. 每日进展
   ------------------------------------------------------------
   列表里每个单元格都很窄，进展只能给「最近两条 + 条数」；
   完整时间线放在弹窗里（写进展 / 审核时看）。 */
.tc-prog { font-size: 13px; }
/* 状态列可能有两个标签（状态 + 「每日」），要能自己折行 */
.tagrow { display: flex; flex-wrap: wrap; gap: 4px 5px; margin-bottom: 3px; }
.progline {
  display: flex; align-items: baseline; gap: 6px;
  line-height: 1.5; margin-bottom: 1px;
}
/* 文本自己截断，标签/署名不参与省略 —— 整行 nowrap 会把「卡点」吞掉 */
.progtxt {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.progline .tag { flex: none; }
/* 进展列里每条前面的日期小标 */
.progday {
  flex: none;
  display: inline-block; padding: 0 5px;
  border-radius: 5px; background: var(--blue-fill); color: var(--blue);
  font-size: 11.5px; line-height: 17px; font-weight: 500;
}
.progwho { flex: none; color: var(--muted); font-size: 11.5px; }
/* 「今日未更新」是催办信号，不是惩罚：用浅底胶囊 + 小字，不铺满底色 */
.stale {
  display: inline-block; margin-bottom: 4px;
  padding: 0 8px; border-radius: 999px;
  background: var(--red-fill); color: var(--red);
  border: 1px solid var(--red-line);
  font-size: 12px; font-weight: 500; line-height: 18px;
}

/* 进度落后于约定的按钮：给它一点紧迫感，但仍然点得到 */
.btn-urgent { border-color: var(--amber-line); color: var(--amber); background: var(--amber-fill); }
.btn-urgent:hover { border-color: var(--amber); background: var(--amber-fill); }

/* 关键任务未更新的提示条 */
.carrybox.stalebox { background: var(--red-fill); border-color: var(--red-line); }
.carrybox.stalebox b { color: var(--red); }

/* 期初欠账提示条：用琥珀色。它要看得见，但必须和「今天没写进展」的红色分开 ——
   这笔债仍然算在原来的月份里、不进本月分母，是背景信息，不是扣分项 */
.carrybox.debtbox { background: var(--amber-fill); border-color: var(--amber-line); }
.carrybox.debtbox b { color: var(--amber); }
.debtwho {
  margin-top: 7px; padding-top: 7px; border-top: 1px dashed var(--amber-line);
  font-size: 12.5px; color: var(--text-2); line-height: 1.7; word-break: break-word;
}
.debtwho b { color: var(--amber); }

/* 看板指标里的警示项 */
.metric.warn { background: var(--red-fill); }
.metric.warn b { color: var(--red); }

/* 勾选项（派单选「关键任务」、写进展勾「有卡点」） */
.chk {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 11px 12px; margin-bottom: 12px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg-soft); font-size: 13.5px; line-height: 1.6;
  cursor: pointer; transition: border-color .14s, background .14s;
}
.chk:hover { border-color: var(--blue-line); background: var(--blue-fill); }
.chk input { width: 17px; height: 17px; margin-top: 2px; flex: none; accent-color: var(--blue); }
.chk span { min-width: 0; }

/* 设置页 · 消息推送：事件勾选排成自适应多列，窄屏自动退成一列 */
.chkgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(228px, 1fr));
  gap: 6px 10px;
}
[data-layout="mobile"] .chkgrid { grid-template-columns: 1fr; }

/* 推送结果小行：时间 / 事件 / 结果 三栏对齐 */
.plog { margin-top: 10px; display: flex; flex-direction: column; gap: 2px; }
.plogrow {
  display: grid;
  grid-template-columns: 142px 96px 1fr;
  gap: 10px;
  align-items: baseline;
  padding: 6px 10px;
  background: var(--bg-soft);
  border-radius: var(--radius-sm);
  font-size: 12.5px;
}
.plogrow .lk { font-weight: 600; }
.plog-ok { color: var(--green); }
.plog-bad { color: var(--red); }
[data-layout="mobile"] .plogrow { grid-template-columns: 1fr; gap: 2px; }

/* 人员名单的一行：上行是姓名/账号/角色，下行是口令状态与操作 ——
   挤在一行里「重置换口令」「看初始口令」「删除」会跟输入框抢宽度 */
.prow {
  padding: 10px 12px; margin-bottom: 8px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg-soft);
}
.prow .psub {
  display: flex; align-items: center; flex-wrap: wrap; gap: 4px 12px;
  margin-top: 8px; padding-top: 8px;
  border-top: 1px solid var(--line-soft);
  font-size: 12px;
}
.prow .psub .stale { margin-bottom: 0; }

/* 初始口令展示：要一眼看清、方便手抄或复制，所以给等宽字体和大字号 */
.pwdbox {
  font-family: var(--mono);
  font-size: 26px; letter-spacing: 5px; text-align: center;
  padding: 15px 12px; margin: 6px 0 2px;
  border: 1px dashed var(--blue-line); border-radius: var(--radius);
  background: var(--blue-fill); color: var(--blue-dark);
  user-select: all; word-break: break-all; font-weight: 600;
}

/* 进展时间线 */
.timeline { max-height: 46vh; overflow-y: auto; }
/* 时间线按「天」分组：每天一个小标题 */
.tlday { margin-bottom: 2px; }
.tldayhead {
  display: flex; align-items: baseline; gap: 8px;
  margin: 14px 0 2px; padding-bottom: 5px;
  border-bottom: 1px solid var(--line);
}
.tlday:first-child .tldayhead { margin-top: 2px; }
.tldaylab { font-weight: 650; font-size: 13.5px; }
.tldayhead .sub2 { font-size: 12px; margin-top: 0; }
.tlitem { padding: 10px 0; border-bottom: 1px solid var(--line-soft); }
.tlitem:last-child { border-bottom: none; }
.tlhead {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  margin-bottom: 5px; font-size: 12.5px;
}
.tlhead b { font-weight: 600; font-family: var(--mono); font-size: 12px; color: var(--text-2); }
.tlhead .btn-link { padding: 0; font-size: 12px; color: var(--muted); }
.tlhead .btn-link:hover { color: var(--red); background: none; text-decoration: underline; }
.tltext { font-size: 14px; line-height: 1.6; word-break: break-word; }

/* 手机上时间线不用限高：整页本来就能滚，套一层内部滚动反而难滑 */
[data-layout="mobile"] .timeline { max-height: none; }

/* ============================================================
   9. 可访问性与动效
   ============================================================ */

:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
button:focus-visible { outline-offset: 1px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* 细滚动条：默认的粗灰条在浅色面板上很扎眼 */
.scroll-x::-webkit-scrollbar, .chipbar::-webkit-scrollbar { height: 8px; }
.scroll-x::-webkit-scrollbar-thumb, .chipbar::-webkit-scrollbar-thumb {
  background: #D5DAE1; border-radius: 4px;
}
.scroll-x::-webkit-scrollbar-track, .chipbar::-webkit-scrollbar-track { background: transparent; }
.scroll-x::-webkit-scrollbar-thumb:hover, .chipbar::-webkit-scrollbar-thumb:hover { background: #C2C9D2; }
