:root {
  /* 明确声明浅色主题：否则浏览器按系统深色渲染 datalist / 自动填充下拉，
     在浅色页面上会突然弹出一个黑色大框盖住表单。 */
  color-scheme: light;
  /* 品牌色 · 取自 CVGBIO logo（2026-09 精确取色） */
  --brand-navy: #17294F;   /* logo 文字深藏青 */
  --brand-blue: #084081;   /* logo 下弧品牌蓝 */
  --brand-teal: #11AF7D;   /* logo 上弧青绿 */
  --bg: #f4f6f9;
  --panel: #ffffff;
  --border: #e2e8f0;
  --text: #1f2937;
  --muted: #64748b;
  --primary: var(--brand-blue);
  --primary-hover: #0A55A8;
  --accent: var(--brand-teal);
  --danger: #dc2626;
  --warn-bg: #fffbeb;
  --warn-border: #f59e0b;
  --ok: var(--brand-teal);
  --sidebar-bg: var(--brand-navy);
  --sidebar-text: #c7d2e4;
  --shadow: 0 1px 3px rgba(23,41,79,.08);
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei", "PingFang SC", sans-serif;
  background: var(--bg); color: var(--text); font-size: 14px;
}
.hidden { display: none !important; }

/* 按钮 */
.btn { display: inline-flex; align-items: center; justify-content: center; padding: 9px 16px;
  border-radius: 8px; border: 1px solid transparent; font-size: 14px; cursor: pointer;
  transition: all .15s; white-space: nowrap; background: #eef0f3; color: var(--text); }
.btn:hover { filter: brightness(.97); }
.btn-primary { background: var(--primary); color: #fff; }
.btn-primary:hover { background: var(--primary-hover); }
.btn-outline { background: #fff; border-color: var(--border); }
.btn-outline:hover { border-color: var(--primary); color: var(--primary); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-ghost { background: transparent; color: var(--sidebar-text); border-color: rgba(255,255,255,.2); }
.btn-ghost:hover { background: rgba(255,255,255,.08); }
.btn-block { width: 100%; }
.btn-sm { padding: 5px 10px; font-size: 13px; border-radius: 6px; }
.btn:disabled, .btn[disabled] { opacity: .4; cursor: not-allowed; filter: none; }
.btn[disabled]:hover { border-color: var(--border); color: var(--text); }
/* 类别管理：「返回全部」按钮（当前正在看的就是这个大类）点亮 */
.btn-outline.active { background: var(--primary); border-color: var(--primary); color: #fff; }
.btn-outline.active:hover { background: var(--primary-hover); color: #fff; }
/* 类别管理：被选中查看的大类整行淡蓝底，一眼知道右侧中类表看的是谁 */
tr.row-sel > td { background: rgba(8,64,129,.06); }

/* 登录 */
.login-screen { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(1100px 500px at 85% -10%, rgba(17,175,125,.28), transparent 60%),
    radial-gradient(900px 480px at -10% 110%, rgba(10,85,168,.45), transparent 55%),
    linear-gradient(135deg, #0E1D3D 0%, #17294F 45%, #084081 100%); }
.login-card { background: #fff; border-radius: 14px; padding: 36px 36px 30px; width: 380px;
  box-shadow: 0 20px 60px rgba(0,0,0,.35); }
.login-brand-img { display: block; margin: 0 auto 14px; height: 84px; }
.login-logo { font-size: 21px; font-weight: 700; text-align: center; color: var(--brand-navy); }
.login-sub { text-align: center; color: var(--muted); margin: 6px 0 28px; font-size: 13px; }
.login-card label { display: block; font-size: 13px; color: var(--muted); margin: 14px 0 6px; }
.login-card input { width: 100%; padding: 11px 12px; border: 1px solid var(--border);
  border-radius: 8px; font-size: 14px; outline: none; }
.login-card input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(8,64,129,.14); }
.login-card .btn { margin-top: 22px; }
.login-error { color: var(--danger); font-size: 13px; min-height: 18px; margin-top: 10px; }
.login-hint { text-align: center; color: var(--muted); font-size: 12px; margin-top: 18px; }

/* 布局 */
.app { display: flex; height: 100vh; }
.sidebar { width: 220px; background: var(--sidebar-bg); color: var(--sidebar-text);
  display: flex; flex-direction: column; flex-shrink: 0; }
.brand { padding: 18px 16px 16px; border-bottom: 1px solid rgba(255,255,255,.08); }
.brand-logo { display: block; height: 46px; margin-bottom: 10px; }
.brand-title { font-size: 19px; font-weight: 700; color: #fff; }
.brand-sub { font-size: 12px; margin-top: 2px; }
.nav { flex: 1; padding: 12px 10px; }
.nav-item { display: flex; align-items: center; gap: 10px; padding: 11px 12px; border-radius: 8px;
  color: var(--sidebar-text); text-decoration: none; font-size: 14px; margin-bottom: 4px; transition: all .15s; }
.nav-item:hover { background: rgba(255,255,255,.08); color: #fff; }
.nav-item.active { background: var(--brand-teal); color: #fff; box-shadow: 0 2px 8px rgba(17,175,125,.35); }
.nav-ico { width: 20px; text-align: center; font-size: 15px; }
.sidebar-footer { padding: 14px; border-top: 1px solid rgba(255,255,255,.08); }
.user-chip { margin-bottom: 10px; }
.user-name { color: #fff; font-size: 14px; font-weight: 600; }
.user-role { font-size: 12px; margin-top: 2px; }

.main { flex: 1; overflow-y: auto; padding: 28px 32px; }
.view { display: none; }
.view.active { display: block; }
.page-head { margin-bottom: 20px; }
.page-head h1 { font-size: 22px; font-weight: 700; }
.page-head p { color: var(--muted); margin-top: 4px; }

/* 卡片 */
.card { background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
  padding: 20px; box-shadow: var(--shadow); margin-bottom: 18px; }
.card-title { font-size: 15px; font-weight: 600; margin-bottom: 16px; }
.card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.card-head .card-title { margin-bottom: 0; }
/* 两栏：大类窄、中类宽（中类表列多，需要空间）。必须写 minmax(0, xfr) ——
   纯 Nfr 的 grid 项 min-width 是 auto，会被表格里的 white-space:nowrap 单元格撑开
   （中类表列一变多就把大类那栏挤窄、切视图宽度乱跳）。
   锁 0 之后，表格内容超出就在卡片内部横向滚动，两栏比例永远固定。
   2fr : 3fr（≈ 40% : 60%），切「查看中类 / 返回全部」宽度不变。 */
.grid-2 { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 18px; }
.grid-2 > * { min-width: 0; }
/* 类别管理两张表：每行必须单行显示 —— 操作列那 4 个按钮（属性/编辑属性/改名/删除）
   一旦换行，行高就变成两倍，整张表看着就花了；所以这里禁掉换行。 */
.grid-2 .op-cell { flex-wrap: nowrap; }
/* 单元格收紧一点，给「操作」列腾地方，尽量不出现卡片内横向滚动条 */
.grid-2 .table th, .grid-2 .table td { padding: 9px 10px; }

/* 类别选择行 */
.pick-row { display: grid; grid-template-columns: 1fr 1fr 1.3fr; gap: 16px; align-items: end; }
.pick-item label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 6px; }
.pick-item select { width: 100%; padding: 9px 11px; border: 1px solid var(--border);
  border-radius: 8px; font-size: 14px; background: #fff; outline: none; }
.pick-item select:focus { border-color: var(--primary); }
.code-box label { visibility: hidden; }
.code-value { font-size: 22px; font-weight: 700; color: var(--primary); text-align: center;
  font-family: "SF Mono", Consolas, monospace; letter-spacing: 1px; padding: 7px 10px;
  background: #EDF4FB; border: 1px dashed var(--primary); border-radius: 8px; }
.mid-note { color: var(--muted); font-size: 13px; margin-top: 12px; min-height: 18px; }
.mid-note b { color: var(--text); }

/* 表单 */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }
.form-row { margin-bottom: 14px; }
.form-row.wide { grid-column: 1 / -1; }
.form-row label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 6px; }
.form-row label em { color: var(--danger); font-style: normal; }
.tip-inline { color: #9ca3af; font-size: 12px; }
.form-row input, .form-row select, .form-row textarea { width: 100%; padding: 9px 11px;
  border: 1px solid var(--border); border-radius: 8px; font-size: 14px; outline: none;
  background: #fff; font-family: inherit; }
.form-row input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(8,64,129,.12); }
.form-row input.invalid { border-color: var(--danger); }
/* 「与字典示例写法不同」是提示不是错误：琥珀色，不拦提交（2026-09-14 自由录入） */
.form-row input.warn { border-color: var(--warn-border); }
.attr-hint { font-size: 12px; color: #9ca3af; margin-top: 5px; line-height: 1.5; }
.attr-hint b { color: #6b7280; font-weight: 600; }
.attr-err { font-size: 12px; color: var(--danger); margin-top: 4px; display: none; }
.attr-err.attr-warn-text { color: #b45309; }
/* 字段级小字说明（如「物料名称自动生成」）与勾选行（无厂商型号豁免） */
.label-hint { font-size: 12px; color: #9ca3af; font-weight: 400; margin-left: 6px; }
.chk-line { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text);
  cursor: pointer; line-height: 1.6; }
.chk-line input[type="checkbox"] { width: auto; margin: 0; flex: 0 0 auto; }
/* 类别管理里「厂商型号 必填/选填」的只读徽标（无权限者看到的样子） */
.badge-src { font-size: 12px; color: var(--muted); }

.attr-head { display: flex; align-items: center; justify-content: space-between;
  margin: 22px 0 14px; padding-top: 18px; border-top: 1px dashed var(--border); flex-wrap: wrap; gap: 10px; }
.attr-head-title { font-size: 14px; font-weight: 600; }
.legend { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.legend-note { font-size: 12px; color: #9ca3af; }
.lv { font-size: 11px; padding: 2px 7px; border-radius: 4px; border: 1px solid; }
.lv-key { color: #b91c1c; background: #fef2f2; border-color: #fecaca; }
.lv-cond { color: #b45309; background: #fffbeb; border-color: #fde68a; }
.lv-minor { color: #084081; background: #EAF1F9; border-color: #C5D9EF; }
.lv-ref { color: #4b5563; background: #f3f4f6; border-color: #e5e7eb; }
.req-star { color: var(--danger); }
.req-cond { color: #b45309; font-size: 12px; }
.fp-badge { font-size: 11px; color: #b91c1c; background: #fef2f2;
  border: 1px solid #fecaca; border-radius: 4px; padding: 2px 6px; }

/* 查重结果 */
.dup-group { border-radius: 10px; padding: 14px 16px; margin-bottom: 12px; border: 1px solid; }
.dup-group:last-child { margin-bottom: 0; }
.dup-block { background: #fef2f2; border-color: #fca5a5; }
.dup-strong { background: var(--warn-bg); border-color: var(--warn-border); }
.dup-weak { background: #f9fafb; border-color: var(--border); }
.dup-group-title { font-weight: 700; margin-bottom: 6px; }
.dup-block .dup-group-title { color: #991b1b; }
.dup-strong .dup-group-title { color: #92400e; }
.dup-weak .dup-group-title { color: #4b5563; }
.dup-group-text { font-size: 13px; color: #6b7280; margin-bottom: 10px; line-height: 1.6; }
/* 保存前的「确认改动」清单（类别管理里每次保存都会先弹这个） */
.chg-list { border: 1px solid var(--border); border-radius: 8px; overflow: hidden; margin-bottom: 12px; }
.chg-row { display: flex; align-items: flex-start; gap: 8px; padding: 8px 12px; font-size: 13px;
  line-height: 1.7; border-bottom: 1px solid #f3f4f6; background: #fff; }
.chg-row:last-child { border-bottom: none; }
.chg-row:nth-child(even) { background: #fafbfc; }
.chg-tag { flex: 0 0 auto; font-size: 11px; border-radius: 4px; padding: 2px 7px; margin-top: 2px;
  border: 1px solid transparent; white-space: nowrap; }
.chg-add { background: #DFF5EC; color: #0B7A57; border-color: #9ADDC4; }
.chg-mod { background: #D9E7F5; color: #084081; border-color: #9DBFDF; }
.chg-del { background: #fee2e2; color: #b91c1c; border-color: #fca5a5; }
.chg-text { color: var(--text); word-break: break-all; }
.attr-snapshot { color: #6b7280; font-size: 12px; white-space: normal; max-width: 340px; }
.reason-cell { font-size: 12px; white-space: normal; max-width: 220px; }
.diff-cell { font-size: 12px; white-space: normal; max-width: 300px; }
.diff-old { color: #b91c1c; text-decoration: line-through; }
.diff-new { color: #0B7A57; font-weight: 600; }

.action-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.action-hint { color: var(--ok); font-size: 13px; }

/* 表格 */
.table-wrap { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-size: 13px; }
.table th, .table td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--border); }
.table th { color: var(--muted); font-weight: 600; background: #fafafa; white-space: nowrap; }
.table td { white-space: nowrap; }
.table tr:hover td { background: #fafbfc; }
.table td.wrap { white-space: normal; max-width: 360px; }
.table .code-cell { font-family: "SF Mono", Consolas, monospace; font-weight: 600; color: var(--primary); }
.table-sm th, .table-sm td { padding: 6px 10px; font-size: 12px; }
.op-cell { display: flex; gap: 6px; flex-wrap: wrap; }

/* 查找区 */
.search-row { display: flex; gap: 10px; flex-wrap: wrap; }
.search-input { flex: 1; min-width: 260px; padding: 10px 12px; border: 1px solid var(--border);
  border-radius: 8px; font-size: 14px; outline: none; }
.search-input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(8,64,129,.12); }
.filter-block { margin-top: 16px; }
.filter-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.filter-title { font-size: 13px; font-weight: 600; color: var(--text); }
.filter-clear { font-size: 12px; color: var(--primary); text-decoration: none; }
.filter-clear:hover { text-decoration: underline; }
.filter-hint { font-size: 12px; color: #9ca3af; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; max-height: 150px; overflow-y: auto; }
.chips-groups { max-height: 220px; overflow-y: auto; border: 1px solid var(--border);
  border-radius: 8px; padding: 10px; background: #fcfcfd; }
.chip-group { margin-bottom: 10px; }
.chip-group:last-child { margin-bottom: 0; }
.chip-group-title { font-size: 12px; color: var(--muted); margin-bottom: 5px; font-weight: 600; }
.chip { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; padding: 4px 9px;
  border: 1px solid var(--border); border-radius: 14px; background: #fff; cursor: pointer;
  user-select: none; transition: all .12s; margin: 0 4px 4px 0; }
.chip:hover { border-color: var(--primary); color: var(--primary); }
.chip.on { background: var(--primary); border-color: var(--primary); color: #fff; }
.chip .chip-sub { opacity: .7; font-size: 11px; }
.active-filters { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.af-label { font-size: 12px; color: var(--muted); }
.af-tag { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; padding: 3px 9px;
  background: #EAF1F9; color: var(--primary); border: 1px solid #C5D9EF; border-radius: 12px; }
.af-tag span { cursor: pointer; font-weight: 700; opacity: .6; }
.af-tag span:hover { opacity: 1; }
.lib-meta { color: var(--muted); font-size: 13px; margin-bottom: 10px; }

/* 分页 */
.pager { display: flex; align-items: center; gap: 8px; margin-top: 14px; justify-content: flex-end; }
.pager button { padding: 6px 12px; border-radius: 6px; border: 1px solid var(--border);
  background: #fff; cursor: pointer; }
.pager button:disabled { opacity: .4; cursor: not-allowed; }
.pager .page-info { color: var(--muted); font-size: 13px; margin: 0 6px; }

/* 类别管理 */
.proposed-tag { font-size: 11px; color: #b45309; background: #fffbeb;
  border: 1px solid #fde68a; border-radius: 4px; padding: 1px 5px; margin-left: 5px; }

/* 弹窗 */
.modal-mask { position: fixed; inset: 0; background: rgba(0,0,0,.4); display: flex;
  align-items: center; justify-content: center; z-index: 100; padding: 20px; }
.modal { background: #fff; border-radius: 12px; width: 560px; max-width: 100%;
  box-shadow: 0 20px 60px rgba(0,0,0,.3); display: flex; flex-direction: column; max-height: 100%; }
.modal.modal-wide { width: 940px; }
.modal-title { padding: 18px 22px; font-size: 16px; font-weight: 700; border-bottom: 1px solid var(--border); }
.modal-body { padding: 20px 22px; overflow-y: auto; flex: 1; }
.modal-footer { padding: 14px 22px; border-top: 1px solid var(--border); display: flex;
  justify-content: flex-end; gap: 10px; flex-wrap: wrap; }
.modal .form-row { margin-bottom: 12px; }
.modal .form-row label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 6px; }
.modal .form-row input, .modal .form-row select { width: 100%; padding: 9px 11px;
  border: 1px solid var(--border); border-radius: 8px; font-size: 14px; outline: none; }
.attr-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.attr-table th, .attr-table td { padding: 6px 8px; border-bottom: 1px solid var(--border);
  text-align: left; vertical-align: top; }
.attr-table th { color: var(--muted); background: #fafafa; }

/* 属性编辑器 */
.editor-hint { font-size: 13px; color: var(--muted); line-height: 1.7; margin-bottom: 14px;
  background: #f8fafc; border: 1px solid var(--border); border-radius: 8px; padding: 12px 14px; }
.editor-hint code { background: #eef2f7; padding: 1px 5px; border-radius: 4px; font-size: 12px; }
.editor-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.editor-table th { font-size: 12px; color: var(--muted); font-weight: 600; text-align: left;
  padding: 6px 6px; background: #fafafa; white-space: nowrap; border-bottom: 1px solid var(--border); }
.editor-table td { padding: 5px 6px; border-bottom: 1px solid #f3f4f6; vertical-align: middle; }
.editor-table input, .editor-table select { width: 100%; padding: 6px 8px; font-size: 13px;
  border: 1px solid var(--border); border-radius: 6px; outline: none; font-family: inherit; }
.editor-table input:focus, .editor-table select:focus { border-color: var(--primary); }
.editor-table .col-seq { width: 34px; text-align: center; color: var(--muted); }
.editor-table .col-name { width: 130px; }
.editor-table .col-lv { width: 96px; }
.editor-table .col-req { width: 84px; }
.editor-table .col-opt { width: 170px; }
.editor-table .col-regex { width: 140px; }
.editor-table .col-del { width: 46px; }
.row-del { color: var(--danger); cursor: pointer; font-size: 16px; line-height: 1;
  background: none; border: none; padding: 2px 6px; }
.row-del:hover { background: #fef2f2; border-radius: 6px; }
/* 「编辑属性」弹窗顶部那条自带项：厂商型号 MPN（必填 / 选填）—— 中类自带，不用自己加一行 */
.sys-field { border: 1px solid #cfe0f2; background: #f4f8fd; border-radius: 8px;
  padding: 10px 14px; margin-bottom: 14px; }
.sys-field-main { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.sys-tag { font-size: 11px; color: #084081; background: #dce9f8; border-radius: 4px;
  padding: 2px 7px; white-space: nowrap; }
.sys-name { font-size: 13px; font-weight: 600; color: var(--text); }
.sys-field select { padding: 5px 8px; font-size: 13px; border: 1px solid var(--border);
  border-radius: 6px; outline: none; font-family: inherit; background: #fff; }
.sys-field select:focus { border-color: var(--primary); }
.sys-note { font-size: 12px; color: var(--muted); line-height: 1.6; margin-top: 6px; }
.sys-note b { color: #6b7280; }
.mid-block { border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; margin-bottom: 12px; }
.mid-block-title { font-size: 13px; font-weight: 600; margin-bottom: 10px; }
.mid-code-input { width: 90px !important; }
.mid-name-input { flex: 1; }
.inline-mid { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; }
.inline-mid input { padding: 8px 10px; border: 1px solid var(--border); border-radius: 6px; font-size: 13px; outline: none; }
.inline-mid input:focus { border-color: var(--primary); }

/* 导出选项 */
.chk-row { display: flex; align-items: center; gap: 9px; padding: 9px 0; font-size: 14px; cursor: pointer; }
.chk-row input { width: 16px; height: 16px; cursor: pointer; }
.chk-row .chk-sub { color: var(--muted); font-size: 12px; }
/* 二选一的分段按钮（导出格式 CSV / Excel）：比下拉少一次点击，也比单选圈更显眼 */
.seg-row { display: inline-flex; border: 1px solid var(--border); border-radius: 8px;
  overflow: hidden; margin: 2px 0 4px; }
.seg-btn { border: none; background: #fff; color: #4b5563; font-size: 13px; cursor: pointer;
  padding: 7px 16px; font-family: inherit; border-right: 1px solid var(--border); }
.seg-btn:last-child { border-right: none; }
.seg-btn:hover { background: #f3f6fa; }
.seg-btn.active { background: var(--primary); color: #fff; font-weight: 600; }
.col-preview { font-family: "SF Mono", Consolas, monospace; font-size: 12px; color: #6b7280;
  background: #f8fafc; border: 1px solid var(--border); border-radius: 6px; padding: 10px 12px;
  margin-top: 8px; line-height: 1.7; word-break: break-all; }

/* toast */
.toast { position: fixed; top: 20px; right: 24px; padding: 12px 18px; border-radius: 8px;
  background: #111827; color: #fff; font-size: 14px; box-shadow: 0 8px 24px rgba(0,0,0,.2);
  z-index: 200; max-width: 380px; line-height: 1.5; }
.toast.ok { background: var(--ok); }
.toast.err { background: var(--danger); }

/* ============ v4 新增 ============ */

/* 查重：同规格不同厂商（引导复用，不新开码） */
.dup-reuse { border-color: #9DBFDF; background: #EDF4FB; }
.dup-reuse .dup-group-title { color: #084081; }

/* 厂商料源清单 */
.src-hint { color: var(--muted); font-size: 12px; margin-top: 3px; }
.pref-badge { display: inline-block; background: #DFF5EC; color: #0B7A57; border: 1px solid #9ADDC4;
  border-radius: 4px; padding: 1px 7px; font-size: 12px; white-space: nowrap; }
.add-src-box { margin-top: 16px; padding-top: 14px; border-top: 1px dashed var(--border); }
.add-src-grid { display: grid; grid-template-columns: repeat(2, 1fr) auto; gap: 8px;
  align-items: center; margin-top: 9px; }
.add-src-grid input[type="text"], .add-src-grid input:not([type]) {
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 6px; font-size: 13px;
  outline: none; font-family: inherit; width: 100%; }
.add-src-grid input:focus { border-color: var(--primary); }
.chk-inline { display: flex; align-items: center; gap: 7px; font-size: 13px;
  color: var(--text); cursor: pointer; margin: 10px 0; }
.chk-inline input { width: 15px; height: 15px; cursor: pointer; }

/* 属性编辑器：常用正则模板下拉 */
.regex-tpl { margin-top: 5px; width: 100%; padding: 5px 6px; font-size: 12px;
  border: 1px solid var(--border); border-radius: 6px; background: #f8fafc;
  color: var(--muted); outline: none; font-family: inherit; }

/* 型号批量粘贴 / 结果标签（智能申请页与料号查找共用；
   注：「申请新料号」页的批量录入 2026-09-14 已下线，仅保留这里在用的类） */
.batch-tools { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 12px 0 10px; }
.file-btn { position: relative; overflow: hidden; }
.file-btn input[type="file"] { position: absolute; left: 0; top: 0; width: 100%; height: 100%;
  opacity: 0; cursor: pointer; }
.batch-text { width: 100%; border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px;
  font-family: "SF Mono", Consolas, "Microsoft YaHei", monospace; font-size: 12px; line-height: 1.7;
  color: var(--text); resize: vertical; outline: none; }
.batch-text:focus { border-color: var(--primary); }
.batch-hint { font-size: 12px; color: var(--muted); line-height: 1.7; margin-top: 8px; }
.batch-sum { display: flex; gap: 8px; flex-wrap: wrap; margin: 16px 0 8px; }
.batch-tag { display: inline-block; border-radius: 999px; padding: 3px 11px; font-size: 12px;
  border: 1px solid transparent; white-space: nowrap; }
.batch-new { background: #DFF5EC; color: #0B7A57; border-color: #9ADDC4; }
.batch-block { background: #fef3c7; color: #b45309; border-color: #fcd34d; }
.batch-blank { background: #f3f4f6; color: #6b7280; border-color: #e5e7eb; }
.batch-err-box { background: #fee2e2; border: 1px solid #fca5a5; color: #b91c1c;
  border-radius: 8px; padding: 10px 12px; font-size: 13px; line-height: 1.7; margin-top: 10px; }

/* ============ v5 新增 ============ */

/* 料号清单：同一编码下多家厂商料源的分组折叠 */
.exp-th { width: 34px; }
.exp-btn { width: 24px; height: 24px; border: 1px solid var(--border); background: #fff;
  border-radius: 5px; cursor: pointer; font-size: 15px; line-height: 1; color: var(--primary);
  font-family: inherit; padding: 0; }
.exp-btn:hover { background: #EDF4FB; border-color: var(--primary); }
.exp-btn.off { color: #cbd5e1; border-color: #e5e7eb; cursor: default; }
tr.grp-row > td { background: #f8fafc; padding-top: 3px; padding-bottom: 3px; }
tr.grp-row .grp-inner { display: flex; gap: 14px; flex-wrap: wrap; align-items: center;
  font-size: 12px; color: #4b5563; }
tr.grp-row .grp-k { color: #9ca3af; }
tr.grp-row .grp-tag { border-radius: 999px; padding: 1px 9px; font-size: 12px;
  background: #e0e7ff; color: #3730a3; }
.src-cell { font-size: 12px; line-height: 1.7; }
.more-hint { color: var(--muted); font-size: 12px; margin-top: 2px; }

/* 料号清单：其他信息（非关键属性 + 开新码原因） */
.oi-cell { font-size: 12px; line-height: 1.75; max-width: 300px; }
.oi-kv { color: #4b5563; }
.oi-kv b { color: #6b7280; font-weight: 400; }
.reason-line { color: #b45309; background: #fffbeb; border: 1px solid #fcd34d;
  border-radius: 4px; padding: 2px 7px; display: inline-block; margin-top: 3px; }
.lib-lock-note { font-size: 12px; color: var(--muted); margin: 2px 0 8px; line-height: 1.7; }

/* 智能申请 */
.smart-status { font-size: 12px; color: var(--muted); }
.smart-table { max-height: 520px; overflow: auto; }
.smart-table th { white-space: nowrap; }
.smart-table input[type="text"], .smart-table select {
  width: 100%; min-width: 76px; padding: 5px 7px; font-size: 12px;
  border: 1px solid var(--border); border-radius: 5px; font-family: inherit;
  outline: none; background: #fff; color: var(--text); }
.smart-table input:focus, .smart-table select:focus { border-color: var(--primary); }
.smart-table tbody tr.bad { background: #fff5f5; }
.conf-pill { border-radius: 999px; padding: 2px 9px; font-size: 12px; white-space: nowrap;
  border: 1px solid transparent; }
.conf-high { background: #DFF5EC; color: #0B7A57; border-color: #9ADDC4; }
.conf-mid { background: #fef3c7; color: #b45309; border-color: #fcd34d; }
.conf-low { background: #fee2e2; color: #b91c1c; border-color: #fca5a5; }
.smart-evi { font-size: 11px; color: #9ca3af; line-height: 1.6; max-width: 260px; }
.sm-attr-row { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
.sm-attr-row:last-child { margin-bottom: 0; }
.sm-attr-row label { flex: none; min-width: 84px; font-size: 12px; color: #4b5563;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sm-attr-row input { min-width: 90px; }
.smart-empty { border: 1px dashed var(--border); border-radius: 8px; padding: 10px 12px;
  font-size: 12px; color: var(--muted); line-height: 1.8; }
.addr-hint { font-size: 12px; color: var(--muted); line-height: 1.8; margin-top: 8px; }

/* ============ v6 新增 ============ */

/* 智能申请：待补齐的行标红（缺必填/缺名称就发不了号，必须一眼看出） */
.smart-table tbody tr.row-needfill > td { background: #fff7f7; }
.smart-table tbody tr.row-needfill > td:first-child { box-shadow: inset 3px 0 0 #ef4444; }
.smart-table tbody tr.row-bad > td { background: #f8fafc; }
.smart-table tbody tr.row-bad > td:first-child { box-shadow: inset 3px 0 0 #cbd5e1; }
.smart-table tbody tr.row-ok > td:first-child { box-shadow: inset 3px 0 0 #86efac; }
.conf-fill { background: #fee2e2; color: #b91c1c; border-color: #f87171; font-weight: 600; }
.pill-sub { font-size: 11px; color: #9ca3af; margin-top: 3px; text-align: center; }
/* 「生成此编码」：贴在判定列胶囊下面的逐条确认入口，比常规按钮更轻 */
.smart-one { display: block; margin: 5px auto 0; padding: 2px 8px; font-size: 11px; }
.batch-fill { background: #fee2e2; color: #b91c1c; border-color: #f87171; font-weight: 600; }
.sum-hint { font-size: 12px; color: #b91c1c; align-self: center; }
.sum-hint.sum-ok { color: #0B7A57; }
.blk-line { color: #b91c1c; font-weight: 600; }
.smart-table input.miss { border-color: #f87171; background: #fff1f1; }
.smart-table input.miss::placeholder { color: #fca5a5; }
.warn-box { background: #fff7ed; border: 1px solid #fdba74; color: #9a3412; border-radius: 8px;
  padding: 8px 11px; font-size: 13px; line-height: 1.8; margin-top: 8px; }
.smart-table .sm-type { border-color: #c7d2fe; background: #f8faff; }

/* 类型剖面：申请页的「先选类型」提示条 */
.type-bar { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 9px 11px; background: #f8fafc; border: 1px solid var(--border); border-radius: 8px;
  margin-bottom: 12px; }
.type-bar-k { font-size: 12px; color: #6b7280; margin-right: 2px; }
.type-chip { border: 1px solid var(--border); background: #fff; border-radius: 999px;
  padding: 3px 11px; font-size: 12px; cursor: pointer; color: #374151; font-family: inherit; }
.type-chip:hover { border-color: var(--primary); color: var(--primary); background: #eef4ff; }
.type-chip.on { background: var(--primary); border-color: var(--primary); color: #fff; }
.type-bar-hint { font-size: 12px; color: #9ca3af; margin-left: auto; }
.type-note { font-size: 12px; color: #b45309; margin-top: 5px; line-height: 1.6; }

/* 图例：颜色含义写在页面上，不用猜 */
.legend-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px;
  font-size: 12px; color: #6b7280; line-height: 1.7; margin: 0 0 10px; }
.legend-row b { color: #b91c1c; }
.legend-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; margin-left: 6px; }
.legend-dot:first-child { margin-left: 0; }
.dot-ok { background: #86efac; }
.dot-warn { background: #fcd34d; }
.dot-fill { background: #ef4444; }
.dot-bad { background: #cbd5e1; }

/* ---------- 生命周期（停用 / 恢复）与变更留痕（2026-09-16） ---------- */
/* 停用不是删除：数据全在，只是"不再使用"，所以用灰色压下去而不是划掉（划掉属性看不清） */
.row-inactive td { background: #f8fafc; color: #9ca3af; }
.row-inactive .code-cell { color: #b4b2a9; }
.off-badge { display: inline-block; margin-top: 3px; font-size: 11px; padding: 1px 7px;
  border-radius: 999px; background: #f3f4f6; color: #6b7280; border: 1px solid #e5e7eb;
  white-space: nowrap; }
.stop-bar { background: #fee2e2; border: 1px solid #fca5a5; color: #b91c1c; border-radius: 8px;
  padding: 9px 12px; font-size: 13px; line-height: 1.7; margin-bottom: 12px; }
/* 停用原因要能一眼看到（这行字的全部意义就是回答「当初为什么停」），
   「谁 + 何时」压成小字跟在后面，不跟原因抢注意力 */
.stop-bar .stop-who { color: #b91c1c; opacity: .78; font-size: 12px; margin-left: 8px; }
/* 「最后修改人」：挂在物料名称下的小字 —— 看得见才会有人在意 */
.mod-line { font-size: 11px; color: #9ca3af; margin-top: 2px; }

/* 变更记录（料号详情里的小节） */
.log-box { border: 1px solid var(--border); border-radius: 8px; overflow: hidden; max-height: 260px; overflow-y: auto; }
.log-line { display: flex; gap: 8px; align-items: baseline; padding: 6px 10px; font-size: 12px;
  border-bottom: 1px solid #f3f4f6; background: #fff; line-height: 1.7; }
.log-line:last-child { border-bottom: none; }
.log-line:nth-child(even) { background: #fafbfc; }
.log-t { color: #9ca3af; font-family: "SF Mono", Consolas, monospace; flex: 0 0 76px; }
.log-a { color: #4b5563; flex: 0 0 auto; max-width: 90px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.log-k { flex: 0 0 auto; font-size: 11px; border-radius: 4px; padding: 1px 6px;
  background: #f3f4f6; color: #4b5563; white-space: nowrap; }
.log-delete, .log-stop { background: #fee2e2; color: #b91c1c; }
.log-create, .log-resume { background: #DFF5EC; color: #0B7A57; }
.log-update { background: #D9E7F5; color: #084081; }
.log-d { color: var(--text); word-break: break-all; }

/* 「显示已停用」这类行内勾选（搜索行里，不能像 .chk-row 那样独占一行） */
.chk-inline { display: inline-flex; align-items: center; gap: 6px; font-size: 13px;
  color: #4b5563; cursor: pointer; white-space: nowrap; }
.chk-inline input { width: 15px; height: 15px; cursor: pointer; }

/* 数据维护（管理员）：查重体检 + 备份 */
.maint-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px;
  margin-bottom: 6px; }
.maint-item { border: 1px solid var(--border); border-radius: 8px; padding: 12px 14px;
  display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.maint-head { font-size: 14px; font-weight: 500; color: var(--text); }
.dup-blk { border: 1px solid var(--border); border-radius: 8px; overflow: hidden; margin-top: 12px; }
.dup-blk-head { padding: 9px 12px; font-size: 13px; background: #fafbfc; border-bottom: 1px solid var(--border); }
.dup-strong .dup-blk-head { background: #fff5f5; }
.dup-tag { display: inline-block; font-size: 11px; border-radius: 4px; padding: 2px 7px;
  border: 1px solid transparent; white-space: nowrap; }
.dup-tag-strong { background: #fee2e2; color: #b91c1c; border-color: #fca5a5; }
.dup-tag-weak { background: #fef3c7; color: #b45309; border-color: #fcd34d; }
.kv-diff { background: #fef3c7; border-radius: 4px; padding: 1px 4px; }
.ok-box { background: #DFF5EC; border: 1px solid #9ADDC4; color: #0B7A57; border-radius: 8px;
  padding: 10px 12px; font-size: 13px; line-height: 1.7; margin-top: 12px; }

/* ---------- 类别字典变更审批（2026-09-16） ---------- */
/* 侧边栏角标：只看「还有几条待处理 / 还没看过」，不引入已读未读那一套 */
.nav-badge { margin-left: auto; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: #ef4444; color: #fff; font-size: 11px; line-height: 18px; text-align: center; flex: 0 0 auto; }
.pwd-warn { margin-top: 6px; font-size: 11px; color: #fcd34d; line-height: 1.5; }
/* 「我的申请」：全站可见的审批结果入口（在料号查找页也能看到自己的申请结果） */
.side-btn { justify-content: flex-start; }

.chg-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  border-radius: 8px; padding: 10px 14px; font-size: 13px; line-height: 1.7; margin-bottom: 14px; }
.chg-bar-wait { background: #fef3c7; border: 1px solid #fcd34d; color: #92400e; }
.chg-bar-ok { background: #DFF5EC; border: 1px solid #9ADDC4; color: #0B7A57; }
.chg-bar .chg-bar-txt { flex: 1 1 auto; min-width: 0; }
.chg-bar b { font-weight: 500; }

.chg-item { border: 1px solid var(--border); border-radius: 8px; overflow: hidden; margin-bottom: 10px; }
.chg-item-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 9px 12px; background: #fafbfc; border-bottom: 1px solid var(--border); }
.chg-item-title { font-size: 13px; font-weight: 500; }
.chg-item-meta { font-size: 12px; color: var(--muted); }
.chg-item-body { padding: 10px 12px; }
.chg-item-head .op-cell { margin-left: auto; }
.chg-st { font-size: 11px; border-radius: 4px; padding: 2px 7px; border: 1px solid transparent; white-space: nowrap; }
.chg-st-pending { background: #fef3c7; color: #b45309; border-color: #fcd34d; }
.chg-st-approved { background: #DFF5EC; color: #0B7A57; border-color: #9ADDC4; }
.chg-st-rejected { background: #fee2e2; color: #b91c1c; border-color: #fca5a5; }
/* 还没看过的结果：申请人得能一眼看到「这条是新的」 */
.chg-item-new { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(8,64,129,.10); }
.chg-item-new .chg-item-head { background: #EDF4FB; }
.chg-new-dot { font-size: 11px; border-radius: 999px; padding: 2px 8px; background: var(--primary);
  color: #fff; white-space: nowrap; }
.chg-note { background: #fef3c7; border-left: 3px solid #f59e0b; padding: 7px 10px;
  border-radius: 0 6px 6px 0; font-size: 12.5px; line-height: 1.7; color: #78350f; margin-bottom: 8px; }
.chg-note-rej { background: #fee2e2; border-left-color: #dc2626; color: #7f1d1d; }
.conflict-box { background: #fee2e2; border: 1px solid #fca5a5; color: #b91c1c; border-radius: 8px;
  padding: 9px 12px; font-size: 13px; line-height: 1.7; margin-bottom: 10px; }

/* ---------- 料号查找表格重排（2026-09-16） ----------
   用户反馈：列多、容易横向溢出，「操作」在视窗外就完全被忽略了。
   做法：① 去掉一列纯占位的展开列（展开按钮挪进编码格）、去掉与编码重复的大类/中类代码；
        ② 「物料编码」钉左边、「操作」钉右边 —— 横向滚动时两头始终可见。 */
.lib-table .col-code { position: sticky; left: 0; z-index: 2; background: #fff;
  box-shadow: 1px 0 0 var(--border); }
.lib-table .col-ops { position: sticky; right: 0; z-index: 2; background: #fff;
  box-shadow: -7px 0 8px -7px rgba(23,41,79,.22); }
.lib-table thead th.col-code, .lib-table thead th.col-ops { background: #fafafa; z-index: 3; }
.lib-table tbody tr:hover td.col-code, .lib-table tbody tr:hover td.col-ops { background: #fafbfc; }
.lib-table tbody tr.row-inactive td.col-code, .lib-table tbody tr.row-inactive td.col-ops { background: #f8fafc; }
/* 停用行整行压灰时会盖掉钉住的底色，所以钉住的格子单独再压一次 */
.lib-table .col-ver { width: 62px; text-align: center; color: var(--muted); }
.lib-table .col-ops .op-cell { flex-wrap: nowrap; justify-content: flex-end; }
.lib-table td.wrap { max-width: 300px; }
.lib-table .code-line { display: flex; align-items: center; gap: 7px; }
.lib-table .code-line .code-text { font-family: "SF Mono", Consolas, monospace; font-weight: 600; }
.lib-table .cat-cell { color: #4b5563; }
.lib-table .cat-big { color: var(--muted); }

/* ---------- 生命周期：料源停用/恢复 + 编号再分配（2026-09-17） ---------- */

/* 料源行的「可用」徽标 —— 跟「已停用」共用同一套尺寸，视觉上成对 */
.live-badge { display: inline-block; font-size: 11px; padding: 1px 7px; border-radius: 999px;
  background: #ECFDF5; color: #047857; border: 1px solid #A7F3D0; white-space: nowrap; }
/* 「随料号停用」：料号停了 → 这家厂商也就暂时用不上（只影响显示，料源数据没动）。
   用比「已停用」更浅的灰 —— 它和「这家厂商自己停产了」不是一回事，恢复料号就会回来 */
.off-badge.mat-off { background: #f9fafb; color: #9ca3af; border-color: #eef0f2; border-style: dashed; }
/* 厂商料源窗口里，料号已停用时给「可用」补一句限定，避免两个页面口径看起来打架 */
.mat-off-note { font-size: 11px; color: #9ca3af; margin-top: 2px; }
/* 「生效但一家货源都没有」是**警告**不是错误（用户明确允许停掉最后一家厂商），
   所以用琥珀色，跟「已停用」的灰、删除的红色区分开 */
.nosupply-badge { display: inline-block; margin-top: 3px; font-size: 11px; padding: 1px 7px;
  border-radius: 999px; background: #FEF3C7; color: #B45309; border: 1px solid #FCD34D;
  white-space: nowrap; }
.nosupply-bar { background: #FFFBEB; border: 1px solid #FCD34D; color: #92400E; border-radius: 8px;
  padding: 9px 12px; font-size: 13px; line-height: 1.7; margin-bottom: 12px; }
.nosupply-hint { margin-top: 8px; font-size: 12px; color: #B45309; line-height: 1.6; }

/* 弹窗里的提示行：普通说明 / 需要停一下看的警示 */
.hint-line { margin-top: 6px; color: var(--muted); }
.hint-warn { margin-top: 7px; padding: 7px 10px; border-radius: 6px; background: var(--warn-bg);
  border: 1px solid #FCD34D; color: #92400E; }

/* 单选式多选项（askReason 的 choices）：整块可点，说明压在小字里。
   停用范围选择用它 —— 「整个料号」和「只停某一家」的差别必须一眼看清。 */
.choice-list { display: flex; flex-direction: column; gap: 7px; }
.choice-item { display: flex; align-items: flex-start; gap: 8px; padding: 8px 10px;
  border: 1px solid var(--border); border-radius: 8px; cursor: pointer; background: var(--panel); }
.choice-item:hover { border-color: var(--primary); background: #F8FAFF; }
.choice-item input { margin-top: 3px; flex: 0 0 auto; }
.choice-text { font-size: 13px; line-height: 1.55; }
.choice-hint { display: block; color: var(--muted); font-size: 12px; margin-top: 2px; }

/* 详情里的生命周期：一次停用一条、一次恢复一条，用左侧色条区分（红=停用，绿=恢复） */
.life-box { display: flex; flex-direction: column; gap: 6px; }
.life-line { padding: 7px 10px; border-radius: 6px; font-size: 13px; line-height: 1.6; }
.life-stop { background: #FEF2F2; border-left: 3px solid #DC2626; }
.life-resume { background: #ECFDF5; border-left: 3px solid #059669; }
.life-meta { color: var(--muted); font-size: 12px; margin-left: 6px; }

@media (max-width: 1000px) {
  .maint-row { grid-template-columns: 1fr; }
  .grid-2, .form-grid { grid-template-columns: 1fr; }
  .pick-row { grid-template-columns: 1fr; }
  .code-box label { visibility: visible; }
  .main { padding: 20px 16px; }
  .modal.modal-wide { width: 100%; }
  .add-src-grid { grid-template-columns: 1fr; }
}
