* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
:root {
  --green: #2e7d32; --green-bg: #e8f5e9;
  --yellow: #f9a825; --yellow-bg: #fff8e1;
  --red: #c62828; --red-bg: #ffebee;
  --blue: #1565c0; --blue-bg: #e3f2fd;
  --gray: #757575; --gray-bg: #eeeeee;
  --primary: #2b5c8f; --primary-dark: #1f456b;
  --bg: #f2f4f7; --card: #ffffff; --line: #e3e8ef; --text: #1f2933; --muted: #6b7280;
}
html, body { height: 100%; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; background: var(--bg); color: var(--text); font-size: 15px; line-height: 1.5; }

/* 顶栏 */
.topbar { background: var(--primary); color: #fff; padding: 12px 16px; display: flex; align-items: center; justify-content: space-between; position: sticky; top: 0; z-index: 20; }
.topbar h1 { font-size: 16px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar .who { font-size: 13px; opacity: .9; display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.topbar button { background: rgba(255,255,255,.15); color: #fff; border: 0; border-radius: 6px; padding: 5px 10px; font-size: 13px; cursor: pointer; }
/* 标题 + 放大镜：窄屏优先压标题（出省略号），右侧用户名/工序下拉不缩 */
.topbar .tb-l { display: flex; align-items: center; gap: 8px; min-width: 0; flex: 0 1 auto; }
.topbar .tb-search { flex: 0 0 auto; width: 28px; height: 28px; padding: 0; display: inline-flex; align-items: center; justify-content: center; border-radius: 8px; }
.topbar .tb-search svg { width: 15px; height: 15px; fill: none; stroke: #fff; stroke-width: 1.7; stroke-linecap: round; }
.topbar .tb-search.on { background: rgba(255,255,255,.34); }

/* 手机端顶栏搜索条（按图号搜卡片）：吸在顶栏下方；放在 #sub 外面，输入时不会因列表重绘而失焦 */
.lsearch { position: sticky; top: 46px; z-index: 19; display: flex; align-items: center; gap: 8px; padding: 9px 14px; background: #fff; border-bottom: 1px solid var(--line); }
.lsearch[hidden] { display: none; }
.lsearch .ls-ico { flex: 0 0 auto; display: inline-flex; }
.lsearch .ls-ico svg { width: 15px; height: 15px; fill: none; stroke: var(--muted); stroke-width: 1.7; stroke-linecap: round; }
.lsearch input { flex: 1 1 auto; min-width: 0; border: 0; background: none; font: inherit; font-size: 15px; color: var(--text); outline: none; padding: 2px 0; -webkit-appearance: none; }
.lsearch input::placeholder { color: #a8b2bf; }
.lsearch input::-webkit-search-cancel-button { display: none; }
.lsearch .ls-cnt { flex: 0 0 auto; font-size: 12px; color: var(--muted); white-space: nowrap; }
.lsearch .ls-cnt.zero { color: #d33; }
.lsearch .ls-x { flex: 0 0 auto; width: 26px; height: 26px; padding: 0; border: 0; border-radius: 50%; background: #eef1f5; color: #6b7785; font-size: 13px; line-height: 1; cursor: pointer; }

/* 顶栏右侧：工序切换下拉（班组长端）+ 用户名二级菜单（改密码 / 退出） */
.topbar .usermenu { position: relative; }
.topbar .user-btn { display: inline-flex; align-items: center; gap: 5px; }
.topbar .user-btn .caret { font-style: normal; font-size: 10px; opacity: .85; }
.topbar .umenu { position: absolute; right: 0; top: calc(100% + 6px); min-width: 138px; background: #fff; border: 1px solid var(--line, #dde3ea); border-radius: 10px; box-shadow: 0 10px 26px rgba(16,38,64,.18); padding: 6px; z-index: 60; display: flex; flex-direction: column; gap: 2px; }
.topbar .umenu[hidden] { display: none; }
.topbar .umenu button { background: none; color: #22303f; text-align: left; padding: 9px 10px; border-radius: 7px; font-size: 13px; opacity: 1; }
.topbar .umenu button:hover, .topbar .umenu button:active { background: #f1f6fc; }
.topbar .who-step { display: flex; align-items: center; }
.topbar .who-sel { max-width: 152px; background: rgba(255,255,255,.94); color: #14304f; border: 0; border-radius: 7px; padding: 5px 8px; font: inherit; font-size: 13px; cursor: pointer; }

/* 导航 */
.nav { display: flex; background: #fff; border-bottom: 1px solid var(--line); position: sticky; top: 46px; z-index: 19; overflow-x: auto; }
.nav button { flex: 1 0 auto; padding: 12px 14px; border: 0; background: none; color: var(--muted); font-size: 14px; cursor: pointer; white-space: nowrap; border-bottom: 2px solid transparent; }
.nav button.active { color: var(--primary); border-bottom-color: var(--primary); font-weight: 600; }

/* 容器 */
.container { max-width: 100%; margin: 0; padding: 16px 20px; }
.mobile .container { padding: 12px; }
/* 卡片网格（宽屏自适应多列，填满页面宽度） */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }

/* 卡片 */
.card { background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 14px; margin-bottom: 12px; }
.card h3 { font-size: 15px; margin-bottom: 8px; display: flex; justify-content: space-between; align-items: center; }
.row { display: flex; justify-content: space-between; align-items: center; padding: 6px 0; border-bottom: 1px dashed var(--line); }
.row:last-child { border-bottom: 0; }
.muted { color: var(--muted); font-size: 13px; }

/* 状态徽章 */
.badge { display: inline-block; padding: 2px 9px; border-radius: 12px; font-size: 12px; font-weight: 600; color: #fff; }
.badge.green { background: var(--green); } .badge.yellow { background: var(--yellow); } .badge.red { background: var(--red); } .badge.blue { background: var(--blue); } .badge.gray { background: var(--gray); }
.badge.purple { background: #8b6fd6; }   /* 择一分支：这一批走的是同组另一道 */
.tag { display: inline-block; padding: 1px 8px; border-radius: 10px; font-size: 12px; background: var(--gray-bg); color: var(--muted); margin-left: 6px; }

/* 进度条 */
.progress { height: 8px; background: var(--gray-bg); border-radius: 5px; overflow: hidden; margin-top: 6px; }
.progress > i { display: block; height: 100%; background: var(--green); }

/* 按钮 */
.btn { display: inline-block; border: 0; border-radius: 8px; padding: 10px 14px; font-size: 14px; cursor: pointer; background: var(--primary); color: #fff; }
.btn.full { width: 100%; }
.btn.sm { padding: 6px 10px; font-size: 13px; }
.btn.green { background: var(--green); } .btn.red { background: var(--red); } .btn.blue { background: var(--blue); } .btn.ghost { background: #fff; color: var(--primary); border: 1px solid var(--primary); }
.btn:disabled { opacity: .5; }
.actions { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }

/* 表单 */
.field { margin-bottom: 12px; }
.field label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 4px; }
.field input, .field select, .field textarea { width: 100%; padding: 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 15px; background: #fff; }
/* 弹层遮罩的三条边由 JS 按 visualViewport 覆盖（键盘弹起时贴合键盘上沿），
   所以 sheet 的高度用 % 而不是 vh —— vh 永远按布局视口算，键盘弹起后不会变小。 */
.modal-mask { position: fixed; inset: 0; background: rgba(0,0,0,.35); display: flex; align-items: flex-end; justify-content: center; z-index: 50; }
/* 手机端（班组长端 body.mobile）弹层打开时锁住背景滚动：键盘弹起时页面不会跟着乱窜、弹层也不会被顶走。
   只看 body.mobile 而不是视口宽度 —— 博士在桌面开弹层时不锁，免得滚动条消失整页往右跳一下。 */
body.mobile.sheet-open { overflow: hidden; }
.modal-mask .sheet { background: #fff; width: 100%; max-width: 560px; border-radius: 14px 14px 0 0; max-height: 88%; display: flex; flex-direction: column; overflow: hidden; }
.modal-mask .sheet-head { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 16px 18px 10px; border-bottom: 1px solid var(--line); background: #fff; }
.modal-mask .sheet-head h3 { margin: 0; }
.modal-mask .sheet-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 14px 18px 18px; }
.step-row { display: grid; grid-template-columns: 24px 1fr 72px 1fr 120px 20px 30px; gap: 6px; margin-bottom: 6px; align-items: center; background: #fff; border-radius: 8px; position: relative; }
/* 工序行里的控件统一成和其它输入框一样的圆角矩形（原来是浏览器默认直角样式） */
.step-row input, .step-row select {
  box-sizing: border-box; width: 100%; height: 34px; padding: 0 9px;
  font-size: 14px; font-family: inherit; min-width: 0;
  border: 1px solid var(--line); border-radius: 8px; background: #fff; color: var(--text);
}
.step-row input:focus, .step-row select:focus { outline: none; border-color: var(--primary); }
.step-row input[disabled], .step-row select[disabled] { background: #f2f4f7; color: var(--muted); }
.step-row .del { box-sizing: border-box; height: 34px; width: 30px; background: var(--red-bg); color: var(--red); border: 0; border-radius: 8px; cursor: pointer; font-size: 15px; line-height: 1; }
.step-row select.procnm, .step-row input.procnm { width: 100%; min-width: 0; text-overflow: ellipsis; }
.step-row .sidx { font-size: 12px; color: var(--muted); text-align: center; }
.step-row .rowhandle, table.mtable .rowhandle { width: 20px; height: 18px; position: relative; flex: 0 0 auto; cursor: grab; color: var(--muted); touch-action: none; display: inline-block; vertical-align: middle; }
.step-row .rowhandle::before, table.mtable .rowhandle::before { content: ''; position: absolute; left: 4px; right: 4px; top: 3px; height: 2px; background: currentColor; border-radius: 1px; box-shadow: 0 5px 0 currentColor, 0 10px 0 currentColor; }
.step-row .rowhandle:active, table.mtable .rowhandle:active { cursor: grabbing; }
.step-row.dragging, table.mtable tr.dragging { opacity: .4; }
.step-row.dragover { border-top: 2px solid var(--primary); }

/* 负责人多选（共同负责）：按钮长得像原来的下拉框，点开是勾人浮层（浮层挂 body，避免被表格裁掉） */
.opick { display: block; min-width: 0; }
.opick-btn { box-sizing: border-box; width: 100%; height: 34px; padding: 0 24px 0 9px; font-size: 14px; font-family: inherit;
  border: 1px solid var(--line); border-radius: 8px; background: #fff; color: var(--text); cursor: pointer;
  text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; position: relative; }
.opick-btn::after { content: '▾'; position: absolute; right: 8px; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: 11px; line-height: 1; }
.opick-btn.empty { color: var(--muted); }
.opick-btn:hover { border-color: var(--primary); }
table.mtable .opick-btn { font-size: 13px; }
.opick-pop { position: fixed; z-index: 3000; width: 226px; max-height: 320px; overflow: auto; background: #fff;
  border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 10px 30px rgba(16, 24, 40, .16); padding: 6px; }
.opick-hd { font-size: 11.5px; color: var(--muted); padding: 4px 6px 6px; }
.opick-item { display: flex; align-items: center; gap: 8px; padding: 7px 8px; border-radius: 7px; cursor: pointer; font-size: 13.5px; }
.opick-item:hover { background: #f5f8ff; }
.opick-item input { width: 15px; height: 15px; accent-color: var(--primary); margin: 0; }
.opick-none { padding: 10px 8px; color: var(--muted); font-size: 12.5px; }
.opick-ft { display: flex; gap: 6px; justify-content: flex-end; padding: 6px 4px 2px; border-top: 1px solid var(--line); margin-top: 4px; }
table.mtable tr.dragover td { border-top: 2px solid var(--primary); }
table.mtable td.ord { white-space: nowrap; }
table.mtable td.ord .sidx { font-size: 12px; color: var(--muted); margin-right: 6px; }
.modal-mask .sheet.mid { max-width: 760px; }

/* 登录 */
.login-wrap { min-height: 100%; display: flex; align-items: center; justify-content: center; padding: 20px; }
.login-card { background: #fff; border-radius: 14px; padding: 24px; width: 100%; max-width: 360px; box-shadow: 0 6px 24px rgba(0,0,0,.08); }
.login-card h2 { text-align: center; margin-bottom: 4px; color: var(--primary); letter-spacing: .5px; }
.login-card .sub { text-align: center; color: var(--muted); font-size: 13px; margin-bottom: 18px; }
.demo { background: var(--bg); border-radius: 8px; padding: 10px; margin-top: 14px; font-size: 12px; color: var(--muted); }
.demo b { color: var(--text); }

/* 看板统计块 */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px; }
.stat { background: #fff; border: 1px solid var(--line); border-radius: 10px; padding: 12px; }
.stat .n { font-size: 22px; font-weight: 700; color: var(--primary); }
.stat .l { font-size: 12px; color: var(--muted); margin-top: 2px; }

/* toast */
#toast { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%); background: rgba(0,0,0,.82); color: #fff; padding: 10px 18px; border-radius: 20px; font-size: 14px; opacity: 0; transition: opacity .25s; pointer-events: none; z-index: 99; }
#toast.show { opacity: 1; }
#toast.act { pointer-events: auto; display: flex; align-items: center; gap: 14px; padding-right: 10px; }
#toast .t-act { border: 0; background: rgba(255,255,255,.18); color: #fff; font: inherit; font-size: 13px; padding: 5px 12px; border-radius: 14px; cursor: pointer; }
#toast .t-act:hover { background: rgba(255,255,255,.32); }
/* 拖列头时贴一条提示：拖到表格外松手就是隐藏这一列 */
body.col-drag-live::after { content: '拖到表格外松手 = 隐藏这一列'; position: fixed; left: 50%; bottom: 66px; transform: translateX(-50%); background: rgba(0,0,0,.72); color: #fff; font-size: 12px; letter-spacing: .3px; padding: 6px 14px; border-radius: 14px; z-index: 98; pointer-events: none; white-space: nowrap; }
body.col-drag-live.col-drop-out::after { content: '松手即隐藏这一列'; background: var(--red); }

/* 看板：筛选条与明细表 */
.toolbar { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; align-items: center; }
.toolbar input, .toolbar select { padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 14px; background: #fff; min-width: 0; }
.toolbar .grow { flex: 1 1 180px; }
.toolbar .spacer { flex: 1; }
.dash-tip { font-size: 12px; color: var(--muted); margin: 2px 0 10px; }
/* 提示 + 行内小按钮（如日计划「已筛选 N/M 条 · 清空」）：让按钮和文字垂直居中对齐 */
.flt-tip { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.flt-tip .btn { flex: 0 0 auto; }
/* 列设置弹层里提示「这套列属于哪个方案」 */
.col-scheme-tip { font-size: 12px; color: #1c4f8a; background: var(--blue-bg); border-radius: 8px; padding: 7px 10px; margin-bottom: 8px; }
.col-scheme-tip b { color: #123c6b; }
/* 列设置底部按钮条：恢复宽度 / 恢复默认列 / 设为默认（博士，第三个才靠右） */
.col-def-bar { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.col-def-bar .btn:nth-child(3) { margin-left: auto; }
/* 看板导出图片：预览弹层（图片自适应宽度，点图看原图） */
.dimg-tip { font-size: 12px; color: var(--muted); margin-bottom: 8px; }
.dimg-tip b { color: var(--text); font-weight: 600; }
.dimg-wrap { background: #f7f9fc; border: 1px solid var(--line); border-radius: 10px; padding: 8px; max-height: 56vh; overflow: auto; }
.dimg-wrap img { display: block; width: 100%; height: auto; border-radius: 6px; background: #fff; box-shadow: 0 1px 5px rgba(16,38,64,.08); cursor: zoom-in; }
.dimg-hint { font-size: 11.5px; color: var(--muted); margin-top: 8px; line-height: 1.5; }
/* 三个按钮一行放下：手机上不换行、字号收一档（复用 .btn.big 时 text 会折成两行） */
.dimg-btns { display: flex; gap: 8px; margin-top: 12px; }
.dimg-btns .btn { flex: 1 1 0; min-width: 0; white-space: nowrap; padding: 12px 6px; font-size: 14px; }
@media (max-width: 420px) { .dimg-btns .btn { font-size: 13.5px; padding: 12px 4px; } }
/* 多图预览（日计划「生成全部工序图片」）：一张工序一张卡片，两列排，手机上单列 */
.dimg-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 10px; }
.dimg-card { border: 1px solid var(--line); border-radius: 10px; padding: 8px; background: #fff; }
.dimg-card-h { display: flex; align-items: baseline; gap: 6px; margin-bottom: 6px; }
.dimg-card-h b { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dimg-card-h span { margin-left: auto; flex: 0 0 auto; font-size: 11.5px; color: var(--muted); }
.dimg-wrap.sm { max-height: 30vh; padding: 6px; }
.dimg-btns.sm { margin-top: 6px; gap: 6px; }
.dimg-btns.sm .btn { padding: 7px 6px; font-size: 12.5px; }
@media (max-width: 560px) { .dimg-list { grid-template-columns: 1fr; } }
/* 博士 11-05：页面上常驻的说明性小字默认不显示（操作指南里统一写），
   按钮/操作产生的提示（toast）照常弹。要恢复就看这里 —— 删掉这条 display:none 即可。
   注意：数据型小字（客户/项目、金额、计数、空状态、筛选生效提示）不在此列，别一起藏了。 */
.tip-note { display: none !important; }

.dtable-wrap { overflow-x: auto; background: #fff; border: 1px solid var(--line); border-radius: 10px; -webkit-overflow-scrolling: touch; }
table.dtable { border-collapse: collapse; width: 100%; font-size: 13px; white-space: nowrap; }
table.dtable th, table.dtable td { border: 1px solid var(--line); padding: 7px 9px; text-align: left; }
table.dtable th { background: #f6f8fa; font-weight: 600; position: relative; }
/* 博士端手工交接（工序进度页）：一行两个小按钮，窄到不撑宽表格 */
table.dtable th.th-hb, table.dtable td.dt-hb { width: 104px; text-align: center; }
/* 「生产进度」表的列设置按钮：靠右、单独一行，不占表格宽度 */
.prog-tools { display: flex; justify-content: flex-end; margin: 0 0 6px; }
table.dtable td.dt-hb .hb { font-size: 11px; line-height: 1; padding: 4px 7px; margin: 0 2px; border-radius: 4px; cursor: pointer; border: 1px solid #c4d2e6; background: #f2f6fc; color: #2f4f7a; }
table.dtable td.dt-hb .hb:hover { background: #e4edfa; border-color: #93b0d8; }
table.dtable td.dt-hb .hb.prev { color: #8a5a1c; background: #fdf6ec; border-color: #e6d3b4; }
table.dtable td.dt-hb .hb.prev:hover { background: #f9ead5; }
table.dtable td.dt-hb .hb:disabled { opacity: .45; cursor: default; }
/* 看板 / 排产的明细表：表格自己滚（表头吸顶、横向滚动条常驻表底），页面不再整页滚走筛选条件 */
.dtable-wrap.tbl-fit { position: relative; overflow: auto; scrollbar-gutter: stable; }
.dtable-wrap.tbl-fit > table > thead > tr > th { position: sticky; top: 0; z-index: 6; background: #f6f8fa; box-shadow: inset 0 -1px 0 var(--line); }
/* 自定义滚动条：占位式，不会压在最后一列/最后一行内容上 */
.dtable-wrap.tbl-fit::-webkit-scrollbar { width: 12px; height: 12px; }
.dtable-wrap.tbl-fit::-webkit-scrollbar-track { background: #f2f4f7; border-radius: 0 0 10px 0; }
.dtable-wrap.tbl-fit::-webkit-scrollbar-thumb { background: #c3ccd8; border-radius: 6px; border: 2px solid #f2f4f7; }
.dtable-wrap.tbl-fit::-webkit-scrollbar-thumb:hover { background: #a7b4c4; }
.dtable-wrap.tbl-fit::-webkit-scrollbar-corner { background: #f2f4f7; }
@media (min-width: 900px) { .dtable-wrap.tbl-fit { max-height: calc(100vh - 300px); } }
/* 筛选条可收起：窄屏/小窗口时把表格让出来 */
.toolbar.flt-row.is-hidden { display: none; }
table.dtable tbody tr:hover { background: #f9fbff; }
table.dtable td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.dtable input[type=checkbox] { width: 16px; height: 16px; }
/* 列宽可调：固定布局 + 超出省略 + 表头右边缘拖拽手柄 */
table.dtable.rz { table-layout: fixed; width: auto; }
table.dtable.rz th, table.dtable.rz td { overflow: hidden; text-overflow: ellipsis; }
table.dtable.rz th { padding-right: 22px; }
/* 勾选列表头：没有调宽手柄、也没有筛选三角，不能留那 22px ——
   44px 的列左右一扣只剩 13px，16px 的 checkbox 溢出就被 ellipsis 画成「...」 */
table.dtable.rz th.th-sel { padding: 0; text-align: center; }
/* 勾选列单元格要跟表头同一套（padding 0 + 居中）。接单表用的是 td.td-sel 这个类，
   以前没定义过样式，checkbox 就贴在左边 —— 博士 11-05 反馈"没有居中"。 */
table.dtable.rz td.td-sel { padding: 0; text-align: center; }
/* 行尾「操作」列：钉在右边（表格横向滚动时按钮始终可见），左边界补一条竖线，
   不然 border-collapse 下 sticky 单元格会把边框一起滚掉 */
table.dtable.rz th.th-act, table.dtable.rz td.td-act { position: sticky; right: 0; z-index: 4; background: #fff; box-shadow: inset 1px 0 0 var(--line); }
table.dtable.rz thead tr th.th-act { z-index: 7; background: #f6f8fa; }
table.dtable.rz tbody tr:hover td.td-act { background: #f9fbff; }
table.dtable th .rz { position: absolute; top: 0; right: 0; width: 8px; height: 100%; cursor: col-resize; z-index: 3; }
table.dtable th .rz::after { content: ''; position: absolute; left: 4px; top: 5px; bottom: 5px; width: 1px; background: var(--line); }
table.dtable th .rz:hover::after, body.col-resizing table.dtable th .rz::after { background: var(--primary); width: 2px; left: 3px; }
/* 表头筛选小三角：贴在调宽手柄左边，平时淡、hover 明显、筛过之后常亮（点它弹该列的值列表） */
table.dtable th .hf { position: absolute; right: 9px; top: 50%; width: 12px; height: 14px; margin-top: -7px; cursor: pointer; opacity: .3; z-index: 2; border-radius: 3px; }
table.dtable th .hf::after { content: ''; position: absolute; left: 50%; top: 50%; margin: -2px 0 0 -4px; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid #5a6b7d; }
table.dtable th:hover .hf { opacity: .6; }
table.dtable th .hf:hover { opacity: 1; background: #e4ecf5; }
table.dtable th .hf.on { opacity: 1; }
table.dtable th .hf.on::after { border-top-color: var(--primary); }
@media (hover: none) { table.dtable th .hf { opacity: .4 } }
body.col-resizing { cursor: col-resize; user-select: none; }
/* 表头拖动换列顺序：按住列名即可拖（右边缘 8px 的 .rz 只调宽，不参与换序） */
table.dtable.rz th[data-wk] { cursor: grab; user-select: none; }
body.col-dragging table.dtable.rz th[data-wk] { cursor: grabbing; }
table.dtable.rz th.col-dragging { cursor: grabbing; opacity: .35; }
table.dtable.rz th.drop-l { box-shadow: inset 3px 0 0 var(--primary), inset 0 -1px 0 var(--line); }
table.dtable.rz th.drop-r { box-shadow: inset -3px 0 0 var(--primary), inset 0 -1px 0 var(--line); }
table.dtable.rz select.route-sel { width: 100%; max-width: none; }
.colrow .colw { width: 76px; flex: 0 0 auto; padding: 5px 7px; border: 1px solid var(--line); border-radius: 6px; font-size: 13px; text-align: right; }
.colrow .colwu { font-size: 12px; color: var(--muted); }
.toolbar .lbl { font-size: 13px; color: var(--muted); align-self: center; }
.toolbar .spacer { flex: 1; }
/* 筛选方案点选条（替代下拉框） */
.scheme-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.schip { position: relative; display: inline-flex; align-items: center; gap: 5px; border: 1px solid var(--line); background: #fff; color: var(--text); border-radius: 999px; padding: 5px 13px; font-size: 13px; line-height: 1.5; cursor: pointer; white-space: nowrap; transition: background .12s, border-color .12s, color .12s; }
.schip:hover { border-color: var(--primary); color: var(--primary); background: #f5f8fc; }
.schip.on { background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600; }
.schip.on:hover { background: var(--primary-dark); color: #fff; }
.schip-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green); flex: 0 0 auto; }
.schip.on .schip-dot { background: #fff; }
.colrow { display: flex; align-items: center; gap: 10px; padding: 7px 4px; border-bottom: 1px solid var(--line); }
.colrow .colname { flex: 1; font-size: 14px; }
.colrow .btn.sm { padding: 3px 8px; font-size: 12px; }
#colList, #fldList { max-height: 60vh; overflow-y: auto; }
@media (max-width: 600px) {
  table.dtable { font-size: 12px; }
  table.dtable th, table.dtable td { padding: 5px 6px; }
}
/* 手机顶栏：工序下拉别把系统名挤成省略号（375px 下原来 "FurnitureBu…"） */
@media (max-width: 430px) {
  .topbar .who-sel { max-width: 106px; }
}

/* loading 全屏遮罩 */
.overlay { position: fixed; inset: 0; background: rgba(0,0,0,.42); display: none; flex-direction: column; align-items: center; justify-content: center; gap: 14px; color: #fff; z-index: 300; }
.overlay.show { display: flex; }
.overlay .spin { width: 40px; height: 40px; border: 4px solid rgba(255,255,255,.3); border-top-color: #fff; border-radius: 50%; animation: fp-spin .8s linear infinite; }
.overlay .otext { font-size: 15px; letter-spacing: .5px; }
@keyframes fp-spin { to { transform: rotate(360deg); } }
.btn.loading { position: relative; color: transparent !important; pointer-events: none; }
.btn.loading::after { content: ''; position: absolute; left: 50%; top: 50%; width: 15px; height: 15px; margin: -8px 0 0 -8px; border: 2px solid rgba(255,255,255,.55); border-top-color: #fff; border-radius: 50%; animation: fp-spin .7s linear infinite; }

/* 列设置：拖拽排序（右侧三横线手柄） */
.colrow[draggable="true"] { cursor: default; }
.colrow .draghandle { margin-left: auto; width: 20px; height: 18px; position: relative; flex: 0 0 auto; cursor: grab; color: var(--muted); touch-action: none; }
.colrow .draghandle::before { content: ''; position: absolute; left: 4px; right: 4px; top: 3px; height: 2px; background: currentColor; border-radius: 1px; box-shadow: 0 5px 0 currentColor, 0 10px 0 currentColor; }
.colrow .draghandle:active { cursor: grabbing; }
.colrow.dragging { opacity: .4; }
.colrow.dragover { border-top: 2px solid var(--primary); }

/* 排产/看板筛选条：字段名在输入框前 */
.flt { display: inline-flex; align-items: center; gap: 6px; }
.flt > span { font-size: 13px; color: var(--muted); white-space: nowrap; }
.flt input, .flt select { padding: 7px 9px; border: 1px solid var(--line); border-radius: 8px; font-size: 14px; background: #fff; min-width: 110px; }
/* 该列在表头里挑过值：筛选条上挂个小徽标，别让条件藏起来 */
.flt-pick { font-size: 11.5px; font-weight: 600; color: #fff; background: var(--primary); border-radius: 9px; padding: 1px 7px; white-space: nowrap; cursor: default; }

/* 筛选方案管理：字段名与勾选框同行，值输入框全宽 */
.field label.chk { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--text); font-weight: 500; cursor: pointer; }
.field label.chk input[type=checkbox] { width: 16px; height: 16px; flex: 0 0 auto; }
.field input[disabled], .field select[disabled] { background: #f2f4f7; color: var(--muted); }

/* 排产列表内联工艺路线下拉 */
table.dtable select.route-sel { padding: 4px 6px; font-size: 12px; border: 1px solid var(--line); border-radius: 6px; background: #fff; max-width: 190px; }
table.dtable select.route-sel.unset { border-color: var(--red); background: var(--red-bg); color: var(--red); }
/* 下拉 + 右侧排产状态并排：下拉只占自己能占的宽度，状态标固定不换行、不被挤掉 */
.rsel { display: flex; align-items: center; gap: 6px; min-width: 0; width: 100%; }
table.dtable.rz select.route-sel.rsel-sel { width: auto; max-width: none; flex: 1 1 0; min-width: 0; }
table.dtable.rz select.route-sel.rsel-sel:disabled { background: #f6f8fa; color: var(--muted); cursor: progress; }
.rsel-st { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px; font-style: normal; font-size: 11px; line-height: 1; white-space: nowrap; }
.rsel-st.syncing { color: #2b6ca3; }
.rsel-st.done { color: var(--green); }
.rsel-st.error { color: var(--red); }
.rspin { display: inline-block; width: 9px; height: 9px; border: 2px solid #cfe0f0; border-top-color: #2b6ca3; border-radius: 50%; animation: rspin .7s linear infinite; }
@keyframes rspin { to { transform: rotate(360deg); } }

/* ============ 宽版弹窗（筛选方案管理横版） ============ */
.modal-mask .sheet.wide { max-width: 1040px; width: calc(100vw - 48px); max-height: 92%; }
/* 超宽版：接单详情（订单信息三列 + 产品明细表 + 五个流程节点排一行）
   1520 是「5 个节点 + 状态 + 三个按钮」能排成一行的余量 */
.modal-mask .sheet.xwide { max-width: 1520px; width: calc(100vw - 32px); max-height: 92%; }
/* 弹窗宽度可自己调（博士 11-05：所有二级页面都让我自定义宽度）：
   右边缘 10px 是拖拽手柄，拉完按档位记进 localStorage，下次打开一样宽。
   手机端不显示 —— 那边本来就是全宽。 */
.modal-mask .sheet { position: relative; }
.sheet-rz { position: absolute; top: 0; right: 0; width: 10px; height: 100%; cursor: col-resize; z-index: 40; }
.sheet-rz::after { content: ''; position: absolute; top: 0; bottom: 0; right: 0; width: 2px; background: transparent; transition: background .15s; }
.sheet-rz:hover::after, body.sheet-resizing .sheet-rz::after { background: var(--primary); }
body.sheet-resizing, body.sheet-resizing .modal-mask { cursor: col-resize; user-select: none; }
body.mobile .sheet-rz { display: none; }

/* ============ 设置页：左侧二级菜单 + 右侧内容（统一横版） ============ */
.settings-wrap { display: flex; gap: 14px; align-items: flex-start; }
.side-menu { flex: 0 0 196px; background: #fff; border: 1px solid var(--line); border-radius: 10px; padding: 6px; position: sticky; top: 96px; }
.side-menu .si { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-radius: 8px; font-size: 14px; color: var(--text); cursor: pointer; border: 0; background: none; width: 100%; text-align: left; }
.side-menu .si:hover { background: var(--bg); }
.side-menu .si.active { background: var(--primary); color: #fff; font-weight: 600; }
.side-menu .si .cnt { margin-left: auto; font-size: 12px; opacity: .8; }
.settings-main { flex: 1; min-width: 0; display: flex; flex-direction: column; min-height: 0; }
/* 卡片纵向堆叠：表头/提示/批量条占自然高度，明细表(.dtable-wrap)用 flex:1 填满剩余空间并内部滚动，
   这样无论上方多了「初始口令栏」还是批量条弹出来，整页都不会出现滚动条 */
.settings-main .card { margin-bottom: 0; display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
.settings-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
.settings-head h3 { font-size: 15px; }
.settings-head .spacer { flex: 1; }
.settings-tip { font-size: 12px; color: var(--muted); margin: 0 0 10px; line-height: 1.6; }
/* 注释 + 批量按钮同行：注释按剩余宽度折行，右侧留出按钮的位置 */
.settings-tiprow { display: flex; gap: 14px; align-items: flex-start; margin: 0 0 10px; }
.settings-tiprow > .settings-tip { flex: 1 1 auto; min-width: 0; margin: 0; }
.settings-tiprow > .batch-actions { flex: 0 0 auto; margin: 0; }

/* 工序/人员管理表格内联编辑 */
table.mtable { border-collapse: collapse; width: 100%; font-size: 13px; }
table.mtable th, table.mtable td { border: 1px solid var(--line); padding: 6px 8px; text-align: left; }
table.mtable th { background: #f6f8fa; font-weight: 600; white-space: nowrap; }
table.mtable input, table.mtable select { width: 100%; padding: 6px 8px; border: 1px solid var(--line); border-radius: 6px; font-size: 13px; background: #fff; }
table.mtable input.num { width: 72px; }
table.mtable td.act { white-space: nowrap; width: 1%; }

/* 设置页：勾选列 + 批量操作条（位于列表上方） */
table.mtable th.chkcol, table.dtable th.chkcol { width: 38px; text-align: center; }
table.mtable td.chktd, table.dtable td.chktd { width: 38px; text-align: center; vertical-align: middle; }
.chktd input.rowchk, th.chkcol input.chkall { width: 16px; height: 16px; cursor: pointer; }
.settings-main .batchbar { background: #f7fbff; border: 1px solid #dceaf6; border-radius: 8px; padding: 8px 10px; margin: 2px 0 10px; align-items: center; overflow: visible; flex-wrap: wrap; }
/* 批量操作按钮：常驻显示，紧贴「+ 新增…」按钮下方右对齐（没勾选时置灰不可点） */
.batch-actions { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; flex: 0 0 auto; margin: -2px 0 6px; }
.batch-actions .btn { flex: 0 0 auto; }
/* 需求4：滚动只发生在「明细表」内部。横向 .dtable-wrap 已 overflow-x:auto；
   纵向让明细表填满卡片剩余空间并内部滚动（flex:1 + min-height:0），整页不出现滚动条；
   其余列表（Excel 导入对应区）同样是 .dtable-wrap，一并受益 */
.settings-main .card > .dtable-wrap { flex: 1 1 auto; min-height: 0; overflow: auto; }
.settings-main .card > .dtable-wrap > table > thead > tr > th {
  position: sticky; top: 0; z-index: 6; background: #f6f8fa;
  box-shadow: inset 0 -1px 0 var(--line);
}
.batchbar .bcnt { font-size: 13px; color: var(--muted); align-self: center; }
.batchbar .spacer { flex: 1; }
.colrm { margin-left: 8px; flex: 0 0 auto; }
.addcol { border: 1px dashed var(--primary); color: var(--primary); background: #fff; }

/* ============ 筛选方案管理：左侧方案列表 + 右侧字段配置 ============ */
.scheme-wrap { display: flex; gap: 16px; align-items: flex-start; }
.scheme-list { flex: 0 0 208px; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; background: #fff; }
.scheme-list .sh { padding: 8px 10px; background: #f6f8fa; font-size: 12px; color: var(--muted); border-bottom: 1px solid var(--line); }
.scheme-item { padding: 10px; border-bottom: 1px solid var(--line); cursor: pointer; font-size: 13px; display: flex; align-items: center; gap: 6px; }
.scheme-item:last-child { border-bottom: 0; }
.scheme-item:hover { background: var(--bg); }
.scheme-item.active { background: var(--blue-bg); color: var(--blue); font-weight: 600; }
.scheme-item .nm { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.scheme-item .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green); flex: 0 0 auto; }
.scheme-item .del { color: var(--muted); background: none; border: 0; cursor: pointer; font-size: 15px; line-height: 1; padding: 0 2px; }
.scheme-item .del:hover { color: var(--red); }
.scheme-main { flex: 1; min-width: 0; }
/* 方案操作按钮挪到「设置明细」上方：另存为 / 设为默认 / 列设置 + 自动保存提示 */
.scheme-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 10px 0 10px; }
.scheme-hint { font-size: 12px; color: var(--muted); opacity: 0; transition: opacity .2s; }
.scheme-hint.on { opacity: 1; }
.scheme-hint.on:not(.sticky) { color: var(--green); }
.scheme-fields { max-height: 52vh; overflow-y: auto; padding-right: 4px; }
.scheme-fields .field { margin-bottom: 0; }

/* 横版紧凑两列（筛选字段 / 导入列对应） */
.grid2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 20px; }
@media (max-width: 780px) { .grid2 { grid-template-columns: 1fr; } }

@media (max-width: 860px) {
  .settings-wrap { flex-direction: column; }
  .side-menu { flex: none; width: 100%; position: static; display: flex; overflow-x: auto; }
  .side-menu .si { width: auto; white-space: nowrap; }
  .scheme-wrap { flex-direction: column; }
  .scheme-list { flex: none; width: 100%; max-height: 140px; overflow-y: auto; display: flex; flex-wrap: wrap; }
  .scheme-list .sh { width: 100%; }
  .scheme-item { width: 50%; }
}
/* 桌面端：整体布局锁定视口高度 —— #app 用 flex 列占满 100vh，顶栏+主导航占自然高度，
   .container 吃剩余高度(min-height:0 允许内部滚动)。这样设置/看板/排产所有「明细表」都能
   在卡片内 flex 填满剩余空间并内部滚动，整页不再出现滚动条（移动端保持整页滚动，不套这个规则）。 */
@media (min-width: 861px) {
  #app { height: 100vh; display: flex; flex-direction: column; }
  .container { flex: 1; min-height: 0; }
  .settings-wrap { align-items: stretch; height: 100%; }
}

/* ================= 日计划（博士端） ================= */
.plan-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.plan-bar .plan-date { padding: 7px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 14px; background: #fff; }
.plan-bar .plan-dayname { font-size: 14px; font-weight: 600; color: var(--primary); }
.plan-bar .spacer { flex: 1; }
.plan-bar .btn.sm { padding: 6px 12px; }
/* 工序卡片筛选（博士 11-05）：单独一行放在日期工具栏下方，不占日期和右侧按钮的位置 */
.step-chips { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; padding: 0; margin: -4px 0 12px; }
.step-chip { flex: 0 0 auto; font-size: 12px; line-height: 1; padding: 7px 9px; border-radius: 14px; border: 1px solid var(--line); background: #fff; color: #42526b; cursor: pointer; white-space: nowrap; }
.step-chip:hover { border-color: #9db8dd; background: #f4f8ff; }
.step-chip em { font-style: normal; margin-left: 5px; font-size: 11px; color: #8592a6; }
.step-chip.on { background: #2f6df6; border-color: #2f6df6; color: #fff; font-weight: 600; }
.step-chip.on em { color: #dbe7ff; }
.step-chip.zero { opacity: .55; }

.kpi-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 12px; }
.kpi { background: #fff; border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; display: flex; flex-direction: column; gap: 2px; }
.kpi span { font-size: 12px; color: var(--muted); }
.kpi b { font-size: 24px; font-weight: 700; line-height: 1.15; letter-spacing: -.5px; }
.kpi em { font-size: 11px; color: var(--muted); font-style: normal; }
.kpi.ok b { color: var(--green); }
.kpi.bad b { color: var(--red); }
.kpi.blue b { color: var(--blue); }

.loadwrap { background: #fff; border: 1px solid var(--line); border-radius: 10px; padding: 10px 14px 6px; margin-bottom: 14px; }
.loadtitle { font-size: 12px; color: var(--muted); margin-bottom: 6px; }
.load-hint { margin-left: 10px; color: var(--muted); opacity: .75; }
.loadstrip { display: flex; align-items: flex-end; gap: 4px; overflow-x: auto; padding-bottom: 4px; }
/* 每天是一个按钮：点一下跳到那天的日计划 */
.loadcol { flex: 1 0 44px; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 2px;
  background: none; border: 0; padding: 4px 0 2px; margin: 0; font: inherit; cursor: pointer; border-radius: 6px;
  transition: background .15s; }
.loadcol:hover { background: #f2f7fc; }
.loadcol:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.loadcol i { width: 100%; max-width: 34px; background: #cfe0f0; border-radius: 4px 4px 0 0; display: block; transition: height .2s, background .15s; }
.loadcol:hover i { background: #a9c9e6; }
.loadcol em { font-size: 11px; color: var(--text); font-style: normal; line-height: 1; }
.loadcol span { font-size: 10px; color: var(--muted); }
.loadcol.today i { background: var(--primary); }
.loadcol.today em, .loadcol.today span { color: var(--primary); font-weight: 700; }
/* 当前正在看的那一天 */
.loadcol.viewing { background: #eaf3fb; box-shadow: inset 0 -3px 0 var(--primary); }
.loadcol.viewing span { color: var(--primary); font-weight: 700; }
/* 前 3 天是历史（已过去，只作对照），整体压暗、柱子用灰蓝，别和未来混在一起 */
.loadcol.past { opacity: .5; }
.loadcol.past i { background: #d5dee8; }
.loadcol.past em { color: var(--muted); font-weight: 500; }

.plan-group { background: #fff; border: 1px solid var(--line); border-radius: 10px; margin-bottom: 12px; overflow-x: auto; overflow-y: hidden; }
.pg-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; padding: 10px 14px; border-bottom: 1px solid var(--line); background: #fafbfd; }
.pg-head b { font-size: 14px; }
/* 工序栏后面的负责人小字（按工序分栏后，人在栏头注明是谁做） */
.pg-owner { font-size: 12px; color: var(--muted); max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pg-tag { font-size: 12px; padding: 2px 8px; border-radius: 10px; background: var(--yellow-bg); color: #8a6100; }
.pg-tag.done { background: var(--green-bg); color: var(--green); }
.pg-done { font-size: 12px; color: var(--muted); margin-left: auto; }
/* 每道工序的当日统计（整行独占一行，跟手机端那排方块一个口径）：数字大、标签小，颜色分档 */
.pg-stats { flex-basis: 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.pgn { display: inline-flex; align-items: baseline; gap: 4px; padding: 2px 9px; border-radius: 11px; background: #eef2f7; color: #46536b; font-size: 11.5px; line-height: 18px; }
.pgn b { font-size: 13px; font-weight: 700; color: #1f2933; font-variant-numeric: tabular-nums; }
.pgn em { font-style: normal; }
.pgn.ok { background: var(--green-bg); color: #2b6a2b; }
.pgn.ok b { color: var(--green); }
.pgn.bad { background: var(--red-bg); color: #9c2b2b; }
.pgn.bad b { color: var(--red); }
.pgn.blue { background: var(--blue-bg); color: #1c4f8a; }
.pgn.blue b { color: var(--blue); }
.pgn.mute { background: #eef0f3; color: var(--muted); }
.pgn.next { background: #eaf2fd; color: #1c4f8a; }
/* 每道工序自己的「生成图片」按钮：贴在栏头最右边（统计条独占下一行） */
.pg-img-btn { margin-left: auto; padding: 3px 10px; font-size: 12px; }
@media (max-width: 640px) { .pg-img-btn { padding: 3px 8px; } }
.pgn.val { margin-left: auto; background: #f4f7ec; color: #4d6b2a; }
.pgn.val b { color: #33691e; }
.pg-table { border: 0; border-radius: 0; }
.pg-table th { font-size: 12px; }
.pg-table td { font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.prow { cursor: pointer; }
.prow:hover td { background: #f7fafd; }
.prow.isdone td { color: var(--muted); }
.prow.isdone td b { color: var(--muted); font-weight: 500; }
.pg-table td.note { color: var(--muted); font-size: 12px; }
/* 受阻原因可能是一句话：窄列里折成两行显示，超出两行再省略（完整内容看 title） */
/* 不加父选择器：日计划是 .pg-table、看板是 .dtable，两边都要有 */
.blk-txt { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; white-space: normal; line-height: 1.35; font-size: 12px; }
/* 受阻时长小字：跟在原因同一行的末尾，不单独占行（占一行会把整格行高撑高） */
.blk-dur { display: inline; font-style: normal; color: #8a97a6; font-size: 10.5px; line-height: 1.2; margin-left: 2px; white-space: nowrap; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12.5px; }
.txt-red { color: var(--red); font-weight: 600; }
.txt-blue { color: var(--blue); }

/* ================= 班组长手机端 ================= */
.dnav { display: flex; align-items: center; gap: 8px; background: #fff; border: 1px solid var(--line); border-radius: 12px; padding: 8px 10px; margin-bottom: 10px; }
.dnav-b { width: 40px; height: 40px; border: 1px solid var(--line); background: #fff; border-radius: 10px; font-size: 20px; line-height: 1; color: var(--primary); cursor: pointer; }
.dnav-m { flex: 1; text-align: center; display: flex; flex-direction: column; }
.dnav-m b { font-size: 15px; }
.dnav-m span { font-size: 11px; color: var(--muted); }

/* 四个统计方块＝分页切换按钮（点击切下面的明细） */
.lsum { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 12px; }
.lsum-i { display: block; width: 100%; background: #fff; border: 1px solid var(--line); border-radius: 12px; padding: 8px 2px; text-align: center; font: inherit; color: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; transition: background .12s, border-color .12s; }
.lsum-i:active { transform: scale(.98); }
.lsum-i b { display: block; font-size: 20px; line-height: 1.2; }
.lsum-i span { display: block; font-size: 10.5px; line-height: 1.25; color: var(--muted); margin-top: 1px; }
.lsum-i.ok b { color: var(--green); }
.lsum-i.bad b { color: var(--red); }
.lsum-i.on { background: #eef5ff; border-color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }
.lsum-i.on span { color: var(--primary); font-weight: 700; }


.lsec { margin-bottom: 14px; }
.lsec-h { display: flex; align-items: center; gap: 8px; margin: 0 2px 8px; font-size: 13px; color: var(--muted); font-weight: 600; }
.lsec-h i { font-style: normal; background: #e8edf4; color: var(--primary); border-radius: 9px; padding: 0 7px; font-size: 12px; }
.lsec-h .lsec-val { margin-left: auto; font-size: 12.5px; font-weight: 700; color: var(--text); white-space: nowrap; }
.lempty { background: #fff; border: 1px dashed var(--line); border-radius: 12px; padding: 22px; text-align: center; color: var(--muted); font-size: 13px; }

.tcard { background: #fff; border: 1px solid var(--line); border-left: 4px solid var(--gray); border-radius: 12px; padding: 12px 14px; margin-bottom: 10px; }
.tcard.c-green { border-left-color: var(--green); }
.tcard.c-yellow { border-left-color: var(--yellow); }
.tcard.c-red { border-left-color: var(--red); }
.tcard.c-blue { border-left-color: var(--blue); }
.tc-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 2px; }
.tc-pname { font-size: 16px; font-weight: 700; line-height: 1.3; }
.tc-val { flex: 0 0 auto; font-size: 14px; font-weight: 700; color: var(--text); }
.tc-l2 { display: flex; flex-wrap: nowrap; align-items: center; justify-content: space-between; gap: 8px; margin-top: 5px; font-size: 14px; font-weight: 700; color: var(--text); }
.tc-l2l { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: center; min-width: 0; }
.tc-l2 .tc-k { white-space: nowrap; }
.tc-l3 { display: flex; flex-wrap: wrap; gap: 3px 14px; margin-top: 3px; font-size: 12px; color: var(--muted); font-family: ui-monospace, Menlo, Consolas, monospace; }
.tc-l4 { margin-top: 4px; font-size: 12px; color: var(--muted); }
.chip { display: inline-block; margin-top: 8px; margin-right: 6px; padding: 3px 9px; border-radius: 999px; font-size: 12px; font-weight: 600; }
.chip.red { background: var(--red-bg); color: var(--red); }
.chip.blue { background: var(--blue-bg); color: var(--blue); }
.tc-actions { display: flex; gap: 8px; align-items: center; margin-top: 12px; }
.btn.big { flex: 1; padding: 13px 16px; font-size: 16px; font-weight: 700; border-radius: 10px; }

.llist { background: #fff; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.tline { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--line); }
.tline:last-child { border-bottom: 0; }
.tl-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; background: var(--gray); }
.tl-dot.green { background: var(--green); } .tl-dot.yellow { background: var(--yellow); } .tl-dot.red { background: var(--red); } .tl-dot.blue { background: var(--blue); }
.tl-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.tl-main b { font-size: 14px; }
.tl-main em { font-size: 12px; color: var(--muted); font-style: normal; }
.tl-side { text-align: right; font-size: 12px; color: var(--muted); }
.tl-side em { display: block; font-style: normal; font-size: 11px; }
.lfoot { margin: 4px 0 20px; }
.tc-wait { margin-top: 12px; padding: 10px 12px; background: var(--gray-bg); color: var(--muted); border-radius: 8px; font-size: 13px; text-align: center; }
/* 明日预告：提示词 + 右侧「提前开工」按钮（按钮样式参考「受阻」） */
.tc-nextrow { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.tc-nextrow .tc-wait { flex: 1 1 auto; margin-top: 0; text-align: left; padding: 8px 10px; }
.tc-nextrow .btn { flex: 0 0 auto; margin: 0; }

/* 今日已完工卡片（两行）：
   第一行 产品名称·图号·批次 ×数量 | 产值   —— 左侧同工序名字体，产值同第二行字体
   第二行 项目名称 | 完工工序 → 交接工序    —— 同第二行字体 */
.dcard { background: #fff; border: 1px solid var(--line); border-left: 4px solid var(--green); border-radius: 12px; padding: 10px 12px; margin-bottom: 8px; }
.dc-l1 { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; font-size: 14px; font-weight: 700; color: var(--text); }
.dc-main { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 产值与第二行：字体/颜色/字号对齐待完工卡片的第三、四行（12px 常规、次要灰） */
.dc-val { flex: 0 0 auto; font-size: 12px; font-weight: 400; color: var(--muted); }
.dc-l2 { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-top: 3px; font-size: 12px; font-weight: 400; color: var(--muted); }
.dc-proj { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dc-flow { flex: 0 0 auto; }

/* ================= 分批交接（玄机2） ================= */
.bchip { display: inline-block; padding: 1px 7px; border-radius: 999px; background: #eef2f9; color: var(--primary); font-size: 12px; font-weight: 600; font-family: ui-monospace, Menlo, Consolas, monospace; }
.chip.b { background: #eef2f9; color: var(--primary); }
.qtybox { background: #f7fafd; border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; margin-bottom: 12px; }
.qtylab { font-size: 14px; margin-bottom: 10px; }
.qtyrow { display: flex; gap: 10px; align-items: center; }
.qtyrow input { flex: 1; min-width: 0; font-size: 22px; font-weight: 700; text-align: center; padding: 10px; border: 2px solid var(--line); border-radius: 10px; }
.qtyrow input:focus { border-color: var(--primary); outline: none; }
.qhint { margin-top: 10px; font-size: 13px; color: var(--muted); line-height: 1.5; }
.qhint b { color: var(--primary); }
.qtag { background: var(--yellow-bg); color: #8a6100; border-radius: 6px; padding: 1px 6px; font-size: 12px; font-weight: 700; }

/* ================= 多线程工艺路线（分叉 / 汇聚） ================= */
.route-tip { font-size: 12.5px; color: var(--muted); line-height: 1.6; background: #f6f9fd; border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; margin-bottom: 10px; }
.route-tip b { color: var(--primary); }

.step-row .depbtn { box-sizing: border-box; height: 34px; padding: 0 8px; font-size: 12.5px; font-family: inherit; border: 1px solid var(--line); background: #fff; border-radius: 8px; cursor: pointer; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.step-row .depbtn.start { color: var(--muted); background: #fbfcfe; border-color: #eaeef4; }
.step-row .depbtn:hover { border-color: var(--primary); color: var(--primary); }

/* 浮层改成「贴着按钮定位的悬浮面板」：原来 absolute 挂在行里，落到弹窗底部会被
   .sheet-body 的 overflow 裁掉，还会压住下面的结构预览/保存按钮 —— 看着像错位。
   现在 position:fixed + JS 量位置，放不下就往上翻，并限高让列表自己滚。 */
.dep-pop { position: fixed; z-index: 60; left: 0; top: 0; width: 296px; max-height: calc(100vh - 16px); overflow-y: auto; background: #fff; border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 12px 32px rgba(20,40,60,.18); padding: 10px; }
.dep-pop-h { margin-bottom: 8px; }
.dep-pop-t { font-size: 13px; font-weight: 600; }
.dep-pop-s { font-size: 11.5px; color: var(--muted); line-height: 1.5; margin-top: 2px; }
.dep-pop-cur { font-size: 12px; color: var(--primary); margin-top: 4px; }
.dep-pop-list { max-height: 240px; overflow-y: auto; border: 1px solid var(--line); border-radius: 8px; padding: 4px; }
.dep-item { display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: 6px; font-size: 13px; line-height: 20px; cursor: pointer; }
.dep-item:hover { background: #f2f7fc; }
.dep-item input { flex: 0 0 auto; width: 15px; height: 15px; margin: 0; accent-color: var(--primary); }
.dep-item span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dep-pop-f { display: flex; gap: 8px; margin-top: 10px; }
.dep-pop-f .btn { flex: 1; }
/* 择一区（二选一）：跟前置选择放在同一个浮层里，认知连贯 —— 选前置的同时指定谁能替代谁 */
.dep-pop-alt { margin-top: 10px; border-top: 1px dashed var(--line); padding-top: 8px; }
.dep-pop-alt .alt-h { font-size: 12.5px; font-weight: 600; color: #5a3fa8; }
.dep-pop-alt .alt-h span { font-weight: 400; font-size: 11.5px; color: var(--muted); }
.dep-pop-alt .alt-s { font-size: 11.5px; color: var(--muted); line-height: 1.55; margin: 3px 0 6px; }
.dep-pop-alt .alt-list { max-height: 132px; overflow-y: auto; border: 1px solid var(--line); border-radius: 8px; padding: 4px; }
/* 前置不同的小提示：勾选会自动对齐，先说清楚免得设出无效的替代 */
.dep-pop-alt .alt-dep { display: block; font-style: normal; font-size: 11px; color: #9a6212; margin-top: 1px; }

/* 表头下拉筛选（Excel 式）：点表头小三角弹这个面板。
   默认一项都不勾 = 这一列不限；勾几项就只看这几项（搜索后勾一项即可，不用先取消一堆）。
   和 dep-pop 一样 position:fixed + JS 定位：挂 table 里会被 .dtable-wrap 的 overflow 裁掉。 */
.hf-pop { position: fixed; z-index: 62; left: 0; top: 0; width: 272px; max-height: calc(100vh - 16px); background: #fff; border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 12px 32px rgba(20,40,60,.18); padding: 9px; visibility: hidden; }
.hf-pop-t { font-size: 12.5px; font-weight: 600; margin-bottom: 5px; display: flex; align-items: center; gap: 5px; }
.hf-pop-t b { font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hf-pop-t em { flex: 0 0 auto; font-style: normal; font-weight: 400; font-size: 11.5px; color: var(--muted); white-space: nowrap; }
/* 「清除筛选」钉在浮层右上角：这一列有筛选时可点，没有就置灰 */
.hf-pop-t .hf-clr { flex: 0 0 auto; margin-left: auto; height: 21px; padding: 0 6px; font-size: 11px; line-height: 19px; font-weight: 400; color: var(--muted); background: #fff; border: 1px solid var(--line); border-radius: 6px; cursor: pointer; white-space: nowrap; }
.hf-pop-t .hf-clr:hover { color: var(--primary); border-color: var(--primary); background: #eef6fd; }
.hf-pop-t .hf-clr:disabled { opacity: .45; cursor: not-allowed; background: #fff; border-color: var(--line); color: var(--muted); }
.hf-pop-h { font-size: 11.5px; line-height: 1.4; color: var(--muted); margin-bottom: 6px; }
.hf-q { width: 100%; box-sizing: border-box; height: 28px; font-size: 12.5px; padding: 0 8px; border: 1px solid var(--line); border-radius: 7px; margin-bottom: 6px; }
.hf-q:focus { outline: none; border-color: var(--primary); }
.hf-list { max-height: 220px; overflow-y: auto; border: 1px solid var(--line); border-radius: 8px; padding: 3px; }
.hf-item { display: flex; align-items: center; gap: 7px; padding: 4px 6px; border-radius: 6px; font-size: 13px; line-height: 19px; cursor: pointer; }
.hf-item:hover { background: #f2f7fc; }
.hf-item input { flex: 0 0 auto; width: 14px; height: 14px; margin: 0; accent-color: var(--primary); }
.hf-item span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hf-item em { flex: 0 0 auto; font-style: normal; font-size: 11px; color: var(--muted); }
.hf-item.is-empty span { color: var(--muted); }
.hf-none { padding: 8px 6px; font-size: 12px; color: var(--muted); }
/* 每个值是「复选行 + 右侧『仅此项』按钮」：一行点一下就能只看这一项 */
.hf-row { display: flex; align-items: center; gap: 3px; }
.hf-row .hf-item { flex: 1; min-width: 0; padding-right: 0; }
.hf-row.hide { display: none; }
.hf-only { flex: 0 0 auto; height: 21px; padding: 0 6px; font-size: 11px; line-height: 19px; color: var(--muted); background: #fff; border: 1px solid var(--line); border-radius: 6px; cursor: pointer; white-space: nowrap; opacity: .8; }
.hf-row:hover .hf-only { opacity: 1; }
.hf-only:hover { color: var(--primary); border-color: var(--primary); background: #eef6fd; }
/* 首行「全选」框：跟 Excel/WPS 一样钉在列表顶上，滚值列表时不动 */
.hf-row-all { position: sticky; top: 0; z-index: 1; background: #fff; border-bottom: 1px solid var(--line); margin-bottom: 2px; padding-right: 10px; }
.hf-item.hf-all { font-weight: 600; border-radius: 0; }
.hf-item.hf-all em { font-weight: 400; }
.hf-f { display: flex; align-items: center; gap: 6px; margin-top: 8px; }
.hf-f .btn { flex: 1; }

.graph-wrap { background: #fbfcfe; border: 1px solid var(--line); border-radius: 10px; padding: 10px; overflow-x: auto; min-height: 64px; }
/* 按自然尺寸显示，长路线靠横向滚动，别把字缩成蚂蚁 */
.route-graph { display: block; width: auto; height: auto; max-width: none; }
.graph-legend { display: flex; gap: 16px; flex-wrap: wrap; font-size: 12px; color: var(--muted); margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--line); }
.graph-legend i { display: inline-block; width: 12px; height: 12px; border-radius: 3px; border: 1px solid var(--line); margin-right: 5px; vertical-align: -2px; }
.graph-legend i.dot { width: 7px; height: 7px; border-radius: 50%; border: 0; background: #8fb8dd; vertical-align: 0; }

/* 人员账号：口令明文显示 */
.pwd-plain { display: inline-block; padding: 3px 10px; border-radius: 6px; background: #f1f6fb; border: 1px solid var(--line); font-family: ui-monospace, Consolas, monospace; font-size: 13.5px; letter-spacing: .5px; color: #2b4156; }
/* 初始口令说明条：只展示系统统一初始值，不展示任何人的真实口令 */
.init-pwd-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 10px 0 12px; padding: 10px 12px; border-radius: 9px; background: #f6faf6; border: 1px solid #d7e8d7; font-size: 13px; color: #33503a; }
.init-pwd-bar > span { font-weight: 600; }
.init-pwd-bar i { flex: 1 1 260px; font-style: normal; color: #5b7361; line-height: 1.6; font-size: 12.5px; }
.init-pwd-bar b.pwd-plain { background: #fff; border-color: #cfe3cf; }
/* 批量选工序 */
.bulk-pick { max-height: 46vh; overflow-y: auto; border: 1px solid var(--line); border-radius: 9px; padding: 4px; margin-top: 8px; }
.bulk-row { display: flex; align-items: center; gap: 10px; padding: 7px 9px; border-radius: 7px; cursor: pointer; font-size: 13.5px; }
.bulk-row:hover { background: #f2f7fc; }
.bulk-row input { width: auto; margin: 0; }
.bulk-row .bname { flex: 1; }
.bulk-row .bmeta { color: var(--muted); font-size: 12.5px; white-space: nowrap; }
.bulk-row.disabled { opacity: .45; cursor: not-allowed; }
.bulk-tools { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 8px; }
.step-row .depbtn { white-space: nowrap; }

/* 待料任务卡（多线程汇聚未齐套）：显示出来但不给操作 */
.tcard.is-wait { background: #fbfcfd; border-left-color: #c9d5e2; }
.tcard.is-wait .tc-step { color: #5c6b7a; }
.tcard.is-wait .tc-prod b { color: #5c6b7a; font-weight: 600; }

/* 卡片左滑：露出「置顶」按钮（pin = 钉在本分组最上方）
   .swipe-item 吃下卡片原来的下间距，卡片本身不再留 margin，滑开时右侧才不会露出白缝 */
.swipe-item { position: relative; margin-bottom: 10px; border-radius: 12px; overflow: hidden; touch-action: pan-y; background: #fff; }
.swipe-item .tcard { margin-bottom: 0; }
/* 置顶按钮的透明度跟着卡片位移走（--swipe-p 由 JS 每帧写入）：
   静止时完全不画（手机上快速纵向滚动不会有橙色残影），拖动时随手指渐显，
   松手弹到位时已经全亮，不会出现"滑完突然冒出橙色"的突兀感。 */
.swipe-acts { position: absolute; top: 0; right: 0; bottom: 0; width: 86px; padding-left: 6px; box-sizing: border-box; display: flex; opacity: var(--swipe-p, 0); pointer-events: none; transition: opacity .18s ease; }
.swipe-item.open > .swipe-acts { opacity: 1; pointer-events: auto; }
.swipe-item.swiping > .swipe-acts { transition: none; }   /* 跟手阶段不要过渡，否则会慢半拍 */
.swipe-btn { flex: 1; margin: 0; padding: 0; border: 0; font-family: inherit; font-size: 13px; font-weight: 700; line-height: 1.3; color: #fff; background: linear-gradient(180deg, #efa32c, #dd880d); cursor: pointer; border-radius: 12px; }
.swipe-btn.off { background: linear-gradient(180deg, #93a0af, #6f7d8c); }
.swipe-btn:active { filter: brightness(.94); }
.swipe-body { position: relative; z-index: 1; background: #fff; transform: translateX(0); transition: transform .18s ease; }
/* will-change 只在真横滑那一下加：常驻会让每张卡片都单独成一层，
   快速上下滚动时层之间露缝，露出底下的橙色按钮 */
.swipe-item.swiping > .swipe-body { will-change: transform; }
.swipe-body.dragging { transition: none; user-select: none; -webkit-user-select: none; }
/* 置顶标识只用图标，卡片本身不变色（博士要求：卡片别跟着变色） */
.pin-ico { display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px; margin-right: 5px; vertical-align: -2px; color: var(--primary); }
.pin-ico svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
/* 日计划列表里的置顶标识：行首一条细竖条（不受当前第一列是哪一列影响） */
.prow.is-pin td:first-child { box-shadow: inset 3px 0 0 var(--primary); }
.tc-wait b { color: var(--primary); }
.tag.t-start { background: #eaf3fc; color: #2b6ca3; }
.tag.t-merge { background: #fff2e0; color: #9a6212; }
.tag.t-fork { background: #eaf6ee; color: #2c7a4b; }
/* 择一分支（二选一）：交接时只走其中一个 */
.tag.t-alt { background: #f0ecfb; color: #5a3fa8; }
.step-row .depbtn.has-alt { color: #5a3fa8; border-color: #cdc2ef; background: #f7f4ff; }

/* 工艺变更：变更摘要 + 变更记录 */
.chg-summary { display: flex; flex-wrap: wrap; gap: 6px; min-height: 30px; align-items: center; }
.chg-chip { display: inline-block; padding: 3px 9px; border-radius: 999px; font-size: 12.5px; line-height: 1.6; border: 1px solid transparent; }
.chg-chip.c-add { background: var(--green-bg); color: var(--green); border-color: #c6e6c8; }
.chg-chip.c-rep { background: var(--yellow-bg, #fff8e1); color: #8d6e00; border-color: #f0e0ad; }
.chg-chip.c-skip { background: var(--red-bg); color: var(--red); border-color: #f5c9cd; }
.chg-chip.c-adj { background: var(--blue-bg); color: var(--blue); border-color: #c6ddf3; }
.chg-warn { flex: 0 0 100%; margin-top: 6px; background: #fff4e5; border: 1px solid #f0d3a8; color: #8a5a12; border-radius: 8px; padding: 7px 10px; font-size: 12.5px; line-height: 1.6; }
.chg-log { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; margin-bottom: 10px; background: #fff; }
.chg-log-h { display: flex; gap: 10px; align-items: baseline; font-size: 13px; }
.chg-log details { margin-top: 4px; }
.chg-log summary { font-size: 12.5px; color: var(--muted); cursor: pointer; }

/* ================= 交接时的工艺变更（班组长手机端） ================= */
.ht-to { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 9px 11px; border-radius: 8px; background: #f6f9fd; border: 1px solid var(--line); margin-bottom: 8px; font-size: 13.5px; }
.ht-to span { color: var(--muted); font-size: 12.5px; }
.ht-to b { color: var(--primary); }
/* 交接时的二选一：两道互为替代的工序，选中的接料、另一个自动取消 */
.altpick { border: 1px solid #cdc2ef; background: #f8f5ff; border-radius: 10px; padding: 11px 12px; margin-bottom: 10px; }
.altpick-t { font-size: 13.5px; font-weight: 600; color: #4a3292; }
.altpick-s { font-size: 12px; color: #6b6180; line-height: 1.6; margin: 3px 0 8px; }
.altpick-s b { color: #4a3292; }
.alt-opt { display: flex; align-items: center; gap: 10px; padding: 11px 12px; background: #fff; border: 1px solid #d8cff2; border-radius: 9px; margin-top: 6px; font-size: 15px; cursor: pointer; }
.alt-opt:has(input:checked) { border-color: #7a5cd6; box-shadow: 0 0 0 1px #7a5cd6 inset; background: #fdfbff; }
.alt-opt input { width: 18px; height: 18px; margin: 0; accent-color: #6b4fd0; flex: 0 0 auto; }
.alt-opt span { flex: 1; min-width: 0; }
/* 选项后缀小标签：上次交给它 / 当前已取消 —— 续交时一眼看出默认值从哪来 */
.alt-opt .alt-b { font-style: normal; font-size: 11px; font-weight: 600; color: #6b4fd0; background: #eee8fd;
  border-radius: 20px; padding: 2px 7px; margin-left: 6px; white-space: nowrap; }
.alt-opt .alt-b + .alt-b { margin-left: 4px; color: #8a6b18; background: #fbf1d6; }
.chgbox { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--line); }
.chg-types { display: grid; gap: 6px; margin-bottom: 10px; }
.chg-t { display: flex; gap: 9px; align-items: flex-start; padding: 9px 11px; border: 1px solid var(--line); border-radius: 8px; background: #fff; cursor: pointer; }
.chg-t input { margin: 2px 0 0; width: 16px; height: 16px; flex: 0 0 auto; }
.chg-t span { display: flex; flex-direction: column; gap: 2px; }
.chg-t b { font-size: 13.5px; font-weight: 600; }
.chg-t i { font-style: normal; font-size: 12px; color: var(--muted); line-height: 1.5; }
.chg-t:has(input:checked) { border-color: var(--primary); background: #f5f9fd; }
.chg-warn2 { background: #fff4e5; border: 1px solid #f0d3a8; color: #8a5a12; border-radius: 8px; padding: 7px 10px; font-size: 12.5px; line-height: 1.6; margin-top: 8px; }
.chg-quick { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 7px; }
.chg-q { border: 1px solid var(--line); background: #fff; color: var(--muted); border-radius: 999px; padding: 3px 10px; font-size: 12px; cursor: pointer; line-height: 1.6; }
.chg-q:hover { border-color: var(--primary); color: var(--primary); }
/* 「标记受阻」弹层：说明条 + 快捷原因 + 两个等宽大按钮（跟完工交接弹窗同一套观感） */
.blk-tip { background: #f2f7fc; border: 1px solid #d6e4f2; color: #2b6ca3; border-radius: 8px; padding: 9px 11px; font-size: 13px; line-height: 1.55; margin-bottom: 12px; }
.blk-err { color: var(--red); font-size: 12.5px; margin: -4px 0 10px; }
.blk-btns { display: flex; gap: 10px; margin-top: 4px; }
.blk-btns .btn { flex: 1; }
.tc-recv { margin-top: 7px; background: #fff4e5; border: 1px solid #f0d3a8; color: #8a5a12; border-radius: 8px; padding: 7px 10px; font-size: 12.5px; line-height: 1.55; }
.tc-next { margin-top: 8px; font-size: 12.5px; color: var(--muted); }

/* 顶栏「变更提醒」（仅博士端） */
.topbar .bell { position: relative; border-radius: 8px; }
.topbar .bell.has-new { background: #fff; color: var(--primary); font-weight: 600; }
.topbar .bell b { position: absolute; top: -6px; right: -6px; min-width: 17px; height: 17px; padding: 0 4px; border-radius: 9px; background: var(--red); color: #fff; font-size: 11px; line-height: 17px; text-align: center; font-weight: 700; }
.notice { border: 1px solid var(--line); border-radius: 9px; padding: 9px 11px; margin-bottom: 8px; background: #fff; }
.notice .nt-h { display: flex; justify-content: space-between; gap: 8px; font-size: 13px; }
.notice .nt-h span { color: var(--muted); font-size: 12px; white-space: nowrap; }
.notice .nt-p { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.notice .nt-s { font-size: 13px; margin-top: 5px; line-height: 1.6; }
.notice .nt-by { font-size: 12px; color: var(--muted); margin-top: 4px; }

/* 已跳过工序：灰显保留在工序链里 */
table.dtable tr.row-skip td { background: #fafbfc; color: var(--muted); }
table.dtable tr.row-skip td.nm { text-decoration: line-through; text-decoration-color: rgba(0,0,0,.22); }
table.dtable tr.row-missing td { background: #fcfcfd; color: #9aa3ad; }
/* 二选一里没被选中的那道：工序名划掉（料整批走了同组另一道，这道对这批等于不走） */
table.dtable td.nm { white-space: nowrap; }
table.dtable td.nm.nm-off { text-decoration: line-through; text-decoration-thickness: 1.5px; text-decoration-color: #b03030; color: #8c8c94; }
/* 已跳过 + 二选一没走：tr.row-skip 的灰划线在下面（更靠后）会盖掉，这里显式要红线 */
table.dtable tr.row-skip td.nm.nm-off { text-decoration-color: #b03030; }
table.dtable td.nm.nm-off .tag { text-decoration: none; }
.skip-note { background: #f4f6f8; border: 1px solid var(--line); border-radius: 8px; padding: 7px 10px; font-size: 12.5px; color: #5c6b7a; margin: 6px 0; }
.skip-note b { color: var(--text); }
.tc-recv i { display: block; font-style: normal; margin-top: 2px; color: #a06a1a; }

.tc-await { display:inline-block; font-size:12px; color:#5a6b7d; background:#f1f5f9; border:1px dashed #cbd5e1; border-radius:8px; padding:6px 10px; }

/* 工单详情：批次切换卡片（分批后每批一条独立生产线） */
.batchbar { display:flex; gap:8px; overflow-x:auto; padding:8px 0 10px; }
.bcard { flex:0 0 152px; display:flex; flex-direction:column; gap:5px; text-align:left; font:inherit; cursor:pointer;
  background:#fff; border:1px solid var(--line); border-radius:10px; padding:9px 11px; }
.bcard:hover { border-color:#b9cbe0; }
.bcard.on { border-color:var(--primary); background:#f7fbff; box-shadow:0 0 0 2px rgba(43,92,143,.13); }
.bcard .bc-t { font-size:14px; font-weight:700; color:var(--primary); }
.bcard.all .bc-t { color:var(--text); }
.bcard .bc-q { font-size:12px; color:var(--muted); }
.bcard .bc-bar { display:block; height:5px; background:var(--gray-bg); border-radius:3px; overflow:hidden; }
.bcard .bc-bar > i { display:block; height:100%; background:var(--green); transition:width .25s; }
.bcard .bc-bar > i.c-yellow { background:var(--yellow); }
.bcard .bc-bar > i.c-red { background:var(--red); }
.bcard .bc-bar > i.c-blue { background:var(--blue); }
.bcard .bc-bar > i.c-gray { background:#b0b7c0; }
.bcard .bc-s { font-size:12px; color:var(--text); line-height:1.35; }
.batch-head { background:#f7fbff; border:1px solid #d6e6f5; border-radius:8px; padding:8px 11px; font-size:13px; margin:2px 0 6px; }
/* 工单详情：全部批次的两种看法（批次矩阵 / 逐行明细） */
.pmg { display:flex; gap:6px; align-items:center; flex-wrap:wrap; margin:2px 0 8px; }
.pmg .pm { font:inherit; font-size:12.5px; padding:3px 11px; border:1px solid var(--line); background:#fff;
  color:var(--muted); border-radius:999px; cursor:pointer; }
.pmg .pm:hover { border-color:#b9cbe0; color:var(--text); }
.pmg .pm.on { border-color:var(--primary); color:var(--primary); background:#f2f8ff; font-weight:600; }
.pmg > .muted { font-size:12px; }
/* 批次矩阵：一行一道工序、一列一批 */
table.pmx th, table.pmx td { padding-left:6px; padding-right:6px; }   /* 列多时要挤得下（6 批也别横向滚动） */
table.pmx th.pmx-bh { white-space:nowrap; cursor:pointer; vertical-align:top; }
table.pmx th.pmx-bh:hover { color:var(--primary); }
table.pmx th.pmx-bh b { font-family:ui-monospace, Menlo, Consolas, monospace; font-size:13px; }
table.pmx th.pmx-bh span { display:block; font-weight:400; font-size:11.5px; color:var(--muted); }
table.pmx th.pmx-bh em { display:block; font-style:normal; font-size:11.5px; font-weight:600; color:var(--muted); }
table.pmx th.pmx-bh em.c-green { color:var(--green); }
table.pmx th.pmx-bh em.c-yellow { color:#b06f00; }
table.pmx th.pmx-bh em.c-red { color:var(--red); }
table.pmx th.pmx-bh em.c-blue { color:var(--blue); }
table.pmx td.pmx-c { white-space:nowrap; cursor:pointer; }
table.pmx td.pmx-c:hover { background:#eef6ff; }
table.pmx td.pmx-c.dim { background:#fcfcfd; }
table.pmx td.pmx-c.offc { background:#fafafa; }
table.pmx td.pmx-c.cur { background:#eef6ff; box-shadow:inset 0 0 0 2px #bfdcf7; border-radius:6px; }
table.pmx .pmx-q { font-size:12px; color:var(--muted); margin-left:5px; }
table.pmx .pmx-od { font-size:11.5px; color:var(--red); font-weight:600; margin-left:5px; }
/* 博士端日计划：明日预告 */
.pg-next { font-size:12px; color:var(--blue); background:var(--blue-bg); padding:2px 8px; border-radius:10px; }
table.dtable tr.isnext td { background:#fbfdff; }
table.dtable tr.isnext td:nth-child(2) { color:#5a6b7d; }
/* 排产列表：分批工单的批次子行 */
tr.batch-sub > td { background:#fafcff; border-top:0; padding:6px 10px 10px; }
.batch-sub .bs-line { display:flex; gap:8px; flex-wrap:wrap; align-items:center; }
.batch-sub .bs-t { font-size:12px; color:var(--muted); margin-right:2px; }
.bchip-btn { display:inline-flex; align-items:center; gap:6px; font:inherit; font-size:12.5px; cursor:pointer;
  background:#fff; border:1px solid var(--line); border-radius:16px; padding:4px 11px; color:var(--text); }
.bchip-btn:hover { border-color:var(--primary); color:var(--primary); }
.bchip-btn b { color:var(--primary); font-weight:700; }
.bchip-btn .dot { width:7px; height:7px; border-radius:50%; display:inline-block; }
.bchip-btn .dot.green { background:var(--green); } .bchip-btn .dot.yellow { background:var(--yellow); }
.bchip-btn .dot.red { background:var(--red); } .bchip-btn .dot.blue { background:var(--blue); }
.bchip-btn .dot.gray { background:#b0b7c0; }
.bchip-btn em { font-style:normal; color:var(--muted); }

/* 排产列表：计划开工 / 交期两列可直接改（原生日期控件：键盘输入 + 日历选择都支持） */
#otable td input.dcel {
  width: 100%; height: 24px; box-sizing: border-box; padding: 0 2px;
  border: 1px solid transparent; border-radius: 6px; background: transparent;
  font: inherit; font-size: 12.5px; color: inherit; cursor: pointer;
}
#otable td input.dcel:hover { border-color: var(--line); background: #fff; }
#otable td input.dcel:focus { border-color: var(--primary); background: #fff; outline: none; }
#otable td input.dcel:disabled { opacity: .55; cursor: progress; }
#otable td input.dcel::-webkit-calendar-picker-indicator { opacity: .45; cursor: pointer; }
#otable td input.dcel:hover::-webkit-calendar-picker-indicator { opacity: .9; }
/* 日期显示统一成 ISO（2026-10-27）：原生控件的文字藏起来，用覆盖文本显示；
   聚焦时再露出原生输入框，键盘敲和点日历选都不受影响 */
#otable td .dwrap { position: relative; display: block; }
#otable td .dwrap .dcel { color: transparent; }
#otable td .dwrap .dcel:focus { color: inherit; }
#otable td .dwrap .dcel:focus + .dshow { display: none; }
#otable td .dshow { position: absolute; left: 6px; right: 24px; top: 50%; transform: translateY(-50%); pointer-events: none; font-size: 12.5px; line-height: 1; white-space: nowrap; overflow: hidden; }
#otable td .dshow.muted { color: var(--muted); }
/* 小日历图标：原生控件的图标在窄格里会被挤掉，自己放一个 */
#otable td .dico { position: absolute; right: 1px; top: 50%; transform: translateY(-50%); width: 19px; height: 19px; display: flex; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 4px; background: transparent; color: #9aa8b6; cursor: pointer; }
#otable td .dico:hover { color: var(--primary); background: #eaf2fb; }
#otable td .dico svg { display: block; }

/* 排产/接单列表：普通单元格双击就地编辑（不弹窗）。
   平时是纯文本（能拖选复制），鼠标划过时淡淡一条下划线提示「这格能改」 */
#otable td .cedit, #stable td .cedit { display: inline-block; min-width: 16px; border-bottom: 1px dashed transparent; }
#otable td:hover .cedit, #stable td:hover .cedit { border-bottom-color: #c7d3df; }
#otable td .cedit:hover, #stable td .cedit:hover { border-bottom-color: var(--primary); color: var(--primary); }
#otable td input.cinput, #stable td input.cinput, #stable td select.csel {
  width: 100%; height: 24px; box-sizing: border-box; padding: 0 4px;
  border: 1px solid var(--primary); border-radius: 6px; background: #fff;
  font: inherit; font-size: 12.5px; color: inherit; outline: none;
  box-shadow: 0 0 0 2px rgba(43,92,143,.12);
}
#otable td input.cinput:disabled { opacity: .6; }

/* 工序已过「最晚开工日」：完工并交接按钮换成加急色，跟卡片上的红标对应 */
.btn.is-urgent { background: linear-gradient(180deg, #e2543b, #c9331a); border-color: #b52d15; color: #fff; }
.btn.is-urgent:hover { background: linear-gradient(180deg, #d94b32, #b62c14); }

/* ================= 接单台账（订单管理模块） ================= */
/* KPI 汇总条：接单数 / 含税 / 自产 / 剩余 / 数量 / 款数 */
.skpi { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 10px; }
.skpi-cell { flex: 1 1 140px; background: #fff; border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px; }
.skpi-cell b { display: block; font-size: 17px; font-weight: 700; color: var(--primary); font-variant-numeric: tabular-nums; }
.skpi-cell span { font-size: 12px; color: var(--muted); }

/* 合计行（博士 11-03 晚定）：不要独立的汇总条，就要 Excel 那样贴在表格最下面一行，
   每个合计值落在它自己那一列底下 —— 拖列宽、换列序、横着滚都跟着走。 */
table.dtable > tfoot > tr > td {
  position: sticky; bottom: 0; z-index: 5;
  background: #f1f5fb; color: var(--primary); font-weight: 700;
  border-top: 2px solid var(--primary);
  font-variant-numeric: tabular-nums;
}
table.dtable > tfoot > tr > td.num { text-align: right; }
table.dtable > tfoot > tr > td.tf-lead { color: var(--muted); font-weight: 600; font-size: 12px; }

/* 选接单弹窗里的一行 */
.pk-list { max-height: 46vh; overflow: auto; border: 1px solid var(--line); border-radius: 8px; }
.pk-row { display: grid; grid-template-columns: 96px 1fr auto; gap: 10px; align-items: center; width: 100%;
  padding: 8px 12px; border: 0; border-bottom: 1px solid var(--line); background: #fff; cursor: pointer;
  font: inherit; font-size: 13px; text-align: left; }
.pk-row:last-child { border-bottom: 0; }
.pk-row:hover { background: #eef6ff; }
.pk-row b { color: var(--primary); }
.pk-row i { font-style: normal; font-size: 12px; color: var(--muted); }

/* 状态胶囊 */
.spill { display: inline-block; font-size: 12px; line-height: 18px; padding: 0 8px; border-radius: 9px; white-space: nowrap; }
.spill.live { background: var(--blue-bg); color: var(--blue); }
.spill.done { background: var(--green-bg); color: var(--green); }
.spill.hold { background: var(--yellow-bg); color: #a06a00; }
.spill.void { background: var(--gray-bg); color: var(--gray); }

/* 五个流程节点：空格子点一下就是 √，再点变 /，再点回空 */
table.dtable td.snode { text-align: center; cursor: pointer; user-select: none; padding: 6px 4px; min-width: 46px; font-weight: 700; }
table.dtable td.snode:hover { background: #eef6ff; }
table.dtable td.snode.v1 { color: var(--green); background: #f2fbf3; }
table.dtable td.snode.v2 { color: #9aa8b6; }
table.dtable td.snode.v0::after { content: '·'; color: #d6dde6; font-weight: 400; }

/* 就地编辑：平时普通文本，双击进入输入框 */
table.dtable td.ed { cursor: text; }
table.dtable td.ed:hover { background: #f6faff; box-shadow: inset 0 0 0 1px #d6e6f7; }
table.dtable td .cell-input { width: 100%; box-sizing: border-box; height: 24px; padding: 0 4px; border: 1px solid var(--primary); border-radius: 5px; font: inherit; font-size: 12.5px; outline: none; background: #fff; }
/* 自产金额是手填（让利价 / 零自产）时的小标记 */
.fix-tag { font-style: normal; font-size: 10px; line-height: 14px; padding: 0 3px; margin-left: 3px; border-radius: 3px; background: var(--yellow-bg); color: #a06a00; vertical-align: 1px; }
/* 「内」= 板式屏风（胶板）内部单，按含税 85 折计产值 —— 跟「手」（Excel 原值）区分开 */
.fix-tag.inner { background: #e8f0fb; color: #2b5c8f; }
.plan-on { color: var(--green); }

/* 分页条 */
.pager { display: flex; align-items: center; gap: 6px; margin-top: 10px; flex-wrap: wrap; }
.pager .spacer { flex: 1; }
.pager .pg-cur { min-width: 34px; text-align: center; font-weight: 700; color: var(--primary); }

/* 接单详情 */
.sdetail { font-size: 13.5px; }
/* 键/值成对排：显式 4 列（标签 值 标签 值），一行两组。
   以前用 auto-fill 自动分列，列数一多媒体查询一变，标签就和值错位（「区域」下面跟着上一组的值）。 */
/* 订单信息：一行三组（博士 11-04）。每组「标签 + 值」包成一个 .sd-f 块，
   整块可拖动换位置 —— 拖动排的是块，不是单元格，所以标签永远跟着自己的值走，不会错位。 */
/* 订单信息：**列优先**（博士 11-04 晚）—— 10 个字段排 3 列就是 4 行：第 1 列 1~4、第 2 列 5~8、第 3 列 9~10。
   以前是行优先（1 2 3 / 4 5 6 …），博士要的是「一列排满再排下一列」。
   列数跟窗口宽度走、行数 = ceil(字段数 / 列数)，都由 JS 算好写进 grid-template-columns / rows，这里只固定流向。 */
.sd-grid { display: grid; grid-auto-flow: column; gap: 6px 18px; align-items: baseline; }
.sd-f { display: grid; grid-template-columns: 84px minmax(0, 1fr); gap: 6px; align-items: baseline;
  border-radius: 6px; padding: 2px 4px; margin: -2px -4px; transition: background .12s; }
.sd-f[data-fk] { cursor: grab; }
.sd-f[data-fk]:hover { background: rgba(43,92,143,.05); }
.sd-f.dragging, .nd-box.dragging { opacity: .4; }
.sd-f.dt-over, .nd-box.dt-over { outline: 2px dashed var(--primary); outline-offset: -2px; }
.sd-grid > .sd-f > .sd-k { color: var(--muted); font-size: 12.5px; }
.sd-grid > .sd-f > .sd-v { font-weight: 600; overflow-wrap: anywhere; }
.sd-grid-tools { display: flex; justify-content: flex-end; align-items: center; gap: 6px; margin: -2px 0 6px; }
/* 「显示字段」面板：两列勾选 */
.sd-fp { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px 14px; max-height: 52vh; overflow: auto; }
.sd-fp-row { display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: 7px; font-size: 13px; cursor: pointer; }
.sd-fp-row:hover { background: #f4f8fd; }
.sd-h { margin: 16px 0 8px; font-size: 14px; padding-bottom: 6px; border-bottom: 1px solid var(--line); }
.sd-nodes { display: flex; flex-wrap: wrap; gap: 6px; }
.sd-foot { margin-top: 16px; display: flex; gap: 8px; justify-content: flex-end; }

/* 新增 / 粘贴 / 下计划：表单 */
.sform { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px 14px; }
.sform > label { display: flex; flex-direction: column; gap: 4px; }
.sform > label.wide { grid-column: 1 / -1; }
.sform > label > span { font-size: 12.5px; color: var(--muted); }
.sform input, .sform select, .sform textarea { padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; font: inherit; font-size: 14px; background: #fff; }
.sform-tip { grid-column: 1 / -1; font-size: 12.5px; color: var(--muted); background: #f7f9fc; border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; line-height: 1.7; }
.sform-foot { grid-column: 1 / -1; display: flex; gap: 8px; justify-content: flex-end; margin-top: 4px; }
.paste-box { grid-column: 1 / -1; min-height: 160px; font-family: ui-monospace, Consolas, monospace; font-size: 12.5px; }
.plan-head { font-size: 13px; color: var(--muted); margin-bottom: 8px; }
.plan-tbl { width: 100%; margin-bottom: 4px; }
.plan-tbl input, .plan-tbl select { width: 100%; box-sizing: border-box; padding: 6px 8px; border: 1px solid var(--line); border-radius: 7px; font: inherit; font-size: 13px; }
table.dtable td .zero { color: var(--muted); }
/* 接单页筛选栏：控件收窄一点，1080 宽也能排成一行 */
.flt-row .flt select { max-width: 130px; }
.flt-row .flt input[type=date] { min-width: 128px; }

/* ===== 接单台账：双页签 ===== */
.stab-row { display: flex; align-items: center; gap: 4px; margin: 2px 0 8px; border-bottom: 1px solid var(--line); }
.stab { background: none; border: 0; border-bottom: 2px solid transparent; padding: 7px 14px; font: inherit; font-size: 13.5px; color: var(--muted); cursor: pointer; }
.stab:hover { color: var(--primary); }
.stab.on { color: var(--primary); border-bottom-color: var(--primary); font-weight: 700; }
.stab i { font-style: normal; font-size: 11.5px; color: var(--muted); margin-left: 4px; background: var(--gray-bg); border-radius: 8px; padding: 0 6px; }
.stab.on i { background: var(--blue-bg); color: var(--blue); }

/* 流程节点：按钮登记 / 撤回 */
.nbtn { min-width: 30px; height: 24px; padding: 0 7px; border: 1px solid var(--line); border-radius: 7px;
  background: #fff; color: #b7c2ce; font: inherit; font-size: 12px; line-height: 22px; cursor: pointer; }
.nbtn:hover { border-color: var(--primary); color: var(--primary); background: #f2f8ff; }
.nbtn.on { border-color: #b7e0bf; background: var(--green-bg); color: var(--green); font-weight: 700; }
.nbtn.na { color: #9aa8b6; border-style: dashed; }

/* 详情里的节点盒子（可拖动换位置，博士 11-04）
   收紧内边距和按钮间距，是为了「五个节点 + 状态 + 三个按钮」在 1520 宽里排成一行 —— 原来一登记就换行 */
.nd-box { display: flex; align-items: center; gap: 6px; border: 1px solid var(--line); border-radius: 9px; padding: 5px 9px; background: #fff;
  cursor: grab; transition: box-shadow .12s, border-color .12s; }
.nd-box[data-nb]:hover { border-color: #bcd0e4; box-shadow: 0 1px 6px rgba(43,92,143,.12); }
.nd-box .btn { cursor: pointer; }
.nd-name { font-weight: 600; font-size: 13px; white-space: nowrap; }
.nd-box i { font-style: normal; font-size: 12px; white-space: nowrap; }
.nd-on { color: var(--green); } .nd-na { color: #9aa8b6; } .nd-off { color: var(--muted); }
.nd-btns { display: flex; gap: 3px; margin-left: auto; }
.nd-btns .btn { padding: 2px 6px; font-size: 12px; white-space: nowrap; }
.btn.na { border-color: #c9d3de; color: #6b7c8c; }
.sd-h { display: flex; align-items: center; gap: 8px; }
.sd-h-tip { font-weight: 400; font-size: 12px; color: var(--muted); }
.sd-h-act { margin-left: auto; display: flex; gap: 6px; }
.sd-h-act .btn { padding: 2px 9px; font-size: 12px; }

/* 操作记录时间线 */
.loglist { list-style: none; margin: 0; padding: 0; max-height: 260px; overflow: auto; border: 1px solid var(--line); border-radius: 9px; }
.loglist li { display: flex; align-items: center; gap: 10px; padding: 6px 10px; font-size: 12.5px; border-bottom: 1px solid #f0f3f7; }
.loglist li:last-child { border-bottom: 0; }
.lg-at { color: var(--muted); font-variant-numeric: tabular-nums; min-width: 92px; }
.lg-who { min-width: 66px; font-weight: 600; }
.lg-kind { font-size: 11.5px; padding: 0 7px; border-radius: 8px; background: var(--gray-bg); color: var(--gray); white-space: nowrap; }
.lg-kind.k-node { background: var(--blue-bg); color: var(--blue); }
.lg-kind.k-status { background: var(--yellow-bg); color: #a06a00; }
.lg-kind.k-item { background: #eef7ef; color: var(--green); }
.lg-kind.k-plan { background: #f3eefc; color: #6b48c8; }
.lg-txt { color: #35424f; }
td .mini { font-style: normal; font-size: 11px; color: var(--muted); margin-left: 3px; font-weight: 400; }
/* 详情里的明细/工单表：列多，允许横向滚动，别把右边一列挤到弹窗外面 */
.sd-tbl { overflow-x: auto; border: 1px solid var(--line); border-radius: 9px; }
.sd-tbl > table.dtable { border: 0; }
.sd-tbl > table.dtable th, .sd-tbl > table.dtable td { white-space: nowrap; }
.sd-tbl > table.dtable tfoot th { background: #f6f8fa; font-size: 12.5px; }
