/* =====================================================================
   app.css —— 可移动烟支缺陷检测系统 网页仿真
   外壳：工业深色主题；人机界面视图：论文 4.2 描述的 Material Design 浅色主题
   ===================================================================== */
:root{
  --bg:#0b0e14; --bg2:#11161f; --panel:#151b26; --panel2:#1a2230;
  --line:rgba(255,255,255,.075); --line2:rgba(255,255,255,.14);
  --txt:#e4e9f2; --txt2:#9aa7bd; --txt3:#6b7789;
  --acc:#4db8ff; --acc2:#63f5c8; --good:#2fbf71; --warn:#e8a33a; --bad:#e2554f;
  --purple:#b083d6; --amber:#ffc14d;
  --r:10px; --r2:7px;
  --font:"Segoe UI","Microsoft YaHei","PingFang SC",system-ui,-apple-system,sans-serif;
  --mono:"JetBrains Mono","Consolas","Courier New",monospace;
}
*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;background:var(--bg);color:var(--txt);font-family:var(--font);font-size:13px;
  display:grid;grid-template-columns:214px 1fr 348px;grid-template-rows:62px 1fr;
  overflow:hidden;
}
body.dock-collapsed{grid-template-columns:214px 1fr 46px}
body.dock-collapsed .dock-scroll{display:none}
body.dock-collapsed .dock-title{display:none}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:rgba(255,255,255,.13);border-radius:6px}
::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.24)}

/* ---------------- 顶栏 ---------------- */
.top{
  grid-column:1/-1;grid-row:1;display:flex;align-items:center;gap:18px;
  padding:0 16px;background:linear-gradient(180deg,#151d29,#101620);
  border-bottom:1px solid var(--line2);z-index:20;
}
.brand{display:flex;align-items:center;gap:11px;min-width:0}
.brand-mark{
  width:36px;height:36px;border-radius:9px;flex:0 0 auto;
  background:linear-gradient(140deg,#4db8ff,#2fbf71);color:#08121b;
  display:grid;place-items:center;font-weight:800;font-size:13px;letter-spacing:.5px;
}
.brand-txt{min-width:0}
.brand-t{font-size:14px;font-weight:650;letter-spacing:.2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.brand-s{font-size:10.5px;color:var(--txt3);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.top-stats{display:flex;gap:6px;margin-left:auto;flex:0 1 auto;overflow:hidden}
.tstat{
  min-width:66px;padding:5px 9px;border-radius:var(--r2);background:rgba(255,255,255,.04);
  border:1px solid var(--line);text-align:center;
}
.tstat-v{font-size:13.5px;font-weight:670;font-family:var(--mono);line-height:1.15}
.tstat-k{font-size:9.5px;color:var(--txt3);margin-top:2px;white-space:nowrap}
.tstat.good .tstat-v{color:var(--good)}
.tstat.warn .tstat-v{color:var(--warn)}
.tstat.bad .tstat-v{color:var(--bad)}
.top-ctrl{display:flex;align-items:center;gap:8px;flex:0 0 auto}

/* ---------------- 按钮 ---------------- */
.btn{
  border:1px solid var(--line2);background:rgba(255,255,255,.05);color:var(--txt);
  padding:6px 11px;border-radius:var(--r2);cursor:pointer;font-family:inherit;font-size:12px;
  transition:background .13s,border-color .13s,transform .06s;
}
.btn:hover{background:rgba(255,255,255,.10);border-color:rgba(255,255,255,.26)}
.btn:active{transform:translateY(1px)}
.btn.on,.btn-primary{background:rgba(77,184,255,.18);border-color:rgba(77,184,255,.55);color:#cfeaff}
.btn-sm{padding:4px 8px;font-size:11px}
.btn-run{background:rgba(47,191,113,.18);border-color:rgba(47,191,113,.5);color:#a8f0c8;font-weight:600}
.btn-run.on{background:rgba(232,163,58,.2);border-color:rgba(232,163,58,.55);color:#ffdca0}
.seg-row{display:flex;border:1px solid var(--line2);border-radius:var(--r2);overflow:hidden}
.seg{
  border:0;background:transparent;color:var(--txt2);padding:6px 9px;cursor:pointer;
  font-family:inherit;font-size:11px;border-right:1px solid var(--line);
}
.seg:last-child{border-right:0}
.seg:hover{background:rgba(255,255,255,.07);color:var(--txt)}
.seg.on{background:rgba(77,184,255,.22);color:#d3ecff}

/* ---------------- 左侧导航 ---------------- */
.rail{
  grid-column:1;grid-row:2;background:var(--bg2);border-right:1px solid var(--line);
  padding:10px 8px;display:flex;flex-direction:column;gap:4px;overflow-y:auto;
}
.rail-btn{
  display:flex;align-items:center;gap:9px;text-align:left;
  border:1px solid transparent;background:transparent;color:var(--txt2);
  padding:8px 9px;border-radius:var(--r2);cursor:pointer;font-family:inherit;
  transition:background .13s,color .13s;
}
.rail-btn:hover{background:rgba(255,255,255,.05);color:var(--txt)}
.rail-btn.on{background:rgba(77,184,255,.13);border-color:rgba(77,184,255,.32);color:#dcefff}
.rail-icon{font-size:15px;width:18px;text-align:center;flex:0 0 auto;opacity:.9}
.rail-txt{display:flex;flex-direction:column;min-width:0}
.rail-name{font-size:12.5px;font-weight:600}
.rail-sub{font-size:9.5px;color:var(--txt3);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rail-btn.on .rail-sub{color:rgba(160,200,235,.75)}

/* ---------------- 舞台 ---------------- */
.stage{grid-column:2;grid-row:2;position:relative;overflow:hidden;background:var(--bg)}
.view{position:absolute;inset:0;display:none;overflow:auto;padding:12px}
.view.on{display:block}
.view[data-view="platform"]{padding:0}
.view[data-view="platform"].on{display:block}

/* ---------------- 卡片 ---------------- */
.card{
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:11px 13px;margin-bottom:11px;
}
.card.tight{padding:9px 10px;margin-bottom:9px}
.card.grow{display:flex;flex-direction:column;min-height:0;flex:1}
.card-title{font-size:12.5px;font-weight:650;color:#e8eef7;margin-bottom:7px;letter-spacing:.2px}
.card-title-row{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
.card-title-row .card-title{margin-bottom:0}
.card-hint{font-size:11px;color:var(--txt3);line-height:1.65;margin-bottom:8px}
.card-body{font-size:12px;color:var(--txt2)}
.chart-box{position:relative;width:100%;margin-top:4px}
.table-box{overflow:auto;max-height:520px;margin-top:4px}
.muted{color:var(--txt3)}
.small{font-size:11px}
.pad{padding:14px}
.grow{flex:1;min-height:0}

.kpi-row{display:flex;flex-wrap:wrap;gap:7px;margin-top:8px}
.kpi{
  flex:1 1 92px;min-width:88px;background:rgba(255,255,255,.035);border:1px solid var(--line);
  border-radius:var(--r2);padding:7px 9px;text-align:center;
}
.kpi-v{font-family:var(--mono);font-size:15px;font-weight:670;line-height:1.2}
.kpi-k{font-size:10px;color:var(--txt3);margin-top:3px}
.kpi.good .kpi-v{color:var(--good)} .kpi.warn .kpi-v{color:var(--warn)} .kpi.bad .kpi-v{color:var(--bad)}

.notice{margin-top:9px;padding:8px 11px;border-radius:var(--r2);font-size:11.5px;line-height:1.65;border-left:3px solid}
.notice.good{background:rgba(47,191,113,.09);border-color:var(--good);color:#a9e8c5}
.notice.warn{background:rgba(232,163,58,.09);border-color:var(--warn);color:#f0d6a4}
.notice.bad{background:rgba(226,85,79,.10);border-color:var(--bad);color:#f0b5b1}

.tag-row{display:flex;flex-wrap:wrap;gap:5px;margin:7px 0}
.tag{
  font-size:10.5px;padding:2.5px 7px;border-radius:20px;background:rgba(255,255,255,.06);
  border:1px solid var(--line2);color:var(--txt2);
}
.tag.zone-0{background:rgba(154,167,189,.13);border-color:rgba(154,167,189,.4)}
.tag.zone-1{background:rgba(99,245,200,.12);border-color:rgba(99,245,200,.4);color:#a8f4dd}
.tag.zone-2{background:rgba(77,184,255,.12);border-color:rgba(77,184,255,.4);color:#bfe2ff}
.tag.zone-3{background:rgba(255,91,110,.12);border-color:rgba(255,91,110,.4);color:#ffc2c8}
.btn-row{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.btn-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(72px,1fr));gap:5px}
.chk-row{display:flex;flex-wrap:wrap;gap:9px;margin-top:9px}
.chk,.switch-row{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--txt2);cursor:pointer}
.chk input,.switch-row input{accent-color:var(--acc)}

.info-name{font-size:13px;font-weight:650;color:#eef3fa}
.info-model{font-size:11px;color:var(--acc);font-family:var(--mono);margin-top:3px}
.info-fn{font-size:11.5px;color:var(--txt2);line-height:1.7;margin-top:7px}
.info-sub{font-size:11px;font-weight:600;color:#cdd8e6;margin-top:9px}
.info-specs{margin:6px 0 0;padding-left:16px;font-size:11px;color:var(--txt2);line-height:1.75}
.info-why{font-size:11px;color:#c9d6e6;line-height:1.7;margin-top:7px;padding:6px 9px;
  background:rgba(77,184,255,.07);border-left:2px solid rgba(77,184,255,.5);border-radius:0 var(--r2) var(--r2) 0}
.info-src{font-size:10px;color:var(--txt3);margin-top:7px;font-family:var(--mono)}
.verdict{display:inline-block;font-size:10.5px;padding:3px 8px;border-radius:20px;margin:7px 5px 0 0}
.verdict.good{background:rgba(47,191,113,.16);color:#a9e8c5;border:1px solid rgba(47,191,113,.4)}
.verdict.bad{background:rgba(226,85,79,.16);color:#f0b5b1;border:1px solid rgba(226,85,79,.4)}

/* ---------------- 表格 ---------------- */
.mini-table{width:100%;border-collapse:collapse;font-size:11.5px;margin-top:5px}
.mini-table th{
  text-align:left;padding:5px 7px;font-size:10.5px;color:var(--txt3);font-weight:600;
  border-bottom:1px solid var(--line2);white-space:nowrap;
}
.mini-table td{padding:4.5px 7px;border-bottom:1px solid var(--line);vertical-align:top}
.mini-table td.k{color:var(--txt3);white-space:nowrap;width:1%}
.mini-table td.v{color:var(--txt);font-family:var(--mono)}
.mini-table td.v.on{color:var(--good);font-weight:650}
.mini-table td.n{color:var(--txt3);font-size:10.5px;line-height:1.6}
.mini-table.wide td.v{font-family:inherit}
.mini-table tr.sel-row td{background:rgba(77,184,255,.08)}
.mini-table tr:hover td{background:rgba(255,255,255,.025)}

.heat-table{border-collapse:collapse;font-size:11px;width:100%}
.heat-table th{
  position:sticky;top:0;background:#1a2230;padding:6px 8px;font-size:10.5px;color:var(--txt2);
  border-bottom:1px solid var(--line2);white-space:nowrap;z-index:2;
}
.heat-table td{padding:4.5px 8px;border-bottom:1px solid var(--line);font-family:var(--mono);text-align:center;white-space:nowrap}
.heat-table td.sticky-col,.heat-table th.sticky-col{
  position:sticky;left:0;background:#161d29;text-align:left;font-family:inherit;z-index:1;
}
.heat-table td.row-head{color:var(--txt2);font-size:11px}
.heat-table td.row-head .cw{color:var(--txt3);font-family:var(--mono);font-size:9.5px;margin-left:6px}
.heat-table td.best{font-weight:750;color:#fff;box-shadow:inset 0 0 0 1px rgba(255,255,255,.34)}

/* ---------------- 图表附件 ---------------- */
.chart-tip{
  position:absolute;display:none;pointer-events:none;background:rgba(12,17,25,.95);
  border:1px solid var(--line2);border-radius:6px;padding:5px 8px;font-size:10.5px;
  color:var(--txt);z-index:6;white-space:nowrap;
}
.legend-row{display:flex;flex-wrap:wrap;gap:12px;margin-top:6px;font-size:10.5px;color:var(--txt3)}
.lg{display:flex;align-items:center;gap:5px}
.lg i{width:10px;height:3px;border-radius:2px;display:inline-block}
.barlist-row{display:flex;align-items:center;gap:8px;margin-bottom:5px}
.barlist-label{flex:0 0 104px;font-size:11px;color:var(--txt2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.barlist-track{flex:1;height:9px;background:rgba(255,255,255,.05);border-radius:6px;overflow:hidden}
.barlist-fill{height:100%;border-radius:6px;transition:width .3s}
.barlist-val{flex:0 0 auto;font-size:10.5px;color:var(--txt3);font-family:var(--mono);white-space:nowrap}

/* =====================================================================
   平台三维
   ===================================================================== */
.p3d-layout{position:absolute;inset:0;display:grid;grid-template-columns:266px 1fr}
.p3d-side{
  background:var(--bg2);border-right:1px solid var(--line);overflow-y:auto;padding:10px;
  display:flex;flex-direction:column;
}
.p3d-canvas{position:relative;overflow:hidden;background:#0d1017}
.p3d-canvas canvas{display:block}
.label-layer{position:absolute;inset:0;pointer-events:none;overflow:hidden}
.p3d-label{
  font-family:var(--font);font-size:10px;color:#cfe2f5;background:rgba(10,15,22,.72);
  border:1px solid rgba(140,180,220,.3);border-radius:4px;padding:1.5px 5px;white-space:nowrap;
  transform:translate(-50%,-50%);
}
.p3d-station{
  font-family:var(--font);font-size:10px;font-weight:600;color:#0b1118;
  background:rgba(99,245,200,.88);border-radius:4px;padding:2px 6px;white-space:nowrap;
  transform:translate(-50%,-160%);
}
.range-row{margin-bottom:9px}
.range-top{display:flex;justify-content:space-between;font-size:11px;color:var(--txt2);margin-bottom:4px;gap:6px}
.range-val{font-family:var(--mono);color:var(--acc);font-size:11px;white-space:nowrap}
.range-row input[type=range]{width:100%;accent-color:var(--acc);height:16px}
.range-hint{font-size:9.5px;color:var(--txt3);margin-top:3px;line-height:1.5}
div.sel-row{margin-bottom:9px}
.sel-label{display:block;font-size:11px;color:var(--txt2);margin-bottom:4px}
div.sel-row select{
  width:100%;background:var(--panel2);color:var(--txt);border:1px solid var(--line2);
  border-radius:var(--r2);padding:5px 7px;font-family:inherit;font-size:11.5px;
}
.bom-tree{overflow-y:auto;flex:1;min-height:120px}
.bom-zone{margin-bottom:8px}
.bom-zone-head{
  display:flex;align-items:center;gap:6px;padding:5px 6px;border-radius:var(--r2);
  background:rgba(255,255,255,.045);font-size:11.5px;font-weight:600;color:#d5e0ee;
}
.bom-zone-head input{accent-color:var(--acc2)}
.bom-zone-name{flex:1}
.bom-count{font-size:9.5px;color:var(--txt3);font-family:var(--mono)}
.bom-part{
  display:flex;align-items:flex-start;gap:6px;padding:4px 6px 4px 14px;border-radius:var(--r2);
  cursor:pointer;border:1px solid transparent;
}
.bom-part:hover,.bom-part.hover{background:rgba(255,255,255,.05)}
.bom-part.sel{background:rgba(77,184,255,.14);border-color:rgba(77,184,255,.36)}
.bom-part input{margin-top:2px;accent-color:var(--acc)}
.bom-part-txt{min-width:0}
.bom-part-name{font-size:11px;color:var(--txt);line-height:1.4}
.bom-part-model{font-size:9.5px;color:var(--txt3);font-family:var(--mono);margin-top:1px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:186px}

/* =====================================================================
   电气原理
   ===================================================================== */
.elec-wrap{display:grid;grid-template-columns:1fr 292px;gap:11px;align-items:start}
.elec-main{min-width:0}
.elec-side{display:flex;flex-direction:column;min-width:0}
/* 舞台宽度 = 视口 − 214 − 348：视口较窄时让原理图占满整宽，保证节点文字可读 */
@media (max-width:1560px){
  .elec-wrap{grid-template-columns:1fr}
  .elec-side{display:grid;grid-template-columns:repeat(auto-fit,minmax(238px,1fr));gap:11px;align-items:start}
  .log-body{max-height:240px}
}
.svg-box{width:100%}
.svg-box svg{width:100%;height:auto;display:block}
.enode{cursor:pointer}
.enode-bg{fill:#1b2331;stroke:rgba(255,255,255,.16);stroke-width:1}
.enode:hover .enode-bg{fill:#222d3e;stroke:rgba(255,255,255,.36)}
.enode.sel .enode-bg{fill:#1d3348;stroke:#4db8ff;stroke-width:1.8}
.zone-detect .enode-bg{stroke:rgba(99,245,200,.4)}
.zone-control .enode-bg{stroke:rgba(77,184,255,.4)}
.zone-exec .enode-bg{stroke:rgba(255,91,110,.4)}
.zone-trans .enode-bg{stroke:rgba(200,210,225,.3)}
.enode-t{fill:#e6ecf5;font-size:12px;font-weight:600;font-family:var(--font)}
.enode-m{fill:#8b9bb1;font-size:9.5px;font-family:var(--mono)}
.enode-z{fill:#6b7789;font-size:8.5px;font-family:var(--font)}
.edge-label{font-family:var(--font);paint-order:stroke;stroke:#0b0e14;stroke-width:3px;stroke-linejoin:round}
.scope-box{width:100%;margin-top:4px}
.chain-body{display:flex;flex-direction:column;gap:4px}
.chain-item{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--txt2)}
.chain-idx{
  width:18px;height:18px;flex:0 0 auto;border-radius:5px;background:rgba(77,184,255,.16);
  color:#bfe2ff;display:grid;place-items:center;font-size:10px;font-family:var(--mono);
}
.log-body{overflow-y:auto;max-height:340px;flex:1;font-size:10.5px}
.log-row{display:flex;gap:7px;padding:3px 0;border-bottom:1px solid rgba(255,255,255,.04);line-height:1.5}
.log-t{flex:0 0 62px;font-family:var(--mono);color:var(--txt3);font-size:9.5px}
.log-x{color:var(--txt2);min-width:0}
.log-row.k-trigger .log-x{color:#8ef0d5}
.log-row.k-infer .log-x{color:#bfe2ff}
.log-row.k-mark .log-x{color:#a6d2ff}
.log-row.k-do .log-x{color:#ffc2c8}
.log-row.k-err .log-x{color:#ff8f98}
.log-row.k-timeout .log-x{color:#ffd08a}
.log-row.k-idle .log-x{color:var(--txt3)}
.log-row.k-sync .log-x{color:#e8d49a}

/* =====================================================================
   工作流程
   ===================================================================== */
.wf-flow{display:flex;align-items:stretch;gap:2px;overflow-x:auto;padding-bottom:4px}
.wf-stage{
  flex:1 1 0;min-width:112px;background:rgba(255,255,255,.035);border:1px solid var(--line);
  border-radius:var(--r2);padding:8px 9px;cursor:pointer;position:relative;
  transition:background .16s,border-color .16s;
}
.wf-stage:hover{background:rgba(255,255,255,.07)}
.wf-stage.sel{border-color:rgba(77,184,255,.55);background:rgba(77,184,255,.10)}
.wf-stage.active{border-color:rgba(99,245,200,.6);box-shadow:0 0 0 1px rgba(99,245,200,.22) inset}
.wf-idx{
  width:19px;height:19px;border-radius:5px;background:rgba(77,184,255,.18);color:#bfe2ff;
  display:grid;place-items:center;font-size:10px;font-family:var(--mono);margin-bottom:5px;
}
.wf-name{font-size:12px;font-weight:620;color:#e6ecf5}
.wf-chain{font-size:9.5px;color:var(--txt3);margin-top:3px;line-height:1.4;min-height:26px}
.wf-meter{height:3px;background:rgba(255,255,255,.07);border-radius:3px;overflow:hidden;margin-top:5px}
.wf-meter-fill{height:100%;width:0;background:linear-gradient(90deg,#63f5c8,#4db8ff);transition:width .12s}
.wf-count{font-size:9.5px;color:var(--txt3);font-family:var(--mono);margin-top:4px;text-align:right}
.wf-arrow{display:grid;place-items:center;color:var(--txt3);font-size:16px;flex:0 0 12px}
.wf-grid{display:grid;grid-template-columns:1fr 1fr;gap:11px;align-items:start}
.slot-canvas-box{width:100%;margin-top:4px}
.valve-box{width:100%}
.valve-verdict{display:flex;flex-wrap:wrap;gap:4px}
.gantt-box{width:100%}
@media (max-width:1560px){.wf-grid{grid-template-columns:1fr}}

/* =====================================================================
   检测算法
   ===================================================================== */
.alg-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:11px;align-items:start}
.alg-grid-2.tight{gap:8px}
@media (max-width:1520px){.alg-grid-2{grid-template-columns:1fr}}
.model-pick{display:grid;grid-template-columns:repeat(auto-fit,minmax(174px,1fr));gap:8px}
.mp{
  border:1px solid var(--line2);border-radius:var(--r2);padding:9px 10px;cursor:pointer;
  background:rgba(255,255,255,.03);transition:background .14s,border-color .14s,transform .08s;
  border-left:3px solid var(--mc);
}
.mp:hover{background:rgba(255,255,255,.07);transform:translateY(-1px)}
.mp.sel{background:color-mix(in srgb,var(--mc) 14%,transparent);border-color:var(--mc);
  box-shadow:0 0 0 1px var(--mc) inset}
.mp-head{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.mp-name{font-size:12px;font-weight:640;color:#e8eef7}
.mp-badge{font-size:9px;padding:1.5px 5px;border-radius:20px;background:rgba(47,191,113,.2);color:#a9e8c5}
.mp-kv{display:flex;align-items:baseline;gap:5px;margin-top:5px}
.mp-map{font-family:var(--mono);font-size:18px;font-weight:700;color:var(--mc)}
.mp-lab{font-size:9.5px;color:var(--txt3)}
.mp-meta{display:flex;gap:9px;font-size:10px;color:var(--txt3);margin-top:3px}
.mp-cx{font-size:9.5px;color:var(--txt3);font-family:var(--mono);margin-top:4px}
.mp-note{font-size:10px;color:var(--txt2);line-height:1.6;margin-top:5px}
.net-box{display:flex;gap:8px;align-items:flex-start;overflow-x:auto;padding:6px 0}
.net-col{flex:1 1 0;min-width:158px}
.net-col-title{font-size:10.5px;color:var(--txt3);margin-bottom:6px;text-align:center;
  padding-bottom:4px;border-bottom:1px solid var(--line)}
.net-node{
  position:relative;background:rgba(255,255,255,.04);border:1px solid var(--line2);
  border-radius:6px;padding:5px 8px;margin-bottom:4px;cursor:pointer;transition:background .13s;
}
.net-node:hover{background:rgba(255,255,255,.09)}
.net-node-name{font-size:11px;font-weight:600;color:#e2e9f2}
.net-node-sub{font-size:9.5px;color:var(--txt3);font-family:var(--mono);margin-top:2px}
.net-node.m-Conv{border-left:3px solid #6b7789}
.net-node.m-C3k2{border-left:3px solid #4db8ff}
.net-node.m-SPPF{border-left:3px solid #e8a33a}
.net-node.m-C2PSA{border-left:3px solid #b083d6}
.net-node.m-Upsample{border-left:3px solid #63f5c8}
.net-node.m-Concat{border-left:3px solid #8a93a8}
.net-node.m-Detect{border-left:3px solid #e2554f}
.net-tap{position:absolute;right:6px;top:5px;font-size:8.5px;color:#ffd68a;font-family:var(--mono)}
.net-oa{position:absolute;right:6px;bottom:4px;font-size:8.5px;padding:0 4px;border-radius:3px;
  background:rgba(176,131,214,.28);color:#dcc4f0;font-family:var(--mono)}
.net-sep{display:grid;place-items:center;color:var(--txt3);font-size:15px;padding-top:40px}
.mod-detail{margin-top:6px;padding-top:8px;border-top:1px solid var(--line)}
.loss-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(258px,1fr));gap:9px;margin-bottom:9px}
.loss-card{background:rgba(255,255,255,.03);border:1px solid var(--line);border-radius:var(--r2);padding:9px 10px}
.loss-name{font-size:12px;font-weight:640;color:#e8eef7}
.loss-formula{font-family:var(--mono);font-size:10.5px;color:var(--acc2);margin-top:6px;line-height:1.65;
  background:rgba(0,0,0,.28);padding:6px 8px;border-radius:5px;overflow-x:auto}
.loss-terms{margin:6px 0 0;padding-left:15px;font-size:10.5px;color:var(--txt3);line-height:1.7}
.loss-issue{font-size:10.5px;color:var(--txt2);line-height:1.7;margin-top:7px}
.cls-grid{display:grid;grid-template-columns:1fr;gap:2px;margin-top:6px}
.cls-item{display:flex;align-items:center;gap:7px;padding:3.5px 6px;border-radius:5px;font-size:11px}
.cls-item:hover{background:rgba(255,255,255,.04)}
.cls-item i{width:9px;height:9px;border-radius:2px;flex:0 0 auto}
.cls-id{font-family:var(--mono);color:var(--txt3);width:14px;font-size:10px}
.cls-nm{flex:1;color:var(--txt2)}
.cls-zone{font-size:9.5px;color:var(--txt3)}
.cls-ap{font-family:var(--mono);font-size:9.5px;color:var(--acc)}

/* =====================================================================
   推理部署
   ===================================================================== */
.dep-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:11px;align-items:start}
@media (max-width:1520px){.dep-grid-2{grid-template-columns:1fr}}
.stack{display:flex;flex-direction:column;gap:2px}
.stack-layer{border:1px solid var(--line2);border-radius:var(--r2);padding:9px 11px;background:rgba(255,255,255,.03)}
.stack-layer.l0{border-left:3px solid #b083d6}
.stack-layer.l1{border-left:3px solid #4db8ff}
.stack-layer.l2{border-left:3px solid #2fbf71}
.stack-head{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.stack-idx{width:19px;height:19px;border-radius:5px;background:rgba(255,255,255,.09);
  display:grid;place-items:center;font-size:10px;font-family:var(--mono);color:var(--txt2)}
.stack-layer-name{font-size:12px;font-weight:640;color:#e8eef7}
.stack-title{font-size:10.5px;color:var(--acc);font-family:var(--mono)}
.stack-points{margin:7px 0 0;padding-left:16px;columns:2;column-gap:22px;font-size:10.5px;color:var(--txt2);line-height:1.75}
.stack-arrow{text-align:center;color:var(--txt3);font-size:10px;line-height:1}
@media (max-width:1000px){.stack-points{columns:1}}
.gauge-row{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-top:6px}
.gauge-cell{position:relative}
.pc-box{display:flex;flex-direction:column;gap:5px}
.pc-row{display:flex;align-items:center;gap:8px}
.pc-cam{flex:0 0 46px;font-family:var(--mono);font-size:11px;color:var(--acc2)}
.pc-tag{flex:0 0 96px;font-size:9.5px;color:var(--txt3)}
.pc-queue{flex:1;display:flex;gap:2px}
.pc-cell{flex:1;height:13px;background:rgba(255,255,255,.05);border-radius:2px;transition:background .12s}
.pc-cell.on{background:linear-gradient(180deg,#ffe066,#e8a33a)}
.pc-meta{flex:0 0 34px;text-align:right;font-family:var(--mono);font-size:10.5px;color:var(--txt3)}
.pc-consumer{display:grid;grid-template-columns:1fr 190px;gap:9px;margin-top:8px;
  padding-top:9px;border-top:1px solid var(--line)}
.pc-c-title{font-size:11px;font-weight:600;color:#d8e2ee;margin-bottom:5px}
.pc-c-bar{height:11px;background:rgba(255,255,255,.05);border-radius:6px;overflow:hidden}
.pc-c-fill{height:100%;width:0;background:linear-gradient(90deg,#b083d6,#4db8ff);transition:width .1s}
.pc-c-info{font-size:10.5px;color:var(--txt3);margin-top:5px;font-family:var(--mono)}
.pc-c-info.busy{color:#bfe2ff}
.pc-c-info.idle{color:var(--warn)}
.pc-save-grid{display:flex;gap:4px}
.pc-save-cell{flex:1;height:20px;display:grid;place-items:center;font-size:9.5px;font-family:var(--mono);
  background:rgba(255,255,255,.05);border-radius:4px;color:var(--txt3);transition:background .12s}
.pc-save-cell.on{background:rgba(47,191,113,.25);color:#a9e8c5}
.mode-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(252px,1fr));gap:9px}
.mode-card{background:rgba(255,255,255,.03);border:1px solid var(--line);border-radius:var(--r2);padding:10px 11px}
.mode-name{font-size:12.5px;font-weight:640;color:#e8eef7}
.mode-algo{font-size:10px;color:var(--acc);font-family:var(--mono);margin-top:3px}
.mode-detail{font-size:10.5px;color:var(--txt2);line-height:1.75;margin-top:7px}

/* =====================================================================
   人机界面（论文 4.2：Material Design 浅色主题）
   ===================================================================== */
.hmi-root{
  --h-bg:#eceff4; --h-card:#ffffff; --h-line:#dce1e9; --h-txt:#25303f; --h-txt2:#5c6a7d;
  --h-acc:#1976d2; --h-good:#2e7d32; --h-bad:#c62828; --h-warn:#ef6c00;
  position:absolute;inset:12px;display:flex;flex-direction:column;border-radius:var(--r);
  overflow:hidden;background:var(--h-bg);color:var(--h-txt);
  box-shadow:0 12px 40px rgba(0,0,0,.45);border:1px solid rgba(255,255,255,.1);
}
.hmi-bar{
  display:flex;align-items:center;gap:8px;padding:0 12px;height:44px;flex:0 0 44px;
  background:linear-gradient(180deg,#fdfdfe,#eef1f6);border-bottom:1px solid var(--h-line);
}
.hmi-title{font-size:13px;font-weight:700;color:#1b2634;letter-spacing:.2px}
.hmi-spacer{flex:1}
.hmi-chip{
  font-size:10.5px;padding:3.5px 9px;border-radius:20px;background:#e3e9f1;color:var(--h-txt2);
  font-family:var(--mono);white-space:nowrap;border:1px solid #d6dde7;
}
.hmi-chip.dev{background:#e3f2e6;color:var(--h-good);border-color:#c6e2ca}
.hmi-chip.clock{background:#e8eef8;color:var(--h-acc);border-color:#cfdcf0}
.hmi-body{flex:1;display:grid;grid-template-columns:1fr 336px;gap:9px;padding:9px;min-height:0}
.hmi-left{display:flex;flex-direction:column;min-width:0;min-height:0}
.hmi-tabs{display:flex;gap:3px;flex:0 0 auto}
.hmi-tab{
  padding:6px 14px;font-size:11.5px;color:var(--h-txt2);cursor:pointer;border-radius:7px 7px 0 0;
  background:#e2e7ef;border:1px solid var(--h-line);border-bottom:0;transition:background .13s;
}
.hmi-tab:hover{background:#e9eef5}
.hmi-tab.on{background:var(--h-card);color:var(--h-acc);font-weight:640;box-shadow:0 -2px 0 var(--h-acc) inset}
.hmi-panes{flex:1;background:var(--h-card);border:1px solid var(--h-line);border-radius:0 7px 7px 7px;
  position:relative;min-height:0;overflow:hidden}
.hmi-pane{position:absolute;inset:0;display:none;flex-direction:column;overflow:auto;padding:8px}
.hmi-pane.on{display:flex}
.hmi-stack{flex:1;min-height:0;position:relative}
.hmi-single{position:absolute;inset:0;display:grid;place-items:center;background:#f4f6f9;border-radius:6px}
.hmi-single canvas{border-radius:5px;box-shadow:0 2px 10px rgba(20,30,45,.14)}
.hmi-quad{position:absolute;inset:0;display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr;gap:5px}
.hmi-quad-cell{
  position:relative;background:#f4f6f9;border:1px solid var(--h-line);border-radius:6px;
  display:grid;place-items:center;overflow:hidden;cursor:pointer;
}
.hmi-quad-cell.active{border-color:var(--h-acc);box-shadow:0 0 0 1px var(--h-acc) inset}
.hmi-quad-cell canvas{border-radius:3px}
.hmi-quad-cap{
  position:absolute;left:0;right:0;bottom:0;padding:2.5px 7px;font-size:9.5px;
  background:rgba(20,28,40,.72);color:#e8eef7;font-family:var(--mono);
}
.hmi-infobar{
  display:flex;align-items:center;gap:12px;flex:0 0 auto;padding:6px 4px 0;font-size:10.5px;
  color:var(--h-txt2);flex-wrap:wrap;
}
.ib{font-family:var(--mono)}
.hmi-nav{margin-left:auto;display:flex;align-items:center;gap:6px}
.hmi-navidx{font-family:var(--mono);font-size:10.5px;color:var(--h-txt2)}
.hbtn{
  border:1px solid #ccd4e0;background:#f6f8fb;color:var(--h-txt);padding:5px 10px;border-radius:6px;
  cursor:pointer;font-family:inherit;font-size:11px;transition:background .13s,box-shadow .13s;
}
.hbtn:hover{background:#eaeff7;box-shadow:0 1px 3px rgba(30,45,70,.12)}
.hbtn:active{background:#dfe6f1}
.hbtn.primary{background:var(--h-acc);border-color:#1565c0;color:#fff;font-weight:600}
.hbtn.primary:hover{background:#1a7fdd}
.hbtn.danger{background:var(--h-bad);border-color:#a91d1d;color:#fff}
.hbtn:disabled{background:#e8eaee;color:#a4adb9;cursor:not-allowed}
.hmi-filelist{display:flex;flex-direction:column;gap:1px;font-size:11px}
.hmi-file-head{font-size:10.5px;color:var(--h-txt2);padding:4px 6px 8px}
.hmi-file{display:flex;align-items:center;gap:9px;padding:4px 8px;border-radius:5px;cursor:pointer}
.hmi-file:hover{background:#eef3fa}
.hf-n{flex:1;font-family:var(--mono);font-size:10.5px;color:var(--h-txt)}
.hf-tag{flex:0 0 104px;font-size:10.5px;font-weight:600}
.hf-c{flex:0 0 44px;text-align:right;font-family:var(--mono);font-size:10.5px;color:var(--h-txt2)}
.hmi-table{width:100%;border-collapse:collapse;font-size:11px}
.hmi-table th{
  text-align:left;padding:6px 8px;background:#eef2f8;color:var(--h-txt2);font-size:10.5px;
  font-weight:640;border-bottom:1px solid var(--h-line);position:sticky;top:0;z-index:1;
}
.hmi-table td{padding:4.5px 8px;border-bottom:1px solid #eef1f5;vertical-align:middle}
.hmi-table tr:hover td{background:#f5f8fc}
.hmi-table td.mono{font-family:var(--mono);font-size:10.5px}
.hmi-table td.desc{color:var(--h-txt2);font-size:10.5px}
.hmi-table td.cid{font-family:var(--mono);white-space:nowrap}
.hmi-table i.sw{display:inline-block;width:9px;height:9px;border-radius:2px;margin-right:6px;vertical-align:-1px}
.hmi-table tr.warn-row td{background:#fff6e6}
.hmi-table tr.bad-row td{background:#fdecec}
.hmi-kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:7px;margin-bottom:10px}
.hmi-kpi{background:#f4f7fb;border:1px solid var(--h-line);border-radius:7px;padding:9px;text-align:center}
.hmi-kpi-v{font-family:var(--mono);font-size:17px;font-weight:700;color:var(--h-acc)}
.hmi-kpi-k{font-size:10px;color:var(--h-txt2);margin-top:3px}
.hmi-bars{margin-bottom:10px}
.hmi-bars .barlist-label{color:var(--h-txt2)}
.hmi-bars .barlist-track{background:#e7ecf3}
.hmi-bars .barlist-val{color:var(--h-txt2)}
.hmi-btnrow{display:flex;gap:6px;flex-wrap:wrap}
.hmi-right{display:flex;flex-direction:column;gap:9px;min-height:0;overflow-y:auto}
.hmi-group{background:var(--h-card);border:1px solid var(--h-line);border-radius:8px;padding:10px 11px}
.hmi-group.grow{flex:1;min-height:0;display:flex;flex-direction:column}
.hmi-group-title{font-size:12px;font-weight:700;color:#1e2a38;margin-bottom:8px;
  padding-bottom:6px;border-bottom:1px solid #eef1f5}
.hmi-sub{margin-bottom:11px}
.hmi-sub-title{font-size:10.5px;color:var(--h-txt2);margin-bottom:6px;font-weight:600}
.hmi-radio{display:flex;align-items:center;gap:6px;font-size:11.5px;padding:3px 0;cursor:pointer}
.hmi-radio input{accent-color:var(--h-acc)}
.hmi-slider{margin-bottom:8px}
.hmi-slider-top{display:flex;justify-content:space-between;font-size:11px;color:var(--h-txt2);margin-bottom:3px}
.hmi-slider-val{font-family:var(--mono);color:var(--h-acc);font-weight:600}
.hmi-slider input[type=range]{width:100%;accent-color:var(--h-acc)}
.hmi-check{display:flex;align-items:center;gap:6px;font-size:11.5px;cursor:pointer;margin-bottom:7px}
.hmi-check input{accent-color:var(--h-acc)}
.hmi-prog{height:6px;background:#e7ecf3;border-radius:4px;overflow:hidden;margin-top:9px}
.hmi-prog-fill{height:100%;width:0;background:linear-gradient(90deg,#42a5f5,#1976d2);transition:width .25s}
.hmi-status{font-size:10.5px;color:var(--h-txt2);margin-top:6px;line-height:1.55}
.hmi-status.ok{color:var(--h-good)}
.hmi-status.run{color:var(--h-acc)}
.hmi-path{font-family:var(--mono);font-size:10px;color:var(--h-txt2);margin-top:6px}
.hmi-perf{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}
.hmi-perf-cell{background:#f4f7fb;border:1px solid var(--h-line);border-radius:6px;padding:7px 5px;text-align:center}
.hmi-perf-v{font-family:var(--mono);font-size:12.5px;font-weight:700;color:#243244}
.hmi-perf-k{font-size:9.5px;color:var(--h-txt2);margin-top:2px}
.hmi-res-sum{font-size:10.5px;color:var(--h-txt2);line-height:1.6;margin-bottom:7px}
.hmi-res-wrap{flex:1;min-height:90px;overflow:auto;border:1px solid var(--h-line);border-radius:6px}
.hmi-campanels{display:grid;grid-template-columns:1fr 1fr;gap:6px}
.hmi-campanel{background:#f4f7fb;border:1px solid var(--h-line);border-radius:6px;padding:7px 8px}
.hmi-cp-title{font-size:10.5px;font-weight:640;color:var(--h-acc);margin-bottom:4px}
.hmi-cp-body{font-size:10px;color:var(--h-txt2)}
.cp-line{display:flex;align-items:center;gap:4px;line-height:1.65}
.cp-line i.sw{width:8px;height:8px;border-radius:2px;display:inline-block}
.hmi-root .muted{color:#98a3b2}

/* =====================================================================
   数据追溯
   ===================================================================== */
.tr-grid-2{display:grid;grid-template-columns:1fr 1.25fr;gap:11px;align-items:start}
@media (max-width:1520px){.tr-grid-2{grid-template-columns:1fr}}
.rec-wrap{overflow:auto;max-height:420px;border:1px solid var(--line);border-radius:var(--r2);margin-top:6px}
.rec-table{width:100%;border-collapse:collapse;font-size:10.5px}
.rec-table th{
  position:sticky;top:0;background:#1a2230;padding:6px 7px;font-size:10px;color:var(--txt3);
  text-align:left;border-bottom:1px solid var(--line2);white-space:nowrap;z-index:1;
}
.rec-table td{padding:4px 7px;border-bottom:1px solid var(--line);white-space:nowrap}
.rec-table td.mono{font-family:var(--mono)}
.rec-table tr{cursor:pointer}
.rec-table tr:hover td{background:rgba(255,255,255,.04)}
.rec-table i.sw{display:inline-block;width:8px;height:8px;border-radius:2px;margin-right:5px}
.rec-table tr.o-rejectOk td.oc{color:var(--good)}
.rec-table tr.o-rejectMiss td{background:rgba(226,85,79,.10)}
.rec-table tr.o-rejectMiss td.oc{color:var(--bad);font-weight:650}
.rec-table tr.o-rejectFalse td{background:rgba(232,163,58,.09)}
.rec-table tr.o-rejectFalse td.oc{color:var(--warn);font-weight:650}
.mini-warn{font-size:9px;padding:0 4px;margin-left:5px;border-radius:3px;
  background:rgba(232,163,58,.22);color:#f0d6a4}
.lim-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:8px}
.lim-card{border:1px solid var(--line);border-radius:var(--r2);padding:9px 10px;background:rgba(255,255,255,.03)}
.lim-card.bad{border-left:3px solid var(--bad)}
.lim-card.good{border-left:3px solid var(--good)}
.lim-t{font-size:11.5px;font-weight:640;color:#e6ecf5}
.lim-d{font-size:10.5px;color:var(--txt2);line-height:1.7;margin-top:5px}

/* =====================================================================
   右侧参数坞
   ===================================================================== */
.dock{
  grid-column:3;grid-row:2;background:var(--bg2);border-left:1px solid var(--line);
  display:flex;flex-direction:column;min-height:0;
}
.dock-head{display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:9px 10px;border-bottom:1px solid var(--line)}
.dock-title{font-size:12px;font-weight:650;color:#e2e9f2}
.dock-scroll{flex:1;overflow-y:auto;padding:9px 10px}
.dock-group{margin-bottom:9px;border:1px solid var(--line);border-radius:var(--r2);overflow:hidden}
.dock-group-head{display:flex;align-items:center;justify-content:space-between;
  padding:7px 9px;background:rgba(255,255,255,.045);cursor:pointer}
.dock-group-t{font-size:11.5px;font-weight:620;color:#dde5ef}
.dock-caret{color:var(--txt3);font-size:10px}
.dock-group-body{padding:9px}
.dock-group.collapsed .dock-group-body{display:none}
.dock-hint{font-size:9.5px;color:var(--txt3);line-height:1.6;margin-bottom:9px;
  padding-bottom:8px;border-bottom:1px dashed var(--line)}
.dock-note{font-size:9.5px;color:var(--txt3);line-height:1.75}
.preset-grid{display:grid;grid-template-columns:1fr;gap:5px}
.preset{
  display:flex;flex-direction:column;gap:2px;text-align:left;cursor:pointer;
  border:1px solid var(--line2);background:rgba(255,255,255,.035);border-radius:var(--r2);
  padding:6px 9px;font-family:inherit;transition:background .13s,border-color .13s;
}
.preset:hover{background:rgba(77,184,255,.11);border-color:rgba(77,184,255,.42)}
.preset-n{font-size:11.5px;font-weight:620;color:#e6ecf5}
.preset-d{font-size:9.5px;color:var(--txt3);line-height:1.5}

/* ---------------- 提示条 / 报警 ---------------- */
.toast{
  position:fixed;left:50%;bottom:22px;transform:translate(-50%,140%);
  background:rgba(14,20,29,.97);border:1px solid var(--line2);border-left:3px solid var(--acc);
  border-radius:var(--r2);padding:10px 16px;font-size:11.5px;color:var(--txt);
  max-width:min(760px,80vw);line-height:1.65;z-index:80;transition:transform .3s cubic-bezier(.2,.8,.2,1);
  box-shadow:0 10px 34px rgba(0,0,0,.5);
}
.toast.on{transform:translate(-50%,0)}
.alarm{
  position:fixed;top:62px;left:214px;right:348px;z-index:60;display:none;
  background:rgba(226,85,79,.95);color:#fff;padding:7px 14px;font-size:12px;font-weight:600;
  border-bottom:1px solid rgba(255,255,255,.2);
}
.alarm.on{display:block}
body.dock-collapsed .alarm{right:46px}

/* ---------------- 窄屏适配 ---------------- */
@media (max-width:1240px){
  body{grid-template-columns:62px 1fr 300px}
  body.dock-collapsed{grid-template-columns:62px 1fr 46px}
  .rail-txt{display:none}
  .rail-btn{justify-content:center;padding:9px 4px}
  .rail-icon{width:auto;font-size:17px}
  .alarm{left:62px;right:300px}
  .p3d-layout{grid-template-columns:238px 1fr}
  .brand-s{display:none}
  .hmi-body{grid-template-columns:1fr 300px}
}
@media (max-width:1040px){
  body{grid-template-columns:62px 1fr 46px}
  .dock-scroll{display:none}
  .top-stats .tstat:nth-child(n+5){display:none}
  .hmi-body{grid-template-columns:1fr}
  .hmi-right{max-height:280px}
}
