/* ============ 郑州地铁 3D 可视化（晨曦主题） ============ */
:root{
  --bg:#0c1230; --bg2:#0f1838; --panel:rgba(22,32,64,.78); --panel2:rgba(32,46,88,.6);
  --panel3:rgba(255,255,255,.06); --line:rgba(140,170,255,.22);
  --text:#eef3ff; --muted:#9db2dd; --accent:#5cb6ff;
  --warn:#ffc24d; --danger:#ff6470; --ok:#3edc97; --ctrl:#b7a1ff; --red:#fb5b4f;
  --topbar-h:58px; --sidebar-w:308px;
  --shadow:0 12px 44px rgba(4,8,26,.55);
  --glow:0 0 18px rgba(92,182,255,.35);
  --radius:16px;
}
*{box-sizing:border-box; margin:0; padding:0;}
html,body{height:100%;}
body{
  font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif;
  background:radial-gradient(1200px 700px at 75% -10%, #1a2a5c 0%, var(--bg) 55%, #090e28 100%);
  color:var(--text); overflow:hidden; font-size:14px;
}

/* ---------- 顶部栏（玻璃拟态） ---------- */
#topbar{
  position:fixed; top:0; left:0; right:0; height:var(--topbar-h); z-index:60;
  display:flex; align-items:center; gap:14px; padding:0 16px;
  background:linear-gradient(180deg, rgba(24,34,68,.82), rgba(14,20,44,.72));
  border-bottom:1px solid rgba(140,170,255,.16);
  backdrop-filter:blur(14px) saturate(1.3); -webkit-backdrop-filter:blur(14px) saturate(1.3);
}
.brand{display:flex; align-items:center; gap:11px; min-width:0;}
.brand-svg{
  width:36px; height:36px; border-radius:10px; flex:0 0 auto;
  background:linear-gradient(135deg,#ff4e3d,#ffa94d 45%,#2aa8ff);
  box-shadow:0 2px 14px rgba(255,90,60,.45), inset 0 0 8px rgba(255,255,255,.25);
}
.brand-text h1{font-size:16px; font-weight:700; letter-spacing:.6px; display:flex; align-items:center; gap:4px;
  background:linear-gradient(90deg,#fff,#9fc4ff); -webkit-background-clip:text; background-clip:text; color:transparent;}
.brand-text h1 em{font-style:normal; color:var(--accent); font-size:15px; -webkit-text-fill-color:var(--accent);}
.brand-text p{font-size:11px; color:var(--muted); white-space:nowrap;}

.search-wrap{position:relative; flex:1; max-width:340px; min-width:140px;}
#searchInput{
  width:100%; padding:9px 14px; border-radius:12px; border:1px solid rgba(140,170,255,.2);
  background:rgba(255,255,255,.06); color:var(--text); font-size:13px; outline:none;
  transition:all .2s;
}
#searchInput::placeholder{color:var(--muted);}
#searchInput:focus{border-color:var(--accent); background:rgba(255,255,255,.09);
  box-shadow:0 0 0 3px rgba(92,182,255,.18);}
.search-results{
  position:absolute; top:calc(100% + 8px); left:0; right:0; z-index:80;
  background:rgba(20,30,60,.96); border:1px solid rgba(140,170,255,.2); border-radius:14px;
  max-height:340px; overflow:auto; box-shadow:var(--shadow); backdrop-filter:blur(16px);
}
.search-results .sr-item{padding:10px 14px; cursor:pointer; border-bottom:1px solid rgba(255,255,255,.05);}
.search-results .sr-item:hover{background:rgba(255,255,255,.07);}
.search-results .sr-name{font-weight:600;}
.search-results .sr-sub{font-size:11px; color:var(--muted); margin-top:2px;}
.search-results .sr-item.active{background:rgba(92,182,255,.12); outline:1px solid var(--accent);}
.search-results .sr-group{font-size:10px; color:var(--muted); padding:6px 14px 2px; letter-spacing:.5px;}
.search-results .sr-item .sr-line{font-size:10px; color:var(--muted); margin-left:6px;}

.time-wrap{display:flex; align-items:center; gap:8px; margin-left:auto;}
.time-wrap label{color:var(--muted); font-size:12px;}
#timeInput{
  width:174px; padding:9px 12px; border-radius:12px; border:1px solid rgba(140,170,255,.2);
  background:rgba(255,255,255,.06); color:var(--text); font-size:13px; text-align:center; cursor:pointer; outline:none;
}
#timePicker{
  position:fixed; left:-9999px; top:0; width:1px; height:1px;
  opacity:0; pointer-events:none; border:0; padding:0; margin:0;
}
.btn{
  padding:8px 14px; border-radius:12px; border:1px solid rgba(140,170,255,.22);
  background:rgba(255,255,255,.07); color:var(--text); font-size:13px; cursor:pointer;
  white-space:nowrap; transition:all .18s;
}
.btn:hover{border-color:var(--accent); color:#fff; background:rgba(92,182,255,.14); box-shadow:var(--glow);}
.btn.ghost{background:transparent;}

/* ---------- 横幅 ---------- */
#alertBanner{
  position:fixed; top:var(--topbar-h); left:0; right:0; z-index:55;
  display:flex; align-items:center; gap:10px; padding:8px 16px;
  background:linear-gradient(90deg, rgba(140,32,44,.92), rgba(96,20,36,.88));
  color:#ffd9dd; border-bottom:1px solid rgba(255,110,120,.3); font-size:13px; cursor:pointer;
  backdrop-filter:blur(10px);
}
#alertBanner .alert-count{background:var(--danger); color:#fff; border-radius:12px; padding:1px 9px; font-size:12px;}
#alertBanner .alert-close{margin-left:auto; background:none; border:none; color:#ffd9dd; cursor:pointer; font-size:15px;}
#alertBanner .alert-close:hover{color:#fff;}

/* ---------- 侧栏（玻璃拟态） ---------- */
#sidebar{
  position:fixed; top:var(--topbar-h); bottom:0; left:0; z-index:50;
  width:var(--sidebar-w); background:linear-gradient(180deg, rgba(20,29,58,.9), rgba(13,18,40,.94));
  border-right:1px solid rgba(140,170,255,.14);
  display:flex; flex-direction:column; transition:transform .25s ease;
  backdrop-filter:blur(18px) saturate(1.2); -webkit-backdrop-filter:blur(18px) saturate(1.2);
  box-shadow:4px 0 28px rgba(4,8,26,.4);
}
#sidebar.hidden{transform:translateX(-102%);}
#sidebar .panel-head{display:flex; align-items:center; justify-content:space-between; padding:14px 16px; border-bottom:1px solid rgba(140,170,255,.12);}
#sidebar h2{font-size:15px; letter-spacing:.4px;}
#sidebar h3{font-size:12px; color:var(--muted); font-weight:600; margin-bottom:8px; letter-spacing:.5px;}
#sidebar .panel{padding:14px 16px; border-bottom:1px solid rgba(255,255,255,.04); overflow-y:auto;}
#sidebar .status{flex:0 0 auto;}
#sidebar .lines-sec{flex:1 1 auto; max-height:46%;}
#sidebar .ann{flex:0 1 auto;}
.disclaimer{padding:10px 16px; font-size:11px; color:var(--muted); line-height:1.6;}
.disclaimer b{color:var(--warn);}

.status-grid{display:grid; grid-template-columns:repeat(4,1fr); gap:9px; margin-bottom:12px;}
.stat{
  background:rgba(255,255,255,.055); border:1px solid rgba(140,170,255,.14);
  border-radius:12px; padding:8px 4px; text-align:center; transition:all .15s;
}
.stat:hover{background:rgba(255,255,255,.09); transform:translateY(-1px);}
.stat dt{font-size:10px; color:var(--muted);}
.stat dd{font-size:19px; font-weight:700; margin-top:2px; text-shadow:0 0 12px rgba(255,255,255,.14);}
.stat dd.alert{color:var(--danger); text-shadow:0 0 12px rgba(255,100,112,.4);}

.legend{display:flex; gap:6px; flex-wrap:wrap;}
.lg{font-size:10px; padding:2px 10px; border-radius:20px; border:1px solid rgba(140,170,255,.18); color:var(--muted); background:rgba(255,255,255,.03);}
.lg.normal{color:var(--ok); border-color:rgba(62,220,151,.45);}
.lg.extended{color:var(--warn); border-color:rgba(255,194,77,.45);}
.lg.reduced{color:var(--accent); border-color:rgba(92,182,255,.45);}
.lg.controlled{color:var(--ctrl); border-color:rgba(183,161,255,.45);}
.lg.closed{color:var(--danger); border-color:rgba(255,100,112,.5);}

.line-open{display:flex; flex-wrap:wrap; gap:10px 14px; margin-bottom:10px; font-size:12px; color:var(--muted);}
.switch{display:inline-flex; align-items:center; gap:6px; cursor:pointer; user-select:none;}
.switch input{position:absolute; opacity:0; width:0;}
.switch span{width:32px; height:18px; border-radius:12px; background:rgba(255,255,255,.14); position:relative; display:inline-block; transition:.2s;}
.switch input:checked + span{background:linear-gradient(90deg,#3ea6ff,#5cb6ff); box-shadow:0 0 10px rgba(92,182,255,.4);}
.switch span::after{content:""; position:absolute; top:2px; left:2px; width:14px; height:14px; border-radius:50%; background:#fff; transition:.2s; box-shadow:0 1px 3px rgba(0,0,0,.4);}
.switch input:checked + span::after{left:16px;}

.line-list{list-style:none; max-height:220px; overflow-y:auto;}
.line-list li{display:flex; align-items:center; gap:9px; padding:7px 4px; cursor:pointer; border-radius:8px; transition:background .15s;}
.line-list li:hover{background:rgba(255,255,255,.06);}
.line-list li.off{opacity:.45;}
.line-list .swatch{width:28px; height:14px; border-radius:5px; flex:0 0 auto; box-shadow:0 0 8px rgba(255,255,255,.15);}
.line-list .lname{flex:1; font-size:13px;}
.line-list .lstate{font-size:10px; padding:1px 7px; border-radius:10px;}
.line-list .lstate.closed{background:rgba(255,100,112,.18); color:var(--danger);}
.line-list .lstate.extended{background:rgba(255,194,77,.16); color:var(--warn);}
.line-list .lstate.reduced{background:rgba(92,182,255,.15); color:var(--accent);}
.line-list .lstate.controlled{background:rgba(183,161,255,.16); color:var(--ctrl);}
.line-list .badge{font-size:10px; color:var(--muted);}

.ann-list{list-style:none; max-height:190px; overflow-y:auto;}
.ann-list li{padding:7px 4px; border-bottom:1px solid rgba(255,255,255,.05); cursor:pointer; transition:all .1s;}
.ann-list li:hover{background:rgba(255,255,255,.06);}
.ann-list .ann-date{font-size:10px; color:var(--muted); display:flex; flex-direction:column; gap:2px; align-items:flex-start;}
.ann-list .ann-title{font-size:12px; line-height:1.4; margin-top:2px;}
.ann-list li.closed-ann{border-left:3px solid var(--danger); padding-left:7px;}
.ann-list li.expired-ann{opacity:.4; border-left-color:var(--muted);}
.ann-list li.expired-ann:hover{opacity:.7;}
.ann-list .ann-flag{font-size:9px; padding:0 4px; border-radius:8px; background:rgba(255,255,255,.06); color:var(--muted); border:1px solid rgba(140,170,255,.18); display:inline-block; text-align:center;}

/* 状态快照时间戳 */
.state-ts{font-size:10px; color:var(--muted); margin-bottom:4px; padding:3px 0;}

/* ---------- 主视图 ---------- */
#viewport{position:fixed; top:var(--topbar-h); left:var(--sidebar-w); right:0; bottom:0; z-index:10;
  background:radial-gradient(1000px 620px at 70% 20%, #1c2a58 0%, #101738 50%, #0a0f28 100%);
}
#viewport.full{left:0;}
#scene{width:100%; height:100%; display:block;}
#busy{position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); color:var(--muted); font-size:13px; display:flex; align-items:center; gap:10px; z-index:5;}
#busy::before{content:""; width:18px; height:18px; border-radius:50%; border:2px solid rgba(140,170,255,.3); border-top-color:var(--accent); animation:spin 0.9s linear infinite;}
@keyframes spin{to{transform:rotate(360deg)}}

/* tooltip（四向边界 clamp 在 JS 内处理） */
.tooltip{
  position:fixed; z-index:40; pointer-events:none; max-width:260px;
  background:rgba(18,27,56,.96); border:1px solid rgba(140,170,255,.22); border-radius:12px;
  padding:10px 12px; box-shadow:var(--shadow); font-size:12px; line-height:1.5;
  backdrop-filter:blur(12px);
}
.tooltip .tt-title{font-weight:700; font-size:13px; margin-bottom:4px;}
.tooltip .tt-row{display:flex; justify-content:space-between; gap:14px;}
.tooltip .tt-row b{margin-left:auto;}

/* 实时指示器 */
.live-indicator{display:inline-flex; align-items:center; gap:5px; margin-left:8px; font-size:11px; color:var(--muted);}
.live-dot{width:8px; height:8px; border-radius:50%; background:var(--ok); box-shadow:0 0 8px var(--ok); animation:pulse-dot 2s infinite;}
@keyframes pulse-dot{0%,100%{opacity:1} 50%{opacity:.4}}
.live-indicator.disconnected .live-dot{background:var(--muted); animation:none; box-shadow:none;}
.live-indicator.disconnected .live-label{color:var(--muted);}

/* 实时信息面板 */
.live-info{display:flex; align-items:center; gap:6px; padding:7px 12px; border-radius:10px; background:rgba(255,255,255,.055); border:1px solid rgba(140,170,255,.16); font-size:11px; color:var(--muted); margin-bottom:10px; flex-wrap:wrap;}
.live-info .live-dot{width:6px; height:6px; flex:0 0 auto;}
.live-info #livePeriod{font-weight:600; color:var(--text);}
.live-info #liveTips{color:var(--warn);}

/* 线路卡片（新版） */
.line-list{list-style:none; max-height:260px; overflow-y:auto; display:flex; flex-direction:column; gap:4px;}
.line-list .line-item{
  display:flex; flex-direction:column; gap:2px; padding:7px 10px; cursor:pointer;
  border-radius:12px; border:1px solid rgba(140,170,255,.12); transition:all .18s; position:relative;
  background:rgba(255,255,255,.045);
}
.line-list .line-item:hover{background:rgba(255,255,255,.09); border-color:rgba(140,170,255,.32); transform:translateX(-2px); box-shadow:0 4px 16px rgba(4,8,26,.35);}
.line-list .line-item.off{opacity:.4;}
.line-list .line-head{display:flex; align-items:center; gap:8px;}
.line-list .line-swatch{width:4px; border-radius:3px; align-self:stretch; flex:0 0 auto; min-height:28px; box-shadow:0 0 10px rgba(255,255,255,.18);}
.line-list .line-name{font-size:13px; font-weight:600; flex:1;}
.line-list .line-state{font-size:10px; padding:1px 8px; border-radius:8px; white-space:nowrap;}
.line-list .line-state.s-normal{color:var(--ok);}
.line-list .line-state.s-closed{background:rgba(255,100,112,.18); color:var(--danger);}
.line-list .line-state.s-extended{background:rgba(255,194,77,.16); color:var(--warn);}
.line-list .line-state.s-reduced{background:rgba(92,182,255,.15); color:var(--accent);}
.line-list .line-state.s-controlled{background:rgba(183,161,255,.16); color:var(--ctrl);}
.line-list .line-sub{display:flex; gap:10px; font-size:10px; color:var(--muted); padding-left:12px;}
.line-list .line-sub .lz{color:var(--muted);}
.line-list .line-item .line-focus{
  position:absolute; right:6px; top:8px; font-size:10px; color:var(--muted); opacity:0; transition:opacity .15s;
  background:rgba(255,255,255,.07); border:1px solid rgba(140,170,255,.2); border-radius:6px; padding:1px 7px;
}
.line-list .line-item:hover .line-focus{opacity:1;}
.line-list .line-item .line-focus:hover{color:var(--accent); border-color:var(--accent);}

/* 列车图例 */
.rail-legend{
  position:fixed; right:14px; bottom:14px; z-index:30; display:flex; align-items:center; gap:8px;
  background:rgba(18,27,56,.85); border:1px solid rgba(140,170,255,.2); border-radius:22px; padding:7px 14px;
  font-size:11px; color:var(--muted); backdrop-filter:blur(10px);
}
.rail-legend .dot{width:10px; height:10px; border-radius:50%; background:var(--accent); box-shadow:0 0 10px var(--accent);}
#legendClock{color:var(--text); font-weight:600;}

/* ---------- 弹窗 ---------- */
.modal{
  position:fixed; inset:0; z-index:100; background:rgba(6,10,24,.6);
  display:flex; align-items:center; justify-content:center; padding:20px; backdrop-filter:blur(6px);
}
.modal[hidden]{display:none;}
.modal-card{
  position:relative; width:min(560px, 94vw); max-height:82vh; overflow-y:auto;
  background:linear-gradient(180deg, rgba(24,34,68,.94), rgba(15,21,44,.97));
  border:1px solid rgba(140,170,255,.22); border-radius:18px; padding:22px; box-shadow:var(--shadow);
  backdrop-filter:blur(18px);
}
.modal-close{position:absolute; top:14px; right:14px; background:rgba(255,255,255,.07); border:1px solid rgba(140,170,255,.2); color:var(--text); width:30px; height:30px; border-radius:9px; cursor:pointer; font-size:15px;}
.modal-close:hover{border-color:var(--danger); color:var(--danger); background:rgba(255,100,112,.12);}
#modalTitle{font-size:20px; margin-bottom:14px; padding-right:36px;}
.modal-content .sch-block{margin-bottom:16px;}
.modal-content h4{font-size:13px; color:var(--muted); margin-bottom:8px; display:flex; align-items:center; gap:8px;}
.modal-content .line-chip{width:22px; height:8px; border-radius:3px;}
.sch-grid{display:grid; grid-template-columns:1fr 1fr; gap:8px;}
.sch-card{background:rgba(255,255,255,.05); border:1px solid rgba(140,170,255,.16); border-radius:12px; padding:11px;}
.sch-card .sc-dir{font-size:13px; font-weight:700; margin-bottom:8px;}
.sch-card .sc-row{display:flex; justify-content:space-between; font-size:12px; padding:2px 0; color:var(--muted);}
.sch-card .sc-row b{color:var(--text);}
.sch-card .sc-empty{color:var(--muted); font-size:12px;}

/* 详情弹窗状态徽标 */
.detail-status{display:inline-block; padding:2px 12px; border-radius:12px; font-size:12px; margin-bottom:10px;}
.detail-status.normal{background:rgba(62,220,151,.15); color:var(--ok);}
.detail-status.closed{background:rgba(255,100,112,.16); color:var(--danger);}
.detail-status.controlled{background:rgba(183,161,255,.16); color:var(--ctrl);}

.meta-chip{display:inline-block; background:rgba(255,255,255,.06); border:1px solid rgba(140,170,255,.18); border-radius:8px; padding:3px 9px; font-size:11px; color:var(--muted); margin:0 6px 6px 0;}
.meta-row{margin-bottom:12px;}

/* ---------- 键盘快捷键帮助 ---------- */
.kbd-card{width:min(560px,94vw);}
.kbd-toolbar{display:flex; gap:8px; margin-bottom:10px;}
.kbd-toolbar .btn{font-size:12px; padding:6px 12px;}
.kbd-toolbar .btn.active{border-color:var(--warn); color:var(--warn); box-shadow:0 0 12px rgba(255,194,77,.25);}
.kbd-hint{font-size:11px; color:var(--muted); margin-bottom:10px; min-height:15px;}
.kbd-list{display:flex; flex-direction:column; gap:14px; max-height:52vh; overflow-y:auto; padding-right:4px;}
.kbd-group h4{font-size:12px; color:var(--accent); margin-bottom:6px; letter-spacing:.4px;}
.kbd-row{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:7px 12px; border-radius:10px; border:1px solid rgba(140,170,255,.12);
  background:rgba(255,255,255,.045); transition:all .15s;
}
.kbd-row .kbd-label{font-size:13px; color:var(--text);}
.kbd-row .kbd-key{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; font-size:12px;
  background:rgba(255,255,255,.08); border:1px solid rgba(140,170,255,.28); border-bottom-width:2px;
  border-radius:7px; padding:3px 10px; min-width:36px; text-align:center; color:#fff;
}
.kbd-card.editing .kbd-row{cursor:pointer;}
.kbd-card.editing .kbd-row:hover{border-color:var(--accent); background:rgba(92,182,255,.1); transform:translateX(-2px);}
.kbd-row.capturing{border-color:var(--warn); background:rgba(255,194,77,.1);}
.kbd-row.capturing .kbd-key{color:var(--warn); border-color:var(--warn); animation:kbd-pulse .9s infinite;}
@keyframes kbd-pulse{0%,100%{box-shadow:0 0 0 0 rgba(255,194,77,.4)} 50%{box-shadow:0 0 0 6px rgba(255,194,77,0)}}
.kbd-foot{font-size:11px; color:var(--muted); margin-top:14px; line-height:1.7; border-top:1px solid rgba(140,170,255,.12); padding-top:12px;}
.kbd-foot b{color:var(--text);}
.kbd{
  display:inline-block; font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; font-size:10px;
  background:rgba(255,255,255,.08); border:1px solid rgba(140,170,255,.28); border-bottom-width:2px;
  border-radius:5px; padding:1px 6px; color:#fff; margin:0 2px;
}

/* ---------- 响应式 ---------- */
@media (max-width:760px){
  :root{--topbar-h:52px;}
  .brand-text p{display:none;}
  .time-wrap{gap:5px;}
  #timeInput{width:150px;}
  #sidebar{width:min(300px, 84vw);}
  #viewport{left:0;}
  .search-wrap{max-width:180px;}
}
@media (max-width:520px){
  #playBtn{padding:6px 9px;}
  .search-wrap{display:none;} /* 小屏搜索收进弹层入口 */
}

/* ---------- 3D 站名标签（CSS2D） ---------- */
.station-label{
  color:#f0f5ff; font-size:9px; background:rgba(16,26,54,.6);
  padding:0 5px; border-radius:5px; border:1px solid rgba(140,170,255,.18);
  white-space:nowrap; transform:translateY(-1px); user-select:none; pointer-events:none;
  text-shadow:0 1px 3px rgba(0,0,0,.9);
}
.station-closed{
  color:#ff9aa4; font-size:12px; font-weight:700; background:rgba(96,20,32,.92);
  padding:2px 8px; border-radius:7px; border:1px solid rgba(255,100,112,.55);
  white-space:nowrap; user-select:none; pointer-events:none;
  box-shadow:0 0 12px rgba(255,100,112,.55);
}

/* 编辑布局按钮 */
.edit-actions{display:flex; gap:8px; margin-bottom:8px;}
.edit-actions .btn{font-size:11px; padding:5px 11px;}
.edit-actions .btn.active{border-color:var(--warn); color:var(--warn); box-shadow:0 0 12px rgba(255,194,77,.25);}

/* ============ hidden 属性保护 ============
 * author CSS 的 display 规则会覆盖 HTML hidden 属性的 UA display:none，
 * 导致元素隐藏失效（busy 加载、alertBanner、liveInfo 等）。
 * 全局强制 hidden 优先。 */
[hidden]{display:none !important;}

/* ============ 布局重设计：悬浮侧栏 + Dock + 细滚动条（苹果风） ============ */
/* —— 全局细窄半透明滚动条（贴合玻璃拟态，hover 才加深） —— */
*{ scrollbar-width:thin; scrollbar-color:rgba(140,170,255,.25) transparent; }
*::-webkit-scrollbar{ width:7px; height:7px; }
*::-webkit-scrollbar-track{ background:transparent; }
*::-webkit-scrollbar-thumb{
  background:rgba(140,170,255,.18); border-radius:8px;
  border:2px solid transparent; background-clip:content-box;
}
*::-webkit-scrollbar-thumb:hover{ background:rgba(140,170,255,.42); background-clip:content-box; }

/* —— 侧栏：悬浮圆角玻璃卡 —— */
#sidebar{
  top:calc(var(--topbar-h) + 12px); bottom:12px; left:12px; width:var(--sidebar-w);
  border-radius:20px; border:1px solid rgba(140,170,255,.16);
  background:linear-gradient(180deg, rgba(24,34,66,.74), rgba(13,18,40,.84));
  backdrop-filter:blur(24px) saturate(1.4); -webkit-backdrop-filter:blur(24px) saturate(1.4);
  box-shadow:0 18px 48px rgba(4,8,26,.5), inset 0 1px 0 rgba(255,255,255,.06);
  overflow:hidden;
}
#sidebar.hidden{ transform:translateX(calc(-100% - 16px)); }
#viewport{ left:calc(var(--sidebar-w) + 24px); }

#sidebar .panel-head{ padding:16px 18px 12px; border-bottom:1px solid rgba(140,170,255,.1); }
#sidebar .panel-title h2{ font-size:16px; letter-spacing:.4px; }
#sidebar .panel-sub{ display:block; font-size:10px; color:var(--muted); letter-spacing:.6px; margin-top:2px; }
#sidebar .btn.icon{ width:30px; height:30px; padding:0; display:inline-flex; align-items:center; justify-content:center; border-radius:9px; }

#sidebar .panel-body{
  flex:1 1 auto; min-height:0; overflow-y:auto;
  padding:8px 12px 12px; display:flex; flex-direction:column; gap:8px;
}
#sidebar .panel{
  padding:0; flex:0 0 auto; overflow:hidden;
  border:1px solid rgba(140,170,255,.1); border-radius:14px;
  background:rgba(255,255,255,.035);
}
#sidebar .panel-toggle{
  width:100%; display:flex; align-items:center; justify-content:space-between; gap:8px;
  background:transparent; border:none; color:var(--text); font-size:12px; font-weight:600;
  padding:11px 14px; cursor:pointer; letter-spacing:.4px; text-align:left;
}
#sidebar .panel-toggle:hover{ background:rgba(255,255,255,.05); }
#sidebar .panel-toggle .chev{ color:var(--muted); font-size:12px; transition:transform .2s; }
#sidebar .panel.collapsed .chev{ transform:rotate(-90deg); }
#sidebar .panel.collapsed .panel-inner{ display:none; }
#sidebar .panel-inner{ padding:2px 12px 12px; }

#sidebar .lines-sec{ flex:1 1 auto; min-height:0; max-height:none; display:flex; flex-direction:column; }
#sidebar .lines-sec .panel-inner{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
#sidebar .line-list{ flex:1 1 auto; min-height:0; max-height:none; }
#sidebar .ann-list{ max-height:none; }

.line-toolbar{ display:flex; flex-wrap:wrap; align-items:center; gap:8px 12px; margin-bottom:10px; }
.line-toolbar .switch{ font-size:12px; color:var(--muted); }
.btn.mini{ font-size:11px; padding:4px 10px; }

.disclaimer{ padding:10px 18px 12px; font-size:10px; border-top:1px solid rgba(140,170,255,.1); }

/* —— 底部 Dock 悬浮工具条 —— */
#dock{
  position:fixed; left:50%; bottom:16px; transform:translateX(-50%); z-index:45;
  display:flex; align-items:center; gap:6px; padding:7px 12px;
  background:rgba(20,30,62,.55); border:1px solid rgba(140,170,255,.18); border-radius:22px;
  backdrop-filter:blur(20px) saturate(1.4); -webkit-backdrop-filter:blur(20px) saturate(1.4);
  box-shadow:0 12px 36px rgba(4,8,26,.5), inset 0 1px 0 rgba(255,255,255,.08);
}
.dock-btn{
  width:40px; height:40px; border-radius:13px; border:none; cursor:pointer;
  background:rgba(255,255,255,.06); color:#fff; font-size:18px; line-height:1;
  display:inline-flex; align-items:center; justify-content:center; position:relative;
  transition:transform .16s cubic-bezier(.34,1.56,.64,1), background .16s, box-shadow .16s;
}
.dock-btn:hover{ transform:scale(1.18) translateY(-3px); background:rgba(255,255,255,.14); box-shadow:0 8px 20px rgba(4,8,26,.45); }
.dock-btn.active{ background:rgba(92,182,255,.2); box-shadow:inset 0 0 0 1px rgba(92,182,255,.5); }
.dock-btn.active::after{
  content:""; position:absolute; bottom:3px; left:50%; transform:translateX(-50%);
  width:4px; height:4px; border-radius:50%; background:var(--accent); box-shadow:0 0 8px var(--accent);
}
.dock-sep{ width:1px; height:22px; background:rgba(140,170,255,.2); margin:0 2px; }

/* —— 响应式补充 —— */
@media (max-width:760px){
  #sidebar{ left:10px; width:min(300px,84vw); }
}
@media (max-width:520px){
  #dock{ bottom:10px; padding:5px 9px; gap:4px; }
  .dock-btn{ width:36px; height:36px; font-size:16px; border-radius:11px; }
  .dock-btn:hover{ transform:scale(1.1) translateY(-2px); }
}

/* ============ 苹果风细节打磨（图标 / 动效 / 按压反馈） ============ */
:root{
  --ease-out:cubic-bezier(0.23,1,0.32,1);
  --ease-in-out:cubic-bezier(0.77,0,0.175,1);
}

/* —— 统一线性 SVG 图标 —— */
.ico{
  width:16px; height:16px; display:block; flex:0 0 auto;
  fill:none; stroke:currentColor; stroke-width:1.8;
  stroke-linecap:round; stroke-linejoin:round;
}
.btn .ico{ width:15px; height:15px; }
.dock-btn .ico{ width:20px; height:20px; }
.brand-svg .ico{ width:22px; height:22px; stroke-width:2; }
.chev .ico{ width:13px; height:13px; }
.modal-close .ico, .kbd-card .modal-close .ico{ width:16px; height:16px; }
.alert-close .ico{ width:14px; height:14px; }
.modal-close, .alert-close{ display:inline-flex; align-items:center; justify-content:center; }

/* —— 品牌 Logo：渐变圆角 + 白色地铁图形 —— */
.brand-svg{
  display:flex; align-items:center; justify-content:center; flex:0 0 auto;
}

/* —— 按钮：精确过渡 + 按压反馈（100-160ms）—— */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  transition:border-color .16s ease, color .16s ease, background .16s ease, box-shadow .16s ease, transform .12s var(--ease-out);
}
.btn:active{ transform:scale(.97); }
.btn.active{ border-color:var(--warn); color:var(--warn); box-shadow:0 0 12px rgba(255,194,77,.25); }

/* —— Dock 按钮按压反馈 —— */
.dock-btn{ transition:transform .18s var(--ease-out), background .16s ease, box-shadow .16s ease; }
.dock-btn:active{ transform:scale(.92); }

/* —— 面板折叠：平滑旋转 —— */
#sidebar .panel-toggle .chev{ transition:transform .2s var(--ease-out); }
#sidebar .panel-inner{ transition:opacity .18s ease; }

/* —— 卡片/列表项：精确过渡，避免 transition:all —— */
.line-list .line-item{ transition:background .15s ease, border-color .15s ease, transform .15s var(--ease-out), box-shadow .15s ease; }
.stat{ transition:background .15s ease, transform .15s var(--ease-out); }
.ann-list li{ transition:background .12s ease, opacity .2s ease; }
.kbd-row{ transition:background .15s ease, border-color .15s ease, transform .15s var(--ease-out); }

/* —— 弹窗入场：中心缩放 + 淡入（偶发交互，标准动画）—— */
.modal-card{ animation:modalIn .24s var(--ease-out) both; }
@keyframes modalIn{
  from{ opacity:0; transform:translateY(8px) scale(.98); }
  to{ opacity:1; transform:translateY(0) scale(1); }
}

/* —— 触摸设备：去掉粘滞 hover 放大 —— */
@media (hover:none){
  .dock-btn:hover{ transform:none; }
  .line-list .line-item:hover{ transform:none; }
}

/* —— 减弱动效偏好 —— */
@media (prefers-reduced-motion:reduce){
  *{ animation-duration:.001ms !important; transition-duration:.001ms !important; }
}

/* ============ 自适应 + 移动端触屏 ============ */
:root{
  --safe-t:env(safe-area-inset-top, 0px);
  --safe-b:env(safe-area-inset-bottom, 0px);
  --safe-l:env(safe-area-inset-left, 0px);
  --safe-r:env(safe-area-inset-right, 0px);
}

/* 刘海屏/底部横条安全区 */
#topbar{
  height:calc(var(--topbar-h) + var(--safe-t));
  padding-top:var(--safe-t);
  padding-left:calc(16px + var(--safe-l));
  padding-right:calc(16px + var(--safe-r));
}
#viewport{ top:calc(var(--topbar-h) + var(--safe-t)); }
#sidebar{
  top:calc(var(--topbar-h) + var(--safe-t) + 12px);
  bottom:calc(12px + var(--safe-b));
  left:calc(12px + var(--safe-l));
}
#dock{ bottom:calc(16px + var(--safe-b)); }
.rail-legend{ right:calc(14px + var(--safe-r)); bottom:calc(14px + var(--safe-b)); }

/* 触屏：禁用文本选择/长按弹出/页面滚动，手势交给 3D 相机 */
#viewport{ overscroll-behavior:none; }
#scene{ touch-action:none; -webkit-user-select:none; user-select:none; -webkit-touch-callout:none; }
body{ -webkit-user-select:none; user-select:none; -webkit-touch-callout:none; }
#searchInput, #timeInput, .kbd-card, .modal-card{ -webkit-user-select:text; user-select:text; }

/* —— 平板（≤900px）：压缩顶部信息 —— */
@media (max-width:900px){
  #kbdBtn, #globalBtn{ display:none; }              /* 已移至 Dock */
  .time-wrap label{ display:none; }
  #timeInput{ width:132px; }
}

/* —— 手机横屏/小平板（≤760px）—— */
@media (max-width:760px){
  :root{ --topbar-h:52px; }
  .brand-text p{ display:none; }
  .search-wrap{ max-width:180px; }
  #timeInput{ width:120px; }
  #sidebar{ left:calc(10px + var(--safe-l)); width:min(310px, 86vw); }
  .rail-legend{ bottom:calc(78px + var(--safe-b)); right:12px; }   /* 让位给 Dock */
}

/* —— 手机竖屏（≤520px）—— */
@media (max-width:520px){
  .brand-text{ display:none; }                       /* 仅留 Logo */
  .search-wrap{ display:none; }                      /* 搜索走 Dock */
  #timeInput{ width:106px; font-size:12px; padding:8px 9px; }
  #playBtn{ padding:8px 10px; }
  #playBtn span{ display:none; }                     /* 播放按钮仅图标 */
  #resetTimeBtn{ padding:8px 10px; }
  #sidebarToggle, #kbdBtn{ padding:8px 10px; }
  #sidebarToggle span{ display:none; }               /* 线路按钮仅图标 */
  .live-indicator .live-label{ display:none; }
  #dock{ bottom:calc(10px + var(--safe-b)); padding:6px 10px; gap:5px; }
  .dock-btn{ width:42px; height:42px; border-radius:14px; }
  .dock-btn .ico{ width:21px; height:21px; }
  .dock-btn:hover{ transform:none; }
}

/* —— 粗指针设备（触屏）：加大触控目标 —— */
@media (pointer:coarse){
  .btn{ min-height:40px; }
  .dock-btn{ width:44px; height:44px; }
  .dock-btn .ico{ width:22px; height:22px; }
  .line-list .line-item{ padding:10px 12px; }
  .kbd-row{ padding:10px 12px; }
}

/* ============ 无侧栏版式：顶部状态条 + 悬浮窗口 + 全宽视口 ============ */
:root{ --strip-h:46px; }

#viewport{
  left:0; right:0;
  top:calc(var(--topbar-h) + var(--safe-t) + var(--strip-h));
}
#alertBanner{ top:calc(var(--topbar-h) + var(--safe-t)); z-index:56; }

/* —— 顶部状态条 —— */
.status-strip{
  position:fixed; top:calc(var(--topbar-h) + var(--safe-t)); left:0; right:0; z-index:54;
  height:var(--strip-h);
  display:flex; align-items:center; gap:12px; padding:0 14px;
  background:linear-gradient(180deg, rgba(22,32,64,.78), rgba(14,20,44,.72));
  border-bottom:1px solid rgba(140,170,255,.14);
  backdrop-filter:blur(18px) saturate(1.3); -webkit-backdrop-filter:blur(18px) saturate(1.3);
  overflow-x:auto; overflow-y:hidden; scrollbar-width:none;
}
.status-strip::-webkit-scrollbar{ display:none; }
.status-strip .live-info{ flex:0 0 auto; margin:0; padding:4px 10px; }
.ss-stats{ display:flex; gap:8px; flex:0 0 auto; }
.ss-stat{
  display:flex; align-items:center; gap:7px; padding:5px 11px; border-radius:10px;
  background:rgba(255,255,255,.05); border:1px solid rgba(140,170,255,.14); white-space:nowrap;
}
.ss-stat dt{ font-size:10px; color:var(--muted); }
.ss-stat dd{ font-size:15px; font-weight:700; text-shadow:0 0 12px rgba(255,255,255,.12); }
.ss-stat dd.alert{ color:var(--danger); text-shadow:0 0 12px rgba(255,100,112,.4); }
.status-strip .legend{ flex:0 0 auto; }
.ss-meta{ margin-left:auto; display:flex; align-items:center; gap:10px; flex:0 0 auto; }
.ss-clock{ font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; font-size:12px; color:var(--text); font-weight:600; }
.status-strip .state-ts{ font-size:10px; margin:0; }

/* —— 悬浮窗口层 —— */
.float-layer{
  position:fixed; top:calc(var(--topbar-h) + var(--safe-t) + var(--strip-h)); left:0; right:0; bottom:0;
  z-index:46; pointer-events:none;
}
.float-win{
  position:absolute; width:320px; max-width:88vw; max-height:calc(100% - 16px);
  display:flex; flex-direction:column; pointer-events:auto; overflow:hidden;
  background:linear-gradient(180deg, rgba(24,34,66,.9), rgba(15,21,44,.94));
  border:1px solid rgba(140,170,255,.18); border-radius:16px;
  backdrop-filter:blur(22px) saturate(1.4); -webkit-backdrop-filter:blur(22px) saturate(1.4);
  box-shadow:0 18px 48px rgba(4,8,26,.5), inset 0 1px 0 rgba(255,255,255,.06);
  animation:winIn .2s var(--ease-out) both;
}
.float-win[hidden]{ display:none !important; }
@keyframes winIn{
  from{ opacity:0; transform:translateY(8px) scale(.98); }
  to{ opacity:1; transform:translateY(0) scale(1); }
}
.fw-head{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  padding:12px 14px; border-bottom:1px solid rgba(140,170,255,.12);
  cursor:grab; user-select:none; -webkit-user-select:none;
}
.fw-head:active{ cursor:grabbing; }
.fw-title{ font-size:13px; font-weight:700; letter-spacing:.4px; }
.fw-close{
  width:26px; height:26px; border:none; border-radius:8px; cursor:pointer;
  background:rgba(255,255,255,.07); color:var(--text);
  display:inline-flex; align-items:center; justify-content:center;
  transition:background .15s ease, color .15s ease;
}
.fw-close:hover{ background:rgba(255,100,112,.16); color:var(--danger); }
.fw-close .ico{ width:14px; height:14px; }
.fw-body{ flex:1 1 auto; min-height:0; overflow-y:auto; padding:12px 14px; }
.fw-body .line-list, .fw-body .ann-list, .fw-body .kbd-list{ max-height:none; overflow:visible; }
.fw-body .disclaimer{ padding:10px 0 0; border-top:1px solid rgba(140,170,255,.1); margin-top:12px; }

#winLines{ right:16px; top:12px; }
#winAnn{ right:16px; top:12px; }
#winKbd{ right:16px; top:12px; width:380px; }
.float-win.dragging{ transition:none; cursor:grabbing; }
.float-win.editing .kbd-row{ cursor:pointer; }
.float-win.editing .kbd-row:hover{ border-color:var(--accent); background:rgba(92,182,255,.1); }

/* —— 线路卡片操作按钮 + 站点展开 —— */
.line-item .line-actions{ display:flex; gap:6px; margin-top:9px; padding-left:12px; }
.line-btn{
  flex:1; padding:6px 0; border-radius:8px; border:1px solid rgba(140,170,255,.18);
  background:rgba(255,255,255,.05); color:var(--muted); font-size:11px; cursor:pointer; text-align:center;
  transition:border-color .15s ease, color .15s ease, background .15s ease, transform .12s var(--ease-out);
}
.line-btn:hover{ border-color:var(--accent); color:#fff; background:rgba(92,182,255,.14); }
.line-btn:active{ transform:scale(.96); }
.line-btn.view{ color:var(--accent); }
.line-item.off .line-btn.view, .line-item.off .line-btn.expand{ opacity:.5; }
.line-item.off .line-btn.toggle{ color:var(--warn); border-color:rgba(255,194,77,.45); }

.line-stations{ display:flex; flex-wrap:wrap; gap:5px; margin-top:9px; padding-left:12px; }
.st-chip{
  font-size:10px; padding:2px 8px; border-radius:9px; cursor:pointer; white-space:nowrap;
  background:rgba(255,255,255,.05); border:1px solid rgba(140,170,255,.14); color:var(--muted);
  transition:border-color .15s ease, color .15s ease, background .15s ease;
}
.st-chip:hover{ border-color:var(--accent); color:#fff; background:rgba(92,182,255,.14); }
.st-chip.st-closed{ color:var(--danger); border-color:rgba(255,100,112,.4); }
.st-chip.st-controlled{ color:var(--ctrl); border-color:rgba(183,161,255,.4); }
.st-chip.st-extended{ color:var(--warn); border-color:rgba(255,194,77,.4); }

/* —— 播放速度分段控件 —— */
.speed-seg{ display:inline-flex; border:1px solid rgba(140,170,255,.2); border-radius:10px; overflow:hidden; }
.speed-btn{
  padding:6px 9px; border:none; background:rgba(255,255,255,.05); color:var(--muted);
  font-size:11px; cursor:pointer; transition:background .15s ease, color .15s ease;
}
.speed-btn + .speed-btn{ border-left:1px solid rgba(140,170,255,.15); }
.speed-btn:hover{ color:#fff; background:rgba(255,255,255,.1); }
.speed-btn.active{ background:rgba(92,182,255,.2); color:#fff; }

/* —— 实时 / 模拟模式指示 —— */
.live-indicator.sim .live-dot{ background:var(--warn); box-shadow:0 0 8px var(--warn); }
.live-indicator.sim .live-label{ color:var(--warn); }
#timeInput.sim{ border-color:var(--warn); color:var(--warn); }

@media (max-width:760px){
  .speed-btn{ padding:5px 7px; font-size:10px; }
}

/* —— 右下角固定信息：数据 / 演示 / 免责（不可隐藏、不可移动） —— */
.page-info{
  position:fixed; right:calc(14px + var(--safe-r)); bottom:calc(14px + var(--safe-b));
  z-index:48; pointer-events:none; user-select:none; -webkit-user-select:none;
  max-width:min(340px, calc(100vw - 28px));
  display:flex; flex-direction:column; gap:3px;
  padding:10px 13px; border-radius:12px;
  background:rgba(12,18,40,.62); border:1px solid rgba(140,170,255,.14);
  backdrop-filter:blur(12px) saturate(1.2); -webkit-backdrop-filter:blur(12px) saturate(1.2);
  box-shadow:0 8px 24px rgba(4,8,26,.35);
  font-size:10px; line-height:1.55; color:var(--muted);
}
.pi-row{ display:block; }
.pi-demo{ color:var(--text); font-weight:600; }
.pi-dot{
  display:inline-block; width:6px; height:6px; border-radius:50%;
  background:var(--warn); margin-right:6px; vertical-align:1px; box-shadow:0 0 8px var(--warn);
}
.pi-disc{ opacity:.72; }
@media (max-width:760px){
  .page-info{ bottom:calc(80px + var(--safe-b)); right:12px; max-width:min(300px, 78vw); }
}

/* —— Dock 小屏横向滚动 —— */
#dock{ max-width:calc(100vw - 16px); overflow-x:auto; scrollbar-width:none; }
#dock::-webkit-scrollbar{ display:none; }

/* —— 无侧栏版式响应式 —— */
@media (max-width:760px){
  .status-strip{ gap:8px; padding:0 10px; }
  .ss-stat{ padding:4px 8px; }
  .ss-stat dt{ display:none; }           /* 仅留数字，紧凑 */
  .status-strip .legend .lg{ padding:2px 7px; }
  .ss-meta .state-ts{ display:none; }    /* 更新时间在小屏隐藏 */
}
@media (max-width:520px){
  #winLines, #winAnn{ width:min(320px, 88vw); }
  #winKbd{ width:min(380px, 92vw); }
  .status-strip{ height:calc(var(--strip-h) + 4px); }
}
