/* ============ LadderSim — PLC Ladder Logic Simulator ============ */
:root{
  --bg:#eef1f6;
  --surface:#ffffff;
  --surface-2:#f6f8fb;
  --surface-3:#eaeef5;
  --border:#d3dae6;
  --border-strong:#b6c0d1;
  --text:#1b2330;
  --text-2:#5a6579;
  --muted:#8a94a6;
  --accent:#2563eb;
  --accent-2:#1d4ed8;
  --accent-soft:#e0e9ff;
  --ok:#16a34a;
  --ok-soft:#dcfce7;
  --warn:#d97706;
  --warn-soft:#fef3c7;
  --danger:#dc2626;
  --danger-soft:#fee2e2;
  --rail:#64748b;
  --wire:#98a2b3;
  --wire-on:#16a34a;
  --elem:#334155;
  --elem-on:#15803d;
  --block:#f8fafc;
  --shadow:0 1px 2px rgba(16,24,40,.06),0 4px 14px rgba(16,24,40,.06);
  --radius:10px;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;
  --font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Noto Sans SC","Noto Sans JP","Noto Sans KR",Arial,sans-serif;
}
[data-theme="dark"]{
  --bg:#0f141c;
  --surface:#161d27;
  --surface-2:#1b2430;
  --surface-3:#222c3a;
  --border:#2c3746;
  --border-strong:#3d4a5c;
  --text:#e7ecf3;
  --text-2:#a8b3c4;
  --muted:#7b8798;
  --accent:#4f8cff;
  --accent-2:#3b7bff;
  --accent-soft:#1d2a44;
  --ok:#34d399;
  --ok-soft:#123227;
  --warn:#fbbf24;
  --warn-soft:#3a2e12;
  --danger:#f87171;
  --danger-soft:#3a1d1d;
  --rail:#93a3b8;
  --wire:#5b6779;
  --wire-on:#34d399;
  --elem:#c3ccd9;
  --elem-on:#34d399;
  --block:#1e2735;
  --shadow:0 1px 2px rgba(0,0,0,.4),0 6px 18px rgba(0,0,0,.35);
}

*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;background:var(--bg);color:var(--text);
  font-family:var(--font);font-size:13px;line-height:1.45;
  -webkit-font-smoothing:antialiased;overflow:hidden;
}
#app{display:flex;flex-direction:column;height:100vh}

/* ---------- top bar ---------- */
.topbar{
  display:flex;align-items:center;gap:14px;padding:8px 12px;
  background:var(--surface);border-bottom:1px solid var(--border);
  box-shadow:var(--shadow);z-index:20;flex-wrap:wrap;
}
.brand{display:flex;align-items:center;gap:9px}
.brand .logo{width:26px;height:26px;fill:var(--accent)}
.brand-txt{display:flex;flex-direction:column;line-height:1.15}
.brand-txt b{font-size:15px;letter-spacing:.2px}
.brand-txt small{color:var(--muted);font-size:10.5px;white-space:nowrap}
.group{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.spacer{flex:1 1 auto}

.btn{
  display:inline-flex;align-items:center;gap:6px;
  padding:6px 11px;border-radius:8px;border:1px solid var(--border);
  background:var(--surface-2);color:var(--text);cursor:pointer;
  font-size:12.5px;font-family:inherit;white-space:nowrap;
  transition:background .12s,border-color .12s,transform .06s;
}
.btn:hover{background:var(--surface-3);border-color:var(--border-strong)}
.btn:active{transform:translateY(1px)}
.btn svg{width:15px;height:15px;fill:currentColor}
.btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}
.btn.primary:hover{background:var(--accent-2)}
.btn.ghost{background:transparent}
.btn.ghost:hover{background:var(--surface-2)}
.btn.icon{padding:6px 8px}
.btn.sm{padding:4px 8px;font-size:12px}
.btn.sm svg{width:13px;height:13px}
.btn.danger{color:var(--danger);border-color:var(--border)}
.btn.danger:hover{background:var(--danger-soft)}
.btn[disabled]{opacity:.45;pointer-events:none}
.btn.active{background:var(--accent-soft);border-color:var(--accent);color:var(--accent-2)}

.select,.input{
  padding:5px 8px;border-radius:7px;border:1px solid var(--border);
  background:var(--surface-2);color:var(--text);font-family:inherit;font-size:12.5px;
}
.input.sm,.select.sm{padding:3px 6px;font-size:12px}
.input:focus,.select:focus{outline:2px solid var(--accent-soft);border-color:var(--accent)}
.inline-field{display:flex;align-items:center;gap:5px;font-size:12px;color:var(--text-2)}
.inline-field input{width:58px;padding:4px 6px;border-radius:6px;border:1px solid var(--border);background:var(--surface-2);color:var(--text);font-family:var(--mono);font-size:12px}
.inline-field em{font-style:normal;color:var(--muted)}

.runstate{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-2);min-width:74px}
.led{width:10px;height:10px;border-radius:50%;background:var(--muted);box-shadow:0 0 0 2px rgba(0,0,0,.05) inset}
.led.on{background:var(--ok);box-shadow:0 0 8px var(--ok)}
.led.err{background:var(--danger);box-shadow:0 0 8px var(--danger)}

/* ---------- workspace ---------- */
.workspace{flex:1;display:flex;min-height:0;overflow:hidden}
.panel{position:relative;background:var(--surface);display:flex;flex-direction:column;min-height:0}
.panel.left{width:270px;min-width:190px;max-width:520px;border-right:1px solid var(--border)}
.panel.right{width:400px;min-width:240px;max-width:760px;border-left:1px solid var(--border)}
.resizer{position:absolute;top:0;right:-3px;width:6px;height:100%;cursor:col-resize;z-index:9}
.resizer.left-edge{right:auto;left:-3px}
.resizer:hover{background:var(--accent-soft)}

.tabs{display:flex;gap:2px;padding:6px 6px 0;border-bottom:1px solid var(--border);background:var(--surface-2)}
.tab{
  flex:1;padding:7px 8px;border:none;background:transparent;cursor:pointer;
  font-family:inherit;font-size:12.5px;color:var(--text-2);border-radius:7px 7px 0 0;
  border-bottom:2px solid transparent;
}
.tab:hover{background:var(--surface-3);color:var(--text)}
.tab.active{color:var(--accent-2);border-bottom-color:var(--accent);background:var(--surface);font-weight:600}
.tabpane{display:none;flex:1;min-height:0;flex-direction:column}
.tabpane.active{display:flex}
.pane-actions{display:flex;align-items:center;gap:6px;padding:7px 8px;border-bottom:1px solid var(--border);flex-wrap:wrap}
.pane-actions .input{flex:1;min-width:70px}
.search-wrap{padding:7px 8px;border-bottom:1px solid var(--border)}
.search-wrap .input{width:100%}
.chk{display:inline-flex;align-items:center;gap:5px;font-size:12px;color:var(--text-2);cursor:pointer;user-select:none}
.chk input{accent-color:var(--accent)}
.muted{color:var(--muted)}
.sm{font-size:11.5px}

/* ---------- palette ---------- */
.palette{flex:1;overflow-y:auto;padding:6px 6px 30px}
.pal-group{margin-bottom:6px}
.pal-head{
  display:flex;align-items:center;gap:6px;padding:5px 7px;cursor:pointer;
  font-size:11px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;
  color:var(--text-2);background:var(--surface-2);border-radius:6px;user-select:none;
}
.pal-head:hover{background:var(--surface-3)}
.pal-head .caret{width:9px;height:9px;fill:currentColor;transition:transform .15s}
.pal-group.collapsed .caret{transform:rotate(-90deg)}
.pal-group.collapsed .pal-items{display:none}
.pal-items{display:grid;grid-template-columns:repeat(auto-fill,minmax(78px,1fr));gap:4px;padding:5px 2px}
.pal-item{
  display:flex;flex-direction:column;align-items:center;gap:2px;padding:5px 2px 4px;
  border:1px solid transparent;border-radius:8px;cursor:grab;background:var(--surface-2);
  transition:border-color .12s,background .12s;
}
.pal-item:hover{border-color:var(--accent);background:var(--accent-soft)}
.pal-item:active{cursor:grabbing}
.pal-item svg{width:100%;height:30px;display:block}
.pal-item .mn{font-family:var(--mono);font-size:10px;font-weight:700;color:var(--text)}
.pal-item .nm{font-size:9px;color:var(--muted);text-align:center;line-height:1.15;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* ---------- tables ---------- */
.table-wrap{flex:1;overflow:auto}
.tagtable{width:100%;border-collapse:collapse;font-size:12px}
.tagtable th{
  position:sticky;top:0;z-index:2;background:var(--surface-2);text-align:left;
  padding:5px 7px;border-bottom:1px solid var(--border);font-size:10.5px;
  text-transform:uppercase;letter-spacing:.4px;color:var(--text-2);font-weight:700;white-space:nowrap;
}
.tagtable td{padding:3px 7px;border-bottom:1px solid var(--border);vertical-align:middle}
.tagtable tr:hover td{background:var(--surface-2)}
.tagtable tr.sel td{background:var(--accent-soft)}
.tagtable .mono{font-family:var(--mono);font-size:11.5px}
.tagtable input,.tagtable select{
  width:100%;border:1px solid transparent;background:transparent;color:var(--text);
  font-family:inherit;font-size:12px;padding:2px 4px;border-radius:5px;
}
.tagtable input:focus,.tagtable select:focus{border-color:var(--accent);background:var(--surface);outline:none}
.tagtable input.mono{font-family:var(--mono)}
.val-bool{display:inline-flex;align-items:center;gap:5px;font-family:var(--mono);font-weight:700;cursor:pointer}
.val-bool .dot{width:9px;height:9px;border-radius:50%;background:var(--border-strong)}
.mon-act{display:flex;gap:4px;flex-wrap:nowrap}
.montr.forced td{background:var(--warn-soft,#fef3c7)}
.montr.forced td.tv{font-weight:700;color:var(--warn-text,#b45309)}
.rowbtn{font-size:10.5px;padding:2px 6px;border:1px solid var(--border);border-radius:6px;background:var(--surface);color:var(--text);cursor:pointer;white-space:nowrap}
.rowbtn:hover{border-color:var(--accent)}
.rowbtn.del:hover{border-color:var(--danger);color:var(--danger)}
.val-bool.on .dot{background:var(--ok);box-shadow:0 0 6px var(--ok)}
.val-bool.on{color:var(--ok)}
.rowbtn{border:none;background:transparent;color:var(--muted);cursor:pointer;padding:2px 4px;border-radius:5px;font-size:12px}
.rowbtn:hover{background:var(--danger-soft);color:var(--danger)}
.rowbtn.f{font-family:var(--mono);font-size:10px;font-weight:700}
.rowbtn.f.act{background:var(--warn);color:#fff}
.empty-note{padding:22px 14px;text-align:center;color:var(--muted);font-size:12px}

/* ---------- center / ladder ---------- */
.center{flex:1;display:flex;flex-direction:column;min-width:0;background:var(--bg)}
.ladder-toolbar{
  display:flex;align-items:center;gap:6px;padding:6px 10px;
  background:var(--surface);border-bottom:1px solid var(--border);flex-wrap:wrap;
}
.ladder-toolbar .sep{width:1px;height:18px;background:var(--border);margin:0 3px}
.zoom-label{font-family:var(--mono);font-size:11.5px;color:var(--text-2);min-width:38px;text-align:center}
.ladder-scroll{flex:1;overflow:auto;padding:14px 14px 120px}
.ladder{transform-origin:0 0}
.ladder-hint{padding:26px 10px;text-align:center;color:var(--muted);font-size:12.5px}

.rung{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
  margin-bottom:10px;box-shadow:var(--shadow);overflow:hidden;
}
.rung.sel{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft)}
.rung-head{
  display:flex;align-items:center;gap:7px;padding:4px 8px;background:var(--surface-2);
  border-bottom:1px solid var(--border);
}
.rung-no{
  font-family:var(--mono);font-size:11px;font-weight:700;color:#fff;background:var(--rail);
  padding:1px 7px;border-radius:5px;min-width:30px;text-align:center;
}
.rung.energized .rung-no{background:var(--ok)}
.rung-cmt{
  flex:1;border:1px solid transparent;background:transparent;color:var(--text-2);
  font-family:inherit;font-size:12px;padding:2px 5px;border-radius:5px;font-style:italic;
}
.rung-cmt:focus{border-color:var(--accent);background:var(--surface);outline:none;font-style:normal}
.rung-tools{display:flex;gap:2px}
.rung-tools button{
  border:none;background:transparent;color:var(--muted);cursor:pointer;
  padding:3px 5px;border-radius:5px;font-size:12px;line-height:1;
}
.rung-tools button:hover{background:var(--surface-3);color:var(--text)}
.rung-tools button.del:hover{background:var(--danger-soft);color:var(--danger)}
.rung-body{overflow-x:auto;padding:2px 0}
.rung svg.net{display:block}

.net .rail{stroke:var(--rail);stroke-width:3;stroke-linecap:round}
.net .wire{stroke:var(--wire);stroke-width:2;fill:none}
.net .wire.on{stroke:var(--wire-on);stroke-width:2.6}
.net .el{stroke:var(--elem);stroke-width:2;fill:none;stroke-linecap:round}
.net .el.on{stroke:var(--elem-on)}
.net .blk{fill:var(--block);stroke:var(--elem);stroke-width:1.6}
.net .blk.on{stroke:var(--elem-on)}
.net text{font-family:var(--font);fill:var(--text);user-select:none}
.net text.opd{font-family:var(--mono);font-size:11px;font-weight:600}
.net text.mn{font-family:var(--mono);font-size:11.5px;font-weight:700}
.net text.prm{font-family:var(--mono);font-size:9.5px;fill:var(--text-2)}
.net text.val{font-family:var(--mono);font-size:9.5px;fill:var(--muted)}
.net text.on{fill:var(--elem-on)}
.net .cellhit{fill:transparent;cursor:pointer}
.net .cellhit:hover{fill:var(--accent-soft);opacity:.45}
.net .cellsel{fill:none;stroke:var(--accent);stroke-width:2;stroke-dasharray:4 3}
.net .lnkhit{fill:var(--border-strong);opacity:0;cursor:pointer;transition:opacity .12s}
.net .lnkhit:hover{opacity:.55}
.net .drop{fill:var(--accent-soft);opacity:.7}

/* ---------- device panel ---------- */
.device-panel{
  flex:1;overflow-y:auto;padding:9px;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(122px,1fr));gap:9px;align-content:start;
}
.dev{
  background:var(--surface-2);border:1px solid var(--border);border-radius:10px;
  padding:6px 5px 5px;display:flex;flex-direction:column;align-items:center;gap:3px;
  position:relative;user-select:none;transition:border-color .12s,box-shadow .12s;
}
.dev:hover{border-color:var(--border-strong)}
.dev.active{border-color:var(--ok);box-shadow:0 0 0 2px var(--ok-soft)}
.dev.dragging{opacity:.4}
.dev.dragover{border-color:var(--accent);border-style:dashed}
.dev svg{width:100%;height:66px;display:block;touch-action:none}
.dev .dlabel{
  font-size:11px;font-weight:600;text-align:center;line-height:1.2;color:var(--text);
  width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.dev .dtag{font-family:var(--mono);font-size:9.5px;color:var(--muted);
  width:100%;text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dev .dtag b{color:var(--accent-2);font-weight:700}
.dev .dbtns{position:absolute;top:2px;right:2px;display:none;gap:1px}
.dev:hover .dbtns{display:flex}
.dev .dbtns button{
  border:none;background:var(--surface);color:var(--muted);border:1px solid var(--border);
  border-radius:5px;cursor:pointer;font-size:10px;line-height:1;padding:2px 4px;
}
.dev .dbtns button:hover{color:var(--text);background:var(--surface-3)}
.dev .dbtns button.del:hover{color:var(--danger);background:var(--danger-soft)}
.dev .drag{position:absolute;top:3px;left:4px;color:var(--muted);font-size:11px;cursor:grab;display:none;line-height:1}
.dev:hover .drag{display:block}
.dev input[type=range]{width:94%;accent-color:var(--accent);margin:0}
.dev .dnum{font-family:var(--mono);font-size:11px;font-weight:700;color:var(--accent-2)}

.trend{width:100%;height:auto;display:block;background:var(--surface-2);border-bottom:1px solid var(--border)}

/* ---------- device picker ---------- */
.picker{display:flex;flex-direction:column;gap:8px;min-height:0}
.picker-groups{display:flex;flex-wrap:wrap;gap:4px}
.picker-body{
  overflow-y:auto;max-height:52vh;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(108px,1fr));gap:7px;padding:2px;
}
.pk{
  background:var(--surface-2);border:1px solid var(--border);border-radius:9px;padding:5px;
  cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:3px;text-align:center;
}
.pk:hover{border-color:var(--accent);background:var(--accent-soft)}
.pk svg{width:100%;height:52px}
.pk span{font-size:10.5px;line-height:1.2;color:var(--text-2)}

/* ---------- modal ---------- */
.modal-back{
  position:fixed;inset:0;background:rgba(15,20,28,.5);backdrop-filter:blur(2px);
  display:flex;align-items:center;justify-content:center;z-index:100;padding:18px;
}
.modal{
  background:var(--surface);border:1px solid var(--border);border-radius:14px;
  box-shadow:0 18px 60px rgba(0,0,0,.28);width:min(680px,100%);max-height:88vh;
  display:flex;flex-direction:column;overflow:hidden;
}
.modal.wide{width:min(900px,100%)}
.modal-head{display:flex;align-items:center;gap:8px;padding:12px 15px;border-bottom:1px solid var(--border)}
.modal-head h3{margin:0;font-size:14.5px;flex:1}
.modal-head .x{border:none;background:transparent;font-size:19px;line-height:1;color:var(--muted);cursor:pointer;padding:2px 6px;border-radius:6px}
.modal-head .x:hover{background:var(--surface-3);color:var(--text)}
.modal-body{padding:14px 15px;overflow:auto}
.modal-foot{display:flex;justify-content:flex-end;gap:7px;padding:11px 15px;border-top:1px solid var(--border);background:var(--surface-2)}
.form-grid{display:grid;grid-template-columns:132px 1fr;gap:9px 11px;align-items:center}
.form-grid label{font-size:12px;color:var(--text-2);text-align:right}
.form-grid .input,.form-grid .select{width:100%}
.form-grid .hint{grid-column:2;font-size:11px;color:var(--muted);margin-top:-5px}
.form-sec{grid-column:1/-1;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;
  color:var(--text-2);border-top:1px solid var(--border);padding-top:9px;margin-top:3px}
.ex-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:9px}
.ex{border:1px solid var(--border);border-radius:10px;padding:11px;cursor:pointer;background:var(--surface-2)}
.ex:hover{border-color:var(--accent);background:var(--accent-soft)}
.ex b{display:block;font-size:13px;margin-bottom:3px}
.ex span{font-size:11.5px;color:var(--text-2)}
.help-body h4{margin:14px 0 5px;font-size:13px}
.help-body h4:first-child{margin-top:0}
.help-body ul{margin:0;padding-left:19px}
.help-body li{margin-bottom:3px;font-size:12.5px;color:var(--text-2)}
.help-body kbd{
  font-family:var(--mono);font-size:11px;background:var(--surface-3);border:1px solid var(--border);
  border-bottom-width:2px;border-radius:5px;padding:0 4px;color:var(--text);
}

/* ---------- statusbar / toast ---------- */
.statusbar{
  display:flex;align-items:center;gap:14px;padding:4px 12px;font-size:11.5px;color:var(--text-2);
  background:var(--surface);border-top:1px solid var(--border);white-space:nowrap;overflow:hidden;
}
.statusbar b{font-weight:600;color:var(--muted)}
.statusbar span{display:inline-flex;gap:4px;align-items:center}
.pill{background:var(--surface-3);border-radius:20px;padding:1px 9px;font-weight:700;font-size:11px}
.pill.run{background:var(--ok-soft);color:var(--ok)}
.pill.stop{background:var(--surface-3);color:var(--muted)}
.pill.pause{background:var(--warn-soft);color:var(--warn)}

/* breakpoint marker on a rung */
.rung.bp .rung-no{position:relative}
.rung.bp .rung-no::after{content:"";position:absolute;right:-12px;top:50%;width:8px;height:8px;border-radius:50%;background:var(--danger);transform:translateY(-50%);box-shadow:0 0 0 2px var(--danger-soft)}
.rung-tools button.bp{color:var(--danger)}
.rung.bp .rung-tools button.bp{background:var(--danger-soft);color:var(--danger)}
.edit-group{margin-left:6px}

.toast{
  position:fixed;bottom:38px;left:50%;transform:translateX(-50%) translateY(20px);
  background:var(--text);color:var(--surface);padding:8px 16px;border-radius:9px;
  font-size:12.5px;opacity:0;pointer-events:none;transition:opacity .2s,transform .2s;z-index:200;
}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

/* scrollbars */
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:6px;border:2px solid var(--surface)}
::-webkit-scrollbar-thumb:hover{background:var(--muted)}

@media (max-width:1100px){
  .panel.left{width:220px}
  .panel.right{width:300px}
  .brand-txt small{display:none}
}
@media (max-width:820px){
  .workspace{flex-direction:column}
  .panel.left,.panel.right{width:auto;max-width:none;height:240px;border:none;border-top:1px solid var(--border)}
  .resizer{display:none}
}

/* ===== editor tabs (LD / FBD / SFC) ===== */
.editor-tabs{display:flex;gap:4px;padding:6px 10px;border-bottom:1px solid var(--border);background:var(--surface-2)}
.etab{appearance:none;border:1px solid var(--border);background:var(--surface);color:var(--text-2);padding:5px 14px;border-radius:7px;font-size:12.5px;font-weight:500;cursor:pointer}
.etab.active{background:var(--accent);color:#fff;border-color:var(--accent)}
.editor{display:none;flex:1;min-height:0;flex-direction:column}
.editor.active{display:flex}

/* ===== FBD ===== */
.fbd-host{flex:1;overflow:hidden;background:var(--surface-2);min-height:0}
.fbd-wrap{display:flex;height:100%}
.fbd-pal{width:172px;flex:none;overflow:auto;border-right:1px solid var(--border);background:var(--surface);padding:6px}
.fbd-pal-group{margin-bottom:8px}
.fbd-pal-item{padding:5px 8px;margin:2px 0;border:1px solid var(--border);border-radius:6px;font-size:12px;cursor:grab;background:var(--surface-2);font-family:var(--mono)}
.fbd-pal-item:hover{border-color:var(--accent);color:var(--accent)}
.fbd-canvas{flex:1;overflow:auto;position:relative;min-width:0}
.fbd-svg{display:block;background:var(--surface);background-image:radial-gradient(var(--border) 1px,transparent 1px);background-size:22px 22px;min-width:1600px;min-height:1000px}
.fbd-box{fill:var(--surface);stroke:var(--border-strong);stroke-width:1.5}
.fbdnode{cursor:move}
.fbdnode.sel .fbd-box{stroke:var(--accent);stroke-width:2}
.fbd-title{font-size:12px;font-weight:500;fill:var(--text)}
.fbd-pl{font-size:10px;fill:var(--text-2)}
.fbd-prm{font-size:9px;fill:var(--muted);font-family:var(--mono)}
.fbd-lit{font-size:9px;fill:var(--accent);font-family:var(--mono)}
.pin{fill:var(--surface);stroke:var(--border-strong);stroke-width:1.5;cursor:crosshair}
.pin.out{stroke:var(--accent)}
.pin.out.on{fill:var(--wire-on);stroke:var(--wire-on)}
.wire{fill:none;stroke:var(--wire);stroke-width:2}
.wire.on{stroke:var(--wire-on);stroke-width:2.5}
.wire.temp{stroke:var(--accent);stroke-dasharray:4 3}

/* ===== SFC ===== */
.sfc-host{flex:1;overflow:hidden;background:var(--surface-2);min-height:0}
.sfc-canvas{flex:1;overflow:auto}
.sfc-svg{display:block;background:var(--surface);background-image:radial-gradient(var(--border) 1px,transparent 1px);background-size:22px 22px;min-width:1400px;min-height:900px}
.sfc-step rect{fill:var(--surface);stroke:var(--border-strong);stroke-width:1.5}
.sfc-step.on rect{fill:var(--ok-soft);stroke:var(--ok);stroke-width:2}
.sfc-step.sel rect{stroke:var(--accent);stroke-width:2}
.sfc-name{font-size:12px;font-weight:500;fill:var(--text)}
.sfc-sub{font-size:9px;fill:var(--muted)}
.sfc-trans rect{fill:var(--surface);stroke:var(--border-strong);stroke-width:1.5}
.sfc-trans.sel rect{stroke:var(--accent);stroke-width:2}
.sfc-trans text{font-size:9px;fill:var(--text-2);font-family:var(--mono)}
.sfc-line{fill:none;stroke:var(--wire);stroke-width:2}

/* ===== ST view ===== */
.st-host{flex:1;display:flex;flex-direction:column;min-height:0;overflow:hidden;background:var(--surface-2)}
.st-code{flex:1;margin:0;padding:12px 14px;overflow:auto;font-family:var(--mono);font-size:12px;line-height:1.5;white-space:pre;
  color:var(--text);background:var(--surface);border-bottom:1px solid var(--border)}
.st-cmt{color:var(--muted);font-style:italic}
.st-kw{color:var(--accent);font-weight:600}
.st-id{color:var(--text)}
.st-num{color:#0a7d4d}
.st-edit-wrap{display:flex;flex-direction:column;border-top:1px solid var(--border);background:var(--surface-2)}
.st-edit-lbl{font-size:11px;color:var(--muted);padding:4px 10px 0}
.st-edit{flex:1;min-height:140px;resize:vertical;border:0;outline:0;padding:8px 14px;font-family:var(--mono);font-size:12px;
  background:var(--surface);color:var(--text);line-height:1.5}

/* ===== ST debugger ===== */
.st-dbg{flex:1;display:flex;flex-direction:column;min-height:0;overflow:hidden;background:var(--surface-2)}
.st-dbg[hidden]{display:none}
.dbg-bar{display:flex;align-items:center;gap:6px;padding:6px 10px;border-bottom:1px solid var(--border);background:var(--surface-2);flex:0 0 auto}
.dbg-bar .input.sm{max-width:180px}
.dbg-state{font-size:11px;color:var(--muted);padding:2px 8px;border-radius:10px;border:1px solid var(--border)}
.dbg-state.on{color:#a35c00;border-color:#e0a94a;background:#fff5e0;font-weight:600}
.dbg-body{flex:1;display:flex;min-height:0;overflow:hidden}
.dbg-code{flex:1;overflow:auto;font-family:var(--mono);font-size:12px;line-height:1.6;background:var(--surface);padding:6px 0}
.dbg-line{display:flex;align-items:flex-start;white-space:pre}
.dbg-line.cur{background:#fff3cd}
.dbg-line.cur .dbg-src{font-weight:600}
.dbg-gut{flex:0 0 44px;text-align:right;padding:0 8px 0 4px;color:var(--muted);user-select:none;border-right:1px solid var(--border)}
.dbg-gut.able{cursor:pointer}
.dbg-gut.able:hover{background:var(--surface-2);color:var(--text)}
.dbg-gut.bp{background:#d63a3a;color:#fff;font-weight:700}
.dbg-src{padding:0 12px;flex:1}
.dbg-watch{flex:0 0 260px;border-left:1px solid var(--border);overflow:auto;background:var(--surface-2)}
.dbg-watch-h{font-size:11px;font-weight:600;color:var(--muted);padding:6px 10px;border-bottom:1px solid var(--border);text-transform:uppercase;letter-spacing:.04em}
.dbg-watch .tbl{width:100%}
.dbg-watch .tbl td,.dbg-watch .tbl th{padding:3px 8px;font-size:11px}
.dbg-watch .r,.tbl .r{text-align:right}
.dbg-empty{padding:12px 14px}

/* ===== Trace bar ===== */
.trace-bar{display:flex;align-items:center;gap:8px;padding:6px 8px;flex-wrap:wrap;border-bottom:1px solid var(--border);background:var(--surface)}
.trace-lbl{font-size:11px;color:var(--muted)}
.range.sm{width:90px;height:4px;accent-color:var(--accent)}
.trace-val{font-size:11px;color:var(--muted);min-width:30px;display:inline-block;text-align:right}
.trend{width:100%;height:150px;display:block;background:var(--surface);border-bottom:1px solid var(--border)}

/* ===== Manager (recipes + alarms) ===== */
.mgr{display:flex;flex:1;min-height:0;overflow:hidden}
.mgr-col{flex:1;display:flex;flex-direction:column;min-height:0;border-right:1px solid var(--border)}
.mgr-col:last-child{border-right:0}
.rcp-list{flex:1;overflow:auto;padding:6px}
.rcp{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 8px;border-radius:8px;background:var(--surface);margin-bottom:6px}
.rcp-name{font-size:13px;font-weight:500}
.rcp-act{display:flex;gap:6px}
.tbl{width:100%;border-collapse:collapse;margin:6px 0;font-size:12px}
.tbl th,.tbl td{border:1px solid var(--border);padding:4px 8px;text-align:left}
.tbl th{background:var(--surface-2);color:var(--text-2);font-weight:600}
.tbl .rcp-chg{background:var(--warn-soft,#fef3c7)}
.tbl .rcp-chg td:first-child{font-weight:600}
.hint{font-size:11px;color:var(--muted);margin:4px 0}
.modal .input.mono,.modal textarea.input.mono{font-family:var(--mono,ui-monospace,monospace);font-size:12px;width:100%;min-height:90px;resize:vertical}
.alm-active{flex:1;overflow:auto;padding:6px;max-height:45%}
.alm-log{flex:1;overflow:auto;padding:6px;border-top:1px solid var(--border);max-height:55%}
.alm-log-h{font-size:11px;color:var(--muted);padding:2px 4px}
.alm{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:8px;background:var(--surface);margin-bottom:6px;border-left:3px solid var(--muted)}
.alm.sev-low{border-left-color:var(--info,#3b82f6)}
.alm.sev-med{border-left-color:#d97706}
.alm.sev-high{border-left-color:var(--danger,#dc2626)}
.alm.ack{opacity:.6}
.alm-dot{width:9px;height:9px;border-radius:50%;background:currentColor}
.alm.sev-low .alm-dot{color:var(--info,#3b82f6)}
.alm.sev-med .alm-dot{color:#d97706}
.alm.sev-high .alm-dot{color:var(--danger,#dc2626)}
.alm-txt{flex:1;display:flex;flex-direction:column}
.alm-txt small{color:var(--muted);font-size:10px;font-family:var(--mono)}
.alm-row{display:flex;align-items:center;gap:8px;padding:3px 6px;font-size:11px;border-radius:6px}
.alm-row.sev-low{color:var(--info,#3b82f6)}
.alm-row.sev-med{color:#d97706}
.alm-row.sev-high{color:var(--danger,#dc2626)}
.alm-row.clr{opacity:.7}
.alm-row.ack{text-decoration:line-through}
.alm-kind{font-weight:700}
.alm-msg{flex:1;font-family:var(--mono)}
.alm-at{color:var(--muted);font-family:var(--mono)}

/* ---------- XRef (cross-reference) ---------- */
.xref-list{padding:8px 10px;overflow:auto;flex:1}
.xref-item{border:1px solid var(--border);border-radius:8px;margin-bottom:8px;overflow:hidden;background:var(--panel-2,#0f172a)}
.xref-head{display:flex;align-items:center;gap:8px;padding:6px 10px;font-weight:600}
.xref-head .mono{font-family:var(--mono)}
.xref-badges{margin-left:auto;display:flex;gap:4px}
.xb{font-style:normal;font-size:10px;font-family:var(--mono);padding:1px 5px;border-radius:6px;background:var(--chip,#1e293b);color:var(--muted)}
.xb.read{background:rgba(59,130,246,.18);color:#60a5fa}
.xb.write{background:rgba(34,197,94,.18);color:#4ade80}
.xb.bind{background:rgba(168,85,247,.18);color:#c084fc}
.xb.lbl{background:rgba(234,179,8,.18);color:#facc15}
.xref-uses{display:flex;flex-wrap:wrap;gap:4px;padding:0 10px 8px}
.xref-use{font-size:11px;font-family:var(--mono);border:1px solid var(--border);background:transparent;color:var(--text);border-radius:6px;padding:2px 6px;cursor:pointer}
.xref-use:hover{border-color:var(--accent);color:var(--accent)}
.xref-use.xb-write{border-color:rgba(34,197,94,.4)}
.xref-use.xb-bind{border-color:rgba(168,85,247,.4)}
.xref-use.xb-label{border-color:rgba(234,179,8,.4)}

/* ---------- Manager (3-column) ---------- */
.mgr{display:flex;flex-direction:column;gap:10px;padding:10px;overflow:auto;flex:1}
.mgr-col{flex:1;min-width:0;border:1px solid var(--border);border-radius:8px;padding:8px;display:flex;flex-direction:column;gap:6px;background:var(--panel-2,#0f172a)}
@media(min-width:900px){.mgr{flex-direction:row;align-items:stretch}.mgr-col{max-height:none}}
.rcp-list{display:flex;flex-direction:column;gap:6px;overflow:auto}
.empty-note{color:var(--muted);font-size:12px;padding:8px 4px}

/* ---- X-Ref warnings (unused / duplicate definitions) ---- */
.xref-warn{margin:8px 0 10px;padding:8px 10px;border:1px solid #f0b429;border-left:4px solid #f0b429;border-radius:8px;background:#fff8e6}
[data-theme="dark"] .xref-warn{background:#3a2f12;border-color:#7a5c12}
.xref-warn-head{font-weight:600;color:#92670a;margin-bottom:4px}
[data-theme="dark"] .xref-warn-head{color:#f3c969}
.xref-warn-item{display:flex;align-items:center;gap:6px;font-size:12px;padding:2px 0;color:var(--text-2)}
.xref-warn-item .mono{font-family:var(--mono,ui-monospace,monospace);color:var(--text)}
.xw-dot{width:8px;height:8px;border-radius:50%;background:#f0b429;flex:none}
.xw-unused .xw-dot{background:#ef4444}
.xw-dupLabel .xw-dot,.xw-dupStep .xw-dot,.xw-dupNode .xw-dot{background:#a855f7}
.xw-undefLabel .xw-dot{background:#f97316}
.xref-item.xref-unused{opacity:.6}
.xref-item.xref-unused .xref-head .mono{color:#ef4444;text-decoration:line-through}

/* ---- advanced data types (UDT / arrays / structs) ---- */
.udt-kind{display:inline-block;font-size:10px;letter-spacing:.04em;padding:1px 5px;border-radius:5px;
  background:var(--accent-soft,#e0e7ff);color:var(--accent,#4f46e5);vertical-align:1px}
[data-theme="dark"] .udt-kind{background:#1e293b;color:#93c5fd}
.tagtable tr.derived{opacity:.85}
.tagtable tr.derived td{background:var(--surface,#f8fafc)}
[data-theme="dark"] .tagtable tr.derived td{background:rgba(255,255,255,.03)}
.tagtable td.sub{padding-left:16px;font-size:11px;color:var(--text-2,#64748b)}
.tagtable td.sub::before{content:"└ ";opacity:.5}
.dimin{width:64px}
.montr.derived td{font-size:11px}

/* ---- task configuration ---- */
.task{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:8px;background:var(--surface);margin-bottom:6px}
.task.off{opacity:.5}
.task-name{font-size:13px;font-weight:500;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.task-badge{font-size:10px;padding:1px 5px;border-radius:5px;background:var(--accent-soft,#e0e7ff);color:var(--accent,#4f46e5)}
[data-theme="dark"] .task-badge{background:#1e293b;color:#93c5fd}
.task-badge.evt{background:#fef3c7;color:#92670a}
[data-theme="dark"] .task-badge.evt{background:#3a2f12;color:#f3c969}
.task-stat{font-size:11px;color:var(--text-2,#64748b);font-family:var(--mono,ui-monospace,monospace)}
.task-stat.over{color:#ef4444;font-weight:600}
.fb-sig{font-size:11px;color:var(--text-2,#64748b);font-family:var(--mono,ui-monospace,monospace)}
.fb-kind{display:inline-block;width:16px;text-align:center;color:var(--accent,#2563eb);font-weight:700}
/* ---- function-block library ---- */
.fbrow{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:8px;background:var(--surface);margin-bottom:6px;border:1px solid transparent}
.fbrow.bad{border-color:var(--danger,#dc2626)}
.fb-name{font-family:var(--mono,ui-monospace,monospace);font-size:13px;font-weight:600}
.fb-inst{margin-left:auto;font-size:11px;color:var(--accent,#4f46e5);font-family:var(--mono,ui-monospace,monospace)}
.fb-cols{display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;margin:8px 0}
.fb-lab{display:block;font-size:11px;color:var(--muted);margin-bottom:2px;font-weight:600}
.fb-body{min-height:160px}
.fb-diag{grid-column:1/-1;font-size:11px;padding:4px 8px;border-radius:6px;margin-top:6px;font-family:var(--mono,ui-monospace,monospace)}
.fb-diag.ok{background:rgba(34,197,94,.14);color:#22c55e}
.fb-diag.bad{background:rgba(220,38,38,.14);color:#ef4444}
.fb-pin-h{font-size:11px;font-weight:700;color:var(--muted);margin:8px 0 2px}
[data-theme="dark"] .fb-diag.ok{color:#4ade80}
[data-theme="dark"] .fb-diag.bad{color:#f87171}

/* ============================================================
   HMI — Visualization editor
   ============================================================ */
.hmi-toolbar{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--line,#2a3142);background:var(--surface,#141a26);flex-wrap:wrap}
.hmi-toolbar .sep{width:1px;height:22px;background:var(--line,#2a3142)}
.hmi-palette{display:flex;align-items:center;gap:6px;padding:8px 10px;border-bottom:1px solid var(--line,#2a3142);background:var(--surface2,#10151f);flex-wrap:wrap}
.hmi-pal-lbl{font-size:11px;color:var(--muted,#9aa6bd);font-weight:700;text-transform:uppercase;margin-right:4px}
.hmi-canvas-wrap{flex:1;overflow:auto;padding:16px;background:#0c1018;position:relative}
.hmi-canvas{position:relative;margin:0 auto;border:1px solid var(--line,#2a3142);box-shadow:0 6px 24px rgba(0,0,0,.35);transform-origin:top center}
.hmi-hint{font-size:11px;color:#e2b53c}
.hmi-props{position:absolute;right:12px;top:64px;width:236px;max-height:calc(100% - 90px);overflow:auto;background:var(--surface,#141a26);border:1px solid var(--line,#2a3142);border-radius:10px;padding:10px;box-shadow:0 6px 22px rgba(0,0,0,.4);z-index:5}
.hmi-props-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}
.hmi-props-hint{color:var(--muted,#9aa6bd);font-size:12px;padding:6px 2px}
.hmi-row{display:flex;align-items:center;gap:8px;margin-bottom:6px}
.hmi-row>label{width:54px;font-size:11px;color:var(--muted,#9aa6bd);flex:none}
.hmi-row>div{flex:1}
.hmi-row .input,.hmi-row .select{width:100%}
/* items */
.hmi-item{position:absolute;box-sizing:border-box;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;user-select:none;color:#e6ecf5;font-size:12px}
.hmi-item.editing{cursor:move;border:1px dashed rgba(120,140,180,.35)}
.hmi-item.selected{outline:2px solid var(--accent,#4f46e5);outline-offset:1px;z-index:3}
.hmi-resize{position:absolute;right:-4px;bottom:-4px;width:12px;height:12px;background:var(--accent,#4f46e5);border:1px solid #fff2;border-radius:3px;cursor:nwse-resize}
.hmi-cap{font-size:11px;color:#aab4c6;text-align:center;line-height:1.1;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hmi-w-btn{display:flex;align-items:center;justify-content:center;width:100%;height:100%;border-radius:7px;color:#fff;font-weight:600;background:#2f7d32;box-shadow:inset 0 -2px 0 rgba(0,0,0,.25);cursor:pointer;padding:2px 6px;text-align:center}
.hmi-item.run .hmi-w-btn:active,.hmi-w-btn.pressed{filter:brightness(1.35);transform:translateY(1px)}
.hmi-lamp{width:60%;height:0;padding-bottom:60%;border-radius:50%;background:#3a3f4b;box-shadow:inset 0 0 6px rgba(0,0,0,.5)}
.hmi-lamp.rect{border-radius:8px}
.hmi-sw{position:relative;width:54px;height:24px;border-radius:14px;background:#3a3f4b;transition:background .15s;cursor:pointer}
.hmi-sw .hmi-sw-knob{position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:50%;background:#dfe6f0;transition:left .15s}
.hmi-item.run .hmi-sw.on{background:#2f7d32}
.hmi-item.run .hmi-sw.on .hmi-sw-knob{left:32px}
.hmi-range{width:100%}
.hmi-val{font-size:11px;color:#cdd6e4;font-family:var(--mono,ui-monospace,monospace)}
.gauge-svg{width:100%;height:calc(100% - 16px)}
.hmi-txt{font-family:var(--mono,ui-monospace,monospace);font-size:14px;color:#cdd6e4;background:#0e1320;border:1px solid var(--line,#2a3142);border-radius:6px;padding:3px 8px;width:100%;text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hmi-trend-cv{width:100%;height:calc(100% - 16px);border:1px solid var(--line,#2a3142);border-radius:6px;display:block}
.hmi-canvas-wrap.run .hmi-item.editing{border-color:transparent;cursor:default}

/* HMI host layout anchor */
#edHMI{position:relative}
#hmiHost{display:flex;flex-direction:column;height:100%;min-height:0}
#hmiHost .hmi-canvas-wrap{flex:1;min-height:0}

/* ============================================================
   Modbus TCP slave configuration
   ============================================================ */
.modbus-panel{padding:10px}
.mod-head{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.mod-status{font-size:11px;padding:2px 8px;border-radius:10px;background:#2a3142;color:#9aa6bd}
.mod-status:not(.off){color:#37c837}
.mod-row{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap}
.mod-row .input{width:80px}
.mod-note{font-size:11px;color:#9aa6bd;background:#10151f;border:1px solid var(--line,#2a3142);border-radius:8px;padding:8px;margin-bottom:8px;line-height:1.4}
.mod-actions{display:flex;gap:8px;margin-bottom:10px}
.mod-areas{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.mod-area{border:1px solid var(--line,#2a3142);border-radius:8px;padding:8px;background:var(--surface,#141a26)}
.mod-area-h{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px;font-size:12px}
.mod-tbl{width:100%;border-collapse:collapse;font-size:11px}
.mod-tbl th{text-align:left;color:var(--muted,#9aa6bd);font-weight:600;padding:2px 4px;border-bottom:1px solid var(--line,#2a3142)}
.mod-tbl td{padding:2px 4px;vertical-align:middle}
.mod-addr{width:56px}
.mod-tbl .select{width:100%}

/* ============================================================
   External Links (MQTT / Modbus RTU / Bluetooth)
   ============================================================ */
.links-panel{padding:10px;overflow:auto}
.link-list{display:flex;flex-direction:column;gap:12px;margin-top:10px}
.link-card{border:1px solid var(--line,#2a3142);border-radius:10px;padding:10px;background:var(--surface,#141a26)}
.link-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.link-head .link-name-in{width:120px;font-weight:600}
.link-type{font-size:11px;color:var(--muted,#9aa6bd);padding:2px 8px;border-radius:10px;background:#20262f}
.link-head .pill{margin-left:auto}
.link-cfg{display:grid;grid-template-columns:1fr 1fr;gap:6px 10px;margin-top:8px}
.link-field{display:flex;flex-direction:column;font-size:11px;color:var(--muted,#9aa6bd)}
.link-field.link-wide{grid-column:1 / -1}
.link-field .lbl{margin-bottom:2px}
.link-in,.map-in{width:100%;box-sizing:border-box;background:var(--bg,#0d1119);color:var(--fg,#e8edf5);border:1px solid var(--line,#2a3142);border-radius:6px;padding:4px 6px;font-size:12px}
.maps-title{margin:10px 0 4px;font-size:12px;font-weight:600;color:var(--fg,#e8edf5)}
.maps-table{width:100%;border-collapse:collapse;font-size:11px}
.maps-table th{text-align:left;color:var(--muted,#9aa6bd);padding:2px 4px;border-bottom:1px solid var(--line,#2a3142);font-weight:600}
.maps-table td{padding:3px 4px;vertical-align:middle}
.maps-table .map-in{padding:3px 4px}
.btn.xsm{font-size:11px;padding:2px 8px}
.btn.xsm.danger{color:#ff7b7b}
