/* ============================================================
   鹰眼智销云 · 统一设计语言（v2）
   零依赖、零构建。布局参考销氪后台的通行形态：
   左侧主导航 + 顶部全局栏 + 主区卡片流。
   两端共用同一套 token，仅主色与导航集合不同：
     客户端 --pri 蓝；管理后端 --pri 靛紫（由 body.end-admin 覆盖）
   ============================================================ */

:root{
  --bg:#f5f6f7;
  --card:#fff;
  --line:#e9ebef;
  --line2:#dcdfe5;
  --ink:#1f2329;
  --ink2:#646a73;
  --ink3:#8f959e;
  --ink4:#b6bcc4;

  --pri:#2b6cff;
  --pri-soft:#eaf1ff;
  --pri-deep:#1a53d6;

  --ok:#1f9254;      --ok-soft:#e8f6ee;
  --warn:#c77700;    --warn-soft:#fdf3e2;
  --dang:#d92d20;    --dang-soft:#fdecea;

  --r:8px; --r-lg:10px; --r-xl:14px;
  --sh:0 1px 2px rgba(31,35,41,.04);
  --nav-w:216px; --nav-w-min:60px; --top-h:56px;

  /* 间距栅格（4px 基准，2026-10-10 V2.9-1009.6 统一）：所有 margin/padding 一律引用 token，
     消灭散落字面量，保证全站布局间距一致、视觉风格统一。例外：0 / auto / 百分比 / 负值 /
     结构占位（如 .h5body 底部 78px 防底栏遮挡）仍用字面量，由 _gate_spacing.py 审计放行。 */
  --sp-hair:2px;  --sp-1:4px;  --sp-2:8px;  --sp-3:12px; --sp-4:16px;
  --sp-5:20px;    --sp-6:24px; --sp-7:32px; --sp-8:40px; --sp-9:48px; --sp-10:56px;
}

body.end-admin{
  --pri:#5b4bdb;
  --pri-soft:#efedfd;
  --pri-deep:#4638b8;
}

*{box-sizing:border-box}
html,body{margin:0;padding: 0}
body{
  background:var(--bg); color:var(--ink);
  font:400 13.5px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  -webkit-font-smoothing:antialiased;
}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit}
code,.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px}
.muted{color:var(--ink3)}
.tiny{font-size:12px;color:var(--ink3)}
.nowrap{white-space:nowrap}
.hidden{display:none !important}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-thumb{background:#d5d8de;border-radius:5px}
::-webkit-scrollbar-thumb:hover{background:#bfc4cc}
::-webkit-scrollbar-track{background:transparent}

/* ============================ 主壳 ============================ */
.shell{display:flex;min-height:100vh}

/* ---- 左侧导航 ---- */
.nav{
  width:var(--nav-w);flex:none;background:var(--card);
  border-right:1px solid var(--line);
  display:flex;flex-direction:column;
  position:sticky;top:0;height:100vh;overflow:hidden;
  transition:width .18s ease;
}
body.nav-min .nav{width:var(--nav-w-min)}
.nav-brand{
  height:var(--top-h);flex:none;display:flex;align-items:center;gap:10px;
  padding: 0 var(--sp-4);border-bottom:1px solid var(--line);
}
.nav-brand .logo{
  width:26px;height:26px;flex:none;border-radius:7px;background:var(--pri);
  color:#fff;display:flex;align-items:center;justify-content:center;
  font-size:13px;font-weight:600;letter-spacing:-.5px;
}
.nav-brand .nm{font-size:15px;font-weight:600;letter-spacing:-.2px;white-space:nowrap}
.nav-brand .sub{font-size:11px;color:var(--ink3);margin-left: auto;white-space:nowrap}
body.nav-min .nav-brand .nm,body.nav-min .nav-brand .sub{display:none}
body.nav-min .nav-brand{justify-content:center;padding: 0}

.nav-body{flex:1;overflow-y:auto;padding: var(--sp-3) var(--sp-2) var(--sp-4)}
.nav-grp{margin:var(--sp-3) 0 var(--sp-1);padding: 0 var(--sp-2);font-size:11.5px;color:var(--ink3)}
.nav-body > .nav-grp:first-child{margin-top:var(--sp-hair)}
body.nav-min .nav-grp{text-align:center;padding: 0;font-size:10px;overflow:hidden;white-space:nowrap}

.nav-item{
  display:flex;align-items:center;gap:10px;height:38px;padding: 0 var(--sp-3);
  border-radius:var(--r);color:var(--ink2);cursor:pointer;white-space:nowrap;
  position:relative;margin-bottom: var(--sp-hair);
}
.nav-item:hover{background:#f4f6f9;color:var(--ink)}
.nav-item.on{background:var(--pri-soft);color:var(--pri);font-weight:500}
.nav-item.on::before{
  content:"";position:absolute;left:-8px;top:9px;bottom:9px;width:3px;
  border-radius:0 3px 3px 0;background:var(--pri);
}
.nav-item .ic{width:18px;height:18px;flex:none;display:flex;align-items:center;justify-content:center}
.nav-item .ic svg{width:17px;height:17px;display:block}
.nav-item .lb{flex:1;overflow:hidden;text-overflow:ellipsis}
.nav-item .ct{
  font-size:11.5px;font-weight:500;color:#fff;background:var(--pri);
  border-radius:9px;padding: var(--sp-hair) var(--sp-2);flex:none;
}
.nav-item .lk{font-size:11px;color:var(--ink4);flex:none}
body.nav-min .nav-item{justify-content:center;padding: 0}
body.nav-min .nav-item .lb,body.nav-min .nav-item .ct,body.nav-min .nav-item .lk{display:none}

.nav-foot{flex:none;border-top:1px solid var(--line);padding: var(--sp-2)}

/* ---- 版本信息展示模块（租户侧 / 平台侧共用） ---- */
.nav-ver{display:flex;flex-direction:column;gap:1px;padding: var(--sp-2) var(--sp-3);margin-top: var(--sp-hair);
  border-radius:8px;cursor:pointer;color:var(--ink3);line-height:1.3;user-select:none}
.nav-ver:hover{background:#f4f6f9;color:var(--ink)}
.nav-ver:focus{outline:2px solid var(--pri-soft);outline-offset:1px}
.nav-ver .vb{font-size:12px;font-weight:600;color:var(--ink2);
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.nav-ver .vd{font-size:10.5px;color:var(--ink4)}
body.nav-min .nav-ver{display:none}
.ver-meta{display:grid;grid-template-columns:84px 1fr;gap:8px 12px;margin: var(--sp-1) 0 var(--sp-4)}
.ver-meta .vr{display:contents}
.ver-meta .vr .k{color:var(--ink4);font-size:12.5px;align-self:center}
.ver-meta .vr .val{font-size:13px;color:var(--ink);
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.vh{font-size:13px;font-weight:600;margin: var(--sp-2) 0 var(--sp-2);color:var(--ink2)}
.vnotes{margin:0;padding-left: var(--sp-5)}
.vnotes li{margin:var(--sp-1) 0;font-size:13px;color:var(--ink);line-height:1.5}
.vn{margin-top:var(--sp-4);padding-top: var(--sp-3);border-top:1px solid var(--line);
  font-size:11.5px;color:var(--ink4);line-height:1.5}

/* ---- 版本与发布信息 · v2（2026-10-03）：运行版本对账 + 版本推进史 ----
   背景：左下角角标此前只显示一个静态版本号，既不知道它是否与实际运行一致，
   也看不出「推进到哪了」。下面两块分别解决这两件事。 */
.nav-ver.drift .vb{color:var(--dang)}
.nav-ver.drift .vb::after{content:'⚠';margin-left: var(--sp-1);font-size:10px}
.vchk{display:flex;align-items:center;gap:8px;margin: 0 0 var(--sp-4);padding: var(--sp-2) var(--sp-3);
  border-radius:var(--r);font-size:12.5px;line-height:1.5;
  background:var(--bg);border:1px solid var(--line)}
.vchk .dot{flex:none;width:7px;height:7px;border-radius:50%;background:var(--ink4)}
.vchk .txt{flex:1;min-width:0;color:var(--ink2)}
.vchk[data-state="ok"] .dot{background:var(--ok)}
.vchk[data-state="ok"] .txt{color:var(--ok)}
.vchk[data-state="bad"]{background:var(--dang-soft);border-color:#f6c9c4}
.vchk[data-state="bad"] .dot{background:var(--dang)}
.vchk[data-state="bad"] .txt{color:var(--dang);font-weight:500}
.vbtn{flex:none;border:1px solid var(--line2);background:#fff;color:var(--ink2);
  border-radius:var(--r);padding: var(--sp-1) var(--sp-3);font-size:12px;cursor:pointer;transition:.12s}
.vbtn:hover{border-color:var(--pri);color:var(--pri)}
.vbtn[disabled]{opacity:.55;cursor:default}
.vtl{list-style:none;margin: 0;padding: 0 0 0 var(--sp-4);position:relative}
.vtl::before{content:'';position:absolute;left:3px;top:6px;bottom:6px;width:1px;background:var(--line2)}
.vtl > li{position:relative;padding: 0 0 var(--sp-3)}
.vtl > li:last-child{padding-bottom:0}
.vtl > li::before{content:'';position:absolute;left:-14px;top:6px;width:7px;height:7px;
  border-radius:50%;background:#fff;border:1.5px solid var(--line2)}
.vtl > li.cur::before{background:var(--pri);border-color:var(--pri)}
.vth{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.vth .t{font-size:12.5px;font-weight:600;color:var(--ink);
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.vth .bdg{font-size:10.5px;line-height:1.5;padding: 0 var(--sp-2);border-radius:9px;
  background:var(--pri-soft);color:var(--pri-deep)}
.vth .d{font-size:11.5px;color:var(--ink4)}
.vth .n{font-size:11px;color:var(--ink4)}
.vtn{list-style:none;margin: var(--sp-1) 0 0;padding: 0}
.vtn > li{font-size:12.5px;color:var(--ink2);line-height:1.55;margin: var(--sp-1) 0;
  padding-left: var(--sp-3);position:relative}
.vtn > li::before{content:'·';position:absolute;left:2px;color:var(--ink4)}
.vtl > li:not(.open) .vtn > li:nth-child(n+2){display:none}
.vmore{margin-top:var(--sp-1);border:0;background:none;color:var(--pri);font-size:12px;
  padding: 0;cursor:pointer}
.vmore:hover{text-decoration:underline}

/* ---- 主区 ---- */
.main{flex:1;min-width:0;display:flex;flex-direction:column}

/* ---- 顶栏 ---- */
.top{
  height:var(--top-h);flex:none;background:var(--card);
  border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:12px;padding: 0 var(--sp-4);
  position:sticky;top:0;z-index:30;
}
.top .burger{
  width:32px;height:32px;flex:none;border:0;background:none;border-radius:var(--r);
  display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--ink2);
}
.top .burger:hover{background:#f2f4f7}
.search{
  display:flex;align-items:center;gap:7px;height:34px;padding: 0 var(--sp-3);
  background:#f2f4f8;border:1px solid transparent;border-radius:17px;
  min-width:170px;max-width:320px;flex:1 1 210px;color:var(--ink3);
}
.search:focus-within{background:var(--card);border-color:var(--pri)}
.search input{border:0;background:none;outline:none;flex:1;min-width:0;font:inherit;color:var(--ink)}
.search input::placeholder{color:var(--ink3)}
.top .sp{flex:1}

.notice{
  display:flex;align-items:center;gap:6px;height:30px;padding: 0 var(--sp-3);
  background:var(--pri-soft);color:var(--pri);border-radius:15px;
  font-size:12.5px;white-space:nowrap;cursor:pointer;
}
.notice:hover{filter:brightness(.97)}
.icobtn{
  width:32px;height:32px;flex:none;border:0;background:none;border-radius:var(--r);
  display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--ink2);position:relative;
}
.icobtn:hover{background:#f2f4f7;color:var(--ink)}
.icobtn .dot{
  position:absolute;top:6px;right:6px;width:6px;height:6px;border-radius:50%;
  background:var(--dang);border:1.5px solid var(--card);
}
/* 站内信未读角标（数字）：默认隐藏，由 loadInboxCount() 按未读数显隐 */
.icobtn .ibdg{
  position:absolute;top:2px;right:2px;min-width:16px;height:16px;padding: 0 var(--sp-1);
  border-radius:8px;background:var(--dang);color:#fff;font-size:10.5px;line-height:16px;
  text-align:center;font-weight:700;border:1.5px solid var(--card);display:none;
}
.who{
  display:flex;align-items:center;gap:8px;height:34px;padding: 0 var(--sp-2) 0 var(--sp-2);
  border-radius:17px;cursor:pointer;white-space:nowrap;
}
.who:hover{background:#f2f4f7}
.ava{
  width:26px;height:26px;flex:none;border-radius:50%;background:var(--pri-soft);color:var(--pri);
  display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500;
}
.who .nm{font-size:13px;color:var(--ink)}
.who .cr{font-size:10px;color:var(--ink3)}

.tsel{
  display:flex;align-items:center;gap:6px;height:32px;padding: 0 var(--sp-3);
  border:1px solid var(--line2);border-radius:var(--r);background:var(--card);
  font-size:12.5px;color:var(--ink);
}
.tsel:hover{border-color:var(--pri)}
.tsel select{border:0;background:none;outline:none;font:inherit;color:inherit;cursor:pointer;max-width:190px}

/* ---- 内容区 ---- */
.content{flex:1;min-width:0;padding: var(--sp-5) var(--sp-6) var(--sp-8);max-width:1500px;width:100%}

.phead{display:flex;align-items:flex-start;gap:12px;margin-bottom: var(--sp-4)}
.phead .tt{min-width:0}
.crumb{font-size:12px;color:var(--ink3);margin-bottom: var(--sp-1)}
.crumb a:hover{color:var(--pri)}
.phead h1{margin:0;font-size:19px;font-weight:600;letter-spacing:-.2px}
.phead .ds{font-size:12.5px;color:var(--ink3);margin-top: var(--sp-1)}
.phead .sp{flex:1}
.phead .acts{display:flex;gap:8px;flex:none;align-items:center;padding-top: var(--sp-hair)}

/* ---- 按钮 ---- */
.btn{
  display:inline-flex;align-items:center;gap:6px;height:32px;padding: 0 var(--sp-3);
  border:1px solid var(--line2);background:var(--card);border-radius:var(--r);
  cursor:pointer;font-size:13px;color:var(--ink);white-space:nowrap;
}
.btn:hover{border-color:var(--pri);color:var(--pri)}
.btn.pri{background:var(--pri);border-color:var(--pri);color:#fff}
.btn.pri:hover{background:var(--pri-deep);border-color:var(--pri-deep);color:#fff}
.btn.sm{height:27px;padding: 0 var(--sp-3);font-size:12.5px}
.btn:disabled{opacity:.45;cursor:not-allowed}
.btn:disabled:hover{border-color:var(--line2);color:var(--ink)}

/* ---- 卡片 ---- */
.card{
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);
  margin-bottom: var(--sp-4);
}
.card > .hd{
  display:flex;align-items:center;gap:10px;padding: var(--sp-3) var(--sp-5);border-bottom:1px solid var(--line);
}
.card > .hd h2{margin:0;font-size:14.5px;font-weight:600}
.card > .hd .sp{flex:1}
.card > .hd .ex{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--ink2)}
.card > .bd{padding:var(--sp-4) var(--sp-5)}
.card > .bd.flush{padding:0}
.card.nb{border:0;background:none;margin-bottom: 0}
.card.nb > .bd{padding:0}

.grid2{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.grid2.a{grid-template-columns:1.35fr 1fr}
.grid3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
.grid4{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px}
@media (max-width:1100px){.grid3,.grid4{grid-template-columns:1fr 1fr}}
@media (max-width:900px){.grid2,.grid2.a{grid-template-columns:1fr}}
@media (max-width:640px){.grid3,.grid4{grid-template-columns:1fr}}

/* ---- 快捷入口 ---- */
.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(108px,1fr));gap:4px;padding: var(--sp-4) var(--sp-3)}
.tile{display:flex;flex-direction:column;align-items:center;gap:9px;padding: var(--sp-3) var(--sp-2);
      border-radius:var(--r);cursor:pointer}
.tile:hover{background:#f4f6f9}
.tile .ci{width:44px;height:44px;border-radius:50%;background:var(--pri-soft);color:var(--pri);
          display:flex;align-items:center;justify-content:center}
.tile .ci svg{width:21px;height:21px}
.tile .lb{font-size:13px;color:var(--ink);white-space:nowrap}

/* ---- 指标组 ---- */
.mgroup{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}
.mbox{padding:var(--sp-1) var(--sp-5) var(--sp-3);border-left:1px solid var(--line)}
.mbox:first-child{border-left:0}
.mbox .mh{display:flex;align-items:center;gap:5px;font-size:12.5px;color:var(--ink2);
          margin-bottom: var(--sp-4);white-space:nowrap}
.mbox .mrow{display:flex;gap:26px;flex-wrap:wrap}
.metric{min-width:76px}
.metric .v{font-size:24px;font-weight:600;color:var(--pri);letter-spacing:-.4px;line-height:1.15}
.metric .v.mut{color:var(--ink4)}
.metric .l{font-size:12px;color:var(--ink3);margin-top: var(--sp-1);white-space:nowrap}
.color-ok{color:var(--ok)} .color-warn{color:var(--warn)} .color-dang{color:var(--dang)}

/* 独立 KPI 卡 */
.kpi{background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);padding: var(--sp-4) var(--sp-4)}
.kpi .l{font-size:12.5px;color:var(--ink2);margin-bottom: var(--sp-1)}
.kpi .v{font-size:25px;font-weight:600;letter-spacing:-.4px;line-height:1.15}
.kpi .v small{font-size:12.5px;font-weight:400;color:var(--ink3);margin-left: var(--sp-1)}
.kpi .f{font-size:11.5px;color:var(--ink3);margin-top: var(--sp-1)}
.kpi.pri .v{color:var(--pri)}

/* ---- 列表行 ---- */
.lrow{display:flex;align-items:center;gap:12px;padding: var(--sp-3) var(--sp-4);border-radius:var(--r);
      background:#f7f9fc;margin-bottom: var(--sp-2);cursor:pointer;border:1px solid transparent}
.lrow:hover{background:#f1f5fb;border-color:#e2ebfa}
.lrow .t{flex:1;min-width:0;font-size:13.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lrow .s{font-size:12px;color:var(--ink3);white-space:nowrap}
.lrow .n{font-size:15px;font-weight:600;color:var(--pri);min-width:26px;text-align:right}

/* ---- 两行行项（重点工作：名称 + 简要描述 + 时间/状态）----
   复用 .lrow 的底色 / 圆角 / 悬停，只把「单行」扩成可容纳描述的「两行」，
   与首页 A01 的 .lrow 视觉完全一致，故首页与「重点工作」页零违和。 */
.lrow.l2{align-items:flex-start;white-space:normal;text-decoration:none;color:inherit;
         cursor:default}
.lrow.l2 .dt{width:8px;height:8px;border-radius:50%;margin-top: var(--sp-2);flex:none;background:var(--pri)}
.lrow.l2 .dt.s-overdue{background:var(--dang)}
.lrow.l2 .dt.s-pending{background:var(--warn)}
.lrow.l2 .dt.s-todo{background:var(--pri)}
.lrow.l2 .dt.s-done{background:var(--ok)}
.lrow.l2 .tx{flex:1;min-width:0}
.lrow.l2 .tx .tt{font-size:13.5px;font-weight:500;line-height:1.45}
.lrow.l2 .tx .dd{font-size:12.5px;color:var(--ink3);margin-top: var(--sp-1);line-height:1.55}
.lrow.l2 .mt{margin-left:auto;flex:none;display:flex;flex-direction:column;align-items:flex-end;gap:5px}
.lrow.l2 .mt .tm{font-size:11.5px;color:var(--ink4);white-space:nowrap}
@media (max-width:640px){
  .lrow.l2{flex-wrap:wrap}
  .lrow.l2 .mt{margin-left:0;flex-direction:row;align-items:center;width:100%;
               justify-content:space-between;margin-top: var(--sp-1)}
}

/* 公海线索富化行（需求5）：号码 / 需求描述 / 评分 */
.lrow.l2 .ph{display:inline-flex;align-items:center;gap:5px;margin: var(--sp-hair) var(--sp-3) var(--sp-hair) 0;
             font-size:12.5px;color:var(--ink2)}
.lrow.l2 .pht{font-size:11px;color:var(--ink4);background:#f2f4f8;padding: var(--sp-hair) var(--sp-2);border-radius:4px}
.lrow.l2 .phs{font-size:11px;color:var(--warn)}
.lrow.l2 .ld{color:var(--ink2);display:inline-block;margin-top: var(--sp-hair)}
.lrow.l2 .sc{font-size:13px;font-weight:600;color:var(--pri)}

/* ---- 表格 ---- */
.twrap{overflow-x:auto;border-radius:0 0 var(--r-lg) var(--r-lg)}
table.t{width:100%;border-collapse:collapse;font-size:13px}
table.t th{text-align:left;font-weight:500;color:var(--ink2);font-size:12.5px;
           padding: var(--sp-3) var(--sp-4);background:#fafbfc;border-bottom:1px solid var(--line);white-space:nowrap}
table.t td{padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--line);vertical-align:middle}
table.t tbody tr:last-child td{border-bottom:0}
table.t tbody tr:hover{background:#fafbfd}
table.t th.num,table.t td.num{text-align:right;font-variant-numeric:tabular-nums}
table.t th.ctr,table.t td.ctr{text-align:center}
table.t td.act{white-space:nowrap;text-align:right}
table.t tr.click{cursor:pointer}

/* ---- 徽章 ---- */
.bdg{display:inline-flex;align-items:center;gap:4px;font-size:11.5px;font-weight:500;
     padding: var(--sp-hair) var(--sp-2);border-radius:5px;white-space:nowrap;line-height:1.6}
.b-ok{background:var(--ok-soft);color:var(--ok)}
.b-warn{background:var(--warn-soft);color:var(--warn)}
.b-dang{background:var(--dang-soft);color:var(--dang)}
.b-pri{background:var(--pri-soft);color:var(--pri)}
.b-gray{background:#f0f1f4;color:var(--ink2)}
.chip{display:inline-block;font-size:12px;padding: var(--sp-hair) var(--sp-2);border-radius:5px;
      background:#f2f4f8;color:var(--ink2);margin: 0 var(--sp-1) var(--sp-1) 0}
.chip.on{background:var(--pri-soft);color:var(--pri)}
.chip.x{cursor:pointer}
.chip.x:hover{background:var(--dang-soft);color:var(--dang)}

/* ---- 闸门判定 ---- */
.gate{display:flex;flex-wrap:wrap;gap:5px}
.gate span{font-size:11.5px;padding: var(--sp-hair) var(--sp-2);border-radius:5px;white-space:nowrap}
.gate .p{background:var(--ok-soft);color:var(--ok)}
.gate .f{background:var(--dang-soft);color:var(--dang)}
.gate .n{background:#f0f1f4;color:var(--ink2)}

/* ---- 进度条 ---- */
.bar{height:6px;border-radius:3px;background:#eef0f4;overflow:hidden}
.bar i{display:block;height:100%;border-radius:3px;background:var(--pri)}
.bar i.ok{background:var(--ok)} .bar i.warn{background:#e8a33d} .bar i.dang{background:var(--dang)}

/* ---- 筛选 ---- */
.filter{display:flex;gap:16px;align-items:flex-start}
.fpanel{width:206px;flex:none;border-right:1px solid var(--line);padding-right: var(--sp-4)}
.fpanel .fg{margin-bottom:var(--sp-4)}
.fpanel .fg .l{font-size:12.5px;color:var(--ink2);margin-bottom: var(--sp-2)}
.fpanel select,.fpanel input{width:100%;height:31px;padding: 0 var(--sp-2);border:1px solid var(--line2);
  border-radius:var(--r);font:inherit;font-size:12.5px;background:var(--card);outline:none;color:var(--ink)}
.fpanel select:focus,.fpanel input:focus{border-color:var(--pri)}
.fresult{flex:1;min-width:0}
.fbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom: var(--sp-3);min-height:26px}
.fbar .sp{flex:1}
@media (max-width:900px){.filter{flex-direction:column}.fpanel{width:100%;border-right:0;
  border-bottom:1px solid var(--line);padding: 0 0 var(--sp-4)}}

/* ---- 抽屉 ---- */
/* ⚠️ 基础规则必须写 pointer-events:none。
   抽屉的 mask 是 position:fixed;inset:0 的**全屏**元素，关闭时只是 opacity:0 变透明，
   **DOM 不移除**（closeDrawer 只摘 .on 类）。不写 pointer-events:none 的话，
   它就以 z-index:60 永久盖在页面上吃点击 —— 顶栏导航只有 z-index:30，
   于是「打开过一次抽屉之后，点任何按钮都没反应」。这是 2026-09-25 报上来的现象。 */
.drawer-mask{position:fixed;inset:0;background:rgba(31,35,41,.28);z-index:60;opacity:0;
             pointer-events:none;
             transition:opacity .18s ease}
.drawer-mask.on{opacity:1;pointer-events:auto}
.drawer{position:fixed;top:0;right:0;bottom:0;width:520px;max-width:94vw;background:var(--card);
        z-index:61;display:flex;flex-direction:column;transform:translateX(100%);
        transition:transform .2s ease;box-shadow:-6px 0 24px rgba(31,35,41,.09)}
.drawer.on{transform:none}
.drawer .dh{flex:none;display:flex;align-items:center;gap:10px;padding: var(--sp-4) var(--sp-5);border-bottom:1px solid var(--line)}
.drawer .dh h2{margin:0;font-size:15px;font-weight:600}
.drawer .dh .sp{flex:1}
.drawer .db{flex:1;overflow-y:auto;padding: var(--sp-4) var(--sp-5)}
.drawer .df{flex:none;padding: var(--sp-3) var(--sp-5);border-top:1px solid var(--line);
            display:flex;gap:8px;justify-content:flex-end;flex-wrap:wrap}
.xbtn{width:28px;height:28px;border:0;background:none;border-radius:var(--r);cursor:pointer;
      color:var(--ink3);display:flex;align-items:center;justify-content:center;font-size:17px;line-height:1}
.xbtn:hover{background:#f2f4f7;color:var(--ink)}

/* ---- 描述表 ---- */
.dl{display:grid;grid-template-columns:92px 1fr;gap:9px 12px;font-size:13px}
.dl dt{color:var(--ink3);font-size:12.5px}
.dl dd{margin:0;word-break:break-word}

.sec{font-size:12.5px;font-weight:600;color:var(--ink2);margin: var(--sp-5) 0 var(--sp-2)}
.sec:first-child{margin-top:0}

/* ---- 载入 / 空 / 错 ---- */
.sk{background:linear-gradient(90deg,#f0f2f5 25%,#f7f8fa 37%,#f0f2f5 63%);
    background-size:400% 100%;animation:sk 1.3s ease infinite;border-radius:5px;height:13px}
@keyframes sk{0%{background-position:100% 50%}100%{background-position:0 50%}}
.skrow{display:flex;gap:14px;padding: var(--sp-3) var(--sp-4);border-bottom:1px solid var(--line)}
.skrow .sk{flex:1}
.empty{padding:var(--sp-7) var(--sp-4);text-align:center;color:var(--ink3);font-size:13px}
.empty .ei{font-size:22px;color:var(--ink4);margin-bottom: var(--sp-2);line-height:1}
.empty .eb{margin-top:var(--sp-3)}
.err{padding:var(--sp-4) var(--sp-4);background:var(--dang-soft);border:1px solid #f7d3cf;
     border-radius:var(--r);color:#a3231a;font-size:13px}
.err .et{font-weight:600;margin-bottom: var(--sp-1)}
.err .rid{font-family:ui-monospace,monospace;font-size:11.5px;color:#b45a51;margin-top: var(--sp-1)}

.spin{display:inline-block;width:12px;height:12px;border:2px solid var(--line2);
      border-top-color:var(--pri);border-radius:50%;animation:sp .7s linear infinite;vertical-align:-2px}
@keyframes sp{to{transform:rotate(360deg)}}

/* ---- toast ---- */
.toast{position:fixed;left:50%;bottom:34px;transform:translateX(-50%);z-index:90;
       display:flex;flex-direction:column;gap:8px;align-items:center;pointer-events:none}
.toast > div{background:#1f2329;color:#fff;font-size:13px;padding: var(--sp-2) var(--sp-4);border-radius:var(--r);
             box-shadow:0 6px 20px rgba(31,35,41,.22);transition:opacity .4s;max-width:70vw}
.toast > div.err{background:var(--dang)} .toast > div.ok{background:var(--ok)}

/* ---- 引导卡：顶置、可关闭、不遮挡 ---- */
.guide{display:flex;align-items:flex-start;gap:10px;padding: var(--sp-3) var(--sp-4);margin-bottom: var(--sp-4);
       background:var(--pri-soft);border:1px solid #d6e3ff;border-radius:var(--r);font-size:13px}
body.end-admin .guide{border-color:#dcd8fb}
.guide .gt{flex:1}
.guide b{font-weight:600}

/* ---- 分区切换 ---- */
.tabs{display:flex;gap:2px;border-bottom:1px solid var(--line);margin-bottom: var(--sp-4);overflow-x:auto}
.tab{border:0;background:none;padding: var(--sp-2) var(--sp-4);cursor:pointer;font-size:13.5px;color:var(--ink2);
     border-bottom:2px solid transparent;margin-bottom: -1px;white-space:nowrap}
.tab:hover{color:var(--ink)}
.tab.on{color:var(--pri);border-bottom-color:var(--pri);font-weight:500}
.tabs>button{border:0;background:none;padding: var(--sp-2) var(--sp-4);cursor:pointer;font-size:13.5px;
     color:var(--ink2);border-bottom:2px solid transparent;margin-bottom: -1px;white-space:nowrap}
.tabs>button:hover{color:var(--ink)}
.tabs>button.on{color:var(--pri);border-bottom-color:var(--pri);font-weight:500}

/* ---- 看板 ---- */
.board{display:flex;gap:12px;overflow-x:auto;padding-bottom: var(--sp-2)}
.col{width:210px;flex:none;background:#f7f8fa;border:1px solid var(--line);border-radius:var(--r-lg)}
.col .ch{display:flex;align-items:center;gap:7px;padding: var(--sp-3) var(--sp-3);border-bottom:1px solid var(--line)}
.col .ch .nm{font-size:12.5px;font-weight:500}
.col .ch .n{font-size:11.5px;color:var(--ink3);margin-left: auto}
.col .cb{padding:var(--sp-2);display:flex;flex-direction:column;gap:8px;min-height:70px}
.opp{background:var(--card);border:1px solid var(--line);border-radius:var(--r);
     padding: var(--sp-3) var(--sp-3);cursor:pointer}
.opp:hover{border-color:var(--pri);box-shadow:var(--sh)}
.opp .t{font-size:12.5px;font-weight:500;margin-bottom: var(--sp-1);line-height:1.45}
.opp .m{font-size:11.5px;color:var(--ink3);display:flex;justify-content:space-between;gap:8px}
.opp .a{font-size:14px;font-weight:600;color:var(--pri);margin-top: var(--sp-2)}

/* ---- 柱图 ---- */
.chart{display:flex;align-items:flex-end;gap:10px;height:130px;padding: var(--sp-2) var(--sp-1) 0}
.chart .c{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;
          height:100%;justify-content:flex-end;min-width:0}
.chart .c .n{font-size:11.5px;color:var(--ink2);font-weight:500}
.chart .c .b{width:100%;max-width:38px;background:var(--pri);border-radius:4px 4px 0 0;min-height:2px}
.chart .c .b.alt{background:#a8c4ff}
body.end-admin .chart .c .b.alt{background:#b9b2f0}
.chart .c .l{font-size:11px;color:var(--ink3);white-space:nowrap;overflow:hidden;
             text-overflow:ellipsis;max-width:100%}
.legend{display:flex;gap:14px;flex-wrap:wrap;font-size:12px;color:var(--ink2);margin-top: var(--sp-3)}
.legend i{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right: var(--sp-1)}

/* ---- 时间线 ---- */
.tl{position:relative;padding-left: var(--sp-5)}
.tl::before{content:"";position:absolute;left:4px;top:6px;bottom:6px;width:1px;background:var(--line)}
.tl .it{position:relative;padding-bottom: var(--sp-4)}
.tl .it::before{content:"";position:absolute;left:-18px;top:5px;width:9px;height:9px;
                border-radius:50%;background:var(--pri);border:2px solid var(--card)}
.tl .it .h{font-size:13px;font-weight:500}
.tl .it .s{font-size:12px;color:var(--ink3);margin-top: var(--sp-hair)}

/* ---- H5（终端客户，独立轻壳）---- */
.h5wrap{max-width:430px;margin: 0 auto;background:var(--card);min-height:100vh;
        box-shadow:0 0 0 1px var(--line)}
.h5top{position:sticky;top:0;background:var(--card);border-bottom:1px solid var(--line);
       padding: var(--sp-3) var(--sp-4);z-index:10}
.h5top h1{margin:0;font-size:16px;font-weight:600}
.h5top .s{font-size:12px;color:var(--ink3);margin-top: var(--sp-hair)}
.h5body{padding:var(--sp-4) var(--sp-4) 78px}
.h5tabs{position:fixed;left:50%;transform:translateX(-50%);bottom:0;width:100%;max-width:430px;
        background:var(--card);border-top:1px solid var(--line);display:flex}
.h5tabs a{flex:1;text-align:center;padding: var(--sp-2) var(--sp-1) var(--sp-3);font-size:11.5px;color:var(--ink3)}
.h5tabs a.on{color:var(--pri);font-weight:500}
.h5tabs a .i{display:block;font-size:17px;line-height:1.3;margin-bottom: var(--sp-hair)}
.msg{max-width:82%;padding: var(--sp-2) var(--sp-3);border-radius:12px;font-size:13.5px;line-height:1.6;margin-bottom: var(--sp-2)}
.msg.me{margin-left:auto;background:var(--pri);color:#fff;border-bottom-right-radius:4px}
.msg.ai{background:#f2f4f8;border-bottom-left-radius:4px}
.msg .tool{font-size:11.5px;color:var(--ink3);margin-top: var(--sp-1);font-family:ui-monospace,monospace}
.msg.me .tool{color:rgba(255,255,255,.75)}

/* ---- 门户 ---- */
.portal{max-width:1010px;margin: 0 auto;padding: var(--sp-10) var(--sp-6)}
.portal .ph{text-align:center;margin-bottom: var(--sp-7)}
.portal .ph .lg{width:52px;height:52px;border-radius:14px;background:var(--pri);color:#fff;
  margin: 0 auto var(--sp-4);display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:600}
.portal .ph h1{margin:0 0 var(--sp-2);font-size:26px;font-weight:600;letter-spacing:-.4px}
.portal .ph p{margin:0;color:var(--ink2);font-size:14px}
.pgroups{display:grid;grid-template-columns:1fr 1fr;gap:22px}
@media (max-width:820px){.pgroups{grid-template-columns:1fr}}
.pgrp h2{font-size:13px;font-weight:600;color:var(--ink2);margin: 0 0 var(--sp-3);
         display:flex;align-items:center;gap:7px}
.pgrp h2 i{width:8px;height:8px;border-radius:2px;background:var(--pri);display:inline-block}
.pgrp.adm h2 i{background:#5b4bdb}
.plist{display:flex;flex-direction:column;gap:9px}
.pcard{display:flex;align-items:center;gap:12px;padding: var(--sp-4) var(--sp-4);background:var(--card);
       border:1px solid var(--line);border-radius:var(--r-lg)}
.pcard:hover{border-color:var(--pri);box-shadow:var(--sh)}
.pcard .ci{width:38px;height:38px;flex:none;border-radius:10px;background:var(--pri-soft);
           color:var(--pri);display:flex;align-items:center;justify-content:center}
.pcard .ci svg{width:19px;height:19px}
.pcard .tx{flex:1;min-width:0}
.pcard .tx .n{font-size:14px;font-weight:500}
.pcard .tx .d{font-size:12px;color:var(--ink3);margin-top: var(--sp-hair)}
.pcard .go{color:var(--ink4);font-size:15px}
.pf{text-align:center;color:var(--ink3);font-size:12px;margin-top: var(--sp-7)}
.pf .tiny{font-size:11.5px;color:var(--ink4)}

/* ---- 门户（分组版）----------------------------------------------
   内容由 HW.NAV 派生，因此两列各自是一叠「功能域」，而不是平铺列表；
   卡片同步做紧凑化，保证 40+ 入口在一屏内可扫读。 */
.portal{max-width:1130px;padding: var(--sp-9) var(--sp-6)}
.portal .ph{margin-bottom:var(--sp-7)}
.pfind{max-width:340px;margin: var(--sp-5) auto 0}
.pfind input{width:100%;height:34px;padding: 0 var(--sp-3);border:1px solid var(--line);
  border-radius:17px;background:var(--card);color:var(--ink);font:400 13px/34px inherit;
  outline:none;transition:border-color .15s,box-shadow .15s}
.pfind input::placeholder{color:var(--ink4)}
.pfind input:focus{border-color:var(--pri);box-shadow:0 0 0 3px var(--pri-soft)}
.pgrp h2 .cnt{margin-left:auto;font-size:11px;font-weight:500;color:var(--ink3);
  background:var(--bg);border:1px solid var(--line);border-radius:9px;padding: var(--sp-hair) var(--sp-2)}
.pgn{margin-bottom:var(--sp-4)}
.pgn:last-child{margin-bottom:0}
.pgl{font-size:11.5px;color:var(--ink3);letter-spacing:.2px;margin: 0 0 var(--sp-2) var(--sp-1);
  display:flex;align-items:center;gap:6px}
.pgl::before{content:'';width:3px;height:10px;border-radius:2px;background:var(--pri);opacity:.85}
.pgrp.adm .pgl::before{background:#5b4bdb}
.portal .plist{gap:7px}
.portal .pcard{padding:var(--sp-3) var(--sp-4);gap:11px}
.portal .pcard .ci{width:34px;height:34px;border-radius:9px}
.portal .pcard .tx .d{font-size:11.5px}
.pgempty{text-align:center;color:var(--ink3);font-size:13px;padding: var(--sp-9) 0}

/* ---- 门户「重点工作」板块（首页底部）------------------------------ */
.pkw{margin-top:var(--sp-7);border-top:1px solid var(--line);padding-top: var(--sp-6)}
.pkw h2{font-size:13px;font-weight:600;color:var(--ink2);margin: 0 0 var(--sp-3);
        display:flex;align-items:center;gap:7px}
.pkw h2 i{width:8px;height:8px;border-radius:2px;background:var(--pri);display:inline-block}
.pkw h2 .cnt{margin-left:auto;font-size:11px;font-weight:500;color:var(--ink3);
  background:var(--bg);border:1px solid var(--line);border-radius:9px;padding: var(--sp-hair) var(--sp-2)}
.kwlist{display:flex;flex-direction:column;gap:9px}
.kwitem{display:flex;align-items:flex-start;gap:12px;padding: var(--sp-3) var(--sp-4);background:var(--card);
  border:1px solid var(--line);border-radius:var(--r-lg);text-decoration:none;color:inherit;
  transition:border-color .15s,box-shadow .15s}
.kwitem:hover{border-color:var(--pri);box-shadow:var(--sh)}
.kwdot{width:9px;height:9px;border-radius:50%;margin-top: var(--sp-1);flex:none;background:var(--pri)}
.kwdot.s-pending{background:var(--warn)} .kwdot.s-todo{background:var(--pri)}
.kwdot.s-done{background:var(--ok)} .kwdot.s-warn{background:var(--dang)}
.kwdot.s-overdue{background:var(--dang)}
.kwtx{flex:1;min-width:0}
.kwt{font-size:14px;font-weight:500;display:block;line-height:1.4}
.kwd{font-size:12px;color:var(--ink3);margin-top: var(--sp-1);line-height:1.5}
.kwm{margin-left:auto;display:flex;flex-direction:column;align-items:flex-end;gap:5px;flex:none}
.kwbadge{font-size:11px;font-weight:600;padding: var(--sp-hair) var(--sp-2);border-radius:8px;
  background:var(--pri-soft);color:var(--pri);white-space:nowrap}
.kwbadge.s-pending{background:rgba(245,158,11,.16);color:var(--warn)}
.kwbadge.s-todo{background:var(--pri-soft);color:var(--pri)}
.kwbadge.s-done{background:rgba(16,185,129,.16);color:var(--ok)}
.kwbadge.s-warn{background:rgba(239,68,68,.16);color:var(--dang)}
.kwbadge.s-overdue{background:rgba(239,68,68,.16);color:var(--dang)}
.kwtime{font-size:11px;color:var(--ink4);white-space:nowrap}
.kwempty{text-align:center;color:var(--ink3);font-size:12.5px;padding: var(--sp-5) 0;
  border:1px dashed var(--line);border-radius:var(--r-lg)}
@media (max-width:640px){
  .kwitem{flex-wrap:wrap}
  .kwm{margin-left:0;flex-direction:row;align-items:center;width:100%;
       justify-content:space-between;margin-top: var(--sp-1)}
}

/* ============================================================
   身份切换器（v2.1）
   两个入口，一套面板：
     · 顶栏右上角常驻的「账号 + 角色 + 端侧」按钮（主入口）
     · 右下角悬浮按钮（快捷入口，滚动到任何位置都够得着）
   面板本身是 fixed 定位的浮层，与页面滚动、路由跳转无关。
   ============================================================ */

.who{height:38px;padding: 0 var(--sp-2) 0 var(--sp-2);border:1px solid transparent;background:none;
     border-radius:19px;max-width:340px}
.who:hover{background:#f2f4f7;border-color:var(--line2)}
.who .tx{min-width:0;display:flex;flex-direction:column;line-height:1.25;text-align:left}
.who .nm{font-size:13px;color:var(--ink);font-weight:500;white-space:nowrap}
.who .cr{font-size:10.5px;color:var(--ink3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:230px}
.who .endbdg{font-size:10px;font-weight:600;padding: var(--sp-hair) var(--sp-2);border-radius:4px;flex:none;
             background:var(--pri-soft);color:var(--pri)}
body.end-admin .who .endbdg{background:#efedfd;color:#5b4bdb}
.who .chev{color:var(--ink4);display:flex;flex:none}


/* ───────── 右侧可拖拽常驻悬浮窗（需求12） ───────── */
/* 容器 pointer-events:none：除按钮外不拦截页面点击，避免遮挡内容；
   按钮 pointer-events:auto 且拖拽用 setPointerCapture 接管，移动中不会丢失事件。 */
.hfab{position:fixed;right:16px;top:50%;transform:translateY(-50%);z-index:40;
  display:flex;flex-direction:column;align-items:center;gap:8px;pointer-events:none;user-select:none}
.hfab .hfab-h{display:flex;align-items:center;justify-content:center;width:42px;height:14px;
  color:var(--ink4);pointer-events:auto;cursor:grab}
.hfab .hfab-b{width:42px;height:42px;border:0;border-radius:50%;cursor:pointer;
  background:var(--card);color:var(--pri);box-shadow:0 2px 10px rgba(31,35,41,.16);
  display:flex;align-items:center;justify-content:center;pointer-events:auto;transition:transform .12s,box-shadow .12s}
.hfab .hfab-b:hover{transform:scale(1.08);box-shadow:0 4px 16px rgba(31,35,41,.24)}
.hfab .hfab-b:active{transform:scale(.96)}
.hfab.dragging{cursor:grabbing}
.hfab.dragging .hfab-h{cursor:grabbing}
body.end-admin .hfab .hfab-b{color:var(--pri)}

/* 客服面板（从右滑出） */
.hfab-panel{position:fixed;top:0;right:0;height:100%;width:320px;max-width:86vw;z-index:86;
  background:var(--card);box-shadow:-8px 0 30px rgba(31,35,41,.18);
  display:flex;flex-direction:column;transform:translateX(100%);transition:transform .2s}
.hfab-panel-h{padding:var(--sp-4) var(--sp-5);font-size:15px;font-weight:600;color:var(--ink);
  border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between}
.hfab-panel-h .hfab-x{border:0;background:none;font-size:22px;line-height:1;color:var(--ink3);cursor:pointer}
.hfab-panel-h .hfab-x:hover{color:var(--dang)}
.hfab-panel-b{padding:var(--sp-5);font-size:13.5px;line-height:1.8;color:var(--ink2)}
.hfab-panel-b a{color:var(--pri)}
.hfab-panel-b .hfab-cta{display:block;margin-top: var(--sp-4);padding: var(--sp-3) var(--sp-4);text-align:center;
  background:var(--pri);color:#fff;border-radius:var(--r);font-weight:600;text-decoration:none}
.hfab-panel-b .hfab-cta:hover{background:var(--pri-deep)}

@media (max-width:520px){
  .hfab{right:10px;gap:6px}
  .hfab .hfab-b{width:38px;height:38px}
}
/* ============================================================
   需求 #452 · 右上角「个人中心」（原「切换身份」面板整体退役）
   仅头像 + 姓名 + 角色；下拉提供 个人信息 / 账户设置 / 修改密码 / 退出登录。
   ============================================================ */
.pc{position:fixed;top:calc(var(--top-h) + 8px);right:14px;z-index:79;
  width:252px;max-width:calc(100vw - 28px);
  background:var(--card);border:1px solid var(--line2);border-radius:var(--r-lg);
  box-shadow:0 14px 40px rgba(31,35,41,.16);overflow:hidden;
  opacity:0;transform:translateY(-6px);transition:opacity .12s,transform .12s}
.pc.on{opacity:1;transform:translateY(0)}
.pc-head{display:flex;gap:11px;align-items:center;padding:var(--sp-4);
  background:var(--pri-soft);border-bottom:1px solid var(--line)}
body.end-admin .pc-head{background:#f4f2fd}
.pc-head .ava{width:40px;height:40px;font-size:16px}
.pc-head .info{flex:1;min-width:0}
.pc-head .r1{font-size:14px;font-weight:600;color:var(--ink)}
.pc-head .r2{font-size:11.5px;color:var(--ink3);margin-top:var(--sp-hair);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pc-menu{padding:var(--sp-2) 0}
.pc-menu a{display:flex;align-items:center;gap:9px;padding:var(--sp-3) var(--sp-4);
  font-size:13px;color:var(--ink);text-decoration:none;cursor:pointer}
.pc-menu a:hover{background:#f4f6f9;color:var(--pri)}
.pc-menu a.dang{color:var(--dang)}
.pc-menu a.dang:hover{background:var(--dang-soft)}
.pc-menu a svg{flex:none;color:var(--ink3)}
.pc-menu a:hover svg{color:currentColor}
.pc-div{height:1px;background:var(--line);margin:var(--sp-2) 0}

/* 个人信息 / 账户设置（抽屉内排版） */
.pcp-head{display:flex;gap:12px;align-items:center;padding-bottom:var(--sp-4);
  border-bottom:1px solid var(--line);margin-bottom:var(--sp-4)}
.pcp-head .ava{width:48px;height:48px;font-size:19px}
.pcp-head .nm{font-size:16px;font-weight:600;color:var(--ink)}
.pcp-head .cr{font-size:12.5px;color:var(--ink3);margin-top:var(--sp-hair)}
.pcp-rows{display:flex;flex-direction:column}
.pcp-row{display:flex;align-items:center;gap:12px;padding:var(--sp-3) 0;
  border-bottom:1px solid var(--line)}
.pcp-row .k{width:84px;flex:none;font-size:12.5px;color:var(--ink3)}
.pcp-row .v{flex:1;font-size:13.5px;color:var(--ink)}
.pcp-form label{display:block;font-size:12.5px;color:var(--ink2);margin-bottom:var(--sp-4)}
.pcp-form input{display:block;width:100%;margin-top:var(--sp-1);height:36px;padding:0 var(--sp-3);
  border:1px solid var(--line2);border-radius:var(--r);font-size:13.5px;box-sizing:border-box}

/* 权限点标签（审计页仍在用，保留） */
.pgrid{display:flex;flex-wrap:wrap;gap:4px}
.pgrid .pt{font-size:11px;font-family:ui-monospace,monospace;padding: var(--sp-hair) var(--sp-2);border-radius:4px;
  background:#f2f4f8;color:var(--ink2)}
.pgrid .pt.hot{background:var(--ok-soft);color:var(--ok)}

/* 无权限提示 */
.pguard{background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);
  padding: var(--sp-8) var(--sp-6);text-align:center;max-width:560px;margin: var(--sp-8) auto}
.pguard .i{width:46px;height:46px;border-radius:50%;background:var(--warn-soft);color:var(--warn);
  display:flex;align-items:center;justify-content:center;margin: 0 auto var(--sp-4)}
.pguard h2{margin:0 0 var(--sp-2);font-size:17px;font-weight:600}
.pguard p{margin:0 0 var(--sp-2);color:var(--ink2);font-size:13px}
.pguard code{background:#f2f4f8;padding: var(--sp-hair) var(--sp-2);border-radius:4px}
.pguard .acts{margin-top:var(--sp-5);display:flex;gap:9px;justify-content:center}

/* 查询条（审计页复用） */
.qbar{display:flex;gap:9px;flex-wrap:wrap;align-items:center}
.qbar .fi{display:flex;flex-direction:column;gap:4px;min-width:118px}
.qbar .fi > label{font-size:11.5px;color:var(--ink3)}
.qbar select,.qbar input{height:31px;padding: 0 var(--sp-2);border:1px solid var(--line2);
  border-radius:var(--r);font:inherit;font-size:12.5px;background:var(--card);
  outline:none;color:var(--ink);min-width:0}
.qbar select:focus,.qbar input:focus{border-color:var(--pri)}
.qbar .sp{flex:1}
.audit-d{font-size:11.5px;color:var(--ink3);max-width:330px;line-height:1.55;
  word-break:break-word}
.audit-d code{font-size:11px}

/* ============================================================
   边界凭据表单（v2.2）
   应用自己接管的 Basic 凭据输入层：取代浏览器反复弹出的原生弹窗。
   表单字段刻意符合密码管理器识别规则（type/name/autocomplete），
   以便「可保存、可自动填充」。
   ============================================================ */

.gate-mask{position:fixed;inset:0;z-index:120;background:rgba(31,35,41,.28);
  display:flex;align-items:center;justify-content:center;padding: var(--sp-5);
  -webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
.gate-box{width:100%;max-width:392px;background:var(--card);border:1px solid var(--line2);
  border-radius:var(--r-xl);box-shadow:0 18px 48px rgba(31,35,41,.20);padding: var(--sp-6) var(--sp-6) var(--sp-6)}
.gate-box .gh{font-size:17px;font-weight:600;margin-bottom: var(--sp-2)}
.gate-box .gd{font-size:12.5px;color:var(--ink2);line-height:1.7;margin: 0 0 var(--sp-4)}
.gate-box .gl{display:block;font-size:12px;color:var(--ink3);margin: 0 0 var(--sp-1)}
.gate-box .gi{width:100%;height:38px;padding: 0 var(--sp-3);border:1px solid var(--line2);
  border-radius:var(--r);font:inherit;font-size:13.5px;outline:none;background:var(--card);
  color:var(--ink);margin-bottom: var(--sp-3)}
.gate-box .gi:focus{border-color:var(--pri)}
.gate-box .gsubmit{width:100%;height:38px;margin-top: var(--sp-1);font-size:13.5px}
.gate-box .gerr{font-size:12.5px;color:var(--dang);background:var(--dang-soft);
  border-radius:var(--r);padding: var(--sp-2) var(--sp-3);margin: 0 0 var(--sp-4);line-height:1.6}
.gate-box .gnote{font-size:11.5px;color:var(--ink3);line-height:1.7;margin-top: var(--sp-4);
  padding-top: var(--sp-3);border-top:1px solid var(--line)}

/* ---- 工作汇报（v3.0）：AI 输出与结构化清单样式 ---- */
.callout{border-left:3px solid var(--pri);background:#f6f9ff;padding: var(--sp-3) var(--sp-3);
  border-radius:8px;font-size:13.5px;line-height:1.7;color:var(--ink)}
.callout.ok{border-left-color:var(--ok);background:#f3fbf5}
.callout.warn{border-left-color:var(--warn);background:#fff8ec}
.callout.dang{border-left-color:var(--dang);background:#fdf2f2}
.pre{background:#f7f9fc;border:1px solid var(--line2);border-radius:8px;padding: var(--sp-3) var(--sp-3);
  font-size:13px;color:var(--ink2)}
.adv,.tdl{margin:0;padding-left: var(--sp-5);line-height:1.85;font-size:13.5px;color:var(--ink)}
.adv li,.tdl li{margin:var(--sp-1) 0}
.adv li::marker{color:var(--pri);font-weight:600}
.tdl li::marker{color:var(--ok);font-weight:600}

/* ============================================================
   软导航（SPA 式局部刷新）——2026-09-25
   ------------------------------------------------------------
   侧边栏点击不再整页刷新，浏览器原生的「加载中」提示随之消失，
   所以必须自己补两件事：进度反馈 + 内容切换的可感知性。
   没有这两样，用户会把「局部刷新」体验成「点了没反应」。
   ============================================================ */

/* ---- 顶部细进度条：软导航进行中的唯一视觉信号 ---- */
#hw-prog{
  position:fixed;top:0;left:0;right:0;height:2px;z-index:200;
  background:linear-gradient(90deg,var(--pri) 0%,#7aa5ff 50%,var(--pri) 100%);
  background-size:40% 100%;background-repeat:no-repeat;
  opacity:0;pointer-events:none;transition:opacity .18s ease;
}
#hw-prog.on{opacity:1;animation:hwProgRun 1.1s linear infinite}
@keyframes hwProgRun{
  from{background-position:-40% 0}
  to{background-position:140% 0}
}

/* ---- 内容切换：只让内容区轻微上浮淡入，侧边栏与顶栏纹丝不动 ----
   这本身就是「页面没重载」的视觉证据：动的只有内容区。 */
@keyframes hwContentIn{
  from{opacity:0;transform:translateY(4px)}
  to{opacity:1;transform:none}
}
#hw-content > .phead,
#hw-content > #hw-pg,
#hw-content > .pguard,
#hw-content > .guide{animation:hwContentIn .16s ease-out}

/* 尊重系统「减少动态效果」设置 */
@media (prefers-reduced-motion:reduce){
  #hw-prog.on{animation:none;background-position:0 0;background-size:100% 100%}
  #hw-content > .phead,
  #hw-content > #hw-pg,
  #hw-content > .pguard,
  #hw-content > .guide{animation:none}
}

/* ============================================================
   统一 UI 组件（HW.ui.modal / filePick / progress / row）
   —— 各业务板块的上传 / 下载 / 列表共享同一套样式与交互
   ============================================================ */

/* ---- 模态框（HW.ui.modal / filePick） ---- */
/* 与抽屉同理：基础态必须 pointer-events:none，遮罩关闭时只靠 opacity 隐藏、DOM 不移除，
   否则会盖在页面上吃点击（参考 2026-09-25 抽屉事故）。z-index 高于抽屉(60)。 */
.modal-mask{position:fixed;inset:0;background:rgba(31,35,41,.32);z-index:80;opacity:0;
           pointer-events:none;transition:opacity .18s ease;
           display:flex;align-items:center;justify-content:center;padding: var(--sp-5)}
.modal-mask.on{opacity:1;pointer-events:auto}
.modal{width:560px;max-width:94vw;max-height:90vh;display:flex;flex-direction:column;
       background:var(--card);border-radius:var(--r-xl);
       box-shadow:0 12px 40px rgba(31,35,41,.18);
       transform:translateY(12px) scale(.98);transition:transform .18s ease;overflow:hidden}
.modal-mask.on .modal{transform:none}
.modal .mh{flex:none;display:flex;align-items:center;gap:10px;padding: var(--sp-4) var(--sp-5);border-bottom:1px solid var(--line)}
.modal .mh h3{margin:0;font-size:15px;font-weight:600;flex:1}
.modal .mb{flex:1;overflow-y:auto;padding: var(--sp-4) var(--sp-5)}
.modal .mf{flex:none;padding: var(--sp-3) var(--sp-5);border-top:1px solid var(--line);
          display:flex;gap:8px;justify-content:flex-end;flex-wrap:wrap}

/* ---- 上传进度条（HW.ui.filePick / progress） ---- */
.ui-prog{height:8px;border-radius:5px;background:#eef0f4;overflow:hidden}
.ui-prog i{display:block;height:100%;width:0;border-radius:5px;background:var(--pri);transition:width .2s ease}
.ui-prog i.ok{background:var(--ok)}
.ui-prog i.dang{background:var(--dang)}
.ui-prog i.ind{width:40%;animation:uipi 1.1s ease-in-out infinite}
@keyframes uipi{0%{margin-left:-40%}100%{margin-left:100%}}

/* ---- 拖拽上传区（HW.ui.filePick） ---- */
.dropzone{border:1.5px dashed var(--line2);border-radius:var(--r-lg);padding: var(--sp-6) var(--sp-5);text-align:center;
          background:#fafbfc;transition:border-color .15s,background .15s}
.dropzone.dz-over{border-color:var(--pri);background:var(--pri-soft)}
.dropzone .dz-ic{color:var(--pri);display:flex;justify-content:center;margin-bottom: var(--sp-2)}
.dropzone .dz-t{font-size:13.5px;color:var(--ink);margin-bottom: var(--sp-1)}
.dropzone .dz-s{margin:var(--sp-2) 0 var(--sp-4)}

/* ---- 文件格式校验提示（HW.ui.filePick） ---- */
.file-err{display:flex;align-items:center;gap:6px;margin-top: var(--sp-3);padding: var(--sp-2) var(--sp-3);border-radius:var(--r);
          background:var(--dang-soft);color:#a3231a;font-size:12.5px;line-height:1.5}
.file-err svg{width:15px;height:15px;flex:none}
