/* 全站公共顶栏组件（身份行）的样式
 * 为什么单独成文件：之前「退出/身份菜单」是**逐页打补丁**加上去的，
 * 结果重新生成某个页面就被盖掉（华哥 2026-09-25 报「退出怎么又没有了」）。
 * 改成公共资源后，任何页面只要 include 就一定有，构建脚本也不会丢。 */

/* 🔴 手机版**去掉双击缩放**（华哥 2026-09-25：两指/双击都会把页面放大，放大后得缩回来才能操作）。
   `manipulation` = 允许单指滚动、允许双指捏合，但**禁掉双击缩放**，顺带去掉 300ms 点击延迟。
   ⚠️ 它管不了**双指捏合**（那要靠 assets/erp-touch.js 拦 iOS 的 gesture 事件）—— 两层一起才完整。 */
/* ⚠️ **必须用 pan-x pan-y，不能用 manipulation**：
   `manipulation` = pan-x pan-y **pinch-zoom** —— 它是**允许捏合**的（只禁双击）！
   我们要禁捏合，就得显式只给 pan，不给 pinch-zoom。 */
html { touch-action: pan-x pan-y; }

/* 🔴 **手机版输入框一律 ≥16px**（华哥 2026-09-25 定）。
   原因不是好看 —— 是 **iOS 的固定行为：输入框字号 < 16px 时，你一点它，Safari 就自动把页面放大**
   （为了让你打字看得清）。这跟"禁缩放"是两回事，`maximum-scale=1` 压不住它，
   正好对上华哥说的「点击窗口的时候也能把页面放大」。
   ⚠️ 只限 `data-view="m"`：`users/stores/change-password` 是**一套两边共用**的单文件，
      在这里限定就不会把电脑版也改掉（电脑版保持它自己的 14px）。 */
html[data-view="m"] input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
html[data-view="m"] select,
html[data-view="m"] textarea {
  font-size: 16px !important;
}

/* 身份行**贴右**：导航药丸在左、身份行在右 —— 这条以前写在各页面里，
   验收入库那页漏了 → 身份行跑到导航药丸旁边（华哥 2026-09-25 红框指出来）。
   → 收进公共 CSS（同一条「公共组件只有一份」的规矩，D40）。 */
.nav-right { margin-left: auto; }

.nav-right .who-wrap { position: relative; display: inline-flex; }
.nav-right .who {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-body); font-size: 13px; font-weight: 600; color: var(--fg);
  background: #F4F1EE; border: 1px solid var(--border); border-radius: 999px;
  padding: 10px 14px; min-height: 44px; cursor: pointer; white-space: nowrap;
}
.nav-right .who:hover { border-color: var(--gold); background: #FBF3E2; }
.nav-right .who:disabled { cursor: default; opacity: 1; }
.nav-right .who-sep { color: #C6C0D2; font-weight: 400; }
.nav-right .who-caret { color: var(--muted); font-size: 11px; }

.who-menu {
  position: absolute; right: 0; top: calc(100% + 8px); min-width: 210px;
  background: #fff; border: 1px solid var(--border); border-radius: 14px;
  box-shadow: 0 18px 40px rgba(12, 9, 30, .18); padding: 8px; z-index: 80;
}
.who-menu-head {
  padding: 8px 10px 10px; border-bottom: 1px solid var(--border); margin-bottom: 6px;
  font-size: 12.5px; color: var(--muted); line-height: 1.6;
}
.who-menu-head b { display: block; color: var(--fg); font-size: 13.5px; font-weight: 700; }
.who-menu a, .who-menu button {
  display: block; width: 100%; text-align: left; box-sizing: border-box;
  padding: 10px; border: none; background: none; cursor: pointer;
  border-radius: 10px; font-family: var(--font-body);
  font-size: 13.5px; font-weight: 600; color: var(--accent); text-decoration: none;
}
.who-menu a:hover, .who-menu button:hover { background: #F4F1EE; }
.who-menu a.danger, .who-menu button.danger { color: #C74A41; }
.who-menu a.danger:hover, .who-menu button.danger:hover { background: #FBE3DF; }
.who-menu .menu-sub {
  padding: 6px 10px 2px; font-size: 11px; font-weight: 700; letter-spacing: .06em;
  color: #A8A2B8; text-transform: uppercase;
}
.who-menu button.store-opt { display: flex; justify-content: space-between; gap: 10px; }
.who-menu button.store-opt .now { color: var(--gold); font-weight: 800; }

/* 修改密码弹窗（公共） */
dialog.pwdialog { border: none; border-radius: 16px; padding: 0; width: min(420px, 92vw);
  box-shadow: 0 30px 70px rgba(20, 15, 45, .35); }
dialog.pwdialog::backdrop { background: rgba(24, 20, 45, .45); }
.pwd-head { padding: 20px 22px 4px; font-size: 17px; font-weight: 800; color: var(--fg); }
.pwd-body { padding: 8px 22px 4px; }
.pwd-body .mrow { margin-bottom: 12px; }
.pwd-body label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 6px; }
.pwd-body input { width: 100%; font-family: var(--font-body); font-size: 14px; padding: 11px 13px;
  border: 1.5px solid var(--border); border-radius: 11px; background: #FFFDFA; min-height: 44px; box-sizing: border-box; }
.pwd-foot { padding: 12px 22px 20px; display: flex; justify-content: flex-end; gap: 10px; }

/* ─────────────────────────────────────────────────────────────
   导航（原来**写死在各页**，样式也各写一套 → 必然不一致；
   现在导航由本组件按权限渲染，样式也归这里，所有页面共用一套）
   ───────────────────────────────────────────────────────────── */
.nav-band { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  background: var(--bg); border-bottom: 1px solid var(--border); padding: 12px 24px; }
.nav-pills { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* ⚠️ 基础态就给一条**透明边框**：选中态有 `border:1px solid var(--gold-lt)`，
   不给的话选中项会比未选中项**高 2px**、一排药丸底边不齐（2026-09-30 经营分析侧实测 66 vs 68）。 */
.nav-pill { font-family: var(--font-body); font-size: 14px; font-weight: 600; color: var(--muted);
  background: none; border: none; border-radius: 12px; padding: 11px 18px; min-height: 44px;
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer; text-decoration: none;
  white-space: nowrap; box-shadow: none; transition: background .15s, color .15s; }
.nav-pill svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; }
.nav-pill:hover { color: var(--accent); background: #F3EEE7; }
.nav-pill.active { background: linear-gradient(180deg, #FFFDF6, #FFFAEE); color: var(--accent);
  border: 1px solid var(--gold-lt); }
.nav-pill.active::before { content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--gold); box-shadow: 0 0 6px rgba(217, 164, 65, .8); }

/* 「更多」下拉 */
.nav-more-wrap { position: relative; }
.more-dropdown { position: absolute; left: 0; top: calc(100% + 8px); background: #fff;
  border: 1px solid var(--border); border-radius: 14px; box-shadow: 0 18px 40px rgba(12, 9, 30, .18);
  padding: 8px; min-width: 210px; z-index: 60; }
.more-sub { padding: 6px 12px 4px; font-size: 11px; font-weight: 700; letter-spacing: .06em;
  color: #A8A2B8; }
.more-item { display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 9px 12px; border-radius: 9px; font-size: 13.5px; color: var(--accent); text-decoration: none; }
.more-item:hover { background: var(--bg); }
.more-item.now { background: #FFFAEE; font-weight: 700; }
.more-item .soon { font-size: 11px; color: var(--muted); padding: 2px 8px; background: var(--na-bg);
  border-radius: 999px; white-space: nowrap; }

/* ─────────────────────────────────────────────────────────────
   🆕 子菜单（D49 · 华哥：「库存管理……要不在库存管理菜单项上加子菜单吧」）
   · 电脑版：一级项本身变成一个**带下拉的按钮**（照「更多」那套，视觉一致）
   · 两种视图：页面内容顶部一条**二级 tab 条**（`#subTabs`，由公共 JS 渲染）
   ⚠️ 这两处的样式**只有这一份**，页面里不许再写（D40）。
   ⚠️ 手机上二级 tab 的触控目标 ≥44px（M1 那条），所以给 min-height:44px。
   ───────────────────────────────────────────────────────────── */
.nav-sub-wrap { position: relative; display: inline-flex; }
.nav-sub-drop { position: absolute; left: 0; top: calc(100% + 8px); background: #fff;
  border: 1px solid var(--border); border-radius: 14px; box-shadow: 0 18px 40px rgba(12, 9, 30, .18);
  padding: 8px; min-width: 180px; z-index: 60; }
.nav-sub-item { display: block; padding: 9px 12px; border-radius: 9px; font-size: 13.5px;
  color: var(--accent); text-decoration: none; white-space: nowrap; }
.nav-sub-item:hover { background: var(--bg); }
.nav-sub-item.now { background: #FFFAEE; font-weight: 700; }

.subtabs { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  border-bottom: 1px solid var(--border); padding-bottom: 10px; margin-bottom: 16px; }
.subtab { font-family: var(--font-body); font-size: 13.5px; font-weight: 600; color: var(--muted);
  background: none; border: 1px solid transparent; border-radius: 11px; padding: 9px 14px;
  min-height: 44px; display: inline-flex; align-items: center; gap: 6px; text-decoration: none;
  white-space: nowrap; }
.subtab:hover { color: var(--accent); background: #F3EEE7; }
.subtab.active { background: #FFFAEE; color: var(--accent); border-color: var(--gold-lt); }
.subtab .n { font-size: 11.5px; color: var(--muted); font-weight: 700; }

/* 🆕 手机上筛选区的排法（华哥 2026-10-08 三轮调出来的形状）：
   · **搜索框独占一行**（`1 0 100%`）；
   · 其余筛选控件换行排，**能放几个放几个**（三个下拉排一行 = 现在这两页的样子）。
   为什么不是让搜索框跟下拉挤一行：华哥要的是「搜索框后面那三个放一行」——
   搜索框占整行、下面三个控件整整齐齐一行，看着最干净。
   ⚠️ 容器必须 `flex-wrap: wrap`（页面里写），否则搜索框会把后面的控件**挤成 0 宽**（实测踩过）。 */
html[data-view="m"] .toolbar.filters > input[type="search"] { flex: 1 0 100%; }
/* 🔴 手机版筛选区的选框**不许被压到看不见字**（2026-10-12 华哥截图：出入库记录那**四个选框全是空壳**，
   只剩一个箭头）—— 根因是 `.toolbar.filters select{flex:1;min-width:0}`：搜索框占住宽度后，
   四个选框各被压到 **30px**。现在给选框一个**看得见字的最小宽度**（104px）+ 按 30% 分摊：
   一行放 3 个，放不下的自动换行 → 加上搜索框正好**两行**。 */
html[data-view="m"] .toolbar.filters > select.filter { flex: 1 1 30%; min-width: 104px; }
/* 容器加了 `.inline-first` → 搜索框**与紧随其后的第一个控件同一行**（剩下的换行）。
   谁用它：控件一行排不下的页面（出入库记录有 4 个筛选），把最高频的「时间范围」提到搜索框旁边；
   控件一行排得下的（库存台账 3 个）就不加，让搜索框独占一行、三个控件整整齐齐一行。
   ⚠️ 两种情况都是**两行**，一条"筛选区最多两行"的墙管着。 */
html[data-view="m"] .toolbar.filters.inline-first > input[type="search"] { flex: 1 1 calc(100% - 116px); min-width: 0; }

/* 🆕 子菜单的**小抽屉**（D49 追加 · 手机）——
   华哥：「库存管理的逻辑与「更多」、「我的」一样，**但这里选项不是很多，面板不要太大**」
   → 用 `compact`：面板高度跟着内容走、上下留白收窄（「更多」那种是整屏高度的大抽屉）。 */
.sheet.compact { max-height: none; }
.sheet.compact .sheet-body { padding: 6px 10px 10px; }
.sheet.compact .sheet-item { min-height: 44px; display: flex; align-items: center; justify-content: space-between; }

/* 「未分线」提示里的小字（两条线都看不到它们，得说清楚） */
.hint, .delta { font-size: 11.5px; color: var(--muted); line-height: 1.7; margin-top: 6px; }
html[data-view="pc"] .hint, html[data-view="pc"] .delta { font-size: 12.5px; }

/* 门店下拉（多门店时，门店本身可点开切换）*/
.nav-right .who.static { cursor: default; }
.store-menu { min-width: 190px; }
.store-menu .store-tip { padding: 8px 10px 4px; font-size: 11.5px; color: var(--muted); line-height: 1.6;
  border-top: 1px solid var(--border); margin-top: 6px; }

/* ─────────────────────────────────────────────────────────────
   表格：横向滚动时**第一列吸住** + 表头吸顶
   做法**参照已上线的验收入库模块**（`入库开发`，店里真在手机上用）：
   不把表格改成卡片，而是让"这行是谁"始终钉在左边 ——
   窄屏左右滑到后面的列时，不会看错行。
   ⚠️ 必须 `border-collapse: separate`：collapse 下 sticky 单元格的边框会错乱
      （所以三处页面样式里的 border-collapse 都去掉了，只在这里定义一处）。
   ───────────────────────────────────────────────────────────── */
table.perm, table.users, table.grid { border-collapse: separate; border-spacing: 0; }

/* 表头吸顶 */
table.perm thead th, table.users thead th, table.grid thead th {
  position: sticky; top: 0; z-index: 3;
}
/* 第一列吸左
   ⚠️ 底色**只能设在 td 上**！给 th 也设白底的话，会**把表头自己的深色底覆盖掉** →
   表头第一格变成白字白底、**整个看不见**（实测踩到：桌面截图里「用户」那一列的表头消失了）。 */
table.perm  td:first-child,
table.users td:first-child,
table.grid  td:first-child {
  position: sticky; left: 0; z-index: 2;
  background: var(--surface, #fff);
  box-shadow: 1px 0 0 #F0ECEF;   /* 一道细线，暗示"这列是钉住的" */
}
/* 表头第一列：只吸住 + 压在所有人上面，**不动它的底色** */
table.perm  thead th:first-child,
table.users thead th:first-child,
table.grid  thead th:first-child {
  position: sticky; left: 0; z-index: 4;
}
/* 鼠标悬停整行高亮时，钉住的那格也要跟着变，否则看着像"半截高亮" */
table.perm tbody tr:hover td:first-child,
table.users tbody tr:hover td:first-child { background: #FBF6F1; }

/* ⚠️ 光是"钉住"不够 —— 第一列本身太宽的话，钉住它会把整个手机屏占满（等于白钉）。
   所以窄屏要**把第一列窄化 + 省略号**，让出空间给后面的列。
   （同 `入库开发` 的 .c-name{max-width:150px;overflow:hidden;text-overflow:ellipsis} 做法）*/
@media (max-width: 820px) {
  /* ⚠️ 别指望在 td 上写 max-width：table-layout:auto 时**浏览器会忽略单元格的 max-width**
     （实测第一列仍是 213px，几乎占满手机屏）→ 得在单元格里**套一层 span** 来截断，
     这也是 `入库开发` 的 .c-name 用的办法。 */
  .cell-clip {
    display: inline-block; max-width: 150px; overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; text-align: left;
  }
  /* 手机上看权限代码没用（那是给开发看的），隐藏掉，把宽度让给角色列 */
  table.perm td:first-child .mono { display: none; }

  /* 用户列表第一列是 flex（头像 + 名字/账号）→ 直接约束里面那块文字，让它省略号收尾 */
  .user-cell > div { max-width: 118px; min-width: 0; }
  .u-name, .u-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* 模块分组行是整行 colspan 的分隔条 → 不参与吸住，跟着滚更自然 */
  table.perm tr.mod-row td:first-child { position: static; }
  /* 分组行的底色要盖住（它 position:static 了，不受 sticky 底色影响） */
  table.perm tr.mod-row td { background: #F7F4FA; }
}

/* ─────────────────────────────────────────────────────────────
   ★ 手机版外观（D37）—— **按"服务端给的版本"切换，不按屏幕宽度**

   华哥 2026-09-25 定的：「重心还是以手机为主」「复杂一点的页面干脆还是做两套」。
   所以判断权在**服务端**（`src/view.js`：UA / cookie / ?view=），结果写进 `<html data-view="m|pc">`，
   前端只认这个属性 —— **前端不许再按宽度猜第二遍**（两处判断打架是这类改动最容易埋的雷：
   平板 900px 能是手机版，电脑窄窗口 500px 还是电脑版，宽度根本不等于版本）。

   这里只管"**模式**"（底栏还是导航带、顶栏怎么排）；
   纯粹的"窄屏微调"（表格 min-width、弹窗贴底）仍然用 `@media` —— 那种场景宽度本来就是对的依据。
   ───────────────────────────────────────────────────────────── */
.tabbar { display: none; }   /* 默认不显示；只有手机版才显示 */

html[data-view="m"] .nav-band { display: none !important; }
/* 手机版：**整条导航带不出现** —— 横向导航进底栏、门店/姓名/角色进「我的」抽屉
   （华哥 2026-09-25：「既然有我的了，页面上的门店/姓名/角色，这个东西可以不要了，排版也好看一点」） */

html[data-view="m"] .tabbar {
  display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
  background: #fff; border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom, 0);
  box-shadow: 0 -6px 20px rgba(43, 42, 84, .07);
}
html[data-view="m"] .tabbar-item {
  flex: 1 1 0; min-width: 0; min-height: 56px;              /* 触控目标 ≥44px */
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  background: none; border: none; cursor: pointer; padding: 8px 4px;
  font-family: var(--font-body); font-size: 11.5px; font-weight: 600; color: var(--muted);
}
html[data-view="m"] .tabbar-item svg { width: 22px; height: 22px; stroke: currentColor; fill: none;
  stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
html[data-view="m"] .tabbar-item span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
html[data-view="m"] .tabbar-item.active { color: var(--accent); }
html[data-view="m"] .tabbar-item.active svg { stroke-width: 2.3; }

/* 给底栏让位置，最后一块内容不被盖住 */
/* ⚠️ 只在**真的有底栏**时才给 body 留位（公共组件建了底栏会加 `has-tabbar`）。
   登录页这类没有底栏的页面引了公共 CSS 也不会凭空多出 64px 空白。 */
html[data-view="m"] body.has-tabbar { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }

/* 🔴 底栏要**一直贴到最底**（华哥 2026-09-25 真机截图：底栏白条下面还露一条奶油色）。
   原因：手机上「可视底」比「布局视口底」更靠下（底部工具栏 / Home 指示条那一块），
   而 `position: fixed; bottom: 0` 只到**布局视口**底 —— 底下那条就归**画布**管（html 的背景）。
   解法：给画布铺白（跟底栏同色），纸上就看不出来接缝了；body 照样是奶油色，页面不受影响。
   ⚠️ 只在**真有底栏**的页面这么干（公共组件会给 html 加 `has-tabbar`）—— 登录页那种没底栏的不动。 */
/* 画布（html）铺**白**：短页面时 body 盒子比"可视底"短，底栏下面那条归画布管 —— 铺白才跟底栏连成一片。
   （body 自己的底色仍是奶油色，页面看着不变。） */
html.has-tabbar { background: #fff; }
html.has-tabbar body { min-height: 100dvh; }
/* 真正管用的是这一条：把 body 的**最后一条**铺成白色（高度 = 底栏 + 安全区 + 余量）。
   正情况下这条被固定底栏盖住、看不见；一旦因为浏览器底部工具栏露出来，它就跟底栏连成一片。 */
html[data-view="m"] body.has-tabbar {
  background-image: linear-gradient(to bottom,
    rgba(0,0,0,0) 0, rgba(0,0,0,0) calc(100% - 96px - env(safe-area-inset-bottom, 0px)),
    #fff calc(100% - 96px - env(safe-area-inset-bottom, 0px)));
  background-repeat: no-repeat;
}
@media (max-width: 820px) { .nav-right { margin-left: 0; width: 100%; } }

/* ═══════════════════════════════════════════════════════════════════════
   顶栏（HERO）—— **全站唯一定义处**（2026-09-25 华哥：
   「你每个页面的顶栏用的不是同一份吗？每个页面都要改吗？……尽量用一处同样的顶栏，
    一处改处处改（其他地方也检测一下有没有类似的问题）」）

   🔴 **规矩：页面里一条 `.hero` / `.lockup-*` 样式都不许写** ——
      包括以前那种页面底部 `<style id="od-topbar-v16">` 的内联 `!important` 覆盖（已全部删掉）。
      顶栏长什么样**只在这个文件里定**；改这里，**所有页面一起变**。

   🔴 **为什么定这条**：2026-09-25 实测（`archive/过程物/量-顶栏一致性.js`）——
      同一套"顶栏"在 7 个页面里量出 **4 种结果**：
        · 标题 18 / 22 / 30px       · logo 62 / 72 / 84px
        · 背景 1 层 / 6 层 / 12 层  · 门店与仓库还是衬线 Didot、颜色也不对
      而且每个页面各带一段 `!important` 互相盖 → 必然对不上（华哥在真机上就是这么看出来的）。

   🛡 **两道守卫（都会红）**：
      ① 静态：`test:mobile-ui` 扫页面，**发现页面自己写顶栏样式就报错**；
      ② 实测：`test:mobile-ui` 真浏览器量每个页面/两种视图的顶栏，**量出来的值必须一模一样**。
   ═══════════════════════════════════════════════════════════════════════ */

/* ───── 桌面版（基准值 · 照 v1.6 精确规范：非衬线 800 / 22px / 金 #EFC77C / 口号 #F6DDE3）───── */
.hero{position:relative;color:#fff;padding:32px 44px 34px;border-radius:0;box-shadow:none;
  background:linear-gradient(120deg,#2B2A5E,#4A3C8C);background-color:#2B2A5E;}
.hero::after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;
  background:linear-gradient(90deg,rgba(239,199,124,0),var(--gold,#D9A441) 30%,var(--gold,#D9A441) 70%,rgba(239,199,124,0));}
/* 顶栏第二层：`.hero::before` 那 4 层（抄原型时漏过一回，华哥看出来"没有渐变"）。
   第 4 层是**右上角的金色柔光**（`circle at 88% -14%`）—— 少了它，顶栏右半边就是死板的深紫。 */
.hero::before{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;background:
  radial-gradient(1.5px 1.5px at 12% 30%,rgba(255,255,255,.55),transparent 60%),
  radial-gradient(1.3px 1.3px at 32% 70%,rgba(255,255,255,.4),transparent 60%),
  radial-gradient(1.4px 1.4px at 80% 22%,rgba(239,199,124,.7),transparent 60%),
  radial-gradient(circle at 88% -14%,rgba(239,199,124,.28),transparent 55%);}
.hero > *{position:relative;z-index:1;}
.hero-lockup{display:flex;align-items:center;gap:20px;position:relative;z-index:1;}
.hero-logo{width:72px;height:auto;flex-shrink:0;object-fit:contain;filter:drop-shadow(0 5px 10px rgba(0,0,0,.35));}
.lockup-text{flex:1;min-width:0;}
.lockup-title{font-family:var(--font-body);font-weight:800;color:#fff;font-size:22px;line-height:1.28;
  letter-spacing:.02em;margin:0;white-space:nowrap;}
.lockup-brand{font-family:var(--font-body);font-weight:800;color:#EFC77C;font-size:11.5px;
  letter-spacing:.15em;margin:6px 0 0;white-space:nowrap;}
.lockup-slogan{color:#F6DDE3;font-size:11.5px;font-style:italic;margin:6px 0 0 60px;letter-spacing:.03em;white-space:nowrap;}

/* ───── 手机版（基准版 · M1）：吸顶 + 让出顶部安全区 + 星空更密 + 字号小一号 ─────
   ⚠️ 顶栏上边距**只由这一处控制** —— 页面里不许再加（登录页曾自己加 26px →
      两个页面差 22px：工作台离灵动岛 29px、登录页只有 7px，华哥一眼看出来）。
      用 max() 而不是"14px + env"：有刘海正好停在安全区下沿；没刘海 env=0，退到 12px 不贴死。
   ⚠️ 手机上**整条顶栏是吸顶的**（工作台那套），各页不许再分叉。 */
html[data-view="m"] .hero{position:sticky;top:0;z-index:50;
  padding:max(12px, env(safe-area-inset-top, 0px)) 16px 12px 10px;
  box-shadow:0 8px 20px rgba(43,42,84,.22);
  background:
    radial-gradient(1.4px 1.4px at 9% 34%,rgba(255,255,255,.85) 45%,transparent 56%),
    radial-gradient(1px 1px at 20% 68%,rgba(255,255,255,.5) 45%,transparent 56%),
    radial-gradient(1.8px 1.8px at 31% 26%,rgba(239,199,124,.9) 45%,transparent 56%),
    radial-gradient(1.3px 1.3px at 43% 54%,rgba(255,255,255,.7) 45%,transparent 56%),
    radial-gradient(1px 1px at 56% 30%,rgba(255,255,255,.5) 45%,transparent 56%),
    radial-gradient(2px 2px at 65% 66%,rgba(239,199,124,.85) 45%,transparent 56%),
    radial-gradient(1.1px 1.1px at 75% 38%,rgba(255,255,255,.6) 45%,transparent 56%),
    radial-gradient(1.3px 1.3px at 85% 72%,rgba(255,255,255,.55) 45%,transparent 56%),
    radial-gradient(1px 1px at 92% 24%,rgba(255,255,255,.5) 45%,transparent 56%),
    radial-gradient(1.2px 1.2px at 97% 54%,rgba(255,255,255,.55) 45%,transparent 56%),
    radial-gradient(140% 95% at 28% -5%,rgba(93,73,168,.5),transparent 58%),
    linear-gradient(120deg,#2B2A5E,#4A3C8C);
  background-color:#2B2A5E;}
html[data-view="m"] .hero .hero-lockup{gap:14px;}
html[data-view="m"] .hero .hero-lockup .hero-logo{width:62px;height:62px;}
html[data-view="m"] .hero .lockup-text{min-width:0;}
html[data-view="m"] .hero .lockup-text .lockup-title{white-space:nowrap;font-size:18px;line-height:1.28;}
html[data-view="m"] .hero .lockup-text .lockup-brand{font-size:11.5px;letter-spacing:.13em;margin:6px 0 0;}
html[data-view="m"] .hero .lockup-text .lockup-slogan{display:block;font-size:11px;margin:6px 0 0 46px;}

/* 登录页那种**大 splash**（logo 居中那张，没有 lockup）：底部要留出「卡片压上来」的空间
   （定稿原型 70px）；上面那条通用规则会把底部压成 12px → 卡片会切到标语那行。 */
html[data-view="m"] .hero.hero-splash{
  position:relative; padding-bottom:70px;
  /* 🔴 **splash 不许压住登录卡片**（2026-09-25 华哥红框：卡片顶上被顶栏盖了一条）。
     原因：上面那条通用规则给顶栏加了 `z-index:50`（工作台那种**吸顶**顶栏需要它），
     而登录卡片是 `z-index:2` 的定位元素 → 顶栏把它盖住了（实测：卡片顶边被盖住 46px，
     elementFromPoint 在卡片顶部取到的是 hero）。
     splash 是**不吸顶**的（position:relative），不需要那个 z-index，也不需要那层投影。 */
  z-index:auto; box-shadow:none;
}

/* ───── 手机版的"壳"与底色（一处管全部页面）─────
   桌面：白色圆角大外框（`.frame`；验收入库那页是它自己的 `#phone`）——留着好看。
   手机：**一律贴边、直角、无阴影**，底色跟工作台一样是奶油色。
   ⚠️ 2026-09-25 华哥真机反馈「页面划到最下面透了深蓝色背景出来」——
      根因就是这里：`#phone` 没被这条规则管到（只写了 `.frame`），
      于是它仍带 `margin:28px` + `border-radius:28px`，卡片比屏幕短 → 底下露出 body 的深蓝。
      顺带那 28px 圆角也把**顶栏的圆角**带出来了（他截图里看到的那两条圆角就是它）。
   ⚠️ `overflow:visible` 是给吸顶用的：外框带 `overflow:hidden` 时，里面的 sticky 顶栏会失效。 */
/* 🔴 **外壳给一个最小高度**（2026-09-25 华哥：验收入库电脑版"页面高度太少，不好看"）——
   内容少的页面，白色外框只有半截，底下空一大片深色底，跟其它页面对不上。
   做法：外框至少撑到「视口高 - 上下外边距」，看不见内容也是同一种"一张大白纸"的观感。
   ⚠️ 桌面外边距 28+28=56；手机没有外边距（贴边）→ 100dvh。
   ⚠️ 只写 min-height：内容高的页面（工作台/用户管理）完全不受影响。 */
/* 🆕 **电脑版外壳的宽度/圆角/阴影也在这一处**（2026-10-07 收进来的）——
   原来 `pc/index.html` · `pc/stock.html` · `users.html` · `stores.html` **四页各写一份**（一字不差），
   新页面（货品档案）只写了 `class="frame"` 没有这条 → 外壳**撑满整屏 1440**，别的页都是 1280 居中
   —— 华哥一句「电脑版的 body 大小跟其他页面好像不一样」就是这个。
   ⚠️ 只在**电脑版**生效：手机版那几条（贴边/去圆角/奶油底）写在下面，权重更高、后写。 */
html[data-view="pc"] .frame {
  width: min(1280px, 100%); margin: 28px auto; background: var(--surface);
  border-radius: 28px; overflow: hidden; box-shadow: var(--shadow-lg);
}

@media (min-width: 821px) {
  /* ⚠️ 选择器要**比页面里那份更高权重**：验收入库的 `#phone{min-height:0}` 写在页面自己的 <style> 里、
     又在公共 CSS 之后 → 同权重它赢（实测：加了这条外壳还是 611px 高）。`html body …` 刚好压住。 */
  html body .frame, html body .phone, html body #phone { min-height: calc(100dvh - 56px); }
}
html[data-view="m"] .frame,
html[data-view="m"] .phone,
html[data-view="m"] #phone { min-height: 100dvh; }

/* 电脑版：外面那圈**深色底衬**（白纸浮在深底上）—— 原来 6 个页面各写一份同样的渐变。
   手机版不用它（手机是奶油底，见下一条）。 */
html[data-view="pc"] body{background:radial-gradient(120% 90% at 50% -10%,#232046 0%,#16112b 58%);}
html[data-view="m"] body{background:var(--bg, #FBF4EE);}
html[data-view="m"] .frame,
html[data-view="m"] .phone,
html[data-view="m"] #phone{width:100%;max-width:100%;margin:0;border-radius:0;box-shadow:none;
  overflow:visible;background:var(--bg, #FBF4EE);}
/* （最小高度在下面那条"外壳给一个最小高度"里统一给，别在这里写两处） */
/* 模块① 搬过来的那层 `.topbar` 原来自己带 `border-radius:20px 20px 0 0` —— 也会在顶栏上显出圆角 */
html[data-view="m"] .topbar{border-radius:0;background:var(--bg, #FBF4EE);}

@media (max-width: 820px) {
  /* 页头（标题 + 右侧按钮）在窄屏竖排，别挤成一行 */
  .page-head { flex-direction: column; align-items: stretch; gap: 12px; }
  .page-head .head-actions { justify-content: flex-end; }

  /* ⚠️ 表格必须给 min-width，否则浏览器为了塞进屏幕会把列**压瘪** ——
     实测门店表的「简称」列被挤成**竖排一个字一行**、编辑/停用按钮被压成 13px 宽。
     给了 min-width 之后是**横向滚动**（配第一列吸住），列宽才正常。
     （users/perm 两张表本来就有 min-width，漏的是 stores 的 table.grid） */
  table.grid { min-width: 720px; }
  table.users { min-width: 760px; }
  table.perm { min-width: 640px; }
  table.grid td, table.grid th { white-space: nowrap; }
  /* 操作列里的「编辑 · 停用」别换行、被挤成竖排 */
  table.grid td button.link, table.grid td .link { white-space: nowrap; }

  /* 表格里的操作链接（编辑/停用/删除）在手机上只有 27×19，太小点不准 → 撑到 ≥44px */
  table.users td a[data-act], table.grid td button.link, table.grid td .link {
    display: inline-flex; align-items: center; min-height: 44px; padding: 0 7px; margin: 0 -3px;
  }
  /* 权限矩阵的勾选框 18 → 24px（矩阵以电脑为主，但手机上至少点得准） */
  .perm td input[type=checkbox] { width: 24px; height: 24px; }

  /* 权限矩阵底部的「保存权限」按钮别被压瘪（实测手机上被挤成竖排 保/存/权/限）。
     原因：它在一个 `overflow-x:auto` 的滚动容器里，block 子元素宽度只有**屏宽**（352px），
     旁边那段提示文字把按钮挤到最小宽度 → 文字竖着排。
     做法：按钮不参与收缩 + 文字不换行；提示文字在窄屏独占一行。 */
  .perm-wrap .btn { flex: none; white-space: nowrap; }
  .perm-wrap > div { flex-wrap: wrap; row-gap: 8px; }
  .perm-wrap .panel-sub { flex: 1 1 100%; margin: 0 !important; }

  /* 弹窗：手机上接近全屏（窄屏下浮层做得太小反而难点） */
  dialog.modal, dialog.pwdialog { width: 100vw !important; max-width: 100vw !important;
    margin: 0 !important; border-radius: 16px 16px 0 0 !important;
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; max-height: 92vh; }
  .modal-body { max-height: none; }
}

/* ── 底部抽屉（手机上的「更多」/「我的」）── */
.sheet-mask {
  position: fixed; inset: 0; z-index: 200; background: rgba(24, 20, 45, .42);
  opacity: 0; pointer-events: none; transition: opacity .18s;
  display: flex; align-items: flex-end;
}
.sheet-mask.show { opacity: 1; pointer-events: auto; }
.sheet {
  width: 100%; background: #fff; border-radius: 18px 18px 0 0;
  padding-bottom: env(safe-area-inset-bottom, 0);
  box-shadow: 0 -18px 44px rgba(20, 14, 50, .28);
  transform: translateY(14px); transition: transform .18s;
  max-height: 78vh; overflow: auto;
}
.sheet-mask.show .sheet { transform: translateY(0); }
.sheet-head {
  padding: 16px 18px 10px; font-size: 15px; font-weight: 800; color: var(--fg);
  border-bottom: 1px solid var(--border); cursor: pointer;
}
.sheet-head::after { content: "关闭"; float: right; font-size: 12px; font-weight: 600; color: var(--muted); }
.sheet-body { padding: 8px 10px 14px; }
.sheet-sub { padding: 10px 12px 4px; font-size: 11.5px; font-weight: 700; letter-spacing: .06em; color: #A8A2B8; }
.sheet-item {
  display: flex; width: 100%; box-sizing: border-box; align-items: center; justify-content: space-between; gap: 10px;
  padding: 14px 12px; min-height: 52px;                             /* 触控目标 ≥44px */
  border: none; background: none; border-radius: 12px; cursor: pointer;
  font-family: var(--font-body); font-size: 14.5px; font-weight: 600; color: var(--accent); text-decoration: none;
}
.sheet-item:hover, .sheet-item:active { background: #F4F1EE; }
.sheet-item.now { background: #FFFAEE; }
.sheet-item.danger { color: #C74A41; }
.sheet-item .now { color: var(--gold); font-weight: 800; font-size: 12px; }
.sheet-item .soon { font-size: 11px; color: var(--muted); padding: 2px 8px; background: var(--na-bg); border-radius: 999px; }
.sheet-id { padding: 12px 12px 6px; }
.sheet-id b { display: block; font-size: 15px; color: var(--fg); }
.sheet-id span { font-size: 12.5px; color: var(--muted); }

/* ═══════════════════════════════════════════════════════════════════════
   按钮（BTN）与提示条（TOAST）—— **全站唯一定义处**（2026-09-25 华哥：
   「尽量用一处同样的顶栏，一处改处处改（**其他地方也检测一下有没有类似的问题**）」）

   实测（`archive/过程物/量-组件一致性.js`）：**按钮在 6 个页面里量出 3 种、提示条 2~3 种** ——
   门店与仓库的按钮是「11px 圆角 / 44px 高」，其余页是「13px / 48px」；
   退出提示条的底色/圆角/位置也各写一份。
   → 现在同样**只在这里定一份**：页面里不许再写 `.btn*` / `.toast*`
     （页面可以用**父级限定**的布局修饰，如 `.import-actions .btn{flex:1}`、`.btn-block`，那不算重定义）。
   守卫：`test:wiring` 静态查页面有没有自己写；要改外观改这里。
   ═══════════════════════════════════════════════════════════════════════ */

.btn{font-family:var(--font-body);font-size:14px;font-weight:700;border:none;border-radius:13px;min-height:48px;
  padding:12px 18px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:8px;
  letter-spacing:.2px;text-decoration:none;transition:background .15s,box-shadow .15s,transform .05s;}
.btn:active{transform:translateY(1px);}
.btn[disabled]{background:#E4E0E8;color:#a49aac;cursor:not-allowed;box-shadow:none;}
.btn-primary{background:var(--accent,#2B2A5E);color:#fff;box-shadow:0 6px 14px rgba(43,42,84,.26);}
.btn-primary:hover{background:var(--accent-hover,#3a3870);}
.btn-secondary{background:var(--accent-2,#4A3C8C);color:#fff;box-shadow:0 6px 14px rgba(74,60,140,.26);}
.btn-secondary:hover{background:var(--accent-2-hover,#5b4aa8);}
.btn-gold{background:linear-gradient(140deg,var(--gold,#D9A441),#caa03a);color:#fff;box-shadow:0 6px 14px rgba(217,164,65,.3);}
.btn-gold:hover{background:linear-gradient(140deg,#e2b455,var(--gold,#D9A441));}
.btn-ghost{background:#F4F1EE;color:var(--accent,#2B2A5E);border:1px solid #E3DEC8;box-shadow:none;}
.btn-ghost:hover{background:var(--gold-soft,#FBF3E2);border-color:var(--gold-lt,#EFC77C);}
.btn-ghost-sm{background:#F4F1EE;color:var(--fg,#2B2B45);border:1px solid var(--border,#E6E1EA);min-height:44px;
  padding:10px 14px;font-size:13px;border-radius:11px;font-weight:600;}
.btn-ghost-sm:hover{background:var(--gold-soft,#FBF3E2);border-color:var(--gold-lt,#EFC77C);}
.btn-block{width:100%;}
/* 大号按钮（登录页那一个，原型钉：高 52px / 字号 15px）—— 原来写在 login.html 里，
   挪到这里之后它就跟其它按钮同一份来源；页面用 `class="btn btn-primary btn-lg btn-block"` 取用。 */
.btn-lg{font-size:15px;border-radius:14px;min-height:52px;padding:14px 20px;letter-spacing:.3px;}

.toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(90px);background:#332f5c;color:#fff;
  font-size:13.5px;font-weight:600;padding:13px 22px;border-radius:14px;box-shadow:0 10px 28px -4px rgba(20,14,50,.35);
  opacity:0;pointer-events:none;transition:transform .3s,opacity .3s;z-index:99;max-width:min(92vw,520px);
  text-align:center;line-height:1.45;white-space:normal;}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
.toast.err{background:#c23a30;}
/* 手机上要**让开底部 Tab**（否则提示条压在底栏上，看不清） */
html[data-view="m"] .toast{bottom:calc(84px + env(safe-area-inset-bottom, 0px));font-size:13px;padding:12px 20px;}

/* ═══════════════════════════════════════════════════════════════════════
   卡片（CARD）—— **全站唯一定义处**（2026-09-25 华哥：「.card 的问题统一点好吧，
   **能统一的东西，全站都要统一点，不要一个页面一个样式**」）

   实测（`archive/过程物/量-四条.js`）改之前：**工作台 18px 圆角 + 内边距 14/12/12、门店 16px、
   其余 20px；内边距还有 0 / 18 / 20 / 20-24 四种**。
   → 现在只有这一份：**圆角 20 · 内边距 20 · 边 rgba(230,225,234,.6) · 阴影 --shadow**；
     表格/列表那类"里面自己带内边距"的用 `.card.pad0`（内边距 0）。
   页面里**不许再写** `.card`（`test:wiring` 静态查 + `test:mobile-ui` 逐页量，值必须一致）。
   ═══════════════════════════════════════════════════════════════════════ */
.card {
  background: var(--surface, #fff);
  border: 1px solid rgba(230, 225, 234, .6);
  border-radius: 20px;
  box-shadow: var(--shadow, 0 6px 18px rgba(43, 42, 84, .07), 0 2px 6px rgba(43, 42, 84, .05));
  padding: 20px;
}
.card.pad0 { padding: 0; overflow: hidden; }

/* ═══════════════════════════════════════════════════════════════════════════
   工具条控件（搜索框 / 下拉筛选）—— **全站唯一定义处**（2026-10-07 收进来的）

   为什么收（华哥 2026-10-07）：「电脑版的 body 大小跟其他页面好像不一样，**搜索框、下拉列表与之前的也不统一，不好看**」。
   实测（`archive/过程物/量-电脑版外壳.js`）货品档案那一页：搜索框 **21px 高 / 圆角 0**、下拉框 **19px / 圆角 0**
   —— 因为这两样的样式分别只写在**库存管理页**和**用户管理页**里，新页面引了类名却没样式 → 掉回浏览器默认控件。
   值**逐字抄自那两页**（观感不变）：搜索框抄库存管理页、下拉框抄用户管理页。
   ⚠️ 手机上仍然是公共的 `html[data-view="m"] … { font-size:16px !important }` 说了算（iOS 输入框 <16px 会自己放大）。
   ═══════════════════════════════════════════════════════════════════════ */
input[type=search] {
  font-family: var(--font-body); font-size: 14px; color: var(--fg);
  padding: 11px 14px; min-width: 220px; min-height: 48px;
  border: 1px solid var(--border); border-radius: 12px; background: #fff;
}
select.filter {
  font-family: var(--font-body); font-size: 13.5px; font-weight: 600; color: var(--fg);
  background: #F4F1EE; border: 1px solid var(--border); border-radius: 12px;
  padding: 10px 14px; min-height: 48px; cursor: pointer;
}
/* 🆕 手机上**把三四个下拉挤进一两行**（华哥 2026-10-08：「三行了，不够紧凑」）：
   ① 控件左右内边距 10 → 8px；② 筛选区间距 8 → 6px。
   ⚠️ 不能靠调字号解决 —— 手机上 `select` 被上面那条 16px 规则**强制**成 16px（iOS 点一下不放大页面），
      所以只能在"内边距/间距"上省；高度（48px 触控）一点不动。 */
html[data-view="m"] select.filter { padding-left: 8px; padding-right: 8px; }
html[data-view="m"] .toolbar.filters { gap: 6px; }
/* 宽表格的横向滚动容器 —— 少了它表格会把**外壳撑宽**（实测：货品档案的外壳被撑到 1440，别的页都是 1280） */
.table-wrap { overflow-x: auto; }

/* ═══════════════════════════════════════════════════════════════════════════
   对话框（MODAL）—— **全站唯一定义处**（2026-10-07 从 users.html 收进来的）

   为什么收进来（D40 同一条规矩：「能统一的东西全站统一点」）：
     `dialog.modal` / `.modal-head` / `.modal-body` / `.modal-foot` / `.mrow` 原来只写在**用户管理页**里，
     货品档案这一版也要用同样的弹窗表单 → 不收进来就是**第 2、第 3 份拷贝**，改一次要改几处。
     值**逐字抄自 users.html**，观感不变（用户管理页那份已删除）。
   ⚠️ 手机上「贴底全屏」那条 `@media` 在下面（原本就有，管 `.modal` + `.pwdialog`）。
   ═══════════════════════════════════════════════════════════════════════ */
dialog.modal{border:none;border-radius:18px;padding:0;width:min(520px,92vw);box-shadow:0 30px 70px rgba(20,15,45,.35);}
dialog.modal::backdrop{background:rgba(24,20,45,.45);}
.modal-head{padding:20px 22px 6px;font-size:17px;font-weight:800;color:var(--fg);}
.modal-body{padding:6px 22px 4px;max-height:60vh;overflow:auto;}
.modal-foot{padding:14px 22px 20px;display:flex;justify-content:flex-end;gap:10px;}
.mrow{margin-bottom:14px;}
.mrow label{display:block;font-size:13px;font-weight:600;margin-bottom:6px;color:var(--fg);}
.mrow input[type=text],.mrow input[type=number],.mrow input[type=password],.mrow select{
  width:100%;font-family:var(--font-body);font-size:14px;
  padding:11px 13px;border:1.5px solid var(--border);border-radius:11px;background:#FFFDFA;min-height:44px;}
/* 只读信息行（编辑弹窗顶部显示"在改哪个货品"） */
.ro-name{font-size:14.5px;font-weight:700;color:var(--fg);line-height:1.4;}
.ro-sub{font-size:11.5px;color:var(--muted);margin-top:4px;font-variant-numeric:tabular-nums;}

/* ═══════════════════════════════════════════════════════════════════════════
   基础层（token / 重置 / 骨架 / 内容组件）—— **全站唯一定义处**

   为什么补这一层（2026-09-30 · 经营分析工作区提的问题清单 `给ERP侧的问题清单-20260930.md`）：
     `erp-chrome.css` 以前**只消费、从不定义** token 与重置 —— 这两层在 ERP 里是**每个页面各写一份**
     （实测 **10 个页面 = 10 份 `:root{}`**，而且**彼此不完全一样**：`index.html`/`stock.html` 连 `--shadow` 都没有）。
     后果：**任何一个新页面只引这份 CSS 就会 `var(--fg)` 全 undefined → 退回浏览器默认衬线字体**。
     这与 `DESIGN.md §5.1` + `决策日志 D40`「能统一的东西全站统一」是同一件事 —— 顶栏收回了，**变量没收**。

   🔴 规矩（同 D40）：**页面里不许再写 `:root{}`（token）、重置行（`*{box-sizing}` / `html,body{margin}` /
      `body{font-family:var(--font-body)…}`）、`.content` / `.page-head` / `.head-actions` / `.card-head`**；
      要改就改这里。守卫：`npm run test:wiring`（静态）+ `npm run test:mobile-ui`（真浏览器量 token 与组件）。
   ⚠️ 值**全部逐字抄自现有页面**（不是新设计的），只做"合并去重"，不改任何现有观感。
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── A. token 层（32 个；值是 10 个页面并集，实测**无冲突**）── */
:root{
  --bg:#FBF4EE; --surface:#FFFFFF; --fg:#2B2B45; --muted:#8A8FA0; --border:#E6E1EA;
  --accent:#2B2A5E; --accent-2:#4A3C8C; --gold:#D9A441; --gold-lt:#EFC77C; --blush:#F6DDE3;
  --gold-soft:oklch(0.94 0.045 87.4);
  --accent-hover:oklch(0.377 0.090 280.8); --accent-2-hover:oklch(0.475 0.128 287.5);
  --gold-hover:oklch(0.811 0.130 79.8);
  --ok:#2E9E63; --ok-bg:#E3F3E9; --ok-tx:#227B4D;
  --warn:#B98312; --warn-bg:#FBEED0; --warn-tx:#916612;
  --bad:#C74A41; --bad-bg:#FBE3DF; --bad-tx:#A83A32;
  --na:#8A93A6; --na-bg:#ECEDF1; --na-tx:#5d6678;
  --shadow:0 6px 18px rgba(43,42,84,.07),0 2px 6px rgba(43,42,84,.05);
  --shadow-sm:0 2px 8px rgba(43,42,84,.06);
  --shadow-lg:0 34px 80px rgba(0,0,0,.42);
  --font-display:"Didot","Songti SC","Noto Serif SC",Georgia,serif;
  --font-body:-apple-system,"PingFang SC","Noto Sans SC","Helvetica Neue","Microsoft YaHei",sans-serif;
  --font-mono:ui-monospace,"SF Mono","Roboto Mono",Menlo,monospace;
  /* 排印尺度：以前**只有组件级固定值**（顶栏 22/18px、卡片 20px…），内容组件没有可用的字号刻度 */
  --fs-kpi:26px;    /* 大数字（KPI） */
  --fs-h2:17px;     /* 区块标题（= .section-title） */
  --fs-body:13.5px; /* 正文 */
  --fs-cap:11.5px;  /* 辅助小字 */
}

/* ── B. 重置层 ── */
*,*::before,*::after{box-sizing:border-box;-webkit-tap-highlight-color:transparent;}
html,body{margin:0;padding:0;}
body{
  font-family:var(--font-body);color:var(--fg);background:var(--bg);
  -webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;
}
:focus-visible{outline:2px solid var(--gold);outline-offset:2px;border-radius:6px;}
a{color:inherit;}
img{max-width:100%;}
/* 长内容不撑破容器（报表里数字/长单号常见） */
.num,.stat-val{overflow-wrap:anywhere;}

/* ── C. 页面骨架 ──
   ⚠️ `.page-head` / `.head-actions` 以前**在下面那条 @media 里被引用、却从来没定义过**（遗留）。 */
.page-head{display:flex;justify-content:space-between;align-items:flex-end;gap:16px;margin-bottom:22px;flex-wrap:wrap;}
.head-actions{display:flex;align-items:center;gap:10px;}
.content{padding:14px 16px 24px;}                       /* 手机版内容容器 */
/* 电脑版内容容器 —— ⚠️ 2026-10-07 收进来的：原来**五份页面各写一份**（`padding:30px 32px 44px;background:var(--bg)`，
   一字不差），而且各自还带一条窄屏覆盖。货品档案这页照着"骨架层"引 `.content`（手机版的），
   结果电脑版**没有背景**：标题落在深色 body 上＝深底深字（实测截图才发现）。
   → 收到这里一处，页面里用 `<main class="page-wrap">` 就行（`test:wiring` 会拦页面里再写一份）。 */
.page-wrap{padding:30px 32px 44px;background:var(--bg);}
@media (max-width:1100px){ .page-wrap{padding:22px 18px 34px;} }
.card-head{display:flex;justify-content:space-between;align-items:center;gap:14px;flex-wrap:wrap;
  padding:20px 20px 14px;border-bottom:1px solid var(--border);}

/* ── D. 内容组件（数据排印）——
   以前 ERP 是「业务页各写一份」，报表页要用就一个都没有；这里给出**最小可用的一套**。
   🔴 KPI 卡的用法：`<div class="card"><div class="stat-lbl">指标</div><div class="stat-val">1,234</div>
      <div class="stat-sub">副行</div></div>` —— **故意不接管 `.stat` 这个类名**：
      工作台上的 `.stat`（统计卡皮肤）是**定稿原型钉过**的，公共层再定义一遍必然打架；
      这里只给**里面那几件排印**（`.stat-lbl/.stat-val/.stat-sub/.stat-row`），容器用 `.card`。 */
.stat-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:16px;}
.stat-lbl{font-size:12.5px;color:var(--muted);letter-spacing:.2px;line-height:1.3;}
.stat-val{display:block;margin-top:8px;font-family:var(--font-display);font-size:var(--fs-kpi);
  font-weight:700;color:var(--fg);line-height:1;font-variant-numeric:tabular-nums;}
.stat-sub{margin-top:7px;font-size:var(--fs-cap);color:var(--muted);font-weight:600;line-height:1.5;}
.num{font-family:var(--font-mono);font-variant-numeric:tabular-nums;}
.muted{color:var(--muted);}
.cap{font-size:var(--fs-cap);color:var(--muted);}
.section-title{font-size:17px;font-weight:700;color:var(--fg);margin:0;letter-spacing:.2px;}
.section-sub{font-size:12.5px;color:var(--muted);margin:5px 0 0;}
.badge{display:inline-flex;align-items:center;gap:4px;font-size:var(--fs-cap);font-weight:700;
  border-radius:999px;padding:3px 9px;background:var(--na-bg);color:var(--na-tx);white-space:nowrap;}
.badge.up{background:var(--ok-bg);color:var(--ok-tx);}
.badge.down{background:var(--bad-bg);color:var(--bad-tx);}
.badge.flat{background:var(--na-bg);color:var(--na-tx);}
/* ⚠️ `warn` 是 2026-10-07 补的：以前只有 绿/红/灰 三档，而"待核对"这种**要人处理**的状态
   既不是成功也不是失败 —— 各页就各写一个 `.chip.pending`（库存页就是这么干的）→ 又一个"一个页面一个样式"。
   现在统一成 `.badge.warn`（色值取的就是页面上那份，观感不变）。 */
.badge.warn{background:var(--warn-bg);color:var(--warn-tx);}
/* 🆕 `.badge.pos` —— 单据上「哪个岗位报的」（D55，2026-10-20）。
   为什么收进公共层：报单页与出库页**四套页面**都要显示这个小标，按 D40 不许各页写一份。
   色用品牌金底，跟状态类 badge（绿/红/灰/黄）区分开：它是**属性**不是状态。 */
.badge.pos{background:var(--gold-soft);color:var(--warn-tx);}
.kv{display:grid;gap:9px;}
.kv-row{display:flex;justify-content:space-between;align-items:baseline;gap:14px;font-size:var(--fs-body);line-height:1.6;}
.kv-row .k{color:var(--muted);}
.kv-row .v{color:var(--fg);font-weight:600;}
/* ⚠️ 占比条叫 **`.pbar`**，**不叫 `.bar`** —— 工作台图表里的 `.bar`（柱子）是另一个东西，
   撞名会把那张图的柱子压成 8px（定稿原型钉过的图，不能动）。 */
.pbar{height:8px;border-radius:999px;background:var(--na-bg);overflow:hidden;}
.pbar-fill{height:100%;border-radius:999px;background:linear-gradient(90deg,var(--accent),var(--accent-2));}
.divider{height:1px;border:none;background:var(--border);margin:16px 0;}
.empty{padding:26px 16px;text-align:center;color:var(--muted);font-size:13px;line-height:1.8;}

/* ── E. 表格基础外观（`table.grid` 以前是"半拉子公共类"：只有 sticky + 窄屏 min-width，
      **padding / 边框 / 表头底色 / 字号一概没有** → 报表想用表格必然掉样式）── */
table.grid, table.users, table.perm{width:100%;font-size:13.5px;}
table.grid th, table.grid td,
table.users th, table.users td,
table.perm th, table.perm td{padding:13px 14px;border-bottom:1px solid #F0ECEF;vertical-align:middle;}
table.grid th, table.users th, table.perm th{
  text-align:left;font-size:12px;font-weight:700;color:var(--muted);
  background:#FBF8F5;border-bottom:1px solid var(--border);white-space:nowrap;}
table.perm th, table.perm td{text-align:center;}
table.grid td, table.users td{text-align:left;white-space:nowrap;}
table.grid tr:last-child td, table.users tr:last-child td, table.perm tbody tr:last-child td{border-bottom:none;}
table.grid td.num, table.grid th.num{text-align:right;font-family:var(--font-mono);font-variant-numeric:tabular-nums;}
table.grid td.name{font-weight:600;}
table td code{font-family:var(--font-mono);font-size:12.5px;background:#F4F1EE;padding:2px 7px;border-radius:6px;}

/* ─────────────────────────────────────────────────────────────
   🆕 要货清单 / 岗位药丸（**D50**）—— 领用报单页与出库执行页**共用这一份**
   （手机版 / 电脑版都在用：`assets/erp-req-form.js` 生成的 DOM 吃的就是这些类名）
   ⚠️ 页面里不许再写这些选择器（D40：公共组件只有一份）。
   ───────────────────────────────────────────────────────────── */
/* 小框（货品 / 单位 / 数量）：**手机两行**（货品单独一行 → 单位 + 数量一行），电脑一行。
   华哥 2026-10-08：「输入框与数量、单位可以分两行放，**单位在数量前面**」 */
/* 小框结构（D50 追加 8 定稿 · 华哥：「不要在错误的控件上反复去改」）：
   `.addline`      = 只是外壳（block）
   `.addline-row`  = 货品 + 单位 + 数量（手机两行：货品 / 单位+数量；电脑一行）
   `.cand-list`    = 候选列表 —— **浮层**，锚在 `.namebox`（输入框）的下沿，跟输入框同宽。
   ⚠️ 前两版把它当"文档流里的一块"：手机贴不到输入框、电脑被 flex 挤到右边。浮层一次解决两个。 */
.addline { display: block; }
.addline-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.addline > input[type="text"] { flex: 1 0 100%; min-width: 0; }
/* 🆕 货品输入框：右边两个键 —— **✕ 清空** + **▾ 展开候选**（D50 追加 5/6）
   🔴 为什么不用原生 `<datalist>`（华哥 2026-10-08 报的 bug：「我现在输不了，也不能逐字删，
      点这个选框直接弹出一个框挡住输入框」）：浏览器原生候选框**不受我们控制** ——
      手机上是整屏弹层会盖住输入框，桌面版还会在 JS 动态改 options 后**吃掉正在输的字**。
      → 全部自绘：候选列表是**页面里的一块**（在输入框下面，**不遮任何东西**）。 */
.namebox { position: relative; flex: 1 0 100%; min-width: 0; }
.namebox > input[type="text"] { width: 100%; padding-right: 92px; }
.namebox-x, .namebox-drop {
  position: absolute; top: 50%; transform: translateY(-50%);
  height: 40px; padding: 0; border: 0; border-radius: 10px;
  background: #EFEAE4; color: var(--muted); font-family: var(--font-body);
  font-size: 15px; font-weight: 700; line-height: 1; cursor: pointer;
}
.namebox-x { right: 46px; width: 40px; border-radius: 50%; }
.namebox-drop { right: 4px; width: 40px; font-size: 13px; }
.namebox-x:active, .namebox-drop:active,
.namebox-drop[aria-expanded="true"] { background: var(--border); color: var(--ink); }
/* 候选列表：**正常文档流里的一块**（不绝对定位 → 谁也挡不住）。
   打字时模糊匹配出现；点 ▾ 展开；最多 4 行高，超了内部滚动。 */
/* 🔴 2026-10-09 第三版（华哥：「不要在错误的控件上反复去改」）——**换成贴着输入框的浮层**：
   前两版都把它当"文档流里的一块"，于是手机离输入框远、电脑还被挤到右边。
   现在它是 `position:absolute`、锚在**输入框正下方 4px**：手机电脑都一样、都不受 flex 影响，
   单位/数量那行也不会被推走（输入框跟它们始终贴在一起）。列表自己是个滚动区，能划。
   ⚠️ 展开时它**盖住**下面的单位/数量/大框 —— 这是下拉框本来的样子（华哥不许的是"盖住输入框"）。 */
.cand-list {
  position: absolute; z-index: 40;
  top: calc(100% + 4px); left: 0; right: 0;            /* 贴着输入框下沿、跟输入框同宽 */
  margin: 0; padding: 6px;
  border: 1px solid var(--border); border-radius: 12px; background: #fff;
  box-shadow: 0 16px 36px -10px rgba(20, 14, 50, .35);
  /* 高度**按整行算**：44px × 5 行 + 12px 内边距 = 232px（整行，不露半截） */
  max-height: calc(6 * 44px + 12px);
  overflow-y: auto; -webkit-overflow-scrolling: touch; /* iOS 惯性滚动 */
  touch-action: pan-y;                                 /* 🔴 手指画动 = 滚动，不该被当成点击 */
  overscroll-behavior: contain;                        /* 划到头不要把整页带着滚 */
}
/* 🔴 2026-10-09 华哥真机：「弹出的选框不能划动，一碰屏幕就是点击了」
   —— 根因：选货绑在 **pointerdown**（手指一按下去就选），手指画动也被当成按。
   现在选货绑 **click**（手指抬起且没怎么移动才算点），CSS 再允许纵向滑。 */
.cand-item {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%;
  padding: 10px 12px; border: 0; border-radius: 9px; background: none;
  font-family: var(--font-body); font-size: 14px; font-weight: 600; color: var(--fg);
  text-align: left; cursor: pointer; min-height: 44px;
}
.cand-item:hover, .cand-item:active { background: #F4F1EE; }
.cand-item { height: 44px; }                           /* 定高 → 上面那个"整行"的账才算得准 */
/* 没库存的：**灰一点**（点它会被拦下并报错，见 erp-req-form.js 的 addPick —— 华哥 2026-10-09 要的） */
.cand-item.is-zero { opacity: .55; }
.cand-item.is-zero > i { color: var(--warn-tx); }
.cand-item > i { font-style: normal; font-size: 12px; font-weight: 700; color: var(--muted); }
.cand-empty { padding: 12px; font-size: 13px; color: var(--muted); text-align: center; }
/* 候选列表顶部那行「共 N 个」—— 让人知道这是在"按岗位/库存类型/分类筛过的清单"里挑（华哥 2026-10-10） */
.cand-head {
  padding: 4px 10px 8px; font-size: 11.5px; font-weight: 700; color: var(--muted);
  border-bottom: 1px dashed #EFE7DC; margin-bottom: 4px;
}
/* 🆕 单位框**常驻**、**宽高固定**（华哥 2026-10-10：「要常驻，大小要固定，不要变来变去」）——
   手机/电脑都用同一条：96px 宽、跟输入框同高（48px）。数量框吃掉剩下的宽度。 */
.addline2 { display: flex; flex: 1 0 100%; gap: 10px; align-items: stretch; min-width: 0; }
.addline2 > select.filter, .addline > select.filter { flex: 0 0 96px; width: 96px; min-width: 96px; max-width: 96px; }
.addline2 > input[type="number"] { flex: 1 1 auto; min-width: 0; }
/* 🔴 电脑版：货品 + 单位 + 数量 **一行**（候选列表在下面那块，不受影响 —— 2026-10-09 华哥：
   「电脑版的选框在侧面出来了，要在输入框下方」）。 */
html[data-view="pc"] .addline-row { flex-wrap: nowrap; }
html[data-view="pc"] .addline-row > input[type="text"] { flex: 1 1 auto; min-width: 220px; }
html[data-view="pc"] .namebox { flex: 1 1 auto; min-width: 220px; }
html[data-view="pc"] .addline2 { flex: 0 1 auto; }
html[data-view="pc"] .addline2 > input[type="number"] { flex: 0 0 140px; }
/* 「库存类型 + 分类」一行（D50 追加）：内容不长，**按内容宽度**排，加起来够一行就行。
   华哥：「这个选框的内容本来不长，选框也不用太长，加起来够页面宽度就行」 */
.addline3 { display: flex; gap: 8px; align-items: center; margin-top: 6px; }
.addline3 > select.filter { flex: 1 1 auto; min-width: 0; max-width: 50%; }
/* 大框（可粘贴多行）：华哥 2026-10-08「**要调大一点**」→ 追加 6 改为「**改成 8 行，四个角要圆角，
   **圆的幅度要跟其他元素统一**」。所以这里**逐条对齐 `.mrow input/select`**（同样的 1.5px 边、
   11px 圆角、同底色、同字体 —— 以前 textarea 什么都没写，掉回浏览器默认：**直角 + 衬线字体**）。
   `rows="8"` 写在页面上（四个页面都写了），这里再兜一道最小高度。 */
/* 🆕 添加 + 清空 一行（华哥 2026-10-13：「在**添加按钮边上**加一个清空按钮，多行输入框内有内容可以清空，
   没有内容这个按钮**变灰不可点**」）—— 外面的 `.add-actions` 管上下留白，按钮自己不再吃 margin。 */
.add-actions { display: flex; gap: 10px; align-items: stretch; margin: 16px 0 20px; }
.btn-add {
  margin: 0; width: 100%;                                 /* 手机版**整宽**（与报单页统一 —— 华哥 2026-10-12） */
  background: #fff; color: var(--accent, #2B2A5E);
  border: 1.5px solid var(--border, #E6E1EA); border-radius: 13px; box-shadow: none;
  font-weight: 800; letter-spacing: .3px; min-height: 48px;
}
.btn-add:hover { background: var(--gold-soft, #FBF3E2); border-color: var(--gold-lt, #EFC77C); }
.btn-add:active { background: #F6EFE2; }
html[data-view="pc"] .btn-add { width: auto; flex: 0 0 auto; min-width: 140px; }
.btn-clear {
  flex: 0 0 auto; min-width: 96px; min-height: 48px; padding: 0 16px;
  font-family: var(--font-body); font-size: 14px; font-weight: 700;
  color: var(--muted, #6B6480); background: #fff;
  border: 1.5px solid var(--border, #E6E1EA); border-radius: 13px; cursor: pointer;
}
.btn-clear:hover:not(:disabled) { color: var(--accent); background: #F3EEE7; }
/* 没内容 → **变灰不可点**（华哥点名要的） */
.btn-clear:disabled, .btn-clear.is-off {
  color: #BDB4AC; background: #F4F1EE; border-color: #EAE4DC; cursor: not-allowed;
}
html[data-view="pc"] .btn-clear { min-width: 96px; }

/* 🆕「候选可点」那块（D50 追加 14 · 华哥 2026-10-13）——
   **不是弹窗**：粘在粘贴框下面的一小块琥珀色面板，一行一行列"对不上的行" + 该行的候选。
   点一个候选就用它（数量带着走），点「都不是 」就跳过这行；全处理完这块自己收起来。 */
.fixbox {
  margin-top: 12px; padding: 12px 12px 4px;
  border: 1px solid var(--gold-lt, #EFC77C); background: var(--gold-soft, #FBF3E2); border-radius: 16px;
}
.fix-head { font-size: 12.5px; line-height: 1.6; color: var(--warn-tx, #8A6A16); margin: 0 0 10px; }
.fix-head b { font-weight: 800; }
.fix-line { margin-bottom: 8px; }
.fix-name { font-size: 14px; font-weight: 700; color: var(--ink, #2B2B45); margin-bottom: 6px; }
.fix-name i { font-style: normal; font-size: 12px; font-weight: 600; color: var(--muted, #6B6480); margin-left: 6px; }
.fix-cands { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.fix-chip {
  min-height: 44px; padding: 8px 12px; text-align: left; line-height: 1.35;
  font-family: var(--font-body); font-size: 12.5px; font-weight: 700; color: var(--accent, #2B2A5E);
  background: #fff; border: 1px solid var(--border, #E6E1EA); border-radius: 999px; cursor: pointer;
}
.fix-chip > i { display: block; font-style: normal; font-size: 11px; font-weight: 600; color: var(--muted); margin-top: 2px; }
.fix-chip.is-zero > i { color: var(--warn-tx, #8A6A16); }
.fix-chip:hover, .fix-chip:active { border-color: var(--gold-lt, #EFC77C); background: #FFFAEE; }
.fix-skip {
  min-height: 44px; padding: 8px 6px; cursor: pointer;
  font-family: var(--font-body); font-size: 11.5px; color: var(--muted, #6B6480);
  background: none; border: none; text-decoration: underline; text-underline-offset: 3px;
}
.fix-skip:hover { color: var(--accent); }

.paste-box {
  width: 100%; margin-top: 10px; resize: vertical;
  font-family: var(--font-body); font-size: 14px; line-height: 1.5; color: var(--fg);
  padding: 11px 13px; border: 1.5px solid var(--border); border-radius: 11px; background: #FFFDFA;
  min-height: calc(8 * 1.5em);
}
.paste-box::placeholder { color: #A89C93; }
.pos-goods { display: flex; flex-wrap: wrap; gap: 6px; }
.pos-chip, .pos-opt {
  font-family: var(--font-body); font-size: 13px; font-weight: 700; color: var(--muted);
  background: #fff; border: 1px solid var(--border); border-radius: 999px;
  padding: 8px 14px; min-height: 40px; cursor: pointer; white-space: nowrap;
}
.pos-chip i { font-style: normal; color: var(--muted); margin-left: 5px; font-size: 11px; font-weight: 600; }
.pos-chip:hover, .pos-opt:hover { color: var(--accent); background: #F3EEE7; }
.pos-opt.on { background: #FFFAEE; border-color: var(--gold-lt); color: var(--accent); }
/* 🆕 要货清单区（D50 追加 7/9）：**列头 + 虚线占位**，有货时是一张**整卡**（行与行之间用细线分，
   不再是一行一个边框盒子 —— 华哥 2026-10-10：「清单列表也不好看」）。 */
.picked-box {
  border: 1px dashed var(--border); border-radius: 16px; padding: 4px 0 12px; background: #FFFDFA;
}
.picked-box.is-filled { border-style: solid; background: var(--surface, #fff); padding: 0 0 4px; overflow: hidden; }
.picked-head {
  display: grid; grid-template-columns: minmax(0, 1fr) 76px 46px 52px; gap: 10px; align-items: center;
  padding: 11px 14px; font-size: 11.5px; font-weight: 700; color: var(--muted);
  letter-spacing: .4px; background: #FAF6F1; border-bottom: 1px solid var(--border);
}
.picked-box:not(.is-filled) .picked-head { background: none; border-bottom: 2px dashed #EFE7DC; padding-bottom: 9px; }
.picked-head > span:nth-child(n+2) { text-align: center; }
.picked-empty { padding: 16px 16px 6px; text-align: center; font-size: 13px; line-height: 1.7; color: var(--muted); }
.picked-empty b { color: var(--fg); font-weight: 700; }
.pick {
  display: grid; grid-template-columns: minmax(0, 1fr) 76px 46px 52px; gap: 10px; align-items: center;
  padding: 12px 14px; border-bottom: 1px solid #F1EBE3; background: none;
}
.pick:last-child { border-bottom: 0; }
.pick:hover { background: #FDFAF6; }
.pick-main { min-width: 0; overflow: hidden; }
.pick-name { font-size: 14.5px; font-weight: 700; color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick-sub { font-size: 11.5px; color: var(--muted); margin-top: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick-warn { color: var(--warn-tx); font-weight: 700; }
.pick-qty {
  width: 100%; min-width: 0; text-align: center; height: 40px; padding: 0 6px;
  border: 1.5px solid var(--border); border-radius: 10px; background: #FFFDFA;
  font-family: var(--font-body); font-size: 14px; font-weight: 700; color: var(--fg);
}
.pick-qty:focus { border-color: var(--gold-lt); outline: none; }
.pick-unit {
  font-size: 11.5px; font-weight: 700; color: var(--muted); text-align: center;
  background: #F4F1EE; border-radius: 999px; padding: 4px 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pick-del {
  min-height: 40px; padding: 0; background: none; border: 1px solid #EADFD8; border-radius: 10px;
  color: var(--warn-tx); font-family: var(--font-body); font-size: 12.5px; font-weight: 700; cursor: pointer;
}
.pick-del:hover { background: #FDF3F0; border-color: #E3B9AC; }
/* 手机版：清单行的单位列窄一点，名字那列还是主角；删除键矮一点但不小于 40px */
html[data-view="m"] .pick, html[data-view="m"] .picked-head {
  grid-template-columns: minmax(0, 1fr) 62px 40px 46px; gap: 8px;
}
html[data-view="m"] .pick { padding: 12px 12px; }
html[data-view="m"] .picked-head { padding: 10px 12px; }
html[data-view="m"] .pick-qty { height: 40px; }

/* ═══════════════════════════════════════════════════════════════════════════
   🆕 列表页脚：「共 N 条 · 全部流水 ›」（华哥 2026-10-10 圈了工作台那一行说样式有问题）——
   以前是一个干巴巴的横排文字 + 下划线链接，看着像个没做完的东西。现在：**整行可点、右对齐带箭头、
   上下有留白、左边计数弱化**，跟卡片长在一起。
   ═══════════════════════════════════════════════════════════════════════════ */
.list-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 18px 15px; border-top: 1px solid var(--border); margin-top: 0;
  font-family: var(--font-body);
}
.list-foot .count { font-size: 12.5px; color: var(--muted); font-weight: 600; }
.list-foot a {
  display: inline-flex; align-items: center; gap: 4px; min-height: 32px;
  font-size: 13px; font-weight: 700; color: var(--accent, #2B2A5E); text-decoration: none;
  padding: 4px 10px; border-radius: 999px; background: #F7F3EE; border: 1px solid var(--border);
}
.list-foot a:hover { background: var(--gold-soft, #FBF3E2); border-color: var(--gold-lt, #EFC77C); }

/* 🆕 备注框（两行）—— 华哥 2026-10-10：「用途输入框去掉，备注输入换成两行的」。
   跟同页输入框一套（1.5px 边 / 11px 圆角 / 同底色 / 同字体），只是多一行高度。 */
.note-box {
  width: 100%; font-family: var(--font-body); font-size: 14px; line-height: 1.5; color: var(--fg);
  padding: 11px 13px; border: 1.5px solid var(--border); border-radius: 11px; background: #FFFDFA;
  resize: vertical; min-height: calc(2 * 1.5em + 22px);
}
.note-box::placeholder { color: #A89C93; }
@media (min-width: 1px) { html[data-view="m"] .note-box { font-size: 16px; } }

/* ═══════════════════════════════════════════════════════════════════════════
   🆕 「区块头 + 工具条」= **全站唯一一份**（2026-10-10 收进公共层，D40）
   为什么收：这两类以前**每个页各写一份**（index/stock/items/stock-flow 四份，边距 16/18 不一），
   而**领用报单页与出库执行页根本没写** → 那两页的「共 N 单」掉到标题下面一行、紧贴着搜索框
   （华哥 2026-10-10 截图圈的就是这个："两个框贴太紧了"）。
   ═══════════════════════════════════════════════════════════════════════════ */
.sec-head { display: flex; align-items: baseline; gap: 9px; margin: 20px 2px 12px; }
.sec-head h2 { font-size: 15.5px; font-weight: 800; color: var(--fg); letter-spacing: .2px; margin: 0; }
.sec-head .more { margin-left: auto; font-size: 12px; font-weight: 600; color: var(--muted); }
.toolbar { display: flex; gap: 8px; align-items: center; margin-bottom: 14px; }
.toolbar input[type="search"] { flex: 1; min-width: 0; }
.toolbar.filters { flex-wrap: wrap; }
.toolbar.filters select { flex: 1; min-width: 0; }

/* 🆕 「已出库」卡片（华哥 2026-10-12：待出库做成卡片页，再加一个已出库）—— 与待出库同一套观感 */
.issued-card { display: flex; align-items: center; gap: 10px; padding: 13px 14px; border-bottom: 1px solid #F1EDF4; }
.issued-card:last-child { border-bottom: 0; }
.issued-main { flex: 1; min-width: 0; }
.issued-no { font-family: var(--font-mono); font-size: 12px; font-weight: 700; color: var(--accent-2); }
.issued-sub { font-size: 11.5px; color: var(--muted); margin-top: 5px; display: flex; flex-wrap: wrap; gap: 7px; align-items: center; }
.issued-acts { display: flex; flex-direction: column; gap: 6px; align-items: stretch; flex: none; }
.issued-acts button {
  min-height: 36px; padding: 0 12px; border-radius: 10px; font-family: var(--font-body);
  font-size: 12px; font-weight: 700; cursor: pointer; background: #fff;
  border: 1px solid var(--border); color: var(--accent);
}
.issued-acts button.danger { color: var(--warn-tx); border-color: #EADFD8; }
.issued-acts button:hover { background: var(--gold-soft, #FBF3E2); border-color: var(--gold-lt, #EFC77C); }
.src-chip { display: inline-block; font-size: 10.5px; font-weight: 800; border-radius: 999px; padding: 2px 8px; }
.src-chip.req { background: #EDE9FB; color: #4A3C8C; }
.src-chip.direct { background: var(--warn-bg); color: var(--warn-tx); }

/* 🆕 取货弹窗里每行的「库存 N 单位」（华哥 2026-10-13：「去出库的那个弹窗上，要显示**出库货品的库存数**」）
   —— 跟「申请 X」并排，**一直都在**（不是等他填大了才提醒）。超过库存的那行 `--bad` 由页面的 `.low` 标。 */
.iv-req { display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: baseline; }
.iv-req .iv-have { font-weight: 800; color: var(--accent, #2B2A5E); font-size: 12.5px; }

/* ─────────────────────────────────────────────────────────────
   🆕 全站页脚：ICP 备案号（2026-10-25 · 云上备案通过后加）
   · 管局要求：**网站底部必须悬挂备案号并链接到工信部备案官网**
   · 🔴 唯一出处在这里，页面里不许再写（D40）；HTML 由 **服务端**注入（src/beian.js）

   ⚠️ 它是**正常流**里的最后一块，不是绝对定位、也不给 body 加 padding ——
      试过绝对定位 + `html body{padding-bottom:46px}` 留位，**把 D40 那条「底栏下面必须纯白」的量测弄红了**
      （body 被撑高 46px，白色渐变带跟着往下移，底栏下面露出奶油色）。
      现在由 beian.js 把页脚**插进页面最后一个内容容器里**（`.frame` / `main.content` / `.page`），
      自然就落在内容末尾；有底栏的页面 body 本来就让出了 64px，页脚正好在底栏上方。
   ──────────────────────────────────────────────────────────── */
.site-foot {
  /* 🔴 手机版的容器（.page / main.content）自己是 flex，页脚当 flex 子项会被**压扁成 0 高**
     （实测 390×844 量到 h=0）→ `flex:0 0 auto` 不许伸不许缩、按内容撑开，`align-self` 免得被拉满。 */
  flex: 0 0 auto; align-self: stretch; min-height: 42px;
  padding: 18px 20px 22px; text-align: center;
  font-family: var(--font-body); font-size: 12px; line-height: 1.5;
  color: var(--muted, #8A8FA0);
}
.site-foot a { color: inherit; text-decoration: none; }
.site-foot a:hover { text-decoration: underline; }
html[data-view="m"] .site-foot {
  font-size: 11.5px;
  padding: 14px 16px calc(16px + env(safe-area-inset-bottom, 0px));
}
