:root {
  --bg: #f4f3ef;
  --panel: #ffffff;
  --panel-2: #ebe9e3;
  --line: #d9d6cd;
  --text: #22231f;
  --muted: #74766d;
  --accent: #b5560f;
  --accent-soft: #f6e3d2;
  --sel: #e3ecf7;
  --hit: #fff1a8;
  --dirty: #d4881c;
  --err: #c62f2f;
  --in: #1e7a3c;
  --out: #b5560f;
  --flag: #2b5fa8;
  --cnt: #7a3fa0;
  --jump: #a0287a;
  --note: #66705c;
  --mono: "JetBrains Mono", "Cascadia Mono", "Consolas", "DejaVu Sans Mono", monospace;
  --row-h: 22px;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #16181b;
    --panel: #1d2024;
    --panel-2: #24282d;
    --line: #33383e;
    --text: #dfe2e6;
    --muted: #8c939c;
    --accent: #f0a050;
    --accent-soft: #3a2a1a;
    --sel: #233247;
    --hit: #4a4220;
    --dirty: #f0a050;
    --err: #ff6b6b;
    --in: #6fcf8a;
    --out: #f0a050;
    --flag: #7fb0ff;
    --cnt: #c99bf0;
    --jump: #f08ad0;
    --note: #93a387;
  }
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  background: var(--bg);
  color: var(--text);
  font: 13px/1.4 system-ui, -apple-system, "Segoe UI", sans-serif;
  display: flex;
  flex-direction: column;
}
button, input, select { font: inherit; color: inherit; }

/* top bar */
.topbar, .toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.topbar { flex-wrap: nowrap; }
.toolbar { padding: 4px 12px; background: var(--panel-2); }
.listing-tools { flex: 1; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
.brand { font-weight: 700; letter-spacing: .04em; color: var(--accent); }
.spacer { flex: 1; }
.info { display: flex; gap: 6px; flex-wrap: nowrap; min-width: 0; overflow: hidden; }
.chip {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 1px 8px;
  font-size: 12px;
  white-space: nowrap;
  color: var(--muted);
}
.chip b { color: var(--text); font-weight: 600; }
.chip.dirty { border-color: var(--dirty); color: var(--dirty); }
.hint { color: var(--muted); font-size: 12px; }
select, input[type=search], input[type=text] {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 4px 6px;
}
.btn {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 4px 10px;
  cursor: pointer;
  white-space: nowrap;
}
.btn:hover:not(:disabled) { border-color: var(--accent); }
.btn:disabled { opacity: .45; cursor: default; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.small { padding: 2px 8px; font-size: 12px; }
.search { display: flex; align-items: center; gap: 6px; }
#search { width: 180px; }
#search-count { color: var(--muted); font-size: 12px; min-width: 48px; }

/* layout */
.layout { flex: 1; display: flex; min-height: 0; }
.sidebar {
  width: 300px;
  flex: none;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border-right: 1px solid var(--line);
  min-height: 0;
}
.tabs { display: flex; border-bottom: 1px solid var(--line); }
.tabs button {
  flex: 1;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 7px 4px;
  cursor: pointer;
  color: var(--muted);
}
.tabs button.active { color: var(--text); border-bottom-color: var(--accent); }
#side-filter { margin: 8px; }
.side-body { flex: 1; overflow: auto; padding: 0 0 12px; }
.side-item {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 8px;
  padding: 3px 10px;
  cursor: pointer;
  align-items: baseline;
}
.side-item:hover { background: var(--sel); }
.side-item .k { font-family: var(--mono); font-size: 12px; }
.side-item .d { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.side-item .n { color: var(--muted); font-size: 11px; }
.side-item.sub .k { font-weight: 700; color: var(--accent); }
.side-item.sub .d { color: var(--text); }
.side-title { padding: 6px 10px; color: var(--muted); font-size: 12px; }
.side-title b { color: var(--text); font-family: var(--mono); }
.op-item { display: grid; grid-template-columns: 52px 1fr 40px 44px; gap: 8px; padding: 3px 10px; align-items: center; }
.op-item .ex { font-family: var(--mono); font-size: 11px; color: var(--accent); cursor: pointer; text-align: right; text-decoration: underline dotted; }
.chip.ok { border-color: color-mix(in srgb, var(--in) 50%, var(--line)); color: var(--in); }
.op-item input { width: 100%; padding: 1px 4px; font-family: var(--mono); font-size: 12px; }
.op-item input.guess { border-style: dashed; }
.op-item .k { font-family: var(--mono); font-size: 12px; color: var(--muted); }
.op-item .n { text-align: right; color: var(--muted); font-size: 11px; }
.side-note { padding: 8px 10px; color: var(--muted); font-size: 12px; }

/* listing */
.listing-wrap { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.listing { flex: 1; overflow: auto; outline: none; font-family: var(--mono); font-size: 12.5px; }
.row {
  display: grid;
  grid-template-columns: 52px 52px 64px 96px 150px minmax(320px, 1fr);
  gap: 0 10px;
  padding: 0 12px 0 8px;
  min-height: var(--row-h);
  align-items: center;
  border-left: 3px solid transparent;
  white-space: pre;
}
.listing-head {
  font-family: system-ui, sans-serif;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--muted);
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
}
.row > span { overflow: hidden; text-overflow: ellipsis; }
.listing .row:hover { background: color-mix(in srgb, var(--sel) 50%, transparent); }
.listing .row.sel { background: var(--sel); }
.listing .row.hit { background: var(--hit); }
.listing .row.sel.hit { background: color-mix(in srgb, var(--sel) 50%, var(--hit)); }
.listing .row.dirty { border-left-color: var(--dirty); }
.listing .row.section { border-top: 1px solid var(--line); margin-top: 6px; padding-top: 2px; }
.c-ln { color: var(--muted); text-align: right; }
.c-lab { color: var(--accent); font-weight: 700; }
.c-op { font-weight: 600; }
.c-op.guess { font-weight: 400; color: var(--muted); font-style: italic; }
.c-op.k-jump { color: var(--jump); }
.c-op.k-set { color: var(--out); }
.c-arg.E { color: var(--in); }
.c-arg.A { color: var(--out); }
.c-arg.M { color: var(--flag); }
.c-arg.C { color: var(--cnt); }
.c-arg.link { color: var(--jump); text-decoration: underline dotted; cursor: pointer; }
.c-arg.ref { cursor: pointer; }
.c-arg.ref:hover { text-decoration: underline; }
.c-sym { color: var(--muted); font-family: system-ui, sans-serif; font-size: 12px; }
.c-cmt { color: var(--text); }
.c-note { grid-column: 2 / -1; color: var(--note); }
.c-note.indent { grid-column: 6 / -1; }
.empty { padding: 40px; color: var(--muted); font-family: system-ui, sans-serif; }

/* inline editors */
.row input.inline {
  width: 100%;
  font-family: var(--mono);
  font-size: 12.5px;
  padding: 0 3px;
  height: 20px;
  border: 1px solid var(--accent);
  border-radius: 2px;
  background: var(--panel);
}
input.invalid { border-color: var(--err) !important; outline-color: var(--err); }

.popover {
  position: fixed;
  z-index: 10;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .25);
  padding: 10px;
  min-width: 380px;
}
.popover .form { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.popover select, .popover input { font-family: var(--mono); }
.popover .operand { width: 140px; }
.popover .meta { margin-top: 8px; font-size: 12px; color: var(--muted); font-family: var(--mono); }
.popover .meta .warn { color: var(--dirty); font-family: system-ui, sans-serif; }
.popover .error { color: var(--err); font-size: 12px; margin-top: 6px; min-height: 1em; }

.toast {
  position: fixed;
  bottom: 16px;
  right: 16px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 4px solid var(--accent);
  padding: 10px 14px;
  border-radius: 4px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .2);
  max-width: 480px;
  z-index: 20;
}
.toast.error { border-left-color: var(--err); }

@media (max-width: 900px) {
  .sidebar { display: none; }
  .row { grid-template-columns: 44px 44px 56px 80px 0 minmax(240px, 1fr); }
}

[hidden] { display: none !important; }

/* view switch */
.views { display: flex; border: 1px solid var(--line); border-radius: 5px; overflow: hidden; }
.views button {
  background: var(--panel);
  border: none;
  padding: 4px 12px;
  cursor: pointer;
  color: var(--muted);
}
.views button + button { border-left: 1px solid var(--line); }
.views button.active { background: var(--accent); color: #fff; }

/* live values in the editor listing */
.listing .row.cold { opacity: .45; }
.c-arg.live::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  margin-right: 5px;
  background: var(--led-off);
  vertical-align: 1px;
}
.c-arg.live.on::before { background: var(--led-in); box-shadow: 0 0 5px var(--led-in); }
.c-arg.live.A.on::before { background: var(--led-out); box-shadow: 0 0 5px var(--led-out); }
.c-arg.live.C::before { display: none; }
.c-arg.live.C::after { content: " =" attr(data-v); color: var(--muted); }

/* simulator */
:root {
  --led-off: #4a4d52;
  --led-in: #3ddc68;
  --led-out: #ff9b2f;
  --module: #2b2e33;
  --module-2: #23262a;
  --module-text: #d6d9dd;
  --module-muted: #8a9099;
}
.sim { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.sim-bar label { display: flex; align-items: center; gap: 4px; }
#sim-cycle { width: 56px; background: var(--panel); border: 1px solid var(--line); border-radius: 4px; padding: 2px 4px; }
.sim-status { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.sim-status .err { color: var(--err); }
.run-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--led-in); margin-right: 5px; animation: blink 1s infinite;
}
@keyframes blink { 50% { opacity: .3; } }
.sim-body { flex: 1; display: flex; min-height: 0; }
.rack-wrap { flex: 1; overflow: auto; padding: 8px 16px 24px; min-width: 0; }
.rack-title { margin: 12px 0 8px; font-weight: 600; display: flex; gap: 12px; align-items: baseline; }
.rack { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-start; }

.card {
  width: 236px;
  background: var(--module);
  color: var(--module-text);
  border-radius: 4px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .25), inset 0 0 0 1px rgba(255, 255, 255, .05);
  font-family: var(--mono);
  font-size: 11.5px;
  overflow: hidden;
  user-select: none;
}
.card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 6px 8px 5px;
  background: var(--module-2);
  border-top: 4px solid #e8730c;
}
.card.out .card-head { border-top-color: #d63c2f; }
.card.reg .card-head { border-top-color: #5c8fd6; }
.card-title { font-weight: 700; font-size: 13px; letter-spacing: .04em; }
.card-type { color: var(--module-muted); font-size: 10.5px; }
.card-ch {
  display: grid;
  grid-template-columns: 14px 12px 38px 1fr;
  gap: 6px;
  align-items: center;
  padding: 2px 8px;
  border-top: 1px solid rgba(255, 255, 255, .04);
}
.card-ch.in { cursor: pointer; }
.card-ch.in:hover { background: rgba(255, 255, 255, .06); }
.card-ch.unused { opacity: .35; }
.card-ch .ch { color: var(--module-muted); }
.card-ch .sym { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: system-ui, sans-serif; }
.led {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--led-off);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, .5);
  display: inline-block;
}
.on > .led, .card-ch.in.on .led { background: var(--led-in); box-shadow: 0 0 6px var(--led-in), inset 0 -1px 2px rgba(0, 0, 0, .3); }
.card-ch.out.on .led { background: var(--led-out); box-shadow: 0 0 6px var(--led-out), inset 0 -1px 2px rgba(0, 0, 0, .3); }
.reg-row { display: grid; grid-template-columns: 44px 1fr 64px; gap: 6px; align-items: center; padding: 2px 8px; }
.reg-row .sym { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: system-ui, sans-serif; }
.reg-row input { width: 100%; background: var(--module-2); color: var(--module-text); border: 1px solid #444; border-radius: 3px; padding: 1px 4px; font: inherit; }

.sim-side {
  width: 360px;
  flex: none;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border-left: 1px solid var(--line);
  min-height: 0;
}
#sim-filter { margin: 8px; }
.sim-row, .step {
  display: grid;
  grid-template-columns: 14px 48px 1fr auto;
  gap: 8px;
  align-items: center;
  padding: 3px 10px;
  cursor: pointer;
}
.step { grid-template-columns: 14px 40px 1fr; }
.sim-row:hover, .step:hover { background: var(--sel); }
.sim-row .k, .step .k { font-family: var(--mono); font-size: 12px; }
.sim-row .d, .step .d { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sim-row .v { font-family: var(--mono); font-size: 12px; font-variant-numeric: tabular-nums; }
.sim-row.byte .led { visibility: hidden; }
.step.on { background: color-mix(in srgb, var(--led-in) 14%, transparent); }
.step.on .d { color: var(--text); }
.chain { margin-bottom: 10px; }
.chain-head { padding: 6px 10px; font-weight: 600; border-bottom: 1px solid var(--line); }
.chain-head b { font-family: var(--mono); color: var(--accent); }
.timer { display: grid; grid-template-columns: 36px 1fr 110px; gap: 8px; align-items: center; padding: 4px 10px; cursor: pointer; font-family: var(--mono); font-size: 12px; }
.timer .bar { height: 6px; background: var(--panel-2); border-radius: 3px; overflow: hidden; }
.timer .bar span { display: block; height: 100%; background: var(--accent); }
.timer.done .bar span { background: var(--led-in); }
.timer .v { text-align: right; color: var(--muted); }
.sim-error { margin: 8px 10px; padding: 8px; border-left: 3px solid var(--err); background: color-mix(in srgb, var(--err) 10%, transparent); cursor: pointer; }

@media (max-width: 900px) {
  .sim-body { flex-direction: column; }
  .sim-side { width: auto; border-left: none; border-top: 1px solid var(--line); max-height: 45vh; }
}
.topbar > * { flex-shrink: 0; }
.topbar > .info, .topbar > .spacer { flex-shrink: 1; }

/* LCD (LM032L, yellow-green STN) */
.lcd {
  display: inline-block;
  padding: 14px 18px;
  background: #1b1c1e;
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .35), inset 0 0 0 1px #333;
}
.lcd-glass {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px;
  background: linear-gradient(180deg, #b6d24a, #9dbb35);
  border-radius: 3px;
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, .35);
}
.lcd-glass.off .lcd-cell { color: transparent; }
.lcd-glass.off .lcd-cell svg { visibility: hidden; }
.lcd-row { display: flex; gap: 2px; }
.lcd-cell {
  width: 21px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  font: 700 23px/1 var(--mono);
  color: #1d2a10;
  background: rgba(40, 60, 10, .09);
  position: relative;
  white-space: pre;
}
.lcd-cell .glyph { width: 15px; height: 24px; fill: #1d2a10; }
.lcd-cell.cursor::after {
  content: "";
  position: absolute;
  left: 2px; right: 2px; bottom: 2px;
  height: 3px;
  background: #1d2a10;
}
.lcd-cell.blink { animation: lcd-blink 1s steps(1) infinite; }
@keyframes lcd-blink { 50% { background: #1d2a10; color: #b0cc45; } }
.lcd-info { margin-top: 6px; }
@media (max-width: 900px) {
  .lcd-cell { width: 13px; height: 22px; font-size: 15px; }
}

/* compare view */
:root {
  --d-removed: color-mix(in srgb, #e5484d 16%, transparent);
  --d-added: color-mix(in srgb, #30a46c 16%, transparent);
  --d-changed: color-mix(in srgb, #f5a623 16%, transparent);
  --d-comment: color-mix(in srgb, #3e7bd6 12%, transparent);
  --d-mark: color-mix(in srgb, #f5a623 45%, transparent);
}
.cmp { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.cmp-bar select { max-width: 320px; }
.cmp-bar label { display: flex; align-items: center; gap: 4px; }
.cmp-body { flex: 1; display: flex; min-height: 0; }
.cmp-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.cmp-rows { flex: 1; overflow: auto; outline: none; font-family: var(--mono); font-size: 12px; }
.cmp-row {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr) 46px minmax(0, 1fr);
  min-height: 20px;
  align-items: center;
  white-space: pre;
}
.cmp-head {
  font: 600 12px system-ui, sans-serif;
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
  padding: 4px 0;
}
.cmp-head .code { overflow: hidden; text-overflow: ellipsis; }
.cmp-row .ln { color: var(--muted); text-align: right; padding-right: 8px; border-right: 1px solid var(--line); }
.cmp-row .code {
  display: grid;
  grid-template-columns: 44px 64px 88px minmax(0, 1fr);
  gap: 6px;
  padding: 0 10px 0 8px;
  overflow: hidden;
}
.cmp-row .code > span { overflow: hidden; text-overflow: ellipsis; }
.cmp-row .code.note { display: block; color: var(--note); overflow: hidden; text-overflow: ellipsis; }
.cmp-row .code + .ln { border-left: 1px solid var(--line); }
.cmp-row .lab { color: var(--accent); font-weight: 700; }
.cmp-row .op { font-weight: 600; }
.cmp-row .cmt { color: var(--muted); }
.cmp-row.k-removed { background: linear-gradient(90deg, var(--d-removed) 50%, transparent 50%); }
.cmp-row.k-added { background: linear-gradient(90deg, transparent 50%, var(--d-added) 50%); }
.cmp-row.k-changed { background: var(--d-changed); }
.cmp-row.k-comment { background: var(--d-comment); }
.cmp-row .chg { background: var(--d-mark); border-radius: 2px; }
.cmp-row .empty-side { background: repeating-linear-gradient(135deg, transparent 0 6px, color-mix(in srgb, var(--line) 50%, transparent) 6px 7px); align-self: stretch; }
.cmp-row.focus { outline: 2px solid var(--accent); outline-offset: -2px; }
.cmp-gap {
  padding: 3px 12px;
  color: var(--muted);
  background: var(--panel-2);
  font: 12px system-ui, sans-serif;
  cursor: pointer;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.cmp-gap:hover { color: var(--text); }
.k-removed { color: #d13438; }
.k-added { color: #1f8a4c; }
.k-changed { color: #b7791f; }
.k-comment { color: #3e7bd6; }
.cmp-side { width: 400px; }
.cmp-item {
  display: grid;
  grid-template-columns: 70px 1fr 1fr;
  gap: 8px;
  padding: 3px 10px;
  font-size: 12px;
  align-items: baseline;
}
.cmp-item .k { font-family: var(--mono); color: inherit; }
.cmp-item .va, .cmp-item .vb { color: var(--text); overflow-wrap: anywhere; }
.cmp-item.k-removed .va, .cmp-item.k-changed .va { text-decoration: line-through; color: var(--muted); }
.cmp-item-head { color: var(--muted); font-weight: 600; border-bottom: 1px solid var(--line); }
.side-item.dim { opacity: .5; }
.cmp-table { padding: 8px 10px; border-bottom: 1px solid var(--line); }
.tchg { display: grid; grid-template-columns: 48px 1fr; gap: 2px 8px; margin-top: 4px; font-size: 11.5px; }
.tchg .vb { grid-column: 2; }
.tchg code { white-space: pre; overflow: hidden; text-overflow: ellipsis; padding: 1px 4px; border-radius: 2px; }
.tchg .va { background: var(--d-removed); }
.tchg .vb { background: var(--d-added); }
@media (prefers-color-scheme: dark) {
  .k-removed { color: #ff7b7f; }
  .k-added { color: #5fd38f; }
  .k-changed { color: #f5b74a; }
  .k-comment { color: #7fb0ff; }
}

/* tables view */
.tbl { flex: 1; display: flex; min-height: 0; }
.tbl .sidebar .side-item.active { background: var(--sel); }
.tbl-body { flex: 1; overflow: auto; min-width: 0; }
.tbl-head { padding: 8px 14px; border-bottom: 1px solid var(--line); background: var(--panel-2); position: sticky; top: 0; z-index: 1; }
.tbl-rows { font-family: var(--mono); font-size: 12px; }
.tbl-row {
  display: grid;
  grid-template-columns: 40px 32px minmax(420px, 1fr) 210px;
  gap: 10px;
  align-items: center;
  padding: 2px 14px;
  min-height: 24px;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 40%, transparent);
  white-space: pre;
}
.tbl-row:hover { background: color-mix(in srgb, var(--sel) 50%, transparent); }
.tbl-row .no, .tbl-row .len { color: var(--muted); text-align: right; }
.tbl-row .src { overflow: hidden; text-overflow: ellipsis; }
.tbl-row.comment .src { color: var(--note); font-style: italic; }
.tbl-row .pv { font-size: 11px; color: var(--muted); overflow: hidden; }
.tbl-row.zuo { grid-template-columns: 60px 1fr; }
.mini-lcd {
  display: inline-flex;
  flex-direction: column;
  padding: 2px 5px;
  background: linear-gradient(180deg, #b6d24a, #9dbb35);
  color: #1d2a10;
  border-radius: 2px;
  font: 600 10.5px/1.25 var(--mono);
  white-space: pre;
}

/* plant: station tabs, field devices, device dialog */
.station-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin: 4px 0 6px; }
.station-tabs:empty { display: none; }
.station-tabs button {
  display: flex; flex-direction: column; align-items: flex-start;
  padding: 5px 12px; border: 1px solid var(--line); border-radius: 5px;
  background: var(--panel); cursor: pointer; color: var(--text);
}
.station-tabs button span { font-size: 11px; color: var(--muted); }
.station-tabs button.active { border-color: var(--accent); box-shadow: inset 0 -3px 0 var(--accent); }
.station-tabs button.err { border-color: var(--err); }
.rack-title .add-dev { margin-left: auto; font-size: 12px; }
.rack-title { flex-wrap: wrap; }
.devices { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-start; }
.dev {
  width: 260px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 8px 10px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .08);
}
.dev.faulty { border-color: color-mix(in srgb, var(--err) 60%, var(--line)); }
.dev-head { display: flex; align-items: baseline; gap: 6px; margin-bottom: 4px; }
.dev-head b { font-size: 13px; }
.dev-head .hint { flex: 1; font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dev-edit { background: none; border: none; cursor: pointer; color: var(--muted); font-size: 15px; padding: 0 2px; }
.dev-edit:hover { color: var(--accent); }
.dev-io, .dev-row { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: center; font: 11.5px var(--mono); }
.dev .io { display: inline-flex; align-items: center; gap: 4px; color: var(--muted); }
.dev .io .led { width: 8px; height: 8px; }
.dev .io.in.on .led { background: var(--led-in); box-shadow: 0 0 5px var(--led-in); }
.dev .io.out.on .led { background: var(--led-out); box-shadow: 0 0 5px var(--led-out); }
.dev .io.on { color: var(--text); }
.dev-fault { margin-top: 4px; font-size: 11.5px; color: var(--err); }
.dev .arrow { color: var(--muted); }
.cyl-svg { width: 100%; height: 50px; display: block; }
.cyl-body { fill: color-mix(in srgb, var(--muted) 18%, transparent); stroke: var(--muted); stroke-width: 1.2; }
.cyl-piston { fill: var(--muted); }
.cyl-rod { fill: color-mix(in srgb, var(--muted) 70%, var(--text)); }
.dev.cyl.moving .cyl-piston { fill: var(--accent); }
.cyl-sensor { fill: var(--led-off); }
.cyl-sensor.on { fill: var(--led-in); filter: drop-shadow(0 0 3px var(--led-in)); }
.cyl-pos { font: 10px var(--mono); fill: var(--muted); }
.push {
  width: 34px; height: 34px; border-radius: 50%;
  border: 3px solid #555; background: radial-gradient(circle at 40% 35%, #4a8bdc, #1e4f9c);
  cursor: pointer; box-shadow: 0 2px 0 #222; flex: none;
}
.push.pressed { transform: translateY(2px); box-shadow: none; filter: brightness(1.25); }
.push.latching { border-radius: 6px; background: #3a3d42; position: relative; }
.push.latching .lever { position: absolute; left: 13px; top: 3px; width: 5px; height: 15px; background: #ddd; border-radius: 2px; transform-origin: 50% 100%; transform: rotate(-30deg); transition: transform .1s; }
.push.latching.pressed .lever { transform: rotate(30deg); }
.card-ch.wired .plug { color: var(--accent); margin-right: 3px; }
.plant-tab .plant-row { display: flex; gap: 6px; align-items: center; padding: 3px 10px; }
.plant-tab .plant-row .hint { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plant-tab .st-name { width: 210px; }
.dev-dialog {
  border: 1px solid var(--line); border-radius: 8px; padding: 0;
  background: var(--panel); color: var(--text); min-width: 520px; max-width: 92vw;
  box-shadow: 0 12px 40px rgba(0, 0, 0, .35);
}
.dev-dialog::backdrop { background: rgba(0, 0, 0, .35); }
.dev-dialog form { padding: 14px 18px; display: flex; flex-direction: column; gap: 6px; }
.dev-dialog h3 { margin: 0 0 6px; }
.dev-dialog .f-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.dev-dialog .f-row > span:first-child { width: 190px; color: var(--muted); font-size: 12px; }
.dev-dialog input, .dev-dialog select { background: var(--panel); border: 1px solid var(--line); border-radius: 4px; padding: 3px 6px; }
.dev-dialog input[type=number] { width: 80px; }
.dev-dialog fieldset { border: 1px solid var(--line); border-radius: 6px; padding: 6px 10px; display: flex; flex-direction: column; gap: 6px; }
.dev-dialog legend { color: var(--muted); font-size: 12px; }
.dev-dialog .f-error { color: var(--err); font-size: 12px; min-height: 1em; }
.dev-dialog .f-buttons { display: flex; gap: 8px; align-items: center; }
.btn.danger { border-color: var(--err); color: var(--err); }

/* import by drag & drop */
body.dropping::after {
  content: "Drop .PRG programs or .plant.json plants to import them";
  position: fixed; inset: 12px; z-index: 50;
  display: flex; align-items: center; justify-content: center;
  border: 3px dashed var(--accent); border-radius: 12px;
  background: color-mix(in srgb, var(--bg) 85%, transparent);
  font-size: 20px; color: var(--accent); pointer-events: none;
}

/* quick fault buttons and servo widget */
.dev-actions { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-top: 6px; }
.chip-btn {
  border: 1px solid var(--line); background: var(--panel-2); border-radius: 10px;
  padding: 1px 9px; font-size: 11.5px; cursor: pointer; color: var(--text);
}
.chip-btn:hover { border-color: var(--err); }
.chip-btn.on { background: var(--err); border-color: var(--err); color: #fff; }
.dev-actions .dev-fault { margin: 0; }
.fault-click { cursor: pointer; }
.dev .io.stuck-off, .dev .io.stuck-on { text-decoration: line-through wavy var(--err); color: var(--err); }
.dev .io.stuck-on .led { background: var(--err); }
.dev.servo { width: 300px; }
.servo-body { display: flex; gap: 10px; align-items: center; }
.servo-wheel { width: 64px; height: 64px; flex: none; }
.servo-wheel .wheel { fill: color-mix(in srgb, var(--muted) 15%, transparent); stroke: var(--muted); stroke-width: 2; stroke-dasharray: 3 2; }
.servo-wheel .spokes line { stroke: var(--muted); stroke-width: 3; }
.servo-wheel .hub { fill: var(--muted); }
.dev.servo.moving .wheel { stroke: var(--accent); }
.servo-values { flex: 1; display: grid; gap: 1px; font-size: 11.5px; }
.servo-values div { display: flex; justify-content: space-between; gap: 8px; }
.servo-values span { color: var(--muted); }
.servo-values b { font-family: var(--mono); font-weight: 600; }
.servo-bar { position: relative; height: 6px; margin: 6px 0 4px; background: var(--panel-2); border-radius: 3px; }
.servo-bar::after { content: ""; position: absolute; left: 50%; top: -2px; bottom: -2px; width: 1px; background: var(--muted); }
.servo-bar span { position: absolute; top: 0; bottom: 0; background: var(--accent); border-radius: 3px; }
.dev .io.idx.on .led { background: var(--led-in); box-shadow: 0 0 5px var(--led-in); }
.dev-dialog .io-select { min-width: 240px; max-width: 320px; }
.dev-dialog .also .hint { font-size: 11px; }
.dev-group-title { margin: 10px 0 6px; font-size: 12px; color: var(--muted); font-weight: 600; }
details.wires { margin-top: 10px; }
details.wires > summary { cursor: pointer; font-size: 12px; color: var(--muted); font-weight: 600; margin-bottom: 6px; }
details.wires .dev { width: 230px; padding: 5px 8px; }
details.wires .dev-head b { font-size: 12px; }

/* form controls follow the theme (plain <input> had the browser's white background) */
input:not([type=checkbox]):not([type=radio]):not([type=file]), select, textarea {
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 3px 6px;
}
input::placeholder { color: var(--muted); }
option, optgroup { background: var(--panel); color: var(--text); }
.plant-tab { color: var(--text); }
.plant-tab .side-title, .plant-tab .side-title b { color: var(--text); }
.plant-tab .chain-head { color: var(--text); }
.plant-tab .plant-row .hint { color: var(--muted); }
.plant-tab .side-note { color: var(--muted); }
.dev.display-dev { width: auto; max-width: 560px; }
.dev.display-dev .lcd { margin: 4px 0 2px; }
.dev.display-dev .dev-io { gap: 2px 8px; }
a.as-device { color: var(--accent); }
.plant-tab .plant-row { flex-wrap: wrap; }
.plant-tab .move { display: inline-flex; gap: 2px; }
.plant-tab .move .btn { padding: 0 6px; line-height: 18px; }

/* plant overview: all stations at a glance */
.rack-wrap.overview > :not(#station-tabs):not(#plant-overview) { display: none !important; }
.station-tabs .ov-tab b { color: var(--accent); }
/* overview: the S7 panel beside the line view */
.ov-line { display: flex; flex-direction: column; gap: 10px; margin-top: 8px; }
.s7-panel { border: 1px solid #8f9294; border-radius: 4px; background: #b4b4b4; color: #111; overflow: hidden; }
.s7-bar { display: flex; gap: 10px; align-items: baseline; padding: 4px 10px; background: #9d9d9d; border-bottom: 2px solid #6d6f70; }
.s7-bar b { color: #0b1f8f; font-size: 15px; }
.s7-bar span { font-size: 11px; color: #333; }
.s7-body { display: flex; flex-wrap: wrap; gap: 14px 40px; padding: 12px; align-items: flex-start; }
.s7-tiles { display: flex; flex-wrap: wrap; gap: 14px; }
.s7-tile { display: flex; flex-direction: column; align-items: stretch; width: 104px; padding: 0; border: 1.5px solid #111; background: #d5d5d5; cursor: pointer; font: inherit; color: #111; }
.s7-label { display: flex; flex-direction: column; justify-content: center; box-sizing: border-box; width: 100%; min-height: 46px; padding: 4px 6px 2px; background: #fff; border-bottom: 1px solid #111; font-size: 12px; text-align: center; }
.s7-pos { display: flex; justify-content: space-between; font-size: 11px; margin-top: 3px; }
.s7-face { display: block; padding: 6px 10px; }
.s7-face svg { display: block; width: 100%; height: auto; }
.s7-face .ring { fill: #ff3b12; stroke: #222; stroke-width: 1.5; }
.s7-face .rim { fill: #fff; }
.s7-face .knob { fill: #5a5a5a; stroke: #222; stroke-width: 1.5; }
.s7-face .lever { transform-origin: 50px 50px; transform: rotate(-40deg); transition: transform .12s; }
.s7-face .lever rect { fill: #9c9c9c; stroke: #555; stroke-width: 1; }
.s7-face .lever circle { fill: #d8d8d8; }
.s7-tile.on .lever { transform: rotate(40deg); }
.s7-tile.on .s7-pos span:last-child, .s7-tile:not(.on):not(.s7-push) .s7-pos span:first-child { font-weight: 700; }
.s7-face .bezel { fill: #c9c9c9; stroke: #777; stroke-width: 3; }
.s7-face .cap { fill: #5a5a5a; stroke: #2a2a2a; stroke-width: 1.5; transform-origin: 50px 50px; transition: transform .05s; }
.s7-tile.s7-push.pressed .cap { transform: scale(.9); fill: #474747; }
.s7-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.s7-info { flex: 0 1 340px; display: flex; flex-direction: column; gap: 10px; font-size: 13px; }
.s7-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.s7-field { min-width: 86px; padding: 3px 8px; background: #a8a8a8; border: 1px solid #fff; color: #fff; font-weight: 700; text-align: center; font-family: var(--mono); }
.s7-field.small { min-width: 0; font-size: 11px; }
.s7-panel .btn { background: #e4e4e4; color: #111; border-color: #777; }
.s7-lamp { width: 22px; height: 22px; border-radius: 50%; border: 1.5px solid #222; background: #b4b4b4; }
.s7-lamp.on { background: #2fd14b; box-shadow: 0 0 6px #2fd14b; }
/* the line view: modules drawn small above the chain */
.line-view { min-width: 0; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); padding: 6px; overflow-x: auto; }
.lv-svg { display: block; width: 100%; min-width: 640px; height: auto; }
.lv-card { cursor: pointer; }
.lv-box { fill: var(--panel-2); stroke: var(--line); }
.lv-head { fill: color-mix(in srgb, var(--muted) 18%, var(--panel)); }
.lv-card:hover .lv-box { stroke: var(--accent); }
.lv-card.fault .lv-box { stroke: var(--err); stroke-width: 2; }
.lv-name { font-weight: 600; font-size: 12px; fill: var(--text); }
.lv-fault { font: 700 10px var(--mono); fill: var(--err); text-anchor: end; display: none; }
.lv-fault.on { display: inline; }
.lv-empty { font: 11px var(--mono); fill: var(--muted); text-anchor: middle; }
.lv-lead { fill: none; stroke: var(--muted); stroke-width: 1; stroke-dasharray: 3 3; }
.lv-track { fill: none; stroke: color-mix(in srgb, var(--muted) 45%, transparent); stroke-width: 10; stroke-dasharray: 3 3; }
.lv-sprocket { fill: var(--panel-2); stroke: var(--muted); stroke-width: 2; }
.lv-sprocket.drive { stroke: var(--accent); }
.lv-spokes { stroke: var(--accent); stroke-width: 2; }
.lv-mark { stroke: var(--text); stroke-width: 2; }
.lv-svg .wt .fixture { fill: var(--panel); stroke: var(--muted); stroke-width: 1.5; }
.lv-svg .wt .part { stroke-width: 1.5; }
.lv-svg .wt.empty .part { display: none; }
.lv-svg .wt.unknown .part { fill: #e0b83a; stroke: #a8861c; }
.lv-svg .wt.good .part { fill: var(--led-in); stroke: var(--in); }
.lv-svg .wt.bad .part { fill: var(--err); stroke: color-mix(in srgb, var(--err) 70%, black); }
.lv-sensor { cursor: pointer; }
.lv-sensor .cap { fill: #3b3b3b; }
.lv-sensor .led { fill: var(--led-off); }
.lv-sensor.on .led { fill: var(--led-in); filter: drop-shadow(0 0 3px var(--led-in)); }
.lv-sensor .body { fill: #b8bcbf; stroke: #6f7375; }
.lv-sensor .nut { fill: #8d9194; }
.lv-sensor .field { fill: none; stroke: var(--led-off); stroke-width: 1.5; }
.lv-sensor.on .field { stroke: var(--led-in); }
.lv-sensor-name { font: 600 10px var(--mono); fill: var(--text); text-anchor: end; }
.lv-drive { font: 11px var(--mono); fill: var(--muted); }
.lv-cam { fill: none; stroke: var(--accent); stroke-width: 4; stroke-linecap: round; }
.lv-ref-name { font: 600 10px var(--mono); fill: var(--text); }
.lv-boxsym { fill: color-mix(in srgb, #c9a227 30%, var(--panel)); stroke: #8a6d12; stroke-width: 1.5; }
.lv-box-count { font: 700 11px var(--mono); fill: var(--text); text-anchor: middle; }
.lv-removal-name { font: 600 11px var(--mono); fill: var(--text); }
.lv-out { font: 600 12px var(--mono); }
.lv-out .good { fill: var(--in); }
.lv-out .bad { fill: var(--err); }
.mini-scene .sc-name { display: none; }
.mini-scene .sc-cyl { cursor: inherit; }
.ov-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 10px; margin-top: 6px; }
.ov-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: 6px;
  padding: 8px 10px; cursor: pointer; display: flex; flex-direction: column; gap: 6px;
  border-top: 3px solid var(--line);
}
.ov-card:hover { border-color: var(--accent); }
.ov-card.fault { border-top-color: var(--err); }
.ov-head { display: flex; align-items: center; gap: 6px; }
.ov-head b { font-size: 13px; white-space: nowrap; }
.ov-head .hint { font-size: 11px; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ov-fault { font-size: 10.5px; padding: 0 6px; border-radius: 8px; color: var(--muted); border: 1px solid var(--line); }
.ov-fault.on { background: var(--err); border-color: var(--err); color: #fff; }
.ov-lcd { align-self: flex-start; font-size: 11.5px; }
.ov-lcd span { min-height: 1.25em; }
.ov-steps { font-size: 11.5px; display: grid; gap: 1px; }
.ov-steps > div { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ov-steps .k { display: inline-block; width: 22px; color: var(--muted); font-family: var(--mono); }
.ov-steps b { font-family: var(--mono); color: var(--in); font-weight: 600; }
.ov-cyls { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 2px 10px; }
.ov-cyl { display: flex; align-items: center; gap: 3px; font-size: 11px; min-width: 0; }
.ov-cyl .bar { width: 38px; height: 6px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 3px; overflow: hidden; flex: none; }
.ov-cyl .bar span { display: block; height: 100%; background: var(--muted); }
.ov-cyl.moving .bar span { background: var(--accent); }
.ov-cyl.faulty .nm { color: var(--err); }
.ov-cyl .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-left: 3px; }
.ov-cyl .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--led-off); flex: none; }
.ov-cyl .dot.on { background: var(--led-in); box-shadow: 0 0 4px var(--led-in); }
.ov-cyl .dot.none { visibility: hidden; }
.ov-servo { grid-column: 1 / -1; font: 11px var(--mono); color: var(--muted); }
.ov-servo.moving { color: var(--accent); }
.ov-sigs { display: flex; flex-wrap: wrap; gap: 2px 10px; font-size: 11px; color: var(--muted); }
.ov-sig { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.ov-sig .led { width: 7px; height: 7px; }
.ov-sig .led + .led { margin-left: -1px; }
.ov-sig.in .led.on { background: var(--led-in); box-shadow: 0 0 4px var(--led-in); }
.ov-sig.out .led.on { background: var(--led-out); box-shadow: 0 0 4px var(--led-out); }
.ov-io { display: grid; gap: 2px; }
.ov-io-row { display: flex; align-items: center; gap: 2px; }
.ov-io-row .k { width: 30px; font: 10.5px var(--mono); color: var(--muted); }
.ov-led { width: 9px; height: 9px; border-radius: 50%; background: var(--led-off); flex: none; }
.ov-led.unused { opacity: .3; }
.ov-led.in.on { background: var(--led-in); box-shadow: 0 0 4px var(--led-in); }
.ov-led.out.on { background: var(--led-out); box-shadow: 0 0 4px var(--led-out); }
.ov-io-row .ov-led:nth-child(9) { margin-left: 4px; }

/* power-on / air and operator buttons */
.air-bar { position: relative; display: inline-block; width: 110px; height: 8px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 4px; overflow: hidden; vertical-align: middle; }
.air-bar > span { position: absolute; left: 0; top: 0; bottom: 0; background: #5aa9e6; }
.air-pct { font: 600 11.5px var(--mono); }
.chip-btn.valve.open { background: #5aa9e6; border-color: #5aa9e6; color: #fff; }
.dev.air-dev .dev-row { gap: 8px; }
.air-phase { font-size: 11px; margin: 2px 0; }
.sim-status .phase { color: #5aa9e6; font-weight: 600; }
.ov-panel {
  display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center;
  padding: 8px 10px; margin-top: 6px; background: var(--panel); border: 1px solid var(--line); border-radius: 6px;
}
.ov-air { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; }
.ov-sep { width: 1px; align-self: stretch; background: var(--line); margin: 0 2px; }
.ov-btn {
  display: inline-flex; align-items: center; gap: 5px; padding: 2px 9px; font-size: 11.5px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); color: var(--text); cursor: pointer; user-select: none;
}
.ov-btn:hover { border-color: var(--accent); }
.ov-btn .lamp { width: 8px; height: 8px; border-radius: 50%; background: var(--led-off); flex: none; }
.ov-btn.pressed, .ov-btn.held { background: color-mix(in srgb, #4a8bdc 35%, var(--panel-2)); border-color: #4a8bdc; }
.ov-btn.pressed .lamp, .ov-btn .lamp.on { background: var(--led-in); box-shadow: 0 0 4px var(--led-in); }
.ov-btn.nc { border-color: color-mix(in srgb, var(--err) 60%, var(--line)); }
.ov-btn.nc.pressed { background: var(--err); color: #fff; }
.ov-btn.pin { border-style: dashed; }
.ov-btns { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.ov-pin-add { font-size: 11px; padding: 0 2px; width: 34px; }
.ov-head { cursor: pointer; }
.ov-card { cursor: default; }
.ov-open { color: var(--muted); font-size: 16px; }
.ov-head:hover .ov-open, .ov-head:hover b { color: var(--accent); }

/* plant-first layout: tree of the plant on the left, the selected place on the right */
.app { flex: 1; display: flex; min-height: 0; }
.main { flex: 1; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.tree {
  width: 230px; flex: none; overflow: auto; background: var(--panel);
  border-right: 1px solid var(--line); padding: 4px 0 16px;
}
.tree-group {
  padding: 12px 12px 4px; font-size: 11px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tree-item {
  display: flex; align-items: baseline; gap: 6px; width: 100%; padding: 4px 12px;
  border: none; border-left: 3px solid transparent; background: none; color: var(--text);
  cursor: pointer; text-align: left;
}
.tree-item:hover { background: color-mix(in srgb, var(--sel) 60%, transparent); }
.tree-item.active { background: var(--sel); border-left-color: var(--accent); }
.tree-item.err { border-left-color: var(--err); }
.tree-item.err .ti-id { color: var(--err); }
.ti-icon { width: 16px; color: var(--muted); text-align: center; flex: none; }
.ti-id { font: 600 11.5px var(--mono); color: var(--accent); width: 26px; flex: none; }
.ti-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ti-prg { font: 11px var(--mono); color: var(--muted); flex: none; }
.tree-item.program .ti-name { font: 12px var(--mono); }
.tree-note { padding: 4px 12px; font-size: 12px; color: var(--muted); }
.ctx-head {
  display: flex; align-items: center; gap: 12px; padding: 6px 12px;
  background: var(--panel); border-bottom: 1px solid var(--line); min-height: 40px; flex-wrap: wrap;
}
.ctx-title { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.ctx-title b { font-size: 14px; white-space: nowrap; }
.ctx-title .hint { font-family: var(--mono); white-space: nowrap; }
.prg-tools { display: flex; align-items: center; gap: 6px; }
.prg-tools #search { width: 160px; }
.bar-sep { width: 1px; align-self: stretch; background: var(--line); margin: 0 2px; }
.plant-pick select { max-width: 220px; font-weight: 600; }
.btn.icon { padding: 2px 6px; }
.btn.warn { background: var(--dirty); border-color: var(--dirty); color: #fff; }
.topbar label { display: flex; align-items: center; gap: 4px; }
.topbar { flex-wrap: wrap; row-gap: 6px; }
.sim-view-side[hidden] { display: none; }
.plant-view { flex: 1; overflow: auto; min-height: 0; }
.plant-page { max-width: 1200px; padding: 8px 16px 24px; }
.plant-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 6px 0 10px; }
.plant-title h2 { margin: 0; font-size: 18px; }
.plant-cols { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 16px; align-items: start; }
.plant-cols > section { background: var(--panel); border: 1px solid var(--line); border-radius: 6px; padding-bottom: 6px; }
.plant-tab .st-id { font: 600 12px var(--mono); color: var(--accent); width: 28px; }
.plant-tab .st-prg { font-family: var(--mono); font-size: 12px; max-width: 170px; }
.plant-tab .err { color: var(--err); font-size: 11.5px; }
@media (max-width: 1000px) {
  .plant-cols { grid-template-columns: 1fr; }
  .tree { width: 180px; }
}
/* names taken from a sister program (the program itself has none) */
.c-sym.borrowed, .card-ch.borrowed .sym { font-style: italic; }
.c-sym.borrowed::before, .card-ch.borrowed .sym::before { content: "≈ "; color: var(--muted); }
/* part feeder */
.dev .part {
  width: 22px; height: 14px; border-radius: 3px; border: 1px dashed var(--muted); flex: none;
}
.dev .part.on { background: #c9a227; border: 1px solid #8a6d12; }
.feed-state { font: 600 11.5px var(--mono); }
.ov-btn.feeder .part { width: 14px; height: 9px; border-radius: 2px; border: 1px dashed var(--muted); }
.ov-btn.feeder .part.on { background: #c9a227; border: 1px solid #8a6d12; }
.ov-btn.feeder.empty { border-color: var(--err); color: var(--err); }
/* selector switch "Automatik / Tippen": shows its position */
.ov-btn.selector .pos-on { display: none; }
.ov-btn.selector.pressed .pos-on { display: inline; }
.ov-btn.selector.pressed .pos-off { display: none; }
.ov-btn.selector:not(.pressed) { border-color: var(--dirty); }
.ov-s7 { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; }
.ov-s7 b { font-family: var(--mono); }
.dev.s7-dev .dev-row { gap: 6px; margin-bottom: 4px; }
.s7-mode, .s7-box { font: 600 11.5px var(--mono); }
/* controller without 24 V */
.ov-card.off { opacity: .55; border-top-color: var(--muted); }
.ov-card.off .ov-24v { border-color: var(--err); color: var(--err); }
.ov-24v { padding: 0 6px; font-size: 10.5px; }
/* travel times window */
.times-wrap { max-height: 50vh; overflow: auto; border: 1px solid var(--line); border-radius: 6px; }
table.times { border-collapse: collapse; width: 100%; font-size: 12px; }
table.times th { position: sticky; top: 0; background: var(--panel-2); text-align: left; padding: 4px 8px; font-weight: 600; }
table.times td { padding: 2px 8px; border-top: 1px solid color-mix(in srgb, var(--line) 50%, transparent); white-space: nowrap; }
table.times td:first-child { font: 600 11px var(--mono); color: var(--accent); }
table.times tr.fast td:nth-child(2)::after { content: " ⚡"; color: var(--muted); }
.dev-dialog table.times input[type=number] { width: 64px; padding: 1px 4px; }
.sim-status .pace.ok { color: var(--in); font-weight: 600; }
.sim-status .pace.slow { color: #fff; background: var(--err); padding: 0 6px; border-radius: 8px; font-weight: 600; }
/* debugging: breakpoints, stop pointer, active steps */
.listing .c-ln { cursor: pointer; position: relative; }
.listing .row.bp .c-ln::before {
  content: ""; position: absolute; left: 2px; top: 50%; width: 9px; height: 9px; margin-top: -5px;
  border-radius: 50%; background: var(--err);
}
.listing .row.pc { background: color-mix(in srgb, #f5c400 30%, transparent) !important; outline: 1px solid #f5c400; }
.listing .row.pc .c-ln::after { content: "▶"; position: absolute; right: -9px; color: #c99a00; font-size: 10px; }
.listing .row.step-on { box-shadow: inset 3px 0 0 var(--led-in); }
.listing .row.step-on .c-lab { color: var(--in); }
.debug-bar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 4px 12px;
  background: color-mix(in srgb, #f5c400 14%, var(--panel)); border-bottom: 1px solid var(--line); font-size: 12px;
}
.debug-bar .dbg-stop { color: #c99a00; }
.debug-bar .reg { font-family: var(--mono); }
.debug-bar .reg i { color: var(--muted); font-style: normal; }

/* 2D layout: nodes, connections, wires, chain */
.layout-view { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.lay-bar { display: flex; align-items: center; gap: 10px; padding: 4px 12px; background: var(--panel-2); border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.lay-bar label { display: flex; gap: 4px; align-items: center; }
.lay-stats { font-size: 12px; color: var(--muted); }
.lay-canvas {
  flex: 1; position: relative; overflow: hidden; cursor: grab; min-height: 0;
  background-color: var(--bg);
  background-image: radial-gradient(color-mix(in srgb, var(--muted) 35%, transparent) 1px, transparent 1px);
  background-size: 22px 22px;
}
.lay-canvas:active { cursor: grabbing; }
.lay-world { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
.lay-wires { position: absolute; left: 0; top: 0; width: 1px; height: 1px; overflow: visible; z-index: 1; }
.lay-nodes { position: relative; z-index: 2; }
.lay-node {
  position: absolute; background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .18); font-size: 11.5px; cursor: default; user-select: none;
}
.lay-node.station { border-top: 3px solid var(--accent); }
.lay-node.off { opacity: .5; }
.lay-node.device { border-top: 3px solid var(--muted); }
.lay-node.device.cylinder { border-top-color: #5aa9e6; }
.lay-node.device.button, .lay-node.device.signal { border-top-color: var(--in); }
.lay-node.device.feeder, .lay-node.device.probe, .lay-node.device.screwdriver { border-top-color: #c9a227; }
.lay-node.device.s7, .lay-node.device.air { border-top-color: #9b7be0; }
.lay-head { display: flex; align-items: center; gap: 6px; padding: 5px 8px; cursor: move; border-bottom: 1px solid var(--line); }
.lay-head b { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lay-head .hint { flex: 1; font-size: 10.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lay-head .led { width: 8px; height: 8px; flex: none; }
.lay-head .led.on { background: var(--led-in); box-shadow: 0 0 5px var(--led-in); }
.lay-lcd { margin: 5px 8px 0; font-size: 10px; }
.lay-node .mini-lcd { margin: 5px 8px 0; }
.lay-node .air-bar { margin: 6px 8px 0; width: auto; display: block; }
.lay-node .hint[data-lay-feed], .lay-node .hint[data-lay-servo], .lay-node .hint[data-lay-s7], .lay-node .hint[data-lay-screw] { padding: 4px 8px 0; font-family: var(--mono); font-size: 10.5px; }
.lay-node .ov-btn { margin: 6px 8px 0; }
.lay-cyl { margin: 6px 8px 0; height: 7px; border: 1px solid var(--line); border-radius: 4px; background: var(--panel-2); overflow: hidden; }
.lay-cyl span { display: block; height: 100%; background: var(--muted); }
.lay-cyl.moving span { background: var(--accent); }
.lay-ports { display: flex; justify-content: space-between; gap: 6px; padding: 5px 0 6px; }
.lay-ports .col { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.lay-ports .col.right { align-items: flex-end; }
.lay-port { display: flex; align-items: center; gap: 4px; height: 16px; max-width: 100%; cursor: crosshair; padding: 0 6px; white-space: nowrap; }
.lay-port.in { flex-direction: row; }
.lay-port.out { flex-direction: row-reverse; }
.lay-port .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--panel); border: 2px solid var(--muted); flex: none; margin: 0 -11px 0 -11px; }
.lay-port.in .dot { margin-left: -11px; margin-right: 2px; }
.lay-port.out .dot { margin-right: -11px; margin-left: 2px; }
/* a module's wiring: the controller as a terminal strip (connections right), the devices with theirs on the left */
.lay-port.right { flex-direction: row-reverse; }
.lay-port.right .dot { margin-right: -11px; margin-left: 2px; }
.lay-port.left { flex-direction: row; }
.lay-port.left .dot { margin-left: -11px; margin-right: 2px; }
.lay-port .io { font: 600 10.5px var(--mono); }
.lay-port .sym { color: var(--muted); overflow: hidden; text-overflow: ellipsis; font-size: 10.5px; }
.lay-port.free .io { color: var(--muted); }
.lay-port.free .dot { border-style: dashed; }
.lay-port.in.on .dot { background: var(--led-in); border-color: var(--led-in); }
.lay-port.out.on .dot { background: var(--led-out); border-color: var(--led-out); }
.lay-port:hover .dot, .lay-port.target .dot { border-color: var(--accent); transform: scale(1.4); }
.lay-wire path { fill: none; }
.lay-wire .hit { stroke: transparent; stroke-width: 10; cursor: pointer; pointer-events: stroke; }
.lay-wire .line { stroke: color-mix(in srgb, var(--muted) 70%, transparent); stroke-width: 1.6; pointer-events: none; }
.lay-wire.link .line { stroke-dasharray: 6 3; }
.lay-wire.bus .line { stroke-width: 3; stroke-dasharray: 2 3; }
.lay-wire.on .line { stroke: var(--led-in); stroke-width: 2.2; }
.lay-wire.sel .line { stroke: var(--accent); stroke-width: 3; }
.lay-wire.dim .line { opacity: .12; }
.lay-wire.hl .line { stroke-width: 2.4; }
.lay-wire.hl:not(.on) .line { stroke: var(--text); }
.lay-temp { fill: none; stroke: var(--accent); stroke-width: 2; stroke-dasharray: 5 4; }
.lay-chain { position: absolute; left: 0; z-index: 3; height: 150px; pointer-events: none; }
.lay-chain-svg { position: absolute; top: 0; overflow: visible; }
.lay-chain-svg .track { fill: none; stroke: color-mix(in srgb, var(--muted) 45%, transparent); stroke-width: 10; stroke-dasharray: 3 3; }
.lay-chain-svg .sprocket { fill: var(--panel-2); stroke: var(--muted); stroke-width: 2; }
.lay-chain-svg .sprocket.drive { stroke: var(--accent); }
.lay-chain-svg .sprocket-spokes path { stroke: var(--accent); stroke-width: 2; }
.lay-chain-svg .station-mark line { stroke: var(--text); stroke-width: 2; }
.lay-chain-svg .station-mark text { font: 600 11px var(--mono); fill: var(--text); text-anchor: middle; }
.lay-chain-svg .station-mark.removal line { stroke: var(--accent); }
.lay-chain-svg .wt { pointer-events: auto; }
.lay-chain-svg .wt .fixture { fill: var(--panel); stroke: var(--muted); stroke-width: 1.5; }
.lay-chain-svg .wt .part { stroke-width: 1.5; }
.lay-chain-svg .wt.empty .part { display: none; }
.lay-chain-svg .wt.unknown .part { fill: #e0b83a; stroke: #a8861c; }
.lay-chain-svg .wt.good .part { fill: var(--led-in); stroke: var(--in); }
.lay-chain-svg .wt.bad .part { fill: var(--err); stroke: color-mix(in srgb, var(--err) 70%, black); }
.lay-chain-svg .drive-label { font: 12px var(--mono); fill: var(--text); }
.lay-chain-svg .drive-label.hint { fill: var(--muted); font-size: 11px; }
.lay-chain-svg .out-good, .lay-chain-svg .out-bad { font: 600 13px var(--mono); text-anchor: middle; }
.lay-chain-svg .out-good { fill: var(--in); }
.lay-chain-svg .out-bad { fill: var(--err); }
/* a larger hit area around the connection dots */
.lay-port .dot { position: relative; }
.lay-port .dot::after { content: ""; position: absolute; inset: -6px; border-radius: 50%; }
.lay-wires { pointer-events: none; }
.lay-wire .hit { pointer-events: stroke; }
/* stop conditions */
.watch-row { display: grid; grid-template-columns: auto 1fr auto; gap: 8px; align-items: center; padding: 3px 10px; font-size: 12px; }
.watch-row label { display: flex; gap: 4px; align-items: center; font-family: var(--mono); }
.watch-row .d { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.watch-add { display: flex; gap: 4px; align-items: center; padding: 6px 10px; }
details.snap { margin: 6px 10px; border: 1px solid var(--err); border-radius: 6px; }
details.snap > summary { cursor: pointer; padding: 4px 8px; font-weight: 600; color: var(--err); }

/* machines on the server, login */
#machine-save.dirty { background: var(--dirty); border-color: var(--dirty); color: #fff; }
.user-menu:empty { display: none; }
.user-menu { font-weight: 600; }
.newer-bar {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  padding: 6px 12px; background: var(--accent-soft); border-bottom: 1px solid var(--line); font-size: 13px;
}
.newer-bar[hidden] { display: none; }
.login {
  position: fixed; inset: 0; z-index: 100; display: grid; place-items: center;
  background: var(--bg); padding: 16px;
}
.login[hidden] { display: none; }
.login-box {
  display: flex; flex-direction: column; gap: 10px; width: min(340px, 100%);
  padding: 24px; background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
}
.login-box h3 { margin: 0; }
.login-box .brand { font-size: 22px; }
.login-box label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); }
.login-box input { font: inherit; font-size: 14px; padding: 6px 8px; }
.login-box .f-error { color: var(--err); font-size: 12px; min-height: 1em; }
.dev-dialog .conflicts { display: flex; flex-direction: column; gap: 8px; max-height: 60vh; overflow: auto; }
.dev-dialog .conflicts fieldset { border: 1px solid var(--line); border-radius: 4px; }
.dev-dialog .conflicts legend { font-family: var(--mono); font-size: 12px; }
.dev-dialog .conflicts .f-row > span { width: auto; color: var(--text); font-family: var(--mono); font-size: 12px; word-break: break-all; }
.dev-dialog .versions { display: flex; flex-direction: column; max-height: 60vh; overflow: auto; }
.version-row { display: flex; gap: 10px; align-items: center; padding: 4px 6px; border-bottom: 1px solid var(--line); font-size: 13px; }
.version-row.current { background: var(--sel); }
.version-row .d { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* the status takes the room that is left (and is cut) instead of pushing buttons into a second row */
.topbar > .sim-status { flex: 1 1 0; min-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* quick setup of a machine */
.setup-wrap { max-height: 50vh; overflow: auto; border: 1px solid var(--line); border-radius: 6px; }
table.setup { border-collapse: collapse; width: 100%; font-size: 12px; }
table.setup th { position: sticky; top: 0; background: var(--panel-2); text-align: left; padding: 4px 8px; font-weight: 600; }
table.setup td { padding: 3px 8px; border-top: 1px solid color-mix(in srgb, var(--line) 50%, transparent); white-space: nowrap; }
table.setup tr.off td:not(:first-child) { opacity: .45; }
table.setup td.order .btn + .btn { margin-left: 2px; }
table.setup input:not([type=checkbox]), table.setup select { font: inherit; padding: 1px 4px; }
table.setup input[data-f=name] { width: 100%; min-width: 180px; }
table.setup .tag { font-size: 10px; padding: 0 5px; border-radius: 8px; background: var(--accent-soft); color: var(--accent); }
.setup-opts { display: flex; flex-direction: column; gap: 4px; border: 1px solid var(--line); border-radius: 6px; font-size: 13px; }
.setup-opts .hint { font-size: 11px; }
.setup-add { display: flex; gap: 10px; align-items: center; }
.dev-dialog form.dropping .setup-wrap { outline: 2px dashed var(--accent); outline-offset: 2px; }
table.setup .empty-row { padding: 14px 8px; text-align: center; white-space: normal; }
table.setup .tag.new { background: color-mix(in srgb, var(--in) 18%, transparent); color: var(--in); }

/* parts buffer: level bar with min and full marks */
.buf-bar { position: relative; display: inline-block; width: 160px; height: 12px; border: 1px solid var(--line); border-radius: 3px; background: var(--panel-2); overflow: hidden; }
.buf-level { position: absolute; left: 0; top: 0; bottom: 0; background: color-mix(in srgb, var(--in) 55%, transparent); }
.buf-min, .buf-full { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--muted); }
.buf-full { background: var(--accent); }
.buf-count { font: 12px var(--mono); margin-left: 8px; }
.lay-wire.bundle .line { stroke: color-mix(in srgb, var(--muted) 55%, transparent); stroke-width: 5; stroke-linecap: round; }
.lay-wire.bundle.on .line { stroke: color-mix(in srgb, var(--led-in) 70%, transparent); }
.lay-wire.bundle text { font: 600 11px var(--mono); fill: var(--muted); text-anchor: middle; }
.lay-node.pinned { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ------------------------------------------------------------ 2D scene of a module */
.seg.dev-view { display: inline-flex; border: 1px solid var(--line); border-radius: 5px; overflow: hidden; }
.seg.dev-view button { border: 0; background: var(--panel); color: var(--muted); padding: 2px 10px; font: inherit; font-size: 12px; cursor: pointer; }
.seg.dev-view button + button { border-left: 1px solid var(--line); }
.seg.dev-view button.on { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.dev-view + .add-dev { margin-left: auto; }
.scene { display: flex; gap: 0; height: 400px; margin-top: 14px; min-height: 240px; resize: vertical; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); overflow: hidden; margin-bottom: 8px; }
.scene-palette { flex: none; width: 150px; padding: 6px; border-right: 1px solid var(--line); background: var(--panel-2); display: flex; flex-direction: column; gap: 4px; overflow-y: auto; }
.pal-title { font-size: 12px; font-weight: 600; color: var(--muted); }
.pal-item { display: flex; flex-direction: row; align-items: center; gap: 6px; padding: 3px 5px; border: 1px solid var(--line); border-radius: 5px;
  background: var(--panel); cursor: grab; font-size: 11.5px; text-align: left; user-select: none; }
.pal-item:hover { border-color: var(--accent); }
.pal-item:active { cursor: grabbing; }
.pal-icon { height: 30px; width: 40px; flex: none; }
.pal-icon .sc-name { display: none; }
.scene-canvas { flex: 1; min-width: 0; overflow: auto; overscroll-behavior: contain; }
.scene-svg { display: block; touch-action: none; user-select: none; }
.pal-zoom { display: flex; align-items: center; justify-content: space-between; gap: 4px; margin-top: auto; }
.scene-svg .grid { fill: none; stroke: color-mix(in srgb, var(--line) 60%, transparent); stroke-width: .7; }
.sc-bg { fill: var(--panel); }
.sc-empty { font-size: 14px; fill: var(--muted); }
.sc-cyl { cursor: grab; }
.sc-cyl:active { cursor: grabbing; }
.sc-cyl .body { fill: color-mix(in srgb, var(--muted) 16%, var(--panel)); stroke: var(--muted); stroke-width: 1.2; }
.sc-cyl .piston { fill: var(--muted); }
.sc-cyl .rod { fill: color-mix(in srgb, var(--muted) 65%, var(--text)); }
.sc-cyl .tool, .sc-cyl .jaw { fill: color-mix(in srgb, var(--muted) 45%, var(--panel)); stroke: var(--muted); stroke-width: 1; }
.sc-cyl .track { fill: none; stroke: var(--line); stroke-width: 2; stroke-dasharray: 3 3; }
.sc-cyl .arm { stroke: color-mix(in srgb, var(--muted) 65%, var(--text)); stroke-width: 7; stroke-linecap: round; }
.sc-cyl .hub { fill: var(--muted); }
.sc-cyl .coil { fill: var(--led-off); stroke: var(--line); stroke-width: .6; }
.sc-cyl .coil.on { fill: var(--led-out); filter: drop-shadow(0 0 3px var(--led-out)); }
.sc-cyl .coil.none, .sc-cyl .sensor.none { display: none; }
.sc-cyl .sensor { fill: var(--led-off); stroke: var(--line); stroke-width: .6; }
.sc-cyl .sensor.on { fill: var(--led-in); filter: drop-shadow(0 0 3px var(--led-in)); }
.sc-cyl .sc-name { font: 600 11px var(--mono); fill: var(--text); paint-order: stroke; stroke: var(--panel); stroke-width: 3px; pointer-events: none; }
.sc-cyl.moving .piston, .sc-cyl.moving .hub { fill: var(--accent); }
.sc-cyl.faulty .body { stroke: var(--err); stroke-dasharray: 4 2; }
.sc-cyl.selected .body { stroke: var(--accent); stroke-width: 2.4; }
.sc-cyl.drop-target .tool, .sc-cyl.drop-target .arm, .sc-cyl.drop-target .plate { stroke: var(--accent); stroke-width: 3; }
.sc-cyl .plate { fill: color-mix(in srgb, var(--muted) 45%, var(--panel)); stroke: var(--muted); stroke-width: 1; }
/* part feeder: bowl, rail, singulation with light barrier; parts in amber */
.sc-feeder .bowl { fill: color-mix(in srgb, var(--muted) 16%, var(--panel)); stroke: var(--muted); stroke-width: 1.2; }
.sc-feeder .level { fill: color-mix(in srgb, var(--dirty) 45%, var(--panel)); }
.sc-feeder .track { fill: none; stroke: var(--muted); stroke-width: 1; stroke-dasharray: 3 3; opacity: .6; }
.sc-feeder .rail { fill: color-mix(in srgb, var(--muted) 45%, var(--panel)); stroke: var(--muted); stroke-width: 1; }
.sc-feeder .nest { fill: none; stroke: var(--muted); stroke-width: 2; }
.sc-feeder .lb { fill: var(--muted); }
.sc-feeder .beam { stroke: var(--led-off); stroke-width: 1.5; stroke-dasharray: 2 2; }
.sc-feeder .beam.on { stroke: var(--led-in); stroke-dasharray: none; }
.sc-cyl .part { fill: var(--dirty); stroke: color-mix(in srgb, var(--dirty) 60%, var(--text)); stroke-width: 1; }
.sc-cyl .part.stuck { stroke: var(--err); stroke-width: 2.5; }
.sc-cyl .sc-note { font: 600 10px var(--mono); fill: var(--err); }
.sc-feeder .shaking { animation: sc-shake .12s linear infinite; }
@keyframes sc-shake { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(.8px, -.6px); } }
@media (prefers-reduced-motion: reduce) { .sc-feeder .shaking { animation: none; } }
/* screwdriver: the motor's stripes run while it turns, the bit is green once the torque is reached */
.sc-screwdriver .spin line { stroke: var(--muted); stroke-width: 2; stroke-dasharray: 4 3; }
.sc-screwdriver .spin.on line { stroke: var(--accent); animation: sc-spin .25s linear infinite; }
@keyframes sc-spin { to { stroke-dashoffset: -7; } }
@media (prefers-reduced-motion: reduce) { .sc-screwdriver .spin.on line { animation: none; } }
.sc-screwdriver .bit { fill: var(--muted); }
.sc-screwdriver .bit.done { fill: var(--led-in); }
/* M8 initiator: brass thread, LED in the cap, the field it sees */
.sc-sensor .cable { stroke: color-mix(in srgb, var(--muted) 70%, var(--text)); stroke-width: 3; stroke-linecap: round; }
.sc-sensor .cap { fill: color-mix(in srgb, var(--muted) 30%, var(--panel)); stroke: var(--muted); stroke-width: 1; }
.sc-sensor .body { fill: color-mix(in srgb, #b8963a 55%, var(--panel)); stroke: #8a6d12; stroke-width: 1; }
.sc-sensor .thread line { stroke: #8a6d12; stroke-width: .7; opacity: .7; }
.sc-sensor .nut { fill: color-mix(in srgb, var(--muted) 45%, var(--panel)); stroke: var(--muted); stroke-width: 1; }
.sc-sensor .face { fill: color-mix(in srgb, var(--flag) 60%, var(--panel)); }
.sc-sensor .field { fill: none; stroke: var(--led-off); stroke-width: 1.4; stroke-dasharray: 2 2; }
.sc-sensor .field.on { stroke: var(--led-in); stroke-dasharray: none; }
.sc-sensor.faulty .body { stroke: var(--err); stroke-dasharray: 3 2; }
/* the chain in front of a module: links moving with it, the carriers with their parts */
.sc-carrier .chain { fill: color-mix(in srgb, var(--muted) 30%, var(--panel)); stroke: var(--muted); stroke-width: 1; }
.sc-carrier .links { stroke: var(--muted); stroke-width: 2; stroke-dasharray: 6 6; }
.sc-carrier .fixture { fill: color-mix(in srgb, var(--flag) 18%, var(--panel)); stroke: var(--flag); stroke-width: 1.2; }
.sc-carrier .part.good { fill: var(--led-in); stroke: color-mix(in srgb, var(--led-in) 60%, var(--text)); }
.sc-carrier .part.bad { fill: var(--err); stroke: color-mix(in srgb, var(--err) 60%, var(--text)); }
.sc-carrier .wt-no { font: 9px var(--mono); fill: var(--muted); text-anchor: middle; }
.sc-carrier .mark { fill: var(--accent); }
.carrier-dev .ok { color: var(--in); }
.carrier-dev .err { color: var(--err); }
/* electric screwdriver: cable to its controller, LEDs ready / OK / NOK */
.sc-escrewdriver .cable { fill: none; stroke: color-mix(in srgb, var(--muted) 70%, var(--text)); stroke-width: 2.5; }
.sc-escrewdriver .spin line { stroke: var(--muted); stroke-width: 2; stroke-dasharray: 4 3; }
.sc-escrewdriver .spin.on line { stroke: var(--accent); animation: sc-spin .2s linear infinite; }
@media (prefers-reduced-motion: reduce) { .sc-escrewdriver .spin.on line { animation: none; } }
.sc-escrewdriver .e-mark { font: 700 8px var(--mono); fill: var(--flag); text-anchor: middle; }
.sc-escrewdriver .bit { fill: var(--muted); }
.sc-escrewdriver .bit.done { fill: var(--led-in); }
.sc-escrewdriver .bit.nok { fill: var(--err); }
.sc-escrewdriver [class^="led-"] { fill: var(--led-off); stroke: var(--line); stroke-width: .6; }
.sc-escrewdriver .led-ready.on { fill: var(--flag); }
.sc-escrewdriver .led-ok.on { fill: var(--led-in); filter: drop-shadow(0 0 3px var(--led-in)); }
.sc-escrewdriver .led-nok.on { fill: var(--err); filter: drop-shadow(0 0 3px var(--err)); }
.scene-tools select { background: var(--panel); color: var(--text); border: 1px solid var(--line); border-radius: 4px; }
.scene-detail { margin-bottom: 10px; }
.scene-detail .dev { max-width: 460px; }
.scene-tools { display: flex; gap: 14px; align-items: center; margin-top: 6px; }
.scene-tools input[type=number] { width: 64px; background: var(--panel); color: var(--text); border: 1px solid var(--line); border-radius: 4px; padding: 2px 4px; }
@media (max-width: 700px) {
  .scene { flex-direction: column; height: auto; resize: none; }
  .scene-canvas { height: 320px; }
  .scene-palette { width: auto; flex-direction: row; flex-wrap: wrap; border-right: 0; border-bottom: 1px solid var(--line); }
  .pal-item { width: 150px; }
}

/* module view: display and the module's controls beside it */
.dev-top { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-start; }
.dev-top > .devices { flex: 0 1 auto; }
.dev-ctl { flex: 1 1 240px; min-width: 220px; max-width: 520px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); padding: 8px 10px; }
.ctl-title { font-weight: 600; font-size: 13px; margin-bottom: 6px; display: flex; gap: 8px; align-items: baseline; }
.ctl-title .hint { font-weight: 400; font-size: 11px; }
.dev-ctl .power-state { margin-top: 6px; color: var(--err); }
.dev-ctl .power-state:empty { display: none; }
/* the module's buttons as hardware on the operator panel */
.hw-panel { display: flex; flex-wrap: wrap; gap: 10px 6px; align-items: flex-end; padding: 8px 8px 6px; margin-bottom: 8px; border-radius: 6px;
  background: linear-gradient(#d9dbd8, #c6c9c5); border: 1px solid #a5a8a3; box-shadow: inset 0 1px 0 #f2f3f1; }
.hw { display: flex; flex-direction: column; align-items: center; gap: 3px; width: 88px; padding: 0; border: 0; background: none; cursor: pointer; font: inherit; color: #1d1f1c; }
.hw:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.hw-svg { width: 54px; height: 54px; display: block; overflow: visible; }
.hw-label { min-width: 60px; max-width: 88px; padding: 2px 4px; border-radius: 2px; background: #1f2121; color: #f1f1ee; font: 600 10px/1.2 var(--mono);
  text-align: center; letter-spacing: .02em; hyphens: auto; }
.hw-shine { fill: #fff; opacity: .28; }
.hw-bezel { fill: #b9bcbe; stroke: #6f7375; stroke-width: 1.5; }
/* push buttons: the cap goes down while held */
.hw-cap { transform-origin: 30px 30px; filter: drop-shadow(0 1.5px 1px rgba(0, 0, 0, .45)); transition: transform .05s; }
.hw-cap circle:first-child { stroke-width: 1.2; }
.hw-push.pressed .hw-cap { transform: scale(.9); filter: brightness(.82); }
.cap-blue circle:first-child { fill: #1f5fbf; stroke: #123a78; }
.cap-black circle:first-child { fill: #262626; stroke: #000; }
.cap-white circle:first-child { fill: #f4f4f2; stroke: #8a8a86; }
.cap-white .hw-shine { opacity: .7; }
.cap-green circle:first-child { fill: #1f8f3a; stroke: #0f5a22; }
.cap-grey circle:first-child { fill: #8b8f92; stroke: #55595b; }
/* selector switch: knob at 10 o'clock (off) or 2 o'clock (on) */
.hw-tick { stroke: #1d1f1c; stroke-width: 2; stroke-linecap: round; }
.hw-selector .hw-bezel { fill: #2b2c2d; stroke: #111; }
.hw-knob-base { fill: #3a3b3c; }
.hw-knob { transform-origin: 30px 30px; transform: rotate(-45deg); transition: transform .12s; filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .5)); }
.hw-knob rect { fill: #1a1a1a; stroke: #555; stroke-width: 1; }
.hw-knob line { stroke: #f1f1ee; stroke-width: 2; stroke-linecap: round; }
.hw-selector.pressed .hw-knob { transform: rotate(45deg); }
.hw-pos { display: flex; justify-content: space-between; width: 88px; font: 600 8px var(--mono); color: #55595b; margin-bottom: -4px; }
.hw-pos span { max-width: 44px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hw-pos .on { text-align: right; }
.hw-selector:not(.pressed) .hw-pos .off, .hw-selector.pressed .hw-pos .on { color: #1d1f1c; text-decoration: underline; text-decoration-thickness: 2px; }
.ctl-sel { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; padding: 2px 6px; border: 1px solid var(--line); border-radius: 12px; }
.ctl-sel select { background: var(--panel); color: var(--text); border: 1px solid var(--line); border-radius: 4px; font-size: 12px; }
.ctl-air { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; }
.ctl-air .air-bar { width: 70px; }

/* program view: what the selected instruction does */
.explain-bar { flex: none; display: flex; gap: 12px; align-items: baseline; min-height: 26px; padding: 4px 12px;
  border-top: 1px solid var(--line); background: var(--panel-2); font-size: 12.5px; overflow: hidden; white-space: nowrap; }
.explain-bar .ex-op { font-family: var(--mono); }
.explain-bar .ex-does { font-family: var(--mono); color: var(--flag); }
.explain-bar .hint { overflow: hidden; text-overflow: ellipsis; }

/* data flow of the hovered line: blue = its value comes from, orange = its result goes to, dashed = through memory */
/* the whole network lightly, its result strongly */
.row.fl-block { background: color-mix(in srgb, var(--flag) 7%, transparent); }
.row.fl-result { background: color-mix(in srgb, var(--accent) 24%, transparent); box-shadow: inset 3px 0 0 var(--accent); font-weight: 600; }
.row.fl-self { box-shadow: inset 3px 0 0 var(--text); }
.row.fl-from { background: color-mix(in srgb, var(--flag) 16%, transparent); box-shadow: inset 3px 0 0 var(--flag); }
.row.fl-to { background: color-mix(in srgb, var(--accent) 16%, transparent); box-shadow: inset 3px 0 0 var(--accent); }
.row.fl-mem-in { box-shadow: inset 3px 0 0 color-mix(in srgb, var(--flag) 60%, transparent); outline: 1px dashed color-mix(in srgb, var(--flag) 50%, transparent); outline-offset: -1px; }
.row.fl-mem-out { box-shadow: inset 3px 0 0 color-mix(in srgb, var(--accent) 60%, transparent); outline: 1px dashed color-mix(in srgb, var(--accent) 50%, transparent); outline-offset: -1px; }
.fl-tag { font-size: 11.5px; padding: 0 6px; border-radius: 8px; border: 1px solid var(--line); }
.fl-tag.from { color: var(--flag); border-color: var(--flag); }
.fl-tag.to { color: var(--accent); border-color: var(--accent); }
.fl-tag.result { color: var(--accent); border-color: var(--accent); font-weight: 600; }
.fl-tag.mem-in { color: var(--flag); border-style: dashed; }
.fl-tag.mem-out { color: var(--accent); border-style: dashed; }
.plant-row .st-place { width: 52px; }
.plant-row .st-place-l { white-space: nowrap; }
.pal-copy { margin-top: auto; width: 100%; font-size: 11.5px; background: var(--panel); color: var(--text); border: 1px solid var(--line); border-radius: 4px; padding: 2px; }
.pal-copy ~ .pal-zoom, .pal-zoom + .pal-zoom { margin-top: 0; }
.plant-row .st-place-l.from-prg { color: var(--in); }
