/* ============================================================
 * XD/XL PLC 仿真软件 — 美化版样式（按设备类型配色）
 * 设备配色：X蓝 / Y绿 / M橙 / S紫 / T青 / C玫红 / D靛蓝 / 应用橙
 * ============================================================ */
:root{
  --x:#3b82f6; --x-bg:#eff6ff;
  --y:#22c55e; --y-bg:#ecfdf5;
  --m:#f59e0b; --m-bg:#fffbeb;
  --s:#a855f7; --s-bg:#faf5ff;
  --t:#0891b2; --t-bg:#ecfeff;
  --c:#db2777; --c-bg:#fdf2f8;
  --d:#4f46e5; --d-bg:#eef2ff;
  --app:#f97316; --app-bg:#fff7ed;
  --wire-on:#dc2626;
  --ink:#1f2937; --sub:#64748b; --line:#e5e7eb; --bg:#eef2f7;
  --blue:#2563eb;
  --text:#334155; --text-600:#475569; --muted:#94a3b8;
  --line-300:#cbd5e1; --border-soft:#d3d8e0; --line-200:#e2e8f0;
  --line-100:#e7ebf1; --bg-2:#e8edf5; --bg-3:#e6ebf3;
  --panel:#f1f5f9; --panel-2:#f3f5f9; --panel-3:#f8fafc; --panel-4:#fbfcfe;
  --panel-5:#f7f9fc; --panel-6:#eef1f5; --panel-7:#e8eef7; --panel-8:#e9edf3;
  --line-ec:#dbe3ec; --line-d8:#d8dee8; --scroll:#c4cbd6; --scroll-hover:#a4adbb;
  --ink-900:#0f172a;

}
* { margin:0; padding:0; box-sizing:border-box; }
html,body { height:100%; }
body {
  font-family:"Segoe UI","Microsoft YaHei","微软雅黑",sans-serif;
  font-size:13px; color:var(--ink);
  background:linear-gradient(135deg,var(--bg) 0%,var(--bg-3) 100%);
  overflow:hidden; -webkit-user-select:none; user-select:none;
}
#app { display:flex; flex-direction:column; height:100vh; }

/* ===== 菜单栏 ===== */
.menubar { display:flex; background:linear-gradient(180deg,#FFFFFF,var(--panel-2)); border-bottom:1px solid var(--line); height:32px; align-items:stretch; box-shadow:0 1px 3px rgba(15,23,42,.05); }
.menu-item { position:relative; padding:0 14px; line-height:32px; cursor:default; font-size:13px; color:var(--text); }
.menu-item:first-child { font-weight:700; color:var(--blue); letter-spacing:.2px; }
.menu-item:hover { background:#EAF2FF; }
.menu-item:hover .dropdown { display:block; }
/* a122m：搜索框聚焦期间强制保持下拉展开（避免中文输入法候选窗盖住鼠标导致 :hover 丢失、下拉收起） */
.menu-item:focus-within .dropdown,
.menu-item.open .dropdown { display:block; }
.dropdown { display:none; position:absolute; left:0; top:32px; min-width:190px; background:#fff; border:1px solid #DBE1EA; box-shadow:0 8px 24px rgba(15,23,42,.14); z-index:500; padding:4px 0; border-radius:0 0 6px 6px; }
.dd-item { padding:6px 18px; cursor:default; white-space:nowrap; color:var(--text); }
.dd-item:hover { background:#EAF2FF; color:var(--blue); }

/* ===== 工具栏 ===== */
.toolbar { display:flex; align-items:center; gap:6px; background:linear-gradient(180deg,var(--panel-5),var(--bg)); border-bottom:1px solid var(--line); padding:6px 12px; height:46px; box-shadow:0 1px 3px rgba(15,23,42,.04); }
.tbtn { display:flex; align-items:center; gap:5px; padding:6px 13px; background:#fff; border:1px solid var(--border-soft); border-radius:6px; cursor:default; font-size:12px; color:var(--text); box-shadow:0 1px 2px rgba(15,23,42,.05); transition:.12s; }
.tbtn:hover { background:#F1F6FF; border-color:#9EC5FF; transform:translateY(-1px); }
.tbtn:active { transform:translateY(0); }
.tbtn .ticon { font-size:13px; }
.t-run { color:#16A34A; border-color:#86EFAC; background:#F0FDF4; font-weight:600; }
.t-run:hover { background:#DCFCE7; border-color:#22C55E; }
.t-run.running { background:#22C55E; color:#fff; border-color:#16A34A; box-shadow:0 0 0 3px rgba(34,197,94,.28); }
.t-stop { color:#DC2626; border-color:#FCA5A5; background:#FEF2F2; font-weight:600; }
.t-stop:hover { background:#FEE2E2; border-color:#EF4444; }
/* a122p-P1-4：运行态下停止键高亮（与运行键三态互斥） */
.t-stop.armed { background:#FEE2E2; border-color:#EF4444; color:#DC2626; box-shadow:0 0 0 2px rgba(220,38,38,.18); }
.t-download { color:#2563EB; border-color:#93C5FD; background:#EFF6FF; font-weight:700; }
.t-download:hover { background:#DBEAFE; border-color:#3B82F6; }
.t-step { color:#EA580C; border-color:#FDBA74; background:#FFF7ED; font-weight:600; }
.t-step:hover { background:#FFEDD5; border-color:#FB923C; }
.t-reset { color:var(--text-600); }
.tsep { width:1px; height:26px; background:var(--border-soft); margin:0 4px; }
.tlabel { font-size:12px; color:var(--sub); margin-left:8px; }
.tslider { width:120px; accent-color:var(--blue); }
.tval { font-size:12px; color:var(--blue); min-width:46px; font-weight:600; }
.tselect { font-size:12px; color:var(--text); background:#fff; border:1px solid var(--border-soft); border-radius:6px; padding:5px 8px; cursor:default; box-shadow:0 1px 2px rgba(15,23,42,.05); }
.tselect:hover { border-color:var(--blue); }
.machine-info { color:var(--sub); font-weight:400; min-width:0; max-width:420px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.machine-info .mi-series { color:var(--blue); font-weight:700; }
.machine-info .mi-warn { color:#B45309; font-weight:700; }
.machine-info .mi-note { color:var(--muted); font-size:11px; }

/* ===== 运动视图（阶段B） ===== */
.motion-readout { display:flex; flex-wrap:wrap; gap:10px; padding:8px 10px; background:var(--panel); border-radius:8px; margin-bottom:8px; }
.mr-item { display:flex; flex-direction:column; align-items:flex-start; min-width:76px; }
.mr-item span { font-size:11px; color:var(--sub); }
.mr-item b { font-size:16px; color:var(--ink-900); font-variant-numeric:tabular-nums; }
.mr-item i { font-size:10px; color:var(--muted); font-style:normal; }
.mr-item.sm b { border-radius:4px; padding:1px 8px; font-size:13px; }
.sm-on { background:#22C55E; color:#fff; }
.sm-off { background:var(--line-200); color:var(--muted); }
.motion-canvas { display:block; width:100%; background:#fff; border:1px solid var(--line-200); border-radius:8px; margin-top:4px; }
.cv-stage { height:200px; }
.cv-wave { height:170px; }
.cv-wiring { height:300px; }
.cv-bench { width:100%; height:380px; display:block; }
/* 虚拟 I/O 面板深色样式见下方「虚拟 I/O 面板」区块 */

/* ===== 脉冲轴面板 ===== */
.axis-wrap { display:flex; flex-wrap:wrap; gap:8px; }
.axis-card { border:1px solid var(--line); border-radius:9px; padding:8px 10px; min-width:190px; background:linear-gradient(180deg,#fff,#FAFCFF); box-shadow:0 1px 4px rgba(15,23,42,.05); }
.axis-card.running { border-color:var(--app); box-shadow:0 0 0 2px rgba(249,115,22,.18); }
.axis-card.selected { border-color:var(--app); box-shadow:0 0 0 2px rgba(249,115,22,.28); background:linear-gradient(180deg,#fff,#FFF7ED); }
.ac-detail-btn { margin-top:8px; width:100%; padding:5px 0; font-size:12px; font-weight:600; color:var(--app); background:#FFF7ED; border:1px solid rgba(249,115,22,.35); border-radius:7px; cursor:pointer; transition:background .15s; }
.ac-detail-btn:hover { background:#FED7AA; }
.axis-card.selected .ac-detail-btn { background:var(--app); color:#fff; border-color:var(--app); }
.ac-head { font-size:12px; font-weight:700; color:var(--text); margin-bottom:6px; display:flex; justify-content:space-between; }
.ac-io { font-size:11px; font-weight:400; color:var(--sub); }
.ac-row { display:flex; align-items:center; gap:6px; font-size:12px; color:var(--sub); padding:2px 0; }
.ac-k { min-width:34px; color:var(--sub); }
.ac-pos, .ac-freq { color:var(--d); font-weight:700; font-variant-numeric:tabular-nums; }
.ac-u { font-size:11px; color:var(--muted); }
.ac-state { padding:1px 8px; border-radius:10px; font-weight:700; font-size:11px; }
.ac-state.off { background:var(--panel); color:var(--muted); }
.ac-state.run { background:#FFF7ED; color:#EA580C; }
.ac-state.done { background:#ECFDF5; color:#059669; }
.ac-dir { color:var(--y); font-weight:700; }
.ac-run { font-size:11px; color:var(--muted); padding:1px 6px; border-radius:8px; background:var(--panel); }
.ac-run.on { color:#fff; background:var(--app); }
.axis-empty { color:var(--sub); font-size:12px; padding:8px; }
.sm-cells { display:grid; grid-template-columns:repeat(auto-fill,minmax(210px,1fr)); gap:6px; }
.sm-cell.on { box-shadow:0 0 0 2px rgba(168,85,247,.35); background:rgba(168,85,247,.1); }
.sm-cell.on .cv { color:var(--s); font-weight:700; }
/* SM13 时钟脉冲：ON 时闪烁（像秒表一样） */
@keyframes sm-blink {
  0%, 100% { opacity: 1; background: rgba(168,85,247,.25); }
  50% { opacity: 0.4; background: rgba(168,85,247,.08); }
}
.sm-cell.type-sm.blink { animation: sm-blink 0.5s ease-in-out infinite; }

/* 强制置位高亮（监控面板 + 梯形图符号联动同一套 device.forced） */
.cell.forced { outline:2px solid #F97316; outline-offset:1px; }
.cell.forced .cv { color:#F97316 !important; }
.sm-clear-btn { grid-column:1/-1; justify-self:start; margin:2px 0 8px; padding:5px 12px; font-size:11px; font-weight:700; color:#B45309; background:#FFF7ED; border:1px solid #FDBA74; border-radius:7px; cursor:pointer; transition:.14s; }
.sm-clear-btn:hover { background:#FFEDD5; border-color:#F97316; }
.force-menu { position:fixed; z-index:9999; min-width:104px; background:#fff; border:1px solid var(--line-200); border-radius:9px; box-shadow:0 8px 28px rgba(15,23,42,.18); padding:5px; font-size:12px; color:var(--text); }
.force-menu-item { padding:7px 12px; border-radius:6px; cursor:pointer; transition:.12s; white-space:nowrap; }
.force-menu-item:hover { background:#EFF6FF; color:#1D4ED8; }
.force-menu-item.cancel { color:var(--muted); margin-top:2px; border-top:1px solid var(--panel); border-radius:0; }
.force-menu-item.cancel:hover { background:var(--panel-3); color:var(--sub); }

/* ===== 工作区 ===== */
.workspace { flex:1; display:grid; grid-template-columns:1.55fr 56px 1fr; grid-template-rows:1.1fr 1fr; gap:8px; padding:8px; min-height:0; }
.pane { display:flex; flex-direction:column; background:#fff; border:1px solid var(--line); border-radius:10px; overflow:hidden; box-shadow:0 2px 10px rgba(15,23,42,.06); }
.pane-ladder { grid-column:1; grid-row:1 / span 2; }
.pane-il { grid-column:3; grid-row:1; }
.pane-monitor { grid-column:3; grid-row:2; }
/* 梯形图 ⇄ 指令表 相互转换控件（工作区中列） */
.convert-col { grid-column:2; grid-row:1 / span 2; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px; background:#fff; border:1px solid var(--line); border-radius:10px; box-shadow:0 2px 10px rgba(15,23,42,.06); padding:8px 4px; }
.conv-label { font-size:11px; font-weight:700; color:var(--sub); writing-mode:vertical-rl; letter-spacing:2px; margin-bottom:2px; }
.conv-btn { display:flex; align-items:center; gap:4px; width:100%; justify-content:center; font-size:11px; font-weight:700; color:var(--text); background:linear-gradient(180deg,var(--panel-4),var(--bg)); border:1px solid var(--line-d8); border-radius:8px; padding:10px 4px; cursor:pointer; transition:all .15s; line-height:1.2; }
.conv-btn:hover { background:var(--line-200); border-color:var(--muted); color:var(--ink-900); }
.conv-btn:active { transform:translateY(1px); }
.conv-arrow { font-size:13px; color:#2563EB; }
.pane-header { display:flex; justify-content:space-between; align-items:center; background:linear-gradient(180deg,var(--panel-4),#F1F4F8); border-bottom:1px solid var(--line-100); padding:6px 12px; font-size:12px; font-weight:700; color:var(--text); border-left:3px solid var(--muted); }
.pane-ladder .pane-header { border-left-color:var(--y); }
  .pane-il .pane-header { border-left-color:var(--x); }
  .pane-monitor .pane-header { border-left-color:var(--m); }
  .header-right { display:flex; align-items:center; gap:8px; }
  .sync-badge {
    font-size:11px; font-weight:700; color:#16A34A;
    background:#ECFDF5; border:1px solid #86EFAC; border-radius:10px;
    padding:1px 8px; opacity:0; transition:opacity .25s;
  }
  .sync-badge.flash { opacity:1; }
  .sync-badge.err { color:#DC2626; background:#FEF2F2; border-color:#FCA5A5; }
.pane-tabs,.mtabs { display:flex; gap:3px; }
.ltab,.mtab { border:none; background:var(--panel-8); padding:3px 11px; font-size:11px; border-radius:5px; cursor:default; color:var(--sub); font-weight:600; }
.ltab.active,.mtab.active { background:var(--blue); color:#fff; box-shadow:0 1px 3px rgba(37,99,235,.35); }
/* a122p-P1-2：监控 tab 分三组（软元件 / 扩展·轴 / 教学），组间加细分隔线，窄屏自动换行 */
.mtabs { flex-wrap:wrap; }
.mtab-group { display:flex; gap:3px; align-items:center; }
.mtab-group + .mtab-group { border-left:1px solid var(--line-200); margin-left:5px; padding-left:8px; }
.hint { font-weight:400; color:var(--muted); font-size:11px; }

/* 梯形图区 */
.ladder-scroll { flex:1; overflow:auto; background:#CCE5A0; padding:10px; }
#ladderSvg { display:block; }
.ld-editor-bar { display:flex; gap:4px; flex-wrap:wrap; padding:7px 8px; background:var(--panel-2); border-top:1px solid var(--line); }
.ld-tool { padding:4px 9px; font-size:12px; background:#fff; border:1px solid var(--border-soft); border-radius:5px; cursor:default; min-width:34px; box-shadow:0 1px 2px rgba(15,23,42,.04); }
.ld-tool:hover { background:#EAF2FF; border-color:#9EC5FF; }
.ld-tool.danger:hover { background:#FEE2E2; border-color:#FCA5A5; color:#DC2626; }
.ld-tool.selected { background:#DBEAFE; border-color:var(--blue); color:var(--blue); }

/* 指令表编辑器（主编辑器） */
.il-wrap { flex:1; display:flex; min-height:0; background:#FCFCFD; }
.il-gutter {
  flex:0 0 auto;
  min-width:42px;
  padding:10px 6px 10px 8px;
  font-family:"Consolas","Courier New",monospace;
  font-size:13px;
  line-height:1.7;
  color:var(--muted);
  background:var(--panel-2);
  border-right:1px solid var(--line);
  text-align:right;
  user-select:none;
  white-space:pre;
  overflow:hidden;
}
.il-editor {
  flex:1; min-width:0;
  border:none; outline:none; resize:none;
  padding:10px 12px;
  font-family:"Consolas","Courier New",monospace;
  font-size:13px;
  line-height:1.7;
  color:var(--ink);
  background:transparent;
  white-space:pre;
  tab-size:2;
}
.il-editor:focus { background:#fff; box-shadow:inset 2px 0 0 var(--x); }

/* 快捷插入栏 */
.il-shortcuts {
  display:flex; flex-wrap:wrap; gap:4px;
  padding:7px 8px;
  background:linear-gradient(180deg,var(--panel-5),var(--bg));
  border-top:1px solid var(--line);
  align-items:center;
}
.sc-label { font-size:11px; color:var(--sub); font-weight:700; margin-right:4px; letter-spacing:.3px; }
.sc-sep { width:1px; height:18px; background:var(--border-soft); margin:0 4px; }
.sc-btn {
  padding:3px 9px;
  font-size:11px;
  font-family:Consolas,monospace;
  background:#fff;
  border:1px solid var(--border-soft);
  border-radius:5px;
  cursor:default;
  color:var(--text-600);
  transition:.12s;
  box-shadow:0 1px 2px rgba(15,23,42,.04);
}
.sc-btn:hover { background:#EAF2FF; border-color:#9EC5FF; color:var(--blue); transform:translateY(-1px); }
.sc-btn:active { transform:translateY(0); }
.sc-btn.sc-mini { padding:3px 6px; font-size:10px; }
.sc-btn.sc-danger { color:#DC2626; border-color:#FCA5A5; background:#FEF2F2; }
.sc-btn.sc-danger:hover { background:#FEE2E2; border-color:#EF4444; }
.sc-btn.sc-emph { color:var(--blue); border-color:#93C5FD; background:#EFF6FF; font-weight:700; }
.sc-btn.sc-emph:hover { background:#DBEAFE; border-color:var(--blue); }

/* ===== 监控面板 ===== */
.monitor-body { flex:1; overflow:auto; padding:10px; background:#FCFCFD; }
.mview { display:flex; flex-direction:column; gap:12px; }
.mgroup { padding:10px 12px 12px; background:#FFFFFF; border:1px solid var(--line); border-left:3px solid var(--line-300); border-radius:10px; box-shadow:0 1px 3px rgba(15,23,42,.05); }
.mgroup.type-x { border-left-color:var(--x); }
.mgroup.type-y { border-left-color:var(--y); }
.mgroup.type-m { border-left-color:var(--m); }
.mgroup.type-s { border-left-color:var(--s); }
.mgroup.type-t { border-left-color:var(--t); }
.mgroup.type-c { border-left-color:var(--c); }
.mgroup.type-d { border-left-color:var(--d); }
.mg-title { display:flex; align-items:center; gap:7px; font-size:11px; color:var(--sub); margin-bottom:8px; font-weight:700; letter-spacing:.4px; }
.mg-title::before { content:''; width:7px; height:7px; border-radius:50%; background:currentColor; opacity:.85; }
.mgroup.type-x .mg-title { color:var(--x); }
.mgroup.type-y .mg-title { color:var(--y); }
.mgroup.type-m .mg-title { color:var(--m); }
.mgroup.type-s .mg-title { color:var(--s); }
.mgroup.type-t .mg-title { color:var(--t); }
.mgroup.type-c .mg-title { color:var(--c); }
.mgroup.type-d .mg-title { color:var(--d); }
.cells { display:flex; flex-wrap:wrap; gap:6px; }
.cell { width:46px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px; padding:7px 0 6px; font-size:11px; border-radius:9px; cursor:default; border:1px solid var(--line-200); background:var(--panel-3); color:var(--sub); transition:.14s; box-shadow:0 1px 2px rgba(15,23,42,.04); }
.cell .cn { font-weight:700; font-size:10px; color:var(--muted); }
.cell .cv { font-size:12px; font-weight:700; font-family:Consolas,monospace; }
.cell.off .cv { color:var(--line-300); }
.cell.on .cv { color:#fff; }
/* HMI 指示灯圆点：OFF 暗灰，ON 实色发光 */
.cdot { width:13px; height:13px; border-radius:50%; background:var(--line-300); box-shadow:inset 0 0 3px rgba(15,23,42,.25); margin-bottom:1px; transition:.15s; }
.cell.toggle:hover { border-color:#9EC5FF; background:#EAF2FF; transform:translateY(-1px); box-shadow:0 3px 8px rgba(37,99,235,.12); }
.cell.toggle:active { transform:translateY(0); }
.cell.type-x { border-color:#BFDBFE; background:#EFF6FF; color:var(--x); }
.cell.type-y { border-color:#BBF7D0; background:#ECFDF5; color:var(--y); }
.cell.type-m { border-color:#FDE68A; background:#FFFBEB; color:var(--m); }
.cell.type-s { border-color:#E9D5FF; background:#FAF5FF; color:var(--s); }
.cell.type-x .cn, .cell.type-y .cn, .cell.type-m .cn, .cell.type-s .cn { color:inherit; opacity:.82; }
.cell.type-x.on { background:var(--x); color:#fff; border-color:var(--x); box-shadow:0 2px 8px rgba(59,130,246,.35); }
.cell.type-x.on .cn { color:#fff; }
.cell.type-y.on { background:var(--y); color:#fff; border-color:var(--y); box-shadow:0 2px 8px rgba(34,197,94,.35); }
.cell.type-y.on .cn { color:#fff; }
.cell.type-m.on { background:var(--m); color:#fff; border-color:var(--m); box-shadow:0 2px 8px rgba(245,158,11,.35); }
.cell.type-m.on .cn { color:#fff; }
.cell.type-s.on { background:var(--s); color:#fff; border-color:var(--s); box-shadow:0 2px 8px rgba(168,85,247,.35); }
.cell.type-s.on .cn { color:#fff; }
.cell.type-x.on .cdot { background:var(--x); box-shadow:0 0 9px 1px var(--x); }
.cell.type-y.on .cdot { background:var(--y); box-shadow:0 0 9px 1px var(--y); }
.cell.type-m.on .cdot { background:var(--m); box-shadow:0 0 9px 1px var(--m); }
.cell.type-s.on .cdot { background:var(--s); box-shadow:0 0 9px 1px var(--s); }

/* T/C/D 表 */
.table { display:grid; grid-template-columns:repeat(auto-fill,minmax(118px,1fr)); gap:4px; }
.tcell { position:relative; display:flex; flex-direction:column; padding:4px 8px 6px; font-size:11px; border:1px solid #D8DDE6; border-radius:6px; background:#fff; overflow:hidden; }
.tcell .tn { font-weight:700; color:var(--text); }
.tcell .tv { color:var(--blue); font-family:Consolas,monospace; font-weight:600; }
.tcell.type-t .tn { color:var(--t); }
.tcell.type-c .tn { color:var(--c); }
.tcell.type-d .tn { color:var(--d); }
.tcell.type-t .tv { color:var(--t); }
.tcell.type-c .tv { color:var(--c); }
.tcell.type-d .tv { color:var(--d); }
/* ET 精确定时器（1ms 时基）：与 T 同框但用青色区分，避免被当成普通 100ms 定时器 */
.tcell.type-et .tn { color:#0E7490; }
.tcell.type-et .tv { color:#0E7490; }
.tcell.type-et .pfill { background:#06B6D4; }
.tcell.type-et { border-style:dashed; }
.tcell.done { background:#ECFDF5; border-color:#86EFAC; }
.tcell.done .tv { color:#16A34A; }
.tcell.done .tn { color:#16A34A; }
.tcell.type-d { cursor:text; }
.pbar { height:3px; margin-top:4px; background:var(--bg); border-radius:3px; overflow:hidden; }
.pfill { height:100%; width:0; background:var(--t); border-radius:3px; transition:width .15s; }
.tcell.type-c .pfill { background:var(--c); }
.tcell.done .pfill { background:#16A34A; }

/* ===== 虚拟 I/O 面板（深色 PLC 面板风，三栏布局） ===== */
#mview-vio { background:linear-gradient(180deg,#0B1120,#0D1526); padding:12px; border-radius:12px; gap:10px; }
.vio-tip { color:#7E93B0; font-size:11px; margin-left:auto; }

.vio-cols { display:grid; grid-template-columns:repeat(3,1fr); gap:14px; align-items:start; }
@media (max-width:1024px){ .vio-cols { grid-template-columns:repeat(2,1fr); } }
@media (max-width:680px){ .vio-cols { grid-template-columns:1fr; } }
.vio-col { background:#0F1B2E; border:1px solid #243650; border-radius:12px; padding:12px; }
.vio-col-title { font-size:14px; font-weight:700; color:#CFE3FF; margin:2px 0 10px; padding-bottom:8px; border-bottom:1px solid #243650; letter-spacing:.5px; }
.vio-group { margin-bottom:14px; }
.vio-group:last-child { margin-bottom:0; }
.vio-group-title { font-size:12px; color:#7E93B0; margin-bottom:8px; font-weight:600; }

/* 按钮区 X0-X3 */
.vio-btn-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:10px; }
.vio-btn { display:flex; flex-direction:column; align-items:center; gap:6px; padding:10px 8px 8px; background:#16233A; border:1px solid #243650; border-radius:12px; cursor:pointer; user-select:none; transition:.14s; }
.vio-btn:hover { border-color:#3B82F6; transform:translateY(-1px); }
.vio-btn-head { width:100%; display:flex; justify-content:space-between; align-items:center; gap:4px; }
.vio-btn-name { font-size:13px; font-weight:700; color:#CFE3FF; font-family:Consolas,monospace; }
.vio-btn-type { font-size:10px; background:#0F1B2E; color:#9FB3D1; border:1px solid var(--text); border-radius:5px; padding:1px 2px; max-width:54px; cursor:pointer; }
.vio-btn-type:focus { border-color:#60A5FA; outline:none; }
.vio-btn-img { width:54px; height:54px; pointer-events:none; transition:.14s; }
.vio-btn.on .vio-btn-img { filter:drop-shadow(0 0 10px rgba(220,38,38,.55)); }
.vio-btn-state { font-size:11px; color:#7E93B0; }
.vio-btn.on .vio-btn-state { color:#F87171; }
.vio-btn-label { font-size:10px; color:#7E93B0; text-align:center; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.vio-btn.on .vio-btn-label { color:#9FB3D1; }
.vio-btn.forced { outline:2px solid #F59E0B; outline-offset:1px; }

/* 20260910：运动视图虚拟按钮 → 工业按钮风（立体凸面 + 状态色）。
   仅用 #mview-motion 限定，避免污染 I/O 监控面板的 X 卡片按钮。 */
#mview-motion .vio-btn {
  position: relative;
  padding: 12px 14px 10px;
  border: none; border-radius: 14px;
  color: #fff; font-weight: 700; font-size: 13px; letter-spacing: .5px;
  cursor: pointer; user-select: none;
  background: linear-gradient(180deg, #34d399 0%, #16a34a 58%, #15803d 100%);
  box-shadow: 0 4px 0 #0f5e2c, 0 6px 14px rgba(0,0,0,.45);
  transition: transform .08s ease, box-shadow .08s ease, filter .12s ease;
}
#mview-motion .vio-btn:hover { filter: brightness(1.08); }
#mview-motion .vio-btn:active { transform: translateY(3px); box-shadow: 0 1px 0 #0f5e2c, 0 2px 6px rgba(0,0,0,.45); }
#mview-motion .vio-btn.k-stop {
  background: linear-gradient(180deg, #fca5a5 0%, #ef4444 58%, #b91c1c 100%);
  box-shadow: 0 4px 0 #7f1212, 0 6px 14px rgba(0,0,0,.45);
}
#mview-motion .vio-btn.k-stop:active { transform: translateY(3px); box-shadow: 0 1px 0 #7f1212, 0 2px 6px rgba(0,0,0,.45); }
#mview-motion .vio-btn.k-warn {
  background: linear-gradient(180deg, #fcd34d 0%, #f59e0b 58%, #b45309 100%);
  box-shadow: 0 4px 0 #7c3f08, 0 6px 14px rgba(0,0,0,.45);
}
#mview-motion .vio-btn.k-warn:active { transform: translateY(3px); box-shadow: 0 1px 0 #7c3f08, 0 2px 6px rgba(0,0,0,.45); }
#mview-motion .vio-btn.on { outline: 2px solid #FCD34D; outline-offset: 2px; }
/* 重置位置按钮：蓝色工业风，与 X 模拟按钮区分 */
#mview-motion .vio-reset {
  padding: 10px 18px; border: none; border-radius: 12px;
  color: #fff; font-weight: 700; font-size: 13px; letter-spacing: .5px; cursor: pointer;
  background: linear-gradient(180deg, #60a5fa 0%, #3b82f6 58%, #2563eb 100%);
  box-shadow: 0 4px 0 #1e40af, 0 6px 14px rgba(0,0,0,.45);
  transition: transform .08s ease, box-shadow .08s ease, filter .12s ease;
}
#mview-motion .vio-reset:hover { filter: brightness(1.08); }
#mview-motion .vio-reset:active { transform: translateY(3px); box-shadow: 0 1px 0 #1e40af, 0 2px 6px rgba(0,0,0,.45); }

/* 20260910b：IO 端子按钮区 → 统一尺寸 + 右侧端子说明卡补空档
   （基础 .vio-btn 是块级 flex 列，导致按钮竖排留右侧空档；这里改成横向 flex 行，
   按钮 flex:1 等宽，.vio-spec 占据剩余空间） */
#mview-motion .vio-btns { display:flex; flex-wrap:wrap; align-items:stretch; gap:10px; }
#mview-motion .vio-btns .vio-btn {
  flex: 1 1 110px; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; min-height: 46px; line-height: 1.25;
}
/* 端子说明卡：填充按钮区右侧空档 */
#mview-motion .vio-spec {
  flex: 2 1 260px; margin-left: auto; align-self: stretch;
  background: #0f1b2e; border: 1px solid #243650; border-radius: 12px;
  padding: 10px 14px; color: #9fb3d1; font-size: 12px;
}
#mview-motion .vio-spec h4 { margin: 0 0 6px; font-size: 12px; letter-spacing: 1px; color: #cbd5e1; }
#mview-motion .vio-spec ul { margin: 0; padding: 0; list-style: none; }
#mview-motion .vio-spec li {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px;
  padding: 3px 0; border-bottom: 1px dashed #1e2d44;
}
#mview-motion .vio-spec li:last-child { border-bottom: none; }
#mview-motion .vio-spec li b { color: #e2e8f0; font-weight: 700; }
#mview-motion .vio-spec li span { color: #7E93B0; font-size: 11px; }

/* 拨动开关 X4-X7 */
.vio-tog-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:10px; }
.vio-toggle { display:flex; align-items:center; gap:10px; padding:12px 10px; background:#16233A; border:1px solid #243650; border-radius:12px; cursor:pointer; user-select:none; transition:.14s; }
.vio-toggle:hover { border-color:#3B82F6; }
.vio-toggle .tog-icon-img { width:64px; height:64px; flex:0 0 auto; object-fit:contain; transition:.14s; }
.vio-toggle.on .tog-icon-img { filter:drop-shadow(0 0 7px rgba(59,130,246,.65)); }
.vio-toggle .tog-name { font-size:13px; font-weight:700; color:#CFE3FF; font-family:Consolas,monospace; }
.vio-toggle .tog-meta { display:flex; flex-direction:column; gap:1px; }
.vio-toggle .tog-label { font-size:10px; color:#7E93B0; }
.vio-toggle.on .tog-label { color:#3B82F6; }
.vio-toggle .tog-state { font-size:11px; font-weight:700; color:var(--muted); margin-top:2px; }
.vio-toggle.on .tog-state { color:#3B82F6; text-shadow:0 0 8px rgba(59,130,246,.6); }
.vio-toggle.forced { outline:2px solid #F59E0B; outline-offset:1px; }

/* 传感器指示 X8-X15 */
.vio-sen-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:10px; }
.vio-sensor { display:flex; align-items:center; gap:10px; padding:11px 10px; background:#16233A; border:1px solid #243650; border-radius:12px; }
.vio-sensor .sen-icon-img { width:56px; height:78px; flex:0 0 auto; object-fit:contain; transition:.14s; }
/* ON 态图标自身亮绿发光+呼吸光晕，不再叠加 CSS 绿光 */
.vio-sensor .sen-meta { display:flex; flex-direction:column; gap:1px; }
.vio-sensor .sen-name { font-size:12px; font-weight:700; color:#CFE3FF; font-family:Consolas,monospace; }
.vio-sensor .sen-type { font-size:10px; color:#7E93B0; }
.vio-sensor .sen-state { margin-left:auto; font-size:11px; color:#7E93B0; }
.vio-sensor.on .sen-state { color:#22C55E; }
.vio-sensor { cursor:pointer; user-select:none; transition:.14s; }
.vio-sensor:hover { border-color:#3B82F6; }
.vio-sensor.forced { outline:2px solid #F59E0B; outline-offset:1px; }

/* 输出面板 Y */
.vio-y-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(118px,1fr)); gap:12px; }
.vio-y-card { background:#16233A; border:1px solid #243650; border-radius:12px; padding:12px; display:flex; flex-direction:column; align-items:center; gap:8px; transition:.14s; }
.vio-y-card.on { border-color:#22C55E; box-shadow:0 0 12px rgba(34,197,94,.25); }
.vio-y-head { width:100%; display:flex; justify-content:space-between; align-items:center; gap:4px; }
.vio-y-name { font-size:13px; font-weight:700; color:#CFE3FF; font-family:Consolas,monospace; }
.vio-y-type { font-size:10px; background:#0F1B2E; color:#9FB3D1; border:1px solid var(--text); border-radius:5px; padding:1px 3px; max-width:64px; }
.vio-y-dev { width:100%; height:58px; display:flex; align-items:center; justify-content:center; position:relative; }
.vio-y-status { font-size:11px; color:#7E93B0; }
.vio-y-card.on .vio-y-status { color:#22C55E; }

/* 设备图标（内联 SVG，currentColor，CSS 着色） */
.vio-dev { width:54px; height:54px; display:inline-flex; align-items:center; justify-content:center;
  color:#5B6B82; filter:drop-shadow(0 2px 3px rgba(0,0,0,.55)); transition:.15s; }
.vio-dev svg { width:100%; height:100%; display:block; }
.vio-y-card.on .vio-dev { color:#22C55E; filter:drop-shadow(0 0 9px rgba(34,197,94,.5)); }
/* 报警灯 ON 闪烁（红）：豆包爆闪灯自带内部 pulse，外层再叠 CSS 透明度闪烁兜底，并用红色辉光 */
.vio-y-card.on.type-alarm .vio-dev,
.vio-y-card.on.type-alarm .vio-dev-img { filter:drop-shadow(0 0 12px rgba(248,113,113,.75)); animation:vioalarm .55s steps(1) infinite; }
/* 信捷写实 SVG（<img> 引用，固定颜色，无需 currentColor 着色） */
.vio-dev-img { width:54px; height:54px; object-fit:contain; filter:drop-shadow(0 2px 3px rgba(0,0,0,.55)); transition:.15s; }
.vio-y-card.on .vio-dev-img { filter:drop-shadow(0 0 10px rgba(34,197,94,.55)); }
/* 按设备类型着色 ON 态 */
.vio-y-card.on.type-motor .vio-dev   { color:#60A5FA; filter:drop-shadow(0 0 9px rgba(96,165,250,.5)); }
/* 气缸：改用豆包生成的写实气动缸 OFF/ON 双文件（assets/vio/agg/cylinder_off.svg|on.svg），ON 态由 .vio-dev-img 统一绿色发光 */
.vio-y-card.type-cylinder .vio-dev-img { width:84px; height:46px; object-fit:contain; }
.vio-y-card.on.type-valve .vio-dev    { color:#F59E0B; filter:drop-shadow(0 0 9px rgba(245,158,11,.5)); }
.vio-y-card.on.type-fan .vio-dev      { color:#A78BFA; filter:drop-shadow(0 0 9px rgba(167,139,250,.5)); animation:viofan .8s linear infinite; }
@keyframes vioalarm { 50% { opacity:.4; } }
@keyframes viofan { 100% { transform:rotate(360deg); } }
/* 设备状态文字 */
.dev-detail { font-size:10px; color:#7E93B0; margin-top:2px; }
.vio-y-card.on .dev-detail { color:#CFE3FF; }
.vio-y-card.on.type-motor .dev-detail { color:#60A5FA; }
.vio-y-card.on.type-cylinder .dev-detail { color:#22C55E; }
.vio-y-card.on.type-alarm .dev-detail { color:#F87171; }
.vio-y-card.on.type-valve .dev-detail { color:#F59E0B; }
.vio-y-card.on.type-fan .dev-detail { color:#A78BFA; }
/* 豆包写实指示灯：<img> 双文件渲染，尺寸略小于通用 54px；ON 绿色辉光由通用 .vio-y-card.on .vio-dev-img 提供 */
.vio-y-card.type-led .vio-dev-img { width:46px; height:46px; object-fit:contain; }

/* T/C 仪表卡片 */
.vio-gauge-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(96px,1fr)); gap:10px; margin-bottom:14px; }
.vio-gauge { background:#16233A; border:1px solid #243650; border-radius:12px; padding:10px; position:relative; overflow:hidden; }
.vio-gauge .gauge-head { display:flex; justify-content:space-between; align-items:center; }
.vio-gauge .gauge-name { font-size:12px; font-weight:700; font-family:Consolas,monospace; }
.vio-gauge.type-t .gauge-name { color:#38BDF8; }
.vio-gauge.type-c .gauge-name { color:#A855F7; }
.vio-gauge .gauge-flag { font-size:10px; color:#0B1120; background:#22C55E; padding:1px 6px; border-radius:6px; visibility:hidden; }
.vio-gauge .gauge-cur { font-size:26px; font-weight:800; color:var(--line-200); font-family:Consolas,monospace; line-height:1.1; margin-top:4px; }
.vio-gauge .gauge-sub { font-size:10px; color:#7E93B0; }
.vio-gauge .gauge-set { font-size:11px; color:#9FB3D1; cursor:pointer; border-bottom:1px dashed var(--text); }
.vio-gauge .gauge-set:hover { color:#38BDF8; border-bottom-color:#38BDF8; }
.gauge-set-input, .inline-int-input { width:56px; font-size:11px; background:#0F1B2E; color:var(--line-200); border:1px solid #38BDF8; border-radius:4px; padding:1px 3px; }
.vio-gauge .gauge-bar { height:5px; margin-top:8px; background:#0F1B2E; border-radius:5px; overflow:hidden; }
.vio-gauge .gauge-fill { height:100%; width:0; background:#38BDF8; border-radius:5px; transition:width .15s; }
.vio-gauge.type-c .gauge-fill { background:#A855F7; }
.vio-gauge.done { border-color:#22C55E; }

/* D 模拟量卡片 */
.vio-analog-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(110px,1fr)); gap:10px; }
.vio-analog { background:#16233A; border:1px solid #243650; border-radius:12px; padding:10px; }
.vio-analog .analog-head { display:flex; justify-content:space-between; }
.vio-analog .analog-name { font-size:12px; font-weight:700; color:#F59E0B; font-family:Consolas,monospace; }
.vio-analog .analog-val { font-size:22px; font-weight:800; color:var(--line-200); font-family:Consolas,monospace; }
.vio-analog .analog-slider { width:100%; margin-top:6px; accent-color:#F59E0B; }
.vio-analog .analog-unit { font-size:10px; color:#7E93B0; }

/* ===== 状态栏 ===== */
.statusbar { display:flex; align-items:center; gap:18px; background:linear-gradient(180deg,var(--panel-5),var(--bg)); border-top:1px solid var(--line); height:28px; padding:0 14px; font-size:11px; color:var(--sub); box-shadow:0 -1px 3px rgba(15,23,42,.04); }
.s-led { font-weight:700; }
.s-led.run { color:#16A34A; animation:pulse 1.3s ease-in-out infinite; }
.s-led.stop { color:#DC2626; }
@keyframes pulse { 0%,100% { opacity:1; text-shadow:0 0 6px rgba(22,163,74,.6); } 50% { opacity:.5; text-shadow:none; } }
.s-item b { color:var(--blue); font-family:Consolas,monospace; }
.s-item.sp { margin-left:auto; }
.s-item.right { color:var(--muted); }
/* 程序已修改、等待自动落盘的提示（防刷新丢失） */
.prog-dirty { color:#B45309; font-weight:600; }

/* ===== 模态框 ===== */
.modal-mask { position:fixed; inset:0; background:rgba(15,23,42,.4); backdrop-filter:blur(2px); display:flex; align-items:center; justify-content:center; z-index:9999; }
.modal { background:#fff; border-radius:12px; width:540px; max-width:90vw; max-height:82vh; display:flex; flex-direction:column; box-shadow:0 20px 60px rgba(15,23,42,.3); overflow:hidden; }
.modal-title { padding:14px 18px; font-size:15px; font-weight:700; border-bottom:1px solid var(--panel-6); background:linear-gradient(180deg,var(--panel-4),#F1F4F8); }
.modal-body { padding:18px; overflow:auto; flex:1; font-size:13px; line-height:1.7; white-space:pre-wrap; }
.modal-body code { background:#F1F4F8; padding:1px 6px; border-radius:4px; font-family:Consolas,monospace; }
.modal-foot { padding:12px 18px; border-top:1px solid var(--panel-6); display:flex; justify-content:flex-end; }
.mbtn { padding:7px 26px; background:var(--blue); color:#fff; border:none; border-radius:6px; font-size:13px; cursor:default; box-shadow:0 2px 6px rgba(37,99,235,.35); }
.mbtn:hover { background:#1D4ED8; }
.param-form { display:flex; flex-direction:column; gap:12px; }
.pf-row { display:flex; align-items:center; justify-content:space-between; gap:12px; font-size:13px; color:var(--text); }
.pf-row span { color:var(--text-600); }
.pf-input { width:160px; padding:6px 8px; border:1px solid var(--border-soft); border-radius:6px; font-size:13px; }
.pf-input:focus { border-color:var(--blue); outline:none; }
.param-note { font-size:11px; color:var(--muted); line-height:1.5; background:var(--panel-3); padding:8px 10px; border-radius:6px; }

/* ===== 指令手册检索弹窗 ===== */
.modal-wide { width:560px; max-width:92vw; }
.help-title { display:flex; align-items:center; gap:10px; }
.help-search { width:auto; flex:1; margin-left:auto; }
.help-list { max-height:60vh; overflow:auto; }
.help-usage { font-size:12px; color:var(--text-600); line-height:1.6; background:var(--panel-3); border-left:3px solid var(--blue); padding:8px 12px; border-radius:6px; margin-bottom:10px; }
.help-item { border:1px solid var(--panel-6); border-radius:8px; padding:8px 10px; margin-bottom:7px; background:#fff; }
.help-item:hover { border-color:var(--blue); }
.hi-name { font-weight:700; font-size:13px; color:var(--ink); font-family:Consolas,monospace; }
.hi-cat { font-size:10px; font-weight:600; color:#fff; background:var(--x); border-radius:8px; padding:1px 7px; margin-left:8px; }
.hi-desc { font-size:12px; color:var(--sub); margin-top:3px; }
.help-empty { color:var(--sub); font-size:13px; padding:12px; text-align:center; }

/* 滚动条 */
::-webkit-scrollbar { width:11px; height:11px; }
::-webkit-scrollbar-thumb { background:var(--scroll); border-radius:6px; border:3px solid var(--panel-2); }
::-webkit-scrollbar-thumb:hover { background:var(--scroll-hover); }
::-webkit-scrollbar-track { background:var(--panel-2); }

/* ===== 梯形图 SVG 样式 ===== */
.ld-grid { fill:var(--panel-4); }
.ld-gridline { stroke:#9BBF6E; stroke-width:1; }            /* 暗绿，绿底上能看见 */
.ld-rail { stroke:var(--ink); stroke-width:3.5; }             /* 深色加粗，贯穿全高 */
.ld-net-border { stroke:var(--text-600); stroke-width:2; fill:none; }      /* OR 框上下横线:深色 2px,在绿底上清晰 */
.ld-net-label { fill:var(--muted); font-size:10px; font-family:Consolas,monospace; }
.ld-step-num { fill:var(--text); font-size:12px; font-family:Consolas,monospace; font-weight:700; }
.ld-wire { stroke:var(--text-600); stroke-width:2; fill:none; }            /* 深灰 2px，绿底上清晰可见 */
.ld-wire.wire-on { stroke:var(--wire-on); stroke-width:2.6; filter:drop-shadow(0 0 2px rgba(22,163,74,.6)); }
.ld-el-bg { stroke:var(--ink); stroke-width:1.2; }                   /* XCPPro 真实风格：触点细黑线 1.2px */
.ld-el-text { fill:var(--ink); font-size:12px; font-family:Consolas,monospace; text-anchor:middle; }
.ld-el-text.text-on { fill:var(--ink-900); font-weight:700; }
.ld-coil-bg { fill:#fff; stroke:var(--ink); stroke-width:1.2; }       /* XCPPro 真实风格：线圈空心圆圈 O，白底黑线 1.2px */
.ld-box-bg { fill:var(--app-bg); stroke:var(--app); stroke-width:1.4; rx:3; }
.ld-selected { stroke:var(--blue); stroke-width:2; fill:none; stroke-dasharray:4 3; }

/* 网格背景（XCPPro 风格：整张画布均匀小格子） */
.ld-grid-path { stroke:#C3E08A; stroke-width:1; }
.ld-grid-rect { fill:url(#ldGrid); pointer-events:none; }
/* 元件下方注释（启动/停止/电机 等） */
.ld-comment { fill:#4A8B3A; font-size:11px; font-family:"Microsoft YaHei","微软雅黑",sans-serif; text-anchor:middle; }
/* 选中网络虚线框（点击网络显示） */
.ld-net-sel { fill:transparent; stroke:none; pointer-events:all; cursor:pointer; }
.ld-net-sel.active { stroke:var(--ink); stroke-width:1.3; stroke-dasharray:5 3; }

/* 多页标签（XCPPro 风格：PLC1 - 梯形图 ▼） */
.ld-tabs { display:flex; padding:4px 8px 0; background:var(--bg); border-bottom:1px solid var(--line); flex:0 0 auto; }
.ld-tab { font-size:12px; padding:5px 13px; background:var(--panel); border:1px solid var(--line); border-bottom:none; border-radius:6px 6px 0 0; color:var(--sub); cursor:default; user-select:none; }
.ld-tab.active { background:#CCE5A0; color:var(--ink); font-weight:600; border-color:#9BBF6E; }
.ld-tab .caret { font-size:9px; opacity:.65; margin-left:5px; }

/* 元件类型色 —— XCPPro 真实风格：触点统一细黑线；线圈统一深色边框（白底+深色stroke=空心圆圈O） */
/* 线圈：统一用基础 .ld-coil-bg 的 var(--ink) 深色边框，不再按 Y/M/S 类型着色（绿边在绿底上不可见） */
/* 指令框保留类型色（T橙/C蓝/应用蓝）——填充框比线圈圆圈醒目 */
.type-t .ld-box-bg { stroke:var(--t); fill:var(--t-bg); }
.type-c .ld-box-bg { stroke:var(--c); fill:var(--c-bg); }
.type-app .ld-box-bg { stroke:var(--app); fill:var(--app-bg); }

/* 通电/发光：XCPPro 风格——得电全部标红。限定在 .ladder-scroll.live 下生效，避免常闭触点在 STOP 状态就被标红（常闭在 X1 OFF 时本身"导通"，会触发 .on） */
.ladder-scroll.live .on .ld-el-bg,
.ladder-scroll.live .on .ld-coil-bg { stroke:#DC2626; stroke-width:2; }
.ladder-scroll.live .type-t.on .ld-box-bg  { stroke:#DC2626; fill:#FEE2E2; stroke-width:2.3; }
.ladder-scroll.live .type-c.on .ld-box-bg  { stroke:#DC2626; fill:#FEE2E2; stroke-width:2.3; }
.ladder-scroll.live .type-app.on .ld-box-bg{ stroke:#DC2626; fill:#FEE2E2; stroke-width:2.3; }
.ladder-scroll.live .on { filter:drop-shadow(0 0 3px rgba(220,38,38,.55)); }
.ladder-scroll.live .on .ld-el-text { fill:#DC2626; font-weight:700; }

/* ============================================================
 * 梯形图图形编辑器 (ladder-editor.js)
 * ============================================================ */
.ld-editor { display:flex; flex-direction:column; height:100%; overflow:hidden; position:relative; font-family:-apple-system,"PingFang SC","Microsoft YaHei",sans-serif; }

/* 工具栏 */
.ld-ed-toolbar { display:flex; align-items:center; gap:4px; padding:5px 10px; background:var(--panel); border-bottom:1px solid var(--line-200); flex-shrink:0; }
.ld-ed-btn { padding:3px 10px; font-size:12px; border:1px solid var(--line-300); border-radius:4px; background:#fff; cursor:pointer; white-space:nowrap; }
.ld-ed-btn:hover{ background:var(--panel-3); border-color:var(--muted); }
.ld-ed-primary{ background:#1E40AF; color:#fff; border-color:#1E40AF; }
.ld-ed-primary:hover{ background:#1D4ED8; }
.ld-ed-danger{ color:#DC2626; border-color:#FCA5A5; margin-top:6px; }
.ld-ed-danger:hover{ background:#FEF2F2; }
.ld-ed-sep{ width:1px; height:18px; background:var(--line-300); margin:0 4px; }
/* a139：符号工具条（按钮只画符号，快捷键仅在悬停提示里出现） */
.ld-ed-symbar{ display:flex; align-items:center; gap:2px; padding:3px 10px; background:var(--panel); border-bottom:1px solid var(--line-200); flex-shrink:0; }
.ld-ed-symbtn{ width:34px; height:26px; display:flex; align-items:center; justify-content:center; padding:0;
  border:1px solid transparent; border-radius:3px; background:transparent; cursor:pointer; }
.ld-ed-symbtn:hover{ background:#fff; border-color:var(--muted); }
.ld-ed-symbtn:active{ background:var(--panel-3); }
.ld-ed-symbtn svg{ display:block; }
.ld-ed-symsep{ width:1px; height:16px; background:var(--line-300); margin:0 3px; }

/* IL 指令输入条（类 XCPPro：输入指令回车生成元件） */
/* 指令输入条（嵌入画布顶部，类信捷 XCPPro） */
.ld-ed-ilbar{ display:flex; flex-wrap:wrap; align-items:center; gap:6px; padding:4px 8px; background:var(--panel); border-bottom:1px solid var(--line-300); flex-shrink:0; position:relative; z-index:10; }
.ld-ed-ilbar-label{ font-size:11px; font-weight:600; color:var(--text-600); white-space:nowrap; }
/* a122q-P2-#10：IL 输入行行内报错 */
.ld-ed-il-err{ flex-basis:100%; font-size:11px; color:#DC2626; min-height:14px; margin-top:2px; }
/* a122q-P2-#9：指令速查浮层 */
.ld-ed-refpanel{ position:absolute; top:44px; right:8px; width:360px; max-height:70%; overflow:auto; background:#fff; border:1px solid var(--line-300); border-radius:8px; box-shadow:0 8px 24px rgba(15,23,42,.18); z-index:30; padding:8px 10px; font-size:12px; }
.ld-ed-ref-head{ display:flex; align-items:center; justify-content:space-between; font-weight:700; color:var(--ink-900); margin-bottom:6px; }
.ld-ed-ref-close{ padding:1px 6px; font-size:11px; }
.ld-ed-ref-cat{ color:var(--muted); font-weight:700; font-size:11px; margin:6px 0 2px; }
.ld-ed-ref-row{ display:flex; gap:6px; padding:2px 0; border-bottom:1px dashed var(--line-200); line-height:1.4; }
.ld-ed-ref-op{ flex:0 0 64px; font-weight:700; color:var(--blue); }
.ld-ed-ref-label{ flex:0 0 96px; color:var(--text); }
.ld-ed-ref-desc{ flex:1; color:var(--text-600); }
.ld-ed-il-input-wrap{ position:relative; flex:1; }
.ld-ed-il-input{ width:100%; padding:3px 8px; font-size:12px; font-family:'Consolas','Courier New',monospace; border:1px solid var(--muted); border-radius:3px; background:#fff; outline:none; box-sizing:border-box; }
.ld-ed-il-input:focus{ border-color:#3B82F6; box-shadow:0 0 0 2px rgba(59,130,246,.15); }

/* 指令自动补全下拉列表 */
.ld-ed-autocomplete{ position:absolute; top:100%; left:0; right:0; max-height:220px; overflow-y:auto;
  background:#fff; border:1px solid var(--muted); border-top:none; border-radius:0 0 4px 4px;
  box-shadow:0 4px 12px rgba(0,0,0,.12); z-index:100; }
.ld-ac-item{ display:grid; grid-template-columns:140px 1fr; align-items:center; gap:8px; padding:4px 8px; cursor:pointer; font-size:11.5px; color:var(--text);
  border-bottom:1px solid var(--panel); }
.ld-ac-item:last-child{ border-bottom:none; }
.ld-ac-item:hover, .ld-ac-item.selected{ background:#EFF6FF; color:#1D4ED8; }
.ld-ac-item.selected{ background:#DBEAFE; }
.ld-ac-op{ font-weight:700; font-family:'Consolas','Courier New',monospace; font-size:11px; color:#1D4ED8; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.ld-ac-desc{ color:var(--sub); font-size:10.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.ld-ed-float-cap{ font-size:11px; font-weight:700; color:#1D4ED8; padding:3px 8px 5px; border-bottom:1px solid var(--line-200); background:#fff; }
.ld-ac-group{ position:sticky; top:0; z-index:1; font-size:10px; font-weight:700; color:#64748B; letter-spacing:.3px; padding:6px 8px 3px; background:#F1F5F9; border-bottom:1px solid var(--line-200); }

/* 就地浮层指令输入框（跟随光标，类信捷 XCPPro） */
.ld-ed-float{ position:fixed; z-index:1000; width:360px; max-width:84vw;
  background:#fff; border:1px solid #3B82F6; border-radius:6px; box-shadow:0 10px 30px rgba(15,23,42,.24); padding:5px; }
/* wx修复(a130)：光标框形态收窄——浮层跟随光标但只占本格附近，不再挡住右侧格子
   （360px 恒宽曾盖住光标格右侧约4格，点击被浮层吃掉，竖线/并联加错位置，实证 _repro_cai.js） */
.ld-ed-float-narrow{ width:96px; }
.ld-ed-float-input{ width:100%; padding:6px 8px; font-size:13px; font-family:'Consolas','Courier New',monospace;
  border:1px solid var(--muted); border-radius:4px; background:#fff; outline:none; box-sizing:border-box; }
.ld-ed-float-input:focus{ border-color:#3B82F6; box-shadow:0 0 0 2px rgba(59,130,246,.15); }
.ld-ed-float-ac{ margin-top:5px; max-height:460px; overflow-y:auto; border-top:1px solid var(--line-200); padding-top:3px;
  background:#fff; border-radius:0 0 4px 4px; }
.ld-ed-float-err{ margin-top:4px; font-size:11px; color:#DC2626; min-height:14px; }

/* 主区域：调色板 | 画布 | 属性+IL */
.ld-ed-main{ display:flex; flex:1; overflow:hidden; }

/* 调色板 */
.ld-ed-palette{ width:130px; padding:6px; background:var(--panel-3); border-right:1px solid var(--line-200); overflow-y:auto; flex-shrink:0; }
.ld-ed-pcat{ font-size:10px; color:var(--sub); margin:6px 0 2px; letter-spacing:1px; }
.ld-ed-pbtn{ display:block; width:100%; padding:4px 6px; margin-bottom:2px; font-size:11px; text-align:left; border:1px solid var(--line-200); border-radius:3px; background:#fff; cursor:pointer; color:var(--text); }
.ld-ed-pbtn:hover{ background:#EFF6FF; border-color:#93C5FD; }
.ld-ed-pbtn-sel{ background:#DBEAFE; border-color:#3B82F6; color:#1D4ED8; font-weight:600; }

/* 画布容器 */
/* a143：悬停注释气泡（替代浏览器原生 SVG title 的延迟提示，官方风格即时显示） */
.ld-ed-tip{ position:absolute; z-index:60; max-width:280px; padding:5px 8px; display:none;
  background:#fffbe6; border:1px solid #d9c97a; border-radius:4px; box-shadow:0 3px 10px rgba(15,23,42,.18);
  font-size:11px; line-height:1.5; color:#3f3f2f; pointer-events:none; white-space:nowrap; }
.ld-ed-tip b{ color:#1f2937; }
.ld-ed-tip .ld-ed-tip-code{ font-family:Consolas,"Courier New",monospace; color:#a12c96; font-weight:600; }
.ld-ed-tip .ld-ed-tip-cmt{ color:#4A8B3A; white-space:normal; }
.ld-ed-tip .ld-ed-tip-pos{ color:#9ca3af; font-size:10px; }
.ld-ed-canvas-wrap{ flex:1; overflow:auto; padding:0; background:#eaf5cf; cursor:crosshair; }
.ld-ed-svg{ display:block; margin:0; background:#eaf5cf; }

/* 底部状态栏（紧凑，替代右侧面板默认显示） */
.ld-ed-statusbar{ font-size:11px; color:var(--sub); padding:4px 8px; background:var(--panel); border-top:1px solid var(--line-200); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* 右侧面板 */
.ld-ed-side{ width:220px; border-left:1px solid var(--line-200); display:flex; flex-direction:column; overflow-y:auto; flex-shrink:0; background:#FAFCFE; }
.ld-ed-side.collapsed{ display:none; }

/* 属性面板 */
.ld-ed-props{ border-bottom:1px solid var(--line-200); }
.ld-ed-props-title{ font-size:11px; font-weight:700; padding:6px 8px 3px; color:var(--text-600); background:var(--panel); border-bottom:1px solid var(--line-200); }
.ld-ed-props-body{ padding:8px; font-size:12px; }
.ld-ed-props label{ display:block; font-size:10px; color:var(--sub); margin-top:6px; }
.ld-ed-props .ld-ed-input{ width:100%; padding:3px 5px; font-size:12px; border:1px solid var(--line-300); border-radius:3px; margin-bottom:3px; box-sizing:border-box; }
.ld-ed-props .ld-ed-input.short{ width:60px; }
.ld-ed-hint{ font-size:11px; color:var(--muted); margin:4px 0; line-height:1.4; }

/* IL 输出区 */
.ld-ed-il-output{ flex:1; display:flex; flex-direction:column; min-height:0; }
.ld-ed-il-title{ font-size:11px; font-weight:700; padding:6px 8px 3px; color:var(--text-600); background:var(--panel); border-bottom:1px solid var(--line-200); }
.ld-ed-il-text{ flex:1; margin:6px; padding:8px; font:11px/1.5 "Cascadia Code","Fira Code",Consolas,monospace; background:#1E293B; color:var(--line-200); border-radius:4px; overflow:auto; white-space:pre; tab-size:2; }

/* 编辑器内元件样式 */
.ld-ed-txt{ font-size:11px; fill:var(--ink); font-family:Consolas,"Courier New",monospace; pointer-events:none; }
.ld-ed-cmt{ font-size:10px; fill:#4A8B3A; font-weight:normal; }
.ld-ed-inv{ font-size:8px; fill:var(--muted); }
.ld-ed-rnum{ font-size:9px; fill:var(--muted); font-family:monospace; }
.ld-ed-cell{ cursor:pointer; }
/* 得电触点高亮：绿色 + 加粗（!important 覆盖一切） */
.ld-ed-cell.live line { stroke:#2563EB !important; stroke-width:4px !important; }
.ld-ed-cell.live text { fill:#2563EB !important; font-weight:800 !important; }
.ld-ed-hover-hint{ font-size:9px; fill:#3B82F6; font-weight:600; pointer-events:none; }

/* 梯形图面板：预览/编辑 模式切换 */
.ld-mode-tabs{ display:flex; gap:2px; }
.ld-mode-tab{ padding:3px 10px; font-size:12px; border:1px solid transparent; border-radius:4px 4px 0 0; background:transparent; cursor:pointer; color:var(--sub); }
.ld-mode-tab.active{ background:#fff; color:#1E293B; border-color:var(--line-200) var(--line-200) #fff var(--line-200); font-weight:600; }
.ld-mode-tab:hover:not(.active){ background:var(--panel); }
.ld-pane-view{ display:block; flex:1; min-height:0; overflow:hidden; }
.ld-title{ font-size:13px; font-weight:700; color:var(--ink); }

/* ===== 数字人讲解系统 ===== */
.narr-controls{ display:flex; flex-wrap:wrap; gap:8px; align-items:center; padding:8px 0; }
.narr-btn{ padding:6px 14px; font-size:13px; border:1px solid #2563EB; background:#2563EB; color:#fff; border-radius:6px; cursor:pointer; }
.narr-btn:hover{ background:#1D4ED8; }
.narr-stage{ font-size:13px; color:var(--text); display:flex; align-items:center; gap:4px; }
.narr-stage select{ padding:4px 6px; border:1px solid var(--line-300); border-radius:5px; font-size:13px; }
.narr-mute{ font-size:13px; color:var(--text); display:flex; align-items:center; gap:4px; }
.narr-progress{ font-size:12px; color:var(--sub); min-height:16px; padding:2px 0; }
.narr-tip{ font-size:12px; color:var(--sub); line-height:1.6; background:var(--panel-3); border-left:3px solid #2563EB; padding:6px 10px; border-radius:0 4px 4px 0; }

/* 数字人讲师形象（阶段2 2D 矢量，自包含内联 SVG） */
.narr-avatar-wrap{ display:flex; flex-direction:column; align-items:center; padding:4px 0 2px; }
.narr-avatar{ position:relative; width:138px; height:156px; overflow:hidden; }
.narr-avatar svg{ width:100%; height:100%; display:block; }
.narr-avatar-img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; border-radius:14px; display:none; }
.narr-avatar-video{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; border-radius:14px; display:none; background:var(--ink-900); }
.narr-avatar-name{ font-size:12px; color:var(--text-600); margin-top:1px; font-weight:600; letter-spacing:0.5px; }
/* 形象模式切换显示 */
.narr-avatar.mode-cartoon svg{ display:block; }
.narr-avatar.mode-cartoon .narr-avatar-img,
.narr-avatar.mode-cartoon .narr-avatar-video,
.narr-avatar.mode-cartoon .narr-composite{ display:none; }
.narr-avatar.mode-real svg{ display:none; }
.narr-avatar.mode-real .narr-avatar-img{ display:block; }
.narr-avatar.mode-real .narr-avatar-video,
.narr-avatar.mode-real .narr-composite{ display:none; }
/* 视频 / 合成模式：撑满讲解区可用宽度 */
.narr-avatar.mode-video{ width:100%; max-width:320px; height:260px; box-shadow:0 4px 14px rgba(15,23,42,.18); margin:0 auto; border-radius:14px; overflow:hidden; }
.narr-avatar.mode-video svg,
.narr-avatar.mode-video .narr-avatar-img,
.narr-avatar.mode-video .narr-composite{ display:none; }
.narr-avatar.mode-video .narr-avatar-video{ display:block; }
/* 合成模式 */
.narr-avatar.mode-composite{ width:100%; max-width:392px; height:300px; box-shadow:0 4px 14px rgba(15,23,42,.18); margin:0 auto; }
.narr-avatar.mode-composite svg,
.narr-avatar.mode-composite .narr-avatar-img,
.narr-avatar.mode-composite .narr-avatar-video{ display:none; }
.narr-avatar.mode-composite .narr-composite{ display:flex; }
/* 合成模式：默认隐藏，仅 mode-composite 时显示 */
.narr-composite{ width:100%; height:100%; gap:6px; display:none; align-items:stretch; }
/* a121：智慧屏改为上下两区（上=梯形图 / 下=讲义），讲义做成纸面融进屏幕，不再是浮层字幕条 */
.narr-screen{ position:relative; flex:1 1 auto; min-width:0; background:#0B1220; border:3px solid #1E293B; border-radius:10px; overflow:hidden; display:flex; flex-direction:column; align-items:stretch; justify-content:flex-start; }
.narr-screen svg{
  position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);
  width:auto !important; height:auto !important; max-width:96% !important; max-height:96% !important;
  display:block; background:#fff;
}
/* a121：svg 必须绝对定位——若参与流式布局，大梯形图会把整块智慧屏撑出视口（实测 1240px），
   讲义区就被顶到屏幕外面看不见了 */
.narr-screen-label{ position:absolute; top:4px; right:6px; z-index:2; font-size:10px; color:#BFDBFE; background:rgba(15,23,42,.55); padding:1px 6px; border-radius:4px; pointer-events:none; }
.narr-screen-empty{ color:var(--muted); font-size:12px; padding:12px; text-align:center; line-height:1.6; }
.narr-composite-teacher{ flex:0 0 130px !important; width:130px !important; max-width:130px !important; height:100% !important; object-fit:cover; border-radius:10px; box-shadow:0 2px 8px rgba(0,0,0,.22); background:var(--ink-900); }
/* 合成/真人说话：讲师照片柔和呼吸式缩放 + 屏幕金色辉光 */
.narr-avatar.mode-composite.talking .narr-composite-teacher{ animation: realTalk .4s ease-in-out infinite; }
.narr-avatar.mode-composite.talking .narr-screen{ box-shadow:0 0 0 2px #F59E0B, 0 0 14px rgba(245,158,11,.5); transition:box-shadow .2s; }
/* 嘴部：说话时上下开合（无音频幅值依赖，由播放状态驱动） */
.narr-avatar #narrMouth{ transform-box: fill-box; transform-origin: center top; }
.narr-avatar.talking #narrMouth{ animation: mouthTalk .3s ease-in-out infinite; }
@keyframes mouthTalk{ 0%,100%{ transform: scaleY(.18); } 50%{ transform: scaleY(1); } }
/* 整体轻微律动，增强"在讲话"的生动感 */
.narr-avatar.talking{ animation: avatarBob .7s ease-in-out infinite; }
@keyframes avatarBob{ 0%,100%{ transform: translateY(0); } 50%{ transform: translateY(-2px); } }
/* 真人版说话：柔和呼吸式缩放（图无独立口型元素） */
.narr-avatar.mode-real.talking .narr-avatar-img{ animation: realTalk .4s ease-in-out infinite; }
@keyframes realTalk{ 0%,100%{ transform: scale(1); } 50%{ transform: scale(1.035); } }

/* 3D 真人模式（Three.js 写实头像 + 实时梯形图 + 屏内字幕） */
.narr-avatar3d{ display:none; flex:0 0 150px !important; width:150px !important; max-width:150px !important; height:100% !important; border-radius:10px; background:#0E1830; box-shadow:0 2px 8px rgba(0,0,0,.28); }
.narr-avatar.mode-composite .narr-avatar3d{ display:none !important; }
.narr-avatar.mode-3d{ width:100%; max-width:392px; height:300px; box-shadow:0 4px 14px rgba(15,23,42,.18); margin:0 auto; }
.narr-avatar.mode-3d svg,
.narr-avatar.mode-3d .narr-avatar-img,
.narr-avatar.mode-3d .narr-avatar-video{ display:none; }
.narr-avatar.mode-3d .narr-composite{ display:flex; }
.narr-avatar.mode-3d .narr-composite-teacher{ display:none !important; }
.narr-avatar.mode-3d .narr-avatar3d{ display:block; }
.narr-avatar.mode-3d.talking .narr-screen{ box-shadow:0 0 0 2px #F59E0B, 0 0 14px rgba(245,158,11,.5); transition:box-shadow .2s; }
/* 3D 模式：禁用容器级 bob 动画。该动画会给含 WebGL 画布的容器加 transform，
   导致 preserveDrawingBuffer 画布在多数显卡上整块闪烁（用户报告的"整个身子闪"）。
   3D 口型由引擎内部 blendshape 驱动，不需要 CSS 抖动。 */
.narr-avatar.mode-3d.talking{ animation: none !important; }
.narr-avatar.mode-3d.talking #narrMouth{ animation: none !important; }

/* ===== a120：全身数字人讲师（DigitalHuman，独立画布避免与 Avatar3D 抢 WebGL context） ===== */
.narr-human3d{ display:none; flex:0 0 150px !important; width:150px !important; max-width:150px !important;
  height:100% !important; border-radius:10px; background:#0E1830; box-shadow:0 2px 8px rgba(0,0,0,.28); }
.narr-avatar.mode-human{ width:100%; max-width:392px; height:300px; box-shadow:0 4px 14px rgba(15,23,42,.18); margin:0 auto; }
.narr-avatar.mode-human svg,
.narr-avatar.mode-human .narr-avatar-img,
.narr-avatar.mode-human .narr-avatar-video{ display:none; }
.narr-avatar.mode-human .narr-composite{ display:flex; }
.narr-avatar.mode-human .narr-composite-teacher{ display:none !important; }
.narr-avatar.mode-human .narr-avatar3d{ display:none !important; }
.narr-avatar.mode-human .narr-human3d{ display:block; }
.narr-avatar.mode-human.talking{ animation: none !important; }
.narr-avatar.mode-human.talking .narr-screen{ box-shadow:0 0 0 2px #F59E0B, 0 0 14px rgba(245,158,11,.5); transition:box-shadow .2s; }
/* 演示模式：全身+抬手需要更宽的画布，给到 40%（3D 头模是 34%） */
body.present-mode .narr-human3d{
  flex:0 0 40% !important; width:40% !important; max-width:none !important; height:100% !important;
}
.narr-screen-inner{ flex:1 1 auto; min-height:0; position:relative; overflow:hidden; background:#fff; }
/* a121-b：讲义区移到梯形图上方——激光笔朝上指，正好指向讲义（蔡哥 10:49 反馈）。
   新句插最顶部（激光笔所指方向），讲过的句子往下推、淡出，只留 3 行 */
.narr-script{
  flex:0 0 30%; min-height:0; display:flex; flex-direction:column; justify-content:flex-start;
  gap:3px; padding:8px 12px; background:#FDFBF3; color:var(--ink); font-size:13px; line-height:1.5;
  border-bottom:2px solid #E2DCC6; overflow:hidden;
}
/* a122i：切句平滑——基类补 max-height/overflow 让 .leaving 能塌缩收行；.enter 为新行滑入初始态 */
.narr-script-line{ flex:0 0 auto; opacity:.38; max-height:4em; overflow:hidden;
  transition:opacity .4s ease, transform .4s ease, max-height .45s ease .05s; }
.narr-script-line.prev{ opacity:.38; }
.narr-script-line.cur{ opacity:1; font-weight:600; color:#111827; }
.narr-script-line.old{ opacity:0; transform:translateY(8px); }
.narr-script-line.enter{ opacity:0; transform:translateY(-10px); }
.narr-script-line.leaving{ opacity:0; transform:translateY(6px); max-height:0; }
/* a121-b：激光阅读头光点——跟随当前逐字读取位置的发光红点。
   仅当 body.narr-laser-on（讲解中 + 全身数字人）且位于当前行(.cur)时显示。 */
.narr-laser-dot{ display:none; }
body.narr-laser-on .narr-script-line.cur .narr-laser-dot{
  display:inline-block;
  width:10px; height:10px; margin-left:6px;
  border-radius:50%; vertical-align:-1px;
  background:radial-gradient(circle at 35% 35%, #FFD9D1, #FF2B2B 46%, #A40000 100%);
  box-shadow:0 0 7px 2px rgba(255,43,43,.9), 0 0 16px 5px rgba(255,60,60,.4);
  animation:narrDotPulse .9s ease-in-out infinite;
}
@keyframes narrDotPulse{
  0%,100%{ transform:scale(1); opacity:1; }
  50%{ transform:scale(1.28); opacity:.82; }
}
.narr-script-empty{ color:#9CA3AF; font-size:12px; }
/* 旧浮层字幕条停用（讲义已融进屏幕下区） */
.narr-screen-sub{ display:none !important; }

/* 底部字幕条（始终可见当前讲解句）——改为浅色调+圆角，不再像"黑色视频条" */
.narr-subbar{
  display:flex; align-items:center; gap:10px;
  padding:6px 16px; background:#FEF3C7; color:#92400E;
  font-size:13px; line-height:1.5; border-top:2px solid #F59E0B;
  border-radius:0 0 8px 8px;
  min-height:34px;
}
.narr-sub-icon{ font-size:16px; flex:0 0 auto; cursor:pointer; user-select:none; }
.narr-sub-text{ flex:1 1 auto; }
/* a122m：讲义条收纳——未讲解时只显示右下角浮标，讲解时自动展开 */
.narr-subbar.narr-collapsed{ display:none; }
.narr-fab{
  display:none; position:fixed; right:14px; bottom:12px; z-index:900;
  width:36px; height:36px; border-radius:50%;
  border:2px solid #F59E0B; background:#FEF3C7; font-size:17px; line-height:1;
  cursor:pointer; box-shadow:0 2px 10px rgba(15,23,42,.28);
  transition:transform .15s ease;
}
.narr-fab:hover{ transform:scale(1.12); }
.narr-fab.show{ display:block; }
body.present-mode .narr-fab{ display:none !important; }

/* a122m：示例菜单搜索框 */
.dd-search{ padding:6px 10px 5px; border-bottom:1px solid var(--line); }
.dd-search input{
  width:100%; padding:4px 8px; border:1px solid var(--line-300); border-radius:4px;
  font-size:12.5px; font-family:inherit; outline:none; background:#fff; color:var(--text);
}
.dd-search input:focus{ border-color:var(--blue); box-shadow:0 0 0 2px #DBEAFE; }
.dd-nores{ padding:8px 16px; color:var(--muted); font-size:12.5px; }

/* ===== 讲解演示模式（铺满全屏：隐藏编辑器，智慧屏+数字人放大） ===== */
body.present-mode .pane-ladder,
body.present-mode .convert-col,
body.present-mode .pane-il{ display:none !important; }

body.present-mode .pane-monitor{
  position:fixed; inset:0; z-index:1000;
  width:100vw; height:100vh; border-radius:0; border:none;
  grid-column:auto; grid-row:auto; box-shadow:none;
}
body.present-mode .pane-monitor .pane-header{ display:none; }
body.present-mode .pane-body.monitor-body{ flex:1 1 auto; min-height:0; padding:0; }
body.present-mode .mtabs{ display:none; }

/* 强制讲解视图显示（不论当前 mtabs 选中谁） */
body.present-mode .mview{ display:none !important; }
body.present-mode #mview-narrate{ display:flex !important; flex-direction:column; flex:1 1 auto; min-height:0; padding:0; }
/* a121：智慧屏改流式布局（梯形图区+讲义区都在文档流内）后，演示视图必须显式限高，
   否则内容会把 #mview-narrate 撑出视口（实测 1320px > 950），讲义区被顶到屏幕外。
   注：CSS 原有的 .pane-monitor 全屏规则因 HTML 实际类名是 .main-view.view-monitor 而从未生效，
   演示模式的"占满"一直靠隐藏其他面板后自然放大——历史内容矮没暴露，这里一并补上约束。 */
body.present-mode .main-view.view-monitor{ height:100vh; overflow:hidden; }
/* a121：高度约束链的最后一环——mview > .mgroup > .narr-avatar-wrap，
   .mgroup 原本是普通块，wrap 的 flex:1 在非 flex 父级里无效，内容仍会把视图撑出视口 */
body.present-mode #mview-narrate .mgroup{ display:flex; flex-direction:column; flex:1 1 0; min-height:0; overflow:hidden; }
body.present-mode #mview-narrate .mg-title{ flex:0 0 auto; }
/* a121：monitor-body 原本不是 flex 容器，#mview-narrate 的 flex:1 形同虚设（高度=内容自然高，
   以前内容矮 + overflow:auto 滚动掩盖）。演示模式下必须立成 flex column，讲解视图才能被约束到视口内 */
body.present-mode .view-monitor .pane-body.monitor-body{ display:flex; flex-direction:column; overflow:hidden; }
body.present-mode .pane-body.monitor-body{ overflow:hidden; }

body.present-mode .narr-avatar-wrap{ flex:1 1 0; min-height:0; width:100%; padding:0; overflow:hidden; }
body.present-mode .narr-avatar{
  width:100% !important; max-width:none !important; height:100% !important;
  margin:0 !important; border-radius:0 !important; box-shadow:none !important;
}
body.present-mode .narr-composite{
  width:100%; height:100%; gap:18px; padding:18px 18px 88px; box-sizing:border-box;
  /* a121-b：底部 padding 88px 给悬浮控制条(narr-controls)留安全区，
     避免控制条盖住梯形图下沿/字幕（蔡哥 10:49 反馈"控制键掩盖字幕"） */
}
body.present-mode .narr-screen{
  flex:1 1 62%; border-width:4px; border-radius:14px;
}
/* 梯形图保持“屏上程序”的合理尺寸（不无限放大），智慧屏不显空 */
/* 演示模式：讲义区（屏上方）放大字号、占屏 22%（梯形图区吃掉剩余空间） */
body.present-mode .narr-script{
  flex:0 0 22%; font-size:21px; line-height:1.6; padding:14px 22px; gap:8px;
  border-top-width:3px;
}
body.present-mode .narr-screen-label{ font-size:14px; padding:3px 10px; }
body.present-mode .narr-avatar3d{
  flex:0 0 34% !important; width:34% !important; max-width:none !important; height:100% !important;
}
/* 视频/照片/卡通形象也铺满 */
body.present-mode .narr-avatar-video,
body.present-mode .narr-avatar-img{
  position:absolute; inset:0; width:100% !important; height:100% !important; object-fit:contain;
}
body.present-mode .narr-avatar svg{ width:100% !important; height:100% !important; }

/* 演示控制条悬浮底部居中 */
body.present-mode .narr-controls{
  position:fixed; left:50%; bottom:18px; transform:translateX(-50%);
  z-index:1001; background:rgba(15,23,42,.85); padding:10px 16px; border-radius:12px;
  box-shadow:0 6px 24px rgba(0,0,0,.4);
}
body.present-mode .narr-progress,
body.present-mode .narr-tip,
body.present-mode .narr-avatar-name{ display:none; }
/* 脚本已进智慧屏，底部字幕条隐藏避免重复 */
body.present-mode .narr-subbar{ display:none; }

/* 退出演示按钮（仅演示时可见） */
.present-exit-btn{
  display:none; position:fixed; top:16px; right:18px; z-index:1002;
  padding:8px 16px; font-size:14px; font-weight:700;
  background:rgba(220,38,38,.92); color:#fff; border:none; border-radius:10px;
  cursor:pointer; box-shadow:0 4px 16px rgba(0,0,0,.35);
}
.present-exit-btn:hover{ background:#DC2626; }
body.present-mode .present-exit-btn{ display:block; }

/* 梯形图讲解高亮层（黄色发光框，区别于 live 绿/蓝） */
/* a122i：讲解高亮 filter 过渡，高亮行切换时平滑亮起（不再瞬间跳） */
.ld-ed-narrfocus{ filter: drop-shadow(0 0 4px #F59E0B); transition: filter .35s ease; }

/* ===== 习题自测（教学闭环 MVP） ===== */
#quizRoot{ width:100%; }
.quiz-wrap{ display:flex; flex-direction:column; gap:12px; padding:2px; }
.quiz-head{ display:flex; align-items:center; justify-content:space-between; gap:12px; background:#fff; border:1px solid var(--line); border-left:3px solid var(--blue); border-radius:10px; padding:10px 14px; box-shadow:0 1px 3px rgba(15,23,42,.05); }
.quiz-title{ font-size:14px; font-weight:700; color:var(--blue); }
.quiz-progress{ display:flex; align-items:center; gap:10px; flex:1 1 auto; justify-content:flex-end; }
.quiz-progress-text{ font-size:12px; color:var(--sub); white-space:nowrap; }
.quiz-progress-text b{ color:var(--y); font-size:14px; }
.quiz-bar{ width:160px; height:8px; background:var(--bg); border-radius:6px; overflow:hidden; border:1px solid var(--line); }
.quiz-bar-fill{ height:100%; background:linear-gradient(90deg,#22C55E,#16A34A); transition:width .35s ease; }
.quiz-list{ display:flex; flex-direction:column; gap:14px; max-height:calc(100vh - 220px); overflow:auto; padding-right:4px; }
/* 检索条：搜索 + 状态筛选 + 全展开/全收起（137 题靠它定位） */
.quiz-tools{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; background:#fff; border:1px solid var(--line); border-radius:10px; padding:8px 12px; }
.quiz-search{ flex:1 1 260px; min-width:200px; font-size:13px; padding:6px 10px; border:1px solid var(--line); border-radius:6px; background:var(--panel-3); color:var(--ink); }
.quiz-search:focus{ outline:none; border-color:var(--blue); background:#fff; }
.quiz-filter{ font-size:12px; padding:6px 8px; border:1px solid var(--line); border-radius:6px; background:var(--panel-3); color:var(--ink); }
.quiz-chapter-title{ font-size:12px; font-weight:700; color:var(--sub); letter-spacing:.4px; margin:2px 2px 6px; display:flex; align-items:center; gap:8px; cursor:pointer; user-select:none; background:var(--panel); border:1px solid var(--line); border-radius:8px; padding:7px 11px; }
.quiz-chapter-title:hover{ background:var(--panel-7); color:var(--blue); }
.quiz-chapter-title .quiz-chapter-arrow{ font-size:10px; width:10px; color:var(--blue); }
.quiz-chapter-title .quiz-chapter-name{ flex:1 1 auto; }
.quiz-chapter-title .quiz-chapter-count{ font-size:11px; font-weight:600; color:var(--sub); background:#fff; border:1px solid var(--line); border-radius:20px; padding:1px 8px; }
.quiz-chapter-title.collapsed .quiz-chapter-count{ color:var(--muted); }
.quiz-chapter-body{ display:flex; flex-direction:column; gap:6px; }
.quiz-empty{ font-size:13px; color:var(--sub); background:var(--panel-3); border:1px dashed var(--line); border-radius:8px; padding:14px; text-align:center; }
.quiz-card{ background:#fff; border:1px solid var(--line); border-radius:10px; box-shadow:0 1px 3px rgba(15,23,42,.05); overflow:hidden; }
.quiz-card-main{ display:flex; align-items:center; gap:10px; padding:10px 12px; cursor:pointer; }
.quiz-card-main:hover{ background:#F7FAFF; }
.quiz-card-title{ font-size:13px; font-weight:600; color:var(--ink); }
.quiz-status{ font-size:10px; padding:2px 8px; border-radius:20px; font-weight:700; white-space:nowrap; }
.quiz-status.status-none{ background:var(--bg); color:var(--muted); }
.quiz-status.status-fail{ background:#FFF7ED; color:#EA580C; border:1px solid #FED7AA; }
.quiz-status.status-pass{ background:#ECFDF5; color:#16A34A; border:1px solid #BBF7D0; }
.quiz-card-detail{ padding:0 12px 12px; border-top:1px dashed var(--line); }
.quiz-desc{ margin-top:10px; font-size:12.5px; line-height:1.7; color:var(--text); white-space:pre-wrap; background:var(--panel-3); border:1px solid var(--line); border-radius:8px; padding:9px 11px; }
/* 案例（三菱101例移植版）：程序代码块 + 不可运行提示 */
.quiz-code{ margin-top:8px; font-family:ui-monospace,Consolas,"Courier New",monospace; font-size:12px; line-height:1.65; white-space:pre; overflow-x:auto; background:var(--ink-900); color:var(--line-200); border:1px solid #1F2D44; border-radius:8px; padding:10px 12px; }
.quiz-case-warn{ margin-top:8px; font-size:12px; line-height:1.6; color:#92400E; background:#FFFBEB; border-left:3px solid #F59E0B; border-radius:6px; padding:7px 10px; }
/* 元器件表（案例卡片）：数据来自 io_rows，放在程序上方，先看表再看程序 */
.quiz-iotable{ margin-bottom:8px; border:1px solid var(--line-ec); border-radius:6px; overflow:hidden; }
.quiz-iotable-cap{ font-size:11px; font-weight:700; color:var(--text-600); background:var(--panel); padding:4px 9px; border-bottom:1px solid var(--line-ec); }
.quiz-iotable-tb{ width:100%; border-collapse:collapse; font-size:11.5px; }
.quiz-iotable-tb th{ text-align:left; font-weight:600; color:var(--sub); background:var(--panel-3); padding:3px 9px; border-bottom:1px solid var(--line-200); }
.quiz-iotable-tb td{ padding:3px 9px; border-bottom:1px solid var(--bg); color:var(--text); vertical-align:top; }
.quiz-iotable-tb tr:last-child td{ border-bottom:none; }
.quiz-iotable-tb .io-addr{ font-family:Consolas,monospace; font-weight:700; color:#0E7490; white-space:nowrap; }
.quiz-hint{ margin-top:8px; font-size:12px; color:#92400E; background:#FFFBEB; border-left:3px solid #F59E0B; border-radius:6px; padding:7px 10px; line-height:1.6; }
/* 信捷101例：工艺控制要求 / IO分配 独立展示 */
.quiz-meta{ margin-top:8px; font-size:12.5px; line-height:1.7; white-space:pre-wrap; border-radius:8px; padding:9px 11px; }
.quiz-meta b{ display:block; font-size:11.5px; letter-spacing:.5px; margin-bottom:3px; opacity:.85; }
.quiz-process{ color:#0F5132; background:#ECFDF5; border:1px solid #BBF7D0; }
.quiz-io{ color:#1E3A8A; background:#EFF6FF; border:1px solid #BFDBFE; }
.quiz-port{ color:#7C2D12; background:#FFF7ED; border:1px solid #FED7AA; }
/* a57：学员练习题「分步目标」清单（拆小步脚手架），复用 tests[].name */
.quiz-steps{ color:var(--text); background:var(--panel); border:1px solid var(--line-200); }
.quiz-steps b{ color:var(--text-600); }
.quiz-steps-list{ margin:4px 0 0; padding-left:20px; }
.quiz-steps-list li{ margin:2px 0; line-height:1.55; }
/* a58：分步判分标记（提交后逐项打标） */
.quiz-steps-list li.step-pass{ color:#15803D; }
.quiz-steps-list li.step-pass::before{ content:'✓ '; color:#16A34A; font-weight:700; }
.quiz-steps-list li.step-fail{ color:#B91C1C; }
.quiz-steps-list li.step-fail::before{ content:'✗ '; color:#DC2626; font-weight:700; }
.quiz-steps-list li.step-block{ color:var(--muted); }
.quiz-steps-list li.step-block::before{ content:'🔒 '; }
/* 错题本 */
.quiz-wrong{ border:1px solid #FCA5A5; color:#DC2626; background:#FEF2F2; }
.quiz-wrong.on{ background:#FEE2E2; border-color:#EF4444; font-weight:700; }
.quiz-wmark{ font-size:10px; padding:2px 7px; border-radius:20px; font-weight:700; white-space:nowrap; background:#FEF2F2; color:#DC2626; border:1px solid #FCA5A5; }
.quiz-card-wrong{ border-color:#FCA5A5; box-shadow:0 1px 4px rgba(220,38,38,.12); }
.quiz-actions{ display:flex; gap:8px; margin-top:10px; }
.quiz-result{ margin-top:10px; font-size:12.5px; line-height:1.6; padding:8px 11px; border-radius:8px; display:none; }
.quiz-result.ok{ display:block; background:#ECFDF5; color:#15803D; border:1px solid #BBF7D0; }
.quiz-result.bad{ display:block; background:#FEF2F2; color:#B91C1C; border:1px solid #FECACA; }

/* ============================================================
 * 2026-08-31 习题页内嵌指令表编辑器 + 实时梯形图预览
 * （学员不离开习题页即可写程序、看梯图、提交、运行）
 * ============================================================ */
.quiz-editor-wrap{
  margin-top:10px;
  background:#FBFDFF;
  border:1px solid #DBEAFE;
  border-radius:10px;
  padding:10px 11px;
}
.quiz-editor-label{
  font-size:12.5px; font-weight:700; color:var(--blue);
  margin-bottom:7px;
}
.quiz-ins-bar{
  display:flex; align-items:center; flex-wrap:wrap; gap:5px;
  margin-bottom:8px;
}
.quiz-il{
  display:block;
  width:100%;
  min-height:120px;
  max-height:300px;
  resize:vertical;
  box-sizing:border-box;
  font-family:"Consolas","Courier New",monospace;
  font-size:13px; line-height:1.7;
  color:var(--ink);
  background:#fff;
  border:1px solid var(--muted); border-radius:8px;
  padding:9px 11px;
  white-space:pre; overflow:auto;
  tab-size:2;
}
.quiz-il:focus{
  outline:none; border-color:#3B82F6;
  box-shadow:0 0 0 2px rgba(59,130,246,.18);
  background:#fff;
}
.quiz-ld-preview{
  margin-top:9px;
  background:#fff;
  border:1px solid var(--line); border-radius:8px;
  padding:8px 10px;
  overflow:auto;
  max-height:360px;
}
.quiz-ld-preview svg{ width:100%; height:auto; display:block; }
.quiz-ld-preview.quiz-ld-err{ border-color:#FCA5A5; background:#FFF7F7; }
.quiz-ld-hint{ font-size:12px; color:#DC2626; line-height:1.5; }

/* ============================================================
 * 2026-08-21 紧凑 XJ 风格布局：主区域改为标签页，不再左右并排
 * ============================================================ */

/* 紧凑工具栏 */
.toolbar.compact{
  height:36px;
  padding:4px 10px;
  gap:0;
  background:linear-gradient(180deg,var(--panel-3),var(--bg));
}
.toolbar.compact .tsep{ height:20px; margin:0 6px; }
.toolbar.compact .tbtn{
  padding:3px 8px;
  font-size:11px;
  border-radius:5px;
}
.toolbar.compact .tbtn.icon-only{
  padding:3px 8px;
  font-size:15px;
  min-width:28px;
  justify-content:center;
}
.toolbar.compact .tbtn .ticon{ font-size:13px; }
.toolbar.compact .tlabel{ font-size:11px; margin-left:6px; }
.toolbar.compact .tslider{ width:90px; }
.toolbar.compact .tselect{ padding:3px 6px; font-size:11px; }
.toolbar.compact .tval{ font-size:11px; }
.toolbar.compact .machine-info{ max-width:220px; }
.tool-group{ display:flex; align-items:center; gap:4px; }
.tool-group.right{ margin-left:auto; }

/* 工作区：左工程面板 + 右主内容区 */
#app .workspace.xj-layout{
  display:flex;
  flex-direction:row;
  gap:0;
  padding:0;
  background:var(--bg-2);
  min-height:0;
}
.project-panel{
  width:160px;
  flex-shrink:0;
  background:var(--panel-5);
  border-right:1px solid var(--line);
  display:flex;
  flex-direction:column;
  overflow:hidden;
}
.pp-header{
  padding:7px 12px;
  font-size:15px;
  font-weight:700;
  color:var(--text);
  background:linear-gradient(180deg,#FFFFFF,var(--panel-2));
  border-bottom:1px solid var(--line);
}
.pp-tree{ padding:8px; font-size:12px; color:var(--text-600); overflow:auto; }
.pp-node{ margin-bottom:4px; }
.pp-caret{ font-size:9px; margin-right:4px; color:var(--muted); }
.pp-children{ margin:4px 0 4px 14px; }
.pp-leaf{
  padding:5px 8px;
  border-radius:5px;
  cursor:default;
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}
.pp-leaf:hover{ background:#EAF2FF; color:var(--blue); }
.pp-leaf.active{ background:#DBEAFE; color:var(--blue); font-weight:600; }
/* a122p-P1-1：工程树默认收起为图标栏（点 ☰ 展开），把横向空间让给梯形图画布 */
.project-panel { transition:width .18s ease; }
.project-panel.collapsed { width:28px; min-width:28px; cursor:pointer; }
.project-panel.collapsed .pp-header,
.project-panel.collapsed .pp-tree { display:none; }
.project-panel.collapsed::before { content:'☰'; display:flex; align-items:center; justify-content:center; height:32px; color:var(--muted); font-size:15px; }
.pp-collapse { cursor:pointer; color:var(--muted); font-size:16px; line-height:1; margin-right:4px; }
.pp-collapse:hover { color:var(--blue); }
.pp-title { font-weight:700; }
/* 轻量导航（教学向）：层级折叠 + 子分组标题 + 可点击光标 */
.pp-node.collapsed > .pp-children { display:none; }
.pp-label { font-weight:600; color:var(--text); }
.pp-subgroup { color:var(--muted); font-weight:600; font-size:11px; }
.pp-leaf[data-mtab], .pp-leaf[data-example], .pp-leaf[data-act] { cursor:pointer; }
.pp-leaf[data-mtab]:hover, .pp-leaf[data-example]:hover, .pp-leaf[data-act]:hover { background:#EAF2FF; color:var(--blue); }

.main-panel{
  flex:1;
  display:flex;
  flex-direction:column;
  min-width:0;
  background:var(--bg-2);
}
.main-tabs{
  display:flex;
  gap:0;
  padding:4px 8px 0;
  background:var(--bg-2);
  border-bottom:1px solid var(--line);
  flex-shrink:0;
}
.main-tab{
  padding:6px 18px;
  font-size:12px;
  font-weight:600;
  color:var(--sub);
  background:var(--panel);
  border:1px solid var(--line);
  border-bottom:none;
  border-radius:6px 6px 0 0;
  cursor:default;
  margin-right:3px;
  border-bottom:1px solid var(--line);
}
.main-tab:hover{ background:var(--line-200); }
.main-tab.active{
  background:#fff;
  color:var(--blue);
  border-color:var(--line);
  border-bottom:1px solid #fff;
  margin-bottom:-1px;
}
.main-body{
  flex:1;
  display:flex;
  flex-direction:column;
  min-height:0;
  padding:8px;
}
.main-view{
  display:none;
  flex-direction:column;
  flex:1;
  min-height:0;
  background:#fff;
  border:1px solid var(--line);
  border-radius:0 0 8px 8px;
  overflow:hidden;
  box-shadow:0 2px 10px rgba(15,23,42,.06);
}
.main-view.active{ display:flex; }

.view-header{
  display:flex;
  justify-content:space-between;
  align-items:center;
  background:linear-gradient(180deg,var(--panel-4),#F1F4F8);
  border-bottom:1px solid var(--line-100);
  padding:6px 12px;
  font-size:12px;
  font-weight:700;
  color:var(--text);
  flex-shrink:0;
}
.view-title{
  border-left:3px solid var(--y);
  padding-left:8px;
}
.view-il .view-title{ border-left-color:var(--x); }
.view-monitor .pane-header{ border-left:3px solid var(--m); }
.view-actions{ display:flex; align-items:center; gap:8px; }
.vbtn{
  padding:4px 10px;
  font-size:11px;
  background:#fff;
  border:1px solid var(--border-soft);
  border-radius:5px;
  cursor:default;
  color:var(--text);
}
.vbtn:hover{ background:#EAF2FF; border-color:#9EC5FF; color:var(--blue); }

/* 梯形图视图内部：让 ladder-editor 画布填满 */
.view-ladder{ background:#fff; }
.view-ladder .ld-pane-view{ flex:1; min-height:0; overflow:hidden; }

/* 示例工艺说明 / 元件表 */
.example-meta{
  flex-shrink:0;
  background:#FAFBFC;
  border-bottom:1px solid var(--line-100);
  padding:8px 12px 10px;
  font-size:12px;
  color:var(--text);
  max-height:160px;
  overflow:auto;
}
.example-meta:empty{ display:none; }
.em-title{ font-weight:700; font-size:13px; margin-bottom:4px; color:var(--ink-900); }
.em-process{ color:var(--text-600); line-height:1.5; margin-bottom:8px; }
.em-iotable{ border-collapse:collapse; width:100%; max-width:600px; }
.em-iotable th,
.em-iotable td{ border:1px solid var(--border-soft); padding:3px 8px; text-align:left; font-size:11px; }
.em-iotable th{ background:#F1F4F8; color:var(--sub); font-weight:600; }
.em-iotable td:first-child{ color:var(--ink-900); font-weight:600; }
.em-iotable td:nth-child(2){ color:#2563EB; font-family:monospace; }

/* ── 案例自检面板（20260902a45）────────────────────────────
   预期值来自案例标准答案的实跑快照，非手写，故口径改造后自动跟随。 */
.em-selfcheck{ margin-top:10px; border-top:1px dashed #D8DEE7; padding-top:8px; max-width:760px; }
.em-sc-head{ display:flex; align-items:center; gap:8px; margin-bottom:6px; }
.em-sc-title{ font-weight:700; font-size:12px; color:var(--ink-900); }
.em-sc-head .vbtn{ font-size:11px; padding:2px 8px; }
.em-sc-sum{ font-size:11px; color:var(--sub); }
.em-sc-sum.ok{ color:#15803D; font-weight:600; }
.em-sc-sum.bad{ color:#B91C1C; font-weight:600; }
.em-sc-body{ font-size:11px; color:var(--text-600); line-height:1.5; }
.em-sc-tip{ color:var(--sub); margin-bottom:6px; }
.em-sc-tbl{ border-collapse:collapse; width:100%; margin-top:4px; }
.em-sc-tbl th,
.em-sc-tbl td{ border:1px solid var(--border-soft); padding:3px 8px; text-align:left; font-size:11px; }
.em-sc-tbl th{ background:#F1F4F8; color:var(--sub); font-weight:600; }
.em-sc-tbl td.mono{ font-family:monospace; }
.em-sc-tbl tr.grp td{ background:var(--panel-3); color:var(--text); font-weight:600; }
.em-sc-tbl td.okv{ color:#15803D; font-weight:600; }
.em-sc-tbl td.badv{ color:#B91C1C; font-weight:600; }
.em-sc-err{ color:#B91C1C; background:#FEF2F2; border:1px solid #FECACA;
  border-radius:6px; padding:6px 8px; margin-top:6px; }

/* 指令表视图内部：让编辑器填满 */
.view-il{ background:#FCFCFD; }
.view-il .il-wrap{ flex:1; min-height:0; }
.view-il .il-editor{ background:#fff; }
.view-il .il-shortcuts{ border-bottom:none; border-radius:0 0 8px 8px; }

/* 监控视图内部：沿用现有 monitor 结构 */
.view-monitor .monitor-body{ flex:1; min-height:0; }

/* 讲解演示模式适配新结构 */
body.present-mode .project-panel,
body.present-mode .main-tabs,
body.present-mode .view-ladder,
body.present-mode .view-il,
body.present-mode .view-monitor{ display:none !important; }
body.present-mode .main-body{ padding:0; }
body.present-mode .main-view.view-monitor{ display:flex !important; position:fixed; inset:0; z-index:1000; width:100vw; height:100vh; border-radius:0; border:none; box-shadow:none; }
body.present-mode .view-monitor .pane-header{ display:none; }
body.present-mode .view-monitor .pane-body.monitor-body{ flex:1 1 auto; min-height:0; padding:0; }
body.present-mode .mtabs{ display:none; }
body.present-mode .mview{ display:none !important; }
body.present-mode #mview-narrate{ display:flex !important; flex-direction:column; flex:1 1 auto; min-height:0; padding:0; }
/* a121：智慧屏改流式布局（梯形图区+讲义区都在文档流内）后，演示视图必须显式限高，
   否则内容会把 #mview-narrate 撑出视口（实测 1320px > 950），讲义区被顶到屏幕外。
   注：CSS 原有的 .pane-monitor 全屏规则因 HTML 实际类名是 .main-view.view-monitor 而从未生效，
   演示模式的"占满"一直靠隐藏其他面板后自然放大——历史内容矮没暴露，这里一并补上约束。 */
body.present-mode .main-view.view-monitor{ height:100vh; overflow:hidden; }
/* a121：高度约束链的最后一环——mview > .mgroup > .narr-avatar-wrap，
   .mgroup 原本是普通块，wrap 的 flex:1 在非 flex 父级里无效，内容仍会把视图撑出视口 */
body.present-mode #mview-narrate .mgroup{ display:flex; flex-direction:column; flex:1 1 0; min-height:0; overflow:hidden; }
body.present-mode #mview-narrate .mg-title{ flex:0 0 auto; }
/* a121：monitor-body 原本不是 flex 容器，#mview-narrate 的 flex:1 形同虚设（高度=内容自然高，
   以前内容矮 + overflow:auto 滚动掩盖）。演示模式下必须立成 flex column，讲解视图才能被约束到视口内 */
body.present-mode .view-monitor .pane-body.monitor-body{ display:flex; flex-direction:column; overflow:hidden; }
body.present-mode .pane-body.monitor-body{ overflow:hidden; }
