:root{font-family:Inter,"Microsoft YaHei",sans-serif;color:#1f2937;background:#f7f8fa;font-size:15px}*{box-sizing:border-box}body{margin:0}.shell{min-height:100vh;display:grid;grid-template-columns:248px 1fr}aside{background:#f0f2f5;border-right:1px solid #e5e7eb;padding:34px 24px;display:flex;flex-direction:column}.brand{width:174px;height:auto;object-fit:contain;margin:0 auto 44px}.side-user{font-weight:700;padding:14px 12px;border-radius:8px;background:#e8edf5;margin-bottom:26px}.side-user small{display:block;color:#667085;font-weight:400;margin-top:5px;font-size:12px}.nav{display:block;width:100%;border:0;background:none;text-align:left;padding:14px 12px;border-radius:8px;color:#475467;font-size:15px;margin:4px 0;cursor:pointer}.nav.active{background:#dfe8f8;color:#0b57b7;font-weight:700}.logout{margin-top:auto;border:0;background:none;color:#667085;text-align:left;padding:12px;cursor:pointer}.content{padding:54px 7vw 80px;max-width:1500px;width:100%}header{display:flex;justify-content:space-between;align-items:flex-start}h1{font-size:38px;letter-spacing:0;margin:6px 0 10px;color:#111827}h2{font-size:20px;margin:0}.eyebrow{font-size:11px;letter-spacing:1.7px;color:#347ff0;font-weight:700;margin:0}.muted{color:#667085}.date{color:#98a2b3}.tabs{display:flex;gap:28px;border-bottom:1px solid #e4e7ec;margin-top:20px}.tabs button{border:0;background:none;padding:14px 2px;color:#667085;cursor:pointer;font-size:15px}.tabs .selected{color:#0b57b7;border-bottom:2px solid #347ff0;font-weight:700}.metrics{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin:28px 0}.metrics>div,.order,.toolbar{background:#fff;border:1px solid #edf0f4;border-radius:8px}.metrics>div{padding:22px 24px}.metrics span{display:block;color:#667085}.metrics strong{display:block;font-size:30px;margin-top:12px;color:#111827}.toolbar{display:flex;gap:12px;padding:14px;margin-bottom:26px}.toolbar input,.toolbar select{border:1px solid #e4e7ec;border-radius:6px;background:#fff;padding:10px 12px;color:#344054}.toolbar input{flex:1;min-width:180px}.section-head{display:flex;justify-content:space-between;align-items:center;margin:25px 0 12px}.section-head span{color:#98a2b3}.order{display:flex;justify-content:space-between;align-items:center;padding:20px 22px;margin:10px 0}.order-title{display:flex;align-items:center;gap:12px}.order h3{margin:0;font-size:16px}.meta{display:flex;gap:22px;color:#667085;font-size:13px;margin-top:13px}.status{font-size:12px;padding:5px 8px;border-radius:5px;white-space:nowrap}.status-machining{background:#e5f0ff;color:#1769c2}.status-pending_production_confirmation{background:#fff3d6;color:#a15c00}.status-completed,.status-archived{background:#e8f6ee;color:#16734a}.status-draft{background:#f2f4f7;color:#667085}.ghost,.primary{border:0;border-radius:6px;padding:10px 15px;cursor:pointer}.ghost{background:#eef4ff;color:#0b57b7}.primary{background:#347ff0;color:white;width:100%;font-size:15px}.toolbar .primary{width:auto;flex:0 0 auto;min-width:90px}.empty{background:#fff;border:1px dashed #d0d5dd;border-radius:8px;padding:48px;text-align:center;color:#98a2b3}.login{min-height:100vh;display:grid;place-items:center;background:#f7f8fa;padding:20px}.login-card{width:min(430px,100%);background:#fff;border:1px solid #edf0f4;border-radius:8px;padding:42px;box-shadow:0 18px 50px #1f29370d}.login-logo{display:block;width:220px;max-height:150px;object-fit:contain;margin:0 auto 24px}.login-card h1{font-size:30px}.login-card form{margin-top:28px}.login-card label{display:block;color:#344054;margin:16px 0}.login-card input{display:block;width:100%;padding:12px;border:1px solid #d0d5dd;border-radius:6px;margin-top:7px;font-size:15px}.error{color:#c43232;min-height:20px;font-size:13px}@media(max-width:800px){.shell{grid-template-columns:1fr}aside{padding:16px 18px;display:block}.brand{width:138px;margin:0 0 10px}.side-user{display:inline-block;margin:0 10px 0 0;padding:8px}.side-user small{display:none}.nav{display:inline-block;width:auto;padding:9px}.logout{float:right;margin:0;padding:10px}.content{padding:28px 18px 50px}h1{font-size:30px}.metrics{grid-template-columns:1fr}.metrics>div{padding:16px}.toolbar{flex-wrap:wrap}.toolbar input,.toolbar select{width:100%}.order{display:block}.order .ghost{margin-top:18px;width:100%}.meta{flex-wrap:wrap;gap:8px 16px}}
.login-version{margin:-16px auto 10px;text-align:center;font-size:12px;color:#94a3b8;letter-spacing:.5px}
.login-card h1{text-align:center;margin:0;font-size:28px;line-height:1.35}.part-responsible{display:inline-flex;align-items:center;margin-left:6px;padding:4px 9px;border-radius:6px;background:#1d2939;color:#fff;font-size:12px;font-weight:700;white-space:nowrap}.status-current-node{font-weight:800!important;background:#344054!important;color:#fff!important;border:1px solid #1d2939;box-shadow:0 1px 2px #10182833}.status-current-node.status-done{background:#16734a!important;border-color:#0e5a36!important;box-shadow:0 1px 2px #16734a33}.status-current-node.status-overdue{background:#d92d20!important;border-color:#b42318!important;box-shadow:0 1px 2px #d92d2033}
.dept-user-form label:has(input[name="password"]) { display: none; }
.dept-position-form select, .dept-user-form select[name="departmentId"] { width: 180px; min-width: 0; }
/* 工具栏按钮统一外观：未带 class 的按钮（如库存查询）与 .primary/.ghost 同高同圆角，不再使用浏览器默认样式 */
.toolbar button{border:0;border-radius:6px;padding:10px 15px;font-size:15px;cursor:pointer;flex:0 0 auto;white-space:nowrap;background:#eef4ff;color:#0b57b7}
.toolbar button:hover{background:#dfe8f8}
.toolbar button:disabled{opacity:.55;cursor:not-allowed}

/* ===== 自适应布局（2026-09-01）：表格横向滚动 + 多断点流式 + 侧边栏折叠 =====
   原则：只调留白/列数/内边距，字号基本不变；不做整体缩放（zoom/transform 会破坏 fixed 弹窗定位与点击命中） */
.table-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.table-scroll>table{min-width:600px}
@media(max-width:1600px){.content{padding:50px 5vw 76px}}
@media(max-width:1440px){.content{padding:46px 40px 70px}h1{font-size:34px}}
@media(max-width:1280px){.content{padding:40px 30px 62px}h1{font-size:31px}.metrics{grid-template-columns:repeat(2,1fr)}.metrics>div{padding:18px 20px}.metrics strong{font-size:26px}.dept-user-table th,.dept-user-table td{padding:10px 12px}.toolbar{gap:10px;padding:12px;flex-wrap:wrap}.section-head{margin:20px 0 10px}}
@media(max-width:1100px){.dept-user-form{grid-template-columns:repeat(2,1fr)}}
@media(max-width:1024px){.content{padding:34px 22px 56px}h1{font-size:28px}.metrics{grid-template-columns:1fr}.dept-user-form{grid-template-columns:1fr}.dept-user-table th,.dept-user-table td{padding:9px 10px}}
/* 侧边栏保持常驻展开（导航图标+文字始终显示，不折叠）；窄屏改为适度收窄侧栏宽度，保证正文可读 */
@media(max-width:1000px){.shell{grid-template-columns:204px 1fr}aside{padding:26px 16px}.brand{width:150px;margin-bottom:30px}.side-user{padding:12px 10px}.nav{padding:12px 10px;font-size:14px}.logout{padding:11px 10px;font-size:14px}}
@media(max-width:900px){.shell{grid-template-columns:180px 1fr}aside{padding:22px 12px}.brand{width:132px}.nav{padding:11px 8px;font-size:13px}.side-user strong{font-size:14px}}
.quote-pending-card{background:#fff7ed;border:1px solid #fed7aa;border-radius:8px;padding:14px 18px;margin:22px 0 6px}.quote-pending-head{font-weight:700;color:#9a3412;margin-bottom:10px}.quote-pending-item{display:block;width:100%;text-align:left;border:0;background:transparent;padding:8px 6px;border-radius:6px;color:#7c2d12;cursor:pointer;font-size:14px}.quote-pending-item:hover{background:#ffedd5}.stock-badge{display:inline-block;font-size:12px;padding:3px 8px;border-radius:5px;white-space:nowrap;font-weight:700;margin-right:4px}.stock-badge.stock-in{background:#e8f6ee;color:#16734a}.stock-badge.stock-out{background:#f2f4f7;color:#667085}.stock-customer{color:#475467;font-size:13px}.inv-tab{padding:8px 14px;border:1px solid #d0d5dd;border-radius:6px;background:#fff;cursor:pointer;font-size:13px;font-weight:600}.inv-tab.active{background:#16734a;border-color:#16734a;color:#fff}.inv-readonly{color:#98a2b3;font-size:13px}
/* 通用「列显示」按钮 + 下拉面板（2026-09-20，见 client/colset.js）：非标识列可按需隐藏，隐藏后剩余列自动向右铺开 */
.colset-wrap{position:relative;display:inline-block}
.colset-panel{position:absolute;top:calc(100% + 6px);left:0;z-index:40;min-width:238px;background:#fff;border:1px solid #e4e7ec;border-radius:8px;box-shadow:0 10px 24px rgba(16,24,40,.14);padding:10px 12px;display:grid;gap:6px;text-align:left}
.colset-head{font-size:12px;color:#98a2b3;line-height:1.5}
.colset-item{display:flex;align-items:center;justify-content:flex-start;gap:8px;padding-left:0;font-size:13px;color:#344054;cursor:pointer;white-space:nowrap;text-align:left}.colset-item input[type="checkbox"]{flex:0 0 auto;order:0;width:15px;height:15px;margin:0;padding:0}.colset-item.colset-fixed{color:#98a2b3;cursor:default}.colset-item.colset-fixed input[type="checkbox"]{cursor:default;opacity:.65}
.colset-foot{display:flex;gap:8px;border-top:1px solid #f2f4f7;padding-top:8px}
.colset-foot button{font:inherit;font-size:12px;padding:5px 10px;border:1px solid #d0d5dd;border-radius:6px;background:#fff;cursor:pointer}.inv-check-col{width:38px;text-align:center}.inv-check-col input{width:15px;height:15px;cursor:pointer;vertical-align:middle}.inv-low{background:#fef2f2}.inv-low-qty{color:#d92d20;font-weight:700}.inv-qty{white-space:nowrap}.inv-att-list{margin-top:4px;display:flex;flex-direction:column;gap:2px}.inv-att a{color:#175cd3;text-decoration:none;font-size:13px}.inv-att a:hover{text-decoration:underline}.inv-att-imgs{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px}.inv-att-img{display:inline-block;width:46px;height:46px;border:1px solid #e4e7ec;border-radius:6px;overflow:hidden;background:#f9fafb;box-shadow:0 1px 2px rgba(16,24,40,.06)}.inv-att-img img{width:100%;height:100%;object-fit:cover;display:block}.inv-att-img:hover{border-color:#98a2b3}.inv-code{color:#0b57b7;font-weight:700;white-space:nowrap}
/* 表格宽度随页面自适应（2026-09-13 用户口径："表格宽度根据页面宽度自动换行调整"）：
   `overflow-wrap:anywhere` 会把单元格的**最小内容宽度**降到"一个字"级别（`break-word` 不具备这个效果，
   所以必须用 `anywhere`）→ 无论多少列，表格都能整表落进卡片/页面宽度，**不再出现横向滚动条**，
   内容按列宽自动断行。列多的库存表（12–14 列）此前正是被"长串不可断"（料号、附件名、SN 列表）
   顶宽才需要横向拉的；`.dept-user-table` 本身已是 `width:100%`，加上这条即与售后管理列表行为一致。
   ⚠️ 写法注意：本仓库 `workflow.css` 在 `app.css` **之后**加载，同优先级会被覆盖（上版库存样式就是这样被吃掉的）
   → 凡与 `.dept-user-table` 基础规则同优先级的，一律用**两个类**（`.dept-user-table.inv-table`）提高优先级。 */
.dept-user-table th,.dept-user-table td{overflow-wrap:anywhere}
/* 库存表：料号/附件名等长串允许断行；操作列按钮改为两行内换行（列窄时不再竖着叠 5 行、把行撑高） */
.dept-user-table.inv-table .inv-code{white-space:normal}
.dept-user-table.inv-table .inv-ops{display:flex;flex-wrap:wrap;gap:4px}
.dept-user-table.inv-table .inv-op{padding:4px 8px;font-size:12px;line-height:1.4}.inv-bom-list{display:flex;flex-wrap:wrap;gap:4px}.inv-bom-item{display:inline-block;font-size:12px;padding:2px 8px;border-radius:4px;background:#eef4ff;color:#175cd3;white-space:nowrap}.mz-dialog-inv{width:min(660px,100%)}.inv-bom-block{grid-column:1/-1}.inv-bom-block label small{display:block;color:#98a2b3;font-weight:400;font-size:12px;margin-top:3px}.inv-bom-rows{display:flex;flex-direction:column;gap:8px}.inv-bom-row{display:grid;grid-template-columns:1fr 110px auto;gap:8px;align-items:center}.inv-bom-row select{width:100%;padding:9px 10px;border:1px solid #e4e7ec;border-radius:6px}.inv-bom-row input{padding:9px 10px;border:1px solid #e4e7ec;border-radius:6px}.inv-bom-block>button{margin-top:10px}.inv-att-row{margin-bottom:4px}.inv-ops{display:flex;flex-wrap:wrap;gap:6px;align-items:center}.inv-op{font:inherit;font-size:12px;line-height:1;padding:7px 10px;border-radius:6px;border:1px solid;background:#fff;cursor:pointer;white-space:nowrap}.inv-op-in{color:#16734a;border-color:#a9dcc0}.inv-op-in:hover{background:#e8f6ee}.inv-op-out{color:#b54708;border-color:#f2c48d}.inv-op-out:hover{background:#fff4e5}.inv-op-edit{color:#175cd3;border-color:#a9c6f2}.inv-op-edit:hover{background:#eef4ff}.inv-op-del{color:#d92d20;border-color:#f0b3ae}.inv-op-del:hover{background:#fef2f2}.inv-op-upload{color:#475467;border-color:#d0d5dd}.inv-op-upload:hover{background:#f2f4f7}@media(max-width:800px){.inv-op{min-height:38px;padding:9px 12px}}.inv-photo-cell{width:84px;text-align:center;vertical-align:middle}.inv-photo{width:60px;height:60px;object-fit:cover;border:1px solid #e4e7ec;border-radius:6px;background:#f9fafb;box-shadow:0 1px 2px rgba(16,24,40,.06);cursor:pointer}.inv-photo:hover{border-color:#98a2b3}.inv-photo-block{grid-column:1/-1;margin-top:8px;padding-top:8px;border-top:1px dashed #eef0f4}.inv-photo-row{display:flex;align-items:center;gap:10px;margin-bottom:6px}.inv-photo-lg{width:160px;height:160px;object-fit:cover;border:1px solid #e4e7ec;border-radius:8px;background:#f9fafb}.inv-photo-none{color:#98a2b3;font-size:13px;margin:0}.inv-photo-preview{display:flex;align-items:center;gap:10px}.inv-att-block{grid-column:1/-1;margin-top:8px;padding-top:8px;border-top:1px dashed #eef0f4}.inv-att-items{display:flex;flex-direction:column;gap:6px;margin-bottom:6px}.inv-att-item{display:flex;gap:10px;align-items:flex-start}.inv-att-thumb{width:46px;height:46px;flex:0 0 auto}.inv-att-thumb .inv-att-img{width:46px;height:46px}.inv-att-meta{display:flex;flex-direction:column;gap:4px}.inv-att-meta a{color:#175cd3;text-decoration:none;font-size:13px;word-break:break-all}.inv-att-meta a:hover{text-decoration:underline}.inv-trace{grid-column:1/-1;margin-top:8px;padding:10px 12px;border:1px solid #e4e7ec;border-radius:8px;background:#fcfcfd}.inv-trace label small{display:block;color:#98a2b3;font-weight:400;font-size:12px;margin-top:3px}.inv-trace-rows{display:flex;flex-direction:column;gap:6px}.inv-trace-row{display:flex;align-items:center;gap:8px;font-size:13px}.inv-trace-k{color:#667085;flex:0 0 68px}.inv-trace-v{color:#101828;font-weight:600;word-break:break-all}.inv-trace-row .link-button{margin-left:auto}
/* 品类管理弹窗（2026-09-21）：桌面端也禁表头折行 —— mobile.css 的同款 `.dept-user-table.inv-table thead th{white-space:nowrap}`
   只在 ≤1180px 生效，>1180px 桌面端原本没有任何 nowrap/min-width 兜底；两类的写法（0,2,1）优先级高于 `.dept-user-table th`(0,1,1)，不受文件加载顺序影响。 */
.mz-dialog-cat .dept-user-table thead th{white-space:nowrap}
/* 品类管理弹窗（2026-09-21 第四次修复，用户确认方案 A）：列宽改为固定比例 + 弹窗收窄。
   旧状（实测 1440×900，弹窗 780 → 内容区 730）：品类 150 / 所属部门 138 / 管理方式 119 / 检查报告时限 157 / 操作 164，
   品类列只有 2 字内容却占 150px = 用户报的"品类的列宽太长了"。
   根因：5 列自动表布局共分 730px，富余宽度按各列 max-content 比例回流 → **只改宽度比例没用**
   （实测改成 20/21/16/20/23% 后品类列仅 150→146），必须同时把弹窗收窄，宽度才有地方让出去。
   ⚠️ 定宽必须配 `table-layout:fixed` + `th` 百分比（合计 100%）：auto 布局会把富余宽度再分回给"没写宽度"的列。
   ⚠️ 选择器写「两类」`.mz-dialog-cat .dept-user-table`（0,2,1）才压得过 `.dept-user-table th`（0,1,1）。
   实测（弹窗 660 → 内容区 610）：品类 122 / 所属部门 128 / 管理方式 97 / 检查报告时限 122 / 操作 140，
   余量仍够：表头"检查报告时限"6 字 + 内边距 ≈ 104px、操作列两按钮 88px + 内边距 ≈ 108px。
   成品/设备工具页签无"检查报告时限"列，4 列合计 81% → 富余 19% 按比例回分，观感一致。 */
.mz-dialog-cat .dept-user-table{table-layout:fixed}
.mz-dialog-cat .dept-user-table th.cat-name{width:20%}
.mz-dialog-cat .dept-user-table th.cat-dept{width:21%}
.mz-dialog-cat .dept-user-table th.cat-mode{width:16%}
.mz-dialog-cat .dept-user-table th.cat-due{width:20%}
.mz-dialog-cat .dept-user-table th.cat-ops{width:23%}
/* 品类管理弹窗（2026-09-21 第五次修复，用户："能不拉动可以全部展示"）：取消本弹窗的最小宽度兜底。
   现象（实测 1100×800）：`.dept-user-table.inv-table` 的最小宽度兜底（mobile.css ≤1180 断点 900px、≤800 断点 920px；
   ≥1181px 无兜底）把这张表顶到 900px，而弹窗内容区只有 610px → `.table-scroll` 出现横滚（scrollWidth 900 / clientWidth 610），
   必须左右拉动才看得全 5 列，品类列也被重新撑到 180px —— 就是"要拉动才全部展示"的真因。
   本弹窗宽度固定 `min(660px,94vw)` → 视口 ≥703px（94vw ≥ 660）时内容区恒为 610px，5 列按上面 20/21/16/20/23% 正好铺满
   （实测 122/128/97/122/140，表头单行、行高 52 不变），故 ≥703px 直接把最小宽度归零，表格永远等于容器宽度、不再横滚。
   选择器 (0,4,1) 压过 mobile.css 的 `.dept-user-table.inv-table`(0,2,0)、`.dept-user-table.cols-*`(0,2,0)
   与 app.css 的 `.table-scroll>table`(0,1,1)，不受文件加载顺序影响。
   ⚠️ 手机端（<703px，弹窗随 94vw 收窄）**保留**原横滚兜底：那时 5 列只剩 70px 上下，
   归零会被压成"一列一个字"，且 nowrap 表头会互相重叠。 */
@media(min-width:703px){
  .mz-dialog-cat .table-scroll>table.dept-user-table.inv-table{min-width:0}
}
/* 品类管理弹窗（2026-09-21 第三次修复）：桌面端也「头/尾固定 + 内容区独立滚动」。
   旧状：`.mz-dialog`（cost.css，0,1,0）只有 `max-height:88vh;overflow:auto` → 92 条品类时
   整块弹窗（连 footer）一起滚（实测 scrollHeight 5010 / clientHeight 790），
   底部「＋ 新增品类 / 关闭」要一路滚到底才看得见 = 用户报的"显示不全"。
   移动端 ≤800px 早已是 flex 列 + `.mz-fields` 内滚（mobile.css），这次把桌面端补齐。
   ⚠️ 必须写「两类」`.mz-dialog.mz-dialog-cat`（0,2,0）：cost.css 在 app.css 之后加载，
   单类 `.mz-dialog-cat`(0,1,0) 会被 `.mz-dialog` 同优先级覆盖（与上面 nowrap 同一条经验）。 */
.mz-dialog.mz-dialog-cat{display:flex;flex-direction:column;overflow:hidden}
.mz-dialog-cat > header,.mz-dialog-cat > footer{flex:0 0 auto}
.mz-dialog-cat > .mz-fields{flex:1;min-height:0;overflow-y:auto}
/* 表头吸顶：长列表滚到中段时仍知道对应哪一列。背景色须显式写（否则透出正文）；
   表格是 border-collapse:collapse，单元格边框在合并边框模型下不跟着 sticky 走 →
   底边改用 inset 阴影绘制，避免滚动时表头与首行之间丢分隔线。 */
.mz-dialog-cat .dept-user-table thead th{position:sticky;top:0;z-index:2;background:#f7f8fa;box-shadow:inset 0 -1px 0 #e4e7ec}
/* 吸顶生效的前提：`.table-scroll` 不能自成滚动容器 —— `overflow-x:auto` 会让 overflow-y 一并算成 auto，
   于是 sticky 会"粘"在中间层（它本身不纵向滚动）而失效。桌面端（>1180px）弹窗内容区宽约 732px ≥
   表格兜底 min-width 600px，本就不需要横向滚动，放开 overflow 无副作用；窄屏保留横滚，吸顶退化为普通表头。 */
@media(min-width:1181px){.mz-dialog-cat .table-scroll{overflow:visible}}
/* 成品库「按型号汇总」视图（2026-09-19 用户确认）：汇总行 + 展开的台次子行（子行缩进靠浅底色区分） */
.dept-user-table.inv-table .inv-group-row>td{background:#f7f9fc}
.dept-user-table.inv-table .inv-group-open>td{background:#eef4ff}
.dept-user-table.inv-table .inv-subrow>td{background:#fbfcfe}
.dept-user-table.inv-table .inv-subrow .inv-sub-spec{color:#667085;font-size:12px}
.dept-user-table.inv-table .inv-subrow-hint>td{color:#98a2b3;font-size:12px;text-align:center}
.dept-user-table.inv-table .inv-group-sn{color:#175cd3}
/* 库存数量列排序按钮（2026-09-08） */
.inv-sort-th{white-space:nowrap}.inv-sort-btn{border:0;background:transparent;padding:0;font:inherit;font-weight:700;color:inherit;cursor:pointer}.inv-sort-btn:hover{color:#16734a;text-decoration:underline}

/* ===== 公共 UI 组件（2026-09-08 方案B）：全站按钮/标签/卡片统一来源 =====
   token：主蓝 #347ff0 / 深蓝 #0b57b7 / 成功 #16734a / 危险 #d92d20 / 警示 #b54708 / 圆角 6px
   使用：主操作 mz-btn mz-btn--primary；次要 mz-btn（默认描边蓝）；中性 mz-btn--plain；
        成功 mz-btn--success；危险 mz-btn--danger；小尺寸追加 mz-btn--sm */
.mz-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;border:1px solid #a9c6f2;background:#fff;color:#175cd3;border-radius:6px;padding:7px 14px;font-family:inherit;font-size:13px;font-weight:600;line-height:1.5;cursor:pointer;white-space:nowrap;text-decoration:none;transition:background .15s,border-color .15s}
.mz-btn:hover{background:#eef4ff}
.mz-btn:disabled{opacity:.55;cursor:not-allowed}
.mz-btn--sm{padding:5px 12px;font-size:12px}
.mz-btn--primary{background:#347ff0;border-color:#347ff0;color:#fff}
.mz-btn--primary:hover{background:#2b6fe0;border-color:#2b6fe0}
.mz-btn--success{background:#16734a;border-color:#16734a;color:#fff}
.mz-btn--success:hover{background:#0e5a36;border-color:#0e5a36}
.mz-btn--danger{border-color:#f0b3ae;color:#d92d20}
.mz-btn--danger:hover{background:#fef2f2}
.mz-btn--danger.mz-btn--primary,.mz-btn--solid-danger{background:#d92d20;border-color:#d92d20;color:#fff}
.mz-btn--danger.mz-btn--primary:hover,.mz-btn--solid-danger:hover{background:#b42318;border-color:#b42318}
.mz-btn--plain{border-color:#d0d5dd;color:#475467}
.mz-btn--plain:hover{background:#f2f4f7}
/* 兼容别名：旧模块类名与公共按钮同规格，避免遗漏处样式失效 */
.proc-op,.att-btn,.att-download-all{display:inline-flex;align-items:center;justify-content:center;gap:6px;border:1px solid #a9c6f2;background:#fff;color:#175cd3;border-radius:6px;padding:5px 12px;font-family:inherit;font-size:12px;font-weight:600;line-height:1.5;cursor:pointer;white-space:nowrap;text-decoration:none;transition:background .15s}
.proc-op:hover,.att-btn:hover,.att-download-all:hover{background:#eef4ff}
.proc-op-danger,.att-btn.danger{color:#d92d20;border-color:#f0b3ae}
.proc-op-danger:hover,.att-btn.danger:hover{background:#fef2f2}
/* 状态标签 */
.mz-tag{display:inline-block;font-size:12px;font-weight:700;padding:3px 9px;border-radius:5px;white-space:nowrap;line-height:1.5}
.mz-tag--info{background:#e5f0ff;color:#1769c2}
.mz-tag--warn{background:#fff3d6;color:#a15c00}
.mz-tag--success{background:#e8f6ee;color:#16734a}
.mz-tag--danger{background:#fef2f2;color:#b42318}
.mz-tag--muted{background:#f2f4f7;color:#667085}
/* 卡片（与订单详情 detail-section 同款观感） */
.mz-card{background:#fff;border:1px solid #edf0f4;border-radius:8px;padding:18px 20px;margin:0 0 18px}
.mz-card__head{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:12px}
.mz-card__head h3,.mz-card__head h4{margin:0;font-size:15px;color:#111827}
.mz-card__body{margin:0}

/* ==== 档案列表与详情（2026-09-12 阶段 2：产品档案 + 设备档案合并）==== */
/* 类型标识：一条记录可能有产品（终检归档）与设备（建档/调试）两种身份 */
.archive-type-chip{display:inline-block;margin-right:4px;padding:1px 8px;border-radius:9px;font-size:12px;line-height:18px;white-space:nowrap}
.archive-type-chip.product{color:#0f55a4;background:#e8f1fb;border:1px solid #c9dff5}
.archive-type-chip.device{color:#6d28d9;background:#f3ecfe;border:1px solid #ddd0fb}
.archive-state{font-size:12px;color:#344054}
/* 档案列表操作列（2026-09-19 用户反馈"文字竖着一列一列排"）：原先「查看 / 新增维修 / 库存 MZ-…」三个
   .link-button（machining-list.css 里 white-space:nowrap）在窄桌面并排约占 340px，把 SN、型号、部门、
   维修次数等列压到每列约 25px，单元格被 overflow-wrap:anywhere 逐字断行 → 纵向排成一列（实测行高 177px，
   正常 82px）。改为可折行的 flex 组（做法同库存表 .inv-ops，app.css 第 34 行）后，操作列最小宽度降到
   约 90px，其余列恢复可读宽度；按钮之间用 gap 代替空格，换行后不留断行空白。
   注意：workflow.css 在 app.css 之后加载，同优先级会被覆盖 → 用两个类（.dept-user-table .archive-ops）提高优先级。 */
.dept-user-table .archive-ops{display:inline-flex;flex-wrap:wrap;gap:4px;align-items:center;vertical-align:middle}
/* 详情弹窗：按身份分区展示（产品档案区 / 设备档案区） */
.mz-fields .archive-identity{border-top:1px dashed #e4e7ec;padding-top:10px;margin-top:2px}
.mz-fields .archive-identity:first-child{border-top:0;padding-top:0}
.mz-fields .archive-identity h4{margin:0 0 8px;font-size:14px;color:#1f3b5c}
/* 标题块（含标题下的「新建订单/报价/项目/档案」按钮）与下方首个区块的间距（2026-09-12 用户要求，对齐订单管理）：
   订单管理页标题下第一个区块是 .tabs（自带 margin-top:20px），而报价/项目/产品档案页标题下直接就是筛选栏/卡片
   （上边距 0）→ 那三页看起来像"卡片贴着按钮"。这里统一给标题后的第一个区块 20px，四页观感一致。 */
main.content > header + *{margin-top:20px}
/* 档案查询卡（2026-09-21 五次重排，用户需求）：取消「终检归档专用」小标题与它独占的第二行——
   全部筛选项与操作同处**一个流式行**：
   建档来源｜全部部门｜全部型号｜关键字｜时间范围（＋「自定义」时的起止日期）｜生产人员｜调试工程师｜查询｜导出 Excel
   布局口径：控件一律 `flex:1 1 <basis>` 且**不再设 max-width**，剩余宽度由 flex 分配到各控件 →
   宽屏一行排满；窄屏自动折行后**每行都被撑满**，不会出现"一行只放两个框、右边空一大片"。
   min-width 兜底给出折行阈值：容器 ≈1110px（视口 ≈1440px）一行、≈950px（视口 ≈1280px）两行。
   （第四次调整的教训：靠 `max-width` 压窄控件只是把第一行的需求从 826px 压到 707px，
   控件不够伸缩 → 一旦放不下就左对齐留白、看着零散；这里改成可伸缩分配。） */
.archive-toolbar{flex-direction:column;align-items:stretch;gap:10px;padding:14px 10px}
.archive-toolbar .af-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;justify-content:flex-start}
/* 筛选项：统一等高 40px、内边距 10px；能伸能缩（basis 128px / 最小 112px / 最大 170px）
   → 一行装不下时自然折行，且行内剩余宽度会被吸收，不出现"控件挤在左边、右边空一片" */
.archive-toolbar .af-filters > select,.archive-toolbar .af-filters > input{flex:1 1 128px;min-width:112px;max-width:170px;height:40px;padding:0 10px}
.archive-toolbar .af-filters select[data-archive-type]{flex:1 1 106px;min-width:96px;max-width:118px}
.archive-toolbar .af-filters .archive-range{flex:1 1 94px;min-width:84px;max-width:104px}
.archive-toolbar .af-filters .archive-keyword{flex:2 1 150px;min-width:120px;max-width:240px;width:auto}
.archive-toolbar .af-custom-range{flex:0 0 auto}
.archive-toolbar .af-custom-range input{flex:0 0 auto;min-width:0;width:132px}
.archive-toolbar .primary{width:auto;flex:0 0 auto;min-width:90px}
/* 「查询 / 导出 Excel」顶到**行尾**：与筛选项同行时停在该行右端，放不下折到下一行时也在右端
   —— 避免"两个按钮缩在下一行左边、右边空一片"的零散观感。
   注意只给**第一个**按钮 `margin-left:auto`：两个都加会各分走一份剩余空间、二者之间裂开一大块。 */
.archive-toolbar .af-filters > .primary,.archive-toolbar .af-filters > .archive-export{height:40px;padding:0 14px;width:auto;min-width:0;flex:0 0 auto}
.archive-toolbar .af-filters > .primary{margin-left:auto}
/* 条数摘要：**全页只此一处**，挂在档案表格顶部（列表卡标题行右端 → margin-left:auto 顶到最右） */
.archive-row-summary{margin-left:auto;font-size:13px;color:#667085;white-space:nowrap}
@media(max-width:760px){.archive-toolbar .af-filters .archive-keyword{flex:1 1 100%;max-width:none}}
/* 导出 Excel（2026-09-20）：「次要操作」观感＝白底描边；主色留给「查询」 */
.archive-export{border:1px solid #e4e7ec;background:#fff;color:#475467;border-radius:8px;padding:9px 16px;font-size:13px;cursor:pointer;white-space:nowrap}
.archive-export:hover{border-color:#bcd0f7;color:#1d63ed}
.archive-export:disabled{opacity:.6;cursor:default}
/* 时间范围：今天 / 近3月 / 近6月 / 1年 / 自定义
   2026-09-21 用户需求——由分段按钮（.archive-range 内的 button 组）改为**普通下拉框**，
   按钮组样式随之删除；下拉宽度见上方 `.archive-toolbar .af-filters .archive-range`（110px）。 */
/* 2026-09-18：原材料入库「检查报告时限」（用户方案 A：时限挂品类 24/48/72 小时、超期只提醒不挡）→ 入库批次里的报告状态行：待补(橙)/已超期(红)/已上传(绿)，未上传时就地补传 */
.inv-report-line{margin-top:4px;font-size:13px;color:#475467}.inv-report-line .inv-report-wait{color:#b54708;font-weight:600}.inv-report-line .inv-report-over{color:#b42318;font-weight:700}.inv-report-line .inv-report-ok{color:#16734a;font-weight:600}.inv-report-line .inv-op{margin-left:6px}
/* 档案详情弹窗（2026-09-18 用户反馈"电脑端也要滑动看了"）：
   ① 弹窗加宽：原 480px 装不下"文件名 + 大小 + 时间 + 上传人 + 操作"一整行（长文件名无断点会顶破弹窗）；
   ② 附件行允许换行：名称独占第一行，元信息与操作折到第二行，长文件名任意位置断行。
   桌面端 ≥801px 生效；手机端仍走 mobile.css 的全宽弹窗 + 横向滚动兜底。
   （用 .attachment-list.archive-attachment-list 提高特异性，避免被 quote-flow.css 的 .attachment-list li 覆盖） */
@media(min-width:801px){.mz-dialog:has(.archive-attachment-list){width:min(680px,92vw)}}
.attachment-list.archive-attachment-list li{flex-wrap:wrap;align-items:flex-start}
.attachment-list.archive-attachment-list li>span{min-width:0;overflow-wrap:anywhere;word-break:break-all}
.attachment-list.archive-attachment-list li>span:first-child{flex:1 1 100%}
.attachment-list.archive-attachment-list li>span:not(:first-child):not(:last-child){color:#667085;font-size:12px}
.attachment-list.archive-attachment-list li>span:last-child{margin-left:auto;display:inline-flex;gap:10px;align-items:center;flex-shrink:0}
