/* ============================================================
   立兴源工厂管理系统 — 样式（移动优先）
   ------------------------------------------------------------
   全部颜色/圆角/阴影都走 :root 的令牌，**不要在规则里写死颜色** ——
   车间的加粗提亮主题（html.theme-workshop）靠覆盖同一套令牌实现，
   写死一个颜色就会在那边对不上。
   例外：单据预览与打印（.doc / .stmt / @media print）必须写死黑白，
         因为那是纸，不管界面什么主题都要印成黑字白底。
   ============================================================ */
:root {
  /* 底色与表面 */
  --bg: #f5f7fa;
  --surface: #ffffff;
  --surface-2: #f8fafc;
  --surface-3: #eef2f7;
  --border: #e8edf3;
  --border-strong: #d3dbe6;

  /* 文字三级 */
  --text: #0f172a;
  --text-2: #566072;
  --muted: #8b94a3;

  /* 主色 */
  --primary: #2563eb;
  --primary-dark: #1d4ed8;
  --primary-soft: #e8effb;
  --primary-line: #cbdcfb;

  /* 语义色：每个都配「深字 / 浅底 / 描边」三件套，chip、banner、stat 共用 */
  --success: #15803d;  --success-soft: #e8f5ed;  --success-line: #c3e6d0;
  --warn: #b45309;     --warn-soft: #fdf4e6;     --warn-line: #f2ddb8;
  --danger: #c02626;   --danger-soft: #fdecec;   --danger-line: #f3c9c9;
  --info: #0e7490;     --info-soft: #e6f4f8;     --info-line: #c5e4ec;
  --purple: #6d28d9;   --purple-soft: #f1ecfd;   --purple-line: #d9cdf8;
  --neutral: #5b6472;  --neutral-soft: #f0f2f6;  --neutral-line: #e0e5ec;

  /* 框架层（顶栏 / 底栏 / 表单底 / 遮罩 / toast） */
  --appbar-bg: #ffffff;
  --appbar-fg: #0f172a;
  --appbar-border: #e8edf3;
  --appbar-btn-bg: #f0f3f8;
  --nav-bg: #ffffff;
  --nav-fg: #98a1ae;
  --nav-on: #2563eb;
  --nav-border: #e8edf3;
  --field-bg: #ffffff;
  --mask: rgba(15, 23, 42, .45);
  --toast-bg: #0f172a;
  --toast-fg: #ffffff;
  /* 登录页：logo 是「蓝底 + 白图标」，这个白是恒定的（不随主题变）。
     ⚠️ 卡片本身是白底 —— 卡片里的文字绝不能用它，会看不见（踩过）。 */
  --login-fg: #ffffff;

  /* 形状与字号 */
  --radius: 14px;
  --radius-sm: 10px;
  --shadow: 0 1px 2px rgba(16,24,40,.04), 0 1px 3px rgba(16,24,40,.05);
  --shadow-md: 0 6px 18px rgba(16,24,40,.10);
  --fs: 15px;
  --appbar-h: 52px;
  --nav-h: 56px;
  --safe-b: env(safe-area-inset-bottom, 0px);
}

/* ---------------- 车间主题（深色，只给 workshop 角色挂）---------------- */
/* 车间主题：**亮色高对比 + 大字号大按钮**。
   ⚠️ 一开始我把它做成了深色（理由是「车间光线差」）—— 这个判断是错的：
   车间恰恰是**强光环境**（照明足，白天还有自然光），深色屏在强光下反光、发灰，
   比浅色更难看清。用户当场反馈「太暗了」。
   车间真正需要的是：**字大、按钮大、对比高、边界清楚**（戴手套、站着、边看机器边看手机）。
   所以这里不换底色，只把对比度和尺寸往上推一档。 */
html.theme-workshop {
  /* 底与边界：底色比默认略深一点点，让白卡浮出来；边框明显加深（车间要一眼分得清块） */
  --bg: #eceff5;
  --surface: #ffffff;
  --surface-2: #f6f8fc;
  --surface-3: #e5eaf3;
  --border: #c6d0de;
  --border-strong: #a3b1c6;
  /* 文字：主字更深、次级字也加深（不能用浅灰，强光下会糊） */
  --text: #0a1120;
  --text-2: #38424f;
  --muted: #667080;
  --primary: #1d4ed8;
  --primary-dark: #1a43bd;
  --primary-soft: #e2ebfd;
  --primary-line: #b6cbf8;
  /* 语义色统一加深一档：浅色系在强光下几乎看不见 */
  --success: #0f5c2c;  --success-soft: #def2e5;  --success-line: #a4d6b7;
  --warn: #8a3c0b;     --warn-soft: #fbeed6;     --warn-line: #e8ca97;
  --danger: #9d1c1c;   --danger-soft: #fbe1e1;   --danger-line: #ecb0b0;
  --info: #0a5a70;     --info-soft: #dcf0f6;     --info-line: #a3d4e1;
  --purple: #5620ae;   --purple-soft: #eae2fa;   --purple-line: #c7b2f0;
  --neutral: #414a58;  --neutral-soft: #e8ecf2;  --neutral-line: #c8d1dd;
  --appbar-bg: #ffffff;
  --appbar-fg: #0a1120;
  --appbar-border: #c6d0de;
  --appbar-btn-bg: #eceff5;
  --nav-bg: #ffffff;
  --nav-fg: #667080;
  --nav-on: #1d4ed8;
  --nav-border: #c6d0de;
  --field-bg: #ffffff;
  --toast-bg: #0a1120;
  --toast-fg: #ffffff;
  /* 车间在机器旁边看手机：字和按钮都要更大 */
  --fs: 16px;
  --nav-h: 64px;
}

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

html, body {
  margin: 0; padding: 0;
  background: var(--bg);
  color: var(--text);
  font-size: var(--fs);
  line-height: 1.55;
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--primary); text-decoration: none; }
.hidden { display: none !important; }
h1, h2, h3, h4 { margin: 0; font-weight: 600; }
/* 金额、数量一律等宽数字：位数不同也能对齐成一列（A 方案的改进点之一） */
.num, .money, .row-no, .row-qty, .stat .v, .fin-card .fc-main, .stmt-flow .v,
.step-info, .m-item-grid b, .m-item-head .time, .task-qty b, .aging-table td {
  font-variant-numeric: tabular-nums;
}

/* ---------------- 登录 ---------------- */
.login-screen {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: linear-gradient(160deg, #1e3a8a 0%, #2563eb 48%, #3b82f6 100%);
}
.login-card {
  width: 100%; max-width: 380px; background: var(--surface);
  border-radius: 18px; padding: 28px 24px 22px; box-shadow: 0 20px 50px rgba(15,23,42,.3);
}
.login-logo { text-align: center; line-height: 1; }
/* 图标放在蓝底方块里 —— 登录卡片是白底，白色描边直接放上去是看不见的（踩过） */
.login-logo svg {
  display: block; width: 40px; height: 40px; margin: 0 auto; padding: 11px;
  box-sizing: content-box;
  background: var(--primary); border-radius: 15px;
  stroke: var(--login-fg); fill: none; stroke-width: 1.8; stroke-linejoin: round;
  box-shadow: 0 6px 16px rgba(37, 99, 235, .3);
}
.login-title { font-size: 20px; text-align: center; margin-top: 14px; letter-spacing: .5px; }
.login-sub { text-align: center; color: var(--muted); font-size: 13px; margin: 6px 0 22px; }
.login-error {
  background: var(--danger-soft); color: var(--danger); border-radius: var(--radius-sm);
  padding: 9px 12px; font-size: 13px; margin-bottom: 12px;
}
.login-hint { text-align: center; color: var(--muted); font-size: 12px; margin-top: 16px; }
/* 版本号：卡片是白底，所以用浅灰（不是白） */
.login-version {
  text-align: center; color: var(--muted); font-size: 11.5px;
  margin-top: 8px; letter-spacing: .3px;
}

/* 「我的」页最下面一行版本号 */
.app-foot {
  text-align: center; color: var(--muted); font-size: 12px;
  padding: 18px 0 6px; letter-spacing: .3px;
}

/* ---------------- 布局 ---------------- */
/* 顶栏：白底 + 深字 + 一条细线。原来是一条蓝渐变，占了近 1/16 屏幕却只放一个标题，
   视觉上还很重 —— 改白之后内容才是主角（A 方案的改动之一）。 */
.appbar {
  position: sticky; top: 0; z-index: 40;
  height: var(--appbar-h);
  display: flex; align-items: center; gap: 10px;
  padding: 0 12px;
  background: var(--appbar-bg); color: var(--appbar-fg);
  border-bottom: 1px solid var(--appbar-border);
}
.appbar-menu {
  background: var(--appbar-btn-bg); border: 0; color: var(--appbar-fg);
  width: 34px; height: 34px; border-radius: 9px; cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
}
.appbar-menu svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; }
.appbar-title { font-size: 16px; font-weight: 600; flex: 1; }
.appbar-user {
  font-size: 12.5px; background: var(--appbar-btn-bg); border: 0; color: var(--appbar-fg);
  padding: 6px 11px; border-radius: 999px; cursor: pointer; font-family: inherit; white-space: nowrap;
}

.shell { display: block; }
.main { padding: 12px 12px calc(78px + var(--safe-b)); min-height: calc(100vh - var(--appbar-h)); max-width: 1080px; margin: 0 auto; }

/* 图标：统一用线性 SVG（原来是九个彩色 emoji，风格各异、视觉噪音大）。
   尺寸和描边跟文字颜色走，所以深浅主题都自动适配。 */
.nav-item i, .bn-item i { display: flex; align-items: center; justify-content: center; font-style: normal; }
.nav-item svg, .bn-item svg {
  width: 17px; height: 17px; stroke: currentColor; fill: none;
  stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round;
}

/* 移动端：内容区是「顶部栏与底部导航之间」的独立滚动区。
   为什么不用整页滚动 + fixed 底栏：那样内容会滑到底部导航底下，
   被压在导航下面的按钮看着能点，实际点到的是导航（比如「出货」），会莫名其妙跳页 —— 踩过。
   把滚动交给内容区，任何按钮都不可能再钻到导航下面。 */
@media (max-width: 899px) {
  .shell { height: calc(100vh - var(--appbar-h) - var(--nav-h) - var(--safe-b)); }
  .main {
    height: 100%; min-height: 0; overflow-y: auto;
    -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
    padding-bottom: 14px;
  }
  /* 侧栏在手机上收成一个「全部功能」抽屉（底栏只留 5 个主入口）。
     底栏少放东西才不会挤成 43px 一个、拇指点错隔壁。 */
  .sidenav {
    display: flex; flex-direction: column; gap: 2px;
    position: fixed; top: var(--appbar-h); left: 0;
    bottom: calc(var(--nav-h) + var(--safe-b));
    width: 236px; max-width: 76vw; z-index: 46;
    background: var(--surface); border-right: 1px solid var(--border);
    padding: 10px 8px calc(10px + var(--safe-b)); overflow-y: auto;
    transform: translateX(-103%); transition: transform .18s ease;
  }
  .sidenav.open { transform: none; box-shadow: var(--shadow-md); }
}
@supports (height: 100dvh) {
  @media (max-width: 899px) {
    .shell { height: calc(100dvh - var(--appbar-h) - var(--nav-h) - var(--safe-b)); }
    .sidenav { bottom: calc(var(--nav-h) + var(--safe-b)); }
  }
}

/* 抽屉遮罩（点它关抽屉） */
.nav-mask {
  position: fixed; inset: 0; z-index: 45; background: var(--mask);
  opacity: 0; pointer-events: none; transition: opacity .18s ease;
}
.nav-mask.show { opacity: 1; pointer-events: auto; }
@media (min-width: 900px) { .nav-mask { display: none; } }

.bottomnav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  height: calc(var(--nav-h) + var(--safe-b));
  display: flex; background: var(--nav-bg);
  border-top: 1px solid var(--nav-border);
  padding-bottom: var(--safe-b);
}
/* 底栏只保留主入口；其余的走「☰ 全部功能」抽屉。
   ⚠️ 用 CSS 隐藏（不是 .hidden 类），这样「当前页在抽屉里」时底栏不会塌 */
.bn-item { display: none; }
.bn-item[data-bn="main"] { display: flex; }
.bn-item {
  flex: 1; text-align: center; padding: 8px 0 6px;
  color: var(--nav-fg); font-size: 11px; flex-direction: column; align-items: center; gap: 3px;
  min-width: 0;
}
.bn-item span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.bn-item.active { color: var(--nav-on); font-weight: 600; }

@media (min-width: 900px) {
  .appbar-menu { display: none; }
  .shell { display: flex; align-items: flex-start; }
  .sidenav {
    display: flex; flex-direction: column; gap: 2px;
    width: 182px; flex: 0 0 182px;
    padding: 12px 8px; position: sticky; top: var(--appbar-h);
    height: calc(100vh - var(--appbar-h));
  }
  .main { flex: 1; padding: 18px 20px 60px; min-width: 0; }
  .bottomnav { display: none; }
}

.nav-item {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: var(--radius-sm);
  color: var(--text-2); font-size: 14px;
}
.nav-item:hover { background: var(--surface); }
.nav-item.active { background: var(--primary-soft); color: var(--primary); font-weight: 600; }

/* ---------------- 卡片与通用 ---------------- */
.card {
  background: var(--surface); border-radius: var(--radius);
  box-shadow: var(--shadow); border: 1px solid var(--border);
  margin-bottom: 12px; overflow: hidden;
}
.card-head {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 14px; border-bottom: 1px solid var(--border);
}
.card-head h3 { font-size: 15px; flex: 1; }
.card-head .sub { font-size: 12px; color: var(--muted); font-weight: 400; }
.card-body { padding: 14px; }
.card-body.tight { padding: 0; }

.section-title {
  display: flex; align-items: center; justify-content: space-between;
  margin: 18px 2px 8px; font-size: 13px; font-weight: 600; color: var(--text-2);
}
.section-title:first-child { margin-top: 4px; }

.stat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
@media (min-width: 640px) { .stat-grid { grid-template-columns: repeat(4, 1fr); } }
.stat {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 12px 13px; box-shadow: var(--shadow);
}
.stat .k { font-size: 12px; color: var(--muted); }
.stat .v { font-size: 22px; font-weight: 700; margin-top: 2px; letter-spacing: -.5px; }
.stat .u { font-size: 12px; color: var(--muted); font-weight: 400; margin-left: 2px; }
.stat.blue .v { color: var(--primary); }
.stat.green .v { color: var(--success); }
.stat.orange .v { color: var(--warn); }
.stat.red .v { color: var(--danger); }

/* 看板专用的「色块统计卡」：四个数字各占一个浅色底，一眼分得开（B 方案的做法，只用在看板页）。
   其它页面仍是白卡 —— 全站都这么疏朗的话，日常翻单会变慢。 */
.stat.tint { border-color: transparent; box-shadow: none; }
.stat.tint .k, .stat.tint .u { color: var(--tint-fg); opacity: .75; }
.stat.tint .v { color: var(--tint-fg); font-size: 24px; }
.stat.tint.blue   { background: var(--primary-soft); --tint-fg: var(--primary); }
.stat.tint.green  { background: var(--success-soft); --tint-fg: var(--success); }
.stat.tint.orange { background: var(--warn-soft);    --tint-fg: var(--warn); }
.stat.tint.red    { background: var(--danger-soft);  --tint-fg: var(--danger); }
.stat.tint.purple { background: var(--purple-soft);  --tint-fg: var(--purple); }
html.theme-workshop .stat.tint { border: 1px solid var(--border); }

/* 状态标签 */
.chip {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 8px; border-radius: 999px; font-size: 12px; font-weight: 500; white-space: nowrap;
  background: var(--surface-2); color: var(--text-2); border: 1px solid var(--border);
}
.chip.open, .chip.waiting, .chip.cancelled { background: var(--neutral-soft); color: var(--neutral); border-color: var(--neutral-line); }
.chip.producing, .chip.doing { background: var(--primary-soft); color: var(--primary); border-color: var(--primary-line); }
.chip.done { background: var(--success-soft); color: var(--success); border-color: var(--success-line); }
.chip.shipped { background: var(--purple-soft); color: var(--purple); border-color: var(--purple-line); }
.chip.urgent { background: var(--danger-soft); color: var(--danger); border-color: var(--danger-line); }
.chip.pending { background: var(--warn-soft); color: var(--warn); border-color: var(--warn-line); }
.chip.danger { background: var(--danger-soft); color: var(--danger); border-color: var(--danger-line); }

/* ---------------- 列表项 ---------------- */
.list { display: flex; flex-direction: column; }
.row {
  display: block; padding: 12px 14px; border-bottom: 1px solid var(--border);
  color: inherit; cursor: pointer;
}
.row:last-child { border-bottom: 0; }
.row:active { background: var(--surface-2); }
.row-top { display: flex; align-items: center; gap: 8px; }
.row-no { font-weight: 600; font-size: 14px; font-variant-numeric: tabular-nums; }
.row-top .spacer { flex: 1; }
.row-main { font-size: 13px; color: var(--text-2); margin-top: 3px; display: flex; flex-wrap: wrap; gap: 4px 10px; }
.row-main .kv { white-space: nowrap; }
.row-main .kv b { font-weight: 600; color: var(--text); }
.row-meta { font-size: 12px; color: var(--muted); margin-top: 4px; display: flex; flex-wrap: wrap; gap: 4px 10px; }
.row-right { text-align: right; }
.row-qty { font-weight: 700; font-size: 15px; font-variant-numeric: tabular-nums; }
.row-qty small { font-weight: 400; color: var(--muted); font-size: 11px; margin-left: 1px; }

/* ---------------- 表单 ---------------- */
.field { display: block; margin-bottom: 12px; }
.field > span { display: block; font-size: 12.5px; color: var(--text-2); margin-bottom: 5px; }
.field > span .req { color: var(--danger); }
input[type=text], input[type=password], input[type=number], input[type=date], input[type=tel], select, textarea {
  width: 100%; padding: 9px 11px; font-size: 15px; color: var(--text);
  background: var(--field-bg); border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  font-family: inherit; outline: none; appearance: none;
}
input:focus, select:focus, textarea:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(37,99,235,.14); }
textarea { min-height: 66px; resize: vertical; }
select { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%2394a3b8' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; padding-right: 30px; }
.form-grid { display: grid; grid-template-columns: 1fr; gap: 0 12px; }
@media (min-width: 640px) { .form-grid.two { grid-template-columns: 1fr 1fr; } }
@media (min-width: 640px) { .form-grid.three { grid-template-columns: repeat(3, 1fr); } }

/* 报价单明细：实时算出来的那一块 */
.quote-calc {
  margin-top: 10px; padding: 10px 12px;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm);
  font-size: 13px; line-height: 1.95;
}
.quote-calc .qc-line { display: flex; flex-wrap: wrap; gap: 4px 14px; }
.quote-calc .qc-line > span { white-space: nowrap; }
.quote-calc .qc-big { font-size: 16px; font-weight: 700; color: var(--danger); }
.quote-calc .qc-muted { color: var(--muted); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 14px; font-size: 14px; font-weight: 500; font-family: inherit;
  border: 1px solid var(--border-strong); background: var(--surface); color: var(--text);
  border-radius: var(--radius-sm); cursor: pointer; white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--primary); border-color: var(--primary); color: #fff; }
.btn-primary:hover { background: var(--primary-dark); }
.btn-success { background: var(--success); border-color: var(--success); color: #fff; }
.btn-danger { background: var(--surface); border-color: var(--danger-line); color: var(--danger); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--primary); }
.btn-block { width: 100%; }
.btn-lg { padding: 13px 16px; font-size: 16px; }
.btn-sm { padding: 5px 10px; font-size: 13px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; }

/* 按钮里的线性图标 */
.btn .bi { width: 15px; height: 15px; flex: 0 0 15px; stroke: currentColor; fill: none; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }

/* ---------------- 工序（报工）---------------- */
.stepline { display: flex; flex-direction: column; }
.step {
  display: flex; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--border);
  align-items: flex-start;
}
.step:last-child { border-bottom: 0; }
.step-idx {
  flex: 0 0 24px; width: 24px; height: 24px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 600;
  background: var(--neutral-soft); color: var(--neutral);
}
.step.doing .step-idx { background: var(--primary); color: #fff; }
.step.done .step-idx { background: var(--success); color: #fff; }
.step-body { flex: 1; min-width: 0; }
.step-name { font-size: 14.5px; font-weight: 600; display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.step.done .step-name { color: var(--text-2); }
.step-info { font-size: 12.5px; color: var(--muted); margin-top: 3px; font-variant-numeric: tabular-nums; }
.step-info b { color: var(--text); font-weight: 600; }
.step-actions { margin-top: 9px; display: flex; gap: 7px; flex-wrap: wrap; }

.progress { height: 5px; background: var(--surface-3); border-radius: 999px; overflow: hidden; margin-top: 7px; }
.progress > i { display: block; height: 100%; background: var(--primary); border-radius: 999px; }
.progress.green > i { background: var(--success); }

/* ---------------- 表格（桌面）---------------- */
.table-wrap { overflow-x: auto; }
table.tbl { width: 100%; border-collapse: collapse; font-size: 13.5px; }
table.tbl th {
  text-align: left; font-weight: 600; color: var(--text-2); font-size: 12.5px;
  padding: 9px 12px; background: var(--surface-2); border-bottom: 1px solid var(--border); white-space: nowrap;
}
table.tbl td { padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
table.tbl tr:last-child td { border-bottom: 0; }
table.tbl tr.clickable:hover { background: var(--surface-2); cursor: pointer; }
.num { text-align: right; font-variant-numeric: tabular-nums; }

/* 桌面端紧凑表格（C 方案）：行高压到 34px、斑马纹、整行可点。
   订单/出货这类一屏要看几十条的列表用它；财务那种小表仍用 .tbl 默认行高。 */
table.tbl.dense { font-size: 13px; }
table.tbl.dense th { padding: 7px 10px; font-size: 11.5px; letter-spacing: .2px; }
table.tbl.dense td { padding: 7px 10px; }
table.tbl.dense tbody tr:nth-child(even) td { background: var(--surface-2); }
table.tbl tr[data-href] { cursor: pointer; }
table.tbl tr[data-href]:hover td { background: var(--primary-soft); }
table.tbl.dense td.no { font-weight: 600; font-variant-numeric: tabular-nums; }

/* ---------------- 工具条 / 搜索 ---------------- */
.toolbar { display: flex; gap: 8px; align-items: center; margin-bottom: 12px; flex-wrap: wrap; }
.toolbar .search { flex: 1; min-width: 130px; position: relative; }
.toolbar input[type=text] { padding-left: 30px; }
.toolbar .search::before {
  content: ""; position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  width: 15px; height: 15px; background: currentColor; color: var(--muted);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.5-3.5'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.5-3.5'/%3E%3C/svg%3E") center/contain no-repeat;
}
.segmented { display: flex; gap: 0; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.segmented button {
  border: 0; background: transparent; padding: 7px 11px; font-size: 13px; color: var(--text-2);
  cursor: pointer; font-family: inherit; border-right: 1px solid var(--border); white-space: nowrap;
}
.segmented button:last-child { border-right: 0; }
.segmented button.active { background: var(--primary); color: #fff; font-weight: 500; }

.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 12px; overflow-x: auto; }
.tabs button {
  border: 0; background: transparent; padding: 9px 13px; font-size: 14px; color: var(--text-2);
  cursor: pointer; font-family: inherit; border-bottom: 2px solid transparent; white-space: nowrap;
}
.tabs button.active { color: var(--primary); border-bottom-color: var(--primary); font-weight: 600; }

/* ---------------- 空态 / 加载 ---------------- */
.empty { text-align: center; padding: 34px 16px; color: var(--muted); font-size: 13.5px; }
.empty .ico { font-size: 30px; display: block; margin-bottom: 8px; opacity: .6; }
.loading { text-align: center; padding: 30px; color: var(--muted); font-size: 13.5px; }
.spinner {
  width: 22px; height: 22px; border: 2.5px solid var(--border); border-top-color: var(--primary);
  border-radius: 50%; animation: spin .7s linear infinite; margin: 0 auto 10px;
}
@keyframes spin { to { transform: rotate(360deg); } }
.banner {
  padding: 10px 13px; border-radius: var(--radius-sm); font-size: 13px; margin-bottom: 12px;
  background: var(--warn-soft); color: var(--warn); border: 1px solid var(--warn-line);
}
.banner.danger { background: var(--danger-soft); color: var(--danger); border-color: var(--danger-line); }
.banner.info { background: var(--info-soft); color: var(--info); border-color: var(--info-line); }
.banner.success { background: var(--success-soft); color: var(--success); border-color: var(--success-line); }

/* ---------------- Toast ---------------- */
.toast {
  position: fixed; left: 50%; bottom: calc(90px + var(--safe-b)); transform: translateX(-50%);
  background: var(--toast-bg); color: var(--toast-fg); padding: 10px 18px; border-radius: 999px;
  font-size: 14px; z-index: 200; box-shadow: var(--shadow-md); max-width: 88vw;
  animation: toastin .18s ease-out;
}
@keyframes toastin { from { opacity: 0; transform: translate(-50%, 8px); } }

/* ---------------- 弹窗 ---------------- */
.modal-mask {
  position: fixed; inset: 0; background: var(--mask); z-index: 100;
  display: flex; align-items: flex-end; justify-content: center;
}
@media (min-width: 640px) { .modal-mask { align-items: center; } }
.modal {
  background: var(--surface); width: 100%; max-width: 620px; max-height: 92vh;
  display: flex; flex-direction: column;
  border-radius: 16px 16px 0 0; overflow: hidden;
}
@media (min-width: 640px) { .modal { border-radius: 16px; max-height: 86vh; } }
.modal-head { display: flex; align-items: center; padding: 14px 16px; border-bottom: 1px solid var(--border); }
.modal-head h3 { flex: 1; font-size: 16px; }
.modal-close { border: 0; background: transparent; font-size: 20px; color: var(--muted); cursor: pointer; line-height: 1; padding: 0 4px; }
.modal-body { padding: 16px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.modal-foot { padding: 12px 16px calc(12px + var(--safe-b)); border-top: 1px solid var(--border); display: flex; gap: 8px; }
.modal-foot .btn { flex: 1; }

/* 明细行编辑 */
.item-row {
  display: grid; grid-template-columns: 1fr; gap: 8px;
  padding: 10px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  margin-bottom: 9px; background: var(--surface-2); position: relative;
}
.item-row .del {
  position: absolute; top: 6px; right: 6px; border: 0; background: transparent; color: var(--muted);
  font-size: 16px; cursor: pointer; line-height: 1;
}
.qty-inline { display: flex; gap: 8px; }
.qty-inline > * { flex: 1; min-width: 0; }

.kv-list { display: flex; flex-direction: column; gap: 0; }
.kv-row { display: flex; gap: 10px; padding: 8px 0; border-bottom: 1px dashed var(--border); font-size: 14px; }
.kv-row:last-child { border-bottom: 0; }
.kv-row .k { flex: 0 0 84px; color: var(--muted); font-size: 13px; }
.kv-row .v { flex: 1; min-width: 0; word-break: break-word; }

.big-qty { display: flex; gap: 10px; }
.big-qty label { flex: 1; }
.big-qty input { font-size: 22px; padding: 12px; text-align: center; font-weight: 600; }

.bar-chart { display: flex; align-items: flex-end; gap: 6px; height: 100px; padding: 6px 2px 0; }
.bar-chart .bar { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; }
.bar-chart .bar > i { width: 100%; max-width: 34px; background: var(--primary); border-radius: 4px 4px 0 0; display: block; }
.bar-chart .bar > span { font-size: 10.5px; color: var(--muted); margin-top: 4px; white-space: nowrap; }

/* ---------------- 移动端卡片（宽表格在小屏上不可用，改卡片）---------------- */
.only-mobile { display: block; }
.only-desktop { display: none; }
@media (min-width: 900px) {
  .only-mobile { display: none; }
  .only-desktop { display: block; }
}
.m-item { padding: 11px 14px; border-bottom: 1px solid var(--border); }
.m-item:last-child { border-bottom: 0; }
.m-item-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; font-size: 14.5px; }
.m-item-head .spec { color: var(--muted); font-size: 12px; }
.m-item-head .time { color: var(--muted); font-size: 12px; margin-left: auto; font-variant-numeric: tabular-nums; }
.m-item-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px 8px; margin-top: 8px; }
.m-item-grid span { font-size: 11.5px; color: var(--muted); display: flex; flex-direction: column; line-height: 1.3; }
.m-item-grid b { font-size: 14px; color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.m-item-grid b.warn { color: var(--danger); }
.m-note { margin-top: 6px; font-size: 12px; color: var(--danger); }

/* ---------------- 财务对账 ---------------- */
.money { font-variant-numeric: tabular-nums; white-space: nowrap; }
.money.neg { color: var(--danger); }
.money.pos { color: var(--success); }

.fin-hero {
  display: grid; grid-template-columns: 1fr; gap: 12px; margin-bottom: 12px;
}
@media (min-width: 720px) { .fin-hero { grid-template-columns: 1fr 1fr; } }
.fin-card {
  border-radius: var(--radius); padding: 14px 15px; border: 1px solid var(--border);
  background: var(--surface); box-shadow: var(--shadow);
}
.fin-card.ar { border-left: 4px solid var(--primary); }
.fin-card.ap { border-left: 4px solid var(--warn); }
.fin-card .fc-label { font-size: 12.5px; color: var(--text-2); display: flex; align-items: center; gap: 6px; }
.fin-card .fc-main { font-size: 26px; font-weight: 700; letter-spacing: -.8px; margin: 4px 0 2px; font-variant-numeric: tabular-nums; }
.fin-card .fc-sub { font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }

.aging-bar { display: flex; height: 8px; border-radius: 999px; overflow: hidden; background: var(--surface-3); margin-top: 8px; }
.aging-bar > i { display: block; height: 100%; }
.aging-legend { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 7px; font-size: 11.5px; color: var(--text-2); }
.aging-legend span { display: inline-flex; align-items: center; gap: 4px; }
.aging-legend em { width: 8px; height: 8px; border-radius: 2px; display: inline-block; font-style: normal; }
.a30 { background: #22c55e; } .a60 { background: #eab308; } .a90 { background: #f97316; } .a90p { background: #dc2626; }

.aging-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.aging-table th, .aging-table td { padding: 7px 8px; border-bottom: 1px solid var(--border); text-align: right; font-variant-numeric: tabular-nums; }
.aging-table th:first-child, .aging-table td:first-child { text-align: left; font-variant-numeric: normal; }
.aging-table thead th { background: var(--surface-2); font-size: 12px; color: var(--text-2); font-weight: 600; white-space: nowrap; }
.aging-table td.z { color: var(--muted); }
.aging-table td.hot { color: var(--danger); font-weight: 600; }

.stmt-flow { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
@media (min-width: 640px) { .stmt-flow { grid-template-columns: repeat(4, 1fr); } }
.stmt-flow > div {
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 10px 12px; text-align: center;
}
.stmt-flow .l { font-size: 12px; color: var(--muted); }
.stmt-flow .v { font-size: 18px; font-weight: 700; margin-top: 3px; font-variant-numeric: tabular-nums; }

.print-area { display: none; }

/* 对账单（同时用于预览与打印） */
.stmt { color: #000; background: #fff; font-size: 13px; line-height: 1.6; }
.stmt h1 { font-size: 19px; text-align: center; letter-spacing: 6px; margin: 6px 0 4px; font-weight: 700; }
.stmt .stmt-company { font-size: 15px; font-weight: 700; }
.stmt .stmt-top { display: flex; justify-content: space-between; align-items: flex-start; border-bottom: 2px solid #000; padding-bottom: 8px; }
.stmt .stmt-meta { margin: 10px 0; display: flex; flex-wrap: wrap; gap: 4px 24px; font-size: 13px; }
.stmt table { width: 100%; border-collapse: collapse; margin-top: 6px; }
.stmt table th, .stmt table td { border: 1px solid #999; padding: 5px 7px; font-size: 12px; }
.stmt table th { background: #f0f0f0; text-align: center; font-weight: 600; }
.stmt table td.r { text-align: right; font-variant-numeric: tabular-nums; }
/* 日期与单号不允许折行：A4 出纸（PDF）时列宽由内容决定，折了会很难看（"2026-10-\n01"） */
.stmt table td.dt, .stmt table td.no { white-space: nowrap; }
.stmt .stmt-foot { display: flex; justify-content: space-between; margin-top: 26px; font-size: 13px; }
.stmt .stmt-note { margin-top: 14px; font-size: 11.5px; color: #444; line-height: 1.7; }

/* ---------------- 车间端「今日生产」 ---------------- */
.today-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; flex-wrap: wrap; margin: 2px 3px 10px;
}
.today-date { font-size: 15px; font-weight: 600; }
.today-mine { font-size: 12.5px; color: var(--text-2); }
.today-mine b { color: var(--success); font-size: 15px; }
.today-mine b.bad { color: var(--danger); }

.task-card { padding: 14px; border-left: 4px solid transparent; }
.task-card.urgent {
  border-left-color: var(--danger);
  background: var(--danger-soft);
}
.task-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.task-wo { font-size: 12.5px; color: var(--muted); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.task-due { font-size: 12px; color: var(--muted); }
.task-product { font-size: 19px; font-weight: 700; margin: 9px 0 1px; letter-spacing: -.2px; }
.task-code { font-size: 12.5px; color: var(--muted); font-weight: 400; margin-left: 6px; }
.task-spec { font-size: 12.5px; color: var(--text-2); }

/* 模具是车间最需要一眼看清的信息：编号、类型、腔数、放在哪 */
.mold-box {
  display: flex; gap: 10px; align-items: flex-start;
  margin: 11px 0; padding: 10px 12px;
  background: var(--primary-soft); border-radius: var(--radius-sm);
}
.mold-ico { font-size: 19px; line-height: 1.15; }
.mold-body { flex: 1; min-width: 0; }
.mold-line { font-size: 13.5px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.mold-line + .mold-line { margin-top: 6px; }
.mold-line b { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.mold-meta { font-size: 12px; color: var(--text-2); }
.mold-none { color: var(--warn); font-size: 13px; }

.task-qty { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.task-qty > div { background: var(--surface-2); border-radius: var(--radius-sm); padding: 7px 9px; text-align: center; }
.task-qty span { display: block; font-size: 11.5px; color: var(--muted); }
.task-qty b { font-size: 17px; }
.task-qty .hl { background: var(--warn-soft); }
.task-qty .hl b { color: var(--warn); }

.task-step { margin-top: 11px; }
.task-step-line { font-size: 13.5px; }
.task-step-line b { color: var(--primary); }
.task-step-of { font-size: 12px; color: var(--muted); margin-left: 6px; }
.task-step .progress { margin-top: 6px; }

.task-actions { display: flex; gap: 9px; margin-top: 13px; }
.task-actions .btn { flex: 1; }
.task-actions .btn-primary { flex: 1.8; }
.task-actions .btn:disabled { opacity: .45; }

/* ---------------- 出货装箱规格 ---------------- */
.packing-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 10px; }
@media (max-width: 420px) { .packing-grid { gap: 7px; } .packing-grid .field span { font-size: 12px; } }

/* ---------------- 单据（送货单 / 生产单） ---------------- */
.doc-preview { background: #fff; border: 1px solid var(--border); border-radius: 8px; padding: 18px; overflow-x: auto; }
.doc-preview .stmt { min-width: 680px; }   /* 对账单在手机上横向滚动查看 */
.doc-preview .stmt,
.print-area .stmt { color: #000; }
.doc { color: #000; background: #fff; font-size: 13px; line-height: 1.6; min-width: 680px; }
/* 窄屏（手机）单据预览：不再强制 680px（外部审查低危项：手机端单据预览强制最小宽度导致横向溢出）。
   680px 在手机上必然横向溢出，用户滑动时容易误触、按钮点不到。改成按屏宽排、字号调小；
   要看细账可以旋转屏幕，或直接打印/下载 PDF。 */
@media (max-width: 639px) {
  .doc, .doc-preview .stmt { min-width: 0; }
  .doc-preview { padding: 10px; }
  .doc-title { font-size: 17px; letter-spacing: 4px; }
  .doc-head { flex-wrap: wrap; gap: 8px; }
  .doc-meta { text-align: left; white-space: normal; }
  .doc-tbl th, .doc-tbl td, .stmt table th, .stmt table td { padding: 3px 4px; font-size: 10.5px; }
}
.doc-title { font-size: 20px; text-align: center; letter-spacing: 8px; margin: 0 0 12px; font-weight: 700; }
.doc-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px; border-bottom: 2px solid #000; padding-bottom: 9px; }
.doc-co { font-size: 16px; font-weight: 700; }
.doc-sub { font-size: 11.5px; color: #333; margin-top: 3px; }
.doc-meta { text-align: right; font-size: 12px; line-height: 1.95; white-space: nowrap; }
.doc-kv { width: 100%; border-collapse: collapse; margin: 10px 0; }
.doc-kv td { border: 1px solid #bbb; padding: 5px 8px; font-size: 12px; }
.doc-kv td.k { background: #f5f5f5; font-weight: 600; width: 80px; color: #333; }
.doc-sec { font-weight: 700; font-size: 12.5px; margin: 14px 0 6px; }
.doc-tbl { width: 100%; border-collapse: collapse; }
.doc-tbl th, .doc-tbl td { border: 1px solid #999; padding: 5px 7px; font-size: 12px; }
.doc-tbl th { background: #f0f0f0; text-align: center; font-weight: 600; }
.doc-tbl td.c { text-align: center; }
.doc-tbl td.r { text-align: right; font-variant-numeric: tabular-nums; }
/* 表头一律不折行：A4 出纸（PDF）时列宽会被压，"序号" 折成 "序\n号" 很难看 */
.doc-tbl th, .stmt table th { white-space: nowrap; }
.doc-tbl tr.doc-sum td { background: #fafafa; font-weight: 700; }
.doc-note { margin-top: 12px; font-size: 11.5px; color: #333; line-height: 1.8; }
.doc-sign { display: flex; justify-content: space-between; gap: 16px; margin-top: 30px; font-size: 12px; flex-wrap: wrap; }
.doc-foot { margin-top: 22px; padding-top: 8px; border-top: 1px dashed #999; font-size: 11px; color: #666; text-align: center; }

/* ---------------- 列表页工具栏吸顶 ----------------
   原来滚下去搜索框就没了，想换个筛选要滚回顶部（A 方案的改动之一）。
   只对 #view 的直接子元素生效 —— 弹窗里的工具栏不能吸顶，那会贴在弹窗外面。 */
#view > .toolbar {
  position: sticky; top: 0; z-index: 20;
  background: var(--bg); margin: 0 -12px 6px; padding: 8px 12px;
}
@media (min-width: 900px) {
  #view > .toolbar { top: var(--appbar-h); margin: 0 -20px 6px; padding: 10px 20px; }
}

/* ---------------- 车间主题的额外调整（亮色高对比 + 字大按钮大）----------------
   配色在上面那份令牌里；这里只管「尺寸与边界」，都是为了让车间戴手套、站着也能一次点准。 */
html.theme-workshop .appbar-title { font-size: 17px; }
html.theme-workshop .bn-item { font-size: 11.5px; padding: 9px 0 7px; }
html.theme-workshop .bn-item svg { width: 21px; height: 21px; stroke-width: 2.1; }
html.theme-workshop .sidenav { width: 260px; }
html.theme-workshop .nav-item { padding: 13px 12px; font-size: 15.5px; }
html.theme-workshop .nav-item svg { width: 19px; height: 19px; }
html.theme-workshop .stat .v { font-size: 25px; }
html.theme-workshop .btn { padding: 11px 16px; font-size: 15px; border-color: var(--border-strong); }
html.theme-workshop .task-actions .btn { padding: 16px 16px; font-size: 17px; }
html.theme-workshop .task-product { font-size: 21px; }
html.theme-workshop .mold-box { background: var(--primary-soft); }
html.theme-workshop input, html.theme-workshop select, html.theme-workshop textarea { font-size: 16px; }
/* 车间卡片：边框比通版重一档（强光下浅边框会「化掉」，块与块分不开） */
html.theme-workshop .card { border-color: var(--border); }
/* 任务卡：补上四周细边、左边条加粗到 5px。
   ⚠️ 这两条的优先级高于 .task-card.urgent，所以必须把加急的左边条颜色**再写一遍**，
   否则加急那条红边会被这里的 border 简写抹掉（普通卡是透明边，看不出来，但加急也一起没了）。 */
html.theme-workshop .task-card { border: 1px solid var(--border); border-left-width: 5px; }
html.theme-workshop .task-card.urgent { border-left-color: var(--danger); }
/* 单据预览/打印永远是纸：主题怎么变都是白底黑字（.doc / .stmt 里写死了黑白，这里只保证容器） */
html.theme-workshop .doc-preview { background: #fff; border-color: var(--border); }

@media print {
  @page { size: A4; margin: 14mm; }
  body { background: #fff; }
  body > *:not(.print-area) { display: none !important; }
  .print-area { display: block !important; }
  /* 打印时按纸张宽度自适应，并避免表格行被跨页截断 */
  .doc { min-width: 0; }
  .doc-preview .stmt,
  .print-area .stmt { min-width: 0; }
  .doc tr, .stmt tr { page-break-inside: avoid; }
  .doc-sign, .doc-head, .stmt-foot { page-break-inside: avoid; }
}
