:root{
  --bg:#f4f5f7; --card:#fff; --ink:#15171c; --sub:#6b7280; --line:#e3e6ea;
  --blue:#2563eb; --green:#059669; --amber:#d97706; --red:#dc2626;
  --purple:#7c3aed; --slate:#475569;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{background:var(--bg);color:var(--ink);
  font:14px/1.6 -apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",
  "Hiragino Sans GB","Heiti SC",sans-serif;
  -webkit-text-size-adjust:100%}
button,input,select,textarea{font:inherit;color:inherit}
button{cursor:pointer}
a{color:var(--blue)}
.hide{display:none!important}

/* ══════════ 顶栏 ══════════ */
.top{background:#15171c;color:#fff;padding:9px 18px;display:flex;align-items:center;
  gap:12px;flex-wrap:wrap;position:sticky;top:0;z-index:40}
.top .logo{display:flex;align-items:center;gap:8px;white-space:nowrap;
  font-size:15px;font-weight:700;letter-spacing:-.2px}
/* 品牌：蓝底白字，圆角
   ★ 2026-10-08 第 46 轮：字改成「Jooydoo」+ 小图标（老板要求跟桌面图标统一）。
     图标是蓝底白字的方图，直接贴进蓝底块里会糊成一片蓝 —— 所以做成小圆角方块，
     加一圈浅描边把图标的白边从蓝底里"抠"出来。 */
.top .brand{background:var(--blue);color:#fff;font-weight:800;
  padding:3px 11px;border-radius:7px;letter-spacing:.5px;
  box-shadow:0 1px 0 rgba(0,0,0,.18);
  display:inline-flex;align-items:center;gap:6px}
.top .brandico{width:16px;height:16px;border-radius:4px;display:block;
  box-shadow:0 0 0 1px rgba(255,255,255,.55)}
.top .dot{color:#60a5fa;font-weight:800;margin:0 -3px}
/* 标题：黑底白字 */
.top .ttl{color:#fff;font-weight:700;letter-spacing:.2px}
/* 姓名 部门：不占地方，靠右一点点 */
.top .who{font-size:12.5px;color:#cbd5e1;margin-left:14px;font-weight:500}
.top .who .r{color:#94a3b8;margin-left:6px}
.top .sp{flex:1}
.btn{border:0;border-radius:8px;padding:8px 14px;font-weight:600;font-size:13px;
  background:#2c3038;color:#fff;transition:.15s;white-space:nowrap}
.btn:hover{background:#3a3f49}
.btn.pri{background:var(--blue)}.btn.pri:hover{background:#1d4ed8}
.btn.g{background:var(--green)}.btn.g:hover{background:#047857}
.btn.gh{background:transparent;border:1px solid #4b5563}
.btn.gh:hover{background:#2c3038}
.btn.sm{padding:5px 11px;font-size:12px;border-radius:7px}
.btn:disabled{opacity:.5;cursor:not-allowed}

/* ══════════ 右上角「更多」折叠菜单 ══════════
   ★ 2026-09-20 老板要求：右上角按钮太多，把不常用的（导出/导入旧看板/
     改密码/退出）收进「更多」，平时就一个「更多」挂着。

   写法照抄系统里已有的两个浮层（.asgpop 选执行人、.calpop 选日期）：
   容器 position:relative + 面板绝对定位 + .on 类控制显隐 + 点外面关闭。
   这样三个浮层行为一致，以后要改一起改。

   ★ 为什么用 right:0 而不是 left:0：
     它挂在工具栏最右边，面板宽 150px 左右。
     要是 left:0 往右展开，手机上会顶出屏幕外。贴右对齐才稳。 */
.more{position:relative;display:inline-block}
.more .caret{font-size:10px;opacity:.75;display:inline-block;
  transition:transform .15s;margin-left:1px}
.more.on .caret{transform:rotate(180deg)}
.morepop{position:absolute;right:0;top:calc(100% + 6px);z-index:65;display:none;
  min-width:152px;background:#fff;border:1px solid #e3e6ea;border-radius:12px;
  box-shadow:0 12px 34px rgba(15,17,21,.18);overflow:hidden;padding:5px}
.morepop.on{display:block;animation:fadein .13s ease}
/* 菜单项：做成整行可点，比小按钮好按（手机上也够大） */
.morepop .mi{display:flex;align-items:center;width:100%;text-align:left;border:0;background:transparent;
  font-family:inherit;font-size:13.5px;font-weight:600;color:#1f2937;
  padding:9px 12px;border-radius:8px;cursor:pointer;white-space:nowrap}
/* ★ 2026-10-24 第 73 轮（老板要求）：菜单项统一成「左边一个图标，右边文字」。
   原来很不齐：「导出 / 导入旧看板 / 改密码 / 退出」是纯文字没有图标，
   「增加新人」写的是 "+"，「人员管理」是 ⚙（文字符号，宽度和 emoji 不一样），
   剩下的才是 emoji —— 混在一起左边缘参差，看着就是没整理过。
   这里把图标单独包一层 .ic：固定 20px 宽、居中、字号固定，
   文字进 .lb 统一字号；图标列宽一致，所以每条的文字左边缘都对齐。
   ★ 用 margin-right 而不是 flex 的 gap：老一点的手机浏览器对 gap 支持不齐，
     这条菜单手机上每天要点，宁可保守。 */
.morepop .mi .ic{flex:0 0 20px;width:20px;margin-right:9px;text-align:center;
  font-size:14px;line-height:1;font-weight:400}
.morepop .mi .lb{flex:1 1 auto;min-width:0}
.morepop .mi:hover{background:#f1f5f9}
/* ★ 第 68 轮：「使用指南」用 <a> 做菜单项 —— 去掉了下划线，颜色跟旁边一致 */
.morepop a.mi{text-decoration:none;color:#1f2937}
/* ★ 2026-10-25 第 80 轮：「设计部任务」对没权限的部门（财务/人事/仓库…）
   也可以看见，但点不动 —— 老板要求「无法点击进入，显示无权限」。
   灰掉 + 禁用手势，点一下由 app.js 弹 toast 说明原因。 */
.morepop .mi.na{color:#9aa4b2;cursor:not-allowed}
.morepop .mi.na:hover{background:#f8fafc}
.morepop .mi.na .ic{opacity:.55}
.morepop .mi.danger{color:#dc2626}
.morepop .mi.danger:hover{background:#fef2f2}
/* 分隔线：把「改密码/退出」跟上面两个数据操作分开 */
.morepop .mline{height:1px;background:#f1f5f9;margin:5px 6px}

/* ══════════ ★ 2026-10-25 第 82 轮：员工视角的菜单顺序 ══════════
   老板要求：「其他人页面显示的顺序是 产品采购负责人、设计部任务、
   使用指南、我的账号、改密码、退出」。
   ★ 这套顺序跟乔总的不一样（乔总那边 使用指南 在 设计部任务 前面），
     一套 DOM 排不出两套顺序 → 员工视角给 .morepop 挂 .staff，
     用 order 重排。order 只影响视觉顺序，DOM 和事件绑定一点都不动。
   ★ 选择器写 .morepop.on.staff（三个类）而不是 .morepop.staff ，
     是为了压过上面的 .morepop.on{display:block} —— 两个类的权重跟它打平，
     谁写在后面谁赢，那种「靠文件顺序」的胜负太脆。
   ★ 没写 order 的项（= 乔总专用的那些）本来就被 .hide 藏了，不占位。 */
.morepop.on.staff{display:flex;flex-direction:column}
.morepop.staff #btn-prod{order:1}
.morepop.staff #btn-design{order:2}
.morepop.staff #btn-guide{order:3}
.morepop.staff #mline1{order:4}
.morepop.staff #btn-myacct{order:5}
.morepop.staff #btn-chpwd{order:6}
.morepop.staff #btn-logout{order:7}
/* flex 列容器里给固定高度的分隔线钉住，免得被压缩成 0 高看不见 */
.morepop.on.staff .mline{flex:0 0 auto}
/* 手机端菜单项做大一点，手指好点 */
@media(max-width:820px){
  .morepop .mi{padding:11px 14px;font-size:14px}
}
/* 白底区域的按钮（弹窗里）：深色背景款在白底上会变成白字白底，看不见 */
.btn.lt{background:#fff;color:#374151;border:1px solid var(--line)}
.btn.lt:hover{background:#f3f4f6;border-color:#9ca3af;color:#111827}
.btn.lt:disabled:hover{background:#fff;border-color:var(--line);color:#374151}

.wrap{max-width:1500px;margin:0 auto;padding:16px 18px 80px}

/* ★ 2026-09-18 第 13 轮：宽屏上人员栏「抢」回一点左右留白。
   老板要的是「一行装下 19 个人」。注意 .wrap 本身 max-width 是 1500，
   窗口再宽它也不长 —— 所以这里同时把上限抬到 1640，
   否则 1506px 的内容硬要在 1480px 里排，差 26px 就会换行。 */
@media(min-width:1180px){
  .wrap{max-width:1640px;padding-left:10px;padding-right:10px}
}

/* ══════════ 登录页 ══════════ */
.authwrap{min-height:100vh;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(150deg,#1a1d24 0%,#252a35 55%,#1e2230 100%);padding:20px}
.authbox{background:#fff;border-radius:16px;width:100%;max-width:400px;padding:30px 28px;
  box-shadow:0 22px 60px rgba(0,0,0,.4)}
.authbox h1{margin:0 0 4px;font-size:21px;letter-spacing:-.4px;
  display:flex;align-items:center;gap:10px}
.authbox h1 b{color:var(--blue)}
/* ★ 2026-10-08 第 46 轮：登录页也换成 Jooydoo 图标（跟桌面图标同一张图） */
.authbox .authlogo{width:40px;height:40px;border-radius:10px;display:block;
  box-shadow:0 3px 10px rgba(0,62,138,.28)}
.authbox .sub{color:var(--sub);font-size:12.5px;margin-bottom:22px}
.fld{display:flex;flex-direction:column;gap:5px;margin-bottom:14px}
.fld label{font-size:12.5px;color:#374151;font-weight:600}
.fld input,.fld select,.fld textarea{border:1px solid var(--line);border-radius:9px;
  padding:11px 12px;outline:none;width:100%;background:#fff;font-size:14px}
.fld input:focus,.fld select:focus,.fld textarea:focus{border-color:var(--blue);
  box-shadow:0 0 0 3px rgba(37,99,235,.13)}
.fld .hint{font-size:11.5px;color:var(--sub)}

/* ══════════ ★ 卡点「备注」框（2026-09-18 第 16 轮）══════════
   老板原话：「这个下边儿有一个选项，叫其他写下方备注。这个没法手动输入，
   你这边儿要给我写预留一个手动输入的这个框。」
   所以这个框要「一眼看出来是可以打字的」，别做成灰扑扑的一行。
   一直显示（不藏着）—— 想补充就写、不写就空着。 */
.bk-extra{margin-top:7px}
.bk-extra input{font-size:13.5px;padding:9px 11px;background:#fbfcfe}
.bk-extra input::placeholder{color:#9ca3af;font-size:13px}
.bk-tip{font-size:11.5px;color:var(--sub);margin-top:5px;line-height:1.5;
  min-height:17px}
/* 提示语在「真会改变存库内容」时点亮 —— 让老板知道写备注是有后果的 */
.bk-tip.on{color:#b45309}
.authbox .btn{width:100%;padding:12px;font-size:15px;margin-top:6px}
.authmsg{border-radius:9px;padding:10px 13px;font-size:13px;margin-bottom:15px;display:none}
.authmsg.on{display:block}
.authmsg.r{background:#fef2f2;border:1px solid #fecaca;color:#991b1b}
.authmsg.i{background:#eff6ff;border:1px solid #bfdbfe;color:#1e40af}
.authmsg.g{background:#ecfdf5;border:1px solid #a7f3d0;color:#065f46}

/* ══════════ 卡片 / 通用 ══════════ */
.card{background:var(--card);border:1px solid var(--line);border-radius:12px;
  padding:16px 18px;margin-bottom:14px;box-shadow:0 1px 2px rgba(16,24,40,.045)}
h2{font-size:15px;margin:0 0 13px;padding-left:10px;border-left:3px solid var(--blue);
  display:flex;align-items:center;gap:9px;flex-wrap:wrap}
h2 .sp{flex:1}
.note{border-radius:9px;padding:11px 14px;font-size:12.5px;line-height:1.7;margin:10px 0}
.note.warn{background:#fffbeb;border:1px solid #fde68a}.note.warn b{color:#92400e}
.note.bad{background:#fef2f2;border:1px solid #fecaca}.note.bad b{color:#991b1b}
.note.info{background:#eff6ff;border:1px solid #bfdbfe}.note.info b{color:#1e40af}
.note.ok{background:#ecfdf5;border:1px solid #a7f3d0}.note.ok b{color:#065f46}
.empty{text-align:center;color:var(--sub);padding:44px 12px;font-size:13.5px}

/* ══════════ 提醒条 —— 已按老板要求删除（2026-09-18 第 14 轮）══════════
   样式一并清掉，免得留一堆没人用的死代码。
   超期 / 3天内到期的信息改由 KPI 卡片承担（点卡片能筛）。 */

/* ══════════ KPI ══════════ */
/* ★ 2026-09-20 第 22 轮：老板要求「上面那一大排方框，文字和数字都改大、更显眼」。
   原话：「把界面上面那一大排方框……把里边这些文字改大，把数字也改大，
         看起来更加显眼，更加突出一些。」

   ★ 第 23 轮（同一天，老板看完第一版后的追加要求）：
     原话：「标签文字原来是 11.5，现在改成 14 太小了……你改成 20 吧，
            改成 24 也行。手机端的标签文字也要改大，尽量改得接近于数字那么大，
            要看起来明显。」
     所以标签从 14px 一把提到 22px，数字 30px —— 两者只差 8px，
     视觉上接近"一样大"，不再是"小标题 + 大数字"的主次感。
     标签一大，卡片高度就得跟着长：padding 14→18、最小宽度 150→168、
     行高 1.15→1.25（中文标签放大后行距太紧会显得糊成一团）。

   布局核算（一行 7 个卡片，容器最宽 1640px，两侧 padding 10px）：
       168px * 7 + 10px 间隙 * 6 = 1236px  <  1620px 可用宽度 ✓ 不会换行
   窄屏兜底：minmax 是 auto-fit，宽度不够时自动降列数，不会挤爆。 */
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(168px,1fr));gap:10px;margin-bottom:14px}
.k{background:#fff;border:1px solid var(--line);border-radius:12px;padding:16px 18px;
  cursor:pointer;transition:.15s}
.k:hover{border-color:#c9cfd8;transform:translateY(-1px);box-shadow:0 3px 10px rgba(16,24,40,.07)}
.k.on{border-color:var(--blue);box-shadow:0 0 0 2px rgba(37,99,235,.16)}
.k .l{font-size:18px;color:#3d4757;font-weight:700;line-height:1.25;margin-bottom:6px}
.k .v{font-size:27px;font-weight:900;letter-spacing:-1px;line-height:1.15;
  font-variant-numeric:tabular-nums}
.k .d{font-size:12px;color:var(--sub);margin-top:3px}
.k.r .v{color:var(--red)}.k.a .v{color:var(--amber)}
.k.g .v{color:var(--green)}.k.b .v{color:var(--blue)}

/* ══════════ 所有人快捷键栏（在 KPI 下面一大排名字）══════════ */
/* ★ 2026-09-18 第 13 轮：整体瘦身，目标「一行装下、高度 ~78px」
   老板原话：「四个框太宽了，占用太多空间，想只占现在 50% 的空间、上下距离窄一点」
   做法：① 部门名从「上方框头」改成「左侧竖排标签」，省掉一行高度
        ② 文字/内边距整体缩一档，但保证 ≥11px 可读、按钮高度 ≥26px 好点
        ③ 四个框水平排开，空间不够时框内自己横滑，绝不换行堆高 */
.peoplebar{margin:-6px 0 9px}
.pbar-in{display:flex;gap:6px;align-items:center;flex-wrap:nowrap;
  background:#f7f8fa;border:1px solid var(--line);border-radius:9px;
  padding:4px 6px;overflow:hidden}
/* 「全部人」按钮：就是一个普通胶囊，跟各框在同一水平线上 */
.pallwrap{display:flex;align-items:center;flex:0 0 auto;min-width:0}
.pallwrap .pghd{display:none}

/* ★ 四个部门框：横着排，按各自内容定宽，**不许收缩**。
   只要允许收缩，浏览器就按「总和=可用宽」掐每个框十几像素，
   表现就是每个框最后一个人被切掉 —— 所以 flex-shrink 必须是 0。 */
.pbar-groups{display:flex;gap:5px;align-items:stretch;flex-wrap:wrap;min-width:0}
.pgroup{border:1px solid #dfe3e8;border-radius:8px;background:#fff;
  padding:2px 4px 2px 3px;min-width:0;display:flex;align-items:center;gap:4px;
  flex:0 0 auto;overflow:visible}
/* 框头改左侧竖排标签：部门名 + 人数上下叠，右边一条竖线分隔。
   ★ 竖排是这一轮省高度的关键：省掉整整一行「框头」，170px → 47px */
.pghd{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:1px;flex:0 0 auto;padding:0 3px 0 1px;margin:0;
  border-bottom:0;border-right:1px solid #eceff3}

/* ══════════ ★ 部门标签：跟人名按钮拉开区分 · 2026-09-18 ══════════
   老板原话：「这四个框，它的设计风格跟每个人的太像了，
   稍微有一点点的区分好不好？或者是颜色，或者是形状。」

   原来的问题：部门标签也是「白底 + 灰字 + 浅边框」，
   跟旁边的人名按钮（.pchip）几乎是同一个东西 —— 扫过去分不清
   哪个是「部门」，哪个是「人」。

   改法（颜色 + 形状一起动，两个维度都拉开）：
     ① 颜色反过来：人名是「白底深字」，部门改成「实底白字」；
        四个部门各一个色，一眼对得上号。
     ② 形状不一样：部门做成整块圆角色条，左边再压一条深色竖条做「标签感」，
        不是按钮那种细边框小胶囊。
     ③ 部门名完整保留（销售部/采购部/设计部），不做缩写 ——
        工人扫一眼要知道这是哪个部门，缩写反而要猜。
   只改样式，DOM 结构一个字没动，所以数据、点击逻辑全不受影响。 */
.pghd{background:var(--pg-bg,#64748b);border-radius:7px;
  padding:3px 7px;border-right:0;margin-right:2px;
  box-shadow:inset 3px 0 0 rgba(0,0,0,.18);
  -webkit-print-color-adjust:exact;print-color-adjust:exact}
.pgname{font-size:11px;font-weight:800;letter-spacing:.3px;
  white-space:nowrap;line-height:1.25;color:#fff;
  text-shadow:0 1px 1px rgba(0,0,0,.14)}
.pgnum{font-size:9.5px;font-weight:800;color:#fff;
  background:rgba(255,255,255,.26);
  border-radius:4px;padding:0 3px;min-width:15px;text-align:center;
  font-variant-numeric:tabular-nums;line-height:1.35;white-space:nowrap}

/* 四个部门各一个颜色。★ 只管「显示成什么颜色」，
   跟 dept 字段、跟数据都无关，改色不会碰到任何一条任务。
   ★ 2026-09-19：老板要求「其他部」换成棕色底白字（原为灰色）。 */
.pgroup:nth-child(1) .pghd{--pg-bg:#2563eb}   /* 销售部 · 蓝 */
.pgroup:nth-child(2) .pghd{--pg-bg:#059669}   /* 采购部 · 绿 */
.pgroup:nth-child(3) .pghd{--pg-bg:#7c3aed}   /* 设计部 · 紫 */
.pgroup:nth-child(4) .pghd{--pg-bg:#8b5a2b}   /* 其他部 · 棕 */
/* 万一以后加到第 5 个部门，给个稳的默认色，别变成透明看不见 */
.pgroup:nth-child(n+5) .pghd{--pg-bg:#475569}
/* 框内的人：横着排；空间不够才横滑，不换行。
   ★ 这里不能用 flex:1 —— 用了它就会「默默缩到能缩的最小」，
   明明右边还有空地，19 个人照样被压成横滑。 */
.pgbody{display:flex;gap:3px;flex-wrap:nowrap;align-items:center;
  overflow-x:auto;overflow-y:hidden;min-width:0;flex:0 0 auto;
  -webkit-overflow-scrolling:touch;scrollbar-width:none}
.pgbody::-webkit-scrollbar{display:none}

/* ══════════ ★ 上下格式（vcol）· 2026-09-18 第 14 轮 ══════════
   老板原话：「这个人名是在上面，数量写到人名下边，这样的左右的宽距就窄了……
   我不需要每个人名折叠到里边，我需要一眼全能看见。」

   竖起来写为什么更省地方：
     横着写「吴丹丹 ⓿」≈ 62px 宽；竖着写最宽也就 ~40px。
     19 个人横着排，一下就省出好几百像素 ——
     所以「框窄」和「一眼全看见」这两件事能同时满足，不用二选一。 */
.pchip.vcol{flex-direction:column;gap:0;padding:2px 5px;
  min-width:30px;text-align:center;justify-content:center}
.pchip.vcol .pn{line-height:1.15;white-space:nowrap}
/* 数量：人名下面的灰色小徽标（老板选的样式） */
.pchip.vcol .pc{margin-top:1px;font-size:9px;min-width:15px;
  padding:0 3px;line-height:1.3;border-radius:3px}

/* 部门标签也是上下格式：部门名在上、人数在下
   ★ 2026-09-18：padding 收成「上下 4px、左右 6px」——
     部门标签现在是实底色块，靠内边距把色块撑起来才有「标签」的样子，
     太瘦会看成一条线。 */
.pghd.vcol{gap:1px;padding:2px 6px}

/* 分组框里的人：字号/内边距收一档（11px 仍然清楚，不像蚂蚁）。 */
.pgroup .pchip{padding:2px 5px;font-size:11px;border-radius:6px;gap:2px;
  min-height:26px}
.pgroup .pchip .pc{font-size:9px;min-width:14px;padding:0 3px}

/* ★ 屏幕不够宽时允许四个框换行，一行装两三个。
   为什么不用「框内横滑」：横滑的话老板看不见后面还有谁，
   得先滑一下才知道——而这一排的用途恰恰是「一眼扫过去谁在忙」。
   宁可多占一行，也不藏人。 */
@media(max-width:1439px){
  .pgroup{overflow:hidden}
  .pgbody{overflow:hidden}
}
/* ★ 1440 以上（含老板在用的 1500）把间距抠紧，四个框一行装到底 */
@media(min-width:1440px){
  .pbar-in{padding:3px 3px}
  .pbar-groups{gap:3px}
  .pgroup{padding:2px 3px 2px 2px;gap:3px}
  /* 部门标签现在是实底色块，内边距不能收太狠，否则色块瘦成一条线 */
  .pghd{padding:3px 5px}
  .pgroup .pchip{padding:2px 4px}
  .pgroup .pchip .pc{min-width:13px;padding:0 2px}
  .pgbody{gap:2px}
  .pallwrap .pchip{padding:2px 6px;font-size:11.5px}
  .pallwrap .pchip .pc{font-size:9px;min-width:14px;padding:0 3px}
}
.pchip{display:inline-flex;align-items:center;gap:5px;border:1px solid #e3e6ea;
  background:#fff;color:#374151;border-radius:7px;padding:4px 8px;font-size:12px;
  font-weight:600;cursor:pointer;transition:.13s;white-space:nowrap;font-family:inherit;
  line-height:1.2;flex:0 0 auto}
.pchip:hover{border-color:#b9c0ca;background:#fbfcfd}
.pchip .pn{letter-spacing:.2px}
.pchip .pc{font-size:10.5px;font-weight:800;color:#8b93a1;background:#f1f3f6;
  border-radius:4px;padding:0 4px;min-width:16px;text-align:center;
  font-variant-numeric:tabular-nums}
/* 没任务的人：压暗一点，但还看得见、还能点 */
.pchip.zero{opacity:.5}
.pchip.zero .pc{background:#f6f7f9;color:#b3b9c2}
/* 选中：蓝底白字 */
.pchip.on{background:var(--blue);border-color:var(--blue);color:#fff;
  box-shadow:0 2px 7px rgba(37,99,235,.28)}
.pchip.on .pc{background:rgba(255,255,255,.25);color:#fff}
.pchip.on:hover{background:#1d4ed8;border-color:#1d4ed8}
/* ══════════ 「全部人」按钮 · 2026-09-19 ══════════
   老板原话：「全部人38这个方框换成橙色底黑字」。
   前一版是深墨色描边（白底），老板还是要更醒目的见方色块 ——
   橙色在 5 个框里谁都不像（销售蓝/采购绿/设计紫/其他棕），
   而且橙底配黑字对比度足够，扫一眼就认得出这是「总开关」。
   ★ 橙底黑字：字必须用深色（#1f2937 近黑），不能用白字 ——
     橙配白对比度只有 2.3:1，远低于无障碍标准 4.5:1，看不清。 */
.pchip.all{background:#f97316;border:1.5px solid #ea580c;color:#1f2937}
/* ★ 数字徽标：橙底上叠一层「浅色凹陷」比叠深色好看 ——
   叠深色（原来用 rgba(0,0,0,.22)）会糊成一坨黑印，数字读不出来。
   改成浅色半透明 + 黑字，既有「凹陷小标签」的感觉，数字又清楚。 */
.pchip.all .pc{background:rgba(255,255,255,.55);color:#7c2d12;font-weight:800}
.pchip.all:hover{background:#fb923c;border-color:#ea580c}
.pchip.all.on{background:#ea580c;border-color:#c2410c;color:#111827;
  box-shadow:0 2px 7px rgba(234,88,12,.35)}
.pchip.all.on .pc{background:rgba(255,255,255,.6);color:#7c2d12}

/* ══════════ 工具栏 ══════════ */
.tools{display:flex;gap:9px;flex-wrap:wrap;align-items:center;margin-bottom:12px}
.tools input,.tools select{border:1px solid var(--line);border-radius:8px;padding:8px 11px;
  background:#fff;font-size:13px;outline:none}
.tools input:focus,.tools select:focus{border-color:var(--blue);
  box-shadow:0 0 0 3px rgba(37,99,235,.12)}
.tools .sp{flex:1}

/* ══════════ 表格 ══════════ */
table{width:100%;border-collapse:collapse;font-size:13px}
th{background:#f8f9fb;text-align:left;padding:9px 10px;border-bottom:1.5px solid var(--line);
  font-weight:700;color:#374151;white-space:nowrap;font-size:12.5px}
td{padding:7px 10px;border-bottom:1px solid #f1f3f5;vertical-align:middle;line-height:1.45}
/* ★ 所有行一律等高（两行行距），不会有的宽有的窄 */
#listwrap tbody tr{height:62px}
tbody tr:last-child td{border-bottom:none}
tbody tr:hover{background:#fafbfc}
tr.overdue{background:#fff7f7}tr.overdue:hover{background:#fff1f1}
tr.soon{background:#fffcf5}tr.soon:hover{background:#fff9ec}
tr.done{opacity:.6}
.tid{font-family:ui-monospace,Menlo,monospace;font-size:11.5px;color:#9ca3af}
.tname{font-weight:600}
.tsub{font-size:11.5px;color:var(--sub);margin-top:1px;line-height:1.4}
.tdim{color:#c3c8ce}
/* 标题区固定两行：标题 1 行 + 详细要求 1 行，超了截断，保证每行一样高 */
.tdetail{font-size:12px;color:#6b7280;max-width:340px;line-height:1.45;margin-top:2px;
  display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;
  white-space:nowrap;text-overflow:ellipsis}
/* 第 2 行：详细要求（不管有没有写，都占一行，行高才统一） */
.tline2{font-size:12px;color:#6b7280;line-height:1.5;margin-top:1px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:420px}
/* 旧标签行已废弃（重要/次要挪到独立列了） */
.tagrow{display:none}
/* 列宽：按用户指定的顺序排 */
.tbl{table-layout:auto}
/* ★ 2026-09-21 老板需求：标题左边新增「任务编号」列（2026-0001 这种）。
   窄列 + 等宽数字，对齐后才像台账。行高一级用 12px，跟创建时间那列一致，
   免得把整行撑高。 */
.tbl .c-no{width:92px;white-space:nowrap;line-height:1.4}
.tbl .c-no .tno{font-weight:600;color:#374151;letter-spacing:.02em}
/* ★★ 2026-09-21 任务编号胶囊（2026-0001）—— 老板要求：「标题左边加一个叫任务编号」。
   ── 为什么做成这样 ──────────────────────────────
   · ui-monospace 等宽字体：编号是给人「对单子」用的，等宽才好逐位比对，
     数字 0 和字母 O 在等宽字体里也更容易分清。
   · 灰底小胶囊：它是标签，不是内容。用背景色把它和标题在视觉上分开，
     眼睛扫过去时不会把「2026-0001」和标题连成一句话读。
   · flex:none：标题很长时不许把它挤变形（编号位数固定，本来也不该伸缩）。
   · 字号比标题小一档：扫列表时标题仍是主角。
   ★ 别改成黑色加粗 —— 那一列会变得跟标题一样抢眼，整张表瞬间变吵。 */
.tno{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:11.5px;
  color:#6b7280;background:#f3f4f6;border:1px solid #e5e7eb;border-radius:4px;
  padding:1px 6px;white-space:nowrap;flex:none;letter-spacing:.02em;
  display:inline-block}
/* 详情弹窗里的大标题旁边，编号给稍大一点点，但那仍然是标签不是标题 */
.dt-tno{font-size:12px;margin-right:8px;vertical-align:2px}
.tbl .c-t{min-width:200px;max-width:360px}
.tbl .c-a{width:84px;white-space:nowrap}
.tbl .c-c{width:74px;white-space:nowrap}
/* ★★ 2026-09-22 第 29 轮：派遣人名字可点、创建时间表头可点 ──
   规矩跟「截止时间」表头保持一致：能点的地方要给 hover 反馈，
   不然老板点上去没任何变化，会以为这功能没做。 */
.tbl th.sortable{cursor:pointer;user-select:none}
.tbl th.sortable:hover{color:#1e40af}
/* ★ 第 89 轮：排序生效时底下带一条蓝杠 —— 原来只有「截止时间」有，
   现在六列都能点了，统一起来；扫一眼就知道「这张表按哪列排的」。
   box-shadow 不占布局，不会把表头撑高一像素。 */
.tbl th.sortable.on{color:#1d4ed8;box-shadow:inset 0 -2px 0 #2563eb}
.tbl th.sortable .arw{font-size:10px;margin-left:3px;vertical-align:1px;opacity:.7}
.tbl th.sortable.on .arw{opacity:1}
/* ★★ 第 89 轮：表头必须不许换行。
   理由：「是否重要」4 个字 ≈ 52px，加箭头 13px、加内边距 20px 就 85px，
   而 .c-p 只给了 76px —— 一换行就把 #listwrap 里写死的 62px 行高顶开，
   表头和第一行数据错位（2026-09-21 做截止时间那列时踩过一模一样的坑）。
   加 nowrap 后 table-layout:auto 会自动把这一列加宽，不用手改宽度。 */
.tbl th.sortable{white-space:nowrap}
/* 「完成时间」表头多了箭头，宽度照「截止时间」那套给足 104px */
.tbl th.c-tmh{width:104px}
/* 派遣人：平时看着就是个普通人名，鼠标一搭上去才告诉你能点 */
.tbl .c-c .cname{cursor:pointer;border-bottom:1px dashed #c7cdd6}
.tbl .c-c .cname:hover{color:#1e40af;border-bottom-color:#1e40af}
/* 正在筛的那个人：做成胶囊，让「列表现在是筛过的」这件事一眼看得见 */
.tbl .c-c .cname.on{background:#eef2ff;color:#1d4ed8;font-weight:600;
  border:1px solid #c7d2fe;border-radius:4px;padding:1px 5px}
/* 提示条里两段话之间的那根竖线 */
.sortnote .ndiv{display:inline-block;width:1px;height:12px;
  background:#cbd5e1;margin:0 2px;vertical-align:-1px}
.tbl .c-tm{width:86px;white-space:nowrap;color:#6b7280;font-size:12px;
  font-variant-numeric:tabular-nums;line-height:1.4}
.tbl .c-p{width:76px}
.tbl .c-cd{width:104px;white-space:nowrap}
.tbl .c-s{width:68px}
.tbl .c-o{width:66px}
/* 是 / 否重要 */
/* ★ 2026-10-01 老板把三档改成 普通/重要/非常重要。
   配色沿用「红=最要紧、灰=普通」的老口径，只把最高档加重一档：
   非常重要 = 深红实底白字，比「重要」的浅红更抢眼，扫一眼就能分出来。 */
.pri-tag{display:inline-block;font-size:11.5px;padding:2px 9px;border-radius:5px;
  font-weight:700;white-space:nowrap}
.pri-tag.veryhigh{background:#dc2626;color:#fff;box-shadow:inset 0 0 0 1px #b91c1c}
.pri-tag.high{background:#fee2e2;color:#b91c1c;box-shadow:inset 0 0 0 1px #fecaca}
.pri-tag.normal{background:#f1f5f9;color:#64748b}
.pri-tag.low{background:#f8fafc;color:#94a3b8}
/* 操作列就一个按钮，行高才压得住 */
.c-o .acts{flex-wrap:nowrap;justify-content:flex-start}

/* ══════════ 已完成分割线 ══════════
   ★★ 2026-10-10 老板需求：「未完成和已完成中间加一条明显的分割线，
   居中明显的大字写上：以下任务已完成。」
   ── 为什么做成「两侧渐隐横线 + 中间大字」而不是一条通栏线 ──
   · 光一条通栏横线，扫列表时很容易被当成某一行的下边框，谈不上「明显」；
     中间开口放字，视线自然停在字上，两侧的线又把两组任务明确分开。
   · 线用 linear-gradient 从两端淡出，避免左右出现两个生硬的断头。
   · 16px / 800：比表头（12.5px）和任务标题（13px）都大一档，
     是这一屏里仅次于 KPI 数字的第二大字，「明显」才落得实。
   · 颜色取中性灰（slate 系：字 #334155 / 线 #94a3b8）。
     ★ 一开始线用的是 #cbd5e1，实测在 1180 宽的表格里虽然铺满，
       但对比度只有 1.35 左右，缩略看基本「糊」成一片白，谈不上明显。
       加深到 #94a3b8 后对比度约 1.9，隔一米也看得见分组。
     ★ 但也别再深了 —— 已完成的活本来就该「退到后面」（tr.done 还压着
       opacity .6），这条线是分界，不是主角。
   ── 选择器为什么要带 #listwrap tbody ──
     上面有 `#listwrap tbody tr{height:62px}`（写死行高）和
     `#listwrap tbody tr:hover{background:#f8fafc}`，都是 id 级选择器，
     光写 tr.done-sep 压不住：分割行被撑成 62px、鼠标一过还变色。
     带上同等前缀才稳，不用 !important。 */
#listwrap tbody tr.done-sep{height:auto;cursor:default}
#listwrap tbody tr.done-sep:hover{background:transparent}
#listwrap tbody tr.done-sep td{border-bottom:none;padding:20px 10px 14px;
  background:transparent}
.dsep{display:flex;align-items:center;gap:14px}
.dsep::before,.dsep::after{content:'';flex:1 1 auto;height:2px;border-radius:2px;
  background:linear-gradient(90deg,rgba(148,163,184,0) 0%,#94a3b8 18%,#94a3b8 100%)}
.dsep::after{background:linear-gradient(270deg,rgba(148,163,184,0) 0%,#94a3b8 18%,#94a3b8 100%)}
.dsep span{font-size:16px;font-weight:800;color:#334155;letter-spacing:.08em;
  white-space:nowrap}

/* ══════════════════════════════════════════════════════════
   ★★ 2026-09-21「截止时间」表头可点排序（老板需求）
   ══════════════════════════════════════════════════════════
   ★ 为什么单独开 .c-due 而不是复用 .c-tm：
     .c-tm 是写死的 86px 宽。「截止时间」4 个字约 52px，加箭头约 10px，
     再加左右内边距 20px —— 86px 会刚好挤爆或换行。
     而 #listwrap tbody tr{height:62px} 是写死的行高，
     表头一换行就会把整张表的头撑高、跟数据行错位。所以给足 104px。
   ★ 用蓝色 #1d4ed8 = 全站交互色（.iconbtn / .tname / .who 都是这个色），
     让人一眼看出「这里能点」。再配 hover 变色 —— 光靠颜色还不够。 */
.tbl th.c-due{width:104px;white-space:nowrap;cursor:pointer;
  user-select:none;-webkit-user-select:none;
  color:#1d4ed8;transition:background .15s}
.tbl th.c-due:hover{background:#eef2ff}
.tbl th.c-due:active{background:#e0e7ff}
/* 排序生效中：表头加深 + 底部一条蓝杠，
   扫一眼就知道「现在这张表是按这列排的」 */
.tbl th.c-due.on{background:#e0e7ff;color:#1e40af;
  box-shadow:inset 0 -2px 0 #2563eb}
.tbl th.c-due .arw{font-size:10px;margin-left:3px;vertical-align:1px;opacity:.7}
.tbl th.c-due.on .arw{opacity:1}
/* 数据格沿用 .c-tm 的等宽数字，但宽度要跟表头对上 */
.tbl td.c-due-v{width:104px}

/* ── 排序生效时的提示条 ──
   排序是个「看不见的状态变化」，不提示的话点完会觉得没反应。
   这条同时替代了「点第三下回默认」—— 回默认的入口写在明面上，不用记。 */
.sortnote{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  font-size:12.5px;color:#1e40af;background:#eef2ff;
  border:1px solid #dbe2fb;border-radius:7px;
  padding:6px 10px;margin-bottom:9px}
.sortnote .lnk{background:none;border:none;padding:0;cursor:pointer;
  color:#2563eb;font-size:12.5px;font-family:inherit;
  text-decoration:underline;text-underline-offset:2px}
.sortnote .lnk:hover{color:#1e40af}
.c-o .iconbtn{padding:4px 10px;font-size:12px}
.iconbtn.del{color:#b91c1c;border-color:#fecaca;background:#fff}
.iconbtn.del:hover{background:#fef2f2;border-color:#dc2626;color:#991b1b}
/* 标题行：文字 + 图数小标 */
.titlerow{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.imgbadge{display:inline-flex;align-items:center;gap:2px;font-size:11px;
  background:#eef2ff;color:#4338ca;border:1px solid #dbe2fb;border-radius:5px;
  padding:1px 6px;white-space:nowrap;font-weight:600;flex:none}
.tagrow{display:flex;gap:4px;flex-wrap:wrap;margin-top:3px}
.tagrow .pill,.tagrow .stag{margin:0}
.pill.ok{background:#dcfce7;color:#166534}
/* 倒计时：只用颜色区分，字体/粗细/字形全都一样（不要斜体） */
.cd{font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap;font-size:13px;
  font-style:normal}
.cd.r{color:var(--red)}
.cd.a{color:var(--amber)}
.cd.g{color:var(--green)}
.cd.s{color:var(--slate)}
.stag{display:inline-block;font-size:11px;padding:2px 9px;border-radius:20px;
  white-space:nowrap;font-weight:600}
.stag.todo{background:#f1f5f9;color:#475569}
.stag.doing{background:#dbeafe;color:#1e40af}
.stag.done{background:#d1fae5;color:#065f46}
.stag.veryhigh{background:#dc2626;color:#fff}
.stag.high{background:#fee2e2;color:#991b1b}
.stag.normal{background:#f3f4f6;color:#4b5563}
/* 旧值，只给 2026-09 那批老任务用 */
.stag.low{background:#f1f5f9;color:#64748b}
.pill{display:inline-block;font-size:11px;padding:2px 8px;border-radius:5px;
  background:#f3f4f6;color:#4b5563;margin:1px 3px 1px 0}
.pill.warn{background:#fef3c7;color:#92400e}
.pill.bad{background:#fee2e2;color:#991b1b}
/* ★ 第 17 轮：重复任务标记（蓝紫系，跟「超期/打回」的红黄区别开） */
.pill.rep{background:#e0e7ff;color:#3730a3}
.rep-b{display:inline-block;margin-left:4px;font-size:12px;color:#4f46e5;
  font-weight:700;vertical-align:middle}
.iconbtn{border:1px solid var(--line);background:#fff;border-radius:7px;padding:5px 10px;
  font-size:12px;color:var(--sub);white-space:nowrap;transition:.12s}
.iconbtn:hover{border-color:var(--blue);color:var(--blue);background:#f8faff}
.iconbtn.p{background:var(--blue);border-color:var(--blue);color:#fff;font-weight:600}
.iconbtn.p:hover{background:#1d4ed8}
.acts{display:flex;gap:5px;flex-wrap:wrap}

/* ══════════ 图片 ══════════ */
/* 弹窗里的图片区 */
.imgbox{border:1px dashed var(--line);border-radius:10px;padding:11px 12px;background:#fcfcfd}
.imglist{display:flex;gap:9px;flex-wrap:wrap}
.imglist:empty{display:none}
.thumb{position:relative;width:74px;height:74px;flex:none;
  animation:fadein .22s ease}
.thumb img{width:100%;height:100%;object-fit:cover;border-radius:8px;
  border:1px solid var(--line);cursor:zoom-in;display:block}
.thumb:hover img{border-color:var(--blue)}
.thumb .del{position:absolute;top:-7px;right:-7px;width:21px;height:21px;border-radius:50%;
  background:#dc2626;color:#fff;font-size:14px;line-height:1;padding:0;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 1px 5px rgba(0,0,0,.3)}
.thumb .del:hover{background:#b91c1c}
.thumb.pending img{opacity:.62;border-style:dashed}
.thumb .badge{position:absolute;left:0;bottom:0;right:0;font-size:9.5px;text-align:center;
  background:rgba(37,99,235,.86);color:#fff;border-radius:0 0 8px 8px;padding:2px 0}
@keyframes fadein{from{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}

/* ★ 右上角「刷新」按钮（2026-09-18 第 14 轮加）
   点击时图标转一圈 + 文字变「刷新中」，让员工知道真的在拉数据 */
#btn-refresh{display:inline-flex;align-items:center;gap:5px}
#btn-refresh .ricon{display:inline-block;font-size:14px;line-height:1;
  transition:transform .2s}
#btn-refresh .ricon.spin{animation:spin360 .85s linear infinite}
#btn-refresh:active{transform:translateY(1px)}
@keyframes spin360{from{transform:rotate(0)}to{transform:rotate(360deg)}}
.imgadd{display:flex;gap:8px;align-items:center;margin-top:10px;flex-wrap:wrap}
.imgtip{font-size:11.5px;color:#9ca3af}
.imgprog{margin-top:9px;font-size:12px;color:var(--blue);font-weight:600}
.lbl-sub{font-weight:400;font-size:11.5px;color:#9ca3af;margin-left:6px}
/* 看大图 */
.lightbox{position:fixed;inset:0;background:rgba(10,11,14,.9);display:none;
  align-items:center;justify-content:center;z-index:200;padding:24px;cursor:zoom-out}
.lightbox.on{display:flex}
.lbinner{max-width:100%;max-height:100%;text-align:center}
.lbinner img{max-width:100%;max-height:calc(100vh - 90px);
  border-radius:8px;box-shadow:0 10px 40px rgba(0,0,0,.5);display:block;margin:0 auto}
.lbname{color:#cbd5e1;font-size:12.5px;margin-top:11px;word-break:break-all}

/* ══════════ 弹窗 ══════════ */
.modal{position:fixed;inset:0;background:rgba(15,17,21,.55);display:none;
  align-items:flex-start;justify-content:center;z-index:100;padding:24px 14px;overflow:auto}
.modal.on{display:flex}
.mbox{background:#fff;border-radius:14px;width:100%;max-width:620px;padding:22px 24px;
  box-shadow:0 20px 50px rgba(0,0,0,.3);margin:auto}
.mbox h3{margin:0 0 16px;font-size:16.5px}
.frm{display:grid;grid-template-columns:1fr 1fr;gap:13px}
.fld.full{grid-column:1/-1}
/* ══════════ ★ 三个选项一排（2026-10-22 第 64 轮）══════════
   老板原话：「这 3 个选项放到一排上，可以适当左右宽度调的窄一些」。
   指截止日期 / 重复 / 优先级 —— 原来在 2 列网格里，优先级被挤到第二排左边，
   三个本该是一组的东西看着散。
   ★ 只包这三块，不动 .frm 的 2 列网格：改 .frm 会把标题/要求/图片全带歪。
   ★ minmax(0,1fr) 不能省 —— 不加的话「重复」下拉里的长选项
     （比如「自定义（可多选）…」）会把这一列撑宽，三列就不等宽了。
   ★ align-items:start 让三列各自顶头排，不要互相拉齐高度：
     截止日期那列底下多了 3 个快捷按钮和一行红字，一拉齐另两列下面就空了。 */
.fld3{grid-column:1/-1;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:13px;align-items:start}
.fld3 .fld{margin-bottom:0}
/* ★ 三列的标签区必须等高，否则三个框顶部参差 ——
   实测「截止日期 / 重复」的副标题各占 2 行（54px），「优先级」没副标题只有 20px，
   结果第三个框比前两个高出 34px，一排看着是歪的。
   定 54px = 主标签 1 行(21) + 副标题 2 行(32)；副标题最多 2 行，多的截掉。 */
.fld3 .fld > label{min-height:54px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fld3 .fld .lbl-sub{display:block;font-weight:400;white-space:normal;
  font-size:11px;line-height:1.45;margin-top:2px;max-height:32px;overflow:hidden}
/* ★ 日期在 182px 宽的列里放不下会折成两行（空框一下变成 63px 高）。
   字号 13.5 → 12，内边距和箭头间隙各收一点，再加 nowrap ——
   实测 12px 时「2026-10-22（周四）17:00」正好装下；
   再窄就省略号，不许折行（折行会让这一列比旁边两列高出一大截）。 */
.fld3 .duebtn{padding:11px 7px;gap:2px}
.fld3 .dueval{font-size:12px;letter-spacing:-.2px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.fld3 .duecar{font-size:10px}
/* ★ 「重复」选「自定义（可多选）」后展开的那 18 个按钮，在 182px 的窄列里
   原来横排会缩成 8 行、面板高 503px，把整个弹窗顶出屏幕（内容被切掉）。
   这里把「每周 / 每月」的小标题挪到按钮上面单独一行、按钮压小一档：
   实测能压到 180px 上下，跟旁边「截止日期」那一列差不多高。
   ★ 只在 .fld3 里这么排；手机上 .fld3 退化成单列，还是原来的横向排法。 */
.fld3 .rp-extra{padding:8px 7px;margin-top:6px}
.fld3 .rp-grp{flex-direction:column;gap:4px;margin-bottom:7px}
.fld3 .rp-grp:last-of-type{margin-bottom:5px}
.fld3 .rp-cap{width:auto;text-align:left;padding-top:0;font-size:11px}
.fld3 .rp-chips{gap:3px}
.fld3 .rp-chip{min-width:24px;padding:4px 0;font-size:11px;border-radius:6px}
.fld3 .rp-foot{flex-wrap:wrap;gap:5px;margin-top:6px}
.fld3 .rp-sum{font-size:10.5px}
.macts{display:flex;gap:9px;justify-content:flex-end;margin-top:18px;
  border-top:1px solid var(--line);padding-top:15px}

/* ══════════ 统计 ══════════ */
.rank{display:flex;align-items:center;gap:9px}
.rank .n{width:22px;height:22px;border-radius:6px;background:#f3f4f6;color:#6b7280;
  display:flex;align-items:center;justify-content:center;font-size:11.5px;font-weight:700;flex:none}
.rank .n.t1{background:#fef3c7;color:#92400e}
.rank .n.t2{background:#e5e7eb;color:#374151}
.pl{width:72px;height:7px;background:#e9ecef;border-radius:4px;overflow:hidden;flex:none}
.pl i{display:block;height:100%;background:var(--green)}
.pl.low i{background:var(--red)}.pl.mid i{background:var(--amber)}
.bignum{font-size:34px;font-weight:800;letter-spacing:-1px;font-variant-numeric:tabular-nums}

/* ══════════ Toast ══════════ */
.toast{position:fixed;left:50%;bottom:30px;transform:translateX(-50%) translateY(22px);
  background:#15171c;color:#fff;padding:11px 20px;border-radius:10px;font-size:13px;
  opacity:0;pointer-events:none;transition:.26s;z-index:200;max-width:88vw;text-align:center;
  box-shadow:0 8px 26px rgba(0,0,0,.32)}
.toast.on{opacity:1;transform:translateX(-50%) translateY(0)}

/* 页脚备份提示 */
.foot{text-align:center;font-size:11.5px;color:#9ca3af;padding:14px 0 4px}

/* ══════════ 新任务弹窗 ══════════
   电脑：右下角滑出一张小卡片
   手机：从顶部下来一张小卡片
   点一下直接打开这条任务的详情 */
.newpop{position:fixed;right:20px;bottom:20px;z-index:180;
  display:flex;flex-direction:column;gap:10px;align-items:flex-end;
  pointer-events:none;max-width:376px}

.np{pointer-events:auto;background:#fff;border:1px solid var(--line);
  border-radius:13px;padding:13px 15px 13px 14px;width:344px;max-width:100%;
  box-shadow:0 10px 34px rgba(16,24,40,.16),0 2px 8px rgba(16,24,40,.07);
  cursor:pointer;position:relative;overflow:hidden;
  transform:translateX(120%);opacity:0;transition:transform .34s cubic-bezier(.2,.9,.3,1),opacity .3s}
.np.on{transform:translateX(0);opacity:1}
.np.out{transform:translateX(120%);opacity:0}
/* 左边一条蓝色竖条 + 顶上一条进度线 */
.np::before{content:'';position:absolute;left:0;top:0;bottom:0;width:4px;background:var(--blue)}
.np.urgent::before{background:var(--red)}
.np.urgent .np-ic{background:#fee2e2;color:#b91c1c}
.np-fill{position:absolute;left:0;top:0;height:2.5px;background:var(--blue);
  opacity:.5;width:100%;transform-origin:left;animation:npcount 14s linear forwards}
.np.urgent .np-fill{background:var(--red)}
@keyframes npcount{from{transform:scaleX(1)}to{transform:scaleX(0)}}

.np-top{display:flex;align-items:flex-start;gap:10px}
.np-ic{flex:0 0 auto;width:34px;height:34px;border-radius:9px;background:#e0edff;
  display:flex;align-items:center;justify-content:center;font-size:17px;line-height:1}
.np-body{flex:1;min-width:0}
.np-h{font-size:12.5px;color:var(--sub);margin-bottom:3px;display:flex;
  align-items:center;gap:6px;flex-wrap:wrap}
.np-from{font-weight:700;color:#111827}
.np-tag{font-size:11px;padding:1px 7px;border-radius:5px;background:#fee2e2;
  color:#b91c1c;font-weight:700}
.np-tag.soon{background:#fef3c7;color:#b45309}
/* 非常重要：比「重要」的浅红更重一档（2026-10-01 新增） */
.np-tag.vh{background:#dc2626;color:#fff}
.np-t{font-size:14.5px;font-weight:700;color:#111827;line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  word-break:break-word}
.np-d{font-size:12px;color:#6b7280;margin-top:4px;line-height:1.45;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  word-break:break-word}
.np-meta{display:flex;align-items:center;gap:9px;margin-top:8px;flex-wrap:wrap;font-size:12px}
.np-due{color:#6b7280}
.np-due b{color:#b45309}
.np-due.red b{color:var(--red)}
.np-cd{font-weight:700;color:var(--red)}
.np-close{position:absolute;right:6px;top:5px;width:24px;height:24px;border:none;
  background:transparent;color:#c3c8ce;font-size:17px;line-height:1;cursor:pointer;
  border-radius:7px;padding:0;font-family:inherit}
.np-close:hover{background:#f3f4f6;color:#6b7280}
.np-go{font-size:12px;color:var(--blue);font-weight:700;margin-top:8px;
  display:flex;align-items:center;gap:4px}
.np:hover{border-color:#c9cfd8;box-shadow:0 12px 38px rgba(16,24,40,.2)}

/* ── 手机：从顶上下来的小卡片 ── */
@media(max-width:820px){
  .newpop{left:8px;right:8px;bottom:auto;top:8px;max-width:none;align-items:stretch}
  .np{width:auto;max-width:none;padding:12px 14px 12px 13px;
    transform:translateY(-140%);box-shadow:0 8px 26px rgba(16,24,40,.22)}
  .np.on{transform:translateY(0)}
  .np.out{transform:translateY(-140%)}
  .np-t{font-size:14px}
  .np-close{width:30px;height:30px;font-size:19px;right:4px;top:3px}
  /* 手机上一次只显示一张，别糊满屏 */
  .np:nth-child(n+2){display:none}
}

/* ══════════ 执行人：多选（一条任务可以派给好几个人）══════════ */
.asgwrap{position:relative}
.asgbox{min-height:40px;display:flex;align-items:center;gap:8px;
  padding:6px 12px 6px 8px;border:1px solid var(--line);border-radius:9px;background:#fff;
  cursor:pointer;flex-wrap:wrap}
.asgbox:hover{border-color:#94a3b8}
.asgbox.on{border-color:#2563eb;box-shadow:0 0 0 3px rgba(37,99,235,.12)}
.asgbox.lock{background:#f9fafb;cursor:default}
.asgbox.lock:hover{border-color:var(--line)}
/* ★ 2026-10-22 第 65 轮：执行人不再默认派给自己，忘选就直接点保存时，
   框子闪两下橙色 —— 只弹一句 toast 很容易看漏，得把「就是这儿没填」指出来 */
.asgbox.need{border-color:#f59e0b;box-shadow:0 0 0 3px rgba(245,158,11,.20);
  animation:asgneed .55s ease 2}
@keyframes asgneed{50%{box-shadow:0 0 0 6px rgba(245,158,11,.30)}}
.asgchips{display:flex;flex-wrap:wrap;gap:5px;flex:1;min-width:0}
.asgchips .empty{color:#9ca3af;font-size:13.5px}
.asgcar{color:#9ca3af;font-size:11px;flex:none;margin-left:auto;
  transition:transform .15s ease}
/* 展开时小三角翻上去，跟「往上弹」的方向对上 */
.asgbox.on .asgcar{transform:rotate(180deg)}
/* 已选的人做成小胶囊，一眼看清派给了几个人 */
.achip{display:inline-flex;align-items:center;gap:5px;background:#eef2ff;color:#3730a3;
  border:1px solid #c7d2fe;border-radius:999px;padding:3px 8px 3px 10px;
  font-size:12.5px;font-weight:600;line-height:1.5;max-width:100%}
.achip .x{color:#818cf8;font-size:14px;line-height:1;cursor:pointer;padding:0 1px;flex:none}
.achip .x:hover{color:#dc2626}
.achip.me{background:#ecfdf5;color:#065f46;border-color:#a7f3d0}
.achip.me .x{color:#6ee7b7}
.achip.lead{box-shadow:inset 0 0 0 1px #a5b4fc}
.achip .leadmark{font-size:10.5px;opacity:.75;font-weight:700}

.asgpop{position:absolute;left:0;bottom:calc(100% + 6px);top:auto;z-index:65;display:none;
  /* ★ 2026-10-22 第 63 轮：360 → 600。执行人列表改成并排 4 列，
     4 列要塞得下（销售/采购/设计/其他），窄一点就得换行。
     弹窗内容区最宽 572px（.mbox 620 − 左右 padding 48），100% 就是它。
     ★ 2026-10-22 第 64 轮：top 定位改成 bottom —— 执行人挪到表单最底部了，
       往下弹会被弹窗底边切掉，老板要求「点小三角向上弹，跟重复一样」。
       上面真放不下时 openAsgList 会给它加 .dn 翻下来（见下面的 .asgpop.dn）。 */
  width:min(600px,100%);background:#fff;border:1px solid #e3e6ea;border-radius:12px;
  box-shadow:0 12px 34px rgba(15,17,21,.18);overflow:hidden}
.asgpop.on{display:block;animation:fadein .13s ease}
/* 兜底：往上放不下了才翻到下面
   ★ 只在宽屏生效 —— 手机上 .asgpop 是 fixed + bottom:8px 贴屏幕底弹，
     这里要是把 bottom 改成 auto，面板会跑到屏幕外。 */
@media(min-width:821px){
  .asgpop.dn{top:calc(100% + 6px);bottom:auto}
}
.asgsearch{padding:9px 10px;border-bottom:1px solid #f1f5f9}
.asgsearch input{width:100%;border:1px solid var(--line);border-radius:8px;padding:7px 10px;
  font-size:13px;font-family:inherit}
/* ★ 2026-10-06 第 44 轮：分组之后列表内容变高（多了 4 个组头），
   238px 一屏只能看到两个部门，勾人还得滚。
   放到 300px —— 弹层总高仍不到 400px，手机上也放得下。 */
.asglist{max-height:300px;overflow:auto;padding:5px}
.asgrow{display:flex;align-items:center;gap:9px;padding:7px 9px;border-radius:8px;
  cursor:pointer;font-size:13.5px}
.asgrow:hover{background:#f8fafc}
.asgrow.on{background:#eef2ff}
.asgrow .ck{width:17px;height:17px;border:1.5px solid #cbd5e1;border-radius:5px;flex:none;
  display:flex;align-items:center;justify-content:center;font-size:11px;color:#fff;
  background:#fff;line-height:1}
.asgrow.on .ck{background:#2563eb;border-color:#2563eb}
.asgrow .nm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.asgrow .dp{font-size:11.5px;color:var(--sub);flex:none}
.asgrow .leadmark{font-size:10.5px;color:#6366f1;font-weight:700;flex:none}
.asglist .none{padding:14px;text-align:center;color:#9ca3af;font-size:12.5px}

/* ══════════ ★ 执行人列表 · 按部门分组 · 2026-10-06 第 44 轮 ══════════
   老板原话：「执行人下拉筛选，每个部门的人放到一起，便于勾选」。
   原来是一整条平铺，二十来个人拉下来，勾人要一个个找。
   现在不搜索时按部门分块，每块一个彩色组头（配色沿用「所有人快捷键栏」
   那一套：销售蓝/采购绿/设计紫/其他棕，全站一个部门一个颜色）。
   ★ 组头做成「粘性」的 —— 列表滚到哪，当前部门名就顶在顶部，
     勾到一半不会忘了自己正在哪个部门里点人。 */
.asggrp{margin-bottom:2px}
.asggrp:last-child{margin-bottom:0}
.asggrphd{
  position:sticky;top:-5px;z-index:2;
  display:flex;align-items:center;gap:6px;
  padding:5px 8px 5px 9px;margin:0 0 1px;
  background:var(--gc,#475569);border-radius:7px;
  box-shadow:inset 3px 0 0 rgba(0,0,0,.18);
}
.asggrphd .gn{font-size:11.5px;font-weight:800;letter-spacing:.3px;
  color:#fff;text-shadow:0 1px 1px rgba(0,0,0,.14);white-space:nowrap}
.asggrphd .gt{font-size:10px;font-weight:700;color:#fff;
  background:rgba(255,255,255,.26);border-radius:4px;
  padding:0 4px;line-height:1.5;white-space:nowrap}
.asggrphd .gp{font-size:10px;font-weight:800;color:#fff;margin-left:auto;
  background:rgba(255,255,255,.9);color:var(--gc,#475569);
  border-radius:4px;padding:0 5px;line-height:1.6;white-space:nowrap}
.asggrpbody{padding:1px 0 4px}
/* 搜索态：平铺，没有组头，行与行之间贴紧一点 */
.asglist>.asggrpbody{padding:0}

/* ══════════ ★ 执行人列表 · 竖着 4 列 · 2026-10-22 第 63 轮 ══════════
   老板原话：「弹窗出来第一列销售部，下面可勾选每个人，第二列采购部，
   下面可以勾选每个人，第三列设计部，第四列其他部门，竖着 4 列呈现，
   可勾选 1 人，和整个部门」。
   ★ 列头（.asgcolhd）就是「整个部门」的开关：
     点一下整部门一起选，再点一下整部门一起取消。
     小方框三态 —— 空 / 浅白底短横杠（选了一部分）/ 纯白底打勾（全选）。
   ★ 列宽用 minmax(0,1fr)：不加的话长名字会把整列撑宽，
     4 列就不再等宽了（flex/grid 的老毛病）。 */
.asgcols{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:7px;padding:1px}
.asgcol{min-width:0;border:1px solid var(--line);border-radius:9px;
  overflow:hidden;background:#fff}
.asgcolhd{display:flex;align-items:center;gap:5px;padding:5px 6px;
  background:var(--gc,#475569);color:#fff;cursor:pointer;user-select:none}
.asgcolhd:hover{filter:brightness(1.07)}
.asgcolhd .ck{width:14px;height:14px;flex:none;border:1.5px solid rgba(255,255,255,.8);
  border-radius:4px;display:flex;align-items:center;justify-content:center;
  font-size:10px;line-height:1;color:transparent}
/* ★ 三态必须「形状」也不同，不能只靠底色深浅 ——
   2026-10-22 首版把 part 做成半透明白底 + 白勾，放大后跟 all 的纯白底
   几乎看不出区别（老板扫一眼会以为整个部门都选上了）。
   现在：空 = 透明底白空框 / part = 浅白底 + 白色短横杠 / all = 纯白底 + 部门色勾。
   font-size:0 是把原来那个 ✓ 文本缩成零宽，只留 ::after 的横杠。 */
.asgcolhd.part .ck{background:rgba(255,255,255,.55);border-color:#fff;font-size:0}
.asgcolhd.part .ck::after{content:'';display:block;width:7px;height:2.5px;
  border-radius:2px;background:#fff}
.asgcolhd.all .ck{background:#fff;border-color:#fff;color:var(--gc,#475569)}
.asgcolhd .gn{font-size:11.5px;font-weight:800;letter-spacing:.2px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.asgcolhd .gt{margin-left:auto;flex:none;font-size:9.5px;font-weight:800;
  color:var(--gc,#475569);background:rgba(255,255,255,.92);border-radius:4px;
  padding:0 4px;line-height:1.6;font-variant-numeric:tabular-nums}
.asgcolbody{padding:3px 2px}
/* 列里的行比平铺态紧一档：4 列一屏要装下全公司二十来个人 */
.asgcol .asgrow{padding:4px 5px;gap:6px;font-size:13px}
.asgcol .asgrow .ck{width:15px;height:15px;font-size:10px}
.asgcol .asgrow .dp{font-size:9.5px}
.asgcol .asgrow .leadmark{font-size:9.5px}

.asgfoot{display:flex;align-items:center;gap:6px;padding:8px 10px;
  border-top:1px solid #f1f5f9;background:#fcfcfd}

/* ══════════ 截止日期：整月中文日历弹窗 ══════════ */
.duewrap{position:relative}
.duebtn{width:100%;display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:9px 12px;border:1px solid var(--line);border-radius:9px;background:#fff;
  font-size:13.5px;font-family:inherit;color:var(--txt);cursor:pointer;text-align:left}
.duebtn:hover{border-color:#94a3b8}
.duebtn:focus{outline:none;border-color:#2563eb;box-shadow:0 0 0 3px rgba(37,99,235,.12)}
.duebtn:disabled{background:#f3f4f6;color:#9ca3af;cursor:not-allowed}
.dueval{font-weight:600;color:#1d4ed8;font-variant-numeric:tabular-nums}
.dueval.ph{font-weight:400;color:#9ca3af}
.duecar{color:#9ca3af;font-size:11px;flex:none}

.calpop{position:absolute;left:0;top:calc(100% + 6px);z-index:60;display:none}
.calpop.on{display:block;animation:fadein .13s ease}
.calbox{width:290px;background:#fff;border:1px solid #e3e6ea;border-radius:12px;
  padding:11px 12px 9px;box-shadow:0 12px 34px rgba(15,17,21,.18)}
.cal-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}
.cal-nav{width:28px;height:28px;border:1px solid var(--line);background:#fff;border-radius:7px;
  font-size:15px;line-height:1;color:#475569;cursor:pointer;flex:none;padding:0;
  font-family:inherit;display:flex;align-items:center;justify-content:center}
.cal-nav:hover{background:#f1f5f9;border-color:#94a3b8;color:#111827}
.cal-year{border:none;background:none;font-family:inherit;font-size:14px;font-weight:800;
  color:#111827;cursor:pointer;padding:3px 9px;border-radius:7px;
  font-variant-numeric:tabular-nums}
.cal-year:hover{background:#f1f5f9;color:#1d4ed8}
.cal-week{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}
.cal-week span{text-align:center;font-size:11.5px;font-weight:700;color:var(--sub);
  padding:3px 0}
.cal-week span.sun{color:#dc2626}
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
.cal-d{height:32px;display:flex;align-items:center;justify-content:center;
  font-size:13px;border-radius:7px;cursor:pointer;user-select:none;
  font-variant-numeric:tabular-nums;transition:.1s}
.cal-d:hover{background:#eef4ff;color:#1d4ed8}
.cal-d.sun{color:#dc2626}
.cal-d.out{color:#d1d5db;cursor:default}
.cal-d.out:hover{background:none;color:#d1d5db}
/* 过去的日期：灰掉、划一道、点不动（派活只能今天或以后） */
.cal-d.past{color:#c9ced6;cursor:not-allowed;position:relative;
  text-decoration:line-through;text-decoration-color:#dfe3e8}
.cal-d.past:hover{background:none;color:#c9ced6}
.cal-d.past.sun{color:#e5b4b4}
/* 已经超期的老任务：日期照常显示（只是不让重新选） */
.cal-d.past.sel{background:#cbd5e1!important;color:#fff!important;
  text-decoration:none}
.cal-d.today{background:#f1f5f9;font-weight:800;color:#1d4ed8;
  box-shadow:inset 0 0 0 1.5px #c7d7f5}
.cal-d.sel{background:var(--blue);color:#fff!important;font-weight:800}
.cal-d.sel:hover{background:#1d4ed8}
.cal-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;
  margin-top:9px;padding-top:9px;border-top:1px solid var(--line)}
.cal-q{border:1px solid var(--line);background:#f8fafc;color:#475569;border-radius:7px;
  padding:5px 10px;font-size:11.5px;font-family:inherit;cursor:pointer;white-space:nowrap}
.cal-q:hover{background:#eef2f7;border-color:#94a3b8;color:#1f2937}
.cal-tip{font-size:11px;color:#9ca3af;flex:1;text-align:center;white-space:nowrap}
.duequick{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}
/* ★ 2026-10-22 第 64 轮：左右 padding 10 → 8。
   三个按钮现在挤在「三选项一排」的第一列里（列宽约 170px），
   原来 46px 一个、三个加间隙 150px，几乎顶满；收窄一档后从容些。 */
.dueq{padding:6px 8px;border:1px solid var(--line);background:#f8fafc;color:#475569;
  border-radius:7px;font-size:12px;cursor:pointer;font-family:inherit;white-space:nowrap}
.dueq:hover{background:#eef2f7;border-color:#94a3b8;color:#1f2937}
.dueq:disabled{background:#f3f4f6;color:#c0c6ce;cursor:not-allowed;border-color:#e5e7eb}
.hint.bad{color:#dc2626}

/* ══════════ ★ 重复任务（2026-09-18 第 17 轮）══════════
   老板要的是「设一次，以后自动建」。所以这块要让人觉得省事：
   常用的一步选走（下拉），只有挑日子多的才展开下面那个面板。 */
.rp-extra{margin-top:9px;padding:11px 12px;border:1px solid var(--line);
  border-radius:9px;background:#fbfcfe}
.rp-grp{display:flex;align-items:flex-start;gap:9px;margin-bottom:9px}
.rp-grp:last-of-type{margin-bottom:7px}
/* ★ 这个「每周 / 每月」的小标题必须按内容定宽，不能被 flex 压扁 */
.rp-cap{flex:0 0 auto;font-size:12px;color:var(--sub);font-weight:700;
  padding-top:5px;width:30px;text-align:right}
.rp-chips{flex:1 1 auto;display:flex;flex-wrap:wrap;gap:5px;min-width:0}
.rp-chip{flex:0 0 auto;min-width:30px;padding:5px 0;text-align:center;
  border:1px solid var(--line);background:#fff;color:#475569;border-radius:7px;
  font-size:12px;cursor:pointer;font-family:inherit;line-height:1.2;
  transition:background .12s,border-color .12s,color .12s}
.rp-chip:hover{background:#eef2f7;border-color:#94a3b8;color:#1f2937}
/* 选中态：一眼看得出挑了哪几天 */
.rp-chip.on{background:var(--pri,#2563eb);border-color:var(--pri,#2563eb);
  color:#fff;font-weight:700}
.rp-chip:disabled{opacity:.45;cursor:not-allowed}
.rp-foot{display:flex;align-items:center;gap:8px;margin-top:8px}
.rp-foot .sp{flex:1}
.rp-sum{font-size:11.5px;color:var(--sub);min-height:16px;line-height:1.5}
.rp-sum.on{color:#b45309}

/* ══════════ 任务详情弹窗 ══════════ */
.mbox-detail{max-width:660px}
.dt-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
.dt-head h3{margin:0;font-size:16px;color:var(--sub);font-weight:700}
.dt-x{width:30px;height:30px;border:none;background:#f3f4f6;color:#6b7280;border-radius:8px;
  font-size:19px;line-height:1;cursor:pointer;flex:none}
.dt-x:hover{background:#e5e7eb;color:#111827}
.dt-body{max-height:62vh;overflow-y:auto;padding-right:2px}
.dt-title{font-size:19px;font-weight:800;line-height:1.4;color:#111827;margin-bottom:9px}
.dt-badges{display:flex;gap:7px;flex-wrap:wrap;align-items:center;margin-bottom:16px}
.dt-sec{margin-bottom:16px}
.dt-lb{font-size:12px;font-weight:700;color:var(--sub);margin-bottom:6px;
  text-transform:none;letter-spacing:.2px}
.dt-txt{font-size:13.5px;line-height:1.65;color:#1f2937;background:#f8fafc;
  border:1px solid #eef1f4;border-radius:9px;padding:11px 13px;word-break:break-word}
.dt-txt.ok{background:#f0fdf4;border-color:#bbf7d0;color:#065f46}
.dt-txt.warn{background:#fffbeb;border-color:#fde68a;color:#92400e}
.dt-txt.bad{background:#fef2f2;border-color:#fecaca;color:#991b1b}
.dt-sub{font-size:11.5px;color:#9ca3af;margin-top:5px}
.dt-grid{display:grid;grid-template-columns:auto 1fr;gap:8px 16px;font-size:13px}
.dt-k{color:var(--sub);white-space:nowrap}
.dt-v{color:#1f2937;word-break:break-word}
.dt-imgs{display:flex;flex-wrap:wrap;gap:8px}
.dt-imgs img{width:94px;height:94px;object-fit:cover;border-radius:9px;border:1px solid var(--line);
  cursor:zoom-in;background:#f3f4f6}
.dt-imgs img:hover{border-color:#2563eb;opacity:.9}
#dt-acts{flex-wrap:wrap}

/* ── 列表「执行人」列：多人的时候把名字都列出来 ── */
.c-a .who{font-weight:600}
.c-a .wholist{display:flex;flex-direction:column;gap:2px}
.c-a .wline{display:flex;align-items:center;gap:5px;font-size:13px;line-height:1.45}
.c-a .wline .nm{font-weight:600;color:#1f2937}
.c-a .wline .st{font-size:10.5px;padding:1px 5px;border-radius:5px;flex:none;
  font-weight:700;line-height:1.5}
.c-a .wline .st.todo{background:#f1f5f9;color:#64748b}
.c-a .wline .st.doing{background:#dbeafe;color:#1d4ed8}
.c-a .wline .st.done{background:#d1fae5;color:#047857}
.c-a .wmore{font-size:11.5px;color:var(--sub);margin-top:3px}
.c-a .wall{font-size:12.5px;color:#374151;line-height:1.6;font-weight:600}

/* ── 详情里每个人的进度条 ── */
.p-list{display:flex;flex-direction:column;gap:7px}
.p-row{display:flex;align-items:center;gap:9px;padding:8px 11px;border-radius:9px;
  background:#f8fafc;border:1px solid #eef1f4;flex-wrap:wrap}
.p-row.me{background:#f0f9ff;border-color:#bae6fd}
.p-row .pnm{font-weight:700;font-size:13.5px;color:#1f2937;white-space:nowrap}
.p-row .pdp{font-size:11.5px;color:var(--sub)}
.p-row .sp{flex:1}
.p-row .pact{display:flex;gap:5px;flex-wrap:wrap}
.p-row .pnote{flex-basis:100%;font-size:12px;color:#475569;line-height:1.55}
.p-row .pnote b{color:#065f46}
.p-row .pwait{font-size:12px;color:#b45309;font-weight:600}
/* ★ 2026-10-26 第 92 批：执行人那行末尾的「×」（移出）。
   只在有权限时出现，所以做成很轻的小方块 —— 不抢「开始做/完成」的视觉重心，
   但鼠标移上去立刻变红，点之前就知道是删。 */
.p-row .pdel{flex:none;width:23px;height:23px;padding:0;line-height:1;border-radius:6px;
  border:1px solid #e5e7eb;background:#fff;color:#94a3b8;font-size:15px;font-family:inherit;
  cursor:pointer;transition:.14s}
.p-row .pdel:hover{background:#fef2f2;border-color:#fecaca;color:#dc2626}
/* 「＋ 拉人一起干」那一行 —— 放在执行人区块的标题右边 */
.dt-lbw{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.dt-lbw .dlad{margin-left:auto;flex:none}
/* 拉人弹窗 */
.jbody{padding:0 18px 16px}
.jtip{font-size:12.5px;font-weight:700;color:#334155;margin:0 0 9px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.jinp{width:100%;box-sizing:border-box;height:38px;border:1px solid #dbe2ea;border-radius:9px;
  padding:0 11px;font-size:13.5px;font-family:inherit;margin-bottom:10px;outline:none}
.jinp:focus{border-color:#93c5fd;box-shadow:0 0 0 3px rgba(59,130,246,.12)}
.jlist{max-height:50vh;overflow:auto;overscroll-behavior:contain}
.jlist.busy{opacity:.55;pointer-events:none}
.jgrp{margin-bottom:10px}
.jgrphd{font-size:11.5px;font-weight:700;color:#64748b;padding:3px 2px 6px;
  position:sticky;top:0;background:#fff;z-index:1}
.jrow{display:flex;align-items:center;gap:8px;width:100%;box-sizing:border-box;
  padding:8px 11px;margin-bottom:5px;border-radius:8px;border:1px solid #eef1f4;
  background:#f8fafc;color:#1f2937;font-size:13.5px;font-family:inherit;
  text-align:left;cursor:pointer;transition:.14s}
.jrow:hover{border-color:#bae6fd;background:#f0f9ff}
.jrow.on{background:#f8fafc;border-color:#e2e8f0;color:#94a3b8;cursor:default}
.jrow .jnm{font-weight:700}
.jrow .jdp{font-size:11.5px;color:#94a3b8}
.jrow .jplus{margin-left:auto;font-size:12px;color:#2563eb;font-weight:700;white-space:nowrap}
.jrow .jon{margin-left:auto;font-size:11.5px;color:#94a3b8;font-weight:700;white-space:nowrap}
.jnone{padding:22px 8px;text-align:center;color:#94a3b8;font-size:13px}
.jfoot{margin-top:9px;padding-top:9px;border-top:1px solid #f1f5f9;
  font-size:11.5px;color:var(--sub);line-height:1.55}
/* ★ 2026-10-12 第 53 轮：已停用账号那一行单独标出来。
   为什么要标：历史任务里挂着离职的人是正常的，不标清楚老板会以为系统坏了；
   而且只有「单独挂在一个停用账号上」的任务才会留在这儿（还有别人一起干的
   已在停用时自动摘除），那种必须让人看见「需重新派人」。 */
.p-row.off{background:#f8fafc;border-color:#e2e8f0}
.p-row.off .pnm{color:#94a3b8}
/* 灰标「已停用」：详情页执行人行 + 列表页执行人列都用它。
   ★ 单独一个类（不是 .p-row .poff）—— 列表页那个要用在 .wline 里。 */
.poff{font-size:10.5px;padding:1px 6px;border-radius:5px;margin-left:5px;
  background:#e2e8f0;color:#64748b;font-weight:700;white-space:nowrap;
  display:inline-block;vertical-align:middle}

/* 列表行可点（进详情） */
#listwrap tbody tr{cursor:pointer}
#listwrap tbody tr:hover{background:#f8fafc}
.tname{color:#1d4ed8}
#listwrap tbody tr:hover .tname{text-decoration:underline}
.who{color:#1d4ed8}
#listwrap tbody tr:hover .who{text-decoration:underline}
.acts{position:relative;z-index:1}

/* ══════════ 手机适配（车间场景）══════════ */
@media(max-width:820px){
  .wrap{padding:11px 11px 70px}
  .top{padding:9px 12px;gap:8px}
  .top .logo{font-size:14px}
  .kpis{grid-template-columns:repeat(2,1fr)}
  /* ★ 2026-09-20 第 24 轮：手机端卡片原来照搬电脑端的内边距（18px 左右），
     结果格子最小宽度被撑到 168+36=204px，390px 手机放两列要 418px —— 放不下，
     自动塌成一列，7 个卡片占了 4 行，反而把「全部任务」推到了第二屏。
     这里把手机端卡片自己的 padding 和最小宽度都收一档，让两列真正排得下。 */
  .k{padding:11px 12px}
  /* ★ 2026-09-20 第 24 轮：手机端卡片高度不齐的根因在这。
     「全部任务」那张卡比别的多一行小注（.k .d，如"共 48 条"），
     它高 102px，没小注的卡片只有 80px —— 差 22px。
     CSS Grid 会把同一行的格子拉伸成等高，于是整个栅格被这张高卡撑高，
     7 个卡片从 2 行摊成 4 行，手机上要往下滑两屏才看完，反而不好用。
     手机上这行小注字本来就只有 12px、看不清，还占地方，直接收掉。 */
  .k .d{display:none}
  /* ★ 2026-09-20 第 23 轮：标签跟数字一起放大（手机端）。
     这里是 400~820px 的中间档（大屏手机横屏、小平板），
     比 400px 以下稍宽，可以给到跟电脑端接近的字号。 */
  .k .l{font-size:16px;line-height:1.25;margin-bottom:5px}
  .k .v{font-size:25px}
  .frm{grid-template-columns:1fr}
  .mbox{padding:18px 16px}
  /* 表格 → 卡片流 */
  table,thead,tbody,tr,td{display:block}
  thead{display:none}
  /* 卡片流不能固定行高，否则文字会叠在一起 */
  #listwrap tbody tr{height:auto}
  tbody tr{border:1px solid var(--line);border-radius:11px;padding:12px 13px;
    margin-bottom:10px;background:#fff}
  tbody tr:hover{background:#fff}
  tr.overdue{background:#fff7f7;border-color:#fecaca}
  tr.soon{background:#fffcf5;border-color:#fde68a}
  tbody td{border:none;padding:5px 0;display:flex;justify-content:space-between;
    align-items:flex-start;gap:12px}
  tbody td::before{content:attr(data-label);font-weight:700;color:var(--sub);
    font-size:12px;flex:none;padding-top:1px}
  tbody td[data-label="标题 / 详细要求"]{display:block;padding:0 0 6px}
  tbody td[data-label="标题 / 详细要求"]::before{display:none}
  /* ★ 2026-09-21：手机端「任务编号」独立成一行小标题（在标题上方），
     因为窄屏下它和标题挤一行会把标题挤到第二行，白占半行。
     靠 data-label 显示「任务编号」四个字，跟别的字段一致。 */
  tbody td[data-label="任务编号"]{padding:0 0 2px;align-items:center}
  tbody td[data-label="任务编号"]::before{font-size:11px;padding-top:0;color:#9ca3af}
  /* ★★ 手机屏窄，编号稍微收一点，让它不占太多宽度。
     桌面那套（11.5px + 6px 内边距 ≈ 62px）在 375 宽下偏大。
     ★ 别再往下压了：10px 在手机上已经是能看清的下限。 */
  .tno{font-size:10.5px;padding:1px 5px;letter-spacing:0}
  tbody td[data-label="操作"]{display:block;padding-top:9px;border-top:1px solid #f1f3f5;
    margin-top:6px}
  tbody td[data-label="操作"]::before{display:none}
  /* ★★ 2026-10-10 已完成分割线（手机端）。
     手机端整张表变成了卡片流：tbody tr 有白底 + 圆角边框 + 12/13 内边距，
     td 是 flex 且用 ::before 挂 data-label。分割行这两样都得摘掉 ——
     不然它会渲染成一个空卡片，还冒出一个不存在的字段名。
     字号和桌面保持一致（16px），只把两侧间距收窄，360px 屏也放得下。 */
  #listwrap tbody tr.done-sep{border:none;background:transparent;
    padding:10px 0 12px;margin:4px 0 2px;border-radius:0}
  #listwrap tbody tr.done-sep:hover{background:transparent}
  #listwrap tbody tr.done-sep td{display:block;padding:0}
  #listwrap tbody tr.done-sep td::before{display:none}
  .dsep{gap:9px}
  .dsep span{font-size:16px;letter-spacing:.03em}
  /* 手机上标题区自然排，两行限制放开 */
  .tline2{max-width:none;white-space:normal}
  .tbl .c-t{min-width:0;max-width:none}
  /* 手指点得中 */
  .iconbtn{padding:9px 14px;font-size:13px;min-height:38px}
  /* ★ 2026-09-21：手机端 thead 整个隐藏（见上面 thead{display:none}），
     表头点不到，「截止时间排序」全靠 .tools 里那个 #fsort 下拉。
     这里把下拉放大到够手指点。 */
  .tools select,.tools input{min-height:38px}
  .acts .iconbtn{flex:1;text-align:center}
  .tdetail{max-width:none}
  /* 手机上按钮大一点，方便点 */
  .imgadd .btn{flex:1;justify-content:center;min-height:40px}
  .imgtip{width:100%;text-align:center}
  .thumb{width:66px;height:66px}

  /* 详情弹窗铺满屏，方便车间里看 */
  .mbox-detail{max-width:none;width:100%;max-height:94vh}
  .dt-body{max-height:none;flex:1}
  #mo-detail .mbox{display:flex;flex-direction:column;max-height:94vh}
  .dt-imgs img{width:88px;height:88px}
  .dt-title{font-size:17px}
  .mbox{margin:0 auto}

  /* 日历：手机上别超出屏幕 */
  .duequick .dueq{flex:1;text-align:center;min-height:36px;padding:7px 4px;font-size:12.5px}
  /* ★ 第 17 轮：手机上重复面板要手指点得中，31 个日子也得排得下 */
  .rp-grp{gap:7px}
  .rp-cap{width:26px;font-size:11.5px}
  .rp-chips{gap:4px}
  .rp-chip{min-width:29px;padding:8px 0;font-size:12.5px;min-height:34px}
  .rp-extra{padding:10px 9px}
  .calpop{position:fixed;left:6px;right:6px;top:auto;bottom:8px;z-index:150}
  .calbox{width:auto;max-width:none;padding:13px 12px 10px;
    box-shadow:0 -4px 30px rgba(15,17,21,.25)}
  .cal-d{height:38px;font-size:14px}
  .cal-nav{width:34px;height:34px}
  .cal-q{min-height:34px;padding:6px 12px}

  /* 卡片流下时间/状态并排也窄一点 */
  tbody td[data-label="创建时间"],
  tbody td[data-label="完成时间"]{font-size:12.5px}
  .imgbadge{font-size:11.5px}

  /* ★ 2026-09-21：手机上排序提示条要能换行、别顶出屏幕。
     390px 屏减去左右内边距只剩 360 出头，「正在按截止时间排序：最急在前 ▲
     恢复默认顺序」一行放不下，得允许折行。 */
  .sortnote{font-size:12px;padding:7px 9px;gap:6px}
  .sortnote .lnk{font-size:12px}

  /* 人员快捷键：手机上按部门分组，一个部门一行。
     ★ 第 14 轮改用上下格式（名字在上、数量在下），框内换行不横滑 ——
       手机上一只手拿着，横滑很难被发现，人会「凭空消失」。
     ★ 第 15 轮：加了徐晨晨（其他部门 4→5 人）后，360px 窄屏从 341px 涨到 384px。
       胶囊本身已经贴着 30px 的触控下限、不能再压了（再小手指点不准），
       所以这轮只收「胶囊外面」的空隙：框内间距、框间距、行间距各收 1px。
       宁可看着挤一点，也不让按钮小到点不准。 */
  .pbar-in{flex-wrap:wrap;overflow:visible;padding:4px;gap:4px;
    align-items:center}
  .pchip{flex:0 0 auto;padding:5px 9px;font-size:12.5px;min-height:30px}
  .pallwrap{width:100%;padding:0;flex:0 0 auto}
  .pallwrap .pghd{display:none}
  .pbar-groups{width:100%;gap:4px;display:block}
  .pgroup{padding:2px 4px;margin-bottom:4px;display:flex;align-items:center;gap:4px}
  .pgroup:last-child{margin-bottom:0}
  /* 竖排标签跟着小一号，别把框撑高。
     ★ 2026-09-18：部门标签改成实底色块后，内边距要能撑出色块，
       同时还得压住高度 —— 手机屏幕窄，这一排不能长太高。 */
  .pghd{padding:3px 5px;gap:0}
  .pgname{font-size:10.5px}
  .pgnum{font-size:9.5px;padding:0 3px;min-width:13px}
  /* ★ 框内换行（不横滑）：人都摆明面上，一眼看得全 */
  .pgbody{flex-wrap:wrap;overflow:visible;flex:1;min-width:0;
    row-gap:3px;gap:3px}
  /* ★ 手机上上下格式的胶囊：字号大一点好认，按钮高度守住 30px 好点 */
  .pchip.vcol{padding:3px 7px;min-width:38px}
  .pchip.vcol .pn{font-size:12.5px}
  .pchip.vcol .pc{font-size:10px;min-width:16px;padding:0 4px}
  .pgroup .pchip{padding:3px 7px;font-size:12.5px;min-height:30px;gap:2px}
  .pgroup .pchip .pc{font-size:10px;min-width:16px;padding:0 4px}

  /* 执行人多选：手机上贴在输入框下面，别跑到屏幕外 */
  .asgpop{position:fixed;left:8px;right:8px;top:auto;bottom:8px;z-index:150;
    width:auto;box-shadow:0 -4px 30px rgba(15,17,21,.25)}
  /* ★ 2026-10-22 第 63 轮：44vh → 58vh。
     44vh 是第 44 轮给「4 个部门上下堆」定的高度，那时内容一屏根本装不下，
     44vh 只是让面板别占满屏。现在窄屏是 2 列 × 2 排，4 个部门一共 484px 左右，
     844 高的手机上 44vh 只有 371px —— 一屏只看得见 3 个部门，还得滚，
     跟「一屏看全公司」的初衷反着来。58vh(≈489) 刚好装下。 */
  .asglist{max-height:58vh}
  .asgrow{padding:10px 11px;font-size:14.5px;min-height:42px}
  .asgbox{min-height:44px}
  .achip{font-size:13px;padding:4px 9px 4px 11px}
  .asgfoot{flex-wrap:wrap}
}

/* 详情弹窗在窄屏上贴底显示，像个抽屉 */
@media(max-width:820px){
  #mo-detail{padding:8px}
  #mo-detail .mbox{border-radius:14px}
}
@media(max-width:400px){
  /* ★ 2026-09-20 第 24 轮：手机端卡片排布修正。
     390px 屏幕实测：两列 → 一列（7 个卡片占 4 行），根因是格子最小宽度被
     .k 自己的 padding（18px）撑大了，auto-fit 判断"排不下"就自动降成一列。
     这里连同 .kpis 的最小宽度一起收窄，并把 .k 的 padding 提前到上面
     820px 档里统一处理（见 @media(max-width:820px)）。 */
  .kpis{grid-template-columns:1fr 1fr;min-width:0}
  /* ★ 2026-09-20 第 23 轮：老板要求「手机端的标签文字也要改大，
     尽量改得接近于数字那么大」。
     手机一行两个卡片，字号不能照搬电脑端的 22/30（会挤爆），
     按比例缩一档：标签 19px、数字 26px —— 两者差 7px，看着还是一档的。
     「3天内到期」5 个字 × 19px ≈ 95px，卡片可用宽度约 130px，放得下不换行。 */
  .k{padding:10px 11px}
  .k .l{font-size:15px;line-height:1.25;margin-bottom:4px}
  .k .v{font-size:23px}
}

@media print{
  /* ★ 2026-09-21：.sortnote 也加进来 —— 排序提示条是屏幕上的操作提示，
     打到纸上就是一条没头没尾的蓝条，得藏掉。 */
  .top,.tools,.iconbtn,.macts,.noprint,.sortnote{display:none!important}
  body{background:#fff}
  .card{box-shadow:none;border:1px solid #ccc}
}

/* ══════════════════════════════════════════════════════════
   ★★ 2026-09-21 新增：历史超期次数 / 增加新人 / 人员管理
   ══════════════════════════════════════════════════════════ */

/* ── 统计页那个可点的超期次数 ──
   要让人一眼看出「这个数字能点」。所以给虚线下划线 + 手型光标，
   鼠标移上去底色变一下。光靠颜色不够 —— 数字后面那行小字
   「点数字看明细」是明说的，两层提示。 */
.ovdnum{cursor:pointer;text-decoration:underline dotted;
  text-underline-offset:3px;transition:.12s;padding:1px 2px;border-radius:4px}
.ovdnum:hover{background:#fee2e2}
/* ★ 2026-10-23 第 66 轮：「被打回」那个数字也能点，样式跟超期次数一个套路，
   但底色换成琥珀（这一列本来就是橙的）。 */
.rejnum{cursor:pointer;text-decoration:underline dotted;
  text-underline-offset:3px;transition:.12s;padding:1px 2px;border-radius:4px}
.rejnum:hover{background:#fef3c7}
/* 明细弹窗里的任务标题 —— 点一下直接打开那条任务 */
.odlink{cursor:pointer;border-radius:4px;padding:1px 2px}
.odlink:hover{background:#eff6ff;color:#1a5fb4;text-decoration:underline}

/* ── 超期明细弹窗里的每一条 ──
   一条一个卡片，横向排：序号 + 标题 + 来源标签；
   下面一行小字写截止日、超了几天、什么时候记的。 */
.odbody{max-height:56vh;overflow:auto;margin-bottom:4px}
.oditem{border:1px solid #e5e7eb;border-radius:10px;padding:10px 12px;
  margin-bottom:8px;background:#fff}
.oditem.gone{background:#f9fafb;opacity:.72}
.odh{display:flex;align-items:center;gap:8px;margin-bottom:5px}
.odh b{font-size:14px;line-height:1.35;word-break:break-word}
.odn{flex:none;width:20px;height:20px;border-radius:50%;background:#f3f4f6;
  color:#6b7280;font-size:11.5px;font-weight:700;
  display:flex;align-items:center;justify-content:center}
.ods{font-size:12px;color:#6b7280;padding-left:28px}

/* ── 「已加好，密码是 xxx」那个面板里的三行信息 ── */
.nl{display:flex;align-items:center;gap:10px;padding:7px 0;
  border-bottom:1px dashed #e5e7eb;font-size:14px}
.nl:last-of-type{border-bottom:0}
.nl span{flex:none;width:48px;color:#6b7280;font-size:12.5px}
.nl b{font-size:15px;letter-spacing:.3px}

/* ── 人员管理表格 ──
   自己写一套，不套统计页那套 —— 统计页表格在小屏走卡片流（data-label），
   这里列少、内容短，直接在弹窗里横向滚动更省事。 */
.stwrap{max-height:56vh;overflow:auto;border:1px solid #e5e7eb;border-radius:10px}
.stattbl{width:100%;border-collapse:collapse;font-size:13px}
.stattbl th{position:sticky;top:0;background:#f9fafb;text-align:left;
  padding:9px 11px;font-size:12px;color:#6b7280;border-bottom:1px solid #e5e7eb;
  white-space:nowrap;z-index:1}
.stattbl td{padding:9px 11px;border-bottom:1px solid #f3f4f6;vertical-align:middle}
.stattbl tr:last-child td{border-bottom:0}
.stattbl tr.off{background:#fafafa}
.stattbl tr.off td{color:#9ca3af}

/* ══════════ ★ 2026-10-12 第 51 轮：人员管理新增「账号 / 密码」两列 ══════════
   老板原话：「人员管理页面内的姓名-部门后再加两个信息按钮：账号-密码，
              最右侧再加1个编辑按钮，这些只有老板能全部看到和修改。」
   ★ 账号 / 密码 用等宽字体：这是要【念给员工】或【复制粘贴】的凭据，
     等宽才好逐位对（0/O、1/l 这种最容易看错）。
   ★ 密码默认就是明文显示（老板要的就是「看到密码」），后面跟一个 👁
     可以临时遮起来 —— 跟产品中心那边「列表页直接展示密码 + 眼睛图标
     切换显隐」是同一套习惯，老板用着顺手。 */
.stattbl{min-width:980px}
.cacct{font-family:Consolas,Monaco,"Courier New",monospace;font-size:12.5px;
  color:#334155;white-space:nowrap}
.cpw{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}
.cpw .cpwv{font-family:Consolas,Monaco,"Courier New",monospace;font-size:12.5px;
  color:#0f172a;letter-spacing:.4px}
.cpw .cpwv.masked{letter-spacing:1.5px;color:#94a3b8}
.cpw .cpw-none{color:#9ca3af;font-size:12px}
.iconmini{border:0;background:transparent;cursor:pointer;padding:1px 3px;
  font-size:12.5px;line-height:1;color:#6b7280;border-radius:5px}
.iconmini:hover{background:#f1f5f9;color:#2563eb}
/* 「只读」标记：一眼看出这个账号跟别人不一样 */
.ro-tag{display:inline-block;margin-left:5px;padding:1px 6px;border-radius:9px;
  font-size:10.5px;font-weight:700;background:#e0e7ff;color:#4338ca;
  vertical-align:1px}

/* ══════════ ★ 2026-10-12 第 51 轮：只读账号（AI 员工）══════════
   任务详情底部那句「可以看，不能改」，和消息区那句说明。 */
.ro-hint{display:inline-flex;align-items:center;gap:5px;margin-right:auto;
  font-size:12.5px;color:#4338ca;background:#eef2ff;border:1px solid #c7d2fe;
  border-radius:8px;padding:5px 11px}
.msg-ro{font-size:12.5px;color:#4338ca;background:#eef2ff;
  border:1px solid #c7d2fe;border-radius:8px;padding:10px 12px;text-align:center}
/* 顶栏那个「只读」标在窄屏上缩小一点，别把名字挤掉 */
@media(max-width:520px){
  .ro-tag{font-size:10px;padding:1px 5px}
}

/* 只读账号：再加一道纯 CSS 的兜底。
   app.js 的 enterApp 里会给 body 挂 .ro-account，这里直接把几个
   「看一眼就知道不该有」的写入口按死 —— 万一哪天 JS 那几行被改坏了，
   起码新建任务这个最大的口子不会露出来。
   ★ 不是权限，服务端那一排 require_writer 才是。 */
body.ro-account #btn-new,
body.ro-account #btn-import{display:none !important}

/* ══════════ ★ 2026-10-08 第 45 轮：我的账号（只读信息表）══════════
   一行一个字段：左边名称、中间值、右边小字注解。
   ── 为什么值用等宽字体 ──────────────────────────────
   账号 ID、邀请码这类东西是给人「报给管理员」用的，
   等宽才好逐位念、逐位对（尤其是 0/O、1/l 这种）。
   ★ 不做成输入框：老板明确要求不可修改。输入框即使是 readonly
     也会让人想去点一下，点了发现没反应反而更困惑。
   ── 为什么用 dl 那种「标签在左、值在右」而不是表格 ──
   字段少（6-8 行），表格一加边框就变成一张「报表」，
   这里是「我自己的信息卡」，松一点更合适。 */
.acct{border:1px solid var(--line);border-radius:10px;overflow:hidden;
  background:#fff;margin:2px 0 4px}
.acct-row{display:flex;align-items:baseline;gap:10px;
  padding:10px 13px;border-bottom:1px solid #f1f3f5}
.acct-row:last-child{border-bottom:0}
.acct-k{flex:0 0 76px;font-size:12.5px;color:#6b7280;font-weight:600}
.acct-v{flex:1;min-width:0;font-size:14px;color:#111827;font-weight:600;
  font-family:ui-monospace,Menlo,Consolas,monospace;
  word-break:break-all;letter-spacing:.01em}
.acct-n{flex:0 0 auto;font-size:11.5px;color:#9ca3af;
  font-family:inherit;font-weight:400}
@media(max-width:420px){
  /* 窄机上注解没地方放，让它自己换到下一行 */
  .acct-row{flex-wrap:wrap;padding:9px 11px}
  .acct-k{flex:0 0 68px;font-size:12px}
  .acct-v{font-size:13.5px}
  .acct-n{flex:1 0 100%;margin-left:78px;margin-top:1px}
}

@media(max-width:820px){
  /* 手机上人员管理表格横向滚动，别把列挤成一团 */
  .stwrap{overflow-x:auto}
  /* ★ 第 51 轮：加了「账号/密码/编辑」三列，原来 520px 装不下了 ——
     最小宽度跟着列数一起放大，手机上左右滑着看。 */
  .stattbl{min-width:900px}
  .stattbl th,.stattbl td{padding:10px 9px}
  /* 弹窗本身在手机上是贴底的，这里收一下最大高度 */
  #mo-staff .mbox{max-width:100%}
  .odbody{max-height:48vh}
}
@media(max-width:400px){
  .stattbl{min-width:860px}
}


/* ══════════ ★ 2026-09-23 第 32 轮：人员管理「可见范围」 ══════════
   老板要的是「每个人的权限，能看什么」。
   这一列平时是一行小字，点一下弹多选框。 */
.scopelnk{
  font-size:12px;color:#6b7280;text-decoration:none;border-bottom:1px dashed #d1d5db;
  cursor:pointer;white-space:nowrap;padding-bottom:1px
}
.scopelnk:hover{color:#2563eb;border-bottom-color:#93c5fd}
/* 配过权限的用蓝色加粗 —— 一眼能看出「这人跟别人不一样」 */
.scopelnk.on{color:#1d4ed8;font-weight:600;border-bottom-color:#93c5fd}

/* 多选面板：一列勾选框，点整行都能勾（手机上勾选框太小） */
.scbody{max-height:46vh;overflow:auto;margin:6px 0 2px;padding:2px}
.scitem{
  display:flex;align-items:center;gap:10px;padding:10px 12px;margin-bottom:6px;
  border:1px solid #e5e7eb;border-radius:9px;cursor:pointer;font-size:14px;
  transition:background .12s,border-color .12s
}
.scitem:hover{background:#f9fafb}
.scitem.on{background:#eff6ff;border-color:#93c5fd}
.scitem input{width:17px;height:17px;cursor:pointer;flex:0 0 auto;accent-color:#2563eb}
.scitem span{flex:1 1 auto}
/* 「敏感」标记：财务/人事。勾了就等于把这两个部门的数据给他看，
   这里给个可见的提醒 —— 老板手一滑勾上的代价比较大。 */
.scwarn{
  font-size:11px;color:#b45309;background:#fef3c7;border-radius:20px;
  padding:1px 8px;flex:0 0 auto
}

/* ══════════════════════════════════════════════════════════
   留言（卡点对话流）  ★ 2026-09-23 第 33 轮新增
   ══════════════════════════════════════════════════════════
   老板要的是「在卡住的下面有个对话框」，所以视觉上按聊天记录做：
   谁说的、什么时候说的、说了什么，一条一条按时间排下来。

   ★ 配色沿用系统里那几个变量（--amber 是卡点用的黄，--blue 是自己说的话），
     不引入新色，免得跟现有页面打架。
   ══════════════════════════════════════════════════════════ */

/* 顶栏未读小红点 —— 只是个状态灯，不是按钮 */
/* ★★ 2026-10-05 第 43 轮：红点外面包了一层常驻按钮 .msg-btn。
   原来 .msg-dot 自己就是按钮、平时 display:none —— 没消息时整个入口消失，
   老板找不到通知按钮（原话「通知按钮在哪里？需要显示」）。现在拆成两层：
     .msg-btn  壳子，永远在（深色顶栏上的描边小方块 + 铃铛图标）
     .msg-dot  数字，绝对定位挂在铃铛右上角，按未读数显隐
   风格照抄顶栏已有的 .btn.gh（透明底 + 1px #4b5563 描边），跟着深色顶栏走。 */
.msg-btn{
  position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;padding:0;flex:0 0 auto;margin-right:6px;
  background:transparent;border:1px solid #4b5563;border-radius:8px;
  color:#e5e7eb;cursor:pointer;user-select:none;transition:.15s;
}
.msg-btn:hover{background:#2c3038;color:#fff}
.msg-btn:active{transform:scale(.94)}
.msg-btn:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.msg-ico{display:block}

.msg-dot{
  display:none;position:absolute;top:-7px;right:-7px;
  min-width:18px;height:18px;padding:0 5px;box-sizing:border-box;
  border-radius:9px;background:var(--red);color:#fff;
  font-size:10.5px;font-weight:700;line-height:18px;text-align:center;
  box-shadow:0 0 0 2px #15171c
}
.msg-dot.on{display:block;animation:msgpulse 1.8s ease-in-out 3}
/* 描边用顶栏底色 #15171c，让红点从铃铛上「浮」起来 */
@keyframes msgpulse{0%,100%{box-shadow:0 0 0 2px #15171c}
  50%{box-shadow:0 0 0 6px rgba(220,38,38,.28)}}

/* 留言区外壳 */
.msg-sec{border:1px solid var(--line);border-radius:11px;padding:11px 13px;background:#fff;
  margin-bottom:16px}
/* ★ 卡住的任务：黄框，跟上面「卡在哪」那块呼应，一眼找到 */
.msg-sec.stuck{border-color:#fcd34d;background:#fffdf6}

.msg-head{display:flex;align-items:center;gap:8px;cursor:pointer;user-select:none}
.msg-head:hover .dt-lb{color:var(--ink)}
.msg-badge{font-size:11.5px;font-weight:700;color:#fff;background:var(--red);
  border-radius:20px;padding:1px 8px;margin-left:auto}
.msg-badge:not(.on){background:#e5e7eb;color:#6b7280}
.msg-fold{font-size:12px;color:var(--blue);flex:0 0 auto;margin-left:6px}

.msg-body{display:none;margin-top:10px}
.msg-body.on{display:block}
.msg-empty{font-size:12.5px;color:#9ca3af;padding:14px 4px;text-align:center}

/* 消息列表：定高可滚。不定高的话，聊得多了详情弹窗本身会滚，
   输入框就被顶到看不见的地方去了。 */
.msg-list{max-height:260px;overflow-y:auto;padding:2px 2px 4px;
  display:flex;flex-direction:column;gap:9px}

/* ══ 2026-10-05 第 42 轮：系统事件（新增 / 卡点 / 打回 / 超期）══
   它不是「谁说的话」，是「这条任务发生了什么」—— 所以不跟聊天气泡
   抢位置：整行居中、灰底、无边框无头像。视觉上退到后面，
   但一直在，翻记录时看得见。
   ★ 标签用颜色区分轻重：超期/打回是红（要处理），
     新增是蓝（知道就行），卡点是黄（跟页面上那套橙黄一个意思）。 */
.msg-sys{display:flex;align-items:center;justify-content:center;gap:6px;
  flex-wrap:wrap;text-align:center;padding:2px 6px;
  font-size:12px;color:#6b7280;line-height:1.5}
.msg-sys-tag{flex:0 0 auto;font-size:10.5px;line-height:16px;padding:0 6px;
  border-radius:9px;background:#eef1f4;color:#5f6b7a}
.msg-sys-txt{word-break:break-word}
.msg-sys-at{flex:0 0 auto;font-size:11px;color:#9ca3af}
.msg-sys[data-k="overdue"] .msg-sys-tag,
.msg-sys[data-k="rejected"] .msg-sys-tag{background:#fee2e2;color:#991b1b}
.msg-sys[data-k="assign"] .msg-sys-tag{background:#dbeafe;color:#1e40af}
.msg-sys[data-k="blocked"] .msg-sys-tag{background:#fef3c7;color:#92400e}

.msg-item{background:#f8fafc;border:1px solid #eef1f4;border-radius:10px;
  padding:8px 11px;max-width:92%;align-self:flex-start;word-break:break-word}
/* 自己说的话：靠右、蓝边，跟别人的分开 */
.msg-item.me{align-self:flex-end;background:#eff6ff;border-color:#bfdbfe}
/* 老板说的话：加一道金边，一眼能认出「这条是乔总说的」 */
.msg-item.boss{border-color:#fcd34d}

.msg-meta{display:flex;align-items:center;gap:7px;font-size:11.5px;color:var(--sub);
  margin-bottom:3px;flex-wrap:wrap}
.msg-meta b{color:var(--ink);font-size:12.5px;font-weight:700}
.msg-item.boss .msg-meta b{color:#92400e}
.msg-dept{background:#e5e7eb;border-radius:20px;padding:0 6px;font-size:10.5px}
.msg-at{color:#9ca3af}
.msg-del{margin-left:auto;color:#cbd5e1;cursor:pointer;font-size:11px;opacity:0;
  transition:opacity .12s}
.msg-item:hover .msg-del{opacity:1}
.msg-del:hover{color:var(--red)}
.msg-text{font-size:13.5px;line-height:1.6;color:#1f2937}
.msg-imgs{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
.msg-imgs img{width:76px;height:76px;object-fit:cover;border-radius:8px;
  border:1px solid var(--line);cursor:zoom-in;background:#f3f4f6}
.msg-imgs img:hover{border-color:var(--blue);opacity:.9}

/* 输入区 */
.msg-write{margin-top:11px;border-top:1px solid var(--line);padding-top:10px}
.msg-pick{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:7px}
.msg-th{position:relative;display:inline-block;width:58px;height:58px}
.msg-th img{width:100%;height:100%;object-fit:cover;border-radius:8px;
  border:1px solid var(--line)}
.msg-th i{position:absolute;top:-5px;right:-5px;width:18px;height:18px;border-radius:50%;
  background:var(--red);color:#fff;font-style:normal;font-size:12px;line-height:18px;
  text-align:center;cursor:pointer}
.msg-th i.up{background:var(--green);cursor:default}
.msg-write textarea{width:100%;border:1px solid var(--line);border-radius:9px;
  padding:9px 11px;font-size:13.5px;line-height:1.55;resize:vertical;min-height:44px;
  background:#fff}
.msg-write textarea:focus{outline:none;border-color:var(--blue);
  box-shadow:0 0 0 3px rgba(37,99,235,.1)}
.msg-bar{display:flex;align-items:center;gap:9px;margin-top:7px}
.msg-clip{font-size:17px;cursor:pointer;line-height:1;padding:3px 5px;border-radius:7px;
  color:var(--sub)}
.msg-clip:hover{background:#f3f4f6;color:var(--ink)}
.msg-bar .btn{margin-left:auto}


/* ══════════════════════════════════════════════════════════
   产品采购负责人（2026-09-29 第 38 轮）
   ══════════════════════════════════════════════════════════
   这一页的核心是「一眼扫到某个月在干什么」，所以月份格子做成
   等宽小色块，靠颜色分辨动作，不用读文字也知道大概。
   ★ 配色沿用全局变量：蓝=销售、橙=研发、绿=上架、灰=没安排。
   ────────────────────────────────────────────────────────── */

/* 12 个月份列太宽，手机上必然放不下。
   用横向滚动而不是改成卡片流：这一页的价值在「一行看全 12 个月」，
   拆成卡片反而把横向对比打散了 —— 老板想看的是趋势，不是单月。 */
.pwrap{overflow-x:auto;-webkit-overflow-scrolling:touch;border:1px solid var(--line);
  border-radius:10px;background:#fff}
.pwrap table{min-width:1180px;border-collapse:collapse}
.pwrap th,.pwrap td{border-bottom:1px solid #f1f3f5}

/* 月份格子 */
.pmo{display:inline-block;min-width:36px;text-align:center;font-size:11.5px;
  line-height:1.5;padding:3px 5px;border-radius:5px;border:1px solid transparent;
  white-space:nowrap;font-weight:600}
.pmo-s{background:#eff6ff;color:#1d4ed8;border-color:#dbeafe}   /* 销售 = 蓝 */
.pmo-r{background:#fffbeb;color:#b45309;border-color:#fde68a}   /* 研发 = 橙 */
.pmo-u{background:#ecfdf5;color:#047857;border-color:#a7f3d0}   /* 上架 = 绿 */
.pmo-0{background:#fcfcfd;color:#d8dce2;border-color:#f1f3f5}   /* 空 = 灰 */

/* 老板视角：格子是个按钮，点一下换下一种动作 */
button.pmo{cursor:pointer;transition:transform .06s ease}
button.pmo:hover{filter:brightness(.96);box-shadow:0 1px 3px rgba(16,24,40,.12)}
button.pmo:active{transform:scale(.94)}

/* 当前月那一列：整列浅蓝底，眼睛一下就能定位到「这个月」。
   ★ 2026-10-08 第 45 轮起，这个表头格不写「N月」了 —— 文字由上面
     那条吸顶 .pmonbar 负责（否则静止时上下两排月份，像 bug）。
     它保留两件事：① 占住 46px 的列宽，保证表头跟数据行列对齐；
     ② 当前月那块蓝底 —— 滚动时若吸顶条盖住它，也还有吸顶条的蓝格。 */
.pmth{width:46px;text-align:center;font-size:12px;
  /* 格子空白，但高度得跟旁边有字的表头一致，不能塌下去 */
  height:26px;padding:0}
/* 当前月：表头格不铺满整块蓝（没字，铺满就是个突兀的大蓝块），
   只在底部压一条蓝杠 —— 作用是「下面对应那一列是本月」的锚点。
   真正显眼的「10月」蓝格在吸顶条上。 */
.pmth.on{background:transparent;border-radius:0;
  box-shadow:inset 0 -3px 0 var(--blue)}
.pmc{text-align:center;padding:4px 3px}
.pmc.cur{background:#f4f8ff}

/* ══════════ ★ 2026-10-08 第 45 轮：月份吸顶条 ══════════
   老板原话：「产品采购负责人界面，向下拉就看不到月份了，
   需要把月份这一排锁定在页最上面，滚动时候保持可见。」

   ── 为什么它是一条独立的东西，而不是表格的 <thead> ──────────
   表格在 .pwrap 里，.pwrap 是 overflow-x:auto（要横滑看 12 个月）。
   一旦 overflow-x 不是 visible，浏览器就把 overflow-y 也算成 auto，
   .pwrap 于是成了「垂直滚动容器」；sticky 只认最近的滚动祖先，
   页面往下滚时 .pwrap 自己不滚，表头就粘不住。
   所以月份头必须挂在 .pwrap 外面，才吸附得到页面滚动。

   ── 位置 ────────────────────────────────────────────────
   top:52px —— 深色顶栏是 sticky top:0，高度约 52px（padding 9*2 +
   按钮 34）。让月份条正好停在顶栏下沿，不重叠、不留缝。
   手机端顶栏是两排（约 88px），在下面的 @media 里单独调。

   ── 左侧留白的宽度是「量」出来的，不是写死的 ──────────────
   一开始这里写死 438px（负责人190 + 编号78 + 产品名170），
   实测偏了 255px —— 表格是 table-layout:auto，「产品大类」被内容
   撑到 425px 宽，根本不是 CSS 里那个 min-width:170。
   所以 .pmb-spacer 的宽度改由 prodSyncMonbar() 现场量
   <thead> 前三列的真实宽度再设上去（见 app.js）。
   下面那个 438px 只是「JS 还没跑」时的初值，不用当真。 */
.pmonbar{position:sticky;top:52px;z-index:30;
  overflow:hidden;border:1px solid var(--line);border-bottom:0;
  border-radius:10px 10px 0 0;background:#f8fafc}
.pmonbar-in{display:flex;align-items:stretch;width:max-content;
  will-change:transform}
.pmb-spacer{flex:0 0 auto;width:438px;
  background:#f8fafc;border-right:1px solid #eef1f4}
.pmb-spacer.end{flex:0 0 auto;width:82px;border-right:0;
  border-left:1px solid #eef1f4}
.pmb{flex:0 0 auto;width:46px;box-sizing:border-box;
  display:flex;align-items:center;justify-content:center;
  font-size:12px;font-weight:600;color:#475569;
  padding:6px 0;border-right:1px solid #eef1f4}
.pmb.on{background:var(--blue);color:#fff;border-right-color:var(--blue)}
/* 吸顶条下面紧贴表格：把表格上边框去掉，两条并成一条线 */
.pmonbar + .pwrap{border-top:0;border-radius:0 0 10px 10px}

/* 负责人列 ★ 第 39 轮：两个人名【并排】—— 共同负责，不再写「协作」 */
.c-owner{width:190px}
.powners{display:flex;gap:5px;flex-wrap:wrap;align-items:center}
.c-code{width:78px}
.c-pname{min-width:170px;max-width:280px}
.c-sets{width:82px;text-align:center;color:#6b7280}
/* 只读时的人名做成小标签：两个人并排时一眼看出是两个人，
   不会被读成「张从政方薇」这样连在一起的一个名字。 */
.poname{font-weight:600;background:#f3f4f6;border:1px solid #e5e7eb;
  border-radius:5px;padding:1px 7px;font-size:12.5px;white-space:nowrap}

/* ══════════ ★ 2026-09-29 第 40 轮：采购员一人一个底色 ══════════
   老板原话：「每个采购姓名加个底色，便于区分」。
   ★ 六种色都刻意避开季节那三种（销售=蓝 / 研发=琥珀 / 上架=绿），
     不然一眼扫过去会分不清哪个是人名、哪个是季节。
   ★ 颜色由 app.js 的 pcolIdx(姓名) 算，同一个人永远同一个色，
     跟名单顺序无关 —— 加人减人不会把别人的颜色顶掉。 */
/* 底色都调得比季节那三个色「重」一档：销售是浅蓝(#eff6ff)、研发是浅琥珀
   (#fffbeb)、上架是浅绿(#ecfdf5)。人名用更饱和的同色系，扫一眼就能分开
   「这是个人名」还是「这是个季节」。 */
.poname.pc-0,.posel.pc-0{background:#ede9fe;color:#6d28d9;border-color:#ddd6fe} /* 紫 */
.poname.pc-1,.posel.pc-1{background:#fce7f3;color:#be185d;border-color:#fbcfe8} /* 粉 */
.poname.pc-2,.posel.pc-2{background:#cffafe;color:#0e7490;border-color:#a5f3fc} /* 青 */
.poname.pc-3,.posel.pc-3{background:#e0e7ff;color:#4338ca;border-color:#c7d2fe} /* 靛 */
.poname.pc-4,.posel.pc-4{background:#ffedd5;color:#c2410c;border-color:#fed7aa} /* 橙 */
.poname.pc-5,.posel.pc-5{background:#e2e8f0;color:#334155;border-color:#cbd5e1} /* 石板 */
/* 没指定负责人：不上色，保持中性，别让人以为「灰色」也是个人 */
.poname.pc-none,.posel.pc-none{background:#f3f4f6;color:#9ca3af;border-color:#e5e7eb}
/* 下拉框里字色别被上色盖住看不清 */
.posel.pc-0,.posel.pc-1,.posel.pc-2,
.posel.pc-3,.posel.pc-4,.posel.pc-5{font-weight:600}

/* 产品大类 / 年研发套数 的行内输入框：
   平时看着就是一行字，鼠标移上去或点进去才显出输入框的样子。
   ★ 为什么不做成弹窗：改产品名是「扫一遍顺手改」的动作，
     弹窗每次都要三步（点开/改/确定），太慢。 */
.pnameinput{width:100%;border:1px solid transparent;background:transparent;
  border-radius:6px;padding:3px 5px;font:inherit;color:inherit;outline:none}
.pnameinput:hover{border-color:var(--line);background:#fff}
.pnameinput:focus{border-color:var(--blue);background:#fff;
  box-shadow:0 0 0 2px rgba(37,99,235,.12)}
.psetsinput{width:100%;max-width:74px;text-align:center;border:1px solid transparent;
  background:transparent;border-radius:6px;padding:2px 4px;font:inherit;
  color:inherit;outline:none}
.psetsinput:hover{border-color:var(--line);background:#fff}
.psetsinput:focus{border-color:var(--blue);background:#fff;
  box-shadow:0 0 0 2px rgba(37,99,235,.12)}
/* 没人负责：红色小胶囊，扫一眼就知道这里要补人 */
.ptbd{display:inline-block;background:#fef2f2;color:#b91c1c;border:1px solid #fecaca;
  border-radius:5px;padding:1px 7px;font-size:11.5px;font-weight:600}

/* 负责人下拉（只有老板看得到） */
/* 两个下拉并排（甲 / 乙），所以单个要收窄一点 */
.posel,.posel2{border:1px solid var(--line);border-radius:6px;padding:2px 4px;
  font-size:12.5px;background:#fff;max-width:86px;outline:none}
.posel2{max-width:86px;font-size:12px}
.posel:focus,.posel2:focus{border-color:var(--blue);
  box-shadow:0 0 0 2px rgba(37,99,235,.12)}

/* 顶部图例 + 统计行 */
.plegend{display:inline-flex;gap:6px;align-items:center;flex:none}
/* 采购员配色图例：跟季节图例之间划一道竖线，别看成一伙的 */
.plegend2{margin-left:2px;padding-left:9px;border-left:1px solid var(--line);
  flex-wrap:wrap}
.psum{font-size:12.5px;color:var(--sub);margin:0 0 10px;line-height:1.6}
.psum b{color:var(--ink)}
.psum b.warn{color:#b91c1c}

/* 手机上：允许左右滑，别把格子压变形 */
@media(max-width:820px){
  .pwrap table{min-width:1080px}
  .pmo{min-width:32px;font-size:11px;padding:2px 3px}
  .psum{font-size:12px}
}

/* ══════════ ★ 2026-09-29 第 39 轮补丁：月份格子的选择菜单 ══════════
   以前点一下就循环换，老板手快连点几下把圆规、蜡笔的季节点没了。
   现在点格子弹这个小菜单，四个里挑一个 —— 多点一步，但改不坏。
   ★ 用 position:fixed 而不是 absolute：表格在 .pwrap 里能横向滚，
     absolute 会跟着表格跑，滚一下菜单就跑没了。 */
.pmenu{position:fixed;z-index:80;display:none;min-width:132px;
  background:#fff;border:1px solid var(--line);border-radius:10px;
  box-shadow:0 8px 26px rgba(15,23,42,.16);padding:5px;overflow:hidden}
.pmenu.on{display:block}
.pmenu-t{font-size:11.5px;color:var(--sub);padding:4px 7px 6px;
  border-bottom:1px solid var(--line);margin-bottom:4px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pmenu-i{display:flex;align-items:center;gap:7px;width:100%;
  border:0;background:none;border-radius:7px;padding:6px 7px;
  font:inherit;font-size:13px;color:var(--ink);cursor:pointer;text-align:left}
.pmenu-i:hover{background:var(--hoverbg,#f4f6f8)}
.pmenu-i .pmenu-dot{width:9px;height:9px;border-radius:50%;flex:none;
  border:1px solid var(--line)}
.pmenu-i.pmo-s .pmenu-dot{background:#2563eb;border-color:#2563eb}
.pmenu-i.pmo-r .pmenu-dot{background:#d97706;border-color:#d97706}
.pmenu-i.pmo-u .pmenu-dot{background:#059669;border-color:#059669}
.pmenu-i.pmo-0 .pmenu-dot{background:#fff;border-color:#cbd5e1}
.pmenu-i .pmenu-x{flex:1}
.pmenu-i.pmo-0 .pmenu-x{color:var(--sub)}
.pmenu-i .pmenu-ok{font-size:11px;color:var(--blue);flex:none}
/* 当前值：打底 + 左侧一道色条，一眼看出这格现在是什么 */
.pmenu-i.on{background:#f4f6f8;font-weight:600}
.pmenu-i.on.pmo-s{background:#eff6ff}
.pmenu-i.on.pmo-r{background:#fffbeb}
.pmenu-i.on.pmo-u{background:#ecfdf5}

@media(max-width:820px){
  .pmenu{min-width:150px}
  .pmenu-i{padding:9px 8px;font-size:14px}   /* 手指点，别太小 */
}

/* ══════════ ★ 2026-09-29 第 40 轮：手机上这页要保持「表格」══════════
   老板原话：「手机端显示的产品采购负责人列表完全不看懂，需要跟电脑
   一个格式，这个板块手机上不必需要操作更改，哪怕只是个图片都可以。」

   ★ 病根：全局有一条 table,thead,tbody,tr,td{display:block}（见上面
     820px 档），把任务列表变成一张张卡片 —— 那是给「标题+详情」那种
     竖着读的数据做的，套到「一行一个产品、12 个月横着排」的表上，
     就变成每格一行、左边挂个「3月」标签的流水账，58 个产品竖着
     堆几百行，谁也看不懂。
   ★ 所以这里把这一张表单独拉回来，恢复成真正的表格：跟电脑端
     一样的横排，左右滑着看。手机上这一页也是只读的（不放下拉框
     和输入框），表更窄、更好读。
   ★ 用 #pane-prod 限定，只影响这一页，任务列表的卡片流原封不动。 */
@media(max-width:820px){
  #pane-prod .pwrap table{display:table;min-width:1000px;border-collapse:collapse}
  #pane-prod .pwrap thead{display:table-header-group}
  #pane-prod .pwrap tbody{display:table-row-group}
  #pane-prod .pwrap tr{display:table-row;border:0;border-radius:0;
    padding:0;margin:0;background:#fff}
  #pane-prod .pwrap tr:hover{background:#fff}
  #pane-prod .pwrap tr.overdue,#pane-prod .pwrap tr.soon{background:#fff}
  #pane-prod .pwrap td{display:table-cell;justify-content:flex-start;
    padding:5px 7px;border-bottom:1px solid var(--line)}
  /* 卡片流靠 data-label 在每格前面挂「3月」字样，表格模式不需要 */
  #pane-prod .pwrap tbody td::before{display:none}
  #pane-prod .pwrap td.c-owner{width:170px}
  #pane-prod .pwrap td.pmc{text-align:center}
  /* 手机上格子本来就小，再套圆角外框就更挤了，改成纯色块 */
  #pane-prod .pwrap .pmo{min-width:30px;padding:2px 2px;font-size:11px}
  /* 横滑提示：这页在手机上是左右滑的，明说一句免得以为只有一列 */
  #pane-prod .phint{display:block}
  /* ★ 2026-10-08 第 45 轮：手机端顶栏是两排（约 88px），
     月份吸顶条要停在它下面 —— 不算准的话会被顶栏压住一截。 */
  .pmonbar{top:88px}
  /* 手机端负责人列收窄到 170px（跟上面 td.c-owner 一致），
     所以左侧留空也要跟着收：170+78+170 = 418 */
  .pmb-spacer{width:418px}
  /* 月份格在手机上小一档（跟 .pmo 的 30px 走），别挤 */
  .pmb{width:40px;font-size:11px}
}
/* 电脑端不需要这句提示 */
.phint{display:none;font-size:12px;color:var(--sub);margin:0 0 8px}

/* ══════════ ★ 2026-09-29 第 41 轮：手机端顶栏改两排 ══════════
   老板原话：「任务列表 手机端把新建任务放到右上角，第二排刷新 统计
   更多依次排列 靠右对齐。」

   ★ 改之前是什么样：顶栏是 flex-wrap:wrap，390px 屏上排成两行 ——
     第 1 行「乔渡·任务列表 + 姓名」+「+ 新建任务」，
     第 2 行「刷新 统计 更多」，但第 2 行是【靠左】的，
     右边空出一大片黑，看着没对齐。

   ★ 怎么改的：不重排 HTML（按钮元素一个没动、id 全不变，
     app.js 里的绑定照旧），纯用 CSS 让第 2 行靠右：
       1. .top 加「行间距」，两行之间拉开
       2. 隐形弹簧 .sp 在手机上有确定宽度（flex-basis），
          吃满第 1 行剩下的空间 —— 于是「新建任务」被顶到右上角
       3. 第 2 行开头插一个 .sp2（手机上才显形的弹簧），
          吃满第 2 行剩下的空间 —— 于是「刷新 统计 更多」被顶到右
   ★ 为什么不把「刷新」挪到 HTML 的第 2 行去：那要动 HTML 结构，
     牵连 app.js 的绑定和「统计」按钮变身「返回任务」的逻辑
     （见 index.html 里那段注释），风险不值当。纯 CSS 达到同样效果。 */
/* ★ 电脑端：.tool2 这一层「不存在」——display:contents 会把包裹层
   从盒模型里摘掉，里面的三个按钮直接当成顶栏的孩子参与弹性布局。
   所以电脑端长什么样，一个字都没变。
   ★ 这条必须写在 @media 上面（第 41 轮第一次把顺序写反了，
     后面的规则把前面的盖掉，白折腾一轮）。 */
.top .tool2{display:contents}
@media(max-width:820px){
  .top{row-gap:8px}
  /* 第 1 行的弹簧：给出确定宽度，把「新建任务」顶到右上角 */
  .top .sp{flex:1 1 auto;min-width:24px}
  /* ★ 窄机（≤420px，比如 360px 的老安卓）上，「乔渡·任务列表 + 姓名」
     这一串太宽（218px），加上「+ 新建任务」的 91px 就超过 360 了 ——
     新建任务会被挤到第 2 行去，第 2 行就成了 4 个按钮，
     老板要的「两排、上排一个下排三个」就散了。
     这里把标题和姓名收小一档，让第 1 行容得下。
     ★ 只收字号，不改文字内容 —— 手机上本来就该小一号。 */
  .top .logo{font-size:13px}
  .top .who{font-size:11.5px;margin-left:8px}
}
@media(max-width:420px){
  /* 再窄一档：姓名只留名字，部门那截最容易把行撑爆 */
  .top .who{margin-left:6px;font-size:11px}
  .top .brand{padding:2px 8px}
  /* ★ 第 2 行：这一层自己占满剩下的整个宽度（flex-basis:100% 强行换行），
     内部再靠右 —— 「刷新 统计 更多」就被整齐推到右边。
     ★ 为什么不是塞个空 div 当弹簧：试过，那只吃到 9px 就不动了，
       右边还空 140px。整层换行 + 内部靠右才推得干净。 */
  .top .tool2{display:flex;align-items:center;gap:8px;
    flex:1 0 100%;margin-left:auto;justify-content:flex-end}
}

/* ══════════ ★ 2026-10-12 第 57 轮：AI 来访页（#pane-aivisit） ══════════
   老板是手机用户，这一页按「手机先能看明白」来做：
     · 五个数字排一行 —— 电脑上 5 列，手机上一律拆成 2~3 列，不挤
     · 表格外面套一层 .aiv-tw（overflow-x:auto）——
       ★ 这是横向溢出的保险：万一哪列撑宽了，是卡片内部横滑，不会把整页推开
     · ★ 全页不写 white-space:nowrap（只有时间和 IP 例外）——
       经验：th{white-space:nowrap} 是这类页面在手机上横向溢出的头号元凶，
       父容器报溢出、子元素自己不报，很难查。宁可换行也不要横滑。
   按钮一律 .btn.lt（白底深字）—— 这页是白卡片，用 .btn.gh 会白字白底看不见。 */
.aiv-card{padding:14px 14px 18px}
.aiv-head{display:flex;align-items:center;justify-content:space-between;
  gap:10px;flex-wrap:wrap;margin-bottom:6px}
.aiv-head h2{margin:0;font-size:17px}
.aiv-sub{color:var(--sub);font-size:12.5px;line-height:1.65;margin:0 0 12px}
.aiv-sub b{color:var(--ink)}
.aiv-kpis{display:grid;grid-template-columns:repeat(5,1fr);gap:7px;margin-bottom:12px}
.aiv-kpi{background:#f7f8fa;border:1px solid var(--line);border-radius:9px;
  padding:8px 4px;text-align:center}
.aiv-kpi b{display:block;font-size:16px;color:var(--blue);line-height:1.35;
  font-variant-numeric:tabular-nums;word-break:break-word}
.aiv-kpi span{display:block;font-size:10.5px;color:var(--sub)}
.aiv-bar{display:flex;flex-wrap:wrap;gap:7px;align-items:center;margin-bottom:12px}
.aiv-bar select{padding:6px 8px;border:1px solid var(--line);border-radius:8px;
  background:#fff;font-size:12.5px;max-width:100%}
.aiv-sec{border-top:1px solid var(--line);padding-top:12px;margin-top:4px}
.aiv-sec h3{font-size:14px;margin:0 0 9px}
.aiv-tw{overflow-x:auto;-webkit-overflow-scrolling:touch}
.aiv-tb{width:100%;border-collapse:collapse;table-layout:fixed}
.aiv-tb th{text-align:left;font-size:11.5px;color:var(--sub);font-weight:600;
  padding:0 6px 6px 0;border-bottom:1px solid var(--line)}
.aiv-tb td{padding:7px 6px 7px 0;border-bottom:1px solid #f1f3f5;font-size:12.5px;
  vertical-align:top;word-break:break-word}
.aiv-ts{color:var(--sub);font-variant-numeric:tabular-nums;white-space:nowrap}
.aiv-src{display:inline-block;font-size:11.5px;padding:1px 6px;border-radius:6px;
  background:#f1f5f9;color:var(--slate);border:1px solid var(--line)}
.aiv-src.cloud{background:#eff6ff;color:#1d4ed8;border-color:#bfdbfe}
.aiv-src.local{background:#f5f3ff;color:#6d28d9;border-color:#ddd6fe}
.aiv-src.none{background:#f8fafc;color:#94a3b8}
.aiv-kind{display:inline-block;font-size:11px;padding:1px 5px;border-radius:5px;
  background:#f1f5f9;color:var(--slate)}
.aiv-kind.ok{background:#ecfdf5;color:#047857}
.aiv-kind.bad{background:#fef2f2;color:#b91c1c}
.aiv-kind.warn{background:#fffbeb;color:#b45309}
.aiv-kind.info{background:#eff6ff;color:#1d4ed8}
.aiv-ip{display:block;font-size:11px;color:var(--sub);
  font-variant-numeric:tabular-nums;word-break:break-all}
.aiv-auth{display:flex;align-items:center;justify-content:space-between;
  gap:10px;padding:9px 0;border-bottom:1px solid #f1f3f5}
.aiv-auth-l{min-width:0}
.aiv-auth-l b{font-size:13.5px}
.aiv-badge{display:inline-block;font-size:11px;padding:1px 7px;border-radius:20px;
  margin-left:6px;font-weight:600}
.aiv-badge.on{background:#ecfdf5;color:#047857;border:1px solid #a7f3d0}
.aiv-badge.off{background:#f8fafc;color:#94a3b8;border:1px solid var(--line)}
.aiv-row{display:flex;align-items:center;justify-content:space-between;
  gap:10px;flex-wrap:wrap;padding:2px 0 8px}
.aiv-row-k{font-size:13px;font-weight:600}
.aiv-sw{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--sub)}
.aiv-sw input{width:17px;height:17px}
.aiv-note{color:var(--sub);font-size:12px;line-height:1.6;margin:6px 0 0}
.aiv-ops{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.aiv-danger{border-color:var(--red)!important;color:var(--red)!important}
.aiv-foot{border-top:1px solid var(--line);padding-top:10px;margin-top:14px}
/* ★★ 手机（≤820px）：跟全站一致 —— 表格改成一条一条的卡片。
   ★ 为什么必须处理：全站在手机上有一条全局规则
       table,thead,tbody,tr,td{display:block}
     （任务列表就是靠它变成卡片流的，见上面的 @media）。那条规则是全局的，
     这张表也会被它接管；一接管，td 因为没有 data-label，就变成
     「没头没尾的几行字」——第一版在 390px 上截图就是这样，读了不知道哪个是哪个。
   ★ 处理办法不是跟它对着干，而是顺着它、按这张表的数据结构重排：
       第一行：时间 · 来源 ……………………………… 类型（靠右）
       第二行：做了什么（占满整行）
     用 flex + order 实现，纯 CSS —— 不用为手机另写一套 JS 渲染，
     手机上看到的和电脑上是同一份数据、同一段代码。 */
@media(max-width:820px){
  .aiv-kpis{grid-template-columns:repeat(3,1fr)}
  .aiv-ops button{flex:1 1 46%}
  .aiv-tw{overflow-x:visible}
  .aiv-tb{table-layout:auto}
  .aiv-tb thead{display:none}
  .aiv-tb tbody{display:block}
  .aiv-tb tr{display:flex;flex-wrap:wrap;align-items:center;gap:6px 8px;
    border:1px solid var(--line);border-radius:10px;padding:9px 11px;
    margin-bottom:8px;background:#fff}
  .aiv-tb td{display:block;border:none;padding:0;width:auto!important;
    font-size:12.5px;vertical-align:baseline}
  .aiv-tb td::before{content:none!important}
  .aiv-tb td:nth-child(1){order:1;font-size:11.5px;color:var(--sub)}
  .aiv-tb td:nth-child(2){order:2}
  .aiv-tb td:nth-child(4){order:3;margin-left:auto}
  .aiv-tb td:nth-child(3){order:9;flex:1 1 100%}
}
/* ★ 420px 以下：五个数字卡片排两列，按钮铺满一行更好点 */
@media(max-width:420px){
  .aiv-kpis{grid-template-columns:repeat(2,1fr)}
  .aiv-ops button{flex:1 1 100%}
}

/* ══════════ ★ 执行人 4 列 · 窄屏退化 · 2026-10-22 第 63 轮 ══════════
   390px 的屏上硬排 4 列，每列只剩 84px —— 名字会被截成两个字，
   勾选框和名字挤在一起，反而更难勾。所以窄屏改成 2 列：
   一屏还是能看见 4 个部门（上下两排），勾选目标够大。
   ★ 这条必须写在文件最后：前面 @media(max-width:820px) 里给
     .asgrow 加过 padding/min-height（手机要点得准），
     而 .asgcol .asgrow 的选择器更具体，写在前面会把那些顶掉。 */
@media(max-width:640px){
  .asgcols{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
  .asgcol .asgrow{padding:8px 7px;font-size:14px;min-height:38px;gap:7px}
  .asgcol .asgrow .ck{width:17px;height:17px}
  .asgcol .asgrow .dp{font-size:10.5px}
  .asgcolhd{padding:7px 7px}
  .asgcolhd .gn{font-size:12.5px}
  .asgcolhd .gt{font-size:10.5px}
}

/* ══════════ ★ 三个选项一排 · 手机退化 · 2026-10-22 第 64 轮 ══════════
   三列在 390px 屏上每列只剩 110px：「截止日期」的日期会被截成「2026-10-2…」，
   勾按钮也点不准。手机上一律回到单列、恢复原来的字号和内边距。
   ★ 手机本来就摆不下一排，这是「适当调窄」的边界 ——
     宁可竖着排，也不能把字挤到看不清。
   ★ 写在文件最后：靠「同优先级、后写生效」压过上面的 .fld3 规则。 */
@media(max-width:820px){
  .fld3{grid-template-columns:1fr;gap:0}
  .fld3 .fld{margin-bottom:14px}
  .fld3 .fld > label{min-height:0}
  .fld3 .fld .lbl-sub{max-height:none}
  .fld3 .duebtn{padding:11px 12px;gap:6px}
  .fld3 .dueval{font-size:14px;letter-spacing:0}
  .fld3 .duecar{font-size:11px}
  .fld3 .rp-extra{padding:11px 12px;margin-top:9px}
  .fld3 .rp-grp{flex-direction:row;gap:9px;margin-bottom:9px}
  .fld3 .rp-cap{width:30px;text-align:right;padding-top:5px;font-size:12px}
  .fld3 .rp-chips{gap:5px}
  .fld3 .rp-chip{min-width:30px;padding:5px 0;font-size:12px}
  .fld3 .rp-foot{flex-wrap:nowrap;gap:8px;margin-top:8px}
  .fld3 .rp-sum{font-size:11.5px}
}

/* ══════════ ★ 完成说明弹窗（必填）· 2026-10-24 第 69 轮 ══════════
   老板原话：「任务完成后 需要写点什么，必须写，不得留空，写完才能点完成。」
   ── 交互上的三条约定 ─────────────────────────────────
   ① 一个字都没写 → 「确认完成」是灰的（.btn:disabled，全站已有），
      点不动才不会让人「点了没反应」地反复试。
   ② 硬点（回车/脚本）→ 橙框闪一下并抖一下，指明「就是这儿没填」。
   ③ 写完亮成绿字告诉他已经够了，别让他猜「到底要写多少」。
   ★ 「必填」不做成红色小标签贴在标题旁 —— 老板要的是「写明必须写」，
     所以正文里那句加粗的话才是主提示，这个标签只是补一个视觉锚点。 */
#mo-done .mbox{padding-bottom:18px}
#mo-done .fld{margin-top:14px}
#mo-done .fld label{display:flex;align-items:center;gap:6px}
#mo-done .fld label .req{font-size:10.5px;font-weight:700;color:#b91c1c;
  background:#fef2f2;border:1px solid #fecaca;border-radius:5px;
  padding:1px 5px;line-height:1.5;letter-spacing:.2px}
#mo-done .fld textarea{min-height:108px;resize:vertical;line-height:1.62;
  font-size:14px;background:#fbfcfe}
#mo-done .fld textarea::placeholder{color:#9ca3af;font-size:13px;line-height:1.6}
/* 提示语：没写是灰的，写了变绿 —— 让「可以点了」这件事自己说出来 */
.dntip{font-size:12px;color:var(--sub);line-height:1.5;margin-top:-4px;
  padding-left:2px;transition:color .15s}
.dntip.ok{color:#047857;font-weight:600}
/* 空白时闪橙框 + 抖一下（.need 由 app.js 的 dnFlash() 加，1.7 秒后自己摘） */
#dn-box.need textarea{border-color:#f59e0b;
  box-shadow:0 0 0 3px rgba(245,158,11,.22);animation:dnShake .34s ease}
@keyframes dnShake{0%,100%{transform:translateX(0)}
  25%{transform:translateX(-4px)}60%{transform:translateX(4px)}
  80%{transform:translateX(-2px)}}
/* 手机上把两个动作按钮摊成等宽，拇指好点 */
@media(max-width:820px){
  #mo-done .macts{display:grid;grid-template-columns:1fr 1fr;gap:8px}
  #mo-done .macts .btn{width:100%;padding:11px 0;font-size:14px}
  #mo-done .fld textarea{min-height:94px}
}

/* ══════════ ★ 每日新增任务汇总 · 2026-10-24 第 70 轮 ══════════
   老板原话：「在这里加一个每日新增任务汇总，最上排依次写上：日期、
             今日新增数量、点击可以弹出详情：日期、派遣人、任务名称。」
   ── 两条交互约定 ──────────────────────────────────────
   ① 整行都能点，不只是数字 —— 手机上那个数字才 15px，拇指点不中。
      hover 变色 + 手型是给电脑端的提示。
   ② 数字本身做成「蓝色 + 虚线下划线」，跟统计页的超期次数、被打回次数
      是同一套视觉语言：这个页面里，带虚线的东西都能点。
   ★ 日期列故意给 26% 而不是 50%：两列的表如果各占一半，
     数字会跑到屏幕最右边，眼睛得横着跳半屏才连得上「哪天 → 几条」。 */
.dlrow{cursor:pointer;transition:background .12s}
.dlrow:hover{background:#f5f9ff}
.dlrow td{white-space:nowrap}
.dlcell{display:inline-flex;align-items:center;gap:6px}
.dldate{font-variant-numeric:tabular-nums;font-weight:600;letter-spacing:.2px}
.dlwd{color:#9ca3af;font-size:11.5px;font-weight:400}
/* 数字：能点的样子，同时保证 1 位数和 3 位数并排时对得齐 */
.dlnum{display:inline-block;min-width:20px;text-align:center;
  font-weight:800;font-size:15px;color:#1a5fb4;
  text-decoration:underline dotted;text-underline-offset:3px;
  font-variant-numeric:tabular-nums}
.dlunit{font-size:12px;color:#6b7280;margin-left:1px}
.dlrow:hover .dlnum{color:#1d4ed8}
/* 数量后面那条细条：长度按「这天是全年最多那天的百分之几」画。
   ★ 它不引入任何新指标，就是把同一个数字换个方式说一遍 ——
     哪几天量大，扫一眼就看得出来，不用逐个念数字。
   ★ 底色很淡，是为了别抢数字本身（数字才是主角）。 */
/* 数量那一格整行铺开：数字 + 一条吃满剩余宽度的轨道。
   为什么让轨道撑满而不写死 190px ——
   写死的话右边会空掉一大片，两列的表看着像没做完；
   撑满之后整行是一根「横条图」，哪天量大一目了然。 */
.dlfill{display:flex;align-items:center;gap:8px;width:100%}
.dlbar{flex:1;height:6px;border-radius:4px;background:#e9eef5;overflow:hidden}
.dlbar i{display:block;height:100%;border-radius:4px;
  background:linear-gradient(90deg,#93c5fd,#60a5fa)}

/* 手机上（表头被藏起来、整表变卡片流）：日期和数量各占一行，
   data-label 自动出「日期 / 今日新增数量」的小字，跟别的表一致。
   ★ 这里只把内边距收一点 —— 两列的表在 390 宽下卡片会显得又高又空。 */
@media(max-width:820px){
  .dlrow td{padding:3px 0}
  .dlnum{font-size:16px}
  /* ★ 手机上整表变成卡片流，一格一行，细条没有落脚的地方 —— 藏掉。
     数字本身已经把话说完了。
     ★ .dlfill 要退回「只包住内容」并靠右，否则它撑满整行后
       数字会被顶到左边，跟上面几行的右对齐不一致。 */
  .dlbar{display:none}
  .dlfill{width:auto;justify-content:flex-end}

  /* ★ 明细弹窗里的「任务名称」在手机上要独占整行。
     默认的卡片流是「标签左、值右、两端对齐」，任务名一长就被挤成
     两三行、还右对齐，读着要来回折 —— 跟任务列表里「标题」那一格
     用同一个办法：标签独占一行，内容整行左对齐。 */
  #dl-body td[data-label="任务名称"]{display:block;padding-top:5px}
  #dl-body td[data-label="任务名称"]::before{display:block;margin-bottom:2px}
  #dl-body td[data-label="任务名称"] .odlink{line-height:1.5}
}
