/* ============================================================================
   工程自动化管理系统 — 视觉设计系统 v2（商务简约 · 工程管理后台）
   ----------------------------------------------------------------------------
   仅视觉层升级：不改任何类名 / ID / DOM 结构 / JS 业务逻辑。
   · 品牌色：深邃工程蓝 #1E5AC8（hover / active 两档深化，聚焦环 --ring）
   · 中性色：冷调石板灰阶，背景 #F3F5F9，卡片纯白 + 细边框 + 双层柔和投影
   · 圆角体系：卡片 10 / 控件 8 / 标签胶囊；阴影三档：flat / raised / overlay
   · 字体层级：页面标题 20·700 / 弹窗 16·600 / 正文 14 / 表格 13 / 辅助 12
   · 移动端：卡片化列表、44px 触控目标、iPhone 安全区 env()、16px 输入防缩放
   · 全部 CSS 变量名保留（JS 注入样式引用 var(--*)），仅升级取值
   ============================================================================ */

/* ==================== 设计变量 ==================== */
:root{
  /* 品牌（2026-10-08 落地设计稿 A 方案「蓝图蓝 + 安全黄」） */
  --primary:#1E5AC8;
  --primary-d:#15419A;
  --primary-dd:#10347D;
  --primary-l:#E8F0FC;
  --primary-ll:#F4F8FE;
  --ring:rgba(30,90,200,.14);
  /* 强调（安全黄，与 GB 2894 警示色系同源） */
  --accent:#FFC53D;
  /* 主色渐变（借鉴 Ovation 参考稿：渐变只用在「选中态 / 主按钮 / 徽章」这类强调位，
     大面积仍保持纯色 —— 这是它显得克制、不花的原因） */
  --grad-primary:linear-gradient(135deg,#3B6FF0 0%,#1E5AC8 100%);
  /* 中性（冷调石板） */
  --bg:#F2F5FA;
  --card:#FFFFFF;
  --text:#1B2333;
  --sub:#5C6575;
  --faint:#99A1AF;
  --slate:#475064;
  --tertiary:#F4F6FA;
  --border:#ECF0F7;
  --border-d:#DCE2EC;
  --hover:#F4F6FA;
  /* 顶栏（#topbar）与侧栏品牌区（.side-head）**必须同高**，否则两条分隔线错位（2026-09-30 用户报：差 2px）。
     以后要调顶栏高度，只改这一个变量即可，两处自动跟随。 */
  --topbar-h:58px;
  /* 语义（A 方案：成功 / 待办 / 警示 各占其位，不与主色抢色位） */
  --green:#12A150;
  --green-l:#E7F7EE;
  --orange:#E08700;
  --orange-l:#FFF5E6;
  --red:#D92D20;
  --red-l:#FDECEA;
  --blue:#1E5AC8;
  --blue-l:#E8F0FC;
  /* 阴影三档（设计稿口径：带负 spread、大半径、低透明度，色相统一冷蓝，让卡片「浮」起来而不是靠描边） */
  --shadow-s:0 4px 14px -2px rgba(23,43,99,.08);
  --shadow:0 10px 26px -4px rgba(23,43,99,.11);
  --shadow-lg:0 14px 34px -6px rgba(23,43,99,.20);
  /* 圆角三档 + 胶囊（设计稿：卡片 18 / 控件 12 / 大卡与弹窗 20） */
  --radius:18px;      /* 卡片 / 分区卡 */
  --radius-s:12px;    /* 控件：按钮 / 输入框 / 下拉 */
  --radius-lg:20px;   /* 弹窗 / 大卡 / 移动卡片 */
  /* 间距六档（8pt 栅格，2026-10-08 收敛：线上原 9 种手感值 12~22） */
  --sp-1:4px;   --sp-2:8px;   --sp-3:12px;
  --sp-4:16px;  --sp-5:24px;  --sp-6:32px;
  --font:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei","Noto Sans SC",sans-serif;
}

*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{height:100%}
body{font-family:var(--font);background:linear-gradient(135deg,#EAF2FC 0%,#F3F6FB 100%);color:var(--text);font-size:14px;line-height:1.6;
  overflow:hidden;overscroll-behavior:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility}
button{font-family:var(--font);cursor:pointer;border:none;background:none;color:inherit}
input,select,textarea{font-family:var(--font);font-size:14px;color:var(--text);outline:none}
a{color:var(--primary);text-decoration:none}
table{border-collapse:collapse;width:100%}
::selection{background:rgba(30,90,200,.16)}
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-thumb{background:#C6CCD6;border-radius:10px}
::-webkit-scrollbar-thumb:hover{background:#A6AEBC}
::-webkit-scrollbar-track{background:transparent}
.num{font-variant-numeric:tabular-nums}
[hidden]{display:none!important}
/* 键盘可达性：仅键盘聚焦时显示焦点环 */
.btn:focus-visible,.nav-item:focus-visible,.seg-tab:focus-visible,.at-tab:focus-visible,
.text-btn:focus-visible,.modal-close:focus-visible{outline:2px solid rgba(30,90,200,.55);outline-offset:1px}

/* ==================== 登录页 ==================== */
/* ⚠ 登录页顶端必须是**纯白**（2026-10-10 用户口径）：手机状态栏恒为纯白，页面顶端若不是白就会有一条色差。
   原来起点是 #F8FAFE（近白偏蓝），在纯白状态栏下能看出分界，故起点改 #FFFFFF，往下再过渡到原色。 */
/* ★ 2026-10-11：登录层必须是**可滚动容器**。
   全站是「应用壳」：`body{overflow:hidden}`，所有滚动都交给内部容器（#content 等），
   而登录层是 `position:fixed;inset:0` 的独立层、以前自己没有 overflow
   ⇒ 表单比视口高时，底部（「单位类型」/「注册并登录」按钮）被直接裁掉，整页也滑不动
   （用户实测：「手机浏览器上注册页显示不全，也不能上下滑动」）。
   同时把「垂直居中」从 .auth-panel 的 align-items:center 改为卡片的 margin:auto ——
   align-items:center 在内容超高时会把顶部推到不可达区（滚动也拉不回来），margin:auto 超高时自动归零。 */
#auth-view{position:fixed;inset:0;display:flex;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;background:linear-gradient(180deg,#FFFFFF 0%,#EFF3FA 100%)}
.auth-brand{flex:1.15;position:relative;overflow:hidden;display:flex;flex-direction:column;justify-content:space-between;
  padding:52px 56px;color:var(--text);background:#FFFFFF;border-right:1px solid var(--border)}
/* 克制的品牌底纹：细点阵 + 一角微光（不花哨） */
.auth-brand .grid-lines{display:block;position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(620px 420px at 88% 12%,rgba(30,90,200,.07),transparent 62%),
    radial-gradient(rgba(30,90,200,.09) 1px,transparent 1.3px);
  background-size:auto,24px 24px}
.auth-brand>*{position:relative;z-index:1}
.auth-brand>.grid-lines{position:absolute;z-index:0}
.brand-logo{display:flex;align-items:center;gap:12px;font-weight:700;font-size:18px;letter-spacing:.5px;color:var(--text)}
/* ★ 2026-10-20：登录页 logo 改用应用图标（assets/icon-192-v2.png，与侧栏/favicon 同一个文件）。
   ⇒ 底色改透明（图标自带渐变蓝）+ overflow:hidden 收圆角，样式与 `.side-head .logo-mark` 对齐。 */
.brand-logo .logo-mark{width:40px;height:40px;border-radius:12px;background:transparent;overflow:hidden;
  display:flex;align-items:center;justify-content:center;box-shadow:0 6px 16px rgba(30,90,200,.28)}
.auth-hero h1{color:var(--text);font-size:34px;font-weight:700;line-height:1.35;letter-spacing:1px}
.auth-hero p{margin-top:16px;color:var(--sub);font-size:14.5px;max-width:430px;line-height:1.9}
.auth-feats{display:flex;gap:24px;flex-wrap:wrap}
.auth-feats .feat{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--sub)}
.auth-feats .feat .dot{width:7px;height:7px;border-radius:50%;background:var(--primary);box-shadow:0 0 0 4px var(--primary-l)}
.auth-panel{flex:1;display:flex;justify-content:center;background:transparent;padding:24px}
.auth-card{width:100%;max-width:384px;margin:auto}
.auth-card h2{font-size:24px;font-weight:700;color:var(--text);letter-spacing:.5px}
.auth-card .sub{color:var(--sub);font-size:13px;margin:8px 0 24px}
.auth-tabs{display:flex;gap:24px;border-bottom:1px solid var(--border);margin-bottom:24px}
.auth-tabs button{padding:8px 2px;font-size:15px;font-weight:500;color:var(--sub);border-bottom:2px solid transparent;margin-bottom:-1px;transition:.2s}
.auth-tabs button.active{color:var(--primary);border-bottom-color:var(--primary);font-weight:600}
.field{margin-bottom:var(--sp-4)}
.field label{display:block;font-size:12.5px;color:var(--slate);font-weight:500;margin-bottom:var(--sp-2)}
.field .ipt{position:relative}
.field .ipt svg{position:absolute;left:11px;top:50%;transform:translateY(-50%);color:var(--faint)}
.field input{width:100%;height:42px;border:1px solid var(--border-d);border-radius:var(--radius-s);padding:0 12px;background:#fff;transition:border-color .18s,box-shadow .18s}
.field .ipt input{padding-left:38px}
/* ⚠ 「单位类型」用的是 <select>，**不吃上面那条 input 的 padding-left** ⇒ 绝对定位的楼宇图标（left:11px）
   正好压在「施工单位（总承包）」前两个字上（2026-10-10 用户截图「登录页有个图标和字重叠了」就是这个）。
   这里把 select 也顶开 38px，并给足高度（手机端点按目标 ≥40px）。 */
.field .ipt select{padding-left:38px;height:42px;cursor:pointer}
.field input:focus{border-color:var(--primary);background:#fff;box-shadow:0 0 0 3px var(--ring)}
.field input:hover{border-color:#B9C1CE}
#auth-code{padding-right:104px;letter-spacing:2px}
.code-btn{position:absolute;right:7px;top:50%;transform:translateY(-50%);color:var(--primary);font-size:12.5px;font-weight:600;
  background:none;padding:4px 8px;border-radius:6px;white-space:nowrap;cursor:pointer;transition:.2s}
.code-btn:hover:not(:disabled){background:var(--primary-l)}
.code-btn:disabled{color:var(--faint);cursor:not-allowed}
/* 密码框小眼睛 */
.field .ipt .pwd-eye-btn{position:absolute;right:6px;top:50%;transform:translateY(-50%);width:32px;height:32px;display:flex;align-items:center;justify-content:center;border:0;background:none;color:var(--faint);cursor:pointer;border-radius:6px;padding:0;z-index:2;transition:.2s}
.field .ipt .pwd-eye-btn:hover{background:var(--hover);color:var(--slate)}
.field .ipt .pwd-eye-btn svg{position:static;left:auto;top:auto;transform:none;width:18px;height:18px;flex:0 0 auto}
#auth-pwd{padding:0 40px 0 38px !important}
.auth-row{display:flex;align-items:center;justify-content:space-between;margin:4px 0 16px;font-size:13px}
.remember{display:flex;align-items:center;gap:7px;color:var(--slate);cursor:pointer;user-select:none}
.remember input{width:15px;height:15px;accent-color:var(--primary);cursor:pointer}
/* 服务条款 / 隐私政策勾选行（2026-10-16） */
.auth-terms{display:flex;align-items:flex-start;gap:7px;font-size:12.5px;color:var(--slate);line-height:1.65;margin:-4px 0 10px;cursor:pointer;user-select:none}
.auth-terms input{margin:2.5px 0 0;flex:0 0 auto;width:15px;height:15px;accent-color:var(--primary);cursor:pointer}
.auth-terms a{color:var(--primary);text-decoration:none}
.auth-terms a:hover{text-decoration:underline}
.link-btn{color:var(--primary);font-size:13px;background:none;transition:.2s}
.link-btn:hover{opacity:.8}
.auth-err{color:var(--red);font-size:12.5px;min-height:16px;margin-bottom:8px}
.btn-block{width:100%;height:44px;border-radius:var(--radius-s);background:var(--primary);color:#fff;font-size:15px;font-weight:600;
  transition:.2s;display:flex;align-items:center;justify-content:center;gap:8px;box-shadow:0 4px 12px rgba(30,90,200,.24);letter-spacing:2px}
.btn-block:hover{background:var(--primary-d);box-shadow:0 6px 16px rgba(30,90,200,.30)}
.btn-block:active{background:var(--primary-dd);transform:scale(.98)}
.btn-block:disabled{background:#A9BDF0;box-shadow:none;cursor:not-allowed}
.auth-note{margin-top:24px;font-size:12px;color:var(--faint);line-height:1.8;text-align:center}

/* ==================== 主框架 ==================== */
#app-view{display:flex;height:100vh}
/* 侧边栏：白色 + 细分隔线，选中项浅蓝胶囊 + 左侧指示条 */
#sidebar{width:232px;background:#FFFFFF;color:var(--text);display:flex;flex-direction:column;flex-shrink:0;
  transition:transform .25s ease;z-index:60;border-right:1px solid var(--border)}
.side-head{height:var(--topbar-h);box-sizing:border-box;padding:0 18px;display:flex;align-items:center;gap:11px;border-bottom:1px solid var(--border);flex-shrink:0}
.side-head .logo-mark{width:34px;height:34px;border-radius:10px;display:flex;align-items:center;justify-content:center;flex-shrink:0;overflow:hidden;
  box-shadow:0 2px 6px rgba(27,35,51,.10)}
.side-head .t1{color:var(--text);font-weight:700;font-size:14.5px;line-height:1.3;letter-spacing:.5px}
.side-head .t2{font-size:11px;color:var(--faint)}
.side-nav{flex:1;overflow-y:auto;overflow-x:hidden;padding:12px 12px 22px;-webkit-overflow-scrolling:touch;scrollbar-width:thin;min-height:0}
.side-nav::-webkit-scrollbar{width:6px}
.side-nav::-webkit-scrollbar-thumb{background:#DDE2EA;border-radius:6px}
.nav-group{font-size:11px;color:var(--faint);padding:15px 12px 7px;letter-spacing:1.5px;font-weight:600}
/* 部门分组头：按部门划分后，分组名是「安全部/工程部/劳资部…」，加一道分隔线让部门之间界限清楚 */
.side-nav .nav-group:not(:first-child){border-top:1px solid var(--border);margin-top:6px}
.nav-item{display:flex;align-items:center;gap:10px;padding:9px 12px 9px 14px;border-radius:10px;font-size:14px;color:#3E4657;
  margin-bottom:2px;cursor:pointer;transition:background .16s,color .16s;user-select:none;width:100%;text-align:left;font-weight:400;position:relative}
.nav-item svg{flex-shrink:0;opacity:1}
/* 选中项左侧指示条 */
.nav-item::before{content:'';position:absolute;left:4px;top:50%;width:3px;height:18px;border-radius:4px;background:var(--primary);
  transform:translateY(-50%) scaleY(0);transition:transform .18s ease}
.nav-item:hover{background:var(--hover);color:var(--text)}
.nav-item.active{background:var(--grad-primary);color:#fff;font-weight:600;box-shadow:0 4px 12px -2px rgba(30,90,200,.32)}
.nav-item.active svg{color:#fff}
/* 选中项改为实底后，左侧指示条与底色同色已不可见，显式关掉避免深色模式下露出来 */
.nav-item.active::before{opacity:0}
.nav-item.active::before{transform:translateY(-50%) scaleY(1)}
.side-foot{padding:12px 14px;border-top:1px solid var(--border);font-size:11.5px;color:var(--faint);line-height:1.7}
#main{flex:1;display:flex;flex-direction:column;min-width:0}
#topbar{height:var(--topbar-h);background:var(--card);border-bottom:1px solid var(--border);display:flex;align-items:center;gap:12px;
  padding:0 22px;flex-shrink:0;z-index:20}
/* 汉堡按钮只在手机端出现（其余断点 display:none），故尺寸直接按触摸标准给 44 */
.hamburger{display:none;width:44px;height:44px;border-radius:var(--radius-s);align-items:center;justify-content:center;color:var(--slate);transition:.2s}
.hamburger:hover{background:var(--hover)}
.proj-pick{display:flex;align-items:center;gap:9px;min-width:0}
.proj-pick .lbl{font-size:12.5px;color:var(--sub);flex-shrink:0}
.proj-select{height:36px;border:1px solid var(--border-d);border-radius:10px;padding:0 10px;background:#fff;min-width:200px;max-width:340px;font-weight:500;transition:.2s;cursor:pointer}
.proj-select:hover{border-color:var(--primary)}
.proj-select:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--ring)}
/* 顶栏「单位徽标 / 身份切换」样式已移除（2026-09-29 用户要求）：顶栏只保留「我的身份」按钮，
   点它即可切换所属单位并查看单位·部门·岗位。 */
.topbar-sp{flex:1}
/* 顶栏「我的身份」在身份缺失时的脉冲提示（2026-09-30）：没单位/没岗位的人一眼能看到要去定位 */
.btn.warn-pulse{border-color:var(--orange);color:var(--orange);background:var(--orange-l);font-weight:600;
  animation:idpulse 1.7s ease-in-out infinite}
@keyframes idpulse{50%{box-shadow:0 0 0 5px rgba(255,125,0,.16)}}
.sync-state{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--sub);background:var(--tertiary);border:1px solid var(--border);padding:6px 12px;border-radius:999px}
.sync-dot{width:7px;height:7px;border-radius:50%;background:var(--green);box-shadow:0 0 0 3px rgba(0,180,42,.14)}
.sync-dot.busy{background:var(--orange);box-shadow:0 0 0 3px rgba(255,125,0,.16);animation:pulse 1.1s infinite}
@keyframes pulse{50%{opacity:.4}}
.user-chip{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--slate)}
.avatar{width:32px;height:32px;border-radius:50%;background:var(--primary);color:#fff;display:flex;
  align-items:center;justify-content:center;font-size:13px;font-weight:700;box-shadow:0 2px 6px rgba(30,90,200,.28)}
.side-mask{display:none;position:fixed;inset:0;background:rgba(27,35,51,.42);z-index:55}
#content{flex:1;overflow-y:auto;overflow-x:hidden;padding:22px 24px;-webkit-overflow-scrolling:touch}
.page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:12px;margin-bottom:var(--sp-5);flex-wrap:wrap}
.page-head h2{font-size:20px;font-weight:700;display:flex;align-items:center;gap:9px;letter-spacing:.3px}
.page-head .desc{font-size:13px;color:var(--sub);margin-top:3px}
.page-head .desc:empty{display:none}
.page-head:has(.desc:empty){align-items:center}
.page-actions{display:flex;gap:9px;flex-wrap:wrap;align-items:center}
/* 页头内嵌分段页签（工伤保险）：页签紧贴标题右侧，省掉标题下的一整行高度（2026-09-30） */
.page-head-tabs{align-items:center}
.page-head-tabs .ph-left{display:flex;align-items:center;gap:16px;flex-wrap:wrap;min-width:0}
.page-head-tabs .ph-left h2{white-space:nowrap;margin:0}

/* ==================== 通用组件 ==================== */
.btn{display:inline-flex;align-items:center;gap:6px;height:36px;padding:0 16px;border-radius:var(--radius-s);font-size:13.5px;font-weight:500;
  background:#fff;border:1px solid var(--border-d);color:#3E4657;transition:all .16s ease;white-space:nowrap;justify-content:center}
.btn:hover{border-color:var(--primary);color:var(--primary);background:var(--primary-ll)}
.btn:active{transform:scale(.98)}
.btn.primary{background:var(--grad-primary);border-color:var(--primary);color:#fff;font-weight:600;box-shadow:0 4px 12px -2px rgba(30,90,200,.35)}
.btn.primary:hover{background:var(--primary-d);border-color:var(--primary-d);color:#fff;box-shadow:0 4px 12px rgba(30,90,200,.30);transform:translateY(-1px)}
.btn.primary:active{background:var(--primary-dd);transform:translateY(0);box-shadow:0 1px 3px rgba(30,90,200,.25)}
.btn.danger{color:var(--red);border-color:#F6C8CB}
.btn.danger:hover{background:var(--red-l);border-color:var(--red);color:var(--red)}
.btn.success{color:var(--green);border-color:#B7E7C6}
.btn.success:hover{background:var(--green-l);border-color:var(--green);color:var(--green)}
.btn.sm{height:30px;padding:0 12px;font-size:12.5px;border-radius:8px}
/* 大按钮（2026-10-08 补）：空态主操作 / 吸底操作条主按钮；只改高度·内距·字号·字重，颜色不变 */
.btn.lg{height:44px;padding:0 22px;font-size:14.5px;font-weight:600}
/* 幽灵按钮（2026-10-08 补）：表格行内「查看」、卡头「查看全部」这类次级动作 */
.btn.ghost{background:transparent;border-color:transparent;color:var(--primary)}
.btn.ghost:hover{background:var(--primary-l);border-color:transparent;color:var(--primary)}
.btn.ghost:active{background:#DCE7FB;transform:none}
.btn.icon-btn{padding:0 9px}
/* 禁用态：pointer-events 一次性关掉 hover/active，避免主按钮还在上浮或加深 */
.btn:disabled,.btn:disabled:hover,.btn:disabled:active{opacity:.55;cursor:not-allowed;box-shadow:none;transform:none;pointer-events:none}
select.btn{appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%2386909c' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 12px center;padding-right:30px;cursor:pointer}
select.btn:hover{border-color:var(--primary);color:var(--primary);background-color:var(--primary-ll);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%231E5AC8' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E")}
select.btn option{padding:8px 12px;font-size:13.5px;color:#1B2333}
select.btn option:disabled{color:#bbb;background:#F4F6FA}
.card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);transition:box-shadow .2s ease}
.card:hover{box-shadow:0 2px 4px rgba(27,35,51,.05),0 8px 24px rgba(27,35,51,.07)}
.toolbar{display:flex;gap:10px;align-items:center;margin-bottom:var(--sp-4);flex-wrap:wrap}
.toolbar .search-box{position:relative;flex:1;min-width:180px;max-width:320px}
.toolbar .search-box > svg{position:absolute;left:11px;top:50%;transform:translateY(-50%);color:var(--faint);pointer-events:none}
.toolbar input[type=search],.toolbar input[type=text],.toolbar select{height:36px;border:1px solid var(--border-d);border-radius:10px;padding:0 12px;background:#fff;font-size:13.5px;color:var(--text);outline:none;transition:border-color .16s,box-shadow .16s,background-color .16s}
/* 下拉框统一自绘箭头（select.btn 已自带样式，排除在外）；padding-right 用 !important 压过 JS 内联 padding，防止箭头压住文字 */
.toolbar select:not(.btn){-webkit-appearance:none;appearance:none;cursor:pointer;padding-right:26px!important;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%2386909c' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 11px center}
/* 工具栏/筛选条里的日期框：最小宽度兜底，防止占位文字与日历图标挤压 */
.toolbar input[type="date"],.filter-bar input[type="date"]{min-width:148px;flex:0 0 auto}
.filter-bar select{padding-right:26px!important}
.toolbar .search-box input{width:100%;padding-left:36px;-webkit-appearance:none;appearance:none}
.toolbar .search-box input::-webkit-search-decoration,.toolbar .search-box input::-webkit-search-cancel-button{display:none}
/* 弹窗内搜索框：复用工具栏圆角放大镜样式（.search-box 默认只在 .toolbar 下生效） */
.modal .search-box{position:relative;display:block;max-width:none}
.modal .search-box > svg{position:absolute;left:11px;top:50%;transform:translateY(-50%);color:var(--faint);pointer-events:none;width:16px;height:16px}
.modal .search-box input{width:100%;height:38px;border:1px solid var(--border-d);border-radius:10px;padding:0 12px 0 36px;background:#fff;font-size:13px;-webkit-appearance:none;appearance:none;transition:.2s}
.modal .search-box input:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--ring);outline:none}
.modal .search-box input::-webkit-search-decoration,.modal .search-box input::-webkit-search-cancel-button{display:none}

/* ===================== 全站搜索框通用「一键清空」 ===================== */
.search-box.has-val input{padding-right:34px}
.search-box .sb-clear{position:absolute;right:9px;top:50%;transform:translateY(-50%);width:18px;height:18px;border-radius:50%;
  display:none;align-items:center;justify-content:center;background:#C6CCD6;color:#fff;cursor:pointer;padding:0;border:none;transition:.15s;z-index:1}
.search-box .sb-clear svg{position:static;transform:none;color:#fff;width:10px;height:10px;stroke-width:3}
.search-box.has-val .sb-clear{display:flex}
.search-box .sb-clear:hover{background:var(--sub)}
.toolbar input:focus,.toolbar select:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--ring);background-color:#fff}
.toolbar input:hover,.toolbar select:hover{border-color:#C2C9D4;background-color:#FBFCFE}
.toolbar select option{background:#fff;color:var(--text)}
.toolbar .sp{flex:1}

/* ===================== 统一筛选条 ===================== */
.filter-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:12px 16px;margin-bottom:16px;
  background:var(--card);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow)}
.filter-bar select,
.filter-bar input[type=search],
.filter-bar input[type=text]{height:36px;border:1px solid var(--border-d);border-radius:10px;padding:0 12px;background:#fff;
  font-size:13.5px;font-family:inherit;color:var(--text);outline:none;transition:border-color .16s,box-shadow .16s,background-color .16s}
.filter-bar select{-webkit-appearance:none;appearance:none;cursor:pointer;padding-right:32px;min-width:132px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%2386909c' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 11px center}
.filter-bar select:hover,
.filter-bar input[type=search]:hover,
.filter-bar input[type=text]:hover{border-color:#C2C9D4;background-color:#FBFCFE}
.filter-bar select:focus,
.filter-bar input[type=search]:focus,
.filter-bar input[type=text]:focus{border-color:var(--primary);background-color:#fff;box-shadow:0 0 0 3px var(--ring)}
.filter-bar select option{background:#fff;color:var(--text)}
/* 搜索框：左侧放大镜 + 右侧一键清空 */
.filter-bar .fb-search{position:relative;flex:1;min-width:230px}
.filter-bar .fb-search .fb-ic{position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--faint);pointer-events:none;display:flex;align-items:center}
.filter-bar .fb-search input{width:100%;padding-left:37px;padding-right:34px}
.filter-bar .fb-search input::-webkit-search-decoration,
.filter-bar .fb-search input::-webkit-search-cancel-button{-webkit-appearance:none;display:none}
.filter-bar .fb-search .fb-clear{position:absolute;right:9px;top:50%;transform:translateY(-50%);width:18px;height:18px;border-radius:50%;
  display:none;align-items:center;justify-content:center;background:#C6CCD6;color:#fff;cursor:pointer;padding:0;border:none;transition:.15s}
.filter-bar .fb-search .fb-clear svg{width:10px;height:10px;stroke-width:3}
.filter-bar .fb-search.has-val .fb-clear{display:flex}
.filter-bar .fb-search .fb-clear:hover{background:var(--sub)}
/* 右侧统计胶囊 + 重置 */
.filter-bar .fb-tail{margin-left:auto;display:flex;align-items:center;gap:8px;white-space:nowrap}
.filter-bar .fb-cnt{font-size:12.5px;color:var(--sub);background:var(--primary-ll);border:1px solid #DCE7FB;
  padding:5px 12px;border-radius:999px;font-variant-numeric:tabular-nums}
.filter-bar .fb-cnt b{color:var(--primary);font-weight:700;font-size:13px}
.filter-bar .fb-reset{display:none;align-items:center;gap:4px;font-size:12.5px;color:var(--sub);background:transparent;
  border:1px solid transparent;padding:5px 10px;border-radius:999px;cursor:pointer;transition:.15s}
.filter-bar .fb-reset svg{width:13px;height:13px}
.filter-bar .fb-reset.show{display:inline-flex}
.filter-bar .fb-reset:hover{background:var(--primary-l);border-color:#D2E0FA;color:var(--primary)}
@media (max-width:768px){
  .filter-bar{padding:8px;gap:8px}
  .filter-bar select{flex:1;min-width:0}
  .filter-bar .fb-search{flex:1 1 100%;min-width:0;order:3}
  .filter-bar .fb-tail{order:2;margin-left:auto}
}
.table-wrap{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);overflow-x:auto;overflow-y:auto;max-height:calc(100vh - 330px);box-shadow:var(--shadow);scrollbar-gutter:stable}
/* ===== 安全管理台账：表格区 flex 自适应填满视口剩余高度 ===== */
section[data-page="safety_inspection"]{display:flex;flex-direction:column;height:calc(100vh - 58px - 44px);min-height:0}
section[data-page="safety_inspection"]>div:not(#si-tab-content){flex-shrink:0}
#si-tab-content{flex:1 1 auto;min-height:0;display:flex;flex-direction:column}
#si-tab-content .toolbar{flex:0 0 auto}
#si-tab-content .table-wrap{flex:1 1 auto;min-height:160px;max-height:none}
#si-tab-content>div:last-child{flex:0 0 auto}
.data-table{font-size:13px;min-width:720px}
.data-table th{background:#F8FAFC;color:#7A8494;font-weight:600;font-size:12px;text-align:center;padding:12px;
  border-bottom:1px solid var(--border);white-space:nowrap;position:sticky;top:0;z-index:2;user-select:none;letter-spacing:.5px}
.data-table th.sortable{cursor:pointer}
.data-table th.sortable:hover{color:var(--primary)}
.data-table td{padding:12px;border-bottom:1px solid var(--border);vertical-align:middle;white-space:nowrap;font-variant-numeric:tabular-nums;text-align:center}
.data-table tbody tr{transition:background .12s ease}
.data-table tbody tr:hover{background:#F6F9FF}
.data-table tbody tr:last-child td{border-bottom:none}
.data-table tbody tr[data-edit-row]{cursor:pointer}
.data-table tbody tr[data-edit-row]:active{background:#E4EDFD}
.data-table .col-idx{color:var(--faint);width:48px}
.data-table .row-actions{display:flex;gap:6px;justify-content:center}
/* 表格操作列：链接间距与字重 */
.data-table td a+a{margin-left:12px}
.data-table td a{font-weight:500}
.text-btn{font-size:12.5px;padding:3px 8px;border-radius:6px;color:var(--primary);transition:.2s}
.text-btn:hover{background:var(--primary-l)}
.text-btn.red{color:var(--red)}
.text-btn.red:hover{background:var(--red-l)}
.badge{display:inline-flex;align-items:center;gap:4px;padding:2px 10px;border-radius:999px;font-size:12px;font-weight:500;line-height:1.7}
.badge.green{background:var(--green-l);color:#009A22}
.badge.gray{background:#F1F3F6;color:#5C6575}
.badge.orange{background:var(--orange-l);color:#D96A00}
.badge.red{background:var(--red-l);color:#D93636}
.badge.blue{background:var(--blue-l);color:var(--primary)}
.empty{padding:64px 20px;text-align:center;color:var(--faint)}
.empty svg{margin-bottom:10px}
.empty .et{font-size:14.5px;margin-bottom:4px;color:var(--sub);font-weight:600}
.empty .es{font-size:12.5px}

/* 统计卡 */
.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:var(--sp-4);margin-bottom:var(--sp-5)}
.stat-card{background:var(--card);border:none;border-radius:var(--radius);padding:24px;box-shadow:var(--shadow);
  position:relative;overflow:hidden;transition:transform .16s ease,box-shadow .16s ease}
.stat-card:hover{transform:translateY(-3px);box-shadow:0 14px 34px -6px rgba(23,43,99,.18)}
.stat-card .ic{position:absolute;right:16px;top:16px;width:40px;height:40px;border-radius:var(--radius-s);display:flex;align-items:center;justify-content:center}
.stat-card .lab{font-size:12.5px;color:var(--sub)}
.stat-card .val{font-size:27px;font-weight:700;margin-top:6px;letter-spacing:.5px;font-variant-numeric:tabular-nums}
.stat-card .unit{font-size:12px;color:var(--faint);font-weight:400;margin-left:3px}
/* 超龄判定标准小标签（2026-10-16 用户口径：移至「N 人」同一行 + 右对齐贴卡片右缘） */
.stat-card .age-tag{display:inline-flex;align-items:center;font-size:11.5px;font-weight:500;color:var(--blue);
  background:var(--primary-l);border-radius:var(--radius-s);padding:2px var(--sp-2);margin-left:auto;white-space:nowrap}
.stat-card .sub2{font-size:12px;color:var(--faint);margin-top:4px}
/* 2026-10-08 视觉降噪：原来「一张卡一个色」（蓝 / 绿 / 橙 / 红各自一个色块）⇒ 四个色块在首屏互抢注意力，
   界面因此显得花、显得「后台味」。改成「默认主色，只有真异常才红」—— 参考稿的图标也是同一色系，
   彩色只留给真正需要警示的那一个。 */
.ic.blue,.ic.green,.ic.orange{background:var(--primary-l);color:var(--blue)}
.ic.red{background:var(--red-l);color:var(--red)}

/* 表单弹窗 */
.modal-mask{position:fixed;inset:0;background:rgba(27,35,51,.46);z-index:1000;display:flex;align-items:center;justify-content:center;padding:18px;
  animation:fadein .18s ease}
@keyframes fadein{from{opacity:0}to{opacity:1}}
.modal{background:#fff;border-radius:16px;width:520px;max-width:100%;max-height:92vh;display:flex;flex-direction:column;
  box-shadow:var(--shadow-lg);animation:popin .2s ease;overflow:hidden}
.modal.wide{width:780px}
@keyframes popin{from{transform:translateY(10px) scale(.98);opacity:.6}to{transform:none;opacity:1}}
.modal-head{padding:20px 24px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;flex-shrink:0;background:#FAFBFD}
.modal-head h3{font-size:16px;font-weight:600;color:var(--text);letter-spacing:.2px}
.modal-close{width:30px;height:30px;border-radius:10px;color:var(--faint);display:flex;align-items:center;justify-content:center;transition:.15s}
.modal-close:hover{background:var(--hover);color:var(--text)}
.modal-body{padding:24px;overflow-y:auto;background:#fff}
.modal-foot{padding:20px 24px;border-top:1px solid var(--border);display:flex;justify-content:flex-end;gap:8px;flex-shrink:0;background:#FAFBFD}
.modal-foot .btn:first-child{margin-right:auto}
/* 表单布局 — 12列网格，字段宽度有层次（2026-10-08：行距 14→16、列距 12→20，行距与列距分开取） */
.form-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:var(--sp-4) 20px}
.form-grid .f-item{grid-column:span 6}
.form-grid .f-item.full{grid-column:span 12}
.form-grid .f-item.wide{grid-column:span 8}
.form-grid .f-item.narrow{grid-column:span 4}
.f-item label{display:block;font-size:12.5px;color:var(--slate);font-weight:500;margin-bottom:var(--sp-2)}
.f-item label .req{color:var(--red);margin-right:2px}
.f-item input,.f-item select,.f-item textarea{width:100%;border:1px solid var(--border-d);border-radius:10px;padding:10px 12px;background:#fff;transition:.15s;font-size:13.5px}
.f-item textarea{resize:vertical;min-height:68px}
.f-item input:focus,.f-item select:focus,.f-item textarea:focus{border-color:var(--primary);background:#fff;box-shadow:0 0 0 3px var(--ring);outline:none}
.f-item input:hover,.f-item select:hover,.f-item textarea:hover{border-color:#B9C1CE}
.f-item .hint{font-size:11.5px;color:var(--faint);margin-top:4px;line-height:1.5}

/* ===== 输入控件的禁用 / 只读态（2026-10-08 补）=====
   线上有 168 处 disabled、8 处 readonly，此前没有任何样式：
   禁用的 select 在 Windows 上只有系统灰底、文字仍是黑色，与可编辑项分不开。 */
.f-item input:disabled,.f-item select:disabled,.f-item textarea:disabled,
.form-horizontal .f-item input:disabled,.form-horizontal .f-item select:disabled,.form-horizontal .f-item textarea:disabled,
.toolbar input:disabled,.toolbar select:disabled,
.filter-bar input:disabled,.filter-bar select:disabled,
.proj-select:disabled,.modal .search-box input:disabled{
  background:var(--tertiary);border-color:var(--border);color:var(--faint);cursor:not-allowed;box-shadow:none}
.f-item input:disabled:hover,.f-item select:disabled:hover,.f-item textarea:disabled:hover,
.form-horizontal .f-item input:disabled:hover,.form-horizontal .f-item select:disabled:hover,.form-horizontal .f-item textarea:disabled:hover,
.toolbar input:disabled:hover,.toolbar select:disabled:hover{
  background:var(--tertiary);border-color:var(--border);box-shadow:none}
.f-item input[readonly],.form-horizontal .f-item input[readonly],.form-horizontal .f-item textarea[readonly]{
  background:#F8FAFC;border-color:var(--border)}
/* 通用弹窗：左标签右输入 */
.form-horizontal .f-item{display:flex;align-items:center;grid-column:span 6;min-width:0}
.form-horizontal .f-item.full{grid-column:span 12}
.form-horizontal .f-item label{display:block;width:124px;min-width:124px;text-align:left;font-size:13px;color:var(--slate);font-weight:500;margin-bottom:0;padding-right:8px;white-space:normal;overflow:visible;line-height:1.35}
.form-horizontal .f-item.col-right label{width:92px;min-width:92px}
/* 往来单位「编辑单位信息」弹窗（2026-10-20）：右列标签加宽到 118px ——
   「基本存款账户编号 / 许可证有效期至 / 委托代理人电话」在 92px 下会折成两行。 */
.form-horizontal.company-dialog .f-item.col-right label{width:118px;min-width:118px}
.form-horizontal.company-dialog .f-item.col-left label{width:118px;min-width:118px}
/* ★ 2026-10-20（第 3 轮）用户口径：「单位名称」也改半框、单位类型单独占右半格
   ⇒ 原先把类型内联进名称那一行的 `.cp-type-inline` 样式已整体删除（DOM 也同步删了，别再加回来）。 */
/* ★ 2026-10-20（第 2 轮）用户反馈「输入框没有垂直对齐」：整窗标签统一 118px。
   病根：`.f-item.full` 走默认 124px，`.col-left/.col-right` 走 118px ⇒ 同一列内输入框左边缘差 6px
   （营业期限 / 注册地址 / 经营范围 比上面几行靠左 6px，看起来就是一条歪线）。 */
.form-horizontal.company-dialog .f-item label{width:118px;min-width:118px}
.form-horizontal.company-dialog .hint-full{padding-left:126px}
/* ★ 2026-10-20：「营业期限」= 起日 至 止日（可勾长期/永久）—— 与同排输入框同高，日期框不铺满整行 */
.form-horizontal.company-dialog .cp-term-inline{display:flex;align-items:center;gap:8px;flex:1;min-width:0}
.form-horizontal.company-dialog .cp-term-inline>input[type="date"]{width:168px;flex:none}
.form-horizontal.company-dialog .cp-term-inline>input[type="date"]:disabled{background:#F3F5F9;color:var(--faint)}
.form-horizontal.company-dialog .cp-term-inline .cp-term-sep{color:var(--sub);font-size:13px;flex:none}
.form-horizontal.company-dialog .cp-term-inline .cp-term-forever{display:flex;align-items:center;gap:6px;flex:none;margin-left:6px;cursor:pointer;user-select:none}
.form-horizontal.company-dialog .cp-term-inline .cp-term-forever input{width:16px;height:16px;flex:none;margin:0}
.form-horizontal.company-dialog .cp-term-inline .cp-term-forever em{font-style:normal;font-size:13px;color:var(--text);white-space:nowrap}
@media (max-width:768px){
  .form-horizontal.company-dialog .cp-term-inline{flex-wrap:wrap;gap:6px}
  .form-horizontal.company-dialog .cp-term-inline>input[type="date"]{width:calc(50% - 20px);flex:1 1 40%}
}
/* 人员档案·管理人员弹窗（2026-10-09 用户口径「输入框垂直对齐」）：
   ⚠ `.col-left`/`.col-right` **只改 label 宽度，不改 grid 落列** —— 落列由 grid 自动流按字段顺序决定。
   新增态没有「状态」字段 ⇒ 自动流错位，同一列内混进 124 / 92 两种标签宽，
   输入框左边缘不齐（实测「姓名」478 vs「联系电话」446，差 32px）。
   本弹窗统一标签宽 = 110px（与「建设人员」弹窗 `.wk-form` 同宽），左右列内部自然对齐。 */
.form-horizontal.wk-mgr-form .f-item label,
.form-horizontal.wk-mgr-form .f-item.col-right label{width:110px;min-width:110px}
/* 复合控件容器（内部多个 input/select 并排）：填满内容区并允许收缩，防止挤压右侧列重叠 */
.form-horizontal .f-item>div[style*="display:flex"],.form-horizontal .f-item>div[style*="display: flex"]{width:100%;min-width:0}
/* label 内嵌按钮：按内容自适应宽度 */
.form-horizontal .f-item label:has(>.btn){width:auto;min-width:74px;flex:none;white-space:nowrap}
/* ⚠ 2026-10-10 修 bug：这条「横排表单的控件」规则**必须排除 checkbox / radio**。
   原来只排 checkbox 之前没排 radio ⇒ 裸 `<input type=radio>` 被当成文本输入框（flex-basis:0 + flex-grow:1、height:36px、1px 边框、圆角），
   安全日志弹窗「今日是否进行危大工程施工」的圆钮被拉成横条、后面的文字只剩 1 个字宽 ⇒ 竖排（用户截图）。
   同类问题：手机段那条 `width:100%!important` 也没排 checkbox/radio ⇒ 复选框被拉成整行宽（实测 402px）。
   全站其余同类规则（908 / 1533 / 1567 / 1580 行）本来就排除了两者，只有这里漏了。 */
.form-horizontal .f-item input:not([type="checkbox"]):not([type="radio"]),.form-horizontal .f-item select,.form-horizontal .f-item textarea{flex:1;min-width:0;width:auto;height:36px;border:1px solid var(--border-d);border-radius:10px;padding:0 12px;background:#fff;transition:.15s;font-size:13.5px}
.form-horizontal .f-item textarea{height:auto;min-height:50px;padding:8px 11px;resize:vertical}
.form-horizontal .f-item input:focus,.form-horizontal .f-item select:focus,.form-horizontal .f-item textarea:focus{border-color:var(--primary);background:#fff;box-shadow:0 0 0 3px var(--ring);outline:none}
.form-horizontal .f-item input::placeholder{color:#C0C5CF}
.form-horizontal .group-title{grid-column:span 12;font-size:13px;font-weight:600;color:var(--primary);border-left:3px solid var(--primary);padding-left:8px;margin:8px 0 0}
.form-horizontal .household-row{grid-column:span 12;display:grid;grid-template-columns:2fr 1fr;gap:12px}
.form-horizontal .hint-full{grid-column:span 12;font-size:11.5px;color:var(--faint);line-height:1.5;padding-left:132px;margin-top:-4px}
/* ===== 证书管理区块（人员档案·管理人员弹窗）：整行独占，标题一行 + 证书列表一行 =====
   ⚠ 原来是 `.f-item full` —— `.form-horizontal .f-item` 是 display:flex（行），
   会把标题压成 124px 窄列、证书列表挤到右边，成了难看的左右分栏（2026-09-30 用户反馈）。
   改用自定义 `.wc-block`（块级）即可上下两行；别改回 `.f-item`。 */
.form-horizontal .wc-block{grid-column:span 12}
.wc-block{min-width:0;background:#f8fafc;border:1px solid var(--border);border-radius:10px;padding:10px 12px}
.wc-block .wc-head{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;margin-bottom:8px}
.wc-block .wc-head label{font-weight:700;font-size:13px;line-height:1.35;color:var(--slate);margin:0;padding:0;width:auto;min-width:0;white-space:normal}
.wc-block .hint{font-size:11.5px;color:var(--faint);line-height:1.5;margin-top:6px}

/* ===== 起草协同单据·抄送单位：一个单位一行的勾选列表（2026-09-30 用户口径） =====
   ⚠ 外层用自定义 `.nt-cc-block`，**不要**塞回 `.form-horizontal .f-item`：
   那里 `display:flex`（行），会把勾选列表挤成多列流式排列、并把右侧提示拉到同一行（曾如此）。
   ⚠ 里面用 `<label>` 包整行（点文字也能勾）；因为不在 `.f-item` 内，不会吃到
   `.form-horizontal .f-item label{width:124px}` 那条，无需再逐个覆盖宽度。 */
.form-horizontal .nt-cc-block{grid-column:span 12;min-width:0}
.nt-cc-title{display:block;font-size:13px;font-weight:500;color:var(--slate);margin-bottom:6px}
.nt-cc-list{display:flex;flex-direction:column;background:#fff;border:1px solid var(--border-d);border-radius:10px;padding:2px 12px;max-height:240px;overflow-y:auto}
.nt-cc-item{display:flex;align-items:center;gap:8px;padding:6px 0;font-size:13px;font-weight:400;cursor:pointer;border-bottom:1px dashed var(--border)}
.nt-cc-item:last-child{border-bottom:none}
.nt-cc-item input[type=checkbox]{flex:none;margin:0;width:16px;height:16px}
.nt-cc-name{color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nt-cc-type{color:var(--faint);white-space:nowrap}
.nt-cc-hint{font-size:12px;color:var(--faint);padding-top:6px;line-height:1.6}

/* ===== 单位档案·关键岗位人员（2026-09-30 新增）=====
   用户口径：往来单位不该只有一个「联系人」—— 监理单位就该登记 总监理工程师 / 专业监理工程师 / 监理员，
   各类单位按自身规范岗位登记。数据存 companies.staff=[{post,name,phone}]。
   ⚠ 外层必须用自定义 `.st-block`（块级），**不要**写成 `.f-item full` ——
     `.form-horizontal .f-item` 是 display:flex（行），会把岗位表格挤成窄列（同 `.wc-block` 踩过的坑）。 */
.form-horizontal .st-block{grid-column:span 12;min-width:0}
.st-title{display:block;font-size:13px;font-weight:500;color:var(--slate);margin-bottom:6px}
.st-box{background:#fff;border:1px solid var(--border);border-radius:10px;overflow:hidden;max-height:420px;overflow-y:auto}
.st-hd,.staff-row{display:grid;grid-template-columns:1.15fr 1fr 1.25fr 40px;gap:8px;align-items:center}
.st-hd{padding:7px 12px;background:#F8FAFC;border-bottom:1px solid var(--border);font-size:12px;color:var(--sub);position:sticky;top:0;z-index:1}
.staff-row{padding:6px 12px;border-bottom:1px dashed var(--border)}
.staff-row:last-child{border-bottom:0}
.staff-row input,.staff-row select{width:100%;box-sizing:border-box;height:34px;border:1px solid var(--border-d);border-radius:10px;padding:0 10px;font-size:13px;background:#fff;color:var(--text)}
.staff-row input:focus,.staff-row select:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--ring);outline:none}
.staff-row .st-del{justify-self:center;padding:0}
.st-ft{display:flex;align-items:center;gap:10px;padding:8px 12px;border-top:1px solid var(--border);flex-wrap:wrap;position:sticky;bottom:0;background:#fff}
.st-tip{font-size:12px;color:var(--faint)}
/* 单位详情里的岗位人员 chips */
.st-chips{display:flex;flex-wrap:wrap;gap:6px 10px;margin-top:5px}
.st-chip{display:inline-flex;align-items:baseline;gap:6px;background:var(--tertiary);border:1px solid var(--border);border-radius:999px;padding:3px 10px;font-size:12.5px;color:var(--text)}
.st-chip b{font-weight:600;color:var(--slate)}
.st-chip em{font-style:normal;color:var(--sub);font-size:12px}
/* ===== 往来单位「证件资料」清单（2026-10-20）：编辑弹窗与单位详情共用 =====
   一行一类：左列类别名（12.5px 灰）、右侧文件名按钮；未上传显示「未上传」。 */
.cp-docs{border:1px solid var(--border);border-radius:var(--radius-s);background:var(--bg);padding:2px 10px}
.cp-doc-row{display:flex;gap:var(--sp-3);align-items:flex-start;padding:6px 0;border-bottom:1px dashed var(--border)}
.cp-doc-row:last-child{border-bottom:none}
.cp-doc-name{flex:none;width:132px;font-size:12.5px;color:var(--sub);line-height:1.7}
.cp-doc-files{flex:1;min-width:0;display:flex;flex-wrap:wrap;gap:2px 6px;line-height:1.7}
.cp-doc-file{display:inline-flex;align-items:center;gap:2px;max-width:100%}
.cp-doc-file .text-btn{max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ===== 一键识别按钮条（营业执照 / 施工许可证）=====
   弹窗顶部「上传…· 自动识别」按钮条：选图 → 后端 OCR → 只回填空白项。
   ⚠ 必须整行（`grid-column:span 12`），不要写成 `.f-item`（会被挤成窄列，见 .st-block 的坑）。
   （2026-10-01 用户口径：删掉按钮后面那串「自动读出 XX、YY…」的说明小字，只留按钮本身。） */
/* 缩进 124px：label width:124px 在全局 border-box 下已含 8px padding-right，
   输入框真实起点 = 124px（此前写 132px 实测偏右 8px+1px 边框，按钮比输入框靠右 9px） */
.form-horizontal .lic-ocr-bar{grid-column:span 12;padding-left:124px}
.lic-ocr-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:10px 12px;background:var(--primary-ll);border:1px dashed var(--primary-l);border-radius:10px}
.lic-ocr-bar .btn{flex:0 0 auto}

/* ===== 项目成员列表：固定列宽的 grid ⇒ 每行的「板块权限 / 所属单位 / 操作」上下对齐 =====
   ⚠ 原来每行是 `display:flex`：flex 的剩余空间是**按行独立分配**的，所以列与列之间根本对不齐
   （2026-09-30 用户反馈"为什么这个板块列和单位列还有后面那个都不能竖向对齐"）。
   ⇒ 换成 `display:grid` + 同一套 `grid-template-columns`。
   ⚠ 列宽**必须全固定/比例**，不能出现 `max-content`/`auto` 这种「按内容算」的轨道 ——
     每行是**各自独立**的网格容器，内容型轨道会随该行内容变宽，照样对不齐（踩过）。 */
.mbr-grid{display:grid;align-items:center;column-gap:12px;
  /* ★ 2026-10-16 列宽重排（删「板块权限」列后 = 4 列）：成员 / 邮箱 / 所属单位 / 操作。
     操作列 360→240（只剩「设为经理 / 移除」两个按钮）。
     ⚠ 轨道仍必须**全定宽或比例**，不能出现 `max-content`/`auto` —— 每行是各自独立的网格容器，
       内容型轨道会随该行内容变宽，行列又会对不齐（踩过）。 */
  grid-template-columns:210px minmax(120px,0.8fr) minmax(170px,1.6fr) 240px}
.mbr-grid>*{min-width:0}
.mbr-grid.mbr-head{padding:6px 0;border-bottom:1px solid var(--border);font-size:11.5px;color:var(--faint)}
.mbr-grid.mbr-row{padding:12px 0;border-bottom:1px solid var(--border)}
.mbr-grid .mbr-ops{display:flex;gap:6px;flex-wrap:wrap;justify-content:center}
/* 板块权限：按权限档分组（管理 / 可编辑 / 只读 各一行）—— 取代「每板块一颗胶囊」的堆叠（2026-10-09 用户口径）。
   `flex:0 0 52px` + `text-align:center` = 三档标签**等宽**，这样各行的板块名左边缘能对齐；
   52px 是「装得下最长档位名『可编辑』(3 字 × 11.5px ≈ 34.5px) 且留白匀称」的功能性定宽，属设计令牌档位外，特此注明。 */
.mbr-perms{display:flex;flex-direction:column;gap:var(--sp-1)}
.mbr-perm-line{display:flex;align-items:baseline;gap:var(--sp-2);font-size:12px}
.mbr-plevel{flex:0 0 52px;text-align:center;border-radius:999px;font-size:11.5px;line-height:18px;font-weight:500;white-space:nowrap}
.mbr-plevel.p-read{background:var(--tertiary);color:var(--sub)}
.mbr-plevel.p-write{background:var(--primary-l);color:var(--primary)}
.mbr-plevel.p-manage{background:var(--primary);color:#fff}
.mbr-pnames{color:var(--sub);min-width:0;line-height:1.7}
/* 窄屏：退回上下堆叠（列宽已无意义），并隐藏表头 */
@media (max-width:820px){
  .mbr-grid{display:flex;flex-wrap:wrap;column-gap:8px;row-gap:8px}
  .mbr-grid.mbr-head{display:none}
  .mbr-grid.mbr-row>*{flex:1 1 auto}
  .mbr-grid .mbr-ops{flex:1 1 100%;justify-content:flex-start}
}
/* 安全日志弹窗：标签列宽（★ 2026-10-12 用户口径：由 150px 收到 92px）
   起因：标签「项目负责人（签字）」按用户口径去掉「（签字）」后变短，控件应随之左移；
        且上方「日志日期」的控件要与之**垂直对齐**（两者同列、同标签宽 ⇒ 控件起点一致）。
   92px = 全站 `.col-right` 默认档，装得下本弹窗最长的定宽标签「项目负责人」（5 字 × 13px + padding-right 8px ≈ 73px）。
   ⚠ 只影响含 #dl-officer 的弹窗（＝安全日志弹窗）；
   ⚠ 带内联 `width:auto` 的标签（专职安全员 / 今日施工情况 / 危大开关）不受本条影响。 */
.form-horizontal:has(#dl-officer) .f-item label,
.form-horizontal:has(#dl-officer) .f-item.col-right label{width:92px;min-width:92px}
.form-horizontal:has(#dl-officer) .hint-full{padding-left:158px}
/* 安全日志弹窗：表头左栏收窄 + 负责人输入框缩短（★ 2026-10-12 第五次微调，用户截图口径）
   ⑨ 「项目负责人」输入框缩短 —— 用户原话："这个框可以短一点，反正就最多四个字"
      ⇒ 固定 96px（4 字 × 13.5px ≈ 54 + 左右内边距 24 + 余量）并取消第 443 行 input 的 flex:1 拉伸；
   ⑩ 左栏由 grid 默认 span 6 收到 span 4 ⇒ 右栏（项目专职安全生产管理人员）起点随之前移约
      3 列 + 3 个 gap ≈ 158px（用户原话："然后项目专职安全生产管理人员就可以左移动"）；
      右栏补成 span 8，与左栏互补、仍正好占满 12 列（span 之和不变 ⇒ 不会错行）。
   ▲ 顺带收益：右栏由 356px 涨到 481px，安全员下拉从 108px 放宽到 ~220px
     「陈超（渝建安C3(2021)0011775）」可完整显示（上一轮遗留的 108px 取舍由此解决）。
   ⚠ 用 :has() 是因为这两格没有专属 class，只能按内部控件 id 定位；`:has()` 的特异性取参数最高者，
     本组 (0,4,0) 高于第 548 行那条 (0,3,0)，不会互相打架。
   ⚠ 只在本组生效的那一行改动：上方「日志日期 / 天气状况」两格**刻意保持 span 6** ——
     若一起收到 span 4，日期控件只剩 ~138px，Chrome 的 `2026/10/12` + 日历图标会被截断。
   ⚠ 手机端（≤820px）第 819-826 行那批 `grid-template-columns:1fr!important` 与
     `grid-column:1/-1!important` 优先级更高，本条不影响移动端单列堆叠。 */
@media (min-width:821px){
  .form-horizontal:has(#dl-officer) .f-item:has(#dl-leader){grid-column:span 4}
  .form-horizontal:has(#dl-officer) .f-item:has(#dl-officer){grid-column:span 8}
  .form-horizontal:has(#dl-officer) #dl-leader{flex:0 0 auto;width:96px}
}
/* 安全日志弹窗：专职安全员下拉右侧的「字体设置」入口（2026-10-12 用户口径，常驻）
   桌面端与旁边 36px 的下拉等高（.btn.sm 本身 30px，这里抬到控件档 36）；
   ⚠ 只在 ≥769px 覆盖 —— 手机端必须让 .btn.sm 的 40px 档生效（design-system 三-2 可点元素 ≥40px）。 */
@media (min-width:769px){
  .form-horizontal .f-item #dl-goto-officers{height:36px}
}
/* 安全日志「今日是否进行危大工程施工」是 / 否单选（2026-10-10 用户截图：选项文字被挤成竖排）
   真因是**两条规则都没排除 radio**，圆钮被当成文本输入框：
     ① 第 429 行 `.form-horizontal .f-item input{flex:1;height:36px;border…}` ⇒ 圆钮被拉长；
     ② 手机段第 819 行 `…input{width:100%!important;flex:0 0 auto!important}` ⇒ 圆钮占满整行、文字只剩 1 字宽。
   两处已同步加 `:not([type="checkbox"]):not([type="radio"])`；这里再把这组选项显式重排一遍。
   ⚠ 本段用 !important 是**必要**的：对家之一是上面那条 `:has(#dl-officer)`（含 id，特异性 1,2,1），
     靠"同分靠后写"压不住；手机段还有一批 `width:100%!important` 的兜底规则。 */
.dl-yn{display:flex;align-items:center;gap:var(--sp-6);flex-wrap:wrap}
.form-horizontal .f-item label.dl-yn-opt{display:flex;align-items:center;gap:var(--sp-2);
  width:auto!important;min-width:0!important;max-width:100%;padding:0;margin-bottom:0;
  font-size:13px;font-weight:500;color:var(--text);line-height:1.45;white-space:normal;cursor:pointer}
.form-horizontal .f-item .dl-yn-opt input[type="radio"]{flex:0 0 auto!important;width:18px!important;
  min-width:18px!important;height:18px!important;min-height:0!important;margin:0;padding:0;
  border:none;border-radius:50%;background:none;accent-color:var(--primary)}
@media (max-width:768px){
  /* 手机端点按目标 ≥40px（design-system 三-2 的「手机次要」档），选项文字取档位内 15px */
  .dl-yn{gap:var(--sp-4)}
  .form-horizontal .f-item label.dl-yn-opt{min-height:40px!important;font-size:15px}
  .form-horizontal .f-item .dl-yn-opt input[type="radio"]{width:20px!important;min-width:20px!important;height:20px!important}
}
/* 班组弹窗：标签文字较长，加宽标签列 */
.team-dialog .f-item label{width:130px;min-width:130px}
.team-dialog .f-item.col-right label{width:120px;min-width:120px}
/* 人员档案弹窗兼容 */
.wk-form .f-item{display:flex;align-items:center;grid-column:span 6}
.wk-form .f-item.full{grid-column:span 12}
.wk-form .f-item label{display:block;width:110px;min-width:110px;text-align:left;font-size:13px;color:var(--slate);font-weight:500;margin-bottom:0;padding-right:8px;white-space:normal;overflow:visible;line-height:1.35}
.wk-form .f-item.col-right label{width:110px;min-width:110px}
.wk-form .f-item label{padding-left:3em}
.wk-form .f-item input,.wk-form .f-item select,.wk-form .f-item textarea{flex:1;min-width:0;width:auto;height:36px;border:1px solid var(--border-d);border-radius:10px;padding:0 11px;background:#fff;transition:.15s;font-size:13.5px}
.wk-form .f-item textarea{height:auto;min-height:50px;padding:8px 11px;resize:vertical}
.wk-form .f-item input:focus,.wk-form .f-item select:focus,.wk-form .f-item textarea:focus{border-color:var(--primary);background:#fff;box-shadow:0 0 0 3px var(--ring);outline:none}
.wk-form .f-item input::placeholder{color:#C0C5CF}
.wk-form .group-title{grid-column:span 12;font-size:13px;font-weight:600;color:var(--primary);border-left:3px solid var(--primary);padding-left:8px;margin:8px 0 0}
/* 主档横幅容器空时不占格子（否则弹窗标题与「基本信息」之间留一大块空白） */
#wk-master-banner:empty{display:none!important}
/* ===== 人员档案弹窗内嵌「特种作业」区块（2026-10-02：特种作业并入人员档案） =====
   容器直接挂在 .form-grid.wk-form 下，必须跨满 12 列且**不能**用 .f-item（那是 flex 行，
   塞多行块会被压成"标签 110px + 内容挤右边"）。内部自带两列 grid。 */
#wk-special-wrap{grid-column:1/-1;border-top:1px dashed var(--border-d);margin-top:8px;padding-top:10px}
#wk-special-wrap .wks-head{font-size:13px;font-weight:600;color:var(--primary);border-left:3px solid var(--primary);padding-left:8px;margin:4px 0 10px}
#wk-special-wrap .wks-sub{font-weight:400;color:var(--faint);font-size:11.5px;margin-left:6px}
#wk-special-wrap .wks-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px 18px}
#wk-special-wrap .wks-item{display:flex;align-items:center;min-width:0}
#wk-special-wrap .wks-item label{width:110px;min-width:110px;padding-left:3em;padding-right:8px;font-size:13px;color:var(--slate);font-weight:500;line-height:1.35;white-space:normal}
#wk-special-wrap .wks-item input{flex:1;min-width:0;height:36px;border:1px solid var(--border-d);border-radius:10px;padding:0 11px;font-size:13.5px;background:#fff;transition:.15s}
#wk-special-wrap .wks-item input:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--ring);outline:none}
#wk-special-wrap .wks-block{border:1px solid var(--border);border-radius:12px;padding:10px 12px;margin-top:12px;background:#fbfcfe}
#wk-special-wrap .wks-block-head{font-size:12.5px;font-weight:600;color:var(--slate);margin-bottom:8px}
#wk-special-wrap .wks-btns{display:inline-flex;gap:6px;flex-wrap:wrap}
#wk-special-wrap .wks-tip{font-size:11.5px;color:var(--faint);line-height:1.6;margin-top:8px}
#wk-special-wrap .wks-file-group{margin-top:10px}
#wk-special-wrap .wks-file-head{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:12.5px;color:var(--slate);margin-bottom:6px}
#wk-special-wrap .wks-file-list{display:flex;flex-direction:column;gap:4px}
#wk-special-wrap .wks-file-row{display:flex;align-items:center;gap:6px}
#wk-special-wrap .wks-file-name{flex:1;min-width:0;text-align:left;background:none;border:none;color:var(--primary);cursor:pointer;font-size:12.5px;padding:2px 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#wk-special-wrap .wks-empty{color:var(--faint);font-size:12px}
@media (max-width:820px){#wk-special-wrap .wks-grid{grid-template-columns:1fr}}
.wk-form .household-row{grid-column:span 12;display:grid;grid-template-columns:1fr 1fr;gap:12px}
.upload-drag{border:2px dashed #C9D2E0;border-radius:12px;padding:20px;text-align:center;color:#98A1AF;font-size:12px;cursor:pointer;transition:.2s}
.upload-drag:hover{border-color:var(--primary);background:var(--primary-ll)}
.upload-drag.dragover{border-color:var(--primary);background:var(--primary-l)}
.wk-form .hint-full{grid-column:span 12;font-size:11.5px;color:var(--faint);line-height:1.5;padding-left:118px;margin-top:-4px}
input[type=checkbox]{accent-color:var(--primary);cursor:pointer;width:16px;height:16px}
select{cursor:pointer}
/* ===== 日期输入框：空值**不显示任何占位**（2026-09-30 用户口径） =====
   原生 date 空值会按浏览器 locale 渲染「年/月/日」，聚焦后又变「yyyy/mm/日」——各端不一致，
   自定义 ::before 占位又不受 flex 居中影响（字飘到框顶）。用户要求：干脆都不显示。
   做法：空值框由 index.html 的同步脚本打 is-empty，这里把原生编辑区整体隐藏；填了值（is-empty 移除）立即恢复。
   ⚠ 必须用 visibility:hidden —— 实测对照过：只设 color:transparent（或给 :focus 的字段去底色 /
     给 fields-wrapper 去底色）都**压不住**聚焦时那块选区蓝底，会只剩一条蓝块。
   ⚠ 不要给 input 本体设 visibility/color —— 会把日历图标一起弄没。 */
input[type="date"].is-empty::-webkit-datetime-edit{visibility:hidden !important}
input[type="date"]::-webkit-calendar-picker-indicator{cursor:pointer;opacity:.55;transition:opacity .2s;padding:2px}
input[type="date"]:hover::-webkit-calendar-picker-indicator{opacity:1}

/* toast */
#toast-root{position:fixed;top:18px;left:50%;transform:translateX(-50%);z-index:2000;display:flex;flex-direction:column;gap:9px;align-items:center}
.toast{background:#1B2333;color:#fff;padding:11px 18px;border-radius:12px;font-size:13.5px;box-shadow:var(--shadow-lg);
  display:flex;align-items:center;gap:9px;animation:toastin .25s ease;max-width:90vw}
@keyframes toastin{from{transform:translateY(-14px);opacity:0}to{transform:none;opacity:1}}
.toast.ok{background:#00B42A}
.toast.err{background:#F53F3F}
.toast.warn{background:#FF7D00}

/* ==================== 考勤 ==================== */
.att-layout{display:grid;grid-template-columns:380px 1fr;gap:16px;align-items:stretch}
.att-input-card{padding:16px}
.att-input-card h4{font-size:14px;margin-bottom:12px;display:flex;align-items:center;gap:8px}
.att-names{width:100%;min-height:150px;border:1px solid var(--border-d);border-radius:10px;padding:10px 12px;resize:vertical;
  font-size:14px;line-height:1.9;background:#fff;transition:.2s}
.att-names:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--ring);outline:none}
.att-actions{display:flex;gap:9px;margin-top:12px;flex-wrap:wrap}
.match-result{margin-top:12px;font-size:12.5px;color:var(--sub);display:flex;gap:14px;flex-wrap:wrap}
.match-result b{color:var(--text)}
.cal-card{padding:16px}
.cal-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}
.cal-head .ym{font-weight:700;font-size:15px;min-width:110px;text-align:center}
.cal-nav{width:34px;height:34px;border-radius:10px;border:1px solid var(--border-d);display:flex;align-items:center;justify-content:center;color:var(--slate);transition:.2s}
.cal-nav:hover{border-color:var(--primary);color:var(--primary)}
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:6px}
.cal-grid .wk{text-align:center;font-size:12px;color:var(--faint);padding:4px 0;font-weight:600}
.cal-cell{aspect-ratio:1;border:1px solid var(--border);border-radius:10px;display:flex;flex-direction:column;align-items:center;justify-content:center;
  font-size:13px;cursor:pointer;position:relative;background:#fff;transition:.2s;min-height:42px}
.cal-cell.empty{border:none;cursor:default;background:transparent}
.cal-cell:not(.empty):hover{border-color:var(--primary)}
.cal-cell.today{box-shadow:inset 0 0 0 1.5px var(--primary)}
.cal-cell.st-work{background:var(--green);border-color:var(--green);color:#fff;font-weight:600}
.cal-cell.st-half{background:var(--orange);border-color:var(--orange);color:#fff;font-weight:600}
.cal-cell.st-leave{background:var(--blue);border-color:var(--blue);color:#fff}
.cal-cell.st-absent{background:var(--red);border-color:var(--red);color:#fff}
.cal-cell .stxt{font-size:10px;line-height:1;margin-top:2px;opacity:.92}
.cal-legend{display:flex;gap:14px;flex-wrap:wrap;margin-top:12px;font-size:12px;color:var(--sub)}
.cal-legend i{display:inline-block;width:11px;height:11px;border-radius:4px;margin-right:5px;vertical-align:-1px}
.cal-stat{margin-top:10px;font-size:13px;color:var(--slate);background:var(--tertiary);border-radius:10px;padding:10px 13px;display:flex;gap:18px;flex-wrap:wrap}

/* 考勤：按班组分组 */
.att-team{border:1px solid var(--border);border-radius:12px;margin-bottom:10px;overflow:hidden;background:var(--card)}
.att-team-head{display:flex;align-items:center;gap:9px;padding:10px 14px;background:#F8FAFC;
  font-weight:700;font-size:13.5px;border-bottom:1px solid var(--border);cursor:pointer;user-select:none;flex-wrap:wrap;row-gap:3px;word-break:keep-all}
.att-team-head .at-cnt{font-weight:600;color:var(--primary);font-size:12.5px;background:var(--primary-l);padding:1px 10px;border-radius:999px;margin-left:auto}
.att-team-head .at-fold{margin-left:0;color:var(--faint);font-size:12px}
.att-team-body table{min-width:0!important}

/* ==================== 项目信息铭牌 ==================== */
.proj-plate{background:var(--primary-ll);border:1px solid #D9E4FB;color:var(--text);border-radius:12px;padding:20px 22px;margin-bottom:18px;
  position:relative;overflow:hidden}
.proj-plate .grid-lines{display:none}
.proj-plate>*{position:relative;z-index:1}
.proj-plate h3{color:var(--text);font-size:18px;margin-bottom:12px;display:flex;align-items:center;gap:9px}
.plate-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:10px 26px}
.plate-grid .pi{font-size:13px;display:flex;gap:8px}
.plate-grid .pi .k{color:var(--sub);flex-shrink:0}
.plate-grid .pi .v{color:var(--text);font-weight:500}

/* 汇总条 */
.sum-bar{display:flex;gap:22px;flex-wrap:wrap;background:var(--primary-l);border:1px solid #D9E4FB;border-radius:var(--radius);
  padding:12px 18px;margin-bottom:14px;font-size:13.5px;color:var(--slate)}
.sum-bar b{color:var(--primary-d);font-size:16px;font-weight:700;margin-left:4px}

/* 候选匹配弹窗 */
.pick-list{display:flex;flex-direction:column;gap:8px;margin-top:6px}
.pick-item{display:flex;align-items:center;gap:12px;border:1px solid var(--border);border-radius:12px;padding:11px 14px;cursor:pointer;transition:.2s}
.pick-item:hover{border-color:var(--primary);background:var(--primary-ll)}
.pick-item .pname{font-weight:700;font-size:14.5px}
.pick-item .pmeta{font-size:12.5px;color:var(--sub);margin-top:2px}
.pick-item .sim{margin-left:auto;font-size:12px;color:var(--primary);font-weight:600}

/* 历史版本时间线 */
.timeline{position:relative;padding-left:22px}
.timeline:before{content:'';position:absolute;left:6px;top:6px;bottom:6px;width:2px;background:var(--border)}
.tl-item{position:relative;margin-bottom:14px;background:var(--tertiary);border-radius:12px;padding:12px 14px}
.tl-item:before{content:'';position:absolute;left:-19px;top:16px;width:10px;height:10px;border-radius:50%;background:var(--primary);box-shadow:0 0 0 3px var(--primary-l)}
.tl-item .vhead{display:flex;justify-content:space-between;font-size:13px;margin-bottom:6px}
.tl-item .vhead b{color:var(--primary-d)}
.diff-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px 16px;font-size:12.5px}
.diff-grid .changed{color:var(--orange)}
.kv-row{display:flex;gap:8px;padding:3px 0;border-bottom:1px dashed var(--border)}
.kv-row .k{color:var(--sub);min-width:84px;flex-shrink:0}

/* 变更历史统一时间流 */
.hist-toolbar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:13px}
.hist-flow{display:flex;flex-direction:column;gap:10px}
.hist-card{background:var(--card);border:1px solid var(--border);border-radius:12px;box-shadow:var(--shadow);padding:12px 15px}
.hist-card .hc-top{display:flex;align-items:center;gap:9px;flex-wrap:wrap;font-size:13px}
.hist-card .hc-time{color:var(--sub);font-size:12.5px;font-variant-numeric:tabular-nums}
.hist-card .hc-label{font-weight:700;font-size:13.5px}
.hist-card .hc-module{font-size:12px;color:var(--primary);background:var(--primary-l);padding:1px 9px;border-radius:999px}
.hist-card .hc-act-add{background:var(--green-l);color:#009A22}
.hist-card .hc-act-edit{background:var(--orange-l);color:#D96A00}
.hist-card .hc-act-del{background:var(--red-l);color:#D93636}
.hist-card .hc-act-batch{background:#EEF0FF;color:#4338CA}
.hist-card .hc-changes{margin-top:8px;font-size:12.5px;color:var(--slate);line-height:1.9}
.hist-card .hc-changes .chg{display:inline-block;margin:2px 14px 2px 0}
.hist-card .hc-changes .arr{color:var(--faint);margin:0 5px}
.hist-card .hc-changes .old{color:var(--faint);text-decoration:line-through;text-decoration-color:#C6CCD6}
.hist-card .hc-changes .new{color:var(--text);font-weight:600}
.hist-card .hc-foot{margin-top:9px;display:flex;gap:8px;justify-content:flex-end}
.act-add{color:#009A22}
.act-edit{color:#D96A00}
.act-del{color:#D93636}

/* 加载 */
.loading-mask{position:fixed;inset:0;background:rgba(255,255,255,.72);backdrop-filter:blur(2px);z-index:1500;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:14px;color:var(--slate)}
.spinner{width:38px;height:38px;border:3px solid var(--primary-l);border-top-color:var(--primary);border-radius:50%;animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* ==================== 分段页签 ==================== */
.seg-tabs{display:inline-flex;gap:4px;background:#EDF0F5;padding:4px;border-radius:12px;flex-wrap:wrap}
.seg-tab{display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 16px;border-radius:10px;font-size:13.5px;font-weight:500;
  color:var(--slate);background:transparent;border:none;cursor:pointer;transition:.2s ease;white-space:nowrap}
.seg-tab:hover{color:var(--primary)}
.seg-tab.active{background:#fff;color:var(--primary);font-weight:600;box-shadow:0 1px 3px rgba(27,35,51,.10)}

/* 自动编号小标签 */
.auto-tag{display:inline-block;margin-left:6px;padding:1px 8px;border-radius:999px;font-size:10.5px;font-weight:600;
  color:var(--primary);background:var(--primary-l);border:1px solid #D2E0FA;vertical-align:middle;letter-spacing:.2px}

/* 本机存储模式提示条 */
.local-mode-bar{display:flex;align-items:center;gap:11px;background:var(--primary-ll);
  border:1px solid #D9E4FB;color:var(--slate);border-radius:12px;padding:10px 14px;font-size:12.5px;line-height:1.6;margin-bottom:12px;
  box-shadow:var(--shadow)}
.local-mode-bar .lm-ic{flex-shrink:0;width:30px;height:30px;border-radius:10px;background:var(--primary-l);color:var(--primary);
  display:flex;align-items:center;justify-content:center}
.local-mode-bar .lm-txt{flex:1;min-width:0}
.local-mode-bar b{color:var(--primary)}
.local-mode-bar .lm-x{flex-shrink:0;width:28px;height:28px;border-radius:6px;border:none;background:transparent;color:var(--faint);
  display:flex;align-items:center;justify-content:center;cursor:pointer;transition:.2s}
.local-mode-bar .lm-x:hover{background:var(--primary-l);color:var(--primary)}

/* ==================== 通用可搜索下拉（combobox） ==================== */
.combo-wrap{position:relative;width:100%}
.combo-wrap input{width:100%!important;box-sizing:border-box;padding-right:34px}
.combo-arrow{position:absolute;right:8px;top:50%;transform:translateY(-50%);color:var(--faint);pointer-events:none;display:flex}
.combo-pop{position:absolute;z-index:1200;left:0;right:0;top:calc(100% + 4px);background:#fff;border:1px solid var(--border-d);border-radius:12px;
  box-shadow:var(--shadow-lg);max-height:248px;overflow-y:auto;padding:5px}
.combo-item{padding:8px 10px;border-radius:10px;font-size:13.5px;cursor:pointer;display:flex;flex-direction:column;gap:2px;transition:.15s}
.combo-item .ci-sub{font-size:11.5px;color:var(--faint)}
.combo-item:hover,.combo-item.on{background:var(--primary-l);color:var(--primary-d)}
.combo-item b{font-weight:700}
.combo-empty{padding:12px;text-align:center;color:var(--faint);font-size:12.5px}
.combo-match{color:var(--red);font-weight:700}
/* —— 二级下拉（2026-10-23）：一级「族」、二级「该族工种」 —— */
.combo-item.combo-grp{flex-direction:row;align-items:center;justify-content:space-between;gap:10px;font-weight:600}
.combo-item.combo-grp .ci-sub{font-weight:400;letter-spacing:0}
.combo-back{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:4px;padding:6px 10px;margin:0 0 3px;
  border-radius:9px;font-size:12px;font-weight:600;color:var(--primary-d);background:var(--primary-l);cursor:pointer}
.combo-back:hover{background:#DCE9FA}
/* 二级下拉（族 → 工种）：放宽高度一屏多看几行，配合 .combo-up 向上翻 */
.combo-pop.combo-hi{max-height:360px}
.combo-pop.combo-hi .combo-item.combo-grp{padding:5px 10px;line-height:1.45}
.combo-pop.combo-up{top:auto;bottom:calc(100% + 4px)}
/* —— 工种「族 → 右侧浮层」（2026-10-23 桌面 hover 版；手机端不出现）——
   挂在 body 上、position:fixed，位置由 JS 算（右侧放不下自动翻左侧）。
   z-index 1300 = pop(1200) 之上、顶层提示(2000) 之下，属既有浮动层层级。 */
.combo-sub{position:fixed;left:0;top:0;z-index:1300;background:#fff;border:1px solid var(--border-d);
  border-radius:var(--radius-s);box-shadow:var(--shadow-lg);overflow-y:auto;overscroll-behavior:contain;
  padding:var(--sp-1);display:flex;flex-direction:column;gap:var(--sp-1)}
.combo-sub[hidden]{display:none}
.combo-sub-hd{position:sticky;top:0;z-index:1;display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);
  padding:var(--sp-1) var(--sp-2);border-radius:9px;font-size:11.5px;font-weight:600;
  color:var(--primary-d);background:var(--primary-l)}
.combo-sub-hd .cs-n{font-weight:400;color:var(--faint)}
.combo-sub .combo-item{flex-direction:row;align-items:center;justify-content:space-between;gap:var(--sp-2);
  padding:var(--sp-1) var(--sp-2);font-size:13px;white-space:nowrap}
.combo-sub .combo-item>span:first-child{overflow:hidden;text-overflow:ellipsis}
@media (max-width:768px){.combo-sub{display:none!important}}

/* ==================== 工作台预警中心 ==================== */
.warn-board{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);
  padding:15px 18px;margin-bottom:18px;border-left:4px solid var(--orange)}
.warn-board .wb-head{display:flex;align-items:center;gap:9px;font-size:15px;font-weight:700;margin-bottom:11px}
.warn-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:11px}
.warn-item{border:1px solid var(--border);border-radius:12px;padding:11px 13px;background:#FAFBFD;display:flex;flex-direction:column;gap:7px}
.warn-item.danger{border-color:#F6C8CB;background:#FFF9F8}
.warn-item.warn{border-color:#FFDCB0;background:#FFFCF5}
.warn-item.info{border-color:#D2E0FA;background:#F6F9FF}
.warn-item .wi-top{display:flex;align-items:center;gap:8px;font-weight:700;font-size:13.5px}
.warn-item .wi-cnt{margin-left:auto;font-size:18px;font-weight:700}
.warn-item.danger .wi-cnt{color:var(--red)}
.warn-item.warn .wi-cnt{color:#D96A00}
.warn-item.info .wi-cnt{color:var(--primary)}
.warn-item .wi-names{font-size:12.5px;color:var(--slate);line-height:1.8;word-break:break-all}
.warn-item .wi-names .wn{display:inline-block;margin:1px 5px 1px 0;padding:1px 8px;background:#F1F3F6;border-radius:999px;cursor:pointer;transition:.15s}
.warn-item .wi-names .wn:hover{background:var(--primary-l);color:var(--primary)}
.warn-item .wi-act{align-self:flex-start}

/* ==================== 响应式 ==================== */
@media (max-width:900px){
  .att-layout{grid-template-columns:1fr}
}
@media (max-width:768px){
  body{font-size:13.5px}
  .auth-brand{display:none}
  .auth-panel{flex:1}
  #sidebar{position:fixed;top:0;left:0;bottom:0;transform:translateX(-100%);box-shadow:var(--shadow-lg);border-right:none}
  #sidebar.open{transform:none}
  #sidebar.open .side-nav{padding-bottom:90px}
  .side-mask.show{display:block}
  .hamburger{display:flex}
  #content{padding:16px}
  #topbar{padding:0 12px;gap:8px}
  .proj-select{min-width:0;max-width:46vw;flex:1}
  .sync-state .sync-text{display:none}
  .form-grid{grid-template-columns:1fr!important;gap:12px}
  /* 所有表单项（含左右两列/宽窄列）在手机上整行堆叠，不再并排挤压 */
  .form-grid .f-item,
  .form-grid .f-item.col-left,
  .form-grid .f-item.col-right,
  .form-grid .f-item.wide,
  .form-grid .f-item.narrow,
  .form-grid .f-item.full{grid-column:1/-1!important}
  /* 单列网格里任何 span 6/8/12 的直接子元素都占满整行 */
  .form-grid > *{grid-column:1/-1!important}
  /* 窄屏下上传条取消桌面端的 132px 缩进（label 已改到控件上方，无列可对齐） */
  .form-horizontal .lic-ocr-bar{padding-left:12px!important}
  /* 横向表单改为纵向：label 在上、控件整行在下 */
  .form-horizontal .f-item,
  .wk-form .f-item,
  .team-dialog .f-item{display:flex!important;flex-direction:column;align-items:stretch!important;gap:8px}
  .form-horizontal .f-item>label,
  .wk-form .f-item>label,
  .team-dialog .f-item>label,
  .form-horizontal .f-item.col-right>label,
  .wk-form .f-item.col-right>label,
  .team-dialog .f-item.col-right>label{
    width:auto!important;min-width:0!important;padding-left:0!important;padding-right:0!important;
    margin-bottom:0;text-align:left;white-space:normal;overflow:visible;text-overflow:clip}
  /* ⚠ 2026-10-10：这三组「控件占满整宽」的选择器**都必须排除 checkbox / radio** ——
     否则手机端复选框/单选钮会被拉成整行宽（实测 402px 宽、看着像一条横线；用户截图里的圆钮就是这么坏的）。 */
  .form-horizontal .f-item input:not([type="checkbox"]):not([type="radio"]),
  .form-horizontal .f-item select,
  .form-horizontal .f-item textarea,
  .wk-form .f-item input:not([type="checkbox"]):not([type="radio"]),
  .wk-form .f-item select,
  .wk-form .f-item textarea,
  .team-dialog .f-item input:not([type="checkbox"]):not([type="radio"]),
  .team-dialog .f-item select{width:100%!important;min-width:0!important;flex:0 0 auto!important;height:44px}
  .form-horizontal .f-item textarea,
  .wk-form .f-item textarea{height:auto!important;min-height:64px!important;padding:8px 12px}
  .form-horizontal input[type=date]{min-width:0!important;width:100%!important}
  .wk-form .hint-full{padding-left:0!important}
  .wk-form .group-title{margin-top:4px}
  /* 户口性质行：单列 */
  .form-horizontal .household-row,
  .wk-form .household-row{grid-column:1/-1;grid-template-columns:1fr!important;gap:8px}
  .wk-form .household-row .f-item>div{flex-wrap:wrap}
  .wk-form .household-row input#wk-household{width:100%!important;flex:1 1 100%!important;height:44px !important}
  .wk-form .household-row .f-item>div .btn{flex:1 1 calc(33.333% - 6px);min-width:0;height:44px;padding-left:4px;padding-right:4px}
  /* 弹窗在手机上减少留白 */
  .modal-mask{padding:8px}
  .modal{max-height:94vh}
  .modal-head{padding:16px 16px}
  .modal-body{padding:16px 16px}
  .modal-foot{padding:8px 16px}
  /* 弹窗只允许上下滚动：iOS 下 1fr 网格轨道会被含 min-width 的子项按 max-content 撑破，
     导致整个表单比屏幕宽、可以左右滑动。这里强制弹窗与所有网格子项可收缩，横向溢出一律禁止。 */
  .modal{min-width:0!important;max-width:calc(100vw - 20px)!important}
  .modal-body{overflow-x:hidden!important}
  .form-grid>*{min-width:0!important;max-width:100%}
  .form-grid .f-item label{min-width:0!important}
  .modal label{min-width:0!important;max-width:100%}
  .modal label>span{min-width:0!important}
  /* 复选框说明行改回块级排版：WebKit 对 flex+嵌套 span 有布局怪癖，会把内容挤出容器造成横向溢出 */
  .modal label:has(>input[type=checkbox]){display:block!important}
  .modal label:has(>input[type=checkbox])>input[type=checkbox]{vertical-align:-2px;margin-right:8px}
  /* 双列对比区单列 */
  .diff-grid{grid-template-columns:1fr}
  /* 弹窗内"输入框 + 选择按钮"横排：输入框可收缩 */
  .modal .f-item>div[style*="display: flex"],
  .modal .f-item>div[style*="display:flex"],
  .modal .f-item>div:has(>.btn){min-width:0;flex-wrap:wrap}
  .modal .f-item>div[style*="display: flex"]>input,
  .modal .f-item>div[style*="display:flex"]>input,
  .modal .f-item>div:has(>.btn)>input{flex:1 1 0!important;min-width:0!important;width:auto!important}
  .modal .f-item>div[style*="display: flex"]>.btn,
  .modal .f-item>div[style*="display:flex"]>.btn,
  .modal .f-item>div:has(>.btn)>.btn{flex:0 0 auto}
  .page-head h2{font-size:17px}
  .btn{height:44px;padding:0 16px}
  .btn.sm{height:40px}
  .stat-card .val{font-size:22px}
  .modal{max-height:88vh}
  .data-table{font-size:12.5px;min-width:0!important}
  /* 宽表在手机上自动转为卡片列表 */
  .table-wrap{overflow:visible;background:transparent;border:none;box-shadow:none}
  /* 台账页手机端恢复自然高度 */
  section[data-page="safety_inspection"]{height:auto}
  #si-tab-content{flex:none;min-height:0;display:block}
  #si-tab-content .table-wrap{flex:none;min-height:0;max-height:none}
  .data-table thead{display:none}
  .data-table tbody tr{display:block;background:var(--card);border:1px solid var(--border);border-radius:var(--radius);
    margin-bottom:8px;padding:4px 12px;box-shadow:var(--shadow)}
  .data-table tbody tr[data-edit-row]:active{background:var(--primary-l)}
  .data-table td{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;
    white-space:normal!important;text-align:right;padding:8px 0;border-bottom:1px dashed #E5E8F0;word-break:break-word}
  .data-table tbody tr td:last-child{border-bottom:none}
  .data-table td::before{content:attr(data-label);font-weight:600;color:var(--sub);font-size:12.5px;text-align:left;flex-shrink:0;padding-right:8px}
  .data-table td.col-idx{display:none}
  .data-table td:first-child{justify-content:flex-start}
  .data-table .row-actions{justify-content:flex-end}
  .user-chip .uemail{display:none}
  .user-chip{gap:8px;flex-shrink:0}
  #logout-btn{white-space:nowrap;flex-shrink:0;padding:4px 8px}
  .sync-state{padding:8px 8px;flex-shrink:0}
  .dash-sum{grid-template-columns:1fr!important}
  .modal-foot{flex-wrap:wrap}
  .modal-foot .btn{flex:1;min-width:110px}
  .stat-grid{grid-template-columns:1fr 1fr;gap:8px}
  .page-actions{width:100%}
  .seg-tabs{width:100%;overflow-x:auto;flex-wrap:nowrap}
  .seg-tab{flex:1;justify-content:center;padding:0 12px}
  .local-mode-bar{flex-wrap:wrap}
  /* iPhone 兼容：输入控件 16px 字号，避免聚焦时页面自动缩放 */
  .toolbar input,.toolbar select,
  .filter-bar input,.filter-bar select,
  .f-item input,.f-item select,.f-item textarea,
  .modal input:not([type=checkbox]):not([type=radio]),.modal select,.modal textarea,
  .m-search input,.att-names,.field input,.proj-select{font-size:16px}
}

/* ==================== 特种人员弹窗内证件材料区 ==================== */
.sp-files-section{margin-top:18px;padding-top:16px;border-top:1px solid var(--border)}
.sp-files-title{font-size:14px;font-weight:600;color:var(--text);margin-bottom:12px}
.sp-file-group{margin-bottom:14px}
.sp-file-group:last-child{margin-bottom:0}
.sp-file-group-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}
.sp-file-group-head>span{font-size:13px;font-weight:500;color:var(--slate)}
.sp-file-list{display:flex;flex-wrap:wrap;gap:6px;min-height:28px}
.sp-file-name{display:inline-flex;align-items:center;max-width:260px;height:28px;padding:0 10px;
  background:var(--tertiary);border:1px solid var(--border);border-radius:10px;font-size:12.5px;color:var(--primary);
  cursor:pointer;transition:background .15s,border-color .15s;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sp-file-name:hover{background:var(--primary-l);border-color:var(--primary)}

/* =========== 特种人员弹窗内区块：现仅「全局共享证件」复用 ===================
   2026-10-16：原「联网查询」板块整体删除；sp-query-section / sp-query-title 因
   #sp-master-certs 的「全局共享证件」列表复用而保留，其余 sp-query-* 一并删除。 */
.sp-query-section{margin-top:18px;padding:14px 16px;background:#F8FAFC;border:1px solid var(--border);border-radius:12px}
.sp-query-title{font-size:14px;font-weight:600;color:var(--text);margin-bottom:10px}

/* ==================== Excel 风格列宽调整 + 列拖拽 ==================== */
.col-resizer{position:absolute;right:0;top:0;width:5px;height:100%;cursor:col-resize;z-index:5;user-select:none}
.col-resizer:hover{background:rgba(30,90,200,.25)}
.col-draggable{cursor:move}
.col-draggable:active{cursor:grabbing}
.data-table th{user-select:none}

/* ============================================================================
   管理端整体背景 + 用户端/管理端通用弹窗
   （管理端视觉主样式由 admin_module.js 注入的 <style id=adm-style> 提供）
   ============================================================================ */
body:has(.adm-root){
  background:#F3F5F9 !important;
  font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif !important;
}

/* 弹窗（用户端/管理端通用） */
.modal{
  border-radius:16px !important;
  overflow:hidden !important;
  box-shadow:0 6px 16px rgba(27,35,51,.09),0 20px 48px rgba(27,35,51,.13) !important;
}
.modal-head{
  background:#FAFBFD !important;
  border-bottom:1px solid var(--border) !important;
  padding:17px 22px !important;
}

/* ===== 自定义下拉 ===== */
.custom-dd{position:relative;display:inline-block}
.custom-dd .dd-arrow{margin-left:4px;font-size:10px;opacity:.6}
.dd-menu{
  display:none;position:absolute;top:calc(100% + 4px);left:0;z-index:1000;
  min-width:220px;background:#fff;border:1px solid var(--border);border-radius:12px;
  box-shadow:var(--shadow-lg);padding:4px 0;
}
.dd-menu.show{display:block}
.dd-item{
  padding:8px 16px;font-size:13.5px;color:#1B2333;cursor:pointer;white-space:nowrap;
  transition:background .12s;
}
.dd-item:hover{background:var(--primary-ll);color:var(--primary)}
.dd-item.dd-disabled{color:#bbb;cursor:default}
.dd-item.dd-disabled:hover{background:transparent;color:#bbb}
.dd-divider{height:1px;background:#EFF1F5;margin:4px 0}
.dd-group-label{font-size:11.5px;color:#9AA1AD;padding:6px 16px 2px;letter-spacing:.5px}
.dd-item.dd-checked{color:var(--primary);font-weight:600}
.dd-item.dd-checked:hover{color:var(--primary);background:var(--primary-ll)}

/* ===== 紧凑表单控件（32px 高密度，腾讯文档风格） ===== */
.form-horizontal select{
  appearance:none !important;
  -webkit-appearance:none !important;
  height:32px !important;
  min-height:32px !important;
  border:1px solid var(--border-d) !important;
  border-radius:6px !important;
  padding:0 30px 0 10px !important;
  background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23909399' d='M6 8.5L1.5 4h9z'/%3E%3C/svg%3E") no-repeat right 10px center / 12px 12px !important;
  background-color:#fff !important;
  font-size:14px !important;
  font-weight:400 !important;
  color:#30364A !important;
  cursor:pointer !important;
  transition:border-color .2s,box-shadow .2s !important;
  line-height:32px !important;
}
.form-horizontal select:hover{border-color:#A8AEBA !important}
.form-horizontal select:focus{
  border-color:var(--primary) !important;
  box-shadow:0 0 0 2px var(--ring) !important;
  outline:none !important;
}
.form-horizontal input[type="date"]{
  height:32px !important;
  min-height:32px !important;
  border:1px solid var(--border-d) !important;
  border-radius:6px !important;
  padding:0 10px !important;
  background:#fff !important;
  font-size:14px !important;
  color:#30364A !important;
  cursor:pointer !important;
  transition:border-color .2s,box-shadow .2s !important;
  width:auto !important;
  min-width:140px !important;
}
.form-horizontal input[type="date"]:hover{border-color:#A8AEBA !important}
.form-horizontal input[type="date"]:focus{
  border-color:var(--primary) !important;
  box-shadow:0 0 0 2px var(--ring) !important;
  outline:none !important;
}
.form-horizontal input[type="date"]::-webkit-calendar-picker-indicator{
  cursor:pointer !important;
  opacity:.55 !important;
  transition:opacity .2s !important;
  padding:2px !important;
}
.form-horizontal input[type="date"]::-webkit-calendar-picker-indicator:hover{opacity:1 !important}
.form-horizontal input[type="date"]::-webkit-datetime-edit{padding:0 !important}
.form-horizontal input:not([type="date"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]){
  height:32px !important;
  min-height:32px !important;
  border:1px solid var(--border-d) !important;
  border-radius:6px !important;
  padding:0 10px !important;
  background:#fff !important;
  font-size:14px !important;
  color:#30364A !important;
  transition:border-color .2s,box-shadow .2s !important;
}
.form-horizontal input:not([type="date"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):hover{border-color:#A8AEBA !important}
.form-horizontal input:not([type="date"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):focus{
  border-color:var(--primary) !important;
  box-shadow:0 0 0 2px var(--ring) !important;
  outline:none !important;
}
.form-horizontal select option{
  padding:8px 10px !important;
  font-size:14px !important;
  color:#30364A !important;
  background:#fff !important;
}
.form-horizontal select option:checked{
  background:var(--primary) !important;
  color:#fff !important;
}

/* ===== 可搜索多选下拉组件 .mc ===== */
.mc{position:relative;width:100%;font-size:13px}
.mc-control{min-height:36px;display:flex;flex-wrap:wrap;align-items:center;gap:5px;padding:3px 30px 3px 9px;
  border:1px solid var(--border-d);border-radius:10px;background:#fff;cursor:text;position:relative;
  transition:border-color .18s,box-shadow .18s}
.mc-control:hover{border-color:var(--primary)}
.mc.open .mc-control{border-color:var(--primary);box-shadow:0 0 0 3px var(--ring)}
.mc-tag{display:inline-flex;align-items:center;gap:3px;max-width:100%;height:24px;padding:0 4px 0 9px;border-radius:6px;
  background:var(--primary-l);color:var(--primary-d);font-size:12.5px;font-weight:500;white-space:nowrap}
.mc-tag i{width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;border-radius:4px;
  cursor:pointer;color:var(--primary);font-style:normal;font-size:13px;line-height:1;opacity:.65}
.mc-tag i:hover{background:rgba(30,90,200,.16);opacity:1}
.mc-input{flex:1;min-width:96px;height:26px;border:none!important;padding:0!important;background:transparent!important;
  box-shadow:none!important;font-size:13px!important;min-height:0!important;outline:none!important}
.mc-input:focus{box-shadow:none!important;border:none!important;outline:none!important}
.f-item .mc .mc-input,.form-horizontal .f-item .mc .mc-input{border:none!important;background:transparent!important;box-shadow:none!important;outline:none!important;padding:0!important;width:auto;min-width:0}
.mc-arrow{position:absolute;right:10px;top:50%;transform:translateY(-50%);color:var(--faint);font-size:10px;
  transition:transform .18s;pointer-events:none}
.mc.open .mc-arrow{transform:translateY(-50%) rotate(180deg)}
.mc-ph{color:var(--faint);font-size:13px;padding-left:2px}
.mc-panel{display:none;position:absolute;z-index:60;top:calc(100% + 4px);left:0;right:0;max-height:250px;overflow-y:auto;
  background:#fff;border:1px solid var(--border);border-radius:12px;box-shadow:var(--shadow-lg);padding:5px}
.mc.open .mc-panel{display:block}
.mc-grp{position:sticky;top:-5px;z-index:1;padding:7px 9px 5px;font-size:12px;font-weight:600;color:var(--sub);
  background:#FAFBFD;border-bottom:1px solid var(--border);margin-bottom:3px;border-radius:6px}
.mc-opt{display:flex;align-items:center;gap:9px;padding:7px 9px;border-radius:10px;cursor:pointer;color:var(--text)}
.mc-opt:hover{background:var(--primary-ll)}
.mc-box{width:15px;height:15px;border:1.5px solid var(--border-d);border-radius:4px;flex-shrink:0;
  display:inline-flex;align-items:center;justify-content:center;color:#fff;font-size:11px;background:#fff;transition:.15s}
.mc-opt.sel{background:var(--primary-ll)}
.mc-opt.sel .mc-box{background:var(--primary);border-color:var(--primary)}
.mc-opt.sel .mc-box::before{content:"\2713";font-size:11px;line-height:1;font-weight:700}
.mc-opt.sel .mc-opt-main{color:var(--primary-d);font-weight:600}
.mc-opt-main{font-size:13px}
.mc-opt-sub{font-size:12px;color:var(--faint);margin-left:6px}
.mc-empty{padding:16px 10px;text-align:center;color:var(--faint);font-size:12.5px;line-height:1.7}
.mc-readonly{display:flex;flex-wrap:wrap;gap:6px;min-height:34px;align-items:center;padding:6px 9px;
  border:1px solid var(--border);border-radius:10px;background:var(--tertiary)}
.mc-ro-tag{display:inline-flex;align-items:center;height:24px;padding:0 10px;border-radius:6px;background:#fff;
  border:1px solid var(--border);font-size:12.5px;color:var(--slate)}
.mc-ro-empty{color:var(--faint);font-size:12.5px}

/* 周月/节假日检查记录：问题明细区块纵向通栏 */
.form-horizontal .f-item.pc-item{flex-direction:column;align-items:stretch!important}
.form-horizontal .f-item.pc-item>label{width:auto!important;min-width:0!important;margin-bottom:8px;white-space:normal!important;padding-right:0}
.form-horizontal .f-item.pc-item #pc-rows{width:100%}
.form-horizontal .f-item.pc-item #pc-addrow{margin-top:2px}

/* ===== 考勤机接入（att-device） ===== */
.att-stat-bar{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin:14px 0 12px}
.att-stat-card{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:12px 14px;display:flex;flex-direction:column;gap:2px;box-shadow:var(--shadow)}
.att-stat-card .n{font-size:24px;font-weight:700;line-height:1.2;color:var(--slate);font-variant-numeric:tabular-nums}
.att-stat-card .t{font-size:12px;color:var(--sub)}
.att-stat-dev{grid-column:1/-1;font-size:12.5px;color:var(--sub)}
.att-stat-sk{grid-column:1/-1;font-size:13px;color:var(--sub);padding:6px 2px}
.att-tabs{display:flex;gap:6px;border-bottom:1px solid var(--border);margin-bottom:14px;flex-wrap:wrap}
.at-tab{display:inline-flex;align-items:center;gap:6px;padding:9px 14px;border:none;background:transparent;color:var(--sub);
  font-size:14px;font-weight:500;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;border-radius:10px 10px 0 0}
.at-tab svg{width:16px;height:16px}
.at-tab:hover{color:var(--primary);background:rgba(30,90,200,.06)}
.at-tab.on{color:var(--primary);border-bottom-color:var(--primary);font-weight:600}
.at-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;
  border-radius:999px;background:var(--red);color:#fff;font-size:11px;font-weight:600;margin-left:2px}
.att-dir{display:inline-block;padding:2px 8px;border-radius:999px;font-size:12px;font-weight:600;white-space:nowrap}
.att-dir.in{background:var(--green-l);color:var(--green)}
.att-dir.out{background:var(--orange-l);color:var(--orange)}
.att-dir.unk{background:#F1F3F6;color:var(--sub)}
.att-ms{display:inline-block;padding:2px 8px;border-radius:999px;font-size:12px;white-space:nowrap}
.att-ms.ok{background:var(--green-l);color:var(--green)}
.att-ms.bad{background:var(--red-l);color:var(--red)}
.att-ms.ig{background:#F1F3F6;color:var(--sub)}
.att-ds{display:inline-block;padding:2px 8px;border-radius:999px;font-size:12px;font-weight:600;white-space:nowrap}
.att-ds.on{background:var(--green-l);color:var(--green)}
.att-ds.off{background:#F1F3F6;color:var(--sub)}
.att-ds.err{background:var(--red-l);color:var(--red)}
.att-ds.unc{background:var(--orange-l);color:var(--orange)}
.att-mode{display:inline-block;padding:2px 8px;border-radius:999px;font-size:12px;white-space:nowrap}
.att-mode.push{background:var(--primary-l);color:var(--primary)}
.att-mode.pull{background:#F0EAFF;color:#722ED1}
.att-unc-box{border:1px solid #FFD9A8;background:var(--orange-l);border-radius:12px;padding:12px 14px;margin-bottom:12px}
.att-unc-title{font-size:13.5px;font-weight:600;color:var(--orange);margin-bottom:8px;display:flex;align-items:center;gap:6px}
.att-unc-row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:6px 0;font-size:13px;flex-wrap:wrap}
.att-dev-pick{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:10px}
.att-pick-card{border:1.5px solid var(--border-d);border-radius:12px;padding:12px 14px;cursor:pointer;transition:.15s;background:var(--card)}
.att-pick-card:hover{border-color:var(--primary);box-shadow:0 2px 10px rgba(30,90,200,.12);transform:translateY(-1px)}
.att-pick-card .pn{font-size:14px;font-weight:600;color:var(--slate);margin-bottom:4px}
.att-pick-card .pd{font-size:12px;color:var(--sub);line-height:1.5}
.att-guide{background:#F6F8FB;border:1px solid var(--border);border-radius:12px;padding:10px 12px;font-size:12.5px;
  color:var(--slate);line-height:1.7;margin:8px 0;white-space:pre-wrap;word-break:break-all}
.att-fld{width:100%;height:38px;border:1px solid var(--border-d);border-radius:10px;padding:0 10px;font-size:14px;box-sizing:border-box;background:#fff}
textarea.att-fld{height:auto;padding:8px 10px;line-height:1.6;font-family:inherit;resize:vertical}
select.att-fld{padding:0 8px}
.att-fld:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--ring)}
.pager-bar{display:flex;align-items:center;justify-content:center;gap:14px;padding:12px;font-size:13px;color:var(--sub)}
.pager-bar .btn.sm{min-width:72px}
@media (max-width:768px){
  .att-stat-bar{grid-template-columns:repeat(2,1fr)}
  .att-tabs{overflow-x:auto;flex-wrap:nowrap}
  .at-tab{white-space:nowrap}
  .att-dev-pick{grid-template-columns:1fr}
}

/* ==================== 移动端 App 化 ==================== */
.m-more-btn{display:none}
#m-tabbar{display:none}
@media (min-width:769px){
  #m-tabbar,#m-allfn{display:none}
}
@media (max-width:768px){
  .m-more-btn{display:flex;background:none;border:none;color:var(--sub);cursor:pointer;width:44px;height:44px;align-items:center;justify-content:center}
  #hamburger{display:none}
  #proj-new-btn{display:none}
  .user-chip .avatar,.user-chip .uemail{display:none}
  #topbar .proj-pick .lbl{display:none}
  #topbar .proj-pick{flex:1;min-width:0;overflow:hidden}
  #topbar .proj-pick .proj-select{font-size:16px;font-weight:600;color:var(--text);background:transparent;border:none;box-shadow:none;padding:0;height:44px;min-width:0;width:100%;max-width:64vw}
  #topbar{height:52px;border-bottom:1px solid var(--border);background:#fff}
  #content{padding-bottom:78px}
  /* 底部 Tab 栏 */
  #m-tabbar{position:fixed;left:0;right:0;bottom:0;height:58px;background:#fff;border-top:1px solid var(--border);display:flex;z-index:900;padding-bottom:env(safe-area-inset-bottom)}
  #m-tabbar .m-tab{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;background:none;border:none;color:#8A94A6;font-size:11.5px;cursor:pointer;padding:4px 0}
  #m-tabbar .m-tab .m-tab-ic{width:24px;height:24px;display:flex;align-items:center;justify-content:center}
  #m-tabbar .m-tab .m-tab-ic svg{width:22px;height:22px}
  #m-tabbar .m-tab.active{color:var(--primary);font-weight:600}
  #m-tabbar .m-tab.active .m-tab-ic{background:var(--primary-l);border-radius:var(--radius-s)}
  /* 全部功能浮层 */
  #m-allfn{position:fixed;inset:0;background:var(--bg);z-index:950;display:flex;flex-direction:column}
  #m-allfn[hidden]{display:none}
  .m-allfn-head{height:52px;display:flex;align-items:center;justify-content:space-between;padding:0 16px;background:#fff;border-bottom:1px solid var(--border);font-size:16px;font-weight:600;color:#1B2333}
  #m-allfn-close{background:none;border:none;color:#333;cursor:pointer;display:flex;padding:4px}
  #m-allfn-body{flex:1;overflow-y:auto;padding:16px 16px 90px}
  .m-af-grp{margin-bottom:16px}
  .m-af-title{font-size:13.5px;color:#8A94A6;margin:0 4px 8px;font-weight:500}
  .m-af-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
  .m-af-item{display:flex;flex-direction:column;align-items:center;gap:8px;background:#fff;border:none;border-radius:var(--radius-lg);padding:16px 4px;box-shadow:var(--shadow);cursor:pointer}
  .m-af-ic{width:40px;height:40px;display:flex;align-items:center;justify-content:center;color:var(--primary);background:var(--primary-l);border-radius:var(--radius)}
  .m-af-ic svg{width:19px;height:19px}
  .m-af-tx{font-size:11.5px;color:#333}
  /* 手机版工作台 */
  .m-dash{padding:0 16px 16px}
  .m-hero{background:linear-gradient(135deg,#2E66F0 0%,#15419A 100%);border-radius:var(--radius-lg);padding:16px 16px 16px;color:#fff;margin-top:12px;box-shadow:0 10px 24px rgba(30,90,200,.26)}
  .m-hero-top{display:flex;justify-content:space-between;align-items:center}
  .m-hero-date{font-size:12.5px;opacity:.92}
  .m-hero-bell{position:relative;background:rgba(255,255,255,.16);border:none;color:#fff;width:40px;height:40px;border-radius:var(--radius);display:flex;align-items:center;justify-content:center;cursor:pointer}
  .m-bell-dot{position:absolute;top:-5px;right:-6px;background:#FF3B30;color:#fff;font-size:11.5px;font-weight:700;min-width:18px;height:18px;border-radius:999px;display:flex;align-items:center;justify-content:center;padding:0 4px;box-shadow:0 0 0 2px #15419A}
  .m-hero-name{font-size:19px;font-weight:700;margin-top:8px}
  .m-hero-addr{font-size:12.5px;opacity:.85;margin-top:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .m-hero-stats{display:flex;margin-top:16px;background:rgba(255,255,255,.14);border-radius:var(--radius);padding:8px 8px}
  .m-hs{flex:1;text-align:center}
  .m-hs-v{font-size:19px;font-weight:700}
  .m-hs-l{font-size:11.5px;opacity:.9;margin-top:4px}
  .m-sec-title{font-size:15px;font-weight:600;color:#333;margin:16px 4px 8px;display:flex;align-items:center;gap:8px}
  .m-sec-title::before{content:'';width:4px;height:14px;border-radius:4px;background:var(--primary)}
  .m-task-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
  .m-task{display:flex;flex-direction:column;align-items:flex-start;gap:4px;background:#fff;border:none;border-radius:var(--radius-lg);padding:12px 16px;box-shadow:var(--shadow);text-align:left;cursor:pointer}
  .m-task-ic{width:40px;height:40px;display:flex;align-items:center;justify-content:center;color:var(--primary);background:var(--primary-l);border-radius:var(--radius)}
  .m-task-ic svg{width:20px;height:20px}
  .m-task-nm{font-size:15px;font-weight:600;color:#222}
  .m-task-sub{font-size:11.5px;color:#8A94A6}
  .m-quick-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
  .m-quick{display:flex;flex-direction:column;align-items:center;gap:8px;background:#fff;border:none;border-radius:var(--radius-lg);padding:12px 4px;box-shadow:var(--shadow);cursor:pointer}
  .m-quick-ic{width:40px;height:40px;display:flex;align-items:center;justify-content:center;color:var(--primary);background:var(--primary-l);border-radius:var(--radius)}
  .m-quick-ic svg{width:18px;height:18px}
  .m-quick-tx{font-size:11.5px;color:#333}
  .m-allfn-entry{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;margin-top:16px;background:#fff;border:none;border-radius:var(--radius-lg);padding:16px;box-shadow:var(--shadow);font-size:13.5px;font-weight:600;color:var(--primary);cursor:pointer}
  .m-allfn-entry svg{width:18px;height:18px}
}

/* ============ 手机端 v0.4：工作台 + 人员档案卡片 ============ */
@media (max-width:768px){
  #content,main{background:var(--bg)}
  section[data-page]{background:transparent}
  #m-tabbar .m-tab.active{color:var(--primary)}
  /* ---- 工作台：轻量顶栏 ---- */
  .m-dash{padding:8px 12px 16px}
  .m-topline{display:flex;align-items:baseline;gap:8px;padding:4px 4px 0}
  .m-top-region{font-size:12.5px;color:var(--faint);flex:none}
  .m-top-name{font-size:13.5px;color:var(--text);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .m-topdate{font-size:12.5px;color:var(--faint);margin:4px 4px 8px}
  /* ---- 统计条 ---- */
  .m-stats{display:flex;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:12px 0;box-shadow:var(--shadow)}
  .m-stat{flex:1;text-align:center;position:relative}
  .m-stat+.m-stat::before{content:'';position:absolute;left:0;top:18%;height:64%;width:1px;background:#E8EBF1}
  .m-stat-v{font-size:19px;font-weight:700;color:var(--text);line-height:1.2;font-variant-numeric:tabular-nums}
  .m-stat-l{font-size:12.5px;color:var(--sub);margin-top:4px}
  /* ---- 区块标题 ---- */
  .m-sec-head{display:flex;align-items:center;justify-content:space-between;margin:16px 4px 8px}
  .m-sec-head>span:first-child{font-size:15px;font-weight:600;color:var(--text)}
  .m-more-link{background:none;border:none;font-size:12.5px;color:var(--primary);cursor:pointer;padding:4px}
  .m-sec-sub{font-size:12.5px;color:var(--faint)}
  /* ---- 今日待办列表 ---- */
  .m-todos{display:flex;flex-direction:column;gap:8px}
  .m-todo{display:flex;align-items:center;gap:8px;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:12px 12px;text-align:left;cursor:pointer;width:100%;box-shadow:var(--shadow)}
  .m-todo-ic{width:40px;height:40px;flex:none;display:flex;align-items:center;justify-content:center;color:var(--primary);background:var(--primary-l);border-radius:var(--radius-s)}
  .m-todo-ic svg{width:18px;height:18px}
  .m-todo-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px;text-align:left}
  .m-todo-t{font-size:13.5px;font-weight:500;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .m-todo-s{font-size:12.5px;color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .m-todo-empty{background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:24px;text-align:center;font-size:13.5px;color:var(--faint)}
  /* ---- 状态标签 ---- */
  .m-tag{flex:none;font-size:11.5px;line-height:1.6;padding:1px 8px;border-radius:6px;white-space:nowrap}
  .m-t-blue{background:var(--primary-l);color:var(--primary)}
  .m-t-orange{background:#FFF4E5;color:#D9800F}
  .m-t-red{background:#FFEFED;color:#E54545}
  .m-t-green{background:#E8F8EF;color:#00A870}
  /* ---- 现场操作 4 卡 ---- */
  .m-ops{display:flex;gap:8px}
  .m-op{flex:1;display:flex;flex-direction:column;align-items:center;gap:8px;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:12px 4px;cursor:pointer;box-shadow:var(--shadow)}
  .m-op-ic{width:40px;height:40px;display:flex;align-items:center;justify-content:center;color:var(--primary);background:var(--primary-l);border-radius:var(--radius)}
  .m-op-ic svg{width:18px;height:18px}
  .m-op-tx{font-size:12.5px;color:var(--text)}
  /* ---- 常用功能 8 格 ---- */
  .m-quick-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
  .m-quick{display:flex;flex-direction:column;align-items:center;gap:8px;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:12px 4px;cursor:pointer;box-shadow:var(--shadow)}
  .m-quick-ic{width:40px;height:40px;display:flex;align-items:center;justify-content:center;color:var(--slate)}
  .m-quick-ic svg{width:20px;height:20px}
  .m-quick-tx{font-size:11.5px;color:var(--text)}
  /* ---- 全部功能入口 ---- */
  .m-allfn-card{display:flex;align-items:center;justify-content:space-between;width:100%;margin-top:16px;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:16px;font-size:15px;font-weight:600;color:var(--text);cursor:pointer;box-shadow:var(--shadow)}
  .m-allfn-cnt{display:flex;align-items:center;gap:4px;font-size:12.5px;font-weight:500;color:var(--faint)}
  .m-allfn-cnt svg{color:#B6BCC4}
  /* ---- 手机工作台 v2（信息架构对齐桌面端，防横滑：一律不写死 min-width） ---- */
  .md-dash{padding-top:12px}
  .md-hero{background:linear-gradient(135deg,#3A76F5 0%,#15419A 100%);border-radius:var(--radius-lg);padding:16px;color:#fff;box-shadow:0 10px 24px rgba(30,90,200,.24);position:relative;overflow:hidden}
  .md-hero-top{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}
  .md-hero-name{font-size:17px;font-weight:700;line-height:1.4;flex:1;min-width:0;word-break:break-all}
  .md-hero-bell{position:relative;flex:none;width:40px;height:40px;border:none;border-radius:var(--radius);background:rgba(255,255,255,.16);color:#fff;font-size:17px;display:flex;align-items:center;justify-content:center;cursor:pointer}
  .md-bell-dot{position:absolute;top:-6px;right:-7px;background:#FF3B30;color:#fff;font-size:11.5px;font-weight:700;min-width:18px;height:18px;border-radius:999px;display:flex;align-items:center;justify-content:center;padding:0 4px;box-shadow:0 0 0 2px #15419A}
  .md-hero-meta{font-size:12.5px;opacity:.92;margin-top:8px}
  .md-hero-plan{font-size:12.5px;opacity:.95;margin-top:4px}
  .md-hero-plan b{color:#FFD8D2!important;font-weight:600}
  .md-hero-units{display:flex;gap:8px 16px;margin-top:12px;padding-top:8px;border-top:1px solid rgba(255,255,255,.18);font-size:11.5px;opacity:.92;flex-wrap:wrap}
  .md-hero-units b{font-weight:500}
  .md-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
  .md-cardx{display:flex;flex-direction:column;align-items:flex-start;gap:4px;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:12px 12px;text-align:left;cursor:pointer;box-shadow:var(--shadow);min-width:0}
  .md-cx-ic{font-size:19px;line-height:1.2}
  .md-cx-lab{font-size:12.5px;color:var(--sub)}
  .md-cx-val{font-size:22px;font-weight:700;color:var(--text);line-height:1.2;font-variant-numeric:tabular-nums}
  .md-cx-val i{font-style:normal;font-size:11.5px;font-weight:500;color:var(--faint);margin-left:4px}
  .md-cx-sub{font-size:11.5px;color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
  .md-cardx.is-bad{border-color:#F6C8CB;background:#FFFBFA}
  .md-cardx.is-bad .md-cx-val{color:var(--red)}
  .md-card{background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:12px;box-shadow:var(--shadow)}
  .md-empty{font-size:12.5px;color:var(--faint);padding:8px 4px;text-align:center}
  .md-dglist{display:flex;flex-direction:column;gap:8px}
  .md-dgrow{display:flex;flex-direction:column;gap:4px;border:1px solid var(--border);border-left-width:3px;border-radius:var(--radius);padding:8px 12px;background:#fff;cursor:pointer;text-align:left;min-width:0}
  .md-dg-top{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
  .md-dg-next{margin-left:auto;font-size:11.5px;color:var(--orange);white-space:nowrap}
  .md-dg-name{font-size:13.5px;font-weight:500;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .md-dg-pills{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
  .md-pill{display:inline-flex;align-items:center;justify-content:center;min-width:56px;padding:4px 8px;border-radius:999px;font-size:11.5px;white-space:nowrap}
  .md-pill.warn{background:#FFEFED;color:var(--red)}
  .md-pill.ok{background:#E8F8EF;color:var(--green)}
  .md-pill.off{background:var(--tertiary);color:var(--faint)}
  .md-dg-owner{font-size:11.5px;color:var(--faint);white-space:nowrap}
  .md-wage-sum{font-size:22px;font-weight:700;color:var(--text);display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
  .md-wage-mom span{font-size:12.5px !important}
  .md-wage-tabs{display:inline-flex;border:1px solid var(--border);border-radius:var(--radius-s);overflow:hidden;margin:8px 0 8px;width:max-content;max-width:100%}
  .md-wage-tabs button{padding:4px 16px;font-size:12.5px;border:none;background:#fff;color:var(--sub);cursor:pointer}
  .md-wage-tabs button.on{background:var(--primary);color:#fff}
  .md-wage-tabs button+button{border-left:1px solid var(--border)}
  .md-wline{display:flex;align-items:baseline;padding:8px 4px;font-size:13.5px;border-bottom:1px dashed var(--border)}
  .md-wline:last-child{border-bottom:none}
  .md-wl-name{color:var(--slate);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .md-wl-amt{font-weight:600;font-variant-numeric:tabular-nums;color:var(--slate);flex:none;margin-left:8px}
  .md-risks{display:flex;flex-direction:column;gap:8px}
  .md-risk{display:flex;align-items:center;gap:12px;border:1px solid #F6C8CB;background:#FFF5F5;border-radius:var(--radius);padding:12px 12px;cursor:pointer;text-align:left;min-width:0}
  .md-risk-ic{width:40px;height:40px;flex:none;display:flex;align-items:center;justify-content:center;background:#fff;border-radius:var(--radius-s);font-size:17px}
  .md-risk-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}
  .md-risk-t{font-size:13.5px;font-weight:600;color:var(--red);display:flex;align-items:center;gap:8px}
  .md-risk-t b{font-size:15px}
  .md-risk-s{font-size:11.5px;color:var(--red);opacity:.75}
  .md-risk-arr{color:var(--red);font-size:15px;flex:none}
  .md-warns{display:flex;flex-direction:column;gap:8px;margin-bottom:16px}
  .md-warns .warn-item .btn{align-self:flex-start}
  .md-dash .m-sec-head:first-of-type{margin-top:16px}
  /* ============ 人员档案 ============ */
  .m-workers{padding:8px 12px 16px}
  /* 新增人员大卡片 */
  .m-bigcard{display:flex;align-items:center;justify-content:space-between;width:100%;border:none;border-radius:var(--radius-lg);padding:16px;cursor:pointer}
  .m-bc-blue{background:linear-gradient(120deg,#4A7DF2 0%,#1E5AC8 58%,#15419A 100%);color:#fff;box-shadow:0 8px 18px rgba(30,90,200,.26);text-align:left}
  .m-bc-main{display:flex;flex-direction:column;gap:4px;text-align:left}
  .m-bc-t{font-size:16px;font-weight:700}
  .m-bc-s{font-size:12.5px;opacity:.88}
  .m-bc-ic{width:42px;height:42px;flex:none;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.2);border-radius:var(--radius)}
  .m-bc-ic svg{width:22px;height:22px;color:#fff}
  /* 小操作行 */
  .m-mini-ops{display:flex;gap:8px;margin:8px 0}
  .m-mini{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:8px 4px;cursor:pointer;box-shadow:var(--shadow)}
  .m-mini svg{width:17px;height:17px;color:var(--slate)}
  .m-mini span{font-size:11.5px;color:var(--slate)}
  /* 搜索 + 分段 */
  /* min-height 44 + input 撑满交叉轴：原来 input 只有 ~21px，上下各 8px padding 是点不到的死区 */
  .m-search{display:flex;align-items:center;gap:8px;min-height:44px;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:0 12px;color:var(--faint);margin-bottom:8px;box-shadow:var(--shadow)}
  .m-search input{flex:1;align-self:stretch;border:none;outline:none;background:transparent;font-size:13.5px;color:var(--text);min-width:0}
  .m-seg{display:flex;background:#E9EDF2;border-radius:var(--radius);padding:4px;margin-bottom:12px}
  .m-seg-btn{flex:1;min-height:40px;border:none;background:transparent;font-size:13.5px;color:var(--sub);padding:8px 0;border-radius:var(--radius-s);cursor:pointer}
  .m-seg-btn.on{background:#fff;color:var(--text);font-weight:600;box-shadow:0 1px 3px rgba(27,35,51,.10)}
  /* 人员卡片列表 */
  .m-wlist{display:flex;flex-direction:column;gap:8px}
  .m-wcard{display:flex;align-items:center;gap:8px;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:12px 12px;width:100%;text-align:left;cursor:pointer;box-shadow:var(--shadow)}
  .m-wavatar{width:40px;height:40px;flex:none;border-radius:50%;background:var(--primary-l);color:var(--primary);font-size:15px;font-weight:600;display:flex;align-items:center;justify-content:center}
  .m-wmain{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px;text-align:left}
  .m-wname{font-size:15px;font-weight:600;color:var(--text);display:flex;align-items:center;gap:4px}
  .m-wsub{font-size:12.5px;color:var(--sub);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .m-badge{font-size:11.5px;padding:0 4px;border-radius:4px;line-height:1.6}
  .m-b-red{background:#FFEFED;color:#E54545}
  .m-b-gray{background:#F0F1F2;color:var(--faint)}
  .m-loadmore{width:100%;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:12px;font-size:13.5px;color:var(--primary);cursor:pointer;margin-top:8px;box-shadow:var(--shadow)}
}

/* ============ 手机端 v0.4：隐患 / 机械 / 考勤 / 登录 ============ */
@media (max-width:768px){
  .m-inspect,.m-equip,.m-att{padding:8px 12px 24px}
  /* 页面头 */
  .m-pagehead{display:flex;align-items:baseline;justify-content:space-between;gap:8px;padding:4px 4px 8px}
  .m-pagehead-t{font-size:19px;font-weight:700;color:var(--text)}
  .m-pagehead-c{font-size:12.5px;color:var(--faint);white-space:nowrap}
  /* CTA 橙 / 绿 */
  .m-bc-orange{background:linear-gradient(120deg,#FFB257 0%,#FF8F03 58%,#F07800 100%);color:#fff;box-shadow:0 8px 18px rgba(255,143,3,.28);text-align:left}
  .m-bc-green{background:linear-gradient(120deg,#35D0A5 0%,#12B886 58%,#089E73 100%);color:#fff;box-shadow:0 8px 18px rgba(18,184,134,.28);text-align:left}
  /* 隐患卡片 */
  .m-ilist,.m-elist{display:flex;flex-direction:column;gap:8px}
  .m-icard{display:flex;align-items:flex-start;gap:8px;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:12px;width:100%;text-align:left;cursor:pointer;box-shadow:var(--shadow)}
  .m-ic-ic{width:40px;height:40px;flex:none;border-radius:var(--radius-s);display:flex;align-items:center;justify-content:center}
  .m-ic-ic svg{width:18px;height:18px}
  .m-ic-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px;text-align:left}
  .m-ic-t{font-size:13.5px;font-weight:600;color:var(--text);line-height:1.4}
  /* ★ 2026-10-12「重大事故隐患」标记（手机隐患卡片标题后的小红标，与桌面列表的红点同语义） */
  .m-major-tag{display:inline-block;margin-left:6px;padding:1px 6px;border-radius:4px;background:var(--red);color:#fff;font-size:10.5px;font-weight:600;line-height:1.5;vertical-align:1px;white-space:nowrap}
  /* ★ 2026-10-20：一般隐患也打标（桌面有「事故类型」列，手机原来只有重大才有标） */
  .m-major-tag.m-normal-tag{background:#EEF2F7;color:#5B6678}
  .m-ic-s{font-size:11.5px;color:var(--faint);line-height:1.4}
  .m-ic-green .m-ic-ic{background:#E8F8EF;color:#00A870}
  .m-ic-blue .m-ic-ic{background:var(--primary-l);color:var(--primary)}
  .m-ic-orange .m-ic-ic{background:#FFF4E5;color:#D9800F}
  .m-ic-red .m-ic-ic{background:#FFEFED;color:#E54545}
  /* 机械卡片 */
  .m-ecard{display:flex;flex-direction:column;gap:4px;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:12px;width:100%;text-align:left;cursor:pointer;box-shadow:var(--shadow)}
  .m-ec-top{display:flex;align-items:center;justify-content:space-between;gap:8px}
  .m-ec-name{font-size:13.5px;font-weight:600;color:var(--text);min-width:0;line-height:1.4}
  .m-ec-s{font-size:11.5px;color:var(--faint);line-height:1.4}
  /* 奖惩 / 周月 actions 容器 */
  .m-si-actions{display:flex;gap:8px;margin-bottom:8px;flex-wrap:wrap}
  .m-si-actions .btn{flex:1;padding:8px 8px;font-size:13.5px}
  /* 低频台账窄屏横向滚动兜底 */
  #m-isec-body .table-wrap,#m-att-box .table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
  /* 考勤 */
  .m-att-stats{display:flex;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:12px 0;box-shadow:var(--shadow)}
  .m-att-stat{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;position:relative}
  .m-att-stat+.m-att-stat::before{content:'';position:absolute;left:0;top:18%;height:64%;width:1px;background:#E8EBF1}
  .m-att-v{font-size:19px;font-weight:700;line-height:1.2;font-variant-numeric:tabular-nums}
  .m-att-l{font-size:12.5px;color:var(--sub)}
  .m-att-export{width:100%;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:8px;font-size:13.5px;color:var(--primary);cursor:pointer;margin-bottom:8px;box-shadow:var(--shadow)}
  .m-att-seg{margin-bottom:12px}
  #m-att-box .att-input-card .att-actions{flex-wrap:wrap}
  /* 登录页：精简品牌头部 */
  #auth-view{flex-direction:column}
  /* 手机端登录页顶块：起点改**纯白**（同 2026-10-10 状态栏口径），往下再过渡到原来的淡蓝/灰底 */
  .auth-brand{display:flex;flex:0 0 auto;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:36px 16px 24px;background:linear-gradient(180deg,#FFFFFF 0%,#E7EEFE 46%,#F3F5F9 100%);border-right:none}
  .auth-brand .grid-lines,.auth-brand .auth-hero,.auth-brand .auth-feats{display:none}
  .auth-brand .brand-logo{flex-direction:column;gap:12px;font-size:19px;color:var(--text)}
  .auth-brand .brand-logo .logo-mark{width:64px;height:64px;border-radius:var(--radius-lg)}
  /* ★ 2026-10-11：手机端登录/注册表单比一屏高（注册多出「验证码 + 单位类型」两项），
     面板改为**不被压缩**（flex:0 0 auto）⇒ 高度随内容长，由 #auth-view 整层上下滑
     （内部再做一个滚动容器会出现「双层滚动」的怪手感）。
     底部留出安全区 + 24px，滚到底时「注册并登录」不会被 Android home 横条 / iOS 横条盖住
     （--sab 属 design-system 第二节允许的「功能性越档数值」）。 */
  .auth-panel{flex:0 0 auto;align-items:flex-start;padding:16px 16px calc(24px + var(--sab));background:transparent}
  .auth-card{border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);width:100%;max-width:420px;padding:24px 16px;margin:0 auto;background:#fff}
}

/* ===== 手机端统一汉堡抽屉（定稿） ===== */
#side-foot-mail,#side-logout-btn{display:none}
@media (max-width:768px){
  #side-foot-mail{display:block}
  #side-logout-btn{display:flex}
  #m-tabbar{display:none !important}
  .m-more-btn{display:none !important}
  #m-allfn{display:none !important}
  .user-chip{display:none !important}
  #hamburger{display:flex !important}
  .proj-pick{flex:1;min-width:0}
  .proj-pick .lbl{display:none}
  #proj-select{max-width:100%;font-size:13.5px}
  #sidebar{width:min(288px,84vw)}
  #sidebar .nav-item{padding:12px 16px 12px 16px;font-size:15px;border-radius:var(--radius);margin-bottom:4px}
  #sidebar .nav-group{padding:16px 12px 8px;font-size:11.5px}
  #sidebar .side-foot{padding:12px 14px calc(14px + env(safe-area-inset-bottom))}
  .side-foot-tip{font-size:11.5px;color:var(--faint);line-height:1.6;margin-bottom:12px}
  .side-foot-mail{font-size:11.5px;color:var(--faint);word-break:break-all;margin-bottom:8px}
  .side-logout-btn{width:100%;height:44px;border-radius:var(--radius);border:1px solid #F6C8CB;background:#fff;color:var(--red);font-size:15px;font-weight:600;display:flex;align-items:center;justify-content:center;gap:8px;cursor:pointer}
  .side-logout-btn:active{background:var(--red-l)}
  #content{padding-bottom:16px !important}
}

/* ============ 通用移动端卡片列表 ============ */
@media (max-width:768px){
  .m-clist-wrap{padding:8px 12px 24px;display:flex;flex-direction:column;gap:12px}
  .m-clist{display:flex;flex-direction:column;gap:12px}
  /* 统一头部控件间距：清除各自 margin，交由 wrap 的 gap 统一控制 */
  .m-clist-wrap>.m-pagehead{padding-bottom:0}
  .m-clist-wrap>.m-bigcard{margin:0}
  .m-clist-wrap>.m-search{margin:0}
  .m-clist-wrap>.m-seg{margin:0}
  .m-clist-wrap>.m-filters{margin:0}
  .m-clist-wrap>.m-loadmore{margin:0}
  .m-ccard{display:flex;align-items:flex-start;gap:8px;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:12px;width:100%;text-align:left;cursor:pointer;box-shadow:var(--shadow)}
  .m-ccard:active{background:#F7F9FC}
  .m-cav{width:40px;height:40px;flex:none;border-radius:50%;background:var(--primary-l);color:var(--primary);font-size:15px;font-weight:600;display:flex;align-items:center;justify-content:center}
  .m-cmain{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px;text-align:left}
  .m-cname{font-size:15px;font-weight:600;color:var(--text);display:flex;align-items:center;gap:8px;flex-wrap:wrap;line-height:1.4}
  .m-csub{font-size:12.5px;color:var(--sub);line-height:1.4}
  .m-cmeta{display:flex;flex-direction:column;gap:4px;margin-top:4px}
  .m-cmeta-row{font-size:11.5px;color:var(--faint);line-height:1.4;display:flex;gap:8px}
  .m-cmk{color:#A3A8B0;flex:none;min-width:48px}
  .m-cbadges{display:flex;flex-direction:column;align-items:flex-end;gap:4px;flex:none}
  .m-filters{display:flex;gap:8px;margin-bottom:8px;flex-wrap:wrap}
  .m-filters select{flex:1;min-width:0;height:44px;border:1px solid var(--border);border-radius:var(--radius-s);padding:0 8px;font-size:16px;background:#fff;color:var(--text)}
  /* 卡片内状态条配色（与 m-t-* 一致） */
  .m-ccard .m-badge{font-size:11.5px;padding:0 4px;border-radius:4px;line-height:1.6}
}

/* ===== 全站手机页头部控件统一间距 ===== */
@media (max-width:768px){
  /* 列表型手机页容器统一改为纵向 flex，由 gap 控制间距 */
  .m-workers,.m-att,.m-inspect,.m-equip{display:flex;flex-direction:column;gap:12px}
  /* 清除容器内控件自身 margin */
  .m-workers>.m-bigcard,.m-workers>.m-mini-ops,.m-workers>.m-search,.m-workers>.m-seg,.m-workers>.m-wlist,.m-workers>.m-loadmore,
  .m-att>.m-att-stats,.m-att>.m-att-export,.m-att>.m-seg,.m-att>#m-att-box,
  .m-inspect>.m-pagehead,.m-inspect>.m-seg,.m-inspect>#m-isec,
  .m-equip>.m-pagehead,.m-equip>.m-bigcard,.m-equip>.m-search,.m-equip>.m-elist,.m-equip>.m-loadmore{margin:0}
  .m-workers>.m-pagehead,.m-inspect>.m-pagehead,.m-equip>.m-pagehead{padding-bottom:0}
  /* 隐患页 #m-isec 是嵌套容器，也要纵向布局并清除内部控件 margin */
  .m-inspect #m-isec{display:flex;flex-direction:column;gap:12px}
  .m-inspect #m-isec>.m-bigcard,.m-inspect #m-isec>.m-search,.m-inspect #m-isec>.m-filters,.m-inspect #m-isec>.m-ilist,.m-inspect #m-isec>.m-loadmore{margin:0}
  .m-inspect .m-si-actions{margin:0}
  /* 卡片列表内部间距统一 12px */
  .m-wlist,.m-ilist,.m-elist{gap:12px}
  /* —— 文字完整显示修复 —— */
  .m-wsub{white-space:normal;overflow:visible;text-overflow:clip;word-break:break-word}
  .m-todo-t,.m-todo-s,.m-hero-addr{white-space:normal;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}
  .m-ccard{flex-wrap:wrap}
  .m-cmain{flex:1 1 210px;min-width:210px}
  .m-cbadges{flex:1 1 auto;flex-direction:row;align-items:center;justify-content:flex-end;flex-wrap:wrap;row-gap:4px}
  .m-cmeta-row>span:last-child{flex:1;min-width:0;word-break:break-word}
  .m-csub,.m-cname{word-break:break-word}
}

/* ============ iPhone / Android / PWA 兼容层 ============ */
/* 刘海屏/挖孔屏安全区：standalone 与 Android 沉浸式 fullscreen 两种模式都避开状态栏 */
@media (display-mode:standalone),(display-mode:fullscreen){
  #topbar{padding-top:env(safe-area-inset-top);height:calc(58px + env(safe-area-inset-top))}
  #auth-view{padding-top:env(safe-area-inset-top)}
  #sidebar{padding-top:env(safe-area-inset-top)}
}
@media (display-mode:standalone) and (max-width:768px),(display-mode:fullscreen) and (max-width:768px){
  #topbar{height:calc(52px + env(safe-area-inset-top))}
}
/* 触摸设备：去掉粘性 hover 残留 */
@media (hover:none){
  .card:hover{box-shadow:var(--shadow)}
  .stat-card:hover{transform:none}
}

/* ============ 登录后「选择入口」页（2026-09-30）============ */
.entry-card{background:var(--card);border:1.5px solid var(--border);border-radius:12px;padding:22px 18px;transition:all .18s ease}
.entry-card:hover{border-color:var(--accent,var(--primary));box-shadow:0 6px 18px rgba(0,0,0,.08);transform:translateY(-2px)}
.identity-opt:hover{border-color:var(--accent,var(--primary));background:#f8faff}

/* ============ 手机端可用性修复（2026-10-01 移动端体检）============
   三条都是「自动化布局检查查不到、真机上一定难受」的问题，见 .workbuddy/docs/手机端方案-20261001.md */

/* ① iOS 输入框聚焦自动放大：Safari 规定 font-size < 16px 的输入控件聚焦即整页 zoom。
      实测手机端 14px/13.5px 遍地（.f-item input 13.5px、.m-search input 13.5px…），
      且它们特异性都高于裸 `input` ⇒ 必须用 !important 一次压住（排除勾选框/单选框）。 */
@media (max-width:768px){
  input:not([type=checkbox]):not([type=radio]),select,textarea{font-size:16px!important}

  /* ② 点按目标抬高：手指点得准（Apple HIG 建议 44，折中取 38~40 兼顾一屏信息量） */
  .btn.sm{height:40px;padding:0 16px;font-size:13.5px}
  .pager-bar .btn.sm{min-width:76px}
  .modal-close{width:40px;height:40px}
  .m-seg-btn{padding:8px 0;font-size:13.5px}

  /* ③ 动态视口高度：移动浏览器/微信 WebView 里 100vh 是「地址栏收起时」的高度，
        地址栏一展开就把底部内容顶出屏幕（历史事故：抽屉底部按钮被裁）。
        保留 100vh 作老内核回落，新版自动用 100dvh。 */
  #app-view{height:100vh;height:100dvh}
  section[data-page="safety_inspection"]{height:calc(100vh - 58px - 44px);height:calc(100dvh - 58px - 44px)}
  .table-wrap{max-height:calc(100vh - 330px);max-height:calc(100dvh - 330px)}

  /* ④ 底部安全区：全面屏底部横条不再压住最后一行的按钮 */
  #content{padding-bottom:calc(18px + env(safe-area-inset-bottom))!important}
}

/* 手机端大卡片上的相机角标：从「装饰」升级成「独立可点入口」（2026-10-01 用户要求）
   点它 = 直接进系统取图（拍照 / 相册），不再需要先点整卡进表单再找「上传正面」 */
@media (max-width:768px){
  .m-bc-cam{min-width:44px;min-height:44px;cursor:pointer;background:rgba(255,255,255,.34);
            box-shadow:inset 0 0 0 1px rgba(255,255,255,.5);transition:transform .12s ease,background .12s ease}
  .m-bc-cam:active{transform:scale(.9);background:rgba(255,255,255,.72)}
}

/* ⚠ 特异性陷阱（2026-10-01 踩过）：styles.css 里有一批「紧凑表单」规则用了
   `.form-horizontal select{font-size:14px!important}` / `.form-horizontal input:not(…)×4{font-size:14px!important}`
   —— 特异性 (0,5,1)+!important，**同级 !important 比特异性**，会压过上面那条通用的
   `input,select,textarea{font-size:16px!important}`(0,2,1) ⇒ 弹窗里的输入框仍是 14px，
   iOS 照样聚焦放大。这里用「等特异性 + 排在文件更后面」压回去（同分则后写者胜）。 */
@media (max-width:768px){
  .form-horizontal input[type="date"],
  .form-horizontal input:not([type="date"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]),
  .form-horizontal select,
  .form-horizontal textarea,
  .mc-input{font-size:16px!important}
}

/* ============ 手机端触摸目标与几何收口（2026-10-08）============
   上面那段只解决了「字号」，紧凑表单的 32px 高度仍是桌面尺寸 —— 手机上手指点不准。
   这里用同一套「等特异性 + 靠后」策略把高度抬到 44，并把圆角收回令牌体系。
   ⚠ 必须留在文件最末尾：同分选择器后写者胜，挪到前面就会被桌面紧凑表单的 !important 压过。 */
@media (max-width:768px){
  .form-horizontal select,
  .form-horizontal input[type="date"],
  .form-horizontal input:not([type="date"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]){
    height:44px!important;min-height:44px!important;line-height:44px!important;
    border-radius:var(--radius-s)!important;
  }
  /* textarea 是多行，不能吃 44px 的行高 */
  .form-horizontal textarea{
    height:auto!important;min-height:88px!important;line-height:1.4!important;
    padding:10px 12px!important;border-radius:var(--radius-s)!important;
  }
  /* 多选控件与行内按钮同高 */
  .form-horizontal .mc-control{min-height:44px}
  .form-horizontal .f-item>div .btn,.form-horizontal .f-item .btn{min-height:44px}

  /* 登录页：密码显隐按钮（原 32×32 / 圆角 6，是全站唯一漏网的 6px）与「忘记密码」文字链接 */
  .field .ipt .pwd-eye-btn{width:40px;height:40px;right:4px;border-radius:var(--radius-s)}
  #auth-pwd{padding:0 48px 0 38px!important}
  .link-btn{min-height:40px;padding:0 8px;display:inline-flex;align-items:center}

  /* ---------- 业务页实测补漏（390px × 18 页逐个量过） ---------- */
  /* 分段页签：全局 32px，手机端偏小（.seg-tabs 与 .ft2-seg 同为分段控件，口径一致） */
  .seg-tab{height:40px}
  /* 内联写死高度的小控件：内联样式没有 !important，所以此处 !important 能压过它。
     考勤年月选择器（app-main.js:10121）、变更历史筛选（:14197）、项目管理绑定（:13167）
     原本都是 30/34px + 6px 圆角 —— 全站最后一处 6px 圆角就在这里。 */
  #cal-year,#cal-month,#hs-act,.mb-bind{height:40px!important;border-radius:var(--radius-s)!important;padding:0 8px!important}
  /* 原内联字号 12.5/13px，同样会触发 iOS 聚焦整页放大，一并提到 16 */
  #cal-year,#cal-month,.mb-bind{font-size:16px!important}
  /* 弹窗内「添加照片」类小按钮：内联 height:30px（app-main.js:1925/1936/1946/1954） */
  #mr-ev-add{height:40px!important}
  /* 成员卡片「部门·职位」：内联 11px，手机端提到可读下限 */
  .mbr-sub{font-size:12.5px!important}

  /* ---------- 登录页（390px 实测补）---------- */
  /* 输入框 42 → 44：登录是手机端最高频入口，主控件按 44 给 */
  .auth-card .field input{height:44px}
  /* 单位类型选择器内联 font-size:14px —— 低于 16 会让 iOS 聚焦时整页放大，同样用 !important 压 */
  #auth-unit{font-size:16px!important}
  /* 「获取验证码」原来只有约 26px 高；抬到 40 且不破 44px 的输入框 */
  .code-btn{min-height:40px;padding:0 10px;right:4px;display:inline-flex;align-items:center}
  /* 「记住账号」整行可点 */
  .remember{min-height:40px;padding:4px 0}
  /* 登录 / 注册页签：加大纵向点击区 */
  .auth-tabs button{padding:12px 4px}
}

/* ==================== 设计稿落地 · 统计卡胶囊 / 待办竖条（2026-10-08）====================
   来源：2026-10-08-视觉底稿-v2「管理端v2」（A 方案蓝图蓝）。这几处是令牌层改不出来的、
   必须动渲染结构的部分。
   ⚠ 2026-10-08 晚：原「① 首屏问候（.dash-hello）」按用户要求整块删除（含 .h-sub / .h-main
   全部规则、app-main.js 里的 greetWord），项目总览改为直接从项目横幅开篇 —— 与手机端
   md-hero 开篇保持一致（手机端本来就没有这块）。 */
/* ① 统计卡辅助信息 → 语义胶囊（原来是一行灰字，状态完全看不出来） */
.stat-card .sub2{display:inline-flex;align-items:center;font-size:12px;font-weight:500;margin-top:10px;
  padding:3px 10px;border-radius:999px;background:var(--tertiary);color:var(--sub);line-height:1.6}
.stat-card .sub2.warn{background:var(--red-l);color:var(--red)}
.stat-card .sub2.ok{background:var(--green-l);color:var(--green)}
.stat-card .sub2.info{background:var(--primary-l);color:var(--primary)}

/* ③ 今日待办卡：左侧彩色竖条标优先级（设计稿里红/橙/蓝三条） */
[data-todo]:nth-child(3n+1){border-left:3px solid var(--red)!important}
[data-todo]:nth-child(3n+2){border-left:3px solid var(--orange)!important}
[data-todo]:nth-child(3n){border-left:3px solid var(--primary)!important}

/* ============================================================================
   手机端状态栏 / 安全区适配（2026-10-09）
   ----------------------------------------------------------------------------
   目标：iOS 刘海 / 灵动岛 与 Android 挖孔 / 状态栏都不遮挡内容，
   并且**保留系统状态栏本身**（时间、信号、电池那一条），不做沉浸式全屏覆盖。
   做法：
   ① 统一变量 --sat / --sab（顶部 / 底部安全区）。JS 会在 Android standalone
      下 env() 取不到值（=0px）时兜底补一个状态栏高度，见 app-main.js `initSafeArea`。
   ② #topbar / #auth-view / #sidebar / 「全部功能」浮层 各自让出 --sat：
      这几个容器都自带底色（白 / 渐变），让位后状态栏区域天然被自己的底色填满，
      不会露出页面灰底，也不会出现「灰条 + 白条」两层割裂。
   ③ theme-color 在手机端改为白色（index.html 按媒体查询拆分），
      系统状态栏底色与顶栏一致，时间/电量会自动转深色，仍然清晰可读。
   ⚠ 安全区属于 design-system 第二节允许的「功能性越档数值」，改动请连同注释一起改。
   ============================================================================ */
:root{
  --sat:env(safe-area-inset-top,0px);
  --sab:env(safe-area-inset-bottom,0px);
}
@media (max-width:768px){
  /* 顶栏：内高恒为 52px，安全区当额外 padding；背景白色直接铺到屏幕最顶端 */
  #topbar{padding-top:var(--sat);height:calc(52px + var(--sat))}
  /* 登录页（position:fixed;inset:0，自带渐变底） */
  #auth-view{padding-top:var(--sat)}
  /* 侧栏抽屉 */
  #sidebar{padding-top:var(--sat)}
  /* 「全部功能」浮层：只让头部让位，避免整层 padding 露出下层底色 */
  .m-allfn-head{height:calc(52px + var(--sat));padding-top:var(--sat)}
  /* 底部 Tab 栏 + 内容区底部留白：统一走变量，并留够 58px 的 Tab 栏高度 */
  #m-tabbar{padding-bottom:var(--sab)}
  #content{padding-bottom:calc(78px + var(--sab))!important}
  /* 隐患页是固定高度布局：58px 是桌面顶栏高（手机端本就是 52px），
     改成 52 + 安全区，否则刘海屏下内容会比可用空间多出一个状态栏高度 */
  section[data-page="safety_inspection"]{
    height:calc(100vh - 58px - 44px);
    height:calc(100dvh - 52px - var(--sat) - 44px);
  }
}

/* ============================================================================
   过渡动画（2026-10-09）
   ----------------------------------------------------------------------------
   用户口径：原来「点一下直接蹦出来」太生硬，要照 APP（UU 远程一类远程/工具类）的手感。
   节奏统一：位移 8~14px、时长 200~300ms、曲线 cubic-bezier(.22,.61,.36,1)（先快后缓）。
   全程只有 opacity / transform 参与 ⇒ 走合成层，不触发重排，低端机也不掉帧。
   ============================================================================ */
/* ① 页面切换（2026-10-09 统一）：原为「Tab 淡入 / 进二级页右推 / 返回左推」三套方向动画，
      不同入口观感不一、显得杂；现统一为单一「淡入 + 轻微上浮」，与 WorkBuddy 桌面端
      点击导航后的出现方式一致（无横向位移）。.pg-fwd / .pg-back 保留为兼容别名
      （旧版 HTML / SW 缓存可能残留 class），全部指向同一动画。 */
/* ⚠ 2026-10-10 更正：只动 opacity，**禁止再加 transform 关键帧**。
   原 `from{transform:translate3d(0,8px,0)}` + `fill-mode:both` 会让 section 的计算值变成
   `matrix(1,0,0,1,0,0)`（**不是** none）⇒ section 成为 `position:fixed` 后代的包含块，
   页内吸底条（.m-selbar）的 `bottom:0` 就落到 section 底部而不是视口底部：
   短列表时吸底条浮在屏幕中间、盖住卡片；长列表时更跑到整页最底、永远看不见。
   复现证据：.workbuddy/tools/_probe-selbar-fixed.mjs（带 .pg-fade → 条 bottom=3481；去掉 → 874＝视口底）。 */
@keyframes pgInFade{from{opacity:0}to{opacity:1}}
#content>section.pg-fade,
#content>section.pg-fwd,
#content>section.pg-back{animation:pgInFade .22s cubic-bezier(.22,.61,.36,1) both}

/* ② 弹窗：手机端改成「底部抽屉」上滑入场（APP 里最常见的二级面板形态），
      关闭时反向滑出 —— 由 app-main.js 的 closeModal 加 .closing 触发 */
@keyframes sheetUp{from{transform:translate3d(0,100%,0)}to{transform:none}}
@keyframes sheetDown{from{transform:none}to{transform:translate3d(0,100%,0)}}
@keyframes maskIn{from{opacity:0}to{opacity:1}}
@keyframes maskOut{from{opacity:1}to{opacity:0}}
@media (max-width:768px){
  .modal-mask{align-items:flex-end;justify-content:center;padding:0;animation:maskIn .22s ease both}
  .modal{width:100%;max-width:100%!important;max-height:92vh;max-height:92dvh;
         border-radius:20px 20px 0 0!important;animation:sheetUp .3s cubic-bezier(.22,.61,.36,1) both}
  /* 底部按钮区让开 home indicator，否则「确定/取消」会压在横条上 */
  .modal-foot{padding-bottom:calc(8px + var(--sab))!important}
  .modal-mask.closing{animation:maskOut .2s ease both}
  .modal-mask.closing .modal{animation:sheetDown .24s cubic-bezier(.4,0,.68,.2) both}
}
/* ③ 「全部功能」浮层：整层淡入上浮，网格项按分组依次入场 */
@keyframes allfnIn{from{opacity:0;transform:translate3d(0,14px,0)}to{opacity:1;transform:none}}
@keyframes afItem{from{opacity:0;transform:translate3d(0,10px,0) scale(.97)}to{opacity:1;transform:none}}
@media (max-width:768px){
  #m-allfn{animation:allfnIn .26s cubic-bezier(.22,.61,.36,1) both}
  .m-af-item{animation:afItem .3s cubic-bezier(.22,.61,.36,1) both}
  .m-af-grp:nth-child(1) .m-af-item{animation-delay:.02s}
  .m-af-grp:nth-child(2) .m-af-item{animation-delay:.06s}
  .m-af-grp:nth-child(3) .m-af-item{animation-delay:.10s}
  .m-af-grp:nth-child(n+4) .m-af-item{animation-delay:.14s}
}
/* ④ 点按回执：手指按下时轻微缩放，让「点到了」有反馈（仅触摸设备） */
@media (hover:none) and (max-width:768px){
  #m-tabbar .m-tab{transition:transform .14s ease,color .18s ease}
  #m-tabbar .m-tab:active{transform:scale(.92)}
  #m-tabbar .m-tab .m-tab-ic{transition:background .18s ease}
  .m-ccard,.m-af-item{transition:transform .14s ease}
  .m-ccard:active,.m-af-item:active{transform:scale(.985)}
}
/* ⑤ 无障碍：系统开启「减弱动态效果」时全部关掉（iOS 设置里很常开） */
@media (prefers-reduced-motion:reduce){
  #content>section,.modal,.modal-mask,#m-allfn,.m-af-item,.m-tab,.m-ccard{animation:none!important;transition:none!important}
}

/* ============================================================================
   「整行说明型勾选项」布局修复（2026-10-09）
   ----------------------------------------------------------------------------
   症状：编辑培训记录弹窗里，「把本次参训人员同步标记为『已教育』（回写人员档案…）」
   那段说明被压成**竖排**，每行只有一两个字。
   真因：第 412 行的 `.form-horizontal .f-item label{width:124px;min-width:124px}`
   是按「左标签 / 右控件」的横排表单设计的；这个 label 里装的是 checkbox + 一整句话，
   于是被硬限制在 124px 内，减去 checkbox(16) + gap(9) + padding-right(8) 只剩 ~90px。
   修法：让这类 label 占满整行（width:auto + flex:1），说明文字自己撑开并给足行高，
   checkbox 改顶部对齐（说明可能换行，居中会飘）。
   ⚠ 手机端不受影响（窄屏下 label 已被统一改成 width:auto!important）。
   ⚠ 以后凡是「checkbox + 长说明」的整行字段，都加 class="note-check"，不要只写内联 flex。
   ============================================================================ */
.form-horizontal .f-item>label.note-check{width:auto;min-width:0;flex:1;padding-right:0}
.form-horizontal .f-item>label.note-check>input[type=checkbox]{margin-top:1px;flex:none}
.form-horizontal .f-item>label.note-check>span{flex:1;min-width:0;line-height:1.7}
/* 同一个坑的另一副面孔：说明文字如果直接挂在 label 上（没有内层 span），也放开宽度 */
.form-horizontal .f-item>label.note-check{white-space:normal;overflow:visible}

/* ============================================================================
   手机端「工伤保险」增员 / 减员申报（2026-10-09 用户口径：手机也要能导出申报与减员）
   ----------------------------------------------------------------------------
   桌面端是「表格 + 吸底操作条」；手机端改成「卡片勾选 + 吸底主按钮」，
   勾选集合仍复用 injuryUI.sel、导出仍走 declareInjury，数据链路与留痕完全一致。
   类名统一 m-ij-* / m-selbar，避免与既有类冲突。
   ============================================================================ */
@media (max-width:768px){
  /* 台账页导出按钮：沿用「导出本月考勤汇总表」的观感，抽成通用名 */
  .m-exp-btn{width:100%;flex:1 1 100%;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:10px;font-size:13.5px;color:var(--primary);cursor:pointer;box-shadow:var(--shadow)}
  /* 勾选工具行：全选本页 / 清空勾选 / 已勾选计数 */
  .m-ij-tools{display:flex;align-items:center;gap:8px}
  .m-ij-mini{border:1px solid var(--border);background:#fff;border-radius:var(--radius-s);padding:7px 12px;font-size:13px;color:var(--text);cursor:pointer}
  .m-ij-mini:active{background:#F1F4F9}
  .m-ij-cnt{margin-left:auto;font-size:12.5px;color:var(--sub)}
  .m-ij-cnt b{color:var(--primary);font-size:14px}
  /* 勾选态卡片：主色描边 + 右上角对勾 */
  .m-ccard.sel{border-color:var(--primary);background:var(--primary-l)}
  .m-selmark{width:20px;height:20px;flex:none;border-radius:50%;background:var(--primary);color:#fff;font-size:12px;line-height:1;display:flex;align-items:center;justify-content:center}
  /* 吸底操作条（2026-10-10 用户口径：改成「底部悬浮」，不再压住列表）
     —— 四边留 --sp-3 边距 + 圆角 + 向上投影，视觉上「浮」在内容之上；底部再避让 home indicator（--sab）。
     ⚠ 必须 fixed 且**祖先不能有 transform**：
        ① 手机端底部 tabbar 已隐藏（#m-tabbar display:none !important），
           sticky 的 bottom 吸附点会落在 #content 的内容框底（带 78px 下内边距）⇒ 实测离屏幕底 78px；
        ② 祖先一旦有 transform，fixed 会被降级成「相对该祖先」⇒ 见上面 pgInFade 的更正。 */
  .m-selbar{position:fixed;left:var(--sp-3);right:var(--sp-3);bottom:calc(var(--sp-3) + var(--sab));
    z-index:50;   /* 高于页面内容（顶栏浮标 30 / 吸顶 29），低于侧栏遮罩 55、侧栏 60、弹窗 1000：抽屉打开时不该盖住抽屉 */
    padding:var(--sp-3);gap:var(--sp-2);
    background:#fff;border-radius:var(--radius);display:flex;flex-direction:column;
    box-shadow:0 -8px 26px -8px rgba(23,43,99,.18)}   /* --shadow-lg 同色相，方向朝上（底部悬浮条的功能性翻转） */
  /* 列表尾部留白：给悬浮条让位（条高 ≈ 98px + 底边距 12px，另留 16px 余量）。
     48px = 32 阶梯 + 16 余量（功能值，非档位）。#content 自身还有 78px 下内边距一并兜底。 */
  .m-clist-wrap.m-ijpick{padding-bottom:calc(48px + var(--sab))}
  .m-selbar-t{font-size:12px;color:var(--faint);text-align:center;line-height:1.5}
  .m-selbar-go{width:100%;min-height:46px;border:none;border-radius:var(--radius);background:var(--primary);color:#fff;font-size:15px;font-weight:600;cursor:pointer}
  .m-selbar-go:active{filter:brightness(.96)}
  .m-selbar-go:disabled{background:#C9D2E4;color:#F2F5FA;cursor:not-allowed}
}

/* ============================================================================
   手机端顶栏「去条化」+ 项目切换进抽屉（2026-10-09 用户口径；2026-10-10 收敛为单浮标）
   ----------------------------------------------------------------------------
   用户原话：「这个项目名称可以长一点…项目切换挪进左侧导航…顶栏整行去掉，内容顶到最上面」。
   做法：
   ① #topbar 在 ≤768px 退化成「透明浮层」：position:fixed、无底色无边框、不占高度，
      只留左上角汉堡一个 44×44 白底浮标（右上角同步钮 2026-10-10 已按用户口径删除）；
      浮层空白处 pointer-events:none，点击穿透到内容，不会挡到下面。
   ② 顶栏的项目下拉 .proj-pick 隐藏；项目切换改由侧栏 #side-proj 承担
      （侧栏宽 288px，长项目名能整行显示、可换行，不再被 64vw 截断）。
   ③ #content 顶部只让出浮标高度 44 + 4×2 = 52 + 安全区。
      原为 顶栏 52 + 内容 padding 16 = 68 ⇒ 内容整体上提 16px，
      并且顶部那条白色横条与分隔线彻底消失（这就是用户要的「空出来的位置上提」）。
   ⚠ 44px 是 design-system 第三节「主路径（顶栏汉堡）」的硬约束，不可再压小。
   ⚠ 桌面端（>768px）完全不受影响：仍是白条 + 项目下拉 + 新增项目 + 用户区。
   ============================================================================ */
/* 桌面端：项目切换只在顶栏，侧栏不重复显示（必须在下面的媒体块之前，否则被同分覆盖） */
.side-proj{display:none}
@media (max-width:768px){
  /* ① 顶栏 → 透明浮层 */
  #topbar{
    position:fixed;left:0;right:0;top:0;
    height:auto;min-height:0;
    padding:calc(var(--sat) + 4px) 12px 0;
    background:transparent;border-bottom:none;box-shadow:none;
    pointer-events:none;          /* 空白区域点击穿透到内容 */
    z-index:30;                   /* 高于内容；低于侧栏 60 / 遮罩 55 / 浮层 100 */
  }
  #topbar>*{pointer-events:auto}
  #topbar .topbar-sp{pointer-events:none}
  /* 项目切换已挪进侧栏抽屉 ⇒ 顶栏不再为它占位 */
  #topbar .proj-pick{display:none}
  /* 汉堡：白底浮标，尺寸仍守 44×44 触摸标准 */
  #topbar .hamburger{
    background:rgba(255,255,255,.92);
    border:1px solid var(--border);
    box-shadow:var(--shadow-s);
    -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  }
  #topbar .hamburger:active{background:#fff}
  /* 2026-10-10 用户口径：顶栏右上角的「同步/刷新」圆钮删掉（只剩一个 7px 绿点、
     点不准，且与下拉刷新手势重复）⇒ 手机端整颗隐藏，刷新统一走「下拉刷新」。
     桌面端（>768px）不受影响：仍保留「● 已同步 hh:mm」文字胶囊，点它照旧手动同步。
     同步状态本身仍由 setSync() 维护（DOM 在，只是手机端不显示）。 */
  #topbar .sync-state{display:none}
  /* ③ 内容上提：正好避开剩下那颗 44px 汉堡浮标（顶栏此时只有它一个浮标） */
  #content{padding-top:calc(var(--sat) + 52px)}
  /* ★ 2026-10-10 用户口径：「手机状态栏应该是纯白，能不能把我们的网页设置一个渐变，从白到我们的颜色，
     这样就算适配状态栏了」⇒ 内容区顶部一条「纯白 → 页面底色」的渐变，正好把纯白状态栏接进来。
     · 写在这里（文件末尾、第 1239 行 `#content,main{background:var(--bg)}` 之后）：同特异性靠后写者胜。
     · #content 的盒子从 y=0 开始（手机端 #topbar 已是 fixed 透明浮层、不占高度）⇒ 渐变顶端就是屏幕顶端。
     · 滚动容器的背景默认不随内容滚动，所以这条白顶会一直贴在屏幕最上方（内容从它下面滑过）。
     · 高度取 130px（≈ 状态栏 47 + 浮标 52 + 一点过渡），再往下就完全是页面底色了。 */
  #content{background:linear-gradient(180deg,#FFFFFF 0,var(--bg) 130px)}

  /* ② 侧栏抽屉里的项目切换 */
  .side-proj{display:block;padding:12px 12px 4px;border-bottom:1px solid var(--border);flex-shrink:0}
  .side-proj-lbl{font-size:11px;font-weight:600;color:var(--faint);letter-spacing:1.5px;padding:0 4px 8px}
  .side-proj-list{display:flex;flex-direction:column;gap:4px;max-height:40vh;overflow-y:auto;overscroll-behavior:contain}
  .side-proj-item{
    display:flex;align-items:center;gap:8px;width:100%;min-height:44px;
    padding:8px 12px;border-radius:var(--radius);border:1px solid transparent;
    background:none;font-size:14px;color:#3E4657;line-height:1.4;text-align:left;cursor:pointer;
  }
  .side-proj-item:active{background:var(--hover)}
  .side-proj-item .sp-name{flex:1;min-width:0;word-break:break-word}
  .side-proj-item .sp-tick{display:none;flex-shrink:0;color:var(--primary)}
  .side-proj-item.active{background:var(--primary-l);color:var(--primary);font-weight:600}
  .side-proj-item.active .sp-tick{display:block}
}

/* ============================================================================
   手机端「下拉刷新」指示器（2026-10-10 用户口径）
   ----------------------------------------------------------------------------
   用户原话：「这个刷新按钮删掉，改成用户下拉刷新（所有办理板块应该都可以下拉刷新）」。
   顶栏右上那颗同步钮在手机端已隐藏（见上），刷新改由手势承担 —— 手势逻辑在
   app-main.js `initPullToRefresh()`：在任意业务页面把内容区下拉超过 56px 即触发
   manualSync()（重拉项目数据 + 重绘当前页）。全站只有一个滚动容器 #content，
   所有板块共用 ⇒ 天然「所有办理板块都能下拉刷新」，不必逐页接线。
   指示器形态：顶部居中的白色小胶囊（与顶栏浮标同一套白底 + 细边 + 轻投影），
   跟随手指下移（阻尼 0.5、上限 90px）：未到阈值「下拉刷新」→ 到位「松开立即刷新」
   → 刷新中「正在刷新…」+ 旋转圈。
   ⚠ z-index 29：低于顶栏浮标 30（汉堡始终可按），高于内容；pointer-events:none 不挡点击。
   ⚠ 桌面端不注册手势（鼠标拖拽不是刷新语义），仍用顶栏「● 已同步」胶囊手动同步。
   ============================================================================ */
.ptr{
  position:fixed;left:50%;top:calc(var(--sat) + 2px);z-index:29;
  display:flex;align-items:center;gap:7px;max-width:70vw;
  padding:6px 13px;border-radius:999px;
  background:rgba(255,255,255,.97);border:1px solid var(--border);
  box-shadow:0 4px 14px rgba(27,35,51,.10);
  font-size:12px;line-height:1.3;color:var(--sub);white-space:nowrap;
  opacity:0;pointer-events:none;will-change:transform,opacity;
  transition:opacity .16s ease;
  transform:translate(-50%,-46px);
}
.ptr.on{opacity:1}
.ptr.busy{color:var(--primary)}
.ptr-spin{
  width:14px;height:14px;flex:none;border-radius:50%;
  border:2px solid rgba(30,90,200,.20);border-top-color:var(--primary);
  transition:transform .18s ease;
}
.ptr.ready .ptr-spin{transform:rotate(180deg)}
.ptr.busy .ptr-spin{animation:ptrSpin .7s linear infinite}
/* 刷新完成：转绿即收（此时不再弹顶部 toast，避免两个提示叠在一起） */
.ptr.done{color:var(--green)}
.ptr.done .ptr-spin{border-color:var(--green-l);border-top-color:var(--green);animation:none;transform:none}
@keyframes ptrSpin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){
  .ptr.busy .ptr-spin{animation:none}
}

/* ============================================================================
   ★ 手机端「功能对等」补齐配套样式（2026-10-11）
   新增三样公共件，全部走 design-system 令牌（圆角 / 间距 / 字号 / 触摸目标）：
     1) .m-crow + .m-cops   —— 卡片右侧 44px「更多操作」竖条（renderMList 的 card.ops）
     2) .m-head-more        —— 页头右侧 44px「更多操作」方钮（renderMList 的 menu）
     3) .m-acts + .m-act    —— 通用动作面板（openSheet），手机端是弹窗内的纵向操作列表
   另把 .dd-menu（TPL 下拉菜单）在手机端改成「贴底浮层」，让导出多格式菜单在手机上可用。
   ============================================================================ */

/* ---- 通用动作面板（弹窗内列表）：手机端底部抽屉 / 桌面端居中弹窗，同一套 ---- */
.m-acts{display:flex;flex-direction:column;gap:var(--sp-2)}
.m-act{
  display:flex;align-items:center;gap:var(--sp-3);width:100%;min-height:52px;
  padding:var(--sp-3) var(--sp-4);background:#fff;border:1px solid var(--border);
  border-radius:var(--radius-s);cursor:pointer;text-align:left;transition:background .14s ease;
}
.m-act:active{background:#F1F4F9}
.m-act-ic{flex:none;width:22px;display:flex;align-items:center;justify-content:center;color:var(--primary)}
.m-act-ic svg{width:17px;height:17px}
.m-act-tx{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.m-act-t{font-size:15px;font-weight:600;color:var(--text);line-height:1.4}
.m-act-s{font-size:12px;color:var(--faint);line-height:1.4;word-break:break-word}
.m-act-arrow{flex:none;color:#C3C8D0;font-size:19px;line-height:1}
.m-act.danger .m-act-t,.m-act.danger .m-act-ic{color:var(--red)}
.m-act.danger{border-color:#F6D2D3}
.m-act[disabled]{opacity:.45;cursor:not-allowed}
/* ★ 2026-10-23：动作面板分隔线（「生成资料」按桌面口径分段用） */
.m-act-sep{height:1px;flex:none;background:var(--border);margin:var(--sp-2) var(--sp-4)}

@media (max-width:768px){
  /* ---- 卡片右侧「更多操作」竖条 ---- */
  .m-crow{display:flex;align-items:stretch;gap:0}
  .m-crow>.m-ccard{flex:1;min-width:0}
  /* 有操作条时卡片右圆角让位，拼成「卡片 + 操作页签」的一体感 */
  .m-crow.has-ops>.m-ccard{border-top-right-radius:0;border-bottom-right-radius:0;border-right:0}
  .m-cops{
    flex:none;width:44px;min-height:44px;display:flex;align-items:center;justify-content:center;
    background:#fff;border:1px solid var(--border);border-left:1px solid var(--border);
    border-radius:0 var(--radius) var(--radius) 0;color:var(--sub);cursor:pointer;
    box-shadow:var(--shadow);transition:background .14s ease,color .14s ease;
  }
  .m-cops:active{background:#F1F4F9;color:var(--primary)}

  /* ---- 页头右侧「更多操作」方钮 ---- */
  .m-pagehead-r{display:flex;align-items:center;gap:var(--sp-2);flex:none}
  .m-head-more{
    flex:none;width:44px;height:44px;display:flex;align-items:center;justify-content:center;
    border:1px solid var(--border);background:#fff;border-radius:var(--radius-s);
    color:var(--sub);cursor:pointer;box-shadow:var(--shadow);transition:background .14s ease,color .14s ease;
  }
  .m-head-more:active{background:#F1F4F9;color:var(--primary)}

  /* ---- 手机端工具栏行（隐患台账的 整改通知单/导出台账/批量删除） ---- */
  .m-toolbar-row{display:flex;gap:var(--sp-2)}
  .m-toolbar-row>.m-mini{margin:0;min-height:56px}

  /* ---- TPL 下拉菜单 → 贴底浮层（导出多格式菜单在手机上可用） ----
     z-index 800：高于页面内容(10)/吸底条(50)/侧栏(60)，低于弹窗(1000)，不会被下拉本身盖住弹窗 */
  .dd-menu{
    position:fixed;left:var(--sp-3);right:var(--sp-3);bottom:calc(var(--sp-3) + var(--sab));
    top:auto;min-width:0;max-height:60dvh;overflow-y:auto;-webkit-overflow-scrolling:touch;
    border-radius:var(--radius);z-index:800;padding:var(--sp-1) 0;
    animation:ddMenuUp .22s cubic-bezier(.22,.61,.36,1);
  }
  .dd-item{min-height:44px;display:flex;align-items:center;padding:var(--sp-3) var(--sp-4);font-size:15px;white-space:normal}
  .dd-group-label{font-size:12px;padding:var(--sp-2) var(--sp-4) 2px}
  .dd-divider{margin:var(--sp-1) 0}
}
@keyframes ddMenuUp{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  .dd-menu{animation:none}
}

/* ★ 2026-10-20（第 3 轮）：「单位类型」已是独立半格字段，原来给内联类型块写的窄屏规则一并删除；
   窄屏下所有 .f-item 本来就整行铺开（见 .form-grid 的 768px 规则），无需特判。 */

/* ===== 隐患台账「自定义日期范围」弹窗（2026-10-20）=====
   桌面/手机共用同一个弹窗（openInspDateRangeDialog），所以样式写在全局，手机端另加 16px/44px 达标覆盖。 */
.insp-dr-row{display:flex;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-3)}
.insp-dr-row label{flex:none;width:72px;font-size:13.5px;color:var(--sub)}
.insp-dr-row input{flex:1;min-width:0;height:36px;border:1px solid var(--border-d);border-radius:var(--radius-s);padding:0 var(--sp-3);background:#fff;color:var(--text);font-size:13.5px;outline:none;transition:border-color .16s,box-shadow .16s}
.insp-dr-row input:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--ring)}
.insp-dr-err{min-height:18px;font-size:12.5px;color:var(--red);line-height:1.6;margin:-4px 0 var(--sp-1)}
.insp-dr-tip{font-size:12px;color:var(--faint);line-height:1.7}
@media (max-width:768px){
  .insp-dr-row{gap:var(--sp-2)}
  .insp-dr-row label{width:64px;font-size:13.5px}
  /* 输入类 ≥16px（iOS 聚焦不放大）+ 控件 ≥44px */
  .insp-dr-row input{height:44px;font-size:16px}
  /* 隐患台账：已选自定义范围时的「起 ~ 止」按钮，占满一整行 */
  .m-filters .m-date-btn{flex:1 1 100%;height:44px;border:1px solid var(--border);border-radius:var(--radius-s);background:#fff;color:var(--primary);font-size:16px;font-weight:600;cursor:pointer}
}

/* ============================================================================
   教育交底 · 「按需组合」启动卡（2026-10-26 新增）
   只服务于 Views.safety_edu 的第三个标签页；不影响任何既有样式
   ============================================================================ */
.edu-pack-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-3)}
.edu-pack-card{
  display:block;text-decoration:none;color:inherit;
  background:var(--card);border:1px solid var(--border);border-radius:var(--radius);
  padding:var(--sp-4);box-shadow:var(--shadow-s);transition:border-color .16s,box-shadow .16s,transform .16s;
}
.edu-pack-card:hover{border-color:var(--primary);box-shadow:var(--shadow);transform:translateY(-2px)}
.edu-pack-card:active{transform:translateY(0)}
.epc-h{display:flex;align-items:center;gap:var(--sp-2);margin-bottom:6px}
.epc-h b{font-size:14px;font-weight:700;letter-spacing:.2px}
.epc-badge{
  margin-left:auto;flex:none;font-size:10.5px;font-weight:700;letter-spacing:.5px;
  padding:2px 7px;border-radius:20px;background:var(--primary-l);color:var(--primary-d);
}
.epc-d{font-size:12.5px;color:var(--sub);line-height:1.7;min-height:42px}
.epc-t{
  margin-top:var(--sp-2);padding-top:var(--sp-2);border-top:1px dashed var(--border-d);
  font-size:11.5px;color:var(--faint);line-height:1.6;
}
@media (max-width:1200px){ .edu-pack-grid{grid-template-columns:repeat(2,1fr)} }
@media (max-width:640px){
  .edu-pack-grid{grid-template-columns:1fr}
  .epc-d{min-height:0}
  .edu-pack-card{padding:var(--sp-4)}
}
