/* ===== base:设计令牌 / 重置 / 舞台 / 顶栏 / 跨页共用组件 ===== */
:root{
  --panel-bg1:rgba(11,26,54,.72); --panel-bg2:rgba(7,16,38,.60);
  --line:rgba(56,130,200,.26); --edge:rgba(80,200,255,.65);
  --cyan:#3fe0ff; --cyan2:#12b6e8; --deep:#0e6cc4;
  --txt:#c8dff2; --muted:#84a2c1; --dim:#5f7ea0;
  --amber:#ffb02e; --green:#39dc86; --red:#ff5566; --blue:#4f8ff0;
  --mono:'Share Tech Mono',ui-monospace,monospace;
  --num:'Rajdhani','DIN Alternate','Segoe UI',sans-serif;
  --cjk:'PingFang SC','Microsoft YaHei','Hiragino Sans GB',system-ui,sans-serif;
}
*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%;background:#000;overflow:hidden;font-family:var(--cjk);color:var(--txt)}
button{font-family:inherit;color:inherit;background:none;border:none;cursor:pointer}
:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}
::-webkit-scrollbar{width:6px;height:6px}
::-webkit-scrollbar-thumb{background:rgba(80,160,220,.35);border-radius:3px}
::-webkit-scrollbar-track{background:transparent}

#viewport{position:fixed;inset:0;background:radial-gradient(120% 90% at 50% 0%,#0a1730 0%,#050a16 60%,#02060f 100%);display:flex;align-items:center;justify-content:center}
#stage{position:absolute;top:50%;left:50%;width:1920px;height:1080px;transform-origin:center;
  background:radial-gradient(80% 60% at 50% 42%,rgba(20,70,130,.28),transparent 70%),linear-gradient(180deg,#071129 0%,#050b19 100%);overflow:hidden}

header{position:absolute;top:0;left:0;right:0;height:86px;z-index:40;background:linear-gradient(180deg,rgba(9,26,58,.9),rgba(9,26,58,0));display:flex;align-items:flex-start}
header::after{content:"";position:absolute;left:0;right:0;top:82px;height:2px;background:linear-gradient(90deg,transparent,rgba(63,224,255,.5) 25%,rgba(63,224,255,.85) 50%,rgba(63,224,255,.5) 75%,transparent)}
.hleft{position:absolute;left:0;top:0;height:86px;display:flex;align-items:center;gap:16px;padding:0 24px;z-index:6}
.clock .clk-t{font:700 29px/1.05 var(--num);letter-spacing:.06em;color:var(--cyan);text-shadow:0 0 16px rgba(63,224,255,.55)}
.clock .clk-d{font-size:12.5px;color:var(--muted);letter-spacing:.1em;margin-top:3px}
.wx{display:flex;align-items:center;gap:10px;padding-left:16px;border-left:1px solid var(--line)}
.wx .wi{width:26px;height:26px;stroke:var(--cyan);fill:none;stroke-width:1.6;flex:0 0 auto}
.wx .wt{font:700 22px/1 var(--num);color:#eafaff;white-space:nowrap}
.wx .wt .u{font-size:12px;color:var(--cyan)}
.wx .ws{font-size:11px;color:var(--muted);line-height:1.5;white-space:nowrap}
.wx .ws b{color:#dcefff;font-weight:600}
.title{position:absolute;left:0;right:0;top:15px;text-align:center;pointer-events:none}
.title h1{font-size:34px;font-weight:700;letter-spacing:.16em;background:linear-gradient(180deg,#fff 10%,#7fe6ff 130%);-webkit-background-clip:text;background-clip:text;color:transparent;text-shadow:0 0 26px rgba(63,224,255,.35);filter:drop-shadow(0 2px 10px rgba(0,60,110,.6))}
.title .wing{position:absolute;top:30px;width:180px;height:12px}
.title .wing.l{left:calc(50% - 360px)}.title .wing.r{right:calc(50% - 360px)}
.wing svg{width:100%;height:100%}
.hnav{position:absolute;right:24px;top:23px;display:none;align-items:center;gap:14px;z-index:6}
.hnav.on{display:flex}
.crumb{font-size:13px;color:var(--muted);letter-spacing:.06em}
.crumb b{color:var(--cyan)}
.homebtn{padding:8px 17px;border:1px solid var(--line);color:var(--txt);font-size:13px;border-radius:5px;background:linear-gradient(180deg,rgba(30,70,130,.4),rgba(20,50,100,.2));transition:.2s;letter-spacing:.05em;text-decoration:none}
.homebtn:hover{color:#eafaff;border-color:rgba(63,224,255,.55);box-shadow:0 0 12px rgba(63,224,255,.3)}

#content{position:absolute;top:86px;bottom:0;left:0;right:0}

.panel{position:relative;background:linear-gradient(160deg,var(--panel-bg1),var(--panel-bg2));border:1px solid var(--line);backdrop-filter:blur(3px)}
.panel>.cn{position:absolute;width:9px;height:9px;pointer-events:none}
.cn-tl{top:-1px;left:-1px;border-top:1.5px solid var(--edge);border-left:1.5px solid var(--edge)}
.cn-tr{top:-1px;right:-1px;border-top:1.5px solid var(--edge);border-right:1.5px solid var(--edge)}
.cn-bl{bottom:-1px;left:-1px;border-bottom:1.5px solid var(--edge);border-left:1.5px solid var(--edge)}
.cn-br{bottom:-1px;right:-1px;border-bottom:1.5px solid var(--edge);border-right:1.5px solid var(--edge)}
.p-hd{display:flex;align-items:center;gap:9px;height:34px;padding:0 12px;font-size:16px;letter-spacing:.08em;color:#dcefff;border-bottom:1px solid var(--line);background:linear-gradient(90deg,rgba(30,90,160,.35),transparent)}
.p-hd::before{content:"";width:4px;height:15px;background:var(--cyan);box-shadow:0 0 8px var(--cyan);border-radius:1px}
.p-hd .tabs{margin-left:auto;display:flex;gap:14px}
.p-hd .tabs button{font-size:13px;color:var(--dim);letter-spacing:.05em}
.p-hd .tabs button.on{color:var(--cyan)}
.p-bd{padding:12px}

.portal{cursor:pointer;transition:box-shadow .2s,border-color .2s,transform .2s}
.portal:hover{border-color:rgba(63,224,255,.6);box-shadow:0 0 0 1px rgba(63,224,255,.45),0 8px 26px rgba(0,40,80,.5)}
.enter{margin-left:auto;font-size:12px;color:var(--cyan);letter-spacing:.05em;opacity:.7;white-space:nowrap;transition:.2s}
.portal:hover .enter{opacity:1;transform:translateX(2px)}

.lbl{font-size:12px;color:var(--muted);letter-spacing:.04em}
.unit{font-size:12px;color:var(--muted);margin-left:3px}
.up{color:var(--red)}.down{color:var(--green)}

/* ===== 跨页共用的示意地图(SVG)基元 ===== */
.prov-fill{fill:rgba(18,52,96,.32)}
.prov-stroke{fill:none;stroke:var(--cyan);stroke-width:2.2;filter:drop-shadow(0 0 6px rgba(63,224,255,.9))}
.prov-glow{fill:none;stroke:rgba(63,224,255,.25);stroke-width:9}
.hw{fill:none;stroke:rgba(120,200,255,.55);stroke-width:2}

/* ===== 跨页共用的高德真实底图容器与标注(AMap marker content) ===== */
.amap-box{position:absolute;inset:0;background:#0a1424}
.amap-box .amap-logo{opacity:.35!important}
.amap-box .amap-copyright{opacity:.4!important}
.amk-nodewrap{position:relative;width:12px;height:12px;display:grid;place-items:center}
.amk-node{width:9px;height:9px;border-radius:50%;background:var(--cyan);box-shadow:0 0 8px var(--cyan);border:1px solid #eafaff}
.amk-node.cap{width:11px;height:11px;box-shadow:0 0 13px var(--cyan);border-color:#ffcf5a}
.amk-pulse{position:absolute;width:12px;height:12px;border-radius:50%;border:1.5px solid var(--cyan)}
.amk-tag{display:flex;align-items:center;gap:6px;padding:2px 8px;background:rgba(8,26,54,.86);border:1px solid rgba(63,224,255,.5);border-radius:3px;white-space:nowrap;box-shadow:0 2px 10px rgba(0,20,50,.5)}
.amk-tag .t{color:#dff2ff;font:600 13px var(--cjk)}
.amk-tag .n{color:var(--cyan);font:700 15px var(--num)}
.amk-tag-real{border-color:rgba(255,210,63,.6)}
.amk-tag-real .t{color:#ffe9a3}
.amk-truck{width:8px;height:8px;border-radius:50%;border:1px solid #fff;box-shadow:0 0 6px rgba(63,224,255,.7)}
.amk-ev{position:relative;width:14px;height:14px}
.amk-ev .d{position:absolute;inset:3px;border-radius:50%;background:var(--red);box-shadow:0 0 6px var(--red)}
.amk-ev .r{position:absolute;inset:0;border-radius:50%;border:1.5px solid var(--red)}
.amk-rsu{width:9px;height:9px;background:rgba(120,210,120,.95);border:1px solid #eafff0;transform:rotate(45deg)}
.amk-end{width:8px;height:8px;border-radius:50%;background:#ffd23f;border:1.5px solid #fff7d6;box-shadow:0 0 9px rgba(255,210,63,.95)}
.ninfo{min-width:168px;padding:7px 11px;background:rgba(8,22,48,.94);border:1px solid var(--lc,#3fe0ff);border-radius:4px;box-shadow:0 4px 18px rgba(0,20,50,.6)}
.ninfo b{display:block;font-size:12.5px;color:#eafaff;font-weight:600;letter-spacing:.02em}
.ninfo span{display:block;font-size:11.5px;color:var(--lc,#3fe0ff);margin-top:2px;font-family:var(--num)}

.grid2{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.fac{display:flex;align-items:center;gap:10px;padding:9px 10px;background:rgba(14,40,78,.35);border:1px solid rgba(60,130,200,.18)}
.fac .fic{width:30px;height:30px;display:grid;place-items:center;color:var(--cyan)}
.fac .fic svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.5}
.fac .fv{font:700 22px var(--num);color:#eafaff}
.fac .fl{font-size:11px;color:var(--muted)}

.donutrow{display:flex;align-items:center;gap:16px}
.donut{position:relative;flex:0 0 auto}
.donut .dc{position:absolute;inset:0;display:grid;place-content:center;text-align:center}
.donut .dc b{font:700 22px var(--num);color:#eafaff}
.donut .dc s{font-size:11px;color:var(--muted);text-decoration:none;display:block}
.dleg{flex:1;display:flex;flex-direction:column;gap:6px}
.dleg .li{display:flex;align-items:center;gap:7px;font-size:12.5px}
.dleg .dot{width:9px;height:9px;border-radius:2px;flex:0 0 auto}
.dleg .li .nm{color:var(--muted)}
.dleg .li .vl{margin-left:auto;font-family:var(--num);color:#dceeff;font-weight:600}
.dleg .li .pc{color:var(--dim);font-family:var(--num);width:38px;text-align:right}

.tbl{width:100%;border-collapse:collapse;font-size:12.5px}
.tbl th{color:var(--muted);font-weight:500;text-align:left;padding:6px 6px;border-bottom:1px solid var(--line);font-size:12px}
.tbl td{padding:6px 6px;border-bottom:1px solid rgba(60,130,200,.1);color:#cfe3f5;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tbl tr:hover td{background:rgba(40,110,180,.16)}
.tbl .mono{font-family:var(--mono);font-size:12px}

.badge{display:inline-flex;align-items:center;gap:4px;padding:1px 7px;border-radius:3px;font-size:11px}
.b-auto{color:var(--cyan);background:rgba(63,224,255,.12);border:1px solid rgba(63,224,255,.3)}
.b-man{color:var(--amber);background:rgba(255,176,46,.12);border:1px solid rgba(255,176,46,.3)}
.b-off{color:var(--dim);background:rgba(120,140,160,.12);border:1px solid rgba(120,140,160,.25)}
.b-run{color:var(--green);background:rgba(57,220,134,.12);border:1px solid rgba(57,220,134,.3)}
.b-wait{color:var(--blue);background:rgba(79,143,240,.12);border:1px solid rgba(79,143,240,.3)}
.b-fault{color:var(--red);background:rgba(255,85,102,.12);border:1px solid rgba(255,85,102,.3)}

.rk-item{display:flex;align-items:center;gap:9px;padding:8px 11px;border-bottom:1px solid rgba(60,130,200,.1)}
.rk-lvl{flex:0 0 auto;width:26px;height:22px;border-radius:3px;color:#04121f;font-size:12px;font-weight:700;display:grid;place-items:center}
.rk-mid{flex:1;min-width:0}
.rk-ev{font-size:13px;color:#eafaff}
.rk-sub{font-size:11px;color:var(--muted);font-family:var(--mono);margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rk-time{font-family:var(--mono);font-size:11px;color:var(--dim);flex:0 0 auto}
@keyframes rkin{from{background:rgba(63,224,255,.2)}to{background:transparent}}
.rk-item.nw{animation:rkin 1.8s ease}

.ovgrid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.ovfeed{position:relative;height:100px;border:1px solid var(--line);overflow:hidden;background:#02060f}
.ovfeed canvas{display:block;width:100%;height:100%}
.ovhud{position:absolute;inset:0;pointer-events:none;font-family:var(--mono)}
.oc{position:absolute;top:4px;left:6px;font-size:10.5px;color:#bfe6ff;text-shadow:0 1px 3px #000}
.olive{position:absolute;top:4px;right:6px;font-size:10px;color:#fff;display:flex;align-items:center;gap:4px}
.olive i{width:6px;height:6px;border-radius:50%;background:var(--red);box-shadow:0 0 6px var(--red);animation:blink 1.4s infinite}
.ots{position:absolute;bottom:4px;left:6px;font-size:10px;color:#cfe6f5;text-shadow:0 1px 3px #000}

.trend{width:100%;height:150px}
.trend text{font:11px var(--num);fill:var(--dim)}

/* ===== shared sub-page frame ===== */
.subwrap{position:absolute;inset:0;padding:14px 20px;display:flex;gap:12px}
.sub-side{width:320px;flex:0 0 auto;display:flex;flex-direction:column;gap:12px;min-height:0}
.sub-main{flex:1;display:flex;flex-direction:column;gap:12px;min-width:0}
.sub-right{width:384px;flex:0 0 auto;display:flex;flex-direction:column;gap:12px;min-height:0}
.fill{flex:1;min-height:0}
.p-bd.scroll{overflow:auto}

.search{display:flex;align-items:center;gap:8px;background:rgba(10,30,64,.6);border:1px solid var(--line);padding:7px 10px;margin:10px 12px}
.search input{flex:1;background:none;border:none;color:var(--txt);font-size:13px}
.search input::placeholder{color:var(--dim)}
.search svg{width:15px;height:15px;stroke:var(--muted);fill:none;stroke-width:1.7}

.vs-hero{display:flex;gap:8px;margin-bottom:11px}
.vs-hero .vs{flex:1;min-width:0;padding:8px 9px;background:rgba(14,40,78,.35);border:1px solid rgba(60,130,200,.18)}
.vs-hero .vs .n{font:700 23px var(--num);color:#eafaff;line-height:1.05;white-space:nowrap}
.vs-hero .vs .n small{font-size:11px;color:var(--muted);margin-left:2px;font-weight:500}
.vs-hero .vs .k{font-size:11px;color:var(--muted);margin-top:3px;white-space:nowrap}
.vsbar{display:flex;height:13px;border:1px solid var(--line);border-radius:3px;overflow:hidden;margin-bottom:10px}
.vsbar i{display:block;height:100%}
.vs-foot{display:flex;justify-content:space-between;gap:10px;margin-top:9px;padding-top:8px;border-top:1px solid rgba(60,130,200,.14);font-size:11.5px;color:var(--muted);white-space:nowrap}
.vs-foot b{font-family:var(--num);font-weight:600}

.kv{display:flex;justify-content:space-between;gap:10px;padding:6px 2px;border-bottom:1px solid rgba(60,130,200,.1);font-size:13px}
.kv .k{color:var(--muted)}
.kv .v{color:#eafaff;font-weight:600;text-align:right}
.kv .v.eta{color:var(--green)}

.vx{display:flex;align-items:center;gap:10px;padding:8px 2px;border-bottom:1px solid rgba(60,130,200,.1)}
.vx:last-child{border-bottom:none}
.vx .vxm{flex:1;min-width:0}
.vx b{display:block;font-size:13px;color:#eafaff;font-weight:600}
.vx small{display:block;font-size:11px;color:var(--dim);margin-top:1px}

/* ===== 监控画面 feed(video + roadnet 共用) ===== */
.feed{position:relative;background:#02060f;border:1px solid var(--line);overflow:hidden}
.feed canvas{display:block;width:100%;height:100%}
.feed .hud{position:absolute;inset:0;pointer-events:none;font-family:var(--mono)}
.feed .cam{position:absolute;top:6px;left:8px;font-size:11px;color:#bfe6ff;letter-spacing:.03em;text-shadow:0 1px 3px #000}
.feed .live{position:absolute;top:6px;right:8px;font-size:11px;color:#fff;display:flex;align-items:center;gap:5px}
.feed .live .rd{width:7px;height:7px;border-radius:50%;background:var(--red);box-shadow:0 0 6px var(--red);animation:blink 1.4s infinite}
.feed .ts{position:absolute;bottom:6px;left:8px;font-size:11px;color:#cfe6f5;text-shadow:0 1px 3px #000}
.feed .meta{position:absolute;bottom:6px;right:8px;font-size:11px;color:var(--cyan);text-align:right;text-shadow:0 1px 3px #000}
@keyframes blink{50%{opacity:.25}}

.netmapbox{position:relative;height:100%}

.route-legend{position:absolute;left:12px;bottom:12px;z-index:8;display:flex;flex-wrap:wrap;gap:8px 14px;padding:8px 12px;background:rgba(8,22,48,.88);border:1px solid var(--line);border-radius:4px;backdrop-filter:blur(4px);font-size:12px;color:var(--muted);pointer-events:none}
.route-legend i{display:inline-block;width:14px;height:3px;border-radius:2px;margin-right:6px;vertical-align:middle}

.hbar{display:flex;align-items:center;gap:10px;margin:9px 0;font-size:13px}
.hbar .nm{width:120px;color:var(--muted);font-size:12.5px;flex:0 0 auto}
.hbar .tr{flex:1;height:9px;background:rgba(90,140,190,.18);border-radius:5px;overflow:hidden}
.hbar .fl{display:block;height:100%;border-radius:5px}
.hbar .vv{width:44px;text-align:right;font:700 14px var(--num);color:#dceeff}
.mini .hbar{margin:5px 0}

.toast{position:absolute;bottom:14px;left:50%;transform:translateX(-50%);background:rgba(10,40,80,.95);border:1px solid var(--cyan);color:#eafaff;padding:9px 18px;font-size:13px;border-radius:6px;z-index:60;opacity:0;transition:.3s;pointer-events:none}
.toast.show{opacity:1}

/* ===== 原 JS 动态注入的 keyframes(静态化;reduced-motion 由下方 media 规则兜底) ===== */
@keyframes flow{to{stroke-dashoffset:-160}}
@keyframes pl{0%{r:6;opacity:.6}100%{r:15;opacity:0}}
@keyframes apul{0%{transform:scale(1);opacity:.7}100%{transform:scale(3);opacity:0}}
.flowline{animation:flow 3s linear infinite}
.pnode{animation:pl 2.4s ease-out infinite}
.amk-pulse{animation:apul 2.4s ease-out infinite}
.amk-ev .r{animation:apul 2.2s ease-out infinite}

@media (prefers-reduced-motion: reduce){*{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}}
