:root{
  --bg:#f5f6f8; --panel:#fff; --ink:#1a1d23; --ink2:#5a6270; --ink3:#8b93a0;
  --line:#e6e8ec; --line2:#eff1f4;
  --brand:#2563eb; --brand-soft:#eef4ff; --brand-d:#1d4ed8; --on-brand:#fff;
  /* --brand 可能是渐变色（渐变彩皮肤），凡是需要"单色"做 color-mix 派生的地方一律用 --brand-flat */
  --brand-flat:#2563eb; --brand-glow:rgba(37,99,235,.34);
  --ok:#16a34a; --ok-soft:#eaf7ee;
  --warn:#d97706; --warn-soft:#fef6e7;
  --bad:#dc2626; --bad-soft:#fdecec;
  --gray-soft:#f1f3f6;
  --r:10px; --r-lg:14px;
  --shadow:0 1px 2px rgba(16,24,40,.04),0 1px 3px rgba(16,24,40,.06);
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0}
body{background:var(--bg);color:var(--ink);font:14px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4{margin:0;font-weight:600}
table{border-collapse:collapse;width:100%}

/* ---------- 布局 ---------- */
/* 侧栏宽度统一走 --sbw：点击左下角按钮在 212（展开）↔ 64（图标条）之间切换。
   丝滑的关键有三条：
   1. 只动容器宽度，文字绝对定位后靠 opacity+transform 渐隐，全程不重排；
   2. 所有参与变化的属性都用同一条缓动（--sb-ease），起手快、收尾软，不会"弹一下停住"；
   3. 文字用 opacity+translateX+scale 组合淡出，图标用 padding 平滑滑到居中，
      收起/展开的颜色也一起过渡，避免"啪"地跳变。 */
.layout{display:flex;min-height:100vh}
.sidebar{
  width:var(--sbw,212px);flex:0 0 var(--sbw,212px);background:var(--panel);
  border-right:1px solid var(--line);display:flex;flex-direction:column;
  position:sticky;top:0;height:100vh;overflow:hidden;
  /* 收放时才挂过渡（html.sb-free），平时改窗口宽度不跟着动画 */
  --sb-ease:cubic-bezier(.32,.72,.24,1);
  --sb-dur:.34s;
}
html.sb-free .sidebar{
  transition:width var(--sb-dur) var(--sb-ease),flex-basis var(--sb-dur) var(--sb-ease);
  will-change:width,flex-basis;
}
/* 导航条目：图标固定左侧，文字层绝对定位，不参与流式布局 → 宽度变化不触发文字重排 */
.nav a{position:relative;display:flex;align-items:center;gap:9px;padding:9px 10px;border-radius:8px;
  color:var(--ink2);font-size:13.5px;margin-bottom:2px;transition:.12s;overflow:hidden}
.nav a .sb-label{position:absolute;left:35px;right:10px;top:50%;transform:translateY(-50%);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none;
  will-change:opacity,transform;contain:paint}
.nav a i{flex:0 0 16px;transition:width .26s var(--sb-ease),height .26s var(--sb-ease),
  flex-basis .26s var(--sb-ease),margin .26s var(--sb-ease),opacity .2s ease}

/* 收放瞬间：让每一步都走同一条缓动，观感才连贯 */
html.sb-free .sb-label{
  transition:opacity .18s ease,transform var(--sb-dur) var(--sb-ease);
}
html.sb-free .nav a{
  transition:padding var(--sb-dur) var(--sb-ease),gap var(--sb-dur) var(--sb-ease),
    background-color .18s ease,color .18s ease;
}
html.sb-free .brand{transition:padding var(--sb-dur) var(--sb-ease),gap var(--sb-dur) var(--sb-ease)}
html.sb-free .nav{transition:padding var(--sb-dur) var(--sb-ease)}
html.sb-free .brand-text{transition:opacity .16s ease,transform .28s var(--sb-ease)}
html.sb-free .nav-sep{transition:padding var(--sb-dur) var(--sb-ease),
  margin var(--sb-dur) var(--sb-ease),background-color .2s ease}
html.sb-free .brand-mark{transition:width .28s var(--sb-ease),height .28s var(--sb-ease),
  flex-basis .28s var(--sb-ease)}

/* ---------- 收起态（图标条） ---------- */
html.sb-collapsed .sidebar{--sbw:64px}
html.sb-collapsed .brand{justify-content:center;padding:18px 0 14px;gap:0;cursor:pointer}
/* 文字不 display:none，改成淡出＋左移微缩，收起来的过程才"看得见"；
   同时把宽度压成 0——否则文字虽然透明了仍占位，logo 会被挤得不居中 */
html.sb-collapsed .brand-text{
  opacity:0;transform:translateX(-6px) scale(.97);pointer-events:none;
  width:0;flex:0 0 0;min-width:0;margin:0;padding:0;overflow:hidden;
}
html.sb-collapsed .nav-sep span{opacity:0;transform:translateX(-6px);pointer-events:none}
html.sb-collapsed .nav a .sb-label{
  opacity:0;transform:translateY(-50%) translateX(-8px) scale(.96);
}
html.sb-collapsed .nav{padding:4px 8px}
html.sb-collapsed .nav a{justify-content:center;gap:0;padding:11px 0}
html.sb-collapsed .nav i{width:18px;height:18px;flex:0 0 18px;margin:0}
html.sb-collapsed .nav-sep{height:1px;padding:0 12px;margin:9px 0;background:var(--line);overflow:hidden;color:transparent}
html.sb-collapsed .icp{opacity:0;pointer-events:none}
/* 收起时导航区两侧留白不同，图标要重新居中：用 padding 变化吃掉，不碰宽度 */

/* 收起后悬停出气泡（纯 CSS） */
html.sb-collapsed .nav a::after,
html.sb-collapsed .nav a::before{opacity:0;pointer-events:none;transition:opacity .12s .12s}
html.sb-collapsed .nav a:hover::after{
  content:attr(data-tip);opacity:1;
  position:absolute;left:calc(100% + 14px);top:50%;transform:translateY(-50%);
  background:#1f2530;color:#fff;font-size:12px;line-height:1;padding:7px 9px;border-radius:7px;
  white-space:nowrap;z-index:60;box-shadow:0 4px 14px rgba(16,24,40,.2);font-weight:400}
html.sb-collapsed .nav a:hover::before{
  content:"";opacity:1;position:absolute;left:calc(100% + 8px);top:50%;
  transform:translateY(-50%) rotate(45deg);width:7px;height:7px;background:#1f2530;
  border-radius:1px;z-index:60}

/* ---------- 收起/展开手柄：贴右缘的小竖柄，垂直居中 ---------- */
/* 低调优先：白底细边浅影的小 chip，平时几乎融入边缘；悬停点亮成品牌色。
   展开态平时隐身（悬停侧栏才淡入），收起态常驻但同样克制。 */
.sb-fold{position:absolute;right:0;top:50%;transform:translateY(-50%);z-index:40;
  width:15px;height:44px;padding:0;margin:0;
  border:1px solid var(--line);border-right:0;border-radius:8px 0 0 8px;
  background:var(--panel);color:var(--ink2);cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  opacity:0;box-shadow:-2px 2px 8px -3px rgba(16,24,40,.22);
  transition:opacity .18s ease,background .14s,color .14s,border-color .14s,
    box-shadow .18s ease,transform .22s var(--sb-ease)}
.sidebar:hover .sb-fold,html.sb-collapsed .sb-fold,.sb-fold:focus-visible{opacity:.95}
.sb-fold:hover{opacity:1;color:#fff;background:var(--brand-flat);border-color:var(--brand-flat);
  box-shadow:-3px 3px 12px -4px rgba(16,24,40,.3);
  transform:translateY(-50%) translateX(1px)}
/* 收起态再窄也贴得住：图标条 64px，手柄 15px 挂右缘不挡图标 */
/* 收起态：手柄常驻可见但保持低调（白 chip + 边框浅影），不搞大色块 */
html.sb-collapsed .sb-fold{opacity:.95}
.sb-fold svg{transition:transform .34s cubic-bezier(.32,.72,.24,1);flex:none}
html.sb-collapsed .sb-fold svg{transform:rotate(180deg)}
/* 收起态再窄也贴得住：图标条 64px，手柄 15px 挂右缘不挡图标 */

/* 窄屏：侧栏变成抽屉。收起时是 64px 图标条；展开时浮在内容上方（挤压是手机端
   布局崩坏的根源——375px 的屏被侧栏挤得只剩 160px），同时盖一层可点遮罩 */
@media(max-width:860px){
  .sidebar{position:fixed;left:0;top:0;z-index:1400}
  /* 内容区永远只给图标条让位，展开侧栏浮在上面，不再挤压 */
  .layout,html:not(.sb-collapsed) .layout{padding-left:64px}
  html:not(.sb-collapsed) .sidebar{box-shadow:0 18px 60px -12px rgba(16,24,40,.35)}
  /* 横向溢出兜底：窄屏一律裁掉，页面绝不左右晃 */
  html,body{overflow-x:hidden}
  /* 抽屉遮罩：展开时盖住内容，点一下收起（元素由 app.js 注入，桌面端无样式不生效）。
     宽度显式用视口单位而不是 inset:0 —— inset 自动宽度在移动端视口换算里
     会和自身宽度互相依赖，个别页面会把整页撑宽 */
  .sb-drawer-mask{position:fixed;left:0;top:0;width:100vw;height:100vh;z-index:1390;
    background:rgba(15,23,42,.34);opacity:0;pointer-events:none;transition:opacity .26s ease;
    -webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
  html:not(.sb-collapsed) .sb-drawer-mask{opacity:1;pointer-events:auto}
}
.brand{display:flex;gap:10px;align-items:center;padding:18px 18px 14px;white-space:nowrap;min-width:0}
.brand-text{min-width:0;overflow:hidden}
.brand-mark{width:30px;height:30px;border-radius:8px;background:linear-gradient(135deg,#2563eb,#4f46e5);flex:0 0 30px;position:relative}
.brand-mark::after{content:"";position:absolute;top:8px;right:8px;bottom:8px;left:8px;border:2px solid #fff;border-radius:3px;border-bottom-color:transparent;border-right-color:transparent;transform:rotate(-45deg)}
.brand-name{font-weight:600;font-size:14.5px;letter-spacing:.2px;overflow:hidden;text-overflow:ellipsis}
.brand-sub{font-size:11px;color:var(--ink3);overflow:hidden;text-overflow:ellipsis}
.nav{padding:4px 10px;flex:1;overflow-y:auto;overflow-x:hidden;scrollbar-width:none;-ms-overflow-style:none}
.nav::-webkit-scrollbar{display:none}
.nav a{display:flex;align-items:center;gap:9px;padding:9px 10px;border-radius:8px;color:var(--ink2);font-size:13.5px;margin-bottom:2px;transition:.12s;position:relative;overflow:hidden}
.nav a .sb-label{position:absolute;left:35px;right:10px;top:50%;transform:translateY(-50%);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none;contain:paint}
.nav a i{flex:0 0 16px}
.nav a:hover{background:var(--gray-soft);color:var(--ink)}
.nav a.on{background:var(--brand-soft);color:var(--brand-flat);font-weight:600}
.nav-sep{font-size:11px;color:var(--ink3);padding:14px 10px 6px;letter-spacing:.5px}
/* 分组标题的文字层单独淡出：收起后整条变成一根细线，过渡才不突跳 */
.nav-sep span{display:block;transition:opacity .16s ease,transform .3s var(--sb-ease)}
/* ---------- 侧栏导航：光带游标 + 玻璃副面板 ----------
   桌面端一级只留 5 行，子项从右侧玻璃面板飞出；触屏/窄屏退回手风琴。
   两套共用同一份 DOM，靠媒体查询切换，不重复渲染。 */
.nav{position:relative}
.nav-grp{margin-bottom:3px}

/* 光带：一块软胶囊高亮，靠 transform 从一行滑到另一行；空闲时停靠在当前页所在的组 */
.nav-beam{position:absolute;left:5px;right:5px;top:0;height:38px;border-radius:10px;
  opacity:0;pointer-events:none;z-index:0;background:var(--brand-soft);
  transform:translate3d(0,0,0);
  transition:transform .42s cubic-bezier(.32,.72,.24,1),height .3s var(--sb-ease),opacity .24s ease;
  will-change:transform}
.nav-beam.show{opacity:1}
/* 左侧那一竖条：整条皮肤渐变（--brand 在渐变皮肤下是 image，只能给 background） */
.nav-beam::before{content:"";position:absolute;left:0;top:50%;width:3px;height:17px;
  margin-top:-8.5px;border-radius:0 3px 3px 0;background:var(--brand);
  box-shadow:0 0 10px -1px var(--brand-flat,var(--brand))}

/* 一级行：图标 + 名称 + 条目数 + 折叠箭头（箭头只在手风琴模式出现） */
.nav-ghd{position:relative;z-index:1;display:flex;align-items:center;gap:9px;width:100%;
  background:none;border:0;cursor:pointer;font-family:inherit;font-size:13.5px;
  color:var(--ink2);padding:9px 10px;border-radius:10px;text-align:left;
  transition:color .16s ease,padding .3s var(--sb-ease)}
.nav-ghd:hover{color:var(--ink)}
.nav-ghd i{flex:0 0 16px;opacity:.7;
  transition:opacity .16s ease,transform .2s cubic-bezier(.32,.72,.24,1)}
.nav-grp.is-hov .nav-ghd i,.nav-grp.is-cur .nav-ghd i{opacity:1}
.nav-grp.is-cur .nav-ghd{color:var(--brand-flat);font-weight:600}
/* 一级行的文字层留在 flex 流里（要靠它把数字胶囊顶到行尾），但必须 nowrap + 裁切：
   侧栏宽度过渡时它会被压缩，中文一旦换行就变成竖排（v3.44.5 修的就是这个）。
   收放时的观感靠 opacity 延时错开：收起先淡出、展开等宽度长开再淡入。 */
.nav-ghd .sb-label{position:static;pointer-events:auto;flex:1;min-width:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  transition:opacity .14s ease}
html.sb-free .nav-ghd .sb-label{transition:opacity .16s ease .15s}
html.sb-free.sb-collapsed .nav-ghd .sb-label{transition:opacity .1s ease 0s}
.nav-cnt{flex:none;margin-left:auto;font-style:normal;font-size:10.5px;line-height:1;font-weight:500;
  min-width:17px;height:17px;padding:0 5px;border-radius:9px;display:flex;
  align-items:center;justify-content:center;background:var(--gray-soft);color:var(--ink3);
  transition:opacity .18s ease,background-color .16s ease,color .16s ease}
.nav-grp.is-cur .nav-cnt,.nav-grp.is-hov .nav-cnt{background:var(--brand-soft);color:var(--brand-flat)}
.nav-ghd .chev{width:11px;height:11px;flex:none;opacity:.45;margin-left:2px;
  transition:transform .22s var(--sb-ease),opacity .16s ease}
.nav-grp.open .nav-ghd .chev{transform:rotate(90deg)}
/* 手风琴（触屏 / 窄屏）：子项在行下方展开 */
.nav-gbd{overflow:hidden;max-height:0;transition:max-height .3s var(--sb-ease)}
.nav-grp.open .nav-gbd{max-height:560px}
/* 顶级直链（车间看板）：和组头同一套观感，但点了直接走，不展开 */
.nav-single{position:relative;z-index:1;display:flex;align-items:center;gap:9px;
  margin-bottom:3px;color:var(--ink2);font-size:13.5px;text-decoration:none;
  padding:9px 10px;border-radius:10px;
  transition:color .16s ease,padding .3s var(--sb-ease)}
.nav-single:hover{color:var(--ink)}
.nav-single i{flex:0 0 16px;opacity:.7;
  transition:opacity .16s ease,transform .2s cubic-bezier(.32,.72,.24,1)}
.nav-single:hover i{opacity:1;transform:scale(1.1)}
.nav-single.on{color:var(--brand-flat);font-weight:600}
.nav-single.on i{opacity:1}
.nav-single .sb-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;transition:opacity .14s ease}
html.sb-free .nav-single .sb-label{transition:opacity .16s ease .15s}
html.sb-free.sb-collapsed .nav-single .sb-label{transition:opacity .1s ease 0s}
/* 收起态（图标条，触屏）：组头隐藏、图标全部平铺，组间细线还原旧观感 */
html.sb-collapsed .nav-ghd{display:none}
html.sb-collapsed .nav-single{padding:11px 0;justify-content:center;gap:0}
html.sb-collapsed .nav-single .sb-label{opacity:0;flex:0 0 0;width:0;min-width:0;pointer-events:none}
html.sb-collapsed .nav-gbd{max-height:none;overflow:visible}
html.sb-collapsed .nav-grp + .nav-grp::before{content:"";display:block;height:1px;
  background:var(--line);margin:9px 4px}

/* ---------- 玻璃副面板（桌面悬停飞出） ---------- */
.nav-fly{position:fixed;z-index:1500;width:250px;padding:8px;border-radius:16px;
  background:var(--panel);border:1px solid var(--line);
  -webkit-backdrop-filter:blur(20px) saturate(1.6);backdrop-filter:blur(20px) saturate(1.6);
  box-shadow:0 24px 64px -20px rgba(16,28,60,.38),0 4px 14px rgba(16,28,60,.08);
  opacity:0;transform:translateX(-9px) scale(.975);transform-origin:left center;
  pointer-events:none;transition:opacity .18s ease,transform .26s cubic-bezier(.32,.72,.24,1)}
.nav-fly.on{opacity:1;transform:none;pointer-events:auto}
/* 指向一级行的小尖角 */
.nf-notch{position:absolute;left:-5px;width:10px;height:10px;background:var(--panel);
  border-left:1px solid var(--line);border-bottom:1px solid var(--line);
  border-radius:0 0 0 3px;transform:rotate(45deg);transition:top .26s cubic-bezier(.32,.72,.24,1)}
.nf-head{display:flex;align-items:center;gap:8px;padding:4px 8px 8px}
.nf-head span{font-size:11px;color:var(--ink3);letter-spacing:.4px;white-space:nowrap}
.nf-head em{font-style:normal;font-size:10.5px;color:var(--ink3);min-width:16px;height:16px;
  padding:0 5px;border-radius:8px;background:var(--gray-soft);display:flex;
  align-items:center;justify-content:center}
.nf-head::after{content:"";flex:1;height:1px;background:var(--line)}
.nf-list{display:flex;flex-direction:column;gap:2px}
.nf-i{display:flex;align-items:center;gap:9px;padding:8px 9px;border-radius:9px;
  color:var(--ink2);font-size:13px;font-weight:400;opacity:0;transform:translateX(-6px)}
/* 逐条错开淡入：面板一开，子项像被"抖"出来 */
.nav-fly.on .nf-i{animation:nfIn .34s cubic-bezier(.32,.72,.24,1) forwards;
  animation-delay:calc(var(--i,0) * 26ms)}
@keyframes nfIn{to{opacity:1;transform:none}}
.nf-i:hover{background:var(--brand-soft);color:var(--brand-flat)}
.nf-i.on{background:var(--brand-soft);color:var(--brand-flat);font-weight:600}
.nf-i i{flex:0 0 16px;opacity:.8}
.nf-i.on i,.nf-i:hover i{opacity:1}
.nf-i span{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.nf-dot{width:6px;height:6px;border-radius:50%;background:#e5484d;flex:none}
.nf-ar{font-style:normal;font-size:14px;line-height:1;color:var(--ink3);opacity:0;
  transform:translateX(-3px);flex:none;transition:opacity .14s ease,transform .18s var(--sb-ease)}
.nf-i:hover .nf-ar{opacity:1;transform:none}
/* 面板在 .nav 之外，图标基础样式要重挂一遍（mask 由 .i-* 提供） */
.nav-fly i{width:16px;height:16px;display:inline-block;background:currentColor;
  -webkit-mask-repeat:no-repeat;-webkit-mask-position:center;-webkit-mask-size:contain;
  mask-repeat:no-repeat;mask-position:center;mask-size:contain}

/* 桌面且支持悬停：收起手风琴，改走副面板 */
@media (hover:hover) and (min-width:861px){
  .nav-gbd{display:none}
  .nav-ghd .chev{display:none}
  .nav-grp.is-hov .nav-ghd{color:var(--ink)}
  .nav-grp.is-hov .nav-ghd .sb-label{transform:translateX(2px);
    transition:transform .22s cubic-bezier(.32,.72,.24,1),opacity .16s ease .15s}
  .nav-grp.is-hov .nav-ghd i{transform:scale(1.1)}
  /* 收起成 64px 图标条：五组各一个图标，悬停同样飞出面板 */
  html.sb-collapsed .nav-ghd{display:flex;justify-content:center;gap:0;padding:11px 0}
  html.sb-collapsed .nav-single{padding:11px 0;justify-content:center;gap:0}
  html.sb-collapsed .nav-single i{transform:none}
  /* 收起：文字和数字归零淡出。用「宽度归零」而不是 display:none——
     display:none 会让展开的第一帧把中文塞进 64px 里挤成竖排。 */
  html.sb-collapsed .nav-ghd .sb-label,
  html.sb-collapsed .nav-single .sb-label,
  html.sb-collapsed .nav-ghd .nav-cnt{opacity:0;flex:0 0 0;width:0;min-width:0;
    padding:0;margin:0;overflow:hidden;pointer-events:none}
  html.sb-collapsed .nav-beam{left:4px;right:4px}
  html.sb-collapsed .nav-grp + .nav-grp::before{display:none}
}
.nav i{width:16px;height:16px;flex:0 0 16px;display:inline-block;background:currentColor;opacity:.75;
  -webkit-mask-repeat:no-repeat;-webkit-mask-position:center;-webkit-mask-size:contain;mask-repeat:no-repeat;mask-position:center;mask-size:contain}
.i-home{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M3 11l9-8 9 8v9a1 1 0 0 1-1 1h-5v-7H9v7H4a1 1 0 0 1-1-1z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M3 11l9-8 9 8v9a1 1 0 0 1-1 1h-5v-7H9v7H4a1 1 0 0 1-1-1z'/></svg>")}
.i-orders{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M5 3h14a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zM8 10h8v-2H8zm0 4h8v-2H8zm0 4h5v-2H8z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M5 3h14a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zM8 10h8v-2H8zm0 4h8v-2H8zm0 4h5v-2H8z'/></svg>")}
.i-cards{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M3 6h18v4H3zm0 7h18v5H3z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M3 6h18v4H3zm0 7h18v5H3z'/></svg>")}
.i-check{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z'/></svg>")}
.i-log{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 4h16v2H4zm0 5h16v2H4zm0 5h11v2H4zm0 5h8v2H4z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 4h16v2H4zm0 5h16v2H4zm0 5h11v2H4zm0 5h8v2H4z'/></svg>")}
.i-gear{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8zm0 6a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm8.4-2a8.4 8.4 0 0 0-.14-1.4l2.02-1.57-2-3.46-2.38.96a8.5 8.5 0 0 0-2.42-1.4L15.1 2.4h-4l-.38 2.53a8.5 8.5 0 0 0-2.42 1.4l-2.38-.96-2 3.46L5.94 10.5A8.4 8.4 0 0 0 5.8 12c0 .47.05.94.14 1.4l-2.02 1.57 2 3.46 2.38-.96a8.5 8.5 0 0 0 2.42 1.4l.38 2.53h4l.38-2.53a8.5 8.5 0 0 0 2.42-1.4l2.38.96 2-3.46-2.02-1.57c.09-.46.14-.93.14-1.4z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8zm0 6a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm8.4-2a8.4 8.4 0 0 0-.14-1.4l2.02-1.57-2-3.46-2.38.96a8.5 8.5 0 0 0-2.42-1.4L15.1 2.4h-4l-.38 2.53a8.5 8.5 0 0 0-2.42 1.4l-2.38-.96-2 3.46L5.94 10.5A8.4 8.4 0 0 0 5.8 12c0 .47.05.94.14 1.4l-2.02 1.57 2 3.46 2.38-.96a8.5 8.5 0 0 0 2.42 1.4l.38 2.53h4l.38-2.53a8.5 8.5 0 0 0 2.42-1.4l2.38.96 2-3.46-2.02-1.57c.09-.46.14-.93.14-1.4z'/></svg>")}
.i-box{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2l9 5v10l-9 5-9-5V7zm0 2.3L5.6 7.9 12 11.5l6.4-3.6zM5 9.4v6.6l6 3.3v-6.6zm14 0l-6 3.3v6.6l6-3.3z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2l9 5v10l-9 5-9-5V7zm0 2.3L5.6 7.9 12 11.5l6.4-3.6zM5 9.4v6.6l6 3.3v-6.6zm14 0l-6 3.3v6.6l6-3.3z'/></svg>")}
.i-user{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zm0 2c-4 0-8 2-8 5v1h16v-1c0-3-4-5-8-5z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zm0 2c-4 0-8 2-8 5v1h16v-1c0-3-4-5-8-5z'/></svg>")}
.i-cloud{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M6.5 19a4.5 4.5 0 0 1-.5-8.97A6 6 0 0 1 17.5 9a4 4 0 0 1 .5 7.97V19h-3v-4h2.4A2 2 0 0 0 17 11.1l-1.2.05-.35-1.15a4 4 0 0 0-7.7.75l-.2.85-.87.1A2.5 2.5 0 0 0 7 17h2v2z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M6.5 19a4.5 4.5 0 0 1-.5-8.97A6 6 0 0 1 17.5 9a4 4 0 0 1 .5 7.97V19h-3v-4h2.4A2 2 0 0 0 17 11.1l-1.2.05-.35-1.15a4 4 0 0 0-7.7.75l-.2.85-.87.1A2.5 2.5 0 0 0 7 17h2v2z'/></svg>")}
.i-truck{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M3 6h11v9H3zM14 9h4l3 3v3h-7zM7 19a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm10 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M3 6h11v9H3zM14 9h4l3 3v3h-7zM7 19a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm10 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4z'/></svg>")}
.i-cust{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 5h16a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1zm1 2v10h14V7H5zm2.5 2.5a1.8 1.8 0 1 1 0 3.6 1.8 1.8 0 0 1 0-3.6zM5.4 15c0-1.4 1.2-2.2 2.6-2.2s2.6.8 2.6 2.2v.3H5.4V15zM12.5 9H17v1.6h-4.5zm0 3H17v1.6h-4.5z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 5h16a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1zm1 2v10h14V7H5zm2.5 2.5a1.8 1.8 0 1 1 0 3.6 1.8 1.8 0 0 1 0-3.6zM5.4 15c0-1.4 1.2-2.2 2.6-2.2s2.6.8 2.6 2.2v.3H5.4V15zM12.5 9H17v1.6h-4.5zm0 3H17v1.6h-4.5z'/></svg>")}
.i-perm{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2l8 3.2v6.1c0 4.6-3.2 8.6-8 10.7-4.8-2.1-8-6.1-8-10.7V5.2L12 2zm0 2.2L5.5 6.8v4.5c0 3.6 2.4 6.9 6.5 8.8 4.1-1.9 6.5-5.2 6.5-8.8V6.8L12 4.2zm0 4a2.6 2.6 0 0 1 1.3 4.85V16h-2.6v-2.95A2.6 2.6 0 0 1 12 8.2z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2l8 3.2v6.1c0 4.6-3.2 8.6-8 10.7-4.8-2.1-8-6.1-8-10.7V5.2L12 2zm0 2.2L5.5 6.8v4.5c0 3.6 2.4 6.9 6.5 8.8 4.1-1.9 6.5-5.2 6.5-8.8V6.8L12 4.2zm0 4a2.6 2.6 0 0 1 1.3 4.85V16h-2.6v-2.95A2.6 2.6 0 0 1 12 8.2z'/></svg>")}
.i-staff{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M9 11a3.4 3.4 0 1 0 0-6.8A3.4 3.4 0 0 0 9 11zm0 1.8c-3.3 0-6 1.7-6 4.2V19h12v-2c0-2.5-2.7-4.2-6-4.2zM16.6 11.2a2.9 2.9 0 1 0-1.5-5.55A4.5 4.5 0 0 1 14.6 8c0 .9-.2 1.7-.7 2.5.4.1.9.2 1.4.3zM17.4 12.9c1.6.5 2.6 1.6 2.6 3.1v2h-2.6v-2c0-1.2-.4-2.3-1.2-3.1h1.2z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M9 11a3.4 3.4 0 1 0 0-6.8A3.4 3.4 0 0 0 9 11zm0 1.8c-3.3 0-6 1.7-6 4.2V19h12v-2c0-2.5-2.7-4.2-6-4.2zM16.6 11.2a2.9 2.9 0 1 0-1.5-5.55A4.5 4.5 0 0 1 14.6 8c0 .9-.2 1.7-.7 2.5.4.1.9.2 1.4.3zM17.4 12.9c1.6.5 2.6 1.6 2.6 3.1v2h-2.6v-2c0-1.2-.4-2.3-1.2-3.1h1.2z'/></svg>")}
.i-chart{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 20V10h3v10H4zm6.5 0V4h3v16h-3zM17 20v-7h3v7h-3z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 20V10h3v10H4zm6.5 0V4h3v16h-3zM17 20v-7h3v7h-3z'/></svg>")}
.i-print{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M7 3h10v4H7V3zm-3 5h16a2 2 0 012 2v6h-4v5H6v-5H2v-6a2 2 0 012-2zm3 9h10v4H7v-4zm10-5a1 1 0 100 2 1 1 0 000-2z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M7 3h10v4H7V3zm-3 5h16a2 2 0 012 2v6h-4v5H6v-5H2v-6a2 2 0 012-2zm3 9h10v4H7v-4zm10-5a1 1 0 100 2 1 1 0 000-2z'/></svg>")}
.i-out{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M13 3h8v8h-2V6.4l-8.3 8.3-1.4-1.4L17.6 5H13V3zM4 5h7v2H6v11h11v-5h2v7H4V5z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M13 3h8v8h-2V6.4l-8.3 8.3-1.4-1.4L17.6 5H13V3zM4 5h7v2H6v11h11v-5h2v7H4V5z'/></svg>")}
.i-alert{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2l10 18H2L12 2zm0 3.6L5.3 18h13.4L12 5.6zM11 9h2v5h-2V9zm0 6.5h2V18h-2v-2.5z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2l10 18H2L12 2zm0 3.6L5.3 18h13.4L12 5.6zM11 9h2v5h-2V9zm0 6.5h2V18h-2v-2.5z'/></svg>")}
/* 成品仓：厂房（屋顶 + 货架）轮廓，跟「订单管理」的立方体区分开 */
.i-wh{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2 2 7.5V22h20V7.5L12 2zm0 2.2 8 4.4V20h-5v-6H9v6H4V8.6l8-4.4zM9 12h2v2H9v-2zm4 0h2v2h-2v-2z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2 2 7.5V22h20V7.5L12 2zm0 2.2 8 4.4V20h-5v-6H9v6H4V8.6l8-4.4zM9 12h2v2H9v-2zm4 0h2v2h-2v-2z'/></svg>")}
/* 生产工单：夹板工单（顶部夹子 + 清单行），比纯白纸更像「任务单」 */
.i-woc{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M5 5h14a1 1 0 0 1 1 1v15a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1zM8 12h8v-2H8zm0 4h8v-2H8zm0 4h5v-2H8zM9 2h6a1 1 0 0 1 1 1v3H8V3a1 1 0 0 1 1-1z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M5 5h14a1 1 0 0 1 1 1v15a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1zM8 12h8v-2H8zm0 4h8v-2H8zm0 4h5v-2H8zM9 2h6a1 1 0 0 1 1 1v3H8V3a1 1 0 0 1 1-1z'/></svg>")}
/* 订单管理：带折角的单据（与产品与工艺的立方体区分） */
.i-doc{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M6 3a1 1 0 0 1 1-1h8l5 5v14a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V3zm9-.5V7h4.5L15 2.5zM9 14h6v-2H9zm0 4h6v-2H9z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M6 3a1 1 0 0 1 1-1h8l5 5v14a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V3zm9-.5V7h4.5L15 2.5zM9 14h6v-2H9zm0 4h6v-2H9z'/></svg>")}
/* 采购申请：购物袋（与分组头的购物车区分） */
.i-bag{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2a5 5 0 0 1 5 5v1h3.2a1 1 0 0 1 1 1.1l-1.2 11a2 2 0 0 1-2 1.9H6a2 2 0 0 1-2-1.9l-1.2-11A1 1 0 0 1 3.8 8H7V7a5 5 0 0 1 5-5zm3 6V7a3 3 0 0 0-6 0v1h6z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2a5 5 0 0 1 5 5v1h3.2a1 1 0 0 1 1 1.1l-1.2 11a2 2 0 0 1-2 1.9H6a2 2 0 0 1-2-1.9l-1.2-11A1 1 0 0 1 3.8 8H7V7a5 5 0 0 1 5-5zm3 6V7a3 3 0 0 0-6 0v1h6z'/></svg>")}
/* 质检管理分组头：盾牌 + 对勾（与出厂检验的对勾区分） */
.i-shield{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2l8 3v6c0 5.2-3.4 8.6-8 11-4.6-2.4-8-5.8-8-11V5l8-3zm0 2.2L6 6.4V11c0 4 2.6 6.8 6 8.8 3.4-2 6-4.8 6-8.8V6.4l-6-2.2zM9.2 12.8l1.4-1.4 2 2 3.6-3.6 1.4 1.4-5 5z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2l8 3v6c0 5.2-3.4 8.6-8 11-4.6-2.4-8-5.8-8-11V5l8-3zm0 2.2L6 6.4V11c0 4 2.6 6.8 6 8.8 3.4-2 6-4.8 6-8.8V6.4l-6-2.2zM9.2 12.8l1.4-1.4 2 2 3.6-3.6 1.4 1.4-5 5z'/></svg>")}
/* 后台管理：显示器 + 支架（与分组头的齿轮区分） */
.i-sys{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M2 3h20v3H2zM2 14h20v3H2zM2 3h3v14H2zM19 3h3v14h-3zM10 17h4v3h-4zM6 20h12v2H6z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M2 3h20v3H2zM2 14h20v3H2zM2 3h3v14H2zM19 3h3v14h-3zM10 17h4v3h-4zM6 20h12v2H6z'/></svg>")}
/* 仓库管理分组头：双层货架 + 货箱（与物料仓的料箱、成品仓的厂房区分） */
.i-whg{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 2h2v20H4zM18 2h2v20h-2zM4 2h16v2H4zM6 11h12v2H6zM6 19h12v2H6zM8 8h3v3H8zM14 8h3v3h-3zM8 15h3v4H8zM14 15h2v4h-2z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 2h2v20H4zM18 2h2v20h-2zM4 2h16v2H4zM6 11h12v2H6zM6 19h12v2H6zM8 8h3v3H8zM14 8h3v3h-3zM8 15h3v4H8zM14 15h2v4h-2z'/></svg>")}
/* 物料仓：敞口料箱 + 上方三颗物料颗粒（与成品仓的「厂房」图标区分） */
.i-mat{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M5.6 9h12.8L20 21H4L5.6 9zm2 2-.5 3h9.8l-.5-3H7.6zM7.4 16l.5 3h8.2l.5-3H7.4z'/><circle cx='8' cy='4' r='1.6'/><circle cx='12.5' cy='2.8' r='1.6'/><circle cx='16.6' cy='4.6' r='1.6'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M5.6 9h12.8L20 21H4L5.6 9zm2 2-.5 3h9.8l-.5-3H7.6zM7.4 16l.5 3h8.2l.5-3H7.4z'/><circle cx='8' cy='4' r='1.6'/><circle cx='12.5' cy='2.8' r='1.6'/><circle cx='16.6' cy='4.6' r='1.6'/></svg>")}

/* 采购：购物车（申请单）+ 货箱（商品库），和委外/成品仓区分开 */
.i-pur{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M7 18a2 2 0 1 0 .001 4.001A2 2 0 0 0 7 18zm10 0a2 2 0 1 0 .001 4.001A2 2 0 0 0 17 18zM8.2 14h9.5c.9 0 1.6-.6 1.8-1.4L21.8 5H6.3L5.9 3H2v2h2.3l2.5 11.1c.1.5.6.9 1.1.9h12.1v-2H8.2zM7.2 7h12.3l-1.5 5H8.6L7.2 7z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M7 18a2 2 0 1 0 .001 4.001A2 2 0 0 0 7 18zm10 0a2 2 0 1 0 .001 4.001A2 2 0 0 0 17 18zM8.2 14h9.5c.9 0 1.6-.6 1.8-1.4L21.8 5H6.3L5.9 3H2v2h2.3l2.5 11.1c.1.5.6.9 1.1.9h12.1v-2H8.2zM7.2 7h12.3l-1.5 5H8.6L7.2 7z'/></svg>")}
.i-purbox{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M21 8l-9-6-9 6v8l9 6 9-6V8zm-9 1.2L5.6 6 12 2.7 18.4 6 12 9.2zM4 9.6l7 3.7v6.9l-7-4.7V9.6zm9 10.6v-6.9l7-3.7v5.9l-7 4.7z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M21 8l-9-6-9 6v8l9 6 9-6V8zm-9 1.2L5.6 6 12 2.7 18.4 6 12 9.2zM4 9.6l7 3.7v6.9l-7-4.7V9.6zm9 10.6v-6.9l7-3.7v5.9l-7 4.7z'/></svg>")}
.i-site{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 4h7v7H4zm9 0h7v7h-7zM4 13h7v7H4zm9 0h7v7h-7z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 4h7v7H4zm9 0h7v7h-7zM4 13h7v7H4zm9 0h7v7h-7z'/></svg>")}
.i-sliders{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M3 17v2h6v-2H3zM3 5v2h10V5H3zm10 16v-2h8v-2h-8v-2h-2v6h2zM7 9v2H3v2h4v2h2V9H7zm14 4v-2H11v2h10zm-6-4h2V7h4V5h-4V3h-2v6z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M3 17v2h6v-2H3zM3 5v2h10V5H3zm10 16v-2h8v-2h-8v-2h-2v6h2zM7 9v2H3v2h4v2h2V9H7zm14 4v-2H11v2h10zm-6-4h2V7h4V5h-4V3h-2v6z'/></svg>")}
.who{display:flex;gap:9px;align-items:center}
.avatar{width:30px;height:30px;border-radius:50%;background:var(--brand-soft);color:var(--brand-flat);display:flex;align-items:center;justify-content:center;font-weight:600;font-size:13px;flex:0 0 30px}
.who-name{font-size:13px;font-weight:600;line-height:1.3}
.who-role{font-size:11px;color:var(--ink3)}
.logout{display:block;margin-top:9px;font-size:12px;color:var(--ink3)}
.logout:hover{color:var(--bad)}
.icp{font-size:10.5px;color:var(--ink3);margin-top:8px;line-height:1.4}
/* 收起态只是淡出，不 display:none —— 否则过渡一挂就直接消失，收放会"抽一下" */
html.sb-free .icp{transition:opacity .16s ease}
html.sb-collapsed .icp{max-height:0;margin-top:0;overflow:hidden}

.main{flex:1;min-width:0;padding:22px 26px 60px}
.topbar{display:flex;align-items:center;justify-content:space-between;margin-bottom:18px;gap:16px;flex-wrap:wrap}
.topbar h1{font-size:20px;letter-spacing:-.2px}
.top-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap}

/* ---------- 通用组件 ---------- */
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow)}
.card-pad{padding:16px 18px}
.card-hd{display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:14px 18px;border-bottom:1px solid var(--line2);flex-wrap:wrap;
  position:relative;z-index:30}
.card-hd h3{font-size:14px;flex:none}
.card-hd .more{font-size:12.5px;color:var(--brand-flat)}
/* 卡片头右侧：筛选条 + 操作按钮排一行，自动靠右 */
.hd-right{display:flex;align-items:center;gap:10px;margin-left:auto;flex-wrap:wrap}
/* 卡片头里的筛选条一律去掉独立条的衬底（衬底只给表格上方的独立筛选条用），
   控件高度统一 30px，跟 .btn.sm 一致，免得一行里高矮不齐 */
.card-hd .flt,.hd-right .flt{padding:0;border:0}
.card-hd .flt-input,.card-hd .flt-input input,.card-hd .flt-dd-btn{height:30px}
.card-hd .btn.sm{height:30px}

/* 岗位卡片：原地操作的小提示（做成只在卡片内出现，不打断页面） */
#postCard .card-hd{display:flex;align-items:center;gap:10px}
.post-toast{margin-left:auto;font-size:12px;color:var(--ok,#0f9d58);font-weight:500;
  opacity:0;transform:translateY(-2px);transition:.18s;pointer-events:none;white-space:nowrap}
.post-toast.on{opacity:1;transform:none}
.post-toast.bad{color:var(--bad,#dc2626)}
/* 已停用的岗位行整体压暗，删除按钮也收掉 */
tr.post-off td:first-child input{color:var(--ink3);text-decoration:line-through;opacity:.7}
.hd-sum{font-size:12.5px;color:var(--ink3);white-space:nowrap}
.grid{display:grid;gap:14px}
.g4{grid-template-columns:repeat(4,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g2{grid-template-columns:repeat(2,1fr)}
@media(max-width:1180px){.g4{grid-template-columns:repeat(2,1fr)}.g3{grid-template-columns:repeat(2,1fr)}}
@media(max-width:760px){.g4,.g3,.g2{grid-template-columns:1fr}}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:34px;padding:0 14px;border-radius:8px;border:1px solid var(--line);background:var(--panel);color:var(--ink);font-size:13px;cursor:pointer;transition:.12s;white-space:nowrap}
.btn:hover{border-color:var(--line);background:var(--gray-soft)}
.btn.primary{background:var(--brand);background-image:var(--brand);border-color:var(--brand-flat);color:var(--on-brand)}
.btn.primary:hover{background:var(--brand-d);border-color:var(--brand-d)}
.btn.danger{color:var(--bad);border-color:#f3c8c8}
.btn.danger:hover{background:var(--bad-soft)}
.btn.sm{height:28px;padding:0 10px;font-size:12px}
.btn.block{width:100%}
.btn:disabled{opacity:.5;cursor:not-allowed}

.tag{display:inline-flex;align-items:center;gap:4px;height:22px;padding:0 8px;border-radius:6px;font-size:12px;background:var(--gray-soft);color:var(--ink2);font-weight:500}
.tag.ok{background:var(--ok-soft);color:var(--ok)}
.tag.warn{background:var(--warn-soft);color:var(--warn)}
.tag.bad{background:var(--bad-soft);color:var(--bad)}
.tag.info{background:var(--brand-soft);color:var(--brand-flat)}
.tag.urgent{background:#fff1f0;color:#cf1322}

.stat{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);padding:16px 18px;box-shadow:var(--shadow)}
.stat .lab{font-size:12.5px;color:var(--ink3);margin-bottom:8px}
.stat .num{font-size:28px;font-weight:600;letter-spacing:-.5px;line-height:1.1}
.stat .num small{font-size:12.5px;font-weight:400;color:var(--ink3);margin-left:6px;letter-spacing:0}
.stat .sub{font-size:12px;color:var(--ink3);margin-top:8px}
.stat.hl .num{color:var(--brand-flat)}

table.tb{font-size:13px}
.tb th{text-align:left;font-weight:500;color:var(--ink3);font-size:12px;padding:10px 12px;border-bottom:1px solid var(--line);white-space:nowrap;background:var(--gray-soft)}
.tb td{padding:11px 12px;border-bottom:1px solid var(--line2);vertical-align:middle}
.tb tr:last-child td{border-bottom:0}
.tb tr:hover td{background:var(--gray-soft)}
.tb .num{font-variant-numeric:tabular-nums}
.tb-wrap{overflow-x:auto}

.empty{padding:48px 20px;text-align:center;color:var(--ink3);font-size:13px}
.empty b{display:block;color:var(--ink2);font-size:14px;margin-bottom:6px;font-weight:600}

.field{margin-bottom:14px}
.field label{display:block;font-size:12.5px;color:var(--ink2);margin-bottom:6px;font-weight:500}
.field label .req{color:var(--bad);margin-left:2px}
.field input,.field select,.field textarea{width:100%;height:38px;padding:0 11px;border:1px solid var(--line);border-radius:8px;font-size:14px;background:var(--panel);color:var(--ink);font-family:inherit;transition:.12s}
.field textarea{height:auto;padding:9px 11px;min-height:76px;resize:vertical}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--brand-flat);box-shadow:0 0 0 3px rgba(37,99,235,.1)}
.field .hint{font-size:11.5px;color:var(--ink3);margin-top:5px}
.row{display:flex;gap:12px}
.row>*{flex:1;min-width:0}

.progress{height:5px;background:var(--line2);border-radius:3px;overflow:hidden;min-width:60px}
.progress>i{display:block;height:100%;background:var(--brand);background-image:var(--brand);border-radius:3px;transition:width .3s}
.progress.done>i{background:var(--ok)}

/* ---------- 登录 ---------- */
.login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px;
  background:radial-gradient(1200px 600px at 50% -10%,#e8eeff,transparent),var(--bg)}
.login-box{width:100%;max-width:376px;background:var(--panel);border:1px solid var(--line);border-radius:16px;padding:32px 28px;box-shadow:0 8px 40px rgba(16,24,40,.08)}
.login-box .logo{width:44px;height:44px;border-radius:12px;background:linear-gradient(135deg,#2563eb,#4f46e5);margin-bottom:14px;position:relative}
.login-box .logo::after{content:"";position:absolute;top:12px;right:12px;bottom:12px;left:12px;border:2.5px solid #fff;border-radius:4px;border-bottom-color:transparent;border-right-color:transparent;transform:rotate(-45deg)}
.login-box h2{font-size:19px;margin-bottom:6px}
.login-box .desc{font-size:13px;color:var(--ink3);margin-bottom:18px}
/* ================= 操作提醒：右侧浮出的小卡片 ================= */
.alert{position:relative;display:flex;align-items:flex-start;gap:10px;
  padding:11px 14px 12px;border-radius:12px;font-size:13px;margin-bottom:14px;
  border:1px solid transparent;overflow:hidden;line-height:1.5;flex-shrink:0}
.alert::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px}
.alert .al-ico{width:18px;height:18px;flex:0 0 18px;margin-top:1px;border-radius:50%;
  display:flex;align-items:center;justify-content:center}
.alert .al-ico svg{width:11px;height:11px}
.alert .al-txt{flex:1;min-width:0}
.alert .al-x{flex:none;width:20px;height:20px;border:0;background:transparent;cursor:pointer;
  color:currentColor;opacity:.45;border-radius:6px;font-size:15px;line-height:1;
  display:flex;align-items:center;justify-content:center;padding:0;margin-top:-1px}
.alert .al-x:hover{opacity:.9}

.alert.ok{background:linear-gradient(180deg,#f1faf4,#e9f7ee);color:#0f7a3d;
  border-color:#c9ecd6;box-shadow:0 1px 2px rgba(16,120,60,.06)}
.alert.ok::before{background:linear-gradient(180deg,#22c55e,#16a34a)}
.alert.ok .al-ico{background:#16a34a;color:#fff}

.alert.bad{background:linear-gradient(180deg,#fef3f3,#fdeceb);color:#b91c1c;
  border-color:#f6d2d2;box-shadow:0 1px 2px rgba(180,40,40,.06)}
.alert.bad::before{background:linear-gradient(180deg,#f87171,#dc2626)}
.alert.bad .al-ico{background:#dc2626;color:#fff}

/* 自动消失：底部一条进度线走完就淡出 */
.alert-flash{animation:alertIn .26s cubic-bezier(.34,1.4,.64,1)}
.alert-flash::after{content:"";position:absolute;left:0;bottom:0;height:2px;
  background:currentColor;opacity:.28;animation:alertBar 4s linear forwards}
.alert-flash.hide{opacity:0;transform:translateY(-6px);transition:opacity .32s ease,transform .32s ease}
@keyframes alertIn{from{opacity:0;transform:translateY(-8px) scale(.99)}to{opacity:1;transform:none}}
@keyframes alertBar{from{width:100%}to{width:0}}

/* ================= 列表搜索 + 字段筛选（靠右） ================= */
.flt{padding:0 18px 12px;border-bottom:1px solid var(--line2)}
.flt-form{display:flex;flex-direction:column;gap:0}

/* 顶栏：只放右侧的「搜索框 + 筛选」 */
.flt-bar{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:wrap;
  position:relative}

/* ---- 搜索框 ---- */
.flt-input{position:relative;display:flex;align-items:center;width:250px;height:32px}
.flt-input > svg{position:absolute;left:10px;color:var(--ink3);pointer-events:none}
.flt-input input{width:100%;height:32px;padding:0 10px 0 31px;border:1px solid var(--line);
  border-radius:8px;background:var(--panel);font-size:12.5px;outline:none;
  font-family:inherit;color:var(--ink);transition:.12s}
.flt-input input::placeholder{color:var(--ink3)}
.flt-input input:focus{border-color:color-mix(in srgb,var(--brand-flat) 55%,var(--line));
  box-shadow:0 0 0 3px color-mix(in srgb,var(--brand-flat) 12%,transparent)}

/* ---- 筛选下拉按钮 ---- */
.flt-dd{position:relative}
.flt-dd-btn{display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 10px;
  border:1px solid var(--line);border-radius:8px;background:var(--panel);color:var(--ink2);
  font-size:12.5px;font-family:inherit;cursor:pointer;transition:.12s;white-space:nowrap}
.flt-dd-btn:hover{border-color:color-mix(in srgb,var(--brand-flat) 45%,var(--line));color:var(--brand-flat)}
.flt-dd-btn.open{background:var(--brand-soft);color:var(--brand-flat);
  border-color:color-mix(in srgb,var(--brand-flat) 45%,var(--line))}
.flt-caret{transition:transform .16s;opacity:.7}
.flt-dd-btn.open .flt-caret{transform:rotate(180deg)}
.flt-dot{width:6px;height:6px;border-radius:50%;background:var(--brand);background-image:var(--brand);flex:none}
.flt-dot[hidden]{display:none}

/* ---- 下拉面板：右对齐，宽 290 ---- */
/* 面板脱离父级层叠上下文：卡片 / 表头 / tb-wrap 的 overflow 都裁不到它，
   位置由 app.js 按按钮的实际位置算出来（见 placePanel） */
.flt-dd-panel{position:fixed;top:0;left:0;width:290px;z-index:900;
  background:var(--panel);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 14px 34px -12px rgba(15,23,42,.3);overflow:hidden;
  animation:ddIn .14s ease}
@keyframes ddIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.flt-dd-panel[hidden]{display:none}

.flt-dd-hd{display:flex;align-items:center;justify-content:space-between;
  padding:10px 12px 6px;font-size:11.5px;font-weight:600;color:var(--ink3);letter-spacing:.2px}
.flt-dd-all{border:0;background:transparent;color:var(--brand-flat);font-size:11.5px;
  cursor:pointer;font-family:inherit;padding:2px 4px;border-radius:5px}
.flt-dd-all:hover{background:var(--brand-soft)}

.flt-dd-list{max-height:212px;overflow-y:auto;padding:2px 6px 6px}
.flt-dd-sep{height:1px;background:var(--line2);margin:6px 0}

/* 勾选项 */
.flt-opt{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:7px;
  font-size:12.5px;color:var(--ink2);cursor:pointer;transition:background .1s}
.flt-opt:hover{background:var(--gray-soft)}
.flt-opt input{position:absolute;opacity:0;width:0;height:0}
.flt-opt-box{width:15px;height:15px;flex:none;border:1.5px solid var(--line);
  border-radius:4px;background:var(--panel);display:flex;align-items:center;justify-content:center;
  color:#fff;transition:.12s}
.flt-opt input:checked + .flt-opt-box{background:var(--brand);background-image:var(--brand);border-color:var(--brand-flat)}
.flt-opt input:checked + .flt-opt-box svg{opacity:1}
.flt-opt-box svg{opacity:0;transition:opacity .1s}
.flt-opt input:checked ~ .flt-opt-t{color:var(--brand-flat);font-weight:500}
.flt-opt-t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* 精确过滤行 */
.flt-pick{display:flex;align-items:center;gap:8px;padding:4px 8px}
.flt-pick .flt-opt-t{font-size:12.5px;color:var(--ink2)}
.flt-pick-sel{flex:none;width:118px;height:26px;border:1px solid var(--line);border-radius:6px;
  background:var(--panel);color:var(--ink);font-size:12px;padding:0 4px;
  font-family:inherit;outline:none;cursor:pointer}
.flt-pick-sel:focus{border-color:color-mix(in srgb,var(--brand-flat) 55%,var(--line))}

.flt-dd-tip{padding:2px 12px 8px;font-size:11px;color:var(--ink3)}
.flt-dd-foot{display:flex;align-items:center;justify-content:flex-end;gap:8px;
  padding:8px 12px;border-top:1px solid var(--line2);background:var(--gray-soft)}
.flt-dd-clear{border:0;background:transparent;color:var(--ink3);font-size:12px;
  cursor:pointer;font-family:inherit;margin-right:auto;padding:2px 4px;border-radius:5px}
.flt-dd-clear:hover{color:var(--bad);background:var(--bad-soft)}

/* ---- 已生效条件胶囊（搜索框左侧区域自动让位） ---- */
.flt-chips{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.flt-chip{display:inline-flex;align-items:center;gap:5px;height:26px;padding:0 4px 0 9px;
  border-radius:20px;background:var(--brand-soft);
  border:1px solid color-mix(in srgb,var(--brand-flat) 22%,transparent);
  font-size:12px;color:var(--ink2);animation:chipIn .16s ease}
@keyframes chipIn{from{opacity:0;transform:scale(.94)}to{opacity:1;transform:none}}
.flt-chip b{font-weight:600;color:var(--brand-flat);white-space:nowrap}
.flt-chip em{font-style:normal;color:var(--ink);font-weight:500;max-width:140px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.flt-chip-x{width:16px;height:16px;flex:none;border:0;border-radius:50%;background:transparent;
  color:var(--ink3);font-size:14px;line-height:1;cursor:pointer;display:flex;
  align-items:center;justify-content:center;padding:0;transition:.12s}
.flt-chip-x:hover{background:var(--bad-soft);color:var(--bad)}

/* 筛选条下方的小提示条（如"正在看某天"） */
.flt-tip{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:8px 18px;border-bottom:1px solid var(--line2);
  font-size:12px;color:var(--ink3);background:var(--gray-soft)}
.flt-tip b{color:var(--ink2);font-weight:600}
.cnt{display:inline-block;margin-left:7px;font-size:11.5px;font-weight:600;color:var(--ink3);
  background:var(--gray-soft);padding:1px 7px;border-radius:20px;vertical-align:2px}
.flt-hint{font-size:12px;color:var(--ink3)}
.flt-hint{font-size:12px;color:var(--ink3)}
.flt-hint{font-size:12px;color:var(--ink3)}
.divider{display:flex;align-items:center;gap:10px;color:var(--ink3);font-size:11.5px;margin:18px 0}
.divider::before,.divider::after{content:"";flex:1;height:1px;background:var(--line)}
/* 企业微信扫码登录按钮：用企微品牌绿，区别于普通按钮 */
.wxbtn{background:#0082ef;border-color:#0082ef;color:#fff;font-weight:500;
  box-shadow:0 4px 14px rgba(0,130,239,.28)}
.wxbtn:hover{background:#0072d6;border-color:#0072d6;color:#fff;
  box-shadow:0 6px 18px rgba(0,130,239,.36)}

/* ---------- 报工页（移动优先） ---------- */
.mobile{background:var(--bg);min-height:100vh;padding-bottom:96px}
.m-top{background:var(--panel);padding:14px 16px;border-bottom:1px solid var(--line);position:sticky;top:0;z-index:10}
.m-top .t1{font-size:15px;font-weight:600}
.m-top .t2{font-size:12px;color:var(--ink3);margin-top:3px}
.m-body{padding:14px}
.mcard{background:var(--panel);border-radius:12px;padding:16px;margin-bottom:12px;border:1px solid var(--line)}
.mcard h4{font-size:13px;color:var(--ink2);margin-bottom:12px;font-weight:600}
.step{display:flex;gap:10px;align-items:flex-start;padding:11px 0;border-bottom:1px dashed var(--line2)}
.step:last-child{border-bottom:0}
.step .dot{width:22px;height:22px;border-radius:50%;flex:0 0 22px;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600;background:var(--gray-soft);color:var(--ink3);margin-top:1px}
.step.done .dot{background:var(--ok);color:#fff}
.step.cur .dot{background:var(--brand);background-image:var(--brand);color:var(--on-brand)}
.step .nm{font-size:14px;font-weight:500}
.step.done .nm{color:var(--ink3)}
.step .meta{font-size:11.5px;color:var(--ink3);margin-top:2px}
.pick{display:block;border:1.5px solid var(--line);border-radius:10px;padding:12px 14px;margin-bottom:9px;cursor:pointer;transition:.12s}
.pick:has(input:checked){border-color:var(--brand-flat);background:var(--brand-soft)}
.pick input{display:none}
.pick .pn{font-size:14.5px;font-weight:600}
.pick .pm{font-size:12px;color:var(--ink3);margin-top:2px}
.big-input{width:100%;height:52px;border:1.5px solid var(--line);border-radius:10px;font-size:22px;font-weight:600;text-align:center;padding:0 12px;font-variant-numeric:tabular-nums}
.big-input:focus{outline:none;border-color:var(--brand-flat);box-shadow:0 0 0 3px rgba(37,99,235,.1)}
.msubmit{position:fixed;left:0;right:0;bottom:0;padding:12px 16px calc(12px + env(safe-area-inset-bottom));background:var(--panel);border-top:1px solid var(--line)}
.msubmit .btn{height:48px;font-size:16px;border-radius:10px}
.mine{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--ink2);background:var(--gray-soft);padding:9px 12px;border-radius:8px}
.mine b{color:var(--ink)}
.toast{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);z-index:99;
  padding:15px 22px;border-radius:18px;font-size:14px;max-width:80vw;text-align:center;line-height:1.6;
  color:#f4f6fb;isolation:isolate;overflow:hidden;
  background:linear-gradient(140deg,rgba(30,36,48,.82),rgba(16,20,30,.72));
  -webkit-backdrop-filter:blur(22px) saturate(1.5);backdrop-filter:blur(22px) saturate(1.5);
  border:1px solid rgba(255,255,255,.16);
  box-shadow:0 26px 60px -14px rgba(8,12,22,.55),0 4px 16px -6px rgba(8,12,22,.4),
    inset 0 1px 0 rgba(255,255,255,.14),inset 0 -1px 0 rgba(255,255,255,.04);
  animation:glassToastIn .45s cubic-bezier(.22,1.32,.36,1)}
/* 顶部一道斜向高光，模拟玻璃反光面 */
.toast::before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;pointer-events:none;
  background:radial-gradient(120% 90% at 18% -10%,rgba(255,255,255,.14),transparent 55%)}
@keyframes glassToastIn{
  0%{opacity:0;transform:translate(-50%,-50%) scale(.86)}
  62%{opacity:1;transform:translate(-50%,-50%) scale(1.03)}
  100%{opacity:1;transform:translate(-50%,-50%) scale(1)}}

/* ---------- 打印 ---------- */
@media print{
  .sidebar,.topbar,.no-print{display:none!important}
  .main{padding:0}
  body{background:#fff}
  .print-sheet{border:0!important;box-shadow:none!important;page-break-after:always}
}
.print-sheet{background:#fff;border:1px solid #ccc;max-width:1000px;margin:0 auto;padding:22px 26px}

/* ---------- 筛选栏 ---------- */
.filters{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.filters input,.filters select{height:32px;padding:0 10px;border:1px solid var(--line);border-radius:8px;font-size:13px;background:var(--panel);color:var(--ink);font-family:inherit;min-width:130px}
.filters input[type=search]{min-width:190px}
.filters input:focus,.filters select:focus{outline:none;border-color:var(--brand-flat);box-shadow:0 0 0 3px rgba(37,99,235,.1)}
.inline-form{display:flex;gap:6px;align-items:center}
.inline-form input{height:28px;padding:0 8px;border:1px solid var(--line);border-radius:7px;font-size:12.5px;font-family:inherit}

/* ---------- 复选框 / chips ---------- */
.check{display:flex;gap:8px;align-items:center;font-size:13px;color:var(--ink2);cursor:pointer;margin-top:4px}
.check input{width:16px;height:16px;margin:0;flex:0 0 16px;accent-color:var(--brand-flat)}
.chips{display:flex;gap:8px;flex-wrap:wrap}
.chip{height:32px;padding:0 12px;border-radius:8px;border:1px solid var(--line);background:var(--panel);font-size:13px;color:var(--ink2);cursor:pointer;font-family:inherit;transition:.12s}
.chip:hover{border-color:#c9d3e5}
.chip.on{border-color:var(--bad);background:var(--bad-soft);color:var(--bad);font-weight:500}
.chip-check{display:inline-flex;align-items:center;gap:6px;padding:6px 11px;border:1px solid var(--line);border-radius:8px;font-size:13px;cursor:pointer;background:var(--panel);transition:.12s}
.chip-check:hover{border-color:#c9d3e5}
.chip-check input{width:14px;height:14px;margin:0;accent-color:var(--brand-flat)}
.chip-check:has(input:checked){border-color:var(--brand-flat);background:var(--brand-soft);color:var(--brand-flat)}
.chip-check small{color:var(--ink3);font-size:11px}

/* ---------- 键值列表 ---------- */
.kv{font-size:13px}
.kv>div{display:flex;justify-content:space-between;gap:12px;padding:8px 0;border-bottom:1px dashed var(--line2)}
.kv>div:last-child{border-bottom:0}
.kv span{color:var(--ink3);flex:0 0 auto;font-size:12.5px}
.kv b{font-weight:500;text-align:right;word-break:break-all}

/* ---------- 时间轴（流转卡详情） ---------- */
.timeline{position:relative}
.tl-item{display:flex;gap:12px;align-items:flex-start;padding:12px 0;border-bottom:1px dashed var(--line2);position:relative}
.tl-item:last-child{border-bottom:0}
.tl-dot{width:26px;height:26px;border-radius:50%;flex:0 0 26px;display:flex;align-items:center;justify-content:center;
  font-size:12px;font-weight:600;background:var(--gray-soft);color:var(--ink3);margin-top:2px}
.tl-item.done .tl-dot{background:var(--ok);color:#fff}
.tl-item.cur .tl-dot{background:var(--brand);background-image:var(--brand);color:var(--on-brand);box-shadow:0 0 0 4px color-mix(in srgb,var(--brand-flat) 18%,transparent)}
.tl-body{flex:1;min-width:0}
.tl-head{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.tl-name{font-size:14px;font-weight:600}
.tl-item.done .tl-name{color:var(--ink2)}
.tl-meta{font-size:12px;color:var(--ink3);margin-top:3px}
.tl-nums{display:flex;gap:14px;font-size:12.5px;color:var(--ink2);margin-top:5px;flex-wrap:wrap}
.tl-nums b{font-variant-numeric:tabular-nums}

/* ---------- 二维码卡 ---------- */
.qr-box{text-align:center;padding:6px 0 14px;border-bottom:1px solid var(--line2);margin-bottom:12px}
.qr-box img{display:block;margin:0 auto;border:1px solid var(--line);border-radius:8px;background:var(--panel)}
.qr-tip{font-size:12px;color:var(--ink3);margin-top:8px}

/* ---------- 弹层 ---------- */
/* 层级规划（务必按此表，别再往上加）：
     .bot-wrap     2000000   左下角助手头像
     .bot-panel    2000100   助手对话面板
     .modal-mask   2001000   普通弹窗
     .fl-mask      2002000   表单布局弹窗（要高过它所在的普通弹窗）
     .lyt-modal    2003000   布局里的「预览」层
     .fl-props     2004000   字段属性层（最上层）
     .cf-mask      2005000   二次确认框（要盖住上面所有层：
                             在布局弹窗里点删除字段，确认框必须在最前面）

   注意：浏览器把 z-index 当 32 位有符号整数处理，超过 2147483647 会被
   直接钳制到 2147483647。原先这里写的是 2147484000~2147487000，全部越界后
   变成同一个值，导致「表单布局」弹窗被同页的「新增客户」弹窗盖住，
   保存/预览按钮点不到（现象就是点了没反应）。不要再写大于 2147483647 的数字。 */
.modal-mask{position:fixed;top:0;right:0;bottom:0;left:0;background:rgba(16,24,40,.45);display:flex;align-items:center;justify-content:center;
  z-index:2001000;padding:20px;animation:fadeIn .12s ease}
.modal-mask[hidden]{display:none}
/* 二次确认框（mesConfirm）：永远压在最上面，哪怕是从布局/属性弹窗里点出来的 */
.cf-mask{z-index:2005000}
.modal{background:var(--panel);border-radius:14px;padding:22px 24px;width:100%;max-width:480px;box-shadow:0 20px 60px rgba(16,24,40,.24);
  max-height:90vh;overflow:auto}
.modal h3{font-size:16px;margin-bottom:8px}
/* 弹窗底部操作区：贴底固定。长表单（如编辑员工）在小屏滚动时，
   保存按钮始终可见，不用滚到底才能提交 */
.modal-actions{position:sticky;bottom:-22px;z-index:2;
  display:flex;gap:8px;justify-content:flex-end;
  margin:14px -24px -22px;padding:12px 24px;
  background:var(--panel);border-top:1px solid var(--line);
  border-radius:0 0 14px 14px}
/* 贴底区上方加一点阴影，滚动时明确"下面还有内容" */
.modal-actions::before{content:"";position:absolute;left:0;right:0;top:-16px;height:16px;
  pointer-events:none;
  background:linear-gradient(transparent,color-mix(in srgb,var(--ink) 7%,transparent))}

/* ---------- 分体式弹窗：标题固定 / 内容滚动 / 底部按钮固定 ---------- */
.modal.split{display:flex;flex-direction:column;padding:0;max-height:90vh}
.modal.split .modal-hd{flex:none;padding:16px 20px 12px;border-bottom:1px solid var(--line)}
.modal.split .modal-hd h3{margin-bottom:2px}
.modal-hd-sub{font-size:12px;color:var(--ink3);font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
.modal.split .modal-bd{flex:1;min-height:0;overflow-y:auto;padding:16px 20px}
.modal.split .modal-ft{flex:none;padding:12px 20px;border-top:1px solid var(--line);
  display:flex;gap:8px;justify-content:flex-end;background:var(--panel);
  border-radius:0 0 14px 14px}
/* 内容区滚动条：细圆角半透明，不再出现系统粗滚动条 */
.modal.split .modal-bd::-webkit-scrollbar{width:8px}
.modal.split .modal-bd::-webkit-scrollbar-thumb{background:rgba(120,130,150,.28);border-radius:4px}
.modal.split .modal-bd::-webkit-scrollbar-thumb:hover{background:rgba(120,130,150,.45)}
.modal.split .modal-bd::-webkit-scrollbar-track{background:transparent}
.modal.split .modal-bd{scrollbar-width:thin;scrollbar-color:rgba(120,130,150,.3) transparent}
/* 重设登录密码：折叠块，默认收起不抢视线 */
.pwd-box{margin-top:14px;border:1px solid var(--line);border-radius:10px;background:var(--gray-soft)}
.pwd-box summary{padding:10px 13px;font-size:13px;color:var(--ink2);cursor:pointer;
  user-select:none;list-style:none;display:flex;align-items:center;gap:7px}
.pwd-box summary::-webkit-details-marker{display:none}
.pwd-box summary::before{content:'▸';font-size:11px;color:var(--ink3);transition:transform .15s}
.pwd-box[open] summary::before{transform:rotate(90deg)}
.pwd-box summary:hover{color:var(--ink)}
.pwd-box .pwd-row{display:flex;gap:8px;padding:0 13px 12px}
.pwd-box .pwd-row input{flex:1;height:34px;padding:0 11px;border:1px solid var(--line);
  border-radius:8px;font-family:inherit;background:var(--card,#fff);color:var(--ink)}
.modal-desc{font-size:12.5px;color:var(--ink2);line-height:1.7;margin:0 0 14px}
/* 弹窗内的即时错误：不跳页也要让人看见到底哪里不行 */
.modal-err{margin:0 0 12px;padding:9px 11px;border-radius:9px;font-size:12.5px;line-height:1.6;
  background:#fef3f2;color:#b42318;border:1px solid #fecdca}
.modal-err[hidden]{display:none}
/* 工号一行：只读展示 + 「改工号」按钮 */
.no-row{display:flex;gap:8px;align-items:center}
.no-row input{flex:1;min-width:0}
.no-row input[readonly]{background:var(--gray-soft);color:var(--ink2);cursor:default;
  border-color:transparent;box-shadow:none}
.no-row input[readonly]:focus{outline:none;border-color:var(--line)}
/* 提交中的按钮：视觉变灰但仍可按（disabled 会取消提交，见 employees.html 注释） */
.btn.busy{opacity:.72;pointer-events:none}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}

/* ---------- 产品/工艺预览 ---------- */
.preview-box{background:#fcfcfd;border:1px solid var(--line2);border-radius:10px;padding:4px 14px}
.pv-row{display:flex;justify-content:space-between;padding:10px 0;border-bottom:1px dashed var(--line2);font-size:13px}
.pv-row:last-child{border-bottom:0}
.pv-row span{color:var(--ink3)}
.pv-row b{font-weight:600}

/* ---------- 媒体网格 ---------- */
.media-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px}
.media-item{border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--panel);transition:.12s;display:block}
.media-item:hover{border-color:var(--brand-flat);box-shadow:0 2px 10px rgba(37,99,235,.1)}
.media-item img{width:100%;height:118px;object-fit:cover;display:block;background:var(--gray-soft)}
.media-file{height:118px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  background:var(--gray-soft);padding:8px}
.media-icon{font-size:22px;color:var(--ink2)}
.media-name{font-size:11px;color:var(--ink3);text-align:center;word-break:break-all;line-height:1.4;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.media-meta{font-size:11px;color:var(--ink3);padding:6px 8px;display:flex;justify-content:space-between;gap:4px;align-items:center}

/* ---------- 报工页补充 ---------- */
.mobile .hint{font-size:11.5px;color:var(--ink3);line-height:1.6}
.mobile .step .nm .tag{vertical-align:middle}
.quick-row{display:flex;gap:8px;margin-top:10px}
.quick{flex:1;height:38px;border:1px dashed var(--line);background:var(--panel);border-radius:9px;font-size:13px;
  color:var(--brand-flat);cursor:pointer;font-family:inherit;transition:.12s}
.quick:hover{background:var(--brand-soft);border-color:var(--brand-flat)}

/* ---------- 打印流转卡 ---------- */
.print-bar{display:flex;gap:10px;align-items:center;padding:14px 22px;background:#fff;border-bottom:1px solid var(--line);
  position:sticky;top:0;z-index:5}
.print-hint{font-size:12px;color:var(--ink3)}
.print-page{background:#eef0f4}
.print-page .print-sheet{margin:22px auto}
.card-sheet{padding:20px 22px;font-size:12.5px}
.ps-head{display:flex;justify-content:space-between;align-items:flex-start;border-bottom:2px solid #1a1d23;padding-bottom:10px;margin-bottom:12px}
.ps-title{font-size:21px;font-weight:700;letter-spacing:3px}
.ps-sub{font-size:11px;color:#5a6270;margin-top:4px;letter-spacing:1px}
.ps-no{text-align:right}
.ps-card-no{font-size:16px;font-weight:700;font-family:ui-monospace,Consolas,monospace}
.ps-order{font-size:11px;color:#5a6270;margin-top:3px}
.ps-info{width:100%;border:1px solid #1a1d23;font-size:12px;margin-bottom:12px}
.ps-info th{background:#f4f5f7;border:1px solid #c8ccd4;padding:6px 8px;font-weight:500;width:70px;text-align:left;color:#3a4150}
.ps-info td{border:1px solid #c8ccd4;padding:6px 8px}
.ps-info td.strong{font-weight:700;font-size:13px}
.ps-steps{width:100%;border:1px solid #1a1d23;font-size:12px}
.ps-steps th{background:#f4f5f7;border:1px solid #c8ccd4;padding:6px 5px;font-weight:500;color:#3a4150}
.ps-steps td{border:1px solid #c8ccd4;padding:7px 5px;height:26px}
.ps-steps td.c{text-align:center}
.ps-steps tr.rw td{background:#fffdf5}
.ps-steps tr.blank td{height:26px}
.ps-rw{font-size:10px;background:#fef6e7;color:#d97706;padding:1px 5px;border-radius:3px;margin-left:5px}
.ps-foot{display:flex;gap:18px;margin-top:14px;align-items:flex-start}
.ps-qr{text-align:center;flex:0 0 auto}
.ps-qr img{display:block;border:1px solid #c8ccd4;padding:4px;background:#fff}
.ps-qr-tip{font-size:10px;color:#5a6270;margin-top:4px;line-height:1.4}
.ps-notes{flex:1;font-size:11.5px;line-height:1.9;color:#3a4150}
.ps-note-line{margin-bottom:2px}
.ps-sign{display:flex;gap:22px;margin-top:16px;font-size:12px;color:#3a4150}
@media print{
  .print-page{background:#fff}
  .print-page .print-sheet{margin:0}
  .card-sheet{border:0;padding:0}
  @page{size:A5 landscape;margin:8mm}
}

/* ---------- 授权向导 ---------- */
.wstep{display:flex;gap:12px;padding:14px 0;border-bottom:1px dashed var(--line2)}
.wstep:first-child{padding-top:0}
.wstep-no{width:24px;height:24px;flex:0 0 24px;border-radius:50%;background:var(--brand-soft);
  color:var(--brand-flat);font-size:12px;font-weight:700;display:flex;align-items:center;justify-content:center;margin-top:2px}
.wstep-body{flex:1;min-width:0}
.wstep-title{font-size:14px;font-weight:600;margin-bottom:5px}
.wstep-desc{font-size:12.5px;color:var(--ink2);line-height:1.8}
.wstep-desc code{background:var(--gray-soft);padding:1px 5px;border-radius:4px;font-size:12px}
.wstep .field input{height:34px;font-size:13px}


/* ---------- 顶栏工具区 ---------- */
.tb-tools{display:flex;align-items:center;gap:8px}
.tb-icon{width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--line);background:var(--panel);border-radius:9px;color:var(--ink2);
  cursor:pointer;transition:.12s;padding:0}
.tb-icon:hover{border-color:color-mix(in srgb,var(--brand-flat) 45%,var(--line));color:var(--brand-flat);
  background:var(--brand-soft)}
.usermenu{position:relative}
.tb-user{display:flex;align-items:center;gap:5px;height:34px;padding:0 6px;border:0;
  background:transparent;border-radius:9px;cursor:pointer;font-family:inherit;color:var(--ink);transition:.12s}
.tb-user:hover{background:var(--gray-soft)}
.tb-user-name{font-size:13px;font-weight:500;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tb-caret{color:var(--ink3);transition:.15s}
.usermenu.open .tb-caret{transform:rotate(180deg)}
.avatar.sm{width:24px;height:24px;flex:0 0 24px;font-size:12px}
.user-drop{position:absolute;right:0;top:calc(100% + 8px);min-width:224px;background:var(--panel);
  border:1px solid var(--line);border-radius:14px;box-shadow:0 16px 44px rgba(16,24,40,.18),0 2px 8px rgba(16,24,40,.06);
  padding:6px;z-index:90;transform-origin:top right;animation:udIn .18s cubic-bezier(.2,1.1,.4,1)}
.user-drop[hidden]{display:none}
@keyframes udIn{from{opacity:0;transform:translateY(-6px) scale(.96)}to{opacity:1;transform:none}}
/* 头部：姓名/角色（不放头像，保持轻量） */
.ud-head{padding:10px 12px 11px;margin:-2px -2px 4px;border-radius:10px 10px 0 0;
  background:linear-gradient(135deg,color-mix(in srgb,var(--brand-flat) 10%,transparent),transparent 65%);
  border-bottom:1px solid var(--line2)}
.ud-who{min-width:0}
.ud-name{font-size:13.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ud-role{font-size:11.5px;color:var(--ink3);margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 菜单项：图标盒 + 标签 + 右侧灰字说明 */
.ud-item{display:flex;align-items:center;gap:10px;width:100%;height:38px;padding:0 10px;
  border-radius:9px;font-size:13px;color:var(--ink2);border:0;background:transparent;
  font-family:inherit;text-align:left;cursor:pointer;transition:background .12s,color .12s}
.ud-item:hover{background:var(--gray-soft);color:var(--ink)}
.ud-ico-box{width:26px;height:26px;flex:0 0 26px;border-radius:8px;display:flex;
  align-items:center;justify-content:center;background:var(--gray-soft);color:var(--ink3);
  transition:background .12s,color .12s}
.ud-item:hover .ud-ico-box{background:color-mix(in srgb,var(--brand-flat) 14%,transparent);color:var(--brand-flat)}
.ud-label{font-weight:500}
.ud-sub{margin-left:auto;font-size:11px;color:var(--ink3);font-weight:400;
  max-width:76px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ud-quit:hover{background:var(--bad-soft);color:var(--bad)}
.ud-quit:hover .ud-ico-box{background:color-mix(in srgb,var(--bad) 14%,transparent);color:var(--bad)}
/* 更新日志菜单项：有新版本时的小红点（跟在文字后面，不挤布局） */
.ud-dot{flex:none;width:7px;height:7px;border-radius:50%;background:var(--bad);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--bad) 18%,transparent)}
.ud-sep{height:1px;background:var(--line2);margin:4px 8px}

/* ---------- 看板车间切换 ---------- */
.ws-seg{display:flex;gap:6px;background:var(--gray-soft);padding:4px;border-radius:10px;
  margin-bottom:14px;flex-wrap:wrap;width:fit-content;max-width:100%;
  overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}
.ws-seg::-webkit-scrollbar{display:none}
.ws-seg .seg-b{flex:0 0 auto;height:30px;padding:0 15px;border:0;background:transparent;border-radius:7px;
  font-size:13px;color:var(--ink2);cursor:pointer;font-family:inherit;transition:.12s;white-space:nowrap;
  display:inline-flex;align-items:center}
.ws-seg .seg-b:hover{color:var(--ink)}
.ws-seg .seg-b.on{background:var(--panel);color:var(--brand-flat);font-weight:600;
  box-shadow:0 1px 3px rgba(16,24,40,.12)}
.ws-note{display:flex;align-items:center;justify-content:space-between;gap:12px;
  font-size:12.5px;color:var(--ink2);margin:-4px 0 14px;padding:8px 12px;
  background:var(--brand-soft);border-radius:8px}
.ws-note b{color:var(--brand-flat)}
.ws-note a{color:var(--brand-flat);font-size:12.5px;white-space:nowrap}
.sk-modal{max-width:520px;padding:0}
.sk-hd{display:flex;align-items:center;justify-content:space-between;padding:18px 22px 0}
.sk-hd h3{font-size:16px}
.sk-x{width:28px;height:28px;border:0;background:transparent;font-size:22px;line-height:1;
  color:var(--ink3);cursor:pointer;border-radius:6px;font-family:inherit}
.sk-x:hover{background:var(--gray-soft);color:var(--ink)}
.sk-modal .modal-desc{padding:0 22px;margin:6px 0 14px}
.sk-label{padding:0 22px;font-size:12px;color:var(--ink3);margin-bottom:9px;font-weight:500}
.sk-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;padding:0 22px 16px}
.sk-chip{display:flex;align-items:center;gap:7px;height:38px;padding:0 11px;border-radius:9px;
  border:1px solid var(--line);background:var(--panel);cursor:pointer;font-family:inherit;
  font-size:12.5px;color:var(--ink2);transition:.12s}
.sk-chip:hover{border-color:color-mix(in srgb,var(--brand-flat) 45%,var(--line))}
.sk-chip.on{border-color:var(--brand-flat);background:var(--brand-soft);color:var(--brand-flat);font-weight:600;
  box-shadow:0 0 0 3px color-mix(in srgb,var(--brand-flat) 13%,transparent)}
.sk-dot{width:15px;height:15px;border-radius:50%;flex:0 0 15px;box-shadow:inset 0 0 0 1px rgba(0,0,0,.1)}
/* 渐变主题的色块：方一点并加白边，才看得出"两种颜色过渡" */
.sk-dot-grad{border-radius:5px;box-shadow:inset 0 0 0 1px rgba(255,255,255,.35),0 0 0 1px rgba(0,0,0,.06)}
.sk-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sk-custom{display:grid;grid-template-columns:repeat(4,1fr);gap:9px;padding:0 22px 16px}
.sk-field span{display:block;font-size:11.5px;color:var(--ink3);margin-bottom:5px}
.sk-field input[type=color]{width:100%;height:36px;padding:2px;border:1px solid var(--line);
  border-radius:8px;background:var(--panel);cursor:pointer}
.sk-upload{display:flex;align-items:center;gap:10px;padding:0 22px 10px;flex-wrap:wrap}
.sk-up-btn{cursor:pointer}
.sk-up-tip{font-size:11.5px;color:var(--ink3);flex:1;min-width:0}
.sk-dim{padding:0 22px 14px}
.sk-dim-hd{display:flex;justify-content:space-between;font-size:12px;color:var(--ink2);margin-bottom:6px}
.sk-dim input[type=range]{width:100%;accent-color:var(--brand-flat)}
.sk-dim-tip{font-size:11px;color:var(--ink3);margin-top:4px}
.sk-preview{padding:0 22px 16px}

/* ---------- 换肤预览：一整块"迷你 MES 界面" ---------- */
.pv-wrap{display:flex;height:150px;border-radius:11px;overflow:hidden;
  border:1px solid rgba(16,24,40,.12);box-shadow:0 2px 10px rgba(16,24,40,.07);
  font-size:0;transition:background .2s,color .2s}
.pv-side{width:76px;flex:0 0 76px;padding:8px 7px;display:flex;flex-direction:column;
  gap:6px;border-right:1px solid}
.pv-brand{display:flex;align-items:center;gap:5px;margin-bottom:5px}
.pv-brand i{width:12px;height:12px;border-radius:4px;display:block}
.pv-brand span{display:block;width:34px;height:5px;border-radius:3px;background:currentColor;opacity:.75}
.pv-nav{height:11px;border-radius:5px}
.pv-nav.on{opacity:.95}
.pv-main{flex:1;padding:8px 9px;display:flex;flex-direction:column;gap:7px;min-width:0}
.pv-top{display:flex;align-items:center;justify-content:space-between;
  height:20px;padding:0 7px;border-radius:7px;border:1px solid}
.pv-title{display:block;width:44px;height:6px;border-radius:3px;background:currentColor;opacity:.85}
.pv-btn{display:block;width:26px;height:10px;border-radius:5px;border:1px solid;opacity:.7}
.pv-stats{display:flex;gap:6px}
.pv-stat{flex:1;min-width:0;height:38px;border-radius:7px;border:1px solid;
  padding:6px 7px;display:flex;flex-direction:column;justify-content:space-between}
.pv-k{display:block;width:60%;height:4px;border-radius:2px;opacity:.55}
.pv-n{display:block;width:45%;height:8px;border-radius:3px;background:currentColor;opacity:.9;
  font-size:0}
.pv-card{flex:1;border-radius:7px;border:1px solid;padding:6px 8px;
  display:flex;flex-direction:column;justify-content:space-around;min-height:0}
.pv-row{display:flex;align-items:center;gap:5px;padding-bottom:5px;border-bottom:1px solid}
.pv-cell{display:block;flex:1;height:4px;border-radius:2px;opacity:.6}
.pv-tag{display:block;width:20px;height:8px;border-radius:4px;flex:0 0 20px}
.pv-prog{height:4px;border-radius:2px;overflow:hidden;margin-top:4px}
.pv-prog i{display:block;height:100%;border-radius:2px}

.sk-ft{display:flex;justify-content:space-between;gap:10px;padding:14px 22px;
  border-top:1px solid var(--line2);background:color-mix(in srgb,var(--ink) 2.5%,var(--panel));
  border-radius:0 0 14px 14px}
@media(max-width:560px){
  .sk-grid{grid-template-columns:repeat(2,1fr)}
}

/* ---------- 悬停文字提示 ---------- */
.tip{position:relative}
.tip::after{content:attr(data-tip);position:absolute;top:calc(100% + 7px);left:50%;
  transform:translateX(-50%) translateY(-3px);white-space:nowrap;
  background:#1f2937;color:#fff;font-size:11.5px;line-height:1;font-weight:400;
  padding:6px 9px;border-radius:6px;pointer-events:none;
  opacity:0;transition:opacity .14s,transform .14s;z-index:95;
  box-shadow:0 4px 12px rgba(16,24,40,.18)}
.tip::before{content:"";position:absolute;top:calc(100% + 2px);left:50%;
  transform:translateX(-50%) translateY(-3px);
  border:5px solid transparent;border-bottom-color:#1f2937;
  pointer-events:none;opacity:0;transition:opacity .14s,transform .14s;z-index:95}
.tip:hover::after,.tip:focus-visible::after{opacity:1;transform:translateX(-50%) translateY(0)}
.tip:hover::before,.tip:focus-visible::before{opacity:1;transform:translateX(-50%) translateY(0)}

/* ---------- 系统风格弹层 ---------- */
.sty-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;padding:0 22px 6px}
.sty-card{position:relative;display:flex;flex-direction:column;gap:10px;padding:11px;border-radius:13px;
  border:1px solid var(--line);background:var(--panel);cursor:pointer;font-family:inherit;
  text-align:left;transition:.14s}
.sty-card:hover{border-color:color-mix(in srgb,var(--brand-flat) 45%,var(--line));
  box-shadow:0 4px 16px rgba(16,24,40,.08)}
.sty-card.on{border-color:var(--brand-flat);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--brand-flat) 14%,transparent)}
.sty-check{position:absolute;right:9px;top:9px;width:19px;height:19px;border-radius:50%;
  background:var(--brand);background-image:var(--brand);color:var(--on-brand);font-size:11.5px;font-weight:700;display:none;
  align-items:center;justify-content:center}
.sty-card.on .sty-check{display:flex}
.sty-meta{display:flex;flex-direction:column;gap:3px}
.sty-name{font-size:13.5px;font-weight:600;color:var(--ink)}
.sty-desc{font-size:11.5px;color:var(--ink3);line-height:1.55}

/* 缩略图：用纯 CSS 画「一块界面」，直观看出两种风格的差别 */
.sty-pv{display:flex;gap:5px;height:86px;border-radius:9px;overflow:hidden;padding:6px;
  background:var(--gray-soft);border:1px solid var(--line2)}
.sty-pv-side{width:25%;border-radius:5px;background:var(--panel);border:1px solid var(--line2)}
.sty-pv-main{flex:1;display:flex;flex-direction:column;gap:5px;min-width:0}
.sty-pv-bar{height:9px;border-radius:4px;background:var(--panel);border:1px solid var(--line2)}
.sty-pv-row{flex:1;border-radius:6px;background:var(--panel);border:1px solid var(--line2)}

/* 液态玻璃缩略图：渐变底 + 毛玻璃块 + 高光 */
.sty-pv-glass{position:relative;border:0;
  background:
    radial-gradient(60% 70% at 20% 0%,color-mix(in srgb,var(--brand-flat) 62%,#fff),transparent 72%),
    radial-gradient(60% 70% at 90% 100%,color-mix(in srgb,var(--brand-flat) 40%,var(--ink)),transparent 70%),
    linear-gradient(150deg,color-mix(in srgb,var(--brand-flat) 55%,#fff),color-mix(in srgb,var(--brand-flat) 30%,var(--bg)))}
.sty-pv-glass .sty-pv-side,
.sty-pv-glass .sty-pv-bar,
.sty-pv-glass .sty-pv-row{
  background:rgba(255,255,255,.34);
  border:1px solid rgba(255,255,255,.55);
  -webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.7),0 2px 6px rgba(16,24,40,.1)}
.sty-pv-glass .sty-pv-row:first-of-type{background:rgba(255,255,255,.46)}
.sty-pv-glass::after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;
  background:linear-gradient(115deg,rgba(255,255,255,.55) 0%,transparent 38%,transparent 62%,rgba(255,255,255,.18) 100%)}

.sty-note{margin:12px 22px 0;padding:10px 12px;border-radius:10px;font-size:11.5px;line-height:1.7;
  color:var(--ink2);background:var(--brand-soft)}
.sty-note b{color:var(--brand-flat);font-weight:600}
@media(max-width:560px){.sty-grid{grid-template-columns:1fr}}

/* ============================================================ 自定义字段控件 */
.cf-field.cf-wide{grid-column:1/-1}
.cf-chips{display:flex;flex-wrap:wrap;gap:6px;padding:2px 0}
.cf-chip{display:inline-flex;align-items:center;gap:5px;height:30px;padding:0 10px;
  border:1px solid var(--line);border-radius:8px;background:#fff;font-size:12.5px;
  color:var(--ink2);cursor:pointer;transition:.12s;user-select:none}
.cf-chip:hover{border-color:var(--brand-flat);color:var(--brand-flat)}
.cf-chip input{margin:0;accent-color:var(--brand-flat);width:13px;height:13px}
.cf-chip:has(input:checked){background:var(--brand-soft);border-color:var(--brand-flat);
  color:var(--brand-flat);font-weight:500}

/* 多选下拉 */
.cf-msel{position:relative}
.cf-msel-box{display:flex;align-items:center;gap:8px;min-height:36px;padding:4px 10px;
  border:1px solid var(--line);border-radius:8px;background:#fff;cursor:pointer}
.cf-msel-box:focus{outline:none;border-color:var(--brand-flat);box-shadow:0 0 0 3px rgba(37,99,235,.1)}
.cf-msel-tags{display:flex;flex-wrap:wrap;gap:4px;flex:1;min-width:0}
.cf-msel-tags em{font-style:normal;font-size:12px;padding:1px 7px;border-radius:5px;
  background:var(--brand-soft);color:var(--brand-flat)}
.cf-msel-tags i{font-style:normal;font-size:13px;color:var(--ink3);padding:4px 0}
.cf-msel-arrow{color:var(--ink3);font-size:11px;flex:none}
/* 弹窗里字段多时多选弹层会被 .modal 的 overflow:auto 裁掉，
   这里让它贴底时向上翻，并给模态框留出底部空间 */
.cf-msel-pop{position:absolute;left:0;right:0;top:calc(100% + 4px);z-index:30;
  background:#fff;border:1px solid var(--line);border-radius:9px;padding:8px;
  box-shadow:0 10px 28px rgba(16,24,40,.14);display:flex;flex-wrap:wrap;gap:6px;
  max-height:180px;overflow:auto}
.cf-msel.up .cf-msel-pop{top:auto;bottom:calc(100% + 4px)}
.cf-msel-pop[hidden]{display:none!important}

/* 开关 */
.cf-switch{display:inline-flex;align-items:center;gap:9px;cursor:pointer;height:34px}
.cf-switch>input{position:absolute;opacity:0;width:0;height:0}
.cf-switch-track{width:38px;height:21px;border-radius:11px;background:#cbd5e1;position:relative;
  transition:.18s;flex:none}
.cf-switch-track i{position:absolute;left:2px;top:2px;width:17px;height:17px;border-radius:50%;
  background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.2);transition:.18s}
.cf-switch>input:checked + .cf-switch-track{background:var(--brand);background-image:var(--brand)}
.cf-switch>input:checked + .cf-switch-track i{transform:translateX(17px)}
.cf-switch-text{font-size:13px;color:var(--ink2)}

/* 媒体字段 */
.cf-media-list{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}
.cf-media-list:empty{display:none}
.cf-media-item{position:relative;border-radius:9px;overflow:hidden;border:1px solid var(--line);
  background:var(--gray-soft)}
.cf-media-thumb{display:block;width:86px;height:86px}
.cf-media-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.cf-media-item video{display:block;width:150px;height:86px;object-fit:cover;background:#000}
.cf-media-file{display:flex;align-items:center;gap:4px;padding:8px 10px;font-size:12px;
  color:var(--ink2);max-width:170px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cf-media-del{position:absolute;right:3px;top:3px;width:19px;height:19px;border:0;border-radius:50%;
  background:rgba(16,24,40,.62);color:#fff;font-size:13px;line-height:1;cursor:pointer;
  display:flex;align-items:center;justify-content:center;padding:0}
.cf-media-del:hover{background:var(--bad)}
.cf-media-add{display:inline-flex;align-items:center;justify-content:center;height:34px;padding:0 14px;
  border:1px dashed var(--line);border-radius:8px;font-size:12.5px;color:var(--ink2);
  cursor:pointer;transition:.12s;background:#fff}
.cf-media-add:hover{border-color:var(--brand-flat);color:var(--brand-flat);background:var(--brand-soft)}
.cf-media-add input{display:none}
.cf-view-thumb{width:56px;height:56px;object-fit:cover;border-radius:7px;border:1px solid var(--line);
  margin-right:6px;vertical-align:middle}

/* ================= 权限管理 ================= */
.pm-wrap{display:grid;grid-template-columns:250px 1fr;gap:16px;align-items:start}

/* 左：角色列表 */
.pm-side{position:sticky;top:16px;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--shadow);overflow:hidden}
.pm-side-hd{display:flex;align-items:center;justify-content:space-between;
  padding:12px 14px;border-bottom:1px solid var(--line2);
  font-size:13px;font-weight:600;color:var(--ink)}
.pm-roles{display:flex;flex-direction:column;padding:6px}
.pm-role{display:flex;flex-direction:column;gap:4px;width:100%;text-align:left;
  padding:9px 10px;border:0;border-radius:9px;background:transparent;cursor:pointer;
  font-family:inherit;transition:.12s}
.pm-role:hover{background:var(--gray-soft)}
.pm-role.on{background:var(--brand-soft)}
.pm-role-name{display:flex;align-items:center;gap:6px;font-size:13px;font-weight:500;color:var(--ink)}
.pm-role.on .pm-role-name{color:var(--brand-flat)}
.pm-mini{font-size:10px;padding:0 5px;line-height:15px;font-style:normal}
.pm-role-meta{font-size:11.5px;color:var(--ink3)}
.pm-role-bar{height:3px;border-radius:2px;background:var(--line2);overflow:hidden;margin-top:2px}
.pm-role-bar i{display:block;height:100%;background:var(--brand);background-image:var(--brand);border-radius:2px;transition:width .3s}
.pm-side-tip{padding:10px 14px 12px;font-size:11px;color:var(--ink3);
  border-top:1px solid var(--line2);line-height:1.6}

/* 右：详情 */
.pm-main{min-width:0}
.pm-panel[hidden]{display:none}
.pm-title{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.pm-sub{font-size:12px;color:var(--ink3)}
.pm-sub code{font-family:ui-monospace,monospace;background:var(--gray-soft);
  padding:1px 5px;border-radius:4px;font-size:11.5px}

.pm-lock{display:flex;gap:14px;align-items:flex-start;padding:26px 22px;color:var(--ink2)}
.pm-lock svg{flex:none;color:var(--brand-flat);margin-top:2px}

/* 删除确认里的拦截说明 */
.pm-del-note{padding:10px 12px;border-radius:8px;font-size:12.5px;line-height:1.6;
  background:var(--warn-soft, #fff4e5);color:var(--warn-ink, #8a5300);
  border:1px solid var(--warn-line, #ffd9a8);margin-top:4px}
.btn[disabled],.btn:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}

/* 弹窗里的「会怎样」说明块 */
.pm-note{margin-top:14px;padding:11px 13px;border-radius:9px;
  background:var(--gray-soft);border:1px solid var(--line2)}
.pm-note-row{display:flex;gap:9px;font-size:12px;line-height:1.65;color:var(--ink3)}
.pm-note-row + .pm-note-row{margin-top:5px}
.pm-note-row b{flex:none;width:86px;font-weight:600;color:var(--ink2)}
.pm-note-row i{font-style:normal;flex:1;min-width:0}
.pm-lock b{display:block;font-size:13.5px;color:var(--ink);margin-bottom:5px}
.pm-lock p{font-size:12.5px;line-height:1.7;margin:0;color:var(--ink2)}

.pm-form{padding:4px 18px 0}
.pm-sec{padding:14px 0;border-bottom:1px solid var(--line2)}
.pm-sec:last-of-type{border-bottom:0}
.pm-sec-hd{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}
.pm-sec-t{font-size:12.5px;font-weight:600;color:var(--ink)}
.pm-sec-d{font-size:11.5px;color:var(--ink3);margin-left:8px}
/* 组内快捷操作：只读 / 全选 —— 做成真正的胶囊按钮，一眼能看出是能点的 */
.pm-sec-acts{display:flex;align-items:center;gap:6px}
.pm-sec-all,.pm-sec-read{border:1px solid var(--line);background:var(--panel);color:var(--ink2);
  font-size:11.5px;line-height:1;cursor:pointer;font-family:inherit;
  padding:5px 11px;border-radius:999px;transition:all .15s;user-select:none}
.pm-sec-all{color:var(--brand-flat);border-color:color-mix(in srgb,var(--brand-flat) 35%,var(--line))}
.pm-sec-all:hover{background:var(--brand-soft);border-color:var(--brand-flat)}
.pm-sec-read:hover{background:var(--gray-soft);color:var(--ink);border-color:var(--ink3)}
.pm-sec-all:active,.pm-sec-read:active{transform:scale(.92)}
.pm-sec-all:focus-visible,.pm-sec-read:focus-visible{outline:2px solid var(--brand-flat);outline-offset:1px}
/* 左侧角色卡吸顶滚动时加投影，让「浮在内容上」看起来是有意的 */
.pm-side.stuck{box-shadow:0 10px 28px -14px rgba(20,30,60,.35)}

/* 数据范围：两张卡片式单选 */
.pm-scope{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.pm-radio{display:flex;align-items:flex-start;gap:9px;padding:11px 12px;
  border:1px solid var(--line);border-radius:10px;cursor:pointer;transition:.12s}
.pm-radio:hover{border-color:color-mix(in srgb,var(--brand-flat) 40%,var(--line));
  background:color-mix(in srgb,var(--brand-flat) 4%,transparent)}
.pm-radio input{position:absolute;opacity:0;width:0;height:0}
.pm-radio-box{width:15px;height:15px;flex:none;margin-top:1px;border-radius:50%;
  border:1.5px solid var(--line);background:var(--panel);transition:.12s;position:relative}
.pm-radio input:checked + .pm-radio-box{border-color:var(--brand-flat);border-width:4.5px}
.pm-radio input:checked ~ .pm-radio-t b{color:var(--brand-flat)}
.pm-radio:has(input:checked){border-color:color-mix(in srgb,var(--brand-flat) 45%,var(--line));
  background:var(--brand-soft)}
.pm-radio-t b{display:block;font-size:12.5px;color:var(--ink);font-weight:500;margin-bottom:3px}
.pm-radio-t i{font-style:normal;font-size:11.5px;color:var(--ink3);line-height:1.5}

/* 功能权限：两列网格 */
.pm-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:6px}
.pm-perm{display:flex;align-items:flex-start;gap:9px;padding:8px 10px;border-radius:9px;
  cursor:pointer;transition:.1s;border:1px solid transparent}
.pm-perm:hover{background:var(--gray-soft)}
.pm-perm input{position:absolute;opacity:0;width:0;height:0}
.pm-perm-box{width:16px;height:16px;flex:none;margin-top:1px;border:1.5px solid var(--line);
  border-radius:5px;background:var(--panel);display:flex;align-items:center;justify-content:center;
  color:#fff;transition:.12s}
.pm-perm-box svg{opacity:0;transition:opacity .1s}
.pm-perm input:checked + .pm-perm-box{background:var(--brand);background-image:var(--brand);border-color:var(--brand-flat)}
.pm-perm input:checked + .pm-perm-box svg{opacity:1}
.pm-perm-t b{display:block;font-size:12.5px;font-weight:500;color:var(--ink);line-height:1.5}
.pm-perm-t i{font-style:normal;display:block;font-size:11px;color:var(--ink3);line-height:1.5}
.pm-perm input:checked ~ .pm-perm-t b{color:var(--brand-flat)}

/* 板块权限：一条里带「仅查看 / 可编辑」两个档位（编辑隐含查看） */
.pm-perm.pm-pair{display:block;cursor:default;grid-column:span 1;padding:8px 10px 9px}
.pm-perm.pm-pair:hover{background:transparent}
.pm-pair .pm-perm-t b{font-size:12.5px}
.pm-lv{display:flex;gap:5px;margin-top:7px}
.pm-lv-b{flex:1;display:flex;align-items:center;justify-content:center;height:27px;
  border:1px solid var(--line);border-radius:7px;font-size:11.5px;color:var(--ink2);
  cursor:pointer;transition:.12s;background:var(--panel);user-select:none}
.pm-lv-b:hover{border-color:var(--brand-flat);color:var(--brand-flat)}
.pm-lv-b input{position:absolute;opacity:0;width:0;height:0}
.pm-lv-b.on{background:var(--brand-soft);border-color:var(--brand-flat);color:var(--brand-flat);font-weight:600}
.pm-lv-b.on + .pm-lv-b,
.pm-lv-b.on{box-shadow:none}
/* 可编辑档位更重一点，让人一眼看出层级 */
.pm-lv-b:last-child.on{background:var(--brand);background-image:var(--brand);border-color:var(--brand-flat);color:#fff}

.pm-foot{display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:13px 0 16px;border-top:1px solid var(--line2);margin-top:2px}
.pm-foot-tip{font-size:11.5px;color:var(--ink3);line-height:1.5}

@media (max-width:900px){
  .pm-wrap{grid-template-columns:1fr}
  .pm-side{position:static}
  .pm-scope{grid-template-columns:1fr}
}

/* ================= 页内标签（员工 / 角色权限） ================= */
.seg-tabs{display:flex;gap:3px;padding:3px;border-radius:10px;margin-bottom:14px;
  background:var(--gray-soft);border:1px solid var(--line2);
  overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none;
  flex-shrink:0}
.seg-tabs::-webkit-scrollbar{display:none}
.seg-tab{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 13px;
  border-radius:8px;font-size:12.5px;color:var(--ink2);text-decoration:none;
  transition:.14s;white-space:nowrap}
.seg-tab:hover{color:var(--brand-flat)}
.seg-tab.on{background:var(--panel);color:var(--brand-flat);font-weight:600;
  box-shadow:0 1px 3px rgba(15,23,42,.1)}
.seg-tab i{width:14px;height:14px;flex:none;background-color:currentColor;opacity:.85}
.seg-n{display:inline-flex;align-items:center;justify-content:center;min-width:16px;height:16px;
  padding:0 4px;border-radius:20px;background:var(--line2);color:var(--ink3);
  font-size:10.5px;font-weight:600}
.seg-tab.on .seg-n{background:var(--brand-soft);color:var(--brand-flat)}

/* ============ 表单布局（拖拽编辑） ============ */
.lyt-wrap{display:grid;grid-template-columns:250px 1fr;gap:0}
.lyt-side{border-right:1px solid var(--line);padding:18px 16px}
.lyt-side-t{font-weight:600;font-size:13px;color:var(--ink2);margin-bottom:10px}
.lyt-side-b p{font-size:12.5px;line-height:1.8;color:var(--ink3);margin:0 0 10px}
.lyt-side-b b{color:var(--ink2)}
.lyt-canvas{padding:18px 22px;background:linear-gradient(180deg,var(--bg2,rgba(120,140,180,.05)),transparent)}
.lyt-canvas-t{font-size:12.5px;color:var(--ink3);margin-bottom:12px}
.lyt-list{display:flex;flex-direction:column;gap:10px;max-width:640px}
.lyt-item{display:flex;align-items:flex-start;gap:12px;background:var(--paper,#fff);
  border:1px solid var(--line);border-radius:12px;padding:12px 16px;cursor:grab;
  transition:box-shadow .15s,opacity .15s,transform .12s;position:relative;user-select:none}
.lyt-item:hover{box-shadow:0 4px 14px rgba(40,70,140,.10);border-color:var(--brand,#5b8cff);transform:translateY(-1px)}
/* ---------- 拖拽排序（托起 + 让位） ---------- */
/* 原位置留下的占位框：虚线，高度与原卡片一致，形成「空位」 */
.lyt-item.drag-placeholder{
  background:color-mix(in srgb,var(--brand,#5b8cff) 6%,transparent);
  border:1.5px dashed color-mix(in srgb,var(--brand,#5b8cff) 55%,transparent);
  border-radius:12px;box-shadow:none!important;transform:none!important;
  transition:height .16s cubic-bezier(.4,0,.2,1);
  pointer-events:none}
.lyt-item.drag-placeholder > *{visibility:hidden}
/* 跟随光标的浮起卡片 */
.lyt-item.drag-ghost{
  position:fixed;z-index:2004500;margin:0!important;
  pointer-events:none;cursor:grabbing;
  box-shadow:0 18px 42px rgba(16,28,60,.28),0 4px 10px rgba(16,28,60,.14);
  border-color:var(--brand,#5b8cff);
  transform:rotate(1.2deg) scale(1.02);
  opacity:.97;transition:box-shadow .15s,transform .15s;
  will-change:transform,top,left}
.lyt-item.drag-lifting{transition:transform .18s cubic-bezier(.4,0,.2,1),box-shadow .18s}
/* 拖拽期间禁止其它卡片 hover 抖动，避免让位动画被打断 */
.lyt-list.drag-active .lyt-item:not(.drag-ghost):not(.drag-placeholder){transition:transform .16s ease}
.lyt-list.drag-active .lyt-item:not(.drag-ghost):hover{transform:none;box-shadow:none}
.lyt-list.drag-active{cursor:grabbing}
/* 落位：从浮起状态轻轻「放回」，给一个短促的沉降反馈 */
.lyt-item.drag-landing{animation:lytLand .22s cubic-bezier(.34,1.3,.64,1)}
@keyframes lytLand{
  0%{transform:scale(1.02) translateY(-2px);box-shadow:0 14px 32px rgba(16,28,60,.24)}
  100%{transform:none;box-shadow:0 4px 14px rgba(40,70,140,.10)}}
.lyt-item.is-hidden{opacity:.55;background:var(--bg2,rgba(120,140,180,.06))}
.lyt-grip{color:var(--ink3);font-size:15px;line-height:1.4;padding-top:2px;
  opacity:0;transition:opacity .15s}
.lyt-item:hover .lyt-grip{opacity:1}
.lyt-no{width:22px;height:22px;border-radius:6px;background:var(--bg2,rgba(120,140,180,.1));
  color:var(--ink3);font-size:11.5px;display:flex;align-items:center;justify-content:center;flex:none;margin-top:1px}
.lyt-main{flex:1;min-width:0}
.lyt-lab{font-weight:600;font-size:13.5px;color:var(--ink);margin-bottom:7px;display:flex;align-items:center}
.lyt-desc{font-size:11.5px;color:var(--ink3);margin:-4px 0 8px}
.lyt-real{pointer-events:none}
.lyt-real .ipt{width:78%;background:var(--paper,#fff)}
.lyt-real textarea.ipt{width:88%}
.lyt-modal{position:fixed;top:0;right:0;bottom:0;left:0;background:rgba(20,30,60,.45);z-index:2003000;
  display:none;align-items:center;justify-content:center;padding:26px}
.lyt-modal.on{display:flex}
.lyt-modal-box{background:var(--paper,#fff);border-radius:14px;
  width:min(1080px,100%);height:calc(100vh - 52px);
  display:flex;flex-direction:column;overflow:hidden;
  box-shadow:0 18px 60px rgba(10,20,50,.3)}
.lyt-modal-box iframe{flex:1;display:block;width:100%;border:0;background:#f5f7fb}
.lyt-modal-bar{display:flex;justify-content:space-between;align-items:center;
  padding:10px 16px;border-bottom:1px solid var(--line);
  background:var(--bg2,rgba(120,140,180,.06));font-size:13px;color:var(--ink2)}
.lyt-modal-bar span::before{content:"👁 ";}
.lyt-modal-box iframe{flex:1;border:0;width:100%;background:#f5f7fb}
.lyt-toast{font-size:12.5px;color:var(--ok,#18a058);opacity:0;transition:opacity .2s;pointer-events:none}
.lyt-toast.on{opacity:1}
@media (max-width:900px){.lyt-wrap{grid-template-columns:1fr}.lyt-side{border-right:none;border-bottom:1px solid var(--line)}}

.lyt-form-panel{background:var(--paper,#fff);border:1px solid var(--line);border-radius:14px;
  padding:20px 26px 26px;max-width:640px;box-shadow:0 2px 12px rgba(40,70,140,.06)}
.lyt-form-title{text-align:center;font-weight:700;font-size:15.5px;color:var(--ink);margin-bottom:4px}
.lyt-canvas .lyt-canvas-t{text-align:center;margin-bottom:14px}
.lyt-mock-opts{display:flex;gap:14px;padding:6px 0}
.lyt-mock-opts span{display:flex;align-items:center}
.lyt-mock-opts span::before{content:"";width:13px;height:13px;border-radius:50%;
  border:1.5px solid var(--line);margin-right:5px;display:inline-block}
.lyt-mock-date{width:44%}

/* iframe 内嵌预览：隐藏外框 */
html.embedded .sidebar, html.embedded .topbar,
body.embedded .sidebar, body.embedded .topbar,
html.embedded .bot-wrap, html.embedded .bot-panel,
html.embedded #botWrap, html.embedded .icp{display:none !important}
html.embedded .layout, body.embedded .layout{padding-left:0 !important;display:block !important;min-height:auto !important}
html.embedded .main, body.embedded .main{margin:0 !important;padding:14px 18px 28px !important;max-width:none !important}
html.embedded body{background:var(--panel,#fff) !important}

/* 左侧字段面板 */
.lyt-palette{display:grid;grid-template-columns:1fr 1fr;gap:7px}
.lyt-pal{display:flex;align-items:center;gap:6px;border:1px solid var(--line);
  background:var(--paper,#fff);border-radius:8px;padding:7px 9px;font-size:12px;
  color:var(--ink2);cursor:pointer;transition:all .12s}
.lyt-pal:hover{border-color:var(--brand,#5b8cff);color:var(--brand,#5b8cff);
  box-shadow:0 2px 8px rgba(60,100,200,.12);transform:translateY(-1px)}
.lyt-pal.busy{opacity:.5;pointer-events:none}
.lyt-pal-ic{font-size:12px;opacity:.8}
.lyt-syslist{display:flex;flex-direction:column;gap:2px;max-height:220px;overflow:auto}
.lyt-sysrow{display:flex;align-items:center;gap:7px;padding:5px 8px;border-radius:7px;
  font-size:12.5px;color:var(--ink2);cursor:pointer}
.lyt-sysrow:hover{background:var(--bg2,rgba(120,140,180,.08))}
.lyt-sysrow.off .lyt-sys-name{color:var(--ink3);text-decoration:line-through}
.lyt-sys-eye{font-size:12px}
/* 字段块右侧一列：「系统/自定义」标签 + 操作按钮组（简道云风格）
   静止时只显示类型标签；悬浮时按钮组在**同一位置**浮现、标签淡出——
   高度恒定，不会出现「标签悬在空白上」的突兀色块。 */
.lyt-aside{position:relative;flex:none;min-width:86px;display:flex;justify-content:flex-end;padding-top:2px}
.lyt-aside .tag{transition:opacity .15s}
.lyt-item .lyt-acts{position:absolute;top:2px;right:0;display:flex;gap:4px;
  opacity:0;transition:opacity .15s;pointer-events:none}
.lyt-item:hover .lyt-acts{opacity:1;pointer-events:auto}
.lyt-item:hover .lyt-aside > .tag{opacity:0}
/* 类型标签统一轻量描边风：底色融入卡片，仅靠文字色区分系统/自定义 */
.lyt-item .lyt-aside .tag{background:transparent;border:1px solid var(--line);height:24px;padding:0 9px}
.lyt-item .lyt-aside .tag.info{color:var(--brand,#5b8cff);border-color:color-mix(in srgb,var(--brand,#5b8cff) 45%,transparent)}
/* 玻璃皮肤对 .tag.info 的底色覆写特异性更高，这里对齐提一级，保证统一为描边风 */
html[data-style="glass"] .lyt-item .lyt-aside .tag{background:transparent}
html[data-style="glass"] .lyt-item .lyt-aside .tag.info{
  background:transparent;color:var(--brand,#2563eb);
  border-color:color-mix(in srgb,var(--brand,#2563eb) 45%,transparent)}
/* 图标方块按钮：白底细描边，hover 泛品牌色；删除 hover 泛红 */
.lyt-act{border:1px solid var(--line);background:var(--paper,#fff);cursor:pointer;font-size:13px;
  width:28px;height:28px;border-radius:7px;color:var(--ink3);line-height:1;
  display:inline-flex;align-items:center;justify-content:center;transition:.12s}
.lyt-act:hover{border-color:var(--brand,#5b8cff);color:var(--brand,#5b8cff);
  background:color-mix(in srgb,var(--brand,#5b8cff) 8%,#fff)}
.lyt-act.bad:hover{border-color:#e46a6a;color:#d43;background:rgba(220,60,60,.08)}

/* ============ 画布 1:1 真实表单外观 ============ */
.lyt-item{background:transparent;border:1px solid transparent;border-radius:8px;
  padding:6px 8px;gap:8px;box-shadow:none}
.lyt-item:hover{border:1px dashed var(--brand,#2563eb);background:rgba(37,99,235,.045);
  box-shadow:none;transform:none}
.lyt-item.is-hidden{background:transparent;opacity:.5}
.lyt-no{width:18px;height:18px;font-size:10px;border-radius:5px;margin-top:2px;flex:none}
.lyt-main{flex:1;min-width:0}
.lyt-lab{font-size:12.5px;font-weight:500;color:var(--ink2);margin-bottom:6px}
.lyt-desc{font-size:11px;color:var(--ink3);margin:-3px 0 6px}
.lyt-real{pointer-events:none;width:100%}
.lyt-real .ipt,.lyt-real input,.lyt-real select{width:100%;height:38px;padding:0 11px;
  font-size:14px;border-radius:8px;background:var(--panel);color:var(--ink)}
.lyt-real textarea.ipt{height:auto;min-height:76px;padding:9px 11px;resize:vertical}
.lyt-real input[type="date"]{min-width:0}

/* 面板镜像真实卡片：标题左对齐 + card-pad 内边距 */
.lyt-form-panel{border-radius:10px;padding:14px 18px 18px}
.lyt-form-title{text-align:left;font-size:14.5px;margin-bottom:2px;padding-bottom:10px;
  border-bottom:1px solid var(--line)}
.lyt-canvas .lyt-canvas-t{text-align:left;margin:8px 0 4px}
.lyt-list{max-width:100%}

.btn.busy{opacity:.5;pointer-events:none}

/* ================= 登录页：动态渐变背景 + 玻璃卡片 ================= */
.login-wrap{position:relative;overflow:auto;
  background:
    radial-gradient(900px 520px at 10% -8%,#e9f1ff 0%,transparent 62%),
    radial-gradient(820px 520px at 102% 108%,#e9f7ff 0%,transparent 58%),
    #f6f7fa !important}

/* 一张大卡：左侧表单区 + 右侧问候区（同一张卡，共用圆角与投影） */
.login-stage{position:relative;z-index:1;display:flex;align-items:stretch;
  width:100%;max-width:908px;overflow:hidden;
  background:#fff;border-radius:22px;
  border:1px solid rgba(16,24,40,.07);
  box-shadow:0 26px 64px rgba(23,43,99,.11),0 2px 8px rgba(23,43,99,.05);
  margin:auto;animation:loginCardIn .6s cubic-bezier(.22,1.2,.36,1)}
.login-left{position:relative;flex:0 0 384px;width:384px;max-width:100%;
  display:flex;align-items:center;
  background:linear-gradient(180deg,#fff 0%,#fff 58%,#fcfdff 100%)}
.login-box{position:relative;z-index:1;border:0;border-radius:0;background:transparent;
  box-shadow:none;animation:none;padding:30px 32px}
.login-box .btn.primary{box-shadow:0 6px 18px rgba(37,99,235,.32);transition:.18s}
.login-box .btn.primary:hover{transform:translateY(-1px);box-shadow:0 9px 24px rgba(37,99,235,.4)}
@keyframes loginCardIn{from{opacity:0;transform:translateY(18px) scale(.97)}to{opacity:1;transform:none}}

.login-hero{position:relative;flex:1 1 auto;min-width:0;overflow:hidden;
  border-radius:0;border:0;box-shadow:none;
  /* 纯渐变过渡：白 → 淡蓝，无点阵、无接缝 */
  background-image:
    radial-gradient(120% 90% at 100% 100%,rgba(198,222,255,.55) 0%,rgba(198,222,255,0) 62%),
    linear-gradient(105deg,#ffffff 0%,#f6faff 34%,#e8f1ff 68%,#dfeaff 100%);
  padding:40px 40px 46px;display:flex;flex-direction:column;
  animation:none}
.lh-copy{align-self:stretch;text-align:left}
.lh-copy h1{margin:0 0 10px;font-size:clamp(23px,2.4vw,30px);line-height:1.34;
  letter-spacing:-.6px;font-weight:800;color:#17181c}
.lh-copy p{margin:0;font-size:13.5px;color:#5b6b82;line-height:1.8}

/* 吉祥物：骨骼级动画角色（static/mascot-engine.js 驱动），从卡片底部探出头 */
.lh-mascot-wrap{position:absolute;left:0;right:0;bottom:0;display:flex;justify-content:center;
  cursor:pointer;-webkit-tap-highlight-color:transparent;pointer-events:none}
.lh-mascot{display:block;width:clamp(190px,54.5%,300px);height:auto;overflow:visible}
/* 悬停第三方登录时，眼珠里换成对应 logo（瞳孔同步隐去） */
.lh-mascot .m-logo{opacity:0;transform:scale(.4);transform-origin:0 0;
  transition:opacity .16s ease,transform .32s cubic-bezier(.18,1.5,.4,1)}
.lh-mascot.show-auth .m-logo{opacity:1;transform:scale(1.5)}
.lh-mascot .m-pupil-ball{transition:opacity .16s ease}
.lh-mascot.show-auth .m-pupil-ball{opacity:0}

/* 密码框内的"显示密码"眼睛：按下时角色会睁一只眼偷看（peek 状态） */
.pwd-field{position:relative}
.pwd-field input{padding-right:40px}
.pwd-eye{position:absolute;right:6px;bottom:5px;width:30px;height:30px;
  display:flex;align-items:center;justify-content:center;border:0;border-radius:8px;
  background:transparent;color:var(--ink3);cursor:pointer;transition:.15s}
.pwd-eye:hover{background:rgba(16,24,40,.05);color:var(--ink2)}
.pwd-eye.on{color:#2563eb}

@media (prefers-reduced-motion: reduce){
  .lh-mascot-wrap{animation:none}
  .login-hero{transition:none}
}
@media (max-width:880px){
  .login-stage{max-width:412px;border-radius:20px}
  .login-hero{display:none}
  .login-left{flex:1 1 auto;width:100%;max-width:100%}
  .login-box{max-width:100%}
}

/* ---------- 登录反馈：失败提示卡 / 抖动 / 按钮转圈 / 成功过场 ---------- */
/* 失败提示卡：绝对定位钉在登录卡正下方（.login-wrap 是 flex，排流会被挤到卡片旁边） */
.login-alert{position:relative;transform:none;
  z-index:2;display:flex;align-items:center;gap:9px;
  width:100%;max-width:none;margin:16px 0 2px;padding:11px 13px;
  font-size:13px;font-weight:500;line-height:1.45;color:#b91c1c;
  background:#fef4f4;border:1px solid #f6d2d2;border-radius:12px;
  box-shadow:0 6px 20px rgba(185,28,28,.10);
  animation:laIn .3s cubic-bezier(.34,1.35,.64,1)}
.login-alert .la-ico{flex:0 0 18px;width:18px;height:18px;border-radius:50%;
  background:#dc2626;color:#fff;display:grid;place-items:center}
.login-alert .la-txt{flex:1;min-width:0}
.login-alert .la-x{flex:none;width:20px;height:20px;border:0;border-radius:6px;cursor:pointer;
  background:transparent;color:#b91c1c;font-size:16px;line-height:1;
  font-family:inherit;opacity:.6;transition:opacity .15s,background-color .15s}
.login-alert .la-x:hover{opacity:1;background:rgba(185,28,28,.08)}
.login-alert.hide{opacity:0;transform:translateY(-8px);
  transition:opacity .3s,transform .3s}
@keyframes laIn{from{opacity:0;transform:translateY(-10px) scale(.98)}
                to{opacity:1;transform:none}}
/* 密码错时整张卡轻抖：比只弹一行字更"有反应" */
.login-stage.shake{animation:lbShake .42s cubic-bezier(.36,.07,.19,.97)}
@keyframes lbShake{
  10%,90%{transform:translateX(-2px)} 20%,80%{transform:translateX(4px)}
  30%,50%,70%{transform:translateX(-7px)} 40%,60%{transform:translateX(7px)}}
/* 前端拦截（空工号/空密码）的浮动小提示 */
.login-tip{position:fixed;left:50%;top:22px;transform:translateX(-50%);z-index:60;
  padding:9px 16px;border-radius:10px;font-size:12.5px;font-weight:500;
  color:#fff;background:rgba(24,28,38,.9);box-shadow:0 8px 26px rgba(16,24,40,.22);
  pointer-events:none;animation:tipIn .22s cubic-bezier(.34,1.4,.64,1)}
.login-tip.hide{opacity:0;transform:translateX(-50%) translateY(-8px);transition:opacity .3s,transform .3s}
@keyframes tipIn{from{opacity:0;transform:translateX(-50%) translateY(-12px) scale(.96)}to{opacity:1;transform:translateX(-50%)}}
/* 按钮里的转圈点 */
.spin{display:inline-block;width:13px;height:13px;margin-right:7px;vertical-align:-2px;
  border:2px solid currentColor;border-top-color:transparent;border-radius:50%;
  animation:spinTurn .7s linear infinite}
@keyframes spinTurn{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion: reduce){
  .login-stage.shake{animation:none}
}
/* 提交后：整页轻微"进入中"，并锁住重复点击 */
body.logging-in .login-box{pointer-events:none;opacity:.94;transition:opacity .2s}
body.logging-in .login-box::after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;z-index:3;border-radius:0;
  background:color-mix(in srgb,var(--panel) 22%,transparent);backdrop-filter:blur(1px)}

/* ---------- 登录成功落地页的一次性欢迎条（与 toast-pop 同一套液态玻璃语言） ---------- */
.welcome-bar{
  --tint:rgba(21,150,80,.32);--wash:rgba(52,211,153,.22);
  position:fixed;left:50%;top:16px;transform:translateX(-50%);z-index:2001;
  display:flex;align-items:center;gap:11px;max-width:min(92vw,520px);
  padding:12px 15px 13px 12px;border-radius:16px;font-size:13px;font-weight:500;line-height:1.4;
  color:var(--ink);overflow:hidden;isolation:isolate;
  background:linear-gradient(115deg,rgba(255,255,255,.88),rgba(255,255,255,.6) 52%,rgba(255,255,255,.8));
  -webkit-backdrop-filter:blur(20px) saturate(1.7);
  backdrop-filter:blur(20px) saturate(1.7);
  border:1px solid rgba(255,255,255,.78);
  box-shadow:0 20px 48px -14px var(--tint),0 3px 12px -4px rgba(16,24,40,.12),
    inset 0 1px 0 rgba(255,255,255,.95),inset 0 -1px 0 rgba(255,255,255,.25);
  animation:wbIn .6s cubic-bezier(.22,1.32,.36,1)}
/* 作者样式的 display:flex 会盖过浏览器对 [hidden] 的 display:none，必须显式声明 */
.welcome-bar[hidden]{display:none}
/* 状态氛围雾 + 底部寿命条，与 toast-pop 完全同构 */
.welcome-bar::before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;pointer-events:none;
  background:radial-gradient(130% 160% at 88% -20%,var(--wash),transparent 62%)}
.welcome-bar::after{content:"";position:absolute;left:0;bottom:0;height:2.5px;border-radius:0 0 15px 15px;
  background:linear-gradient(90deg,transparent,#16a34a 30%,#4ade80);
  box-shadow:0 0 9px var(--wash);opacity:.95;animation:wbBar 5s linear forwards}
.welcome-bar .wb-ico{flex:0 0 20px;width:20px;height:20px;border-radius:50%;
  background:linear-gradient(135deg,#4ade80,#16a34a);color:#fff;display:grid;place-items:center;
  box-shadow:0 0 0 3.5px rgba(34,197,94,.15),0 4px 10px -2px rgba(22,163,74,.55)}
.welcome-bar .wb-txt{flex:1;min-width:0;letter-spacing:.1px}
.welcome-bar .wb-txt b{font-weight:700}
.welcome-bar .wb-x{flex:none;width:20px;height:20px;border:0;border-radius:7px;cursor:pointer;
  background:transparent;color:var(--ink3);font-size:16px;line-height:1;font-family:inherit;
  opacity:.8;transition:opacity .15s,background-color .15s,color .15s}
.welcome-bar .wb-x:hover{opacity:1;background:rgba(16,24,40,.07);color:var(--ink)}
.welcome-bar.hide{opacity:0;transform:translateX(-50%) translateY(-12px) scale(.97);
  transition:opacity .34s,transform .34s}
@keyframes wbIn{
  0%{opacity:0;transform:translateX(-50%) translateY(-20px) scale(.9)}
  62%{opacity:1;transform:translateX(-50%) translateY(2px) scale(1.015)}
  100%{opacity:1;transform:translateX(-50%) translateY(0) scale(1)}}
@keyframes wbBar{from{width:100%}to{width:0}}
@media (max-width:520px){
  .welcome-bar{top:10px;padding:10px 12px;font-size:12.5px}
}
@media (prefers-reduced-motion: reduce){
  .toast-pop,.welcome-bar,.ntf-pop{animation:none}
  .toast-pop::after,.welcome-bar::after{animation:none}
}

/* ============ 表单布局弹窗（取代独立字段管理页） ============ */
.fl-btn{display:inline-flex;align-items:center;gap:6px}
.fl-mask{position:fixed;top:0;right:0;bottom:0;left:0;z-index:2002000;background:rgba(16,26,50,.42);
  display:flex;align-items:center;justify-content:center;padding:24px;
  backdrop-filter:blur(2px)}
.fl-mask[hidden]{display:none}
.fl-panel{width:min(1120px,96vw);max-height:92vh;display:flex;flex-direction:column;
  background:var(--paper,var(--card,#fff));border-radius:16px;overflow:hidden;
  box-shadow:0 24px 60px rgba(12,24,54,.28);animation:flIn .18s ease-out}
@keyframes flIn{from{opacity:0;transform:translateY(10px) scale(.995)}to{opacity:1;transform:none}}
.fl-hd{display:flex;align-items:flex-start;gap:16px;padding:16px 20px;
  border-bottom:1px solid var(--line);background:color-mix(in srgb,var(--brand-flat) 3%,transparent)}
.fl-hd-t h3{margin:0;font-size:16px;display:flex;align-items:center;gap:10px}
.fl-hd-sub{font-size:12px;font-weight:500;color:var(--brand-flat);
  background:var(--brand-soft);padding:2px 9px;border-radius:20px}
.fl-hd-desc{font-size:12px;color:var(--ink3);margin-top:5px;line-height:1.6}
.fl-hd-acts{margin-left:auto;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.fl-hd-acts form{margin:0}
.fl-x{width:30px;height:30px;border:1px solid var(--line);border-radius:8px;background:transparent;
  color:var(--ink3);cursor:pointer;font-size:13px;line-height:1;font-family:inherit}
.fl-x:hover{background:var(--gray-soft);color:var(--ink)}
.fl-body{flex:1;overflow:auto;-webkit-overflow-scrolling:touch}
.fl-body .lyt-wrap{min-height:420px}
.fl-body .lyt-side{background:color-mix(in srgb,var(--gray-soft) 55%,transparent)}
.fl-body .lyt-canvas{min-height:420px}
@media (max-width:760px){
  .fl-mask{padding:0}
  .fl-panel{width:100vw;max-height:100vh;height:100vh;border-radius:0}
  .fl-hd{flex-direction:column}
  .fl-hd-acts{margin-left:0;width:100%}
}

/* 弹层标题行：标题 + 右侧「表单布局」按钮 */
.modal-hd{display:flex;align-items:center;gap:10px;margin-bottom:6px}
.modal-hd h3{margin:0!important}
.modal-hd .fl-btn{margin-left:auto;flex:none;height:28px;font-size:12px;padding:0 9px}

/* ---------- 表单布局：双击改名 / 新字段高亮 / 属性编辑层 ---------- */
.lyt-lab{border-radius:4px;padding:1px 4px;margin-left:-4px;transition:background .15s}
.lyt-lab:not([contenteditable="true"]){cursor:text}
.lyt-lab.editing{background:#fff;box-shadow:0 0 0 2px var(--brand);outline:none;cursor:text}
.lyt-item.flash{animation:lytFlash 1.2s ease}
@keyframes lytFlash{0%{background:color-mix(in srgb,var(--brand-flat) 14%,transparent)}
  100%{background:transparent}}

.fl-props{position:fixed;top:0;right:0;bottom:0;left:0;z-index:2004000;background:rgba(16,26,50,.35);
  display:flex;align-items:center;justify-content:center}
.fl-props[hidden]{display:none}
.fl-props-box{width:min(520px,94vw);max-height:88vh;overflow:auto;background:var(--card,#fff);
  border-radius:14px;box-shadow:0 18px 60px rgba(10,20,50,.28);display:flex;flex-direction:column}
.fl-props-hd{display:flex;align-items:center;justify-content:space-between;
  padding:14px 18px;border-bottom:1px solid var(--line,#e8ecf4)}
.fl-props-hd h4{margin:0;font-size:15px;display:flex;align-items:center;gap:8px}
.fl-props-key{font-size:12px;font-weight:400;color:var(--ink3,#8a93a6);
  background:var(--bg2,#f3f5fa);border-radius:6px;padding:2px 8px}
.fl-props-body{padding:14px 18px;display:flex;flex-direction:column;gap:12px}
.fl-props-row{display:grid;grid-template-columns:86px 1fr;align-items:center;gap:10px}
.fl-props-row[hidden]{display:none}
.fl-props-row>label{font-size:13px;color:var(--ink2,#4b5568);text-align:right}
.fl-props-row .hint{grid-column:2;margin-top:4px;font-size:12px}
.fl-props-2col{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.fl-props-ft{display:flex;align-items:center;justify-content:flex-end;gap:8px;
  padding:12px 18px;border-top:1px solid var(--line,#e8ecf4)}
.fl-props-err{color:var(--bad,#d64545);font-size:13px;margin-right:auto}

/* ============================================================ 更新日志 */
/* 侧栏图标：书签 + 折角（区别于操作日志的横线列表） */
.i-changelog{-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 3l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 16.4 6.8 19.1l1-5.8L3.5 9.2l5.9-.9z'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 3l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 16.4 6.8 19.1l1-5.8L3.5 9.2l5.9-.9z'/></svg>")}
/* 未读新版本小红点 */
.sb-dot{position:absolute;top:9px;right:10px;width:7px;height:7px;border-radius:50%;
  background:var(--bad);box-shadow:0 0 0 2px var(--panel)}
html.sb-collapsed .sb-dot{top:8px;right:14px}

/* ---------- 概览卡 ---------- */
.cl-hero{display:flex;align-items:center;gap:24px;flex-wrap:wrap;
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:20px 24px;margin-bottom:14px;box-shadow:var(--shadow);
  background-image:radial-gradient(560px 200px at 100% 0%,color-mix(in srgb,var(--brand-flat) 8%,transparent),transparent)}
.cl-hero-l{flex:1;min-width:260px}
.cl-hero-badge{display:inline-block;font-size:11.5px;letter-spacing:.4px;color:var(--brand-flat);
  background:var(--brand-soft);border-radius:999px;padding:3px 10px;font-weight:600}
.cl-hero-v{font-size:30px;font-weight:700;letter-spacing:-.5px;line-height:1.25;margin-top:8px;
  color:var(--ink)}
.cl-hero-t{font-size:15px;font-weight:600;color:var(--ink);margin-top:2px}
.cl-hero-d{font-size:12.5px;color:var(--ink3);margin-top:6px}
.cl-hero-r{display:flex;gap:10px;flex-wrap:wrap}
.cl-stat{min-width:104px;text-align:center;background:color-mix(in srgb,var(--gray-soft) 60%,transparent);
  border:1px solid var(--line2);border-radius:12px;padding:12px 14px}
.cl-stat b{display:block;font-size:22px;font-weight:700;color:var(--brand-flat);line-height:1.2}
.cl-stat span{font-size:12px;color:var(--ink3)}
/* 累计代码行：悬停看构成（Python/模板/样式/脚本各多少行），轻微主题色描边区别于业务统计 */
.cl-stat-code{cursor:help;border-color:color-mix(in srgb,var(--brand-flat) 28%,var(--line2));
  background:color-mix(in srgb,var(--brand-flat) 5%,transparent);transition:border-color .15s}
.cl-stat-code:hover{border-color:color-mix(in srgb,var(--brand-flat) 55%,var(--line2))}

/* ---------- 类型筛选 ---------- */
.cl-filter{display:flex;gap:8px;flex-wrap:wrap;margin:0 0 18px}
.cl-f{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:var(--ink2);
  background:var(--panel);border:1px solid var(--line);border-radius:999px;padding:6px 13px;transition:.14s}
.cl-f span{font-size:11.5px;color:var(--ink3);background:var(--gray-soft);border-radius:999px;
  padding:1px 7px;min-width:20px;text-align:center}
.cl-f:hover{border-color:color-mix(in srgb,var(--brand-flat) 45%,transparent);color:var(--brand-flat)}
.cl-f.on{background:var(--brand);background-image:var(--brand);border-color:var(--brand-flat);color:var(--on-brand);font-weight:600}
.cl-f.on span{background:rgba(255,255,255,.22);color:var(--on-brand)}

/* ---------- 时间线 ---------- */
.cl-timeline{position:relative;padding-left:26px}
.cl-timeline::before{content:"";position:absolute;left:6px;top:8px;bottom:26px;width:2px;
  background:linear-gradient(180deg,color-mix(in srgb,var(--brand-flat) 42%,transparent),
    var(--line) 22%,var(--line))}
.cl-rel{position:relative;margin-bottom:14px}
.cl-dot{position:absolute;left:-26px;top:24px;width:14px;height:14px;border-radius:50%;
  background:var(--panel);border:2.5px solid var(--line);box-sizing:border-box}
.cl-dot.cur{border-color:var(--brand-flat);box-shadow:0 0 0 4px color-mix(in srgb,var(--brand-flat) 15%,transparent)}

.cl-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:16px 20px 14px;box-shadow:var(--shadow);transition:.16s}
.cl-card:hover{box-shadow:0 4px 18px rgba(16,28,60,.08);border-color:var(--line2)}
.cl-card-hd{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
.cl-ver{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.cl-ver-n{font-size:15px;font-weight:700;color:var(--ink);letter-spacing:-.2px}
.cl-date{font-size:12.5px;color:var(--ink3);font-variant-numeric:tabular-nums;
  display:flex;align-items:center;gap:7px;text-align:right}
.cl-date b{font-weight:600;color:var(--ink2);font-size:13px}
.cl-date i{font-style:normal;font-size:11.5px;color:var(--brand-flat);
  background:var(--brand-soft);border-radius:999px;padding:1px 8px;font-weight:600}
.cl-tag{font-size:11.5px;border-radius:6px;padding:2px 8px;font-weight:600;border:1px solid transparent}
.cl-tag.major{color:var(--brand-flat);background:var(--brand-soft);
  border-color:color-mix(in srgb,var(--brand-flat) 25%,transparent)}
.cl-tag.minor{color:var(--ink2);background:var(--gray-soft);border-color:var(--line)}
.cl-tag.latest{color:var(--ok);background:var(--ok-soft);
  border-color:color-mix(in srgb,var(--ok) 28%,transparent)}
/* 里程碑徽章：立项 / 测试版上线 / 上云这种架构级节点，紫色区别于大更新 */
.cl-tag.ms{color:#6d3fd4;background:#f1ecfe;border-color:#d8cbfa}
.cl-title{font-size:14.5px;font-weight:600;color:var(--ink);margin-top:8px}
.cl-summary{font-size:13px;color:var(--ink2);margin-top:5px;line-height:1.75}

.cl-list{list-style:none;margin:10px 0 0;padding:0}
.cl-item{display:flex;align-items:flex-start;gap:9px;padding:5px 0;font-size:13px;
  color:var(--ink2);line-height:1.7}
.cl-kind{flex:none;font-size:11px;font-weight:600;border-radius:5px;padding:1px 7px;margin-top:2px;
  border:1px solid transparent;white-space:nowrap}
.kind-new{color:#0f7b4f;background:#e9f7f0;border-color:#c6ecda}
.kind-milestone{color:#6d3fd4;background:#f1ecfe;border-color:#d8cbfa;font-weight:600}
.kind-improve{color:#1d5fd0;background:#eaf1fe;border-color:#cfdffb}
.kind-fix{color:#b4560a;background:#fdf3e6;border-color:#f6ddbe}
.kind-perf{color:#7a3ec8;background:#f4ecfe;border-color:#e2d1fa}
.kind-security{color:#b02a5b;background:#fdecf2;border-color:#f8cfdd}
.kind-upgrade{color:#0e6f7a;background:#e6f6f8;border-color:#c4e8ee}
.cl-text{flex:1}
.cl-more{margin-top:8px;font-size:12.5px;color:var(--brand-flat);background:none;border:none;
  cursor:pointer;padding:4px 0}
.cl-more:hover{text-decoration:underline}

.cl-foot{text-align:center;padding:20px 0 8px;color:var(--ink3);font-size:12.5px}
.cl-foot-sub{display:block;margin-top:4px;font-size:12px;opacity:.8}

@media (max-width:760px){
  .cl-hero{padding:16px;gap:14px}
  .cl-hero-v{font-size:24px}
  .cl-stat{flex:1;min-width:0;padding:10px 8px}
  .cl-card{padding:14px}
  .cl-timeline{padding-left:20px}
  .cl-dot{left:-20px}
}

/* ============================================================
   分页条（列表底部）  _pager.html
   布局：左「第 x–y 条」 / 中「页码胶囊」 / 右「第 x/y 页 + 条数」。
   多页时页码收进一个胶囊容器里，不再是一排挤在一起的小方块；
   作为卡片最后一个元素时随卡片收底部圆角，贴边也不突兀。
   ============================================================ */
.pager{display:flex;align-items:center;justify-content:space-between;gap:12px 16px;
  flex-wrap:wrap;padding:12px 20px;border-top:1px solid var(--line2);
  background:var(--panel);font-size:12.5px;color:var(--ink3)}
.card > .pager:last-child{border-radius:0 0 var(--r-lg) var(--r-lg)}
.pg-left b{color:var(--ink2);font-weight:600;font-variant-numeric:tabular-nums}
/* 页码胶囊：整组页码装在一个圆角容器里，间距统一、多少页都不散 */
.pg-btns{display:flex;align-items:center;gap:4px;flex-wrap:wrap;
  padding:3px;border:1px solid var(--line);border-radius:999px;background:var(--panel)}
.pg-btn,.pg-num{display:inline-flex;align-items:center;justify-content:center;gap:4px;
  min-width:32px;height:28px;padding:0 10px;border-radius:999px;border:1px solid transparent;
  background:transparent;color:var(--ink2);font-size:12.5px;font-weight:500;
  text-decoration:none;cursor:pointer;transition:all .14s;font-variant-numeric:tabular-nums}
.pg-num{padding:0 9px}
.pg-btn:hover,.pg-num:hover{border-color:transparent;
  color:var(--brand-flat);background:var(--brand-soft)}
.pg-num.on{background:var(--brand);background-image:var(--brand);border-color:transparent;color:#fff;font-weight:600;
  cursor:default;box-shadow:0 2px 8px -3px color-mix(in srgb,var(--brand-flat) 60%,transparent)}
.pg-btn.off{opacity:.4;cursor:not-allowed;pointer-events:none}
.pg-gap{display:inline-flex;align-items:center;justify-content:center;min-width:22px;
  height:28px;color:var(--ink3);user-select:none}
.pg-right{display:flex;align-items:center;gap:10px}
.pg-total{font-variant-numeric:tabular-nums}
.pg-size{height:30px;border:1px solid var(--line);border-radius:999px;background:var(--panel);
  color:var(--ink2);font-size:12.5px;padding:0 8px;cursor:pointer;transition:border-color .14s}
.pg-size:hover{border-color:color-mix(in srgb,var(--brand-flat) 45%,transparent)}
.pg-size:focus{outline:none;border-color:var(--brand-flat)}

@media (max-width:700px){
  .pager{padding:12px 14px;justify-content:center}
  .pg-left,.pg-right{width:100%;justify-content:center;text-align:center}
  .pg-num.ell{display:none}
}

/* 紧凑分页（表格上方）：只有 上一页 / 第x/y页 / 下一页 */
.pager.compact{padding:9px 18px;justify-content:center;border-top:none;
  border-bottom:1px solid var(--line2);background:var(--gray-soft)}
.pager.compact .pg-btn{min-width:0;height:26px;padding:0 9px;font-size:12px}
.pager.compact .pg-here{margin-left:8px;font-size:12px;color:var(--ink2);
  font-variant-numeric:tabular-nums}

/* ============================================================
   列表页自适应视口：卡片撑满「顶栏以下」的高度，表体内部滚动，
   底部翻页条始终贴在屏幕内 —— 不用滚到底就能翻页。
   .main.fit：由 _fit 类页面挂上（所有带分页条的列表页）。
   ============================================================ */
/* 高度固定为满屏（flex 百分比要靠它换算）；滚不滚动交给浏览器：
   卡片有保底高度，装不下时内容溢出，body 可滚，不会把卡片压瘪 */
body.list-fit{height:100vh;overflow-y:auto}
body.list-fit .layout{height:100vh;min-height:0}
body.list-fit .main{display:flex;flex-direction:column;min-height:0;padding-bottom:14px}

/* 列表卡片吃掉剩余高度；卡片内部的表体自己滚 */
body.list-fit .main > .card.fit{flex:1 1 auto;min-height:0;display:flex;flex-direction:column}
body.list-fit .main > .card.fit > .tb-wrap{flex:1 1 auto;min-height:0;overflow:auto}
body.list-fit .main > .card.fit > .pager{flex:0 0 auto}

/* 表头在滚动时钉住，长列表也不会忘了列名 */
body.list-fit .main > .card.fit > .tb-wrap > table.tb > thead th{
  position:sticky;top:0;z-index:2;background:var(--panel)}

/* 列表序号列：淡一点、等宽数字，只做视觉定位，不抢内容 */
.th-seq{width:56px;text-align:center;color:var(--ink3);font-weight:500}
.td-seq{width:56px;text-align:center;color:var(--ink3);font-size:12.5px;
  font-variant-numeric:tabular-nums;user-select:none}
/* 序号列居中：压过 .tb th / .tb td 的默认左对齐（同优先级下靠后定义生效） */
.tb th.th-seq,.tb td.td-seq{text-align:center}

/* ------------------------------------------------------------
   产品与工艺页：三个板块在一屏内自适应
   上排 = 产品（1.7fr）+ 工艺路线（1fr）；下排 = 工序。
   每个板块的表体各自内部滚动，表头钉住。
   ------------------------------------------------------------ */
body.list-fit .main > .prods-grid{flex:1 1 46%;min-height:280px;align-items:stretch}
body.list-fit .prods-grid > .card{min-height:0;display:flex;flex-direction:column}
body.list-fit .prods-grid > .card > .tb-wrap{flex:1 1 auto;min-height:0;overflow:auto}
/* 工序卡保底 430px：卡头+分类条+翻页+底注要吃掉约 200px，
   再小就只剩一两行表格，看着像"数据没出来"。屏幕装不下就让整页滚，
   不再把卡片压瘪 */
body.list-fit .main > .card.proc-card{flex:1 1 54%;min-height:420px;
  display:flex;flex-direction:column;margin-top:0!important}
body.list-fit .card.proc-card > .tb-wrap{flex:1 1 auto;min-height:0;overflow:auto}

/* 内部滚动的表格：表头钉在滚动区顶部（不限层级，grid 里的卡也生效） */
body.list-fit .prods-grid .tb-wrap thead th,
body.list-fit .card.proc-card .tb-wrap thead th{
  position:sticky;top:0;z-index:2;background:var(--gray-soft)}

@media(max-width:900px){
  /* 窄屏放弃一屏约束，回到普通滚动 */
  body.list-fit{height:auto;overflow:auto}
  body.list-fit .layout{height:auto;min-height:0}
  body.list-fit .main{height:auto}
  body.list-fit .main > .prods-grid{flex:0 0 auto}
  body.list-fit .main > .card.proc-card{flex:0 0 auto;margin-top:14px!important}
  body.list-fit .prods-grid > .card > .tb-wrap,
  body.list-fit .card.proc-card > .tb-wrap{overflow:visible}
}

/* ------------------------------------------------------------
   屏幕再矮也不再压瘪卡片：卡片有保底高度（见上面的 min-height），
   总高超过视口时由 body 自然滚动（body.list-fit 已改为 overflow-y:auto）。
   这样表体永远有足够高度显示若干行 + 内部滚动，不会出现"只剩两行"。
   ------------------------------------------------------------ */

/* ------------------------------------------------------------
   产品与工艺：三块作为「一张工作台」，而不是三张独立卡片
   · 上下两排按内容重量分配（上排 56% / 下排 44%），不再一刀切
   · 统一头部高度：标题行只有一行，操作全部收进右侧
   · 卡片间距压缩到 12px，视觉上连成一片
   ------------------------------------------------------------ */
.fl-inline{display:inline-flex;align-items:center}
.fl-inline .fl-btn{height:28px}

body.list-fit .main > .prods-grid{
  flex:1 1 46%;min-height:280px;align-items:stretch;gap:12px}
body.list-fit .main > .card.proc-card{
  flex:1 1 54%;min-height:420px;margin-top:12px!important}
body.list-fit .prods-grid > .card,
body.list-fit .card.proc-card{
  border-radius:var(--r-lg);
  box-shadow:0 1px 2px rgba(16,28,60,.04),0 8px 24px -18px rgba(16,28,60,.18)}

/* 卡片头统一高度：所有板块第一行都对齐到同一条基线 */
body.list-fit .prods-grid > .card > .card-hd,
body.list-fit .card.proc-card > .card-hd{min-height:52px;padding:10px 16px}
body.list-fit .prods-grid > .card > .card-hd h3,
body.list-fit .card.proc-card > .card-hd h3{font-size:14.5px}

/* 分类标签条：贴近表头、压缩留白 */
body.list-fit .prods-grid > .card > .cat-bar{padding:6px 16px 8px;gap:6px}
body.list-fit .cat-tab{height:24px;line-height:24px;font-size:12px}

/* 工序卡底注：收在卡片内（翻页条下方），不再单独一张卡悬在窗口底边 */
.proc-foot{flex:0 0 auto;padding:7px 16px;border-top:1px solid var(--line2);
  background:var(--gray-soft);border-radius:0 0 var(--r-lg) var(--r-lg)}
.proc-foot .hint{margin:0;font-size:11px;line-height:1.55}
.proc-foot .hint + .hint{margin-top:2px}

/* ------------------------------------------------------------
   工序板块：车间分类 + 搜索 + 翻页
   工序卡现在也是一个完整的列表卡（头部有筛选条、底部有翻页），
   所以头部高度不能再钉 52px，交给内容撑开。
   ------------------------------------------------------------ */
/* 工序卡头部必须保住最小高度：屏幕矮时整卡被压缩，
   头部一旦被压瘪，表单布局/搜索按钮就会浮到下方分类标签上，
   点「电气车间」点到的是按钮 —— 切换就"失灵"了 */
body.list-fit .card.proc-card > .card-hd{min-height:40px;padding:9px 16px}
body.list-fit .card.proc-card > .card-hd .hd-right{gap:8px}
/* 工序卡的筛选条比产品卡窄一档，避免把标题挤出问题 */
body.list-fit .card.proc-card .flt-bar .flt-input input{width:170px}
body.list-fit .card.proc-card > .cat-bar{padding:2px 16px 8px;gap:6px}
body.list-fit .card.proc-card > .pager{flex:0 0 auto;padding:8px 16px}
/* 车间列：小胶囊，弱化存在感但仍可点 */
.ws-chip{display:inline-block;padding:1px 8px;border-radius:9px;background:var(--gray-soft);
  color:var(--ink2);font-size:11.5px;text-decoration:none;white-space:nowrap}
.ws-chip:hover{background:color-mix(in srgb,var(--ink) 12%,var(--panel));color:var(--ink)}
.ws-chip.on{background:var(--brand);background-image:var(--brand);color:#fff}
/* 车间标签条在表体上方，压缩到和产品卡一致的高度 */
body.list-fit .card.proc-card .cat-bar{margin-bottom:0}

/* 品检判定：三选一卡片（合格 / 返工 / 报废） */
.insp-opt{display:flex;align-items:flex-start;gap:8px;flex:1;padding:10px 12px;
  border:1px solid var(--line);border-radius:10px;cursor:pointer;transition:.12s;background:var(--panel)}
.insp-opt:hover{border-color:#c7d2fe}
.insp-opt.on{border-color:var(--brand-flat);background:rgba(37,99,235,.06)}
.insp-opt input{margin:3px 0 0;accent-color:var(--brand-flat);flex:none}
.insp-opt div{display:flex;flex-direction:column;gap:2px;line-height:1.4}
.insp-opt b{font-size:13px;color:var(--ink)}
.insp-opt span{font-size:11.5px;color:var(--ink3)}

/* ================= 操作提醒：液态玻璃悬浮胶囊 =================
   设计语言与全站玻璃卡片一致：半透白底 + 背景模糊提饱和、内侧高光描边、
   状态色只负责「染色」——投影、氛围光晕、进度条全部由它派生，
   正文保持墨色，状态交给左侧渐变圆徽 + 顶部光晕来表达。 */
.toast-pop{
  --tint:rgba(16,24,40,.22);   /* 状态投影/光晕 */
  --wash:rgba(255,255,255,.5); /* 内部氛围色 */
  --bar-a:#64748b;--bar-b:#94a3b8;
  position:fixed;top:18px;left:50%;transform:translateX(-50%);z-index:2000;
  display:flex;align-items:flex-start;gap:11px;max-width:min(520px,86vw);
  padding:12px 14px 13px 12px;border-radius:16px;font-size:13px;line-height:1.5;
  color:var(--ink);overflow:hidden;isolation:isolate;
  background:linear-gradient(115deg,rgba(255,255,255,.88),rgba(255,255,255,.6) 52%,rgba(255,255,255,.8));
  -webkit-backdrop-filter:blur(20px) saturate(1.7);
  backdrop-filter:blur(20px) saturate(1.7);
  border:1px solid rgba(255,255,255,.78);
  box-shadow:0 20px 48px -14px var(--tint),0 3px 12px -4px rgba(16,24,40,.12),
    inset 0 1px 0 rgba(255,255,255,.95),inset 0 -1px 0 rgba(255,255,255,.25);
  animation:toastIn .55s cubic-bezier(.22,1.32,.36,1)}
/* 状态氛围：右上角一团带色薄雾，从玻璃里透出来 */
.toast-pop::before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;pointer-events:none;
  background:radial-gradient(130% 160% at 88% -20%,var(--wash),transparent 62%)}
/* 底部寿命条：渐变 + 同色辉光，走到头自动关闭 */
.toast-pop::after{content:"";position:absolute;left:0;bottom:0;height:2.5px;border-radius:0 0 15px 15px;
  background:linear-gradient(90deg,transparent,var(--bar-a) 30%,var(--bar-b));
  box-shadow:0 0 9px var(--wash);opacity:.95;animation:toastBar 2s linear forwards}
.toast-pop .al-ico{width:20px;height:20px;flex:0 0 20px;margin-top:1px;border-radius:50%;
  color:#fff;display:flex;align-items:center;justify-content:center}
.toast-pop .al-ico svg{width:11.5px;height:11.5px}
.toast-pop .al-txt{flex:1;min-width:0;font-weight:500;letter-spacing:.1px}
.toast-pop .al-x{flex:none;width:20px;height:20px;border:0;background:transparent;cursor:pointer;
  color:var(--ink3);opacity:.8;font-size:14px;line-height:1;border-radius:7px;
  display:flex;align-items:center;justify-content:center;padding:0;margin-top:-1px;
  transition:opacity .15s,background-color .15s,color .15s}
.toast-pop .al-x:hover{opacity:1;background:rgba(16,24,40,.07);color:var(--ink)}
.toast-pop.ok{--tint:rgba(21,150,80,.32);--wash:rgba(52,211,153,.22);--bar-a:#16a34a;--bar-b:#4ade80}
.toast-pop.ok .al-ico{background:linear-gradient(135deg,#4ade80,#16a34a);
  box-shadow:0 0 0 3.5px rgba(34,197,94,.15),0 4px 10px -2px rgba(22,163,74,.55)}
.toast-pop.bad{--tint:rgba(200,32,32,.3);--wash:rgba(248,113,113,.2);--bar-a:#dc2626;--bar-b:#f87171}
.toast-pop.bad .al-ico{background:linear-gradient(135deg,#f87171,#dc2626);
  box-shadow:0 0 0 3.5px rgba(220,38,38,.13),0 4px 10px -2px rgba(200,32,32,.5)}
.toast-pop.hide{opacity:0;transform:translateX(-50%) translateY(-12px) scale(.97);
  transition:opacity .3s ease,transform .3s ease}@keyframes toastIn{
  0%{opacity:0;transform:translateX(-50%) translateY(-20px) scale(.9)}
  62%{opacity:1;transform:translateX(-50%) translateY(2px) scale(1.015)}
  100%{opacity:1;transform:translateX(-50%) translateY(0) scale(1)}}
@keyframes toastBar{from{width:100%}to{width:0}}
@media (max-width:640px){
  .toast-pop{top:10px;border-radius:14px;padding:11px 12px}
}

/* ================= 实时通知浮层（右下角堆叠） =================
   与 .toast-pop 同宗：半透白渐变 + 背景模糊提饱和 + 内侧高光描边，
   状态色只做「染色」（投影/光晕/细描边/圆徽渐变），正文保持墨色。
   区别是它不自动消失——现场的人可能正低头干活，错过一次就得多跑一趟。 */
.ntf-stack{
  position:fixed;right:18px;bottom:18px;z-index:2100;width:360px;
  max-width:calc(100vw - 28px);display:flex;flex-direction:column;gap:10px;
  pointer-events:none;
}
.ntf-pop{
  --tint:rgba(49,46,129,.28);--wash:rgba(129,140,248,.22);--bar-a:#4f46e5;--bar-b:#818cf8;
  pointer-events:auto;position:relative;display:flex;gap:11px;align-items:flex-start;
  padding:13px 34px 13px 13px;border-radius:17px;isolation:isolate;overflow:hidden;
  font-size:13px;line-height:1.5;color:var(--ink);
  background:linear-gradient(115deg,rgba(255,255,255,.92),rgba(255,255,255,.66) 52%,rgba(255,255,255,.86));
  -webkit-backdrop-filter:blur(20px) saturate(1.7);
  backdrop-filter:blur(20px) saturate(1.7);
  border:1px solid rgba(255,255,255,.82);
  box-shadow:0 24px 54px -18px var(--tint),0 3px 12px -4px rgba(16,24,40,.14),
    inset 0 1px 0 rgba(255,255,255,.95),inset 0 -1px 0 rgba(255,255,255,.22);
  animation:ntfIn .52s cubic-bezier(.22,1.32,.36,1);
}
/* 右上角一团带色薄雾，从玻璃后面透出来 */
.ntf-pop::before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;pointer-events:none;
  background:radial-gradient(130% 150% at 92% -30%,var(--wash),transparent 64%)}
/* 左侧一道 3px 渐变色条：远看就知道是哪类事 */
.ntf-pop::after{content:"";position:absolute;left:0;top:12px;bottom:12px;width:3px;
  border-radius:0 3px 3px 0;background:linear-gradient(180deg,var(--bar-b),var(--bar-a));
  box-shadow:0 0 10px var(--wash)}
.ntf-pop .np-ico{
  width:27px;height:27px;flex:0 0 27px;border-radius:50%;color:#fff;
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(135deg,var(--bar-b),var(--bar-a));
  box-shadow:0 0 0 3.5px var(--wash),0 5px 12px -3px var(--tint);
}
.ntf-pop .np-ico svg{width:14px;height:14px}
.ntf-pop .np-bd{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;align-items:flex-start}
.ntf-pop .np-tag{
  font-size:10.5px;font-weight:700;letter-spacing:.6px;line-height:1.6;
  padding:0 7px;border-radius:6px;margin-bottom:1px;color:var(--bar-a);
  background:rgba(255,255,255,.78);border:1px solid rgba(16,24,40,.08);
}
.ntf-pop b{font-size:13.5px;font-weight:650;letter-spacing:.1px;color:var(--ink);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.ntf-pop i{font-style:normal;font-size:12px;line-height:1.55;color:var(--ink3);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.ntf-pop .np-go{
  margin-top:8px;padding:5px 13px;border-radius:8px;cursor:pointer;font-size:12px;
  font-weight:600;letter-spacing:.2px;color:#fff;border:0;
  background:linear-gradient(135deg,var(--bar-b),var(--bar-a));
  box-shadow:0 5px 12px -5px var(--tint),inset 0 1px 0 rgba(255,255,255,.35);
  transition:transform .12s,box-shadow .12s,filter .12s;
}
.ntf-pop .np-go:hover{filter:brightness(1.05);transform:translateY(-1px);
  box-shadow:0 8px 16px -6px var(--tint),inset 0 1px 0 rgba(255,255,255,.35)}
.ntf-pop .np-go:active{transform:translateY(0)}
.ntf-pop .np-x{
  position:absolute;top:8px;right:8px;width:22px;height:22px;padding:0;border:0;
  background:transparent;border-radius:8px;cursor:pointer;font-size:15px;line-height:1;
  color:var(--ink3);opacity:.72;display:flex;align-items:center;justify-content:center;
  transition:opacity .15s,background-color .15s,color .15s;
}
.ntf-pop .np-x:hover{opacity:1;background:rgba(16,24,40,.07);color:var(--ink)}
/* 状态染色：待处理=琥珀、晚交/不合格=红、偏紧=蓝、逾期=深红 */
.ntf-pop.warn{--tint:rgba(180,83,9,.3);--wash:rgba(251,191,36,.24);--bar-a:#d97706;--bar-b:#fbbf24}
.ntf-pop.high{--tint:rgba(194,65,12,.3);--wash:rgba(251,146,60,.22);--bar-a:#ea580c;--bar-b:#fb923c}
.ntf-pop.late{--tint:rgba(185,28,28,.32);--wash:rgba(248,113,113,.22);--bar-a:#dc2626;--bar-b:#f87171}
.ntf-pop.tight{--tint:rgba(29,78,216,.28);--wash:rgba(96,165,250,.22);--bar-a:#2563eb;--bar-b:#60a5fa}
.ntf-pop.bad{--tint:rgba(185,28,28,.32);--wash:rgba(248,113,113,.22);--bar-a:#dc2626;--bar-b:#f87171}
.ntf-pop.out{opacity:0;transform:translateY(8px) scale(.97);
  transition:opacity .28s ease,transform .28s ease}
@keyframes ntfIn{
  0%{opacity:0;transform:translateY(14px) scale(.94)}
  62%{opacity:1;transform:translateY(-2px) scale(1.01)}
  100%{opacity:1;transform:translateY(0) scale(1)}
}
@media (max-width:640px){
  /* 手机上贴着底边铺开，避开顶栏和输入法；一次最多两条，别挡整屏 */
  .ntf-stack{left:10px;right:10px;bottom:12px;width:auto;max-width:none;gap:8px}
  .ntf-pop{padding:11px 32px 11px 11px;border-radius:15px;font-size:12.5px}
  .ntf-pop b{font-size:13px}
  .ntf-pop i{-webkit-line-clamp:2}
}

/* ================= 客户简码 chip（订单等列表里只亮简码用） ================= */
.cust-code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12.5px;
  font-weight:600;letter-spacing:.4px;color:var(--ink)}

/* ================= 存储归档页：授权状态行 / 未开通警告盒 ================= */
.arc-ok-line{font-size:13px;color:#0f7a3d;background:#f2fbf5;border:1px solid #c9ecd6;
  border-radius:10px;padding:10px 13px;line-height:1.6}
.arc-ok-line code{background:rgba(22,163,74,.09);padding:1px 6px;border-radius:5px;
  font-size:12px;font-family:ui-monospace,monospace}
.arc-warn-box{background:#fef7f4;border:1px solid #f6d8cc;border-radius:12px;padding:14px 16px}
.arc-warn-box .aw-ttl{font-size:13.5px;font-weight:600;color:#b4471c;display:flex;align-items:center;gap:7px}
.arc-warn-box .aw-ttl::before{content:"!";width:17px;height:17px;flex:0 0 17px;border-radius:50%;
  background:#ea7a3c;color:#fff;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center}
.arc-warn-box .aw-desc{font-size:12.5px;color:#8a5a44;line-height:1.8;margin-top:8px}
.arc-warn-box .aw-steps{margin-top:10px;display:flex;flex-direction:column;gap:7px}
.arc-warn-box .aw-steps>div{display:flex;align-items:flex-start;gap:8px;font-size:12.5px;color:#7c4a34;line-height:1.7}
.arc-warn-box .aw-steps i{font-style:normal;width:17px;height:17px;flex:0 0 17px;margin-top:2px;border-radius:50%;
  background:#f7dcc9;color:#b4471c;font-size:10.5px;font-weight:700;display:flex;align-items:center;justify-content:center}
.arc-warn-box a{color:#b4471c;text-decoration:underline;text-underline-offset:2px}
.arc-kv>div{padding:9px 0}
.btn.primary[disabled]{opacity:.45;cursor:not-allowed;filter:saturate(.35)}

/* ---------- 工单列表 · 工序进度带（每段一道工序，按完成度填充） ---------- */
.pcell{position:relative;cursor:pointer}
.pbar{display:flex;gap:2px;height:7px;align-items:stretch;max-width:270px;min-width:150px}
.pbar>i{flex:1 1 0;min-width:2px;border-radius:2px;background:var(--line2);
  transition:opacity .16s,transform .16s}
.pbar>i.done{background:var(--ok)}
.pbar>i.doing{background:linear-gradient(90deg,var(--brand-flat) var(--p),var(--line2) var(--p))}
/* 已开工还没报数（两段式报工）：0% 但描一圈品牌色，和没开工的灰段区分开 */
.pbar>i.str{box-shadow:inset 0 0 0 1px var(--brand-flat)}
.pbar>i.chk{background:linear-gradient(90deg,var(--warn) var(--p),var(--line2) var(--p))}
.pbar>i.late{background:linear-gradient(90deg,var(--bad) var(--p),var(--line2) var(--p))}
/* 弹层开着时：其余段淡出，指到的那段顶起来，和清单对应（仅点击弹出后生效） */
.pbar>i.kb{opacity:1!important;transform:scaleY(1.5);border-radius:2px}
.pbar-txt{display:flex;align-items:baseline;gap:5px;margin-top:7px;max-width:270px;
  font-size:11.5px;color:var(--ink3);white-space:nowrap;overflow:hidden}
.pbar-txt b{font-weight:600;color:var(--ink2);font-size:12px;overflow:hidden;text-overflow:ellipsis;max-width:120px}
.pbar-txt .pp{font-variant-numeric:tabular-nums;flex:0 0 auto}
.pbar-txt .pn{margin-left:auto;flex:0 0 auto;font-variant-numeric:tabular-nums}
.pbar-txt b.pd{color:var(--ok)}
.pbar-txt em{font-style:normal;font-size:10.5px;line-height:16px;padding:0 4px;border-radius:3px;flex:0 0 auto}
.pbar-txt em.pk{background:var(--warn-soft);color:var(--warn)}
.pbar-txt em.pl{background:var(--bad-soft);color:var(--bad)}

/* 悬停详情：完整工序清单，fixed 定位浮在表格之上，滚动表格时不会跟着错位 */
.pbar-pop{position:fixed;z-index:90;width:270px;max-height:min(380px,72vh);overflow:auto;
  border:1px solid var(--line);border-radius:12px;padding:6px;
  box-shadow:0 18px 44px rgba(16,24,40,.17),0 2px 6px rgba(16,24,40,.06);
  font-size:12.5px;display:none;animation:popin .13s ease-out;
  /* 细滚动条（Firefox） */
  scrollbar-width:thin;scrollbar-color:var(--line) transparent;
  /* 上下滚动阴影：还有内容时边缘淡淡的渐隐提示（纯 CSS，跟随滚动自动消失/出现） */
  background:
    linear-gradient(var(--panel) 34%,rgba(255,255,255,0)) 0 0 / 100% 36px no-repeat local,
    linear-gradient(rgba(255,255,255,0),var(--panel) 66%) 0 100% / 100% 36px no-repeat local,
    radial-gradient(farthest-side at 50% 0,rgba(16,24,40,.13),transparent) 0 0 / 100% 13px no-repeat scroll,
    radial-gradient(farthest-side at 50% 100%,rgba(16,24,40,.13),transparent) 0 100% / 100% 13px no-repeat scroll,
    var(--panel)}
.pbar-pop::-webkit-scrollbar{width:9px}
.pbar-pop::-webkit-scrollbar-track{background:transparent}
.pbar-pop::-webkit-scrollbar-thumb{background:var(--line);border-radius:5px;
  border:2px solid var(--panel);background-clip:padding-box}
.pbar-pop::-webkit-scrollbar-thumb:hover{background:var(--ink3);background-clip:padding-box}
@keyframes popin{from{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:none}}
.pbar-pop.on{display:block}
.pbar-pop .ph{position:sticky;top:-6px;z-index:1;display:flex;align-items:baseline;gap:8px;
  padding:6px 8px 8px;background:var(--panel);border-bottom:1px solid var(--line2)}
.pbar-pop .ph b{font-size:12.5px;color:var(--ink)}
.pbar-pop .ph span{margin-left:auto;color:var(--ink3);font-size:11.5px;font-variant-numeric:tabular-nums}
.pbar-pop .pr{display:flex;align-items:center;gap:8px;padding:5px 8px;border-radius:7px;color:var(--ink2)}
.pbar-pop .pr .pii{flex:0 0 14px;width:14px;height:14px;border-radius:50%;
  border:1.5px solid var(--line);display:flex;align-items:center;justify-content:center;
  font-size:9px;color:var(--ink3);font-variant-numeric:tabular-nums}
.pbar-pop .pr.done .pii{background:var(--ok);border-color:var(--ok);color:#fff}
.pbar-pop .pr.doing{color:var(--ink)}
.pbar-pop .pr.doing .pii{border-color:var(--brand-flat);color:var(--brand-flat);font-size:8px;font-weight:700}
.pbar-pop .pr.cur{background:color-mix(in srgb,var(--brand-flat) 8%,transparent)}
.pbar-pop .pr.cur .pnm{font-weight:600;color:var(--ink)}
.pbar-pop .pr.chk .pii{border-color:var(--warn);color:var(--warn);font-size:7.5px}
.pbar-pop .pr.kb{background:var(--line2)}
.pbar-pop .pr .pnm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pbar-pop .pr .pqv{margin-left:auto;flex:0 0 auto;font-size:11px;color:var(--ink3);
  font-variant-numeric:tabular-nums}
.pbar-pop .pfoot{padding:7px 8px 3px;color:var(--ink3);font-size:11px;border-top:1px solid var(--line2);
  margin-top:4px;display:flex;justify-content:space-between}

/* 旧版节点条：保留给可能引用它的页面，工单列表已改用上面的进度带 */
.osteps{display:flex;align-items:flex-start;padding:1px 0 0;overflow-x:auto;overscroll-behavior-x:contain;
  max-width:640px}
.ostep{position:relative;flex:0 0 auto;width:58px;display:flex;flex-direction:column;
  align-items:center;gap:4px;padding:0 2px}
.ostep .oc{position:relative;z-index:1;width:25px;height:25px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:600;
  font-variant-numeric:tabular-nums;letter-spacing:-.2px;
  border:1.5px solid var(--line);background:var(--panel);color:var(--ink3);
  transition:background .15s,border-color .15s,color .15s}
.ostep .ol{font-size:11px;color:var(--ink3);max-width:100%;text-align:center;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.25}
/* 相邻节点之间的连线：画在后一个节点的左半边，到本节点为绿 */
.ostep + .ostep::before{content:"";position:absolute;left:-50%;top:12px;width:100%;height:2px;
  background:var(--line);z-index:0}
.ostep.done + .ostep::before{background:color-mix(in srgb,var(--ok) 45%,var(--line))}
/* 已完成：绿底白勾 */
.ostep.done .oc{border-color:var(--ok);background:var(--ok)}
.ostep.done .oc::after{content:"";width:6px;height:10px;margin-top:-2px;
  border:solid #fff;border-width:0 2px 2px 0;transform:rotate(43deg)}
.ostep.done .ol{color:var(--ink2)}
/* 进行中：品牌色环 + 百分比 */
.ostep.doing .oc{border-color:var(--brand-flat);color:var(--brand-flat);
  background:color-mix(in srgb,var(--brand-flat) 9%,var(--panel))}
.ostep.doing .ol{color:var(--ink2)}
/* 待品检：琥珀色，提醒卡在检验这一步 */
.ostep.chk .oc{border-color:var(--warn);color:var(--warn);
  background:var(--warn-soft)}
/* 未开工：灰色空心圈，显示 0% */
.ostep.wait .oc{border-style:dashed;color:var(--ink3)}
/* 逾期：当前这道工序右上角红角标（交期已过、还没完工） */
.ostep.late::after{content:"";position:absolute;top:-2px;right:7px;width:8px;height:8px;
  border-radius:50%;background:var(--bad);border:1.5px solid var(--panel);z-index:2}
.ostep.late .oc{border-color:var(--bad)}
.ostep.late .ol{color:var(--bad)}
.osteps.od-late .ostep.late .oc{box-shadow:0 0 0 3px color-mix(in srgb,var(--bad) 12%,transparent)}

/* ================= 顶栏通知铃铛（v3.20） ================= */
.tb-bell{position:relative;width:34px;height:34px;border:0;border-radius:9px;
  background:transparent;color:var(--ink2);cursor:pointer;
  display:flex;align-items:center;justify-content:center;transition:.12s}
.tb-bell:hover{background:var(--gray-soft);color:var(--ink)}
.ntf-badge{position:absolute;top:-3px;right:-3px;min-width:16px;height:16px;
  padding:0 4px;border-radius:8px;background:var(--bad,#e24b4a);color:#fff;
  font-size:10px;font-weight:600;line-height:16px;text-align:center;
  box-shadow:0 0 0 2px var(--panel)}
.ntfmenu{position:relative}
.ntf-drop{position:absolute;right:0;top:calc(100% + 8px);width:340px;max-width:calc(100vw - 24px);
  background:var(--panel);border:1px solid var(--line);border-radius:14px;
  box-shadow:0 18px 50px -10px rgba(16,24,40,.25),0 3px 12px rgba(16,24,40,.08);
  z-index:2000500;overflow:hidden;animation:ntfIn .18s ease-out}
@keyframes ntfIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.ntf-hd{display:flex;align-items:center;justify-content:space-between;
  padding:10px 14px;border-bottom:1px solid var(--line)}
.ntf-hd b{font-size:13px;color:var(--ink)}
.ntf-readall{border:0;background:transparent;color:var(--brand-flat,var(--brand));
  font-size:12px;cursor:pointer;font-family:inherit;padding:2px 4px;border-radius:6px}
.ntf-readall:hover{background:var(--gray-soft)}
.ntf-list{max-height:380px;overflow-y:auto;padding:6px}
.ntf-list::-webkit-scrollbar{width:6px}
.ntf-list::-webkit-scrollbar-thumb{border-radius:3px;background:var(--gray-soft)}
.ntf-empty{padding:26px 14px;text-align:center;font-size:12.5px;color:var(--ink3);line-height:1.8}
.ntf-item{display:block;position:relative;padding:10px 12px 10px 14px;border-radius:10px;
  text-decoration:none;transition:.12s}
.ntf-item:hover{background:var(--gray-soft)}
.ntf-item b{display:block;font-size:13px;font-weight:500;color:var(--ink);
  line-height:1.5;margin:2px 0 3px}
.ntf-item i{display:block;font-style:normal;font-size:12px;color:var(--ink2);line-height:1.6}
.ntf-item time{display:block;font-size:11px;color:var(--ink3);margin-top:4px}
.ntf-item.read b{color:var(--ink3);font-weight:400}
.ntf-item.read i{color:var(--ink3)}
.ntf-item::before{content:"";position:absolute;left:5px;top:16px;width:5px;height:5px;
  border-radius:50%;background:var(--bad,#e24b4a)}
.ntf-item.read::before{background:var(--ink3);opacity:.35}
.ntf-tag{display:inline-block;font-size:10.5px;line-height:1;padding:3px 7px;border-radius:999px;
  color:var(--bad,#a32d2d);background:color-mix(in srgb,var(--bad,#e24b4a) 10%,transparent)}
.ntf-item.ntf-high .ntf-tag{color:#ba7517;background:color-mix(in srgb,#ef9f27 14%,transparent)}
.ntf-item.ntf-tight .ntf-tag{color:#185fa5;background:color-mix(in srgb,#378add 12%,transparent)}

/* ============================================================
   手机档（≤600px）：真正的手机端统一收紧
   —— 侧栏抽屉化见 860px 块；这里管内边距、字号、表格、卡片
   ============================================================ */
@media (max-width:600px){
  /* 内容区内边距：桌面 26px 在手机上吃掉大半宽度 */
  .main{padding:14px 12px 52px}
  .topbar{margin-bottom:14px;gap:10px}
  .topbar h1{font-size:18px;letter-spacing:0}
  .card-pad{padding:13px 14px}
  .card-hd{padding:11px 14px}
  /* 表格：窄屏不再把每列挤成竖条文字，保持可读宽度、表体横向滚 */
  .tb th{padding:8px 9px;font-size:11.5px}
  .tb td{padding:9px;font-size:12.5px}
  .tb-wrap>table.tb{min-width:480px}
  /* 卡片内嵌小表（订单/销售详情里 2-3 列的）不需要那么宽 */
  .card .tb-wrap>table.tb{min-width:0}
  body.list-fit .main>.card.fit>.tb-wrap>table.tb,
  body.list-fit .prods-grid .tb-wrap>table.tb,
  body.list-fit .card.proc-card>.tb-wrap>table.tb{min-width:480px}
  .pager{padding:10px 12px}
  /* 表单行两个字段在手机上改成上下排，输入框才有足够宽度 */
  .row{flex-wrap:wrap}
  .row>*{flex:1 1 160px}
  /* 弹窗贴边留 10px，圆角小一号 */
  .modal{max-width:calc(100vw - 20px)!important}
  /* 关键修复：模板里大量 grid 用了内联 grid-template-columns（如看板下方两栏、
     归档页左右栏），内联样式优先级高于 .g2/.g3 的断点规则，手机上仍是两列，
     直接把内容撑出屏幕。这里统一在手机档强制单列——!important 才能压过内联。 */
  .grid{grid-template-columns:1fr!important}
  /* grid/flex 子项默认 min-width:auto，会被内部表格的 min-content 顶宽，
     连带把卡片和整页撑出屏幕——手机档统一放开收缩限制 */
  .grid>*,.card,.tb-wrap,.main{min-width:0}
  .tb-wrap{max-width:100%}
  .card{max-width:100%}
  /* 卡片头右侧的筛选表单（两个下拉并排）在手机上改为整体换行、可收缩 */
  .card-hd .hd-right,.card-hd .hd-right form{max-width:100%;flex-wrap:wrap}
  .card-hd .hd-right{margin-left:0;width:100%}
  .card-hd .hd-right select{max-width:100%;min-width:0}
}

/* ---------- 后台管理设置页：字段行（原模板内联样式迁移） ---------- */
.set-row{display:flex;align-items:flex-start;gap:14px;padding:9px 0;border-bottom:1px dashed var(--line2)}
.set-lab{flex:0 0 190px;font-size:13px;font-weight:600;padding-top:8px}
@media (max-width:600px){
  /* 手机上标签占整行，输入框才有足够宽度（原内联 190px 固定宽会挤成一字宽） */
  .set-row{flex-wrap:wrap;gap:4px}
  .set-lab{flex:1 1 100%;padding-top:0}
}

/* ================= 实时同步的「已同步」小标（列表自己更新完亮一下） ================= */
.live-synced{
  display:inline-block;margin-left:8px;vertical-align:2px;
  font-size:11px;font-weight:600;line-height:1.6;letter-spacing:.2px;
  color:var(--ok);
  background:color-mix(in srgb,var(--ok) 12%,#fff);
  border:1px solid color-mix(in srgb,var(--ok) 26%,#fff);
  border-radius:20px;padding:0 8px;
  animation:liveSyncIn .28s cubic-bezier(.2,.9,.3,1.2);
}
.live-synced.out{opacity:0;transition:opacity .5s}
@keyframes liveSyncIn{
  from{opacity:0;transform:translateY(-3px) scale(.94)}
  to{opacity:1;transform:none}
}
@media (prefers-reduced-motion:reduce){
  .live-synced{animation:none}
}

/* 勾选态高亮：CSS 是 :has()，旧内核由 app.js 补 .on 类（效果一致） */
.pick.on{border-color:var(--brand-flat);background:var(--brand-soft)}
.chip-check.on{border-color:var(--brand-flat);background:var(--brand-soft);color:var(--brand-flat)}
.cf-chip.on{background:var(--brand-soft);border-color:var(--brand-flat)}
.pm-radio.on{border-color:var(--brand-flat)}

/* ================= 工单优先级（0 普通 / 1 加急 / 2 特急） ================= */
/* 特急比加急更重：实底深红白字，扫一眼就能从列表里挑出来 */
.tag.hot{background:#cf1322;color:#fff;font-weight:600;letter-spacing:.3px}
.tag.urgent{background:#fff1f0;color:#cf1322}

/* 建单页：三档优先级卡片。radio 撑满整块，点哪块选哪档；
   高亮态同时写 .on（JS 兜底，旧内核没有 :has） */
.prio-pick{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
.prio-opt{position:relative;display:block;cursor:pointer;padding:9px 11px;
  border:1px solid var(--line);border-radius:10px;background:var(--panel);
  transition:border-color .15s,background .15s}
.prio-opt input{position:absolute;left:0;top:0;width:100%;height:100%;margin:0;
  opacity:0;cursor:pointer}
.prio-opt .prio-t{display:block;font-size:13.5px;font-weight:600;color:var(--ink);line-height:1.4}
.prio-opt em{display:block;font-style:normal;font-size:11.5px;line-height:1.5;
  color:var(--ink3);margin-top:2px}
.prio-opt:last-child .prio-t{color:var(--bad)}
.prio-opt:hover{border-color:var(--brand-flat)}
.prio-opt.on,.prio-opt:has(input:checked){border-color:var(--brand-flat);background:var(--brand-soft)}
.prio-opt:last-child.on,.prio-opt:last-child:has(input:checked){border-color:var(--bad);
  background:rgba(207,19,34,.08)}
.prio-opt.on em,.prio-opt:has(input:checked) em{color:var(--ink2)}

/* 工单详情：状态卡里的三档切换（当前档实心，其余可点） */
.prio-mini{display:flex;align-items:center;gap:5px;margin-top:9px;flex-wrap:wrap}
.prio-cap{font-size:11.5px;color:var(--ink3)}
.prio-mini form{display:inline;margin:0}
.prio-btn{display:inline-flex;align-items:center;height:23px;padding:0 9px;
  font:inherit;font-size:12px;line-height:1;border-radius:7px;
  border:1px solid var(--line);background:var(--panel);color:var(--ink2);
  transition:border-color .15s,color .15s,background .15s}
button.prio-btn{cursor:pointer}
button.prio-btn:hover{border-color:var(--brand-flat);color:var(--brand-flat)}
.prio-btn.p0.on{background:var(--gray-soft);border-color:var(--line);color:var(--ink);cursor:default}
.prio-btn.p1.on{background:#cf1322;border-color:#cf1322;color:#fff;cursor:default}
.prio-btn.p2.on{background:#8a0b17;border-color:#8a0b17;color:#fff;cursor:default}

/* 工单列表：一键加急 / 取消加急的小按钮 */
.btn.prio-flash{padding:0 8px;font-weight:600}
.btn.prio-flash.on{background:#cf1322;border-color:#cf1322;color:#fff}

@media (max-width:640px){
  .prio-pick{grid-template-columns:1fr}
}
/* 就地提交中的按钮：稍微压暗，防止连点 */
.btn.wait, .prio-btn.wait{opacity:.55;cursor:progress}

/* ================= 委外单多选合并打印 ================= */
/* 勾了几张就浮在底部，点一下合成一张纸；不勾的时候完全不占地方 */
.os-pickbar{position:fixed;left:50%;bottom:20px;transform:translateX(-50%);
  display:flex;align-items:center;gap:10px;z-index:60;
  padding:9px 14px;border-radius:14px;
  background:var(--panel);border:1px solid var(--line);
  box-shadow:0 10px 30px rgba(20,26,40,.18);font-size:13px;color:var(--ink)}
.os-pickbar[hidden]{display:none}
.os-pickbar b{font-weight:600;white-space:nowrap}
.os-picktip{font-size:11.5px;color:var(--ink3);max-width:280px;line-height:1.5}
.os-picktip.bad{color:var(--bad)}
@media (max-width:640px){
  .os-pickbar{left:12px;right:12px;bottom:12px;transform:none;flex-wrap:wrap}
  .os-picktip{max-width:none;flex:1 0 100%}
}

/* ================= 开委外单：多部件清单 ================= */
.os-add-row{display:grid;grid-template-columns:1fr 1fr auto;gap:10px;align-items:end}
.os-add-row .field{margin-bottom:12px}
.os-add-row .btn{height:34px;margin-bottom:12px;white-space:nowrap}
.os-list{margin:0 0 14px;border:1px solid var(--line);border-radius:10px;overflow:hidden}
.os-list[hidden]{display:none}
.os-list-hd{padding:7px 11px;background:var(--gray-soft);font-size:12.5px;
  font-weight:600;color:var(--ink2)}
.os-list-tb{width:100%;border-collapse:collapse;font-size:12.5px}
.os-list-tb th{text-align:left;font-weight:500;font-size:11.5px;color:var(--ink3);
  padding:5px 9px;border-bottom:1px solid var(--line);white-space:nowrap}
.os-list-tb td{padding:5px 9px;border-bottom:1px solid var(--line);color:var(--ink)}
.os-list-tb tr:last-child td{border-bottom:0}
.os-list-tb input{width:100%;height:28px;padding:0 7px;font:inherit;font-size:12.5px;
  border:1px solid var(--line);border-radius:7px;background:var(--panel);color:var(--ink)}
.os-list-tb .xs{font-size:11px;color:var(--ink3);margin-top:1px;line-height:1.4}
.os-list-tb .rowdel{border:0;background:transparent;color:var(--ink3);cursor:pointer;
  font-size:15px;line-height:1;padding:4px 6px}
.os-list-tb .rowdel:hover{color:var(--bad)}
.os-list-tip{padding:6px 11px;font-size:11.5px;color:var(--ink3);background:var(--gray-soft)}
@media (max-width:640px){
  .os-add-row{grid-template-columns:1fr 1fr}
  .os-add-row .btn{grid-column:1/-1;margin-bottom:12px}
}

/* ============ 日期选择增强（app.js 自绘日历） ============ */
.dp{position:relative;display:inline-block}
.dp input{cursor:pointer;padding-right:30px}
.dp input::-webkit-calendar-picker-indicator{display:none}
.dp.dp-empty input{color:transparent}
.dp .dp-ic{position:absolute;right:10px;top:50%;transform:translateY(-50%);color:var(--ink3);pointer-events:none}
.dp .dp-ph{position:absolute;left:11px;top:50%;transform:translateY(-50%);font-size:13px;color:var(--ink3);pointer-events:none;display:none;white-space:nowrap}
.dp.dp-empty .dp-ph{display:block}
.dp.dp-empty.dp-focus .dp-ph{display:none}
.dp-panel{position:fixed;z-index:9990;width:266px;padding:10px;background:var(--panel);border:1px solid var(--line);border-radius:10px;box-shadow:0 12px 32px rgba(15,20,30,.18);font-size:13px;color:var(--ink);user-select:none;-webkit-user-select:none}
.dp-panel[hidden]{display:none}
.dp-hd{display:flex;align-items:center;gap:2px;margin-bottom:6px}
.dp-title{flex:1;text-align:center;font-weight:600;letter-spacing:.5px}
.dp-nav{width:24px;height:24px;line-height:22px;text-align:center;border-radius:6px;cursor:pointer;color:var(--ink2);font-size:14px}
.dp-nav:hover{background:var(--gray-soft);color:var(--brand-flat,var(--brand))}
.dp-wk,.dp-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
.dp-wk span{text-align:center;font-size:11.5px;color:var(--ink3);padding:2px 0 4px}
.dp-d{text-align:center;height:30px;line-height:30px;border-radius:7px;cursor:pointer}
.dp-d:hover{background:var(--gray-soft)}
.dp-d.out{color:var(--ink3);opacity:.5}
.dp-d.today{color:var(--brand-flat,var(--brand));font-weight:600}
.dp-d.sel{background:var(--brand);background-image:var(--brand);color:var(--on-brand);font-weight:600}
.dp-d.sel:hover{background-image:var(--brand)}
.dp-ft{display:flex;justify-content:space-between;margin-top:6px;padding-top:7px;border-top:1px solid var(--line2)}
.dp-today,.dp-clear{padding:3px 10px;border-radius:6px;cursor:pointer;color:var(--brand-flat,var(--brand));font-size:12.5px}
.dp-today:hover,.dp-clear:hover{background:var(--gray-soft)}
.dp-clear{color:var(--ink3)}

/* ---------- Excel 导出：按钮内真实进度反馈（蓝条→绿勾） ---------- */
.btn.mex-on{position:relative;overflow:hidden;pointer-events:none;color:var(--ink)}
.btn .mex-fill{position:absolute;left:0;top:0;bottom:0;width:0;
  background:var(--brand-flat, var(--brand));opacity:.16;transition:width .18s ease-out}
.btn .mex-txt{position:relative;z-index:1;font-variant-numeric:tabular-nums;
  font-size:12.5px;color:var(--ink2)}
.btn.mex-done .mex-fill{background:var(--ok);opacity:.9}
.btn.mex-done .mex-txt{color:#fff;font-weight:600}
.btn.mex-done{border-color:var(--ok)}
.btn.mex-fail{border-color:var(--bad)}
.btn.mex-fail .mex-txt{color:var(--bad)}
