/* Drop Count: the whole app's styles. Colors and sizes are the custom properties on :root. */
:root {
  --bg: #0e0e10;
  --bar: #131316;
  --panel: #17171b;
  --panel-2: #212127;
  --hover: #1d1d22;
  --line: #2a2a31;
  --text: #e7e7ea;
  --muted: #9b9ba4;
  --dim: #6d6d76;
  --accent: #4a8df7;
  --accent-2: #2f7bf5;
  --sel: #1e3a68;
  --sel-tx: #cfe0ff;
  --ok: #34c38f;
  --warn: #e8a838;
  --bad: #f0616a;
}
:root { color-scheme: dark; }
* { box-sizing: border-box; }
#viewer::-webkit-scrollbar { width: 12px; height: 12px; background: #000; }
#viewer::-webkit-scrollbar-track, #viewer::-webkit-scrollbar-corner { background: #000; }
#viewer::-webkit-scrollbar-thumb { background: #2a2a31; border-radius: 6px; border: 3px solid #000; }
#viewer::-webkit-scrollbar-thumb:hover { background: #3a3a44; }
html, body { height: 100%; margin: 0; overscroll-behavior: none; }   /* a two-finger swipe never slides the whole page (Chrome's back/forward swipe) */
#viewer, #tree, #symList, #pvCanvas { overscroll-behavior: contain; }   /* scrolling stays inside the drawing or the list, even at its edge */
body {
  background: var(--bg); color: var(--text);
  font: 13px/1.4 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  display: flex; flex-direction: column; overflow: hidden;
}
/* ---- top bar: file, page, zoom, export ---- */
header {
  flex: none; height: 40px; display: flex; align-items: center; gap: 4px; white-space: nowrap;
  padding: 0 10px 0 8px; background: var(--bar); border-bottom: 1px solid var(--line);
}
header h1 { font-size: 14px; font-weight: 600; margin: 0 6px 0 2px; white-space: nowrap; }
.fileMenu { position: relative; }
.fileMenu > button { padding: 4px 9px; font-size: 13px; }
#fileDrop { position: absolute; left: 0; top: 100%; margin-top: 4px; z-index: 50; min-width: 250px; display: flex; flex-direction: column; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 4px; box-shadow: 0 8px 24px rgba(0,0,0,.45); }
#fileDrop[hidden] { display: none; }
.layersMenu { position: relative; }
.layersMenu > button { padding: 4px 9px; font-size: 13px; }
#layersDrop { position: absolute; left: 0; top: 100%; margin-top: 4px; z-index: 50; min-width: 280px; max-height: calc(100vh - 60px); overflow: auto; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 4px 0; box-shadow: 0 8px 24px rgba(0,0,0,.45); font-size: 12px; color: var(--muted); }
#layersDrop[hidden] { display: none; }
#layersDrop #layerBar { flex-direction: column; flex-wrap: nowrap; align-items: flex-start; gap: 7px; padding: 8px 12px; background: transparent; border-top: 0; }
#layersDrop #layerBar .lbSep { width: 100%; height: 1px; }
#layersDrop #layerBar .lbNote { display: block; margin-left: 0; white-space: normal; max-width: 260px; }
#layersDrop .lbShow { display: flex; flex-direction: column; align-items: flex-start; gap: 7px; padding: 8px 12px; border-top: 1px solid var(--line); }
#layersDrop .lbShow .lbTitle { font-weight: 600; color: var(--text); }
#layersDrop .lbShow > label:not(.lbTitle) { margin-left: 18px; }
#layersDrop .lbShow label { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; cursor: pointer; }
#layersDrop .lbShow label:has(input:checked) { color: var(--text); }
#layersDrop .lbSlider { display: flex; align-items: center; gap: 8px; margin-left: 36px; font-size: 11px; color: var(--dim); }   /* the zone fill's opacity, under its tick */
#layersDrop .lbSlider input { width: 120px; margin: 0; }
#layersDrop .lbCable { border-top: 1px solid var(--line); padding: 6px 8px 4px; }
#layersDrop .lbCable label { display: inline-flex; align-items: center; gap: 5px; margin-left: 4px; white-space: nowrap; cursor: pointer; }
#layersDrop .lbCable label:has(input:checked) { color: var(--text); }
#layersDrop .lbRow { display: flex; align-items: center; justify-content: space-between; gap: 18px; width: 100%; }
#layersDrop .opPair { display: inline-flex; gap: 10px; font-size: 11px; color: var(--dim); }
#layersDrop .opPair label { gap: 3px; }
#fileDrop button { text-align: left; border-radius: 5px; color: var(--text); padding: 7px 10px; white-space: nowrap; }
.group { display: flex; align-items: center; gap: 2px; }
#exportGroup { gap: 6px; }
#exportGroup[hidden] { display: none; }
.sep { width: 1px; height: 18px; background: var(--line); margin: 0 6px; }
header .spacer { flex: 1 1 0; min-width: 0; }
button, .btn { background: transparent; color: var(--muted); border: 0; border-radius: 5px; padding: 5px 9px; font: inherit; cursor: pointer; }
button:hover:not(:disabled), .btn:hover { background: var(--hover); color: var(--text); }
button:disabled { opacity: .35; cursor: default; }
select { background: var(--panel); color: var(--text); border: 1px solid var(--line); border-radius: 5px; padding: 4px 8px; font: inherit; cursor: pointer; }
header select { height: 26px; font-size: 12px; padding: 0 4px; }
#dpi { width: 76px; } #fmt { width: 100px; }
svg.i { width: 18px; height: 18px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
/* square icon button */
.ic { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; padding: 0; }
.ic:hover:not(:disabled) { background: var(--panel-2); }
.ic.on { background: var(--sel); color: var(--text); }
/* text button in the top bar */
.tl { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 8px; color: var(--text); }
.tl svg.i { width: 16px; height: 16px; color: var(--muted); }
.readval { min-width: 42px; text-align: center; color: var(--muted); font-variant-numeric: tabular-nums; }
button.primary { background: var(--accent-2); color: #fff; height: 26px; padding: 0 10px; display: inline-flex; align-items: center; gap: 6px; }
button.primary svg.i { width: 16px; height: 16px; }
button.primary:hover:not(:disabled) { background: var(--accent); color: #fff; }
label.check { display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none; }
header label.viewOpt { font-size: 12px; color: var(--muted); white-space: nowrap; margin: 0 4px; }
header label.viewOpt:has(input:checked) { color: var(--text); }
#symMenu { position: absolute; z-index: 40; min-width: 120px; padding: 4px; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 6px 20px rgba(0,0,0,.5); }
#symMenu button { display: block; width: 100%; text-align: left; padding: 6px 12px; background: transparent; border: 0; border-radius: 5px; color: var(--text); font: inherit; font-size: 13px; cursor: pointer; }
#symMenu button:hover { background: var(--sel); color: var(--sel-tx); }
#layerBar { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 16px; padding: 4px 14px; background: var(--bar); border-top: 1px solid var(--line); font-size: 12px; color: var(--muted); }
#layerBar .lbTitle { font-weight: 600; color: var(--text); }
#layerBar label { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
#layerBar label:has(input:checked) { color: var(--text); }
#layerBar label:has(input:disabled) { opacity: .5; }
#layerBar .lbSep { width: 1px; height: 14px; background: var(--line); }
#layerBar .lbNote { margin-left: auto; font-size: 11px; color: var(--dim); }
@media (max-width: 1200px) { #layerBar .lbNote { display: none; } #layerBar { gap: 4px 12px; } }
.muted { color: var(--muted); }
.spacer { flex: 1; }

main { flex: 1; display: flex; min-height: 0; }

/* ---- rail: the thin strip of sections ---- */
#rail {
  width: 54px; flex: none; display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 8px 0; background: var(--bar); border-right: 1px solid var(--line); overflow-y: auto;
}
#rail button {
  width: 44px; padding: 6px 0 5px; border-radius: 7px; display: flex; flex-direction: column; align-items: center; gap: 2px;
  font-size: 10.5px; line-height: 1.15; color: var(--muted);
}
#rail button:hover { background: var(--panel-2); color: var(--text); }
#rail button.on { background: var(--sel); color: var(--text); }

/* ---- left panel: the project tree ---- */
#leftPane { width: 250px; flex: none; background: var(--bg); border-right: 1px solid var(--line); padding: 0 6px 8px; overflow-y: auto; }
#leftPane[hidden] { display: none; }
#leftPane > .sec:first-child { margin-top: 8px; }
.treeEmpty { padding: 6px 8px; color: var(--dim); font-size: 12px; line-height: 1.5; }
.treeEmpty.lv1 { padding-left: 28px; }
#tree .trow { position: relative; }
#tree .tproj + .tproj { border-top: 1px solid rgba(155,155,164,.16); margin-top: 4px; padding-top: 4px; }   /* a faint line between projects */
#tree .trow .tacts { position: absolute; right: 2px; top: 2px; display: none; gap: 0; background: var(--hover); border-radius: 5px; }
#tree .trow:hover .tacts { display: flex; }
#tree .trow .tacts .ic { width: 24px; height: 24px; }
#tree .trow .tacts svg.i { width: 14px; height: 14px; }
#tree .ti.cur:not(.on) { color: var(--sel-tx); }
#tree .ti.static { cursor: default; }
#tree .lv0 { padding-left: 4px; }
#tree .lv3 { padding-left: 28px; }
#tree .lv4 { padding-left: 36px; }
#tree .lv5 { padding-left: 44px; }
#tree .chip { width: 10px; height: 10px; border-radius: 3px; flex: none; margin: 0 3px; }
#tree .nonroom .bl { font-style: italic; }
#tree .fact { height: 24px; font-size: 12px; color: var(--muted); }
#whoDlg { position: fixed; inset: 0; z-index: 50; background: rgba(0,0,0,.72); display: flex; align-items: center; justify-content: center; }
#whoDlg[hidden] { display: none; }
.whoCard { width: min(340px, 90vw); background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 20px; display: flex; flex-direction: column; gap: 12px; }
.whoCard h2 { margin: 0; font-size: 16px; }
#whoList { display: flex; flex-direction: column; gap: 4px; max-height: 50vh; overflow-y: auto; }
.whoBtn { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 10px; color: var(--text); background: var(--bg); border: 1px solid var(--line); border-radius: 6px; text-align: left; }
.whoBtn svg.i { width: 16px; height: 16px; color: var(--muted); }
.whoBtn:hover { border-color: var(--accent); }
#whoForm { display: flex; gap: 6px; }
#whoForm input { flex: 1; height: 32px; padding: 0 10px; background: var(--bg); color: var(--text); border: 1px solid var(--line); border-radius: 6px; font: inherit; }
#whoForm button { height: 32px; }
.projActs { display: flex; align-items: center; gap: 2px; }
.whoChip { display: inline-flex; align-items: center; gap: 4px; height: 22px; max-width: 110px; padding: 0 7px; border-radius: 11px; background: var(--panel-2); color: var(--text); font-size: 11.5px; font-weight: 500; }
.whoChip[hidden] { display: none; }
.whoChip svg.i { width: 12px; height: 12px; }
.whoChip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#tree .tsec { margin: 12px 0 2px; }
#loginDlg { position: fixed; inset: 0; z-index: 50; background: rgba(0,0,0,.72); display: flex; align-items: center; justify-content: center; }
#loginDlg[hidden] { display: none; }
#loginForm { width: min(320px, 90vw); background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 20px; display: flex; flex-direction: column; gap: 12px; }
#loginForm h2 { margin: 0; font-size: 16px; }
#loginForm input { height: 32px; padding: 0 10px; background: var(--bg); color: var(--text); border: 1px solid var(--line); border-radius: 6px; font: inherit; }
#loginForm button { height: 32px; justify-content: center; }
#statusBar { display: flex; align-items: center; background: var(--bar); border-top: 1px solid var(--line); }
#statusBar #status { flex: 1; border-top: 0; }
#saveState { font-size: 12px; color: var(--dim); padding: 0 14px; white-space: nowrap; }
#saveState.bad { color: #fff; background: #c9303a; border-radius: 4px; padding: 1px 8px; margin: 0 10px; font-weight: 600; }
#tree .ti { gap: 6px; }
#tree .ti .bl { flex: 1; min-width: 0; }
#tree .caret { width: 14px; height: 14px; flex: none; color: var(--dim); transition: transform .12s; }
#tree .open > .caret { transform: rotate(90deg); }
#tree .nocaret { width: 14px; flex: none; }
#tree .lv1 { padding-left: 12px; }   /* each level steps in 8px */
#tree .lv2 { padding-left: 20px; }
#tree .pill { font-size: 11px; line-height: 18px; padding: 0 6px; border-radius: 5px; background: var(--panel-2); color: var(--muted); flex: none; }
#tree .delx { display: none; margin-left: 6px; padding: 0 5px; border-radius: 5px; font-size: 12px; line-height: 18px; color: var(--muted); flex: none; }
#tree .ti:hover .delx, #tree .ti:focus-visible .delx { display: inline-block; }
#tree .delx:hover { background: #e5484d; color: #fff; }
#tree .ti.on .pill { background: rgba(255,255,255,.1); color: var(--sel-tx); }

/* ---- center: the chosen section's tools in a bar across the top of the drawing ---- */
#center { flex: 1; min-width: 0; display: flex; flex-direction: column; }
#toolbar { flex: none; background: var(--bar); border-bottom: 1px solid var(--line); }
#toolbar[hidden] { display: none; }
.pane { display: flex; align-items: center; flex-wrap: wrap; gap: 2px; min-height: 40px; padding: 4px 8px; }
.pane[hidden] { display: none; }
/* icons only; hovering a tool (or switching it on) slides its name out */
#toolbar .ti { width: auto; height: 28px; gap: 0; padding: 0 6px; }
#toolbar .ti .bl, #toolbar .ti kbd {
  max-width: 0; opacity: 0; margin-left: 0; overflow: hidden; white-space: nowrap;
  transition: max-width .24s ease, opacity .18s ease, margin-left .24s ease;
}
#toolbar .ti kbd { border-width: 0; padding: 0; }
#toolbar .ti:hover .bl, #toolbar .ti:focus-visible .bl, #toolbar .ti.on .bl, #toolbar .ti.toggled .bl { max-width: 200px; opacity: 1; margin-left: 6px; }
#toolbar .ti:hover kbd, #toolbar .ti:focus-visible kbd { max-width: 60px; opacity: 1; margin-left: 8px; border-width: 1px; padding: 0 5px; }
/* every tool (Symbols, Rooms, Cabling, Clean) always shows its name beside its icon */
#toolbar .pane { gap: 4px; }
#toolbar .pane .ti { padding: 0 9px; }
#toolbar .pane .ti .bl { max-width: none; opacity: 1; margin-left: 6px; font-size: 12.5px; transition: none; }
#toolbar .tgrp { display: none; }
.tsep { width: 1px; height: 18px; background: var(--line); margin: 0 6px; flex: none; }
.tgrp { font-size: 11.5px; font-weight: 600; color: var(--muted); margin: 0 4px 0 2px; white-space: nowrap; }
.sec {
  display: flex; align-items: center; justify-content: space-between; height: 24px; margin: 14px 0 2px;
  padding: 0 4px 0 8px; font-size: 11.5px; font-weight: 600; color: var(--muted);
}
.sec .ic { width: 22px; height: 22px; }
.sec .ic svg.i { width: 14px; height: 14px; }
.ti {
  width: 100%; display: flex; align-items: center; gap: 8px; height: 28px; padding: 0 8px;
  color: var(--text); text-align: left; white-space: nowrap;
}
.ti svg.i { width: 16px; height: 16px; color: var(--muted); }
.ti .bl { overflow: hidden; text-overflow: ellipsis; }
.ti kbd { margin-left: auto; font-size: 10.5px; line-height: 16px; color: var(--dim); border: 1px solid var(--line); border-radius: 4px; padding: 0 5px; }
.ti:hover:not(:disabled) { background: var(--hover); }
.ti.on, .ti.toggled { background: var(--sel); color: var(--text); }
.ti.on svg.i, .ti.toggled svg.i { color: var(--text); }
.ti.accent:not(:disabled) svg.i, .ti.accent:not(:disabled) { color: var(--accent); }
.ti.accent:hover:not(:disabled) { background: var(--accent-2); color: #fff; }
.ti.accent:hover:not(:disabled) svg.i { color: #fff; }

/* gray-removal controls, inline in the Clean toolbar */
#swatch { width: 18px; height: 12px; border-radius: 3px; border: 1px solid var(--line); background: #fff; flex: none; margin-right: 4px; }
#pct { min-width: 34px; font-weight: 600; font-variant-numeric: tabular-nums; }
#track { width: 140px; height: 14px; border-radius: 5px; border: 1px solid var(--line); background: linear-gradient(to right, #fff, #000); position: relative; flex: none; margin: 0 8px 0 2px; }
#level { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; -webkit-appearance: none; appearance: none; background: transparent; cursor: ew-resize; }
#level::-webkit-slider-runnable-track { background: transparent; }
#level::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 10px; height: 22px;
  background: var(--accent); border: 2px solid var(--text); border-radius: 4px; box-shadow: 0 1px 4px rgba(0,0,0,.6);
}
#level::-moz-range-track { background: transparent; }
#level::-moz-range-thumb { width: 8px; height: 22px; background: var(--accent); border: 2px solid #fff; border-radius: 4px; }
#toolbar label.check { color: var(--muted); font-size: 12px; margin: 0 6px 0 4px; white-space: nowrap; }
#toolbar select { height: 26px; font-size: 12px; padding: 0 4px; }

/* ---- viewer ---- */
#vwrap { flex: 1; position: relative; min-width: 0; background: #000; }
#planView { position: absolute; inset: 0; z-index: 4; background: #000; display: flex; flex-direction: column; }
#planView[hidden] { display: none; }
#planView .pvBar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; padding: 6px 10px; background: var(--panel); border-bottom: 1px solid var(--line); font-size: 12px; }
#planView .pvBar .muted { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
#planView .pvBar .sp { flex: 1; }
#planView .pvBar button, #planView .pvBar b { white-space: nowrap; }
#planView .pvBar .ti { width: auto; flex: none; padding: 4px 10px; min-height: 0; }
#planView .pvBar [hidden] { display: none !important; }
#planView .pvBar .muted { flex: 1 1 220px; }
#planView .pvBar button.on { background: var(--sel); color: var(--sel-tx); }
#pvCanvas { flex: 1; min-height: 0; width: 100%; display: block; touch-action: none; }
#viewer {
  position: absolute; inset: 0; overflow: auto; background: #000;
  cursor: grab;
}
/* The marker layer lives inside the scrolling drawing, so the browser moves it with the page on a drag instead of it
   being redrawn a frame late. It is a window-sized-plus-margin sheet that re-centres itself after each move; the clip
   keeps it from stretching the scroll area. */
#ovClip { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 2; }
#overlay { position: absolute; left: 0; top: 0; pointer-events: none; }
#sharpLayer { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1; }
#sharpLayer[hidden] { display: none; }
#calloutTip {
  position: absolute; z-index: 6; pointer-events: none; max-width: 320px;
  background: rgba(15,15,18,.96); color: var(--text); border: 1px solid var(--line); border-radius: 8px;
  padding: 7px 10px; font-size: 12px; line-height: 1.4; box-shadow: 0 6px 20px rgba(0,0,0,.5);
}
#calloutTip[hidden] { display: none; }
#calloutTip .num { font-weight: 600; color: var(--accent); }
#calloutTip .guess { color: var(--dim); font-size: 10.5px; }
/* The trunk-line tip's list by cable type and color (under its first line when the drawing has cable specs): the words on the left, the count on the right, "+ N more" muted */
#calloutTip .guess + .cabLn { margin-top: 3px; }
#calloutTip .cabLn { display: flex; justify-content: space-between; gap: 14px; white-space: nowrap; }
#calloutTip .cabLn span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
#calloutTip .cabN { font-variant-numeric: tabular-nums; }
#calloutTip .cabMore { color: var(--muted); margin-top: 2px; }
#viewer.panning { cursor: grabbing; }
#viewer.areaMode { cursor: crosshair; }
#viewer.cornerHot { cursor: move; }
#viewer.legendMode { cursor: crosshair; }
/* the Add Symbol From Drawing step bar, across the top of the drawing */
#exBar { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); z-index: 4; display: flex; align-items: center; gap: 8px; width: min(680px, calc(100% - 32px));
  background: rgba(23,23,27,.96); border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px 8px 14px; box-shadow: 0 6px 20px rgba(0,0,0,.5); font-size: 12.5px; }
#exBar[hidden] { display: none; }
#exMsg { flex: 1; min-width: 0; color: var(--text); }
#exBar button { height: 28px; padding: 0 12px; flex: none; }
#exBar button:not(.primary) { background: var(--panel-2); color: var(--text); }
#areaTool.on, #roomTool.on, #roomFill.on, #idfTool.on, #fenceTool.on, #portalTool.on, #portShow.on, #trunkTool.on, #fireTool.on, #envTool.on, #zoneTool.on, #moveTool.on, #deleteLine.on { background: var(--sel); color: var(--sel-tx); }
#stage { display: inline-block; position: relative; padding: 24px; min-width: 100%; min-height: 100%; }
#stage.centered { display: flex; align-items: center; justify-content: center; }
canvas#view { display: block; background: #fff; box-shadow: 0 4px 24px rgba(0,0,0,.6); margin: auto; }
/* Negative: on screen only, every sheet. Hue is turned back round so colored markup keeps roughly its own color;
   the marker overlay isn't inverted, so found symbols and cable lines look the same either way. */
body.negative canvas#view, body.negative #sharpLayer,
body.negative .pickRow canvas.thumb { filter: invert(1) hue-rotate(180deg); }
body.negative canvas#view { box-shadow: 0 0 0 1px var(--line); }
/* While placing the IDF or drawing trunk lines the drawing's lines fade to half strength so the cable work stands
   out; the paper itself stays white (or black in Negative). Lines blend 50% into the paper color: invert, halve,
   invert back lifts them halfway to white; in Negative, halving after the negative sinks them halfway to black.
   Done with filters, not opacity, which broke compositing of this layer in the Mac app's engine. Markers are untouched. */
body.cableDim canvas#view, body.cableDim #sharpLayer { filter: invert(1) brightness(.5) invert(1); }
body.negative.cableDim canvas#view, body.negative.cableDim #sharpLayer { filter: invert(1) hue-rotate(180deg) brightness(.5); }
#empty {
  position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; color: var(--muted); text-align: center; pointer-events: none;
}
#empty strong { color: var(--text); font-size: 18px; }
#viewer.dragover { outline: 3px dashed var(--accent); outline-offset: -12px; }
#badge {
  position: absolute; top: 12px; right: 16px; background: rgba(0,0,0,.7); padding: 4px 10px;
  border-radius: 6px; font-size: 12px; pointer-events: none; display: none;
}
#busy {
  position: absolute; inset: 0; background: rgba(14,14,16,.72); display: none; flex-direction: column;
  align-items: center; justify-content: center; gap: 12px; z-index: 5;
}
#busy .bar { width: 320px; height: 6px; background: var(--panel-2); border-radius: 4px; overflow: hidden; }
#busy .bar > div { height: 100%; width: 0; background: var(--accent); transition: width .15s; }
/* ---- choose symbols dialog ---- */
#pickDlg { background: var(--panel); color: var(--text); border: 1px solid var(--line); border-radius: 12px; padding: 0; width: min(560px, 92vw); max-height: 86vh; }
#pickDlg[open] { display: flex; flex-direction: column; }
#libDlg { background: var(--panel); color: var(--text); border: 1px solid var(--line); border-radius: 12px; padding: 0; width: min(640px, 94vw); max-height: 88vh; }
#libDlg[open] { display: flex; flex-direction: column; }
.smallDlg { background: var(--panel); color: var(--text); border: 1px solid var(--line); border-radius: 12px; padding: 16px 18px; width: min(360px, 92vw); }
.smallDlg::backdrop { background: rgba(0,0,0,.55); }
.logDlg { width: min(560px, 94vw); max-height: 80vh; overflow: auto; }
.logDlg .logItem { border-top: 1px solid var(--line); padding: 10px 0 4px; }
.logDlg .logHead { font-size: 13.5px; }
.logDlg .logWhen { font-size: 11.5px; margin: 1px 0 4px; }
.logDlg ul { margin: 4px 0 6px; padding-left: 18px; font-size: 12.5px; line-height: 1.45; }
.dupDlg { position: fixed; right: 16px; bottom: 44px; left: auto; top: auto; margin: 0; width: min(380px, 92vw); max-height: 55vh; overflow: auto; z-index: 20; box-shadow: 0 8px 30px rgba(0,0,0,.5); }
.dupDlg .dupHead { font-weight: 600; font-size: 12.5px; margin: 10px 0 2px; }
.dupDlg .dupSum { font-size: 11.5px; margin-bottom: 4px; }
.dupDlg .dupRow { display: flex; align-items: center; gap: 6px; padding: 4px 6px; border-radius: 6px; font-size: 12.5px; cursor: pointer; }
.dupDlg .dupRow:hover { background: var(--hover); }
.dupDlg .chip { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.smallDlg label { display: flex; align-items: center; gap: 8px; margin: 6px 0; font-size: 13px; }
.smallDlg input, .smallDlg select { background: var(--bg); color: var(--text); border: 1px solid var(--line); border-radius: 6px; padding: 5px 8px; font: inherit; }
.smallDlg #riserName, .smallDlg #panelName, .smallDlg #panelGroup { flex: 1; }
#autoLegList { max-height: 40vh; overflow: auto; margin: 4px 0; }
#autoLegList label { margin: 3px 0; font-size: 12.5px; }
#autoLegList label .muted { margin-left: auto; font-size: 11px; }
.smallDlg .pickFoot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
#libDlg::backdrop { background: rgba(0,0,0,.55); }
#libDlg input[type=search] { flex: 1; background: var(--bg); color: var(--text); border: 1px solid var(--line); border-radius: 6px; padding: 5px 8px; font: inherit; font-size: 13px; }
#libRows { flex: 1; overflow-y: auto; padding: 6px 10px; min-height: 200px; display: flex; flex-direction: column; gap: 4px; }
.libRow { display: flex; align-items: center; gap: 10px; padding: 4px 6px; border-radius: 8px; }
.libRow:hover { background: var(--hover); }
.libRow.off { opacity: .45; }
.libBand { display: flex; align-items: center; gap: 8px; margin: 8px 0 2px; padding: 4px 6px; font-size: 11px; font-weight: 700; letter-spacing: .05em; color: var(--muted); border-bottom: 1px solid var(--line); position: sticky; top: 0; background: var(--bg); z-index: 1; }
.libBand .libFold { width: 22px; height: 22px; padding: 0; border: 1px solid var(--line); border-radius: 5px; background: var(--bg); color: var(--text); font: inherit; font-size: 12px; cursor: pointer; }
.libBand.folded { opacity: .8; }
.libRow.folded { display: none; }
.libRow canvas.thumb { width: 42px; height: 42px; border-radius: 6px; flex: none; }
.libFields { flex: 1; min-width: 0; display: grid; grid-template-columns: 1.4fr 1fr; gap: 4px 6px; }
.libCab { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; font-size: 11.5px; color: var(--muted); }
.libCab label { display: flex; align-items: center; gap: 4px; }
.libCab input[type=number], .libCab input[type=text] { background: var(--bg); color: var(--text); border: 1px solid var(--line); border-radius: 4px; padding: 2px 5px; font: inherit; }
.libCab input[type=number] { width: 44px; }
.libCab input[type=text] { width: 60px; }
.libFields input { min-width: 0; height: 26px; background: var(--bg); color: var(--text); border: 1px solid var(--line); border-radius: 5px; padding: 0 6px; font: inherit; font-size: 12px; }
.libFields .libTx { grid-column: 1 / -1; font-size: 11px; }
#libDelete { margin-right: auto; color: var(--bad); }
#libSelect { height: 26px; font-size: 12px; max-width: 220px; margin: 0 4px; }
#pickDlg::backdrop { background: rgba(0,0,0,.55); }
.pickHead { padding: 14px 16px 10px; display: flex; flex-direction: column; gap: 10px; border-bottom: 1px solid var(--line); }
.pickHead h2 { margin: 0; font-size: 15px; }
.pickHead .row { display: flex; align-items: center; gap: 8px; }
.pickHead input[type=search] { flex: 1; background: var(--bg); color: var(--text); border: 1px solid var(--line); border-radius: 6px; padding: 5px 8px; font: inherit; font-size: 13px; }
.pickHead button, .pickFoot button { padding: 4px 10px; font-size: 12px; }
#pickList { flex: 1; overflow-y: auto; padding: 6px 8px; min-height: 200px; }
.pickCat { display: flex; align-items: center; gap: 8px; padding: 8px 6px 4px; font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--dim, var(--muted)); position: sticky; top: 0; background: var(--panel); z-index: 1; }
.pickCat .muted { margin-left: auto; text-transform: none; letter-spacing: 0; }
.pickRow { display: flex; align-items: center; gap: 10px; padding: 4px 6px; border-radius: 8px; cursor: pointer; font-size: 13px; }
.pickRow:hover { background: var(--hover); }
.pickRow canvas.thumb { border-radius: 6px; flex: none; width: 40px; height: 40px; }
.pickRow .nm { flex: 1; min-width: 0; }
.pickFoot { padding: 10px 16px; border-top: 1px solid var(--line); display: flex; align-items: center; gap: 10px; }
.pickFoot .muted { flex: 1; font-size: 12px; }
/* ---- symbols panel ---- */
#symbols { width: 320px; flex: none; background: var(--bg); border-left: 1px solid var(--line); display: flex; flex-direction: column; min-height: 0; }
#symbols[hidden] { display: none; }
.symHead { padding: 10px 12px 8px; border-bottom: 1px solid var(--line); display: flex; flex-direction: column; gap: 8px; }
.symHead .row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
#symClassWrap[hidden] { display: none; }
.symHead h2 { margin: 0; font-size: 13px; white-space: nowrap; }
.symHead .row:first-child { flex-wrap: nowrap; }
#symSummary { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
.symHead button { height: 26px; padding: 0 10px; font-size: 12px; background: var(--panel-2); color: var(--text); }
.symHead button:hover:not(:disabled) { background: var(--line); }
#symHead #symClose, .symHead #symClose { margin-left: auto; width: 28px; padding: 0; font-size: 18px; background: transparent; color: var(--muted); }
.symHead .seg button { background: transparent; color: var(--muted); }
.symHead .seg button.on { background: var(--sel); color: var(--sel-tx); }
.seg { display: flex; gap: 2px; background: var(--bar); border-radius: 8px; padding: 2px; }
.seg button { flex: 1; border-radius: 6px; padding: 5px 8px; font-size: 12px; }
.seg button.on { background: var(--sel); color: var(--sel-tx); }
.notFound { margin: 6px 4px; font-size: 12px; color: var(--muted); }
.notFound summary { cursor: pointer; padding: 4px 2px; }
.notFound div { padding: 1px 6px; }
.symOpts { font-size: 12px; color: var(--muted); display: flex; flex-direction: column; gap: 4px; }
.symOpts label { display: flex; align-items: center; gap: 6px; }
.symOpts input[type=number] { width: 56px; background: var(--bg); color: var(--text); border: 1px solid var(--line); border-radius: 4px; padding: 1px 4px; }
#symList { flex: 1; overflow-y: auto; padding: 6px; }
/* Custom symbols: built in the right pane, so the sheets stay open and scrollable beside it */
#customView { display: none; flex: 1; overflow-y: auto; padding: 8px 10px 14px; overscroll-behavior: contain; font-size: 13px; }
#symbols.customOn #customView { display: block; }
#symbols.customOn #symList, #symbols.customOn .symFoot, #symbols.customOn .symHead > :not(#paneView):not(#symTitleRow) { display: none; }
#symbols.customOn #paneView button.on { background: transparent; color: var(--muted); }
#layerBar.locked label { cursor: default; }
#layerBar.locked input:disabled:checked { opacity: .55; }
#customView h3 { margin: 14px 0 4px; font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 600; }
#customView .cuBox { background: var(--bg); border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; margin: 6px 0; }
#customView .cuRow { display: flex; align-items: center; gap: 8px; padding: 5px 0; border-top: 1px solid var(--line); }
#customView .cuRow:first-child { border-top: 0; }
#customView .cuRow input[type=text] { flex: 1; min-width: 0; background: var(--panel-2); color: var(--text); border: 1px solid var(--line); border-radius: 5px; padding: 3px 6px; font: inherit; font-size: 12px; }
#customView button { height: 26px; padding: 0 10px; font-size: 12px; background: var(--panel-2); color: var(--text); border: 1px solid var(--line); border-radius: 6px; }
#customView button:hover:not(:disabled) { background: var(--line); }
#customView button.go { background: var(--sel); color: var(--sel-tx); border-color: transparent; }
#customView button.warn { color: #ef6a5b; }
#customView .cuMuted { color: var(--muted); font-size: 12px; }
#customView canvas.cuThumb { background: #fff; border-radius: 4px; flex: none; }
#toolbar .tmax { font-size: 12px; color: var(--muted); white-space: nowrap; margin: 0 2px; }
#toolbar .tnum { width: 54px; height: 26px; background: var(--bg); color: var(--text); border: 1px solid var(--line); border-radius: 6px; padding: 0 6px; font: inherit; font-size: 12px; }
#patchView { display: none; flex: 1; overflow-y: auto; padding: 8px 10px 14px; overscroll-behavior: contain; }
#roomView { display: none; flex: 1; overflow-y: auto; padding: 6px; overscroll-behavior: contain; }
#symbols.roomsOn #roomView { display: block; }
#symbols.roomsOn #symList, #symbols.roomsOn .symFoot, #symbols.roomsOn .symHead > :not(#paneView):not(#symTitleRow) { display: none; }
.rlRow { display: flex; align-items: baseline; gap: 10px; width: 100%; text-align: left; padding: 6px 8px; margin: 0 0 2px; background: transparent; border: 1px solid transparent; border-radius: 6px; color: var(--text); cursor: pointer; font: inherit; }
.rlRow:hover { background: var(--bg); border-color: var(--line); }
.rlRow b { min-width: 58px; font-variant-numeric: tabular-nums; }
.rlRow span { flex: 1; color: var(--muted); }
.rlRow i { font-style: normal; color: var(--muted); }
.rlRow span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.rlRow .sh { flex: none; color: var(--dim); font-size: 11.5px; font-style: normal; }
.rlRow i.ro { flex: none; display: inline-flex; align-self: center; color: var(--muted); }
.rlRow i.ro svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
/* a room with no name is yellow, as on the drawing (the amber of an untagged room); a number used twice on the same floor is red (the drawing's red) */
.rlRow.unn { background: rgba(245,165,36,.10); border-color: rgba(245,165,36,.35); }
.rlRow.unn b, .rlRow.unn span { color: #f5a524; }
.rlRow.unn:hover { background: rgba(245,165,36,.18); }
.rlRow.dup { background: rgba(248,113,113,.12); border-color: rgba(248,113,113,.40); }
.rlRow.dup b, .rlRow.dup span, .rlRow.dup .sh { color: #f87171; }
.rlRow.dup:hover { background: rgba(248,113,113,.2); }
/* the combined sheet's list: the two tick boxes, and a sheet as a folding header */
.modeRow { position: sticky; top: -6px; z-index: 2; display: flex; align-items: center; gap: 18px; margin: -6px -6px 4px; padding: 10px 14px 8px; background: var(--bg); border-bottom: 1px solid var(--line); font-size: 12.5px; }   /* stays at the top while the list scrolls */
.modeRow label { display: flex; align-items: center; gap: 7px; cursor: pointer; user-select: none; }
.modeRow input { width: 14px; height: 14px; margin: 0; accent-color: var(--accent); cursor: pointer; }
.rlHead { display: flex; align-items: center; gap: 7px; width: 100%; padding: 6px 8px; margin: 6px 0 3px; background: var(--panel-2); border-radius: 6px; color: var(--text); font-weight: 600; font-size: 12.5px; cursor: pointer; text-align: left; }
.rlHead .arr { width: 12px; height: 12px; flex: none; transition: transform .12s; color: var(--muted); fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.rlHead.shut .arr { transform: rotate(-90deg); }
.rlHead .n { margin-left: auto; font-weight: 400; color: var(--muted); font-size: 12px; }
.rlHead:hover { background: var(--line); }
/* the Duplicates tab: every pair of sheets that found the same spot, with the sheet each symbol belongs to */
#paneView button { position: relative; white-space: nowrap; padding-left: 6px; padding-right: 6px; }
#paneView button[hidden] { display: none; }
#paneView .badge { position: absolute; top: -7px; right: -2px; min-width: 16px; height: 16px; line-height: 16px; padding: 0 5px; border-radius: 999px; background: var(--warn); color: #1a1405; font-size: 10.5px; font-weight: 700; font-style: normal; text-align: center; pointer-events: none; }
#paneView .badge:empty { display: none; }
#dupTab { display: none; flex: 1; min-height: 0; overflow-y: auto; padding: 10px; overscroll-behavior: contain; }
#dupFoot { display: none; flex: none; border-top: 1px solid var(--line); padding: 8px 10px; font-size: 12px; color: var(--muted); }
#dupFoot:empty { display: none !important; }
#symbols.dupsOn { width: 440px; max-width: 60vw; }
#symbols.dupsOn #dupTab, #symbols.dupsOn #dupFoot { display: block; }
#symbols.dupsOn #symList, #symbols.dupsOn .symFoot, #symbols.dupsOn .symHead > :not(#paneView):not(#symTitleRow) { display: none; }
#dupNote { font-size: 12px; margin: 0 0 10px; color: var(--muted); }
#dupNote:empty { display: none; }
#dupTab .chip { width: 10px; height: 10px; border-radius: 3px; flex: none; }
#dupTab button.bt { height: 24px; padding: 0 8px; font-size: 12px; background: var(--panel-2); color: var(--text); border-radius: 6px; border: 1px solid var(--line); cursor: pointer; }
#dupTab button.bt.on { background: var(--sel); color: var(--sel-tx); border-color: transparent; }
#dupTab button.bt:hover:not(.on) { border-color: var(--dim); }
#dupTab .dupGrp { border: 1px solid var(--line); border-radius: 8px; margin: 0 0 8px; overflow: hidden; }
#dupTab .dupGh { background: var(--panel-2); padding: 6px 8px; display: flex; flex-direction: column; gap: 5px; }
#dupTab .dupGt { display: flex; align-items: center; gap: 6px; font-weight: 600; font-size: 12.5px; cursor: pointer; user-select: none; }
#dupTab .dupGt .chev { width: 14px; height: 14px; transition: transform .12s; flex: none; opacity: .7; }
#dupTab .dupGrp.shut .dupGt .chev { transform: rotate(-90deg); }
#dupTab .dupGt .n { margin-left: auto; font-weight: 400; color: var(--muted); font-size: 12px; }
#dupTab .dupGa { display: flex; align-items: center; gap: 4px; font-size: 12px; flex-wrap: wrap; }
#dupTab .dupGa .st { margin-left: auto; color: var(--muted); font-size: 11.5px; }
#dupTab .dupGa .st.done { color: var(--ok); }
#dupTab .dupGrp.shut .dupBlocks { display: none; }
#dupTab .dupBh { background: color-mix(in srgb, var(--panel-2) 55%, transparent); padding: 5px 8px; display: flex; flex-direction: column; gap: 4px; border-top: 1px solid var(--line); }
#dupTab .dupBh .bt0 { font-weight: 600; font-size: 12px; display: flex; gap: 6px; align-items: baseline; }
#dupTab .dupBh .bt0 .n { color: var(--muted); font-weight: 400; }
#dupTab .dupBh.diff .bt0 { color: var(--warn); }
#dupTab .dupRows { padding: 2px 6px 4px; }
#dupTab .dupPickRow { display: flex; align-items: center; gap: 6px; padding: 4px 2px; font-size: 12.5px; border-top: 1px solid var(--line); }
#dupTab .dupPickRow:first-child { border-top: 0; }
#dupTab .dupWhat { cursor: pointer; min-width: 0; }
#dupTab .dupWhat small { display: block; color: var(--muted); font-size: 11px; }
#dupTab .dupBtns { margin-left: auto; display: flex; gap: 4px; flex: none; }
#symbols.patchOn { width: 520px; }
#symbols.patchOn #patchView { display: block; }
#symbols.patchOn #symList, #symbols.patchOn .symFoot, #symbols.patchOn .symHead > :not(#paneView):not(#symTitleRow) { display: none; }
#symTitleRow { flex-wrap: nowrap !important; }
.pvDetail { position: sticky; top: -8px; z-index: 2; margin: -8px -10px 8px; padding: 9px 12px; background: var(--panel); border-bottom: 1px solid var(--line); font-size: 12px; line-height: 1.45; height: 58px; overflow: hidden; }   /* one fixed height: hovering a port fills it in without moving the racks below */
.pvDetail .pvWhere { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pvDetail .pvLabel b { flex: none; }
.pvDetail .pvName { flex: 1 1 0; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 12px; color: var(--muted); }
.pvDetail .pvName::before { content: '·'; margin-right: 7px; }
.pvDetail .pvOn { flex: none; font-size: 12px; color: var(--muted); }
.pvDetail .pvLabel { display: flex; align-items: center; gap: 7px; font-size: 13px; }
.pvDetail .chip { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.pvIdf { margin: 0 0 16px; }
.pvHead { display: flex; align-items: center; gap: 10px; margin: 2px 2px 6px; }   /* the name line: the name, the summary (what wraps), Isolate devices, and the IDF's three dots, which never leave the line */
.pvHead b { font-size: 14px; white-space: nowrap; min-width: 0; overflow: hidden; text-overflow: ellipsis; }   /* a long IDF name shortens before the summary or the buttons do */
.pvHead .muted { flex: 1 1 0; min-width: 5em; font-size: 12px; line-height: 1.3; }
.pvHead .ic { flex: none; margin-right: -4px; }
.pvHead .nw { white-space: nowrap; }   /* "46 not configured" never breaks in the middle */
.pvIso { flex: none; white-space: nowrap; height: 24px; padding: 0 10px; font-size: 12px; background: var(--panel-2); color: var(--text); border-radius: 6px; }
.pvIso:hover { background: var(--line); }
.pvIso.on { background: var(--sel); color: var(--sel-tx); }
.pvRack { width: 100%; height: auto; display: block; border-radius: 6px; border: 1px solid var(--line); }
/* panels sit flush in one continuous rack: the rack's rounded ends and its top and bottom edge show only where the run starts or ends */
.pvPanel { position: relative; margin: 0; }
.pvPanel .pvRack { margin: 0; border-radius: 0; border-top-width: 0; border-bottom-width: 0; }
.pvPanel .pvRack.capT { border-radius: 6px 6px 0 0; border-top-width: 1px; }
.pvPanel .pvRack.capB { border-radius: 0 0 6px 6px; border-bottom-width: 1px; }
.pvPanel .pvRack.capT.capB { border-radius: 6px; }
/* the title and size are text in the app's own title font (system, 14 px, semibold), raised and stamped: a light edge above, a shadow below */
.pvPanel .ptitle, .pvPanel .psize { position: absolute; transform: translateY(-50%); white-space: nowrap; pointer-events: none; font-size: 14px; font-weight: 600; line-height: 1; color: #e6e7ec; text-shadow: 0 -1px 0 rgba(255,255,255,.24), 0 1px 0 rgba(0,0,0,.95); }
.pvPanel .psize { font-size: 11px; font-weight: 400; color: #9b9ba4; }
/* the steel's grain and sheen are laid OVER the lettering, so it reads as stamped into the panel rather than printed on top */
.pvPanel .tband { position: absolute; pointer-events: none; border-radius: 6px 6px 0 0; background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='60'><filter id='n' x='0' y='0' width='100%25' height='100%25'><feTurbulence type='fractalNoise' baseFrequency='1.15' numOctaves='2' seed='4'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .34 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>"), linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,0) 55%, rgba(0,0,0,.18)); }
/* the panel's three dots: sized with the drawing (larger than the title at 900 px, small enough at 440 px to sit between the panel's top edge and its port numbers) */
.pvPanel .dots { position: absolute; transform: translateY(-50%); color: var(--text); width: clamp(19px, 4.2%, 32px); height: auto; aspect-ratio: 1; }
.pvPanel .dots svg.i { width: 94%; height: 94%; }
.pvPanel .dots::after { content: ''; position: absolute; inset: -5px; }   /* the hit area stays a comfortable size when the drawn button is small */
.pvPanel .dots:disabled { opacity: .35; }
/* the steel strip under an IDF's last panel (tools/patch-rack.js strip): a short blank rack panel in the same black steel as the patch panels (ears, grooves, a screw at each end, grain over stamped lettering), no ports */
.lbar { position: relative; display: flex; flex-wrap: wrap; gap: 2px 10px; align-items: center; min-height: 26px; padding: 6px 6.6%; font-size: 12px; font-weight: 400; line-height: 1.3; color: var(--muted); border: 1px solid var(--line); border-top-width: 0; border-bottom-width: 0;   /* the same type as the IDF summary line above the rack */
  background:
    linear-gradient(90deg,#4a4d55 0,#8d919b 0.5%,#555861 1.05%) left / 1.05% 100% no-repeat,
    linear-gradient(90deg,#555861 0,#8d919b 0.5%,#4a4d55 1.05%) right / 1.05% 100% no-repeat,
    linear-gradient(90deg,transparent 4.6%,rgba(0,0,0,.8) 4.6% 4.85%,rgba(255,255,255,.12) 4.85% 5%,transparent 5% 95%,rgba(0,0,0,.8) 95% 95.15%,rgba(255,255,255,.12) 95.15% 95.4%,transparent 95.4%),
    linear-gradient(180deg,rgba(255,255,255,.28) 0,rgba(255,255,255,.28) 1px,transparent 1px,transparent calc(100% - 2px),rgba(0,0,0,.7) calc(100% - 2px)),
    linear-gradient(180deg,#34353b 0,#202126 6%,#121316 55%,#08080a 100%) padding-box; }
.lbar .scr { position: absolute; top: 50%; width: 2.63%; aspect-ratio: 1; transform: translateY(-44%); overflow: visible; pointer-events: none; }   /* the same screw drawing as the patch panel's, centred .325 of a rack unit from the edge */
.lbar .scr.l { left: .395%; }
.lbar .scr.r { right: .395%; }
.lbar span { white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 -1px 0 rgba(255,255,255,.24), 0 1px 0 rgba(0,0,0,.95); }
.lbar .chip { display: inline-block; flex: none; border-radius: 3px; width: 8px; height: 8px; margin-right: 4px; box-shadow: 0 0 0 1px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.4); }
.lbar .grain { position: absolute; inset: 0 1.05%; pointer-events: none; background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='60'><filter id='n' x='0' y='0' width='100%25' height='100%25'><feTurbulence type='fractalNoise' baseFrequency='1.15' numOctaves='2' seed='4'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .34 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>"), linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,0) 55%, rgba(0,0,0,.18)); }
.lcap { height: 6px; border: 1px solid var(--line); border-top-width: 0; border-radius: 0 0 6px 6px; background: linear-gradient(90deg,#4a4d55 0,#8d919b 1.7%,#555861 3.9%,#101114 3.9% 96.1%,#4a4d55 96.1%,#8d919b 98.3%,#555861 100%); }
/* ---- what the strip holds: the drops whose cable does not go on a patch panel, one line per symbol type, stacked. It runs flush into the panel above it and closes the rack;
   .lcap.top gives it a top edge of its own when nothing joins it from above (an IDF with no panels, or a setup area open above it). ---- */
.lbar.strip { flex-direction: column; flex-wrap: nowrap; align-items: flex-start; gap: 3px; padding-top: 8px; padding-bottom: 8px; }
.lbar.strip .ln { display: block; max-width: 100%; }   /* a group is one line of running text; one too long for the strip wraps at its spaces rather than being cut off (the color and the count never split) */
.lbar.strip .ln span { white-space: normal; max-width: none; overflow: visible; text-overflow: clip; }
.lbar.strip .ln .nw { white-space: nowrap; }
.lcap.top { border-top-width: 1px; border-bottom-width: 0; border-radius: 6px 6px 0 0; }
/* messages: the Help manual's note box, with the app's warn / ok tokens */
#patchView .imsg { margin: 0 0 8px; padding: 8px 12px; border-left: 3px solid var(--accent); background: var(--panel); border-radius: 0 8px 8px 0; font-size: 12px; line-height: 1.45; }
#patchView .imsg.warn { border-left-color: var(--warn); }
#patchView .msg { font-size: 12px; margin: 2px 0 6px; }
#patchView .msg.err { color: var(--bad); }
#patchView .msg.ok { color: var(--ok); }
/* the IDF options card and the open panel's setup */
#patchView { scroll-padding: 70px 0 12px; }
#patchView .idfopt { background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 8px 12px 10px; margin: 0 0 8px; }
#patchView .sh { display: flex; align-items: center; gap: 8px; min-height: 28px; margin-bottom: 6px; }
#patchView .sh b { font-size: 13px; white-space: nowrap; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
#patchView .sh .muted { flex: 1; min-width: 0; font-size: 12px; line-height: 1.35; }
#patchView .sh .ic { margin-right: -6px; }
#patchView .setup { margin: 6px 0 0; padding: 8px 4px 2px; border-top: 1px solid var(--line); }
#patchView .grp { margin: 0 0 10px; }
#patchView .gl { margin: 0 0 4px; font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
#patchView .sf { display: flex; gap: 8px; margin-top: 10px; }
#patchView .sf button { height: 26px; padding: 0 10px; font-size: 12px; background: var(--panel-2); color: var(--text); border-radius: 6px; }
#patchView .sf button:hover:not(:disabled) { background: var(--line); }
#patchView .sf button.warn { color: var(--bad); }
/* radio groups: native radios and checkboxes exactly as the app draws its own (no accent override), labels like the layer checkboxes (muted until ticked) */
#patchView .rad { display: flex; flex-wrap: wrap; gap: 4px 14px; }
#patchView .rad input { margin: 0; }
#patchView .rad label { display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none; color: var(--muted); }
#patchView .rad label:hover, #patchView .rad label:has(input:checked) { color: var(--text); }
#patchView .rad label.dis { opacity: .45; cursor: default; }
#patchView .rad label.dis:hover { color: var(--muted); }
#patchView .rad label.dis:has(input:checked) { color: var(--text); }
/* two-way toggles: the app's .seg, its buttons being labels over hidden radios */
#patchView .seg.fit { display: inline-flex; }
#patchView .seg label { position: relative; flex: 1; text-align: center; white-space: nowrap; border-radius: 6px; padding: 5px 12px; font-size: 12px; color: var(--muted); cursor: pointer; user-select: none; }
#patchView .seg label:hover { background: var(--hover); color: var(--text); }
#patchView .seg label:has(input:checked) { background: var(--sel); color: var(--sel-tx); }
#patchView .seg label:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: -2px; }
#patchView .seg label.dis { opacity: .35; cursor: default; }
#patchView .seg label.dis:hover { background: transparent; color: var(--muted); }
#patchView .seg label.dis:has(input:checked):hover { background: var(--sel); color: var(--sel-tx); }
#patchView .seg input { position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0; margin: 0; }
/* the range text box: the field the custom builder uses in this same right pane (panel-2, 5px corners, 12px text) */
#patchView .cust { width: 100%; height: 28px; margin: 6px 0 2px; padding: 3px 8px; background: var(--panel-2); color: var(--text); border: 1px solid var(--line); border-radius: 5px; font: inherit; font-size: 12px; }
#patchView .cust::placeholder { color: var(--dim); }
#patchView .cust:focus { outline: none; border-color: var(--accent); }
#patchView .cust.bad, #patchView .cust.bad:focus { border-color: var(--bad); }
#patchView .cust:disabled { opacity: .45; }
#patchView .lrow { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0 28px; }   /* the layout boxes and By Row / By Panel side by side; they stack when the pane is narrow */
/* section rows (like the custom builder's rows) */
#patchView .srow { display: grid; grid-template-columns: 84px 1fr; gap: 4px 12px; align-items: center; padding: 8px 0; border-top: 1px solid var(--line); }
#patchView .srow .sn { font-weight: 600; white-space: nowrap; }
#patchView .srow .sn span { display: block; font-weight: 400; font-size: 11px; color: var(--muted); }
#patchView .srow .use { grid-column: 1 / 3; font-size: 11px; color: var(--muted); }
#patchView .srow label.rm { grid-column: 1 / 3; font-size: 12px; color: var(--muted); }
#patchView .srow label.rm:has(input:checked) { color: var(--text); }
#patchView .srow label.rm:has(input:disabled) { cursor: default; }
#patchView .srow.locked { opacity: .55; }
#patchView .srow.locked .tsel:disabled { opacity: 1; }
/* the drop-type dropdown: a select-like button that opens the app's floating menu (.topMenu / .topDrop / .mi) */
#patchView .srow .topMenu { min-width: 0; max-width: 460px; }
#patchView .topMenu > .tsel { display: flex; align-items: center; gap: 6px; width: 100%; height: 28px; padding: 0 8px; background: var(--panel-2); color: var(--text); border: 1px solid var(--line); border-radius: 5px; font-size: 12px; text-align: left; }
#patchView .tsel:hover:not(:disabled) { border-color: var(--dim); background: var(--panel-2); color: var(--text); }
#patchView .tsel[aria-expanded="true"] { border-color: var(--accent); }
#patchView .tsel .lab { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#patchView .tsel .lab.ph { color: var(--muted); }
#patchView .tsel .chev, #patchView .tsel svg.i { width: 14px; height: 14px; margin-left: auto; opacity: .7; transition: transform .12s; }
#patchView .tsel svg.chev { width: 12px; height: 12px; }   /* the app's menu chevron is 12px */
#patchView .tsel[aria-expanded="true"] .chev { transform: rotate(180deg); }
#patchView .tsel .chip, #patchView .topDrop .chip { display: inline-block; width: 10px; height: 10px; border-radius: 3px; flex: none; }
#patchView .srow .topDrop { left: auto; right: 0; min-width: 100%; width: max-content; max-width: min(340px, calc(100% + 96px)); max-height: min(300px, 50vh); overflow-y: auto; overscroll-behavior: contain; }
#patchView .topDrop label.mi { border-radius: 5px; cursor: pointer; user-select: none; font-size: 13px; }
#patchView .topDrop label.mi .nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
#patchView .topDrop label.mi .n { margin-left: auto; padding-left: 10px; font-size: 11px; color: var(--muted); }
#patchView .topDrop label.mi.on .n { color: var(--sel-tx); opacity: .75; }
#patchView .topDrop label.mi.dis { opacity: .45; cursor: default; }
#patchView .topDrop label.mi.dis:hover { background: transparent; }
/* the open panel: blue outline round it and its setup, the others dimmed */
#patchView .pwrap { border: 0 solid transparent; border-width: 0 2px; border-radius: 12px; padding: 0; margin: 0; transition: opacity .15s; }
#patchView .pwrap.open { border-width: 2px; border-color: var(--accent); padding: 6px; margin: 6px 0 12px; background: color-mix(in srgb, var(--accent) 6%, transparent); }
#patchView .pwrap.dim { opacity: .45; }
.pvPort.has { cursor: pointer; }
.pvPort.has:hover .jack, .pvPort.hov .jack { stroke: #fff; stroke-width: 0.07; }
.pvPort.sel .jack { stroke: #ff5a5a; stroke-width: 0.1; }
.symEmpty { color: var(--muted); text-align: center; padding: 28px 12px; font-size: 13px; }
/* A submenu: a menu item with an arrow opens its own list beside it (on roll over, with the keyboard, or with a click). It stays open while the pointer or the cursor is inside it. */
.sub { position: relative; }
.sub > .subBtn { display: flex; align-items: center; width: 100%; }
.sub > .subBtn .arr { margin-left: auto; padding-left: 14px; color: var(--muted); }
.sub > .fly { display: none; position: absolute; left: 100%; top: -5px; margin-left: -2px; min-width: 230px; z-index: 51; flex-direction: column; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 4px; box-shadow: 0 8px 24px rgba(0,0,0,.45); }
.sub:hover > .fly, .sub:focus-within > .fly, .sub.open > .fly { display: flex; }
.sub:hover > .subBtn, .sub.open > .subBtn { background: var(--hover); color: var(--text); }
.fly hr.mh, #fileDrop hr.mh { border: 0; border-top: 1px solid var(--line); margin: 4px 2px; width: auto; }
.fly .setRow { display: flex; align-items: center; gap: 8px; padding: 6px 10px; font-size: 13px; color: var(--text); white-space: nowrap; }
.fly label.setRow { cursor: pointer; user-select: none; }
.fly .setRow input[type=number] { width: 56px; background: var(--bg); color: var(--text); border: 1px solid var(--line); border-radius: 4px; padding: 1px 4px; font-size: 13px; }
.fly .setRow input[type=checkbox] { width: 14px; height: 14px; margin: 0; accent-color: var(--accent); cursor: pointer; }
.fly .setRow .unit { color: var(--muted); }
/* the tick box above the symbol list: all on, all off, or a dash when only some are on */
.symAll { display: flex; align-items: center; gap: 8px; height: 26px; margin: 0 0 4px; padding: 0 0 0 12px; font-size: 12.5px; color: var(--text); user-select: none; }
.symAll label { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.symAll input { width: 14px; height: 14px; margin: 0; accent-color: var(--accent); cursor: pointer; }
.symAll .cnt { margin-left: auto; padding-right: 14px; font-size: 11.5px; color: var(--muted); }
/* The symbol list: one line per symbol type. Tick box, small picture (white shape on black, thin border in the row's color), description, count on the sheet; the color down both ends. */
.symRow { --c: #888; display: flex; gap: 8px; align-items: center; margin: 0 0 3px; padding: 0 0 0 7px; height: 30px; background: var(--panel); border: 1px solid var(--line); border-left: 4px solid var(--c); border-right: 4px solid var(--c); border-radius: 5px; cursor: pointer; overflow: hidden; }
.symRow:hover { background: var(--hover); }
.symRow.sel { background: var(--sel); }
.symRow.off { opacity: .5; }
.symRow canvas.thumb { box-sizing: content-box; border: 1px solid var(--c); border-radius: 3px; flex: none; }
.symRow .name, .symRow .lbl { flex: 1; min-width: 0; color: #fff; font: inherit; font-size: 13px; font-weight: 500; }
.symRow .name { padding: 2px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.symRow .name.unnamed { color: var(--muted); font-style: italic; font-weight: 400; }
.symRow .lbl { background: var(--bg); border: 1px solid var(--accent); border-radius: 4px; padding: 1px 4px; outline: none; }
.symRow .cntCell { flex: none; min-width: 34px; padding: 0 8px 0 2px; text-align: right; color: #fff; font-weight: 600; font-size: 13px; }
.symRow .vis { flex: none; display: flex; align-items: center; cursor: pointer; }
.symRow .vis input { width: 14px; height: 14px; margin: 0; accent-color: var(--accent); cursor: pointer; }
/* What a description says in full when the line cut it off with "…" (the symbol list shows it on roll over) */
#symTip { position: fixed; z-index: 30; pointer-events: none; max-width: 300px; background: rgba(15,15,18,.96); color: var(--text); border: 1px solid var(--line); border-radius: 6px; padding: 4px 8px; font-size: 12px; line-height: 1.4; box-shadow: 0 6px 20px rgba(0,0,0,.5); }
.symFoot { border-top: 1px solid var(--line); padding: 8px 12px; font-size: 12px; color: var(--muted); display: flex; flex-direction: column; gap: 5px; }
.symFoot label { display: flex; align-items: center; gap: 6px; }
.symFoot { display: none; }                                  /* the two export checkboxes: Export is parked, hidden until it has a new home */
#status { font-size: 12px; color: var(--muted); padding: 4px 14px; background: var(--bar); border-top: 1px solid var(--line); min-height: 26px; }
.pane[data-pane="clean"] { display: none !important; }   /* the Clean section is gone: gray removal, hold for original, remove color by pixel */
.topMenu { position: relative; }
.topMenu > button { padding: 4px 9px; font-size: 13px; display: inline-flex; align-items: center; gap: 6px; }
.topDrop { position: absolute; left: 0; top: 100%; margin-top: 4px; z-index: 50; min-width: 250px; display: flex; flex-direction: column; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 4px; box-shadow: 0 8px 24px rgba(0,0,0,.45); }
.topDrop[hidden] { display: none; }
.topDrop .mi { width: 100%; height: auto; justify-content: flex-start; gap: 10px; padding: 7px 10px; color: var(--text); white-space: nowrap; }
.topDrop .mi[hidden] { display: none; }
.topDrop .mi .ml { display: inline; font-size: 13px; }
.topDrop .mi.on { background: var(--sel); color: var(--sel-tx); }
.ml { display: none; }
#toolbar .tbMenu > .menuBtn { padding: 0 9px; }
#toolbar .tbMenu .chev { width: 12px; height: 12px; margin-left: 6px; opacity: .7; }
#toolbar .topDrop { min-width: 230px; }
#toolbar .topDrop .ti { width: 100%; height: auto; justify-content: flex-start; gap: 10px; padding: 7px 10px; color: var(--text); white-space: nowrap; }
#toolbar .topDrop .ti .bl { max-width: none; opacity: 1; margin-left: 0; font-size: 13px; }
#toolbar .topDrop .ti:disabled { opacity: .45; }
#toolbar .topDrop hr.mh { border: 0; border-top: 1px solid var(--line); margin: 3px 0; width: 100%; }
#toolbar .topDrop .limRow { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; padding: 6px 10px; }
#toolbar .topDrop .limRow { display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; }
#toolbar .topDrop .limRow .tmax { margin: 0; }
#toolbar .topDrop .limRow .tmax:first-child { min-width: 78px; }

/* ---- Help: the manual with search (tools/help.js; the text is help/help.html) ---- */
#helpDlg { background: var(--panel); color: var(--text); border: 1px solid var(--line); border-radius: 12px; padding: 0; width: min(1120px, 96vw); height: min(86vh, 900px); }
#helpDlg[open] { display: flex; flex-direction: column; }
#helpDlg::backdrop { background: rgba(0,0,0,.55); }
#helpDlg .hpHead { flex: none; display: flex; align-items: center; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--line); background: var(--bar); border-radius: 12px 12px 0 0; }
#helpDlg .hpHead b { font-size: 14px; white-space: nowrap; }
#helpSearch { flex: 1; min-width: 120px; background: var(--bg); color: var(--text); border: 1px solid var(--line); border-radius: 8px; padding: 7px 11px; font: inherit; font-size: 14px; }
#helpSearch:focus { outline: none; border-color: var(--accent); }
#helpCount { font-size: 12px; white-space: nowrap; }
#helpDlg .hpMain { flex: 1; min-height: 0; display: flex; }
#helpNav { flex: none; width: 290px; overflow-y: auto; border-right: 1px solid var(--line); padding: 8px 6px 16px; background: var(--bar); font-size: 12.5px; overscroll-behavior: contain; }
#helpNav .hnGroup { margin: 12px 8px 4px; color: var(--dim); font-size: 10.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
#helpNav a { display: block; padding: 4px 8px; border-radius: 6px; color: var(--text); text-decoration: none; line-height: 1.3; }
#helpNav a:hover { background: var(--hover); }
#helpNav a.on { background: var(--sel); color: var(--sel-tx); }
#helpNav a.hnRes { padding: 7px 8px; border-bottom: 1px solid var(--line); border-radius: 0; }
#helpNav .hnWhere { display: block; font-size: 10.5px; color: var(--dim); margin: 1px 0 2px; }
#helpNav .hnSnip { display: block; color: var(--muted); font-size: 11.5px; line-height: 1.35; }
#helpNav mark, #helpBody mark.hl { background: rgba(232, 168, 56, .35); color: inherit; border-radius: 2px; padding: 0 1px; }
#helpBody { flex: 1; min-width: 0; overflow-y: auto; padding: 4px 26px 40px; font-size: 14px; line-height: 1.6; overscroll-behavior: contain; scroll-behavior: auto; }
#helpBody:focus { outline: none; }
#helpBody h2.hpGroup { margin: 34px 0 6px; padding-bottom: 6px; border-bottom: 1px solid var(--line); font-size: 12px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--accent); }
#helpBody section { margin: 20px 0 0; padding: 14px 16px 6px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg); scroll-margin-top: 8px; }
#helpBody section.flash { animation: hpFlash 1.4s ease-out; }
@keyframes hpFlash { 0% { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(74,141,247,.35); } 100% { border-color: var(--line); box-shadow: none; } }
#helpBody section[hidden] { display: none; }
#helpBody h3 { margin: 0 0 8px; font-size: 17px; font-weight: 650; }
#helpBody h4 { margin: 16px 0 4px; font-size: 13px; font-weight: 650; color: var(--sel-tx); }
#helpBody p { margin: 8px 0; }
#helpBody ul, #helpBody ol { margin: 8px 0; padding-left: 22px; }
#helpBody li { margin: 3px 0; }
#helpBody a { color: var(--accent); text-decoration: none; }
#helpBody a:hover { text-decoration: underline; }
#helpBody kbd { font: 600 11.5px ui-monospace, Menlo, monospace; background: var(--panel-2); border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 5px; padding: 1px 6px; white-space: nowrap; }
#helpBody code { font: 12.5px ui-monospace, Menlo, monospace; background: var(--panel-2); border-radius: 4px; padding: 1px 5px; }
#helpBody table { border-collapse: collapse; margin: 10px 0; font-size: 13px; width: 100%; }
#helpBody th, #helpBody td { text-align: left; vertical-align: top; padding: 5px 10px; border: 1px solid var(--line); }
#helpBody th { background: var(--panel-2); font-weight: 600; }
#helpBody .tip, #helpBody .note, #helpBody .warn { margin: 10px 0; padding: 8px 12px; border-left: 3px solid var(--accent); background: var(--panel); border-radius: 0 8px 8px 0; font-size: 13px; }
#helpBody .tip { border-left-color: var(--ok); }
#helpBody .warn { border-left-color: var(--warn); }
#helpBody .hpNote, #helpBody .hpEmpty { margin: 24px 0; color: var(--muted); }
#helpBody .hpNote { margin: 14px 0 0; font-size: 12.5px; }
@media (max-width: 760px) { #helpNav { width: 190px; } #helpBody { padding: 4px 14px 30px; } }
#helpNav #helpMore { display: block; width: calc(100% - 16px); margin: 10px 8px; padding: 7px; background: var(--panel-2); color: var(--text); border: 1px solid var(--line); border-radius: 8px; cursor: pointer; font: inherit; font-size: 12px; }
#helpNav #helpMore:hover { background: var(--hover); }

/* ---- cable types and colors: the Cable Specs table and the two list editors (tools/cable-specs-ui.js, tools/cable-editors.js) ---- */
.cableDlg { background: var(--panel); color: var(--text); border: 1px solid var(--line); border-radius: 12px; padding: 0; width: min(980px, 96vw); max-height: 88vh; }
.cableDlg[open] { display: flex; flex-direction: column; }
.cableDlg::backdrop { background: rgba(0,0,0,.55); }
#colorsDlg { width: min(640px, 96vw); }
#typesDlg { width: calc(100vw - 32px); max-width: none; max-height: calc(100vh - 32px); }   /* the Edit Cable Types window uses the whole window width (and height), the table spreads across it */
.cableDlg .pickHead .row { justify-content: space-between; }
.cableDlg .cBody { flex: 1; overflow: auto; padding: 0 16px 14px; min-height: 160px; overscroll-behavior: contain; }
.cableDlg .cBody > :first-child { margin-top: 10px; }
.cableDlg .sub { color: var(--muted); font-size: 12px; margin: 0; line-height: 1.45; }
.cableDlg .sub b { color: var(--text); font-weight: 600; }
.cableDlg .imsg { margin: 0; padding: 8px 12px; border-left: 3px solid var(--accent); background: var(--bg); border-radius: 0 8px 8px 0; font-size: 12px; line-height: 1.45; }
.cableDlg .imsg.warn { border-left-color: var(--warn); }
.cableDlg .msg { font-size: 12px; margin: 0 0 8px; }
.cableDlg .msg.err { color: var(--bad); }
.cableDlg .cMsg { margin: 8px 16px 0; padding: 6px 10px; border-left: 3px solid var(--bad); background: var(--bg); border-radius: 0 6px 6px 0; }   /* a refused change: between the header and the scrolling list, always in view */
.cableDlg .cBody:focus { outline: none; }
.cableDlg .grid { display: grid; gap: 8px 10px; align-items: center; }
.cableDlg .specHead, .cableDlg .specRow { grid-template-columns: 22px minmax(130px,1.4fr) 54px minmax(160px,1.6fr) minmax(130px,1fr); }
.cableDlg .specHead { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--dim); padding: 0 0 6px; }
.cableDlg .specRow { padding: 6px 0; border-top: 1px solid var(--line); }
.cableDlg .specRow .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cableDlg .catRow { margin-top: 10px; padding: 5px 2px; font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--accent); border-top: 1px solid var(--line); }
.cableDlg .catRow:first-of-type { margin-top: 0; }
.cableDlg .sw, .cableDlg .chip { display: inline-block; width: 12px; height: 12px; border-radius: 3px; flex: none; box-shadow: 0 0 0 1px rgba(255,255,255,.28), inset 0 1px 0 rgba(255,255,255,.3); vertical-align: -2px; }
.cableDlg .chip { width: 10px; height: 10px; }
/* the two pickers: a select-like button that opens the app's floating menu (.topMenu / .topDrop / .mi), flipped above its button when there is no room below */
.cableDlg .topMenu.pick { position: relative; min-width: 0; }
.cableDlg .topMenu.pick > .tsel { display: flex; align-items: center; gap: 6px; width: 100%; height: 28px; padding: 0 8px; background: var(--panel-2); color: var(--text); border: 1px solid var(--line); border-radius: 5px; font: inherit; font-size: 12px; text-align: left; cursor: pointer; }
.cableDlg .tsel:hover:not(:disabled) { border-color: var(--dim); background: var(--panel-2); color: var(--text); }
.cableDlg .tsel[aria-expanded="true"] { border-color: var(--accent); }
.cableDlg .tsel .lab { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cableDlg .tsel .lab.ph { color: var(--muted); }
.cableDlg .tsel svg.chev { width: 12px; height: 12px; margin-left: auto; opacity: .7; transition: transform .12s; flex: none; }   /* the app's menu chevron is 12px */
.cableDlg .tsel[aria-expanded="true"] svg.chev { transform: rotate(180deg); }
.cableDlg .topDrop.pickDrop { position: fixed; z-index: 1000; margin: 0; width: max-content; max-width: 340px; overflow-y: auto; overscroll-behavior: contain; min-width: 150px; }
.cableDlg .topDrop .mi { display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 10px; border-radius: 5px; cursor: pointer; font-size: 12.5px; text-align: left; background: transparent; border: 0; color: var(--text); height: auto; }
.cableDlg .topDrop .mi:hover { background: var(--panel-2); }
.cableDlg .topDrop .mi.on { background: var(--sel); color: var(--sel-tx); }
.cableDlg .topDrop .mi.hd { font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--dim); padding: 7px 10px 2px; cursor: default; pointer-events: none; }
.cableDlg .topDrop .mi.act { color: var(--sel-tx); border-top: 1px solid var(--line); border-radius: 0 0 5px 5px; margin-top: 3px; padding-top: 8px; }
.cableDlg .topDrop .mi .n { margin-left: auto; padding-left: 10px; font-size: 11px; color: var(--muted); }
.cableDlg .topDrop .mi.on .n { color: var(--sel-tx); opacity: .75; }
.cableDlg .topDrop .mi.lastu { font-weight: 600; border-bottom: 1px solid var(--line); border-radius: 5px 5px 0 0; margin-bottom: 3px; padding-bottom: 8px; }   /* "Last Used: <name>", first in the list */
/* click and hold on a picker takes the last type / color picked (tools/cable-specs-ui.js, HOLD_MS): it fills left to right while held (the .45s must match HOLD_MS), then flashes once */
.cableDlg .topMenu.pick > .tsel { user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.cableDlg .topMenu.pick > .tsel.holding { background-image: linear-gradient(color-mix(in srgb, var(--accent) 38%, transparent), color-mix(in srgb, var(--accent) 38%, transparent)); background-repeat: no-repeat; background-size: 0% 100%; animation: holdfill .45s linear forwards; }
@keyframes holdfill { to { background-size: 100% 100%; } }
.cableDlg .topMenu.pick > .tsel.flash { animation: holdflash .8s ease-out; }
@keyframes holdflash { 0% { box-shadow: 0 0 0 2px var(--accent); } 100% { box-shadow: 0 0 0 0 transparent; } }
/* the list editors */
.cableDlg .fld { background: var(--panel-2); color: var(--text); border: 1px solid var(--line); border-radius: 5px; padding: 0 8px; height: 26px; font: inherit; font-size: 12px; width: 100%; }
.cableDlg .fld:focus { outline: none; border-color: var(--accent); }
.cableDlg input[type=color] { width: 30px; height: 26px; padding: 0; border: 1px solid var(--line); border-radius: 5px; background: var(--panel-2); }
.cableDlg .btn { background: var(--panel-2); color: var(--text); border: 1px solid var(--line); border-radius: 6px; padding: 4px 10px; font: inherit; font-size: 12px; cursor: pointer; }
.cableDlg .btn:hover:not(:disabled) { background: var(--line); }
.cableDlg .btn:disabled { opacity: .4; cursor: default; }
.cableDlg .btn.pri { background: var(--sel); color: var(--sel-tx); border-color: var(--accent); }
.cableDlg .addRow { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; padding: 10px; background: var(--bg); border: 1px solid var(--line); border-radius: 8px; margin: 0 0 12px; }
.cableDlg .addRow .fld { width: auto; flex: 1 1 140px; }
.cableDlg .addRow select.fld { flex: 0 0 150px; }
.cableDlg .addRow input[type=color] { width: 36px; height: 28px; }
.cableDlg .addRow label { display: flex; gap: 5px; align-items: center; font-size: 12px; }
.cableDlg .catAdd { display: inline-flex; gap: 6px; align-items: center; }
.cableDlg kbd { font: inherit; font-size: 11px; border: 1px solid var(--line); border-radius: 4px; padding: 0 4px; }
.cableDlg table.t { border-collapse: collapse; width: 100%; font-size: 12.5px; }
.cableDlg table.t th { text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--dim); font-weight: 600; padding: 4px 5px 6px; border-bottom: 1px solid var(--line); white-space: normal; vertical-align: bottom; position: sticky; top: 0; background: var(--panel); z-index: 2; }
.cableDlg table.t td { padding: 5px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.cableDlg table.t td.r, .cableDlg table.t th.r { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cableDlg table.t tr.ret td { opacity: .55; }
.cableDlg table.t tr.gh td { background: var(--bar); font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--accent); padding: 5px 8px; }
.cableDlg table.t input[type=number].fld { width: 64px; }
/* the Device Groups window (tools/device-groups-ui.js): the Inputs list is checkable (a label per type), the two pickers are plain selects */
#groupsDlg { width: min(1100px, 96vw); }
#groupsDlg table.t td { vertical-align: top; }
#groupsDlg table.t td:first-child { min-width: 170px; }   /* the Name box keeps its room when the window is narrow */
#groupsDlg table.t select.fld { width: auto; min-width: 140px; height: 28px; }
#groupsDlg .topMenu.pick { min-width: 220px; }
#groupsDlg .topDrop label.mi { gap: 8px; }
#groupsDlg .topDrop label.mi input { margin: 0; }
#groupsDlg .topDrop label.mi .nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
#groupsDlg .topDrop label.mi.dis { opacity: .45; cursor: default; }
#groupsDlg .topDrop label.mi.dis:hover { background: transparent; }
/* the Cable Length window's "By IDF and panel" section: one table per root under the main one */
#cableLenDlg .cSect { margin: 18px 0 6px; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--accent); border-top: 1px solid var(--line); padding-top: 10px; }
#cableLenDlg .cRoot { margin: 12px 0 4px; font-size: 13px; }
#cableLenDlg .cRoot .muted { font-size: 12px; }
#typesDlg table.t { min-width: 960px; }
#typesDlg .nameFld { min-width: 175px; } #typesDlg th.pp { min-width: 92px; }
#typesDlg .btn { padding: 3px 7px; }
#typesListDlg { width: min(560px, 96vw); }
#typesListDlg table.t { min-width: 0; }
#typesListDlg .nameFld { min-width: 220px; }
#colorsDlg table.t { min-width: 480px; }

/* ---- cable types and colors: the pieces the three editors and Bulk Edit share (tools/cable-editors.js, tools/cable-specs-ui.js, tools/cable-color-picker.js) ---- */
/* .cFix: the part of a window that does not scroll (the Add row, the Move Types / Bulk Edit row or bar); only .cBody under it scrolls. A drop-down in it opens over the list. */
.cableDlg .cFix { flex: none; position: relative; z-index: 5; padding: 12px 16px 0; }
.cableDlg .cFix:empty { display: none; }
.cableDlg .cFix > :last-child { margin-bottom: 10px; }
.cableDlg .cFix .addRow { margin: 0 0 10px; }
/* the table's head stays put while the list scrolls: the column names, and in Bulk Edit the Apply To Selected row under them */
.cableDlg table.t.stk thead { position: sticky; top: 0; z-index: 3; }
.cableDlg table.t.stk thead th { position: static; }
.cableDlg table.t.stk thead th, .cableDlg table.t.stk .bulkRow td { background: var(--panel); }
.cableDlg th label.hk { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; text-transform: inherit; letter-spacing: inherit; font: inherit; color: inherit; }
.cableDlg table.t th.ctr, .cableDlg table.t td.ctr { text-align: center; }
/* Bulk Edit: a bar with Apply and Cancel; Cable Specs adds a second row of two fields, each with its own tick box */
.cableDlg .bulkTop { display: flex; justify-content: flex-end; margin: 0 0 10px; }
.cableDlg .bulkBar { display: flex; flex-wrap: wrap; gap: 10px 18px; align-items: center; padding: 10px 12px; background: var(--bg); border: 1px solid var(--accent); border-radius: 8px; margin: 0 0 10px; }
.cableDlg .bulkBar .brow { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: 10px 18px; align-items: center; }
.cableDlg .bulkBar .bfTop { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; }
.cableDlg .bulkBar .bf { display: flex; align-items: center; gap: 8px; min-width: 250px; }
.cableDlg .bulkBar .bf > label { display: flex; align-items: center; gap: 6px; font-size: 12px; white-space: nowrap; cursor: pointer; }
.cableDlg .bulkBar .bf .topMenu { flex: 1; min-width: 150px; }
.cableDlg .bulkBar .bf.off .topMenu { opacity: .45; }
/* Edit Cable Types, Bulk Edit: the first row of the table, one choice under each ticked column */
.cableDlg .bulkRow td { background: color-mix(in srgb, var(--accent) 9%, var(--panel)); border-top: 1px solid var(--accent); border-bottom: 1px solid var(--accent); padding: 6px 5px; }
.cableDlg .bulkRow td.off > * { opacity: .45; }
.cableDlg .bulkRow td.bl { font-size: 12px; font-weight: 600; white-space: nowrap; }
.cableDlg .bulkRow .fld { width: 100%; }
/* Cable Specs in Bulk Edit: a tick box before every row, and in each category heading */
.cableDlg .specRow.bulk, .cableDlg .specHead.bulk { grid-template-columns: 24px 22px minmax(130px,1.4fr) 54px minmax(160px,1.6fr) minmax(130px,1fr); }
.cableDlg .chk { display: flex; align-items: center; justify-content: center; }
.cableDlg .catRow label { display: flex; align-items: center; gap: 8px; cursor: pointer; }
/* a row that was just added: it flashes once */
@keyframes newrow { 0% { background: color-mix(in srgb, var(--accent) 30%, transparent); } 100% { background: transparent; } }
.cableDlg tr.newrow td { animation: newrow 1.4s ease-out; }
/* Add A Cable Color: the swatch drop-down (the 16 most used colors, or the site's own color picker under Custom…) */
.cableDlg .topMenu.cpick { position: relative; flex: none; }
.cableDlg .topMenu.cpick > .tsel { width: 58px; height: 30px; padding: 0 8px; display: flex; align-items: center; justify-content: space-between; gap: 6px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px; cursor: pointer; font: inherit; color: var(--text); }
.cableDlg .topMenu.cpick > .tsel[aria-expanded="true"] { border-color: var(--accent); }
.cableDlg .topMenu.cpick > .tsel .sw { width: 22px; height: 18px; border-radius: 4px; }
.cableDlg .topMenu.cpick > .tsel svg.chev { width: 12px; height: 12px; margin-left: 0; opacity: .7; transition: transform .12s; flex: none; }
.cableDlg .topMenu.cpick > .tsel[aria-expanded="true"] svg.chev { transform: rotate(180deg); }
.cableDlg .topMenu.cpick .topDrop { position: absolute; top: calc(100% + 4px); left: 0; right: auto; width: max-content; min-width: 0; padding: 8px; z-index: 40; }
.cableDlg .cgrid { display: grid; grid-template-columns: repeat(4, 34px); gap: 6px; }
.cableDlg .cgrid .cs { width: 34px; height: 34px; border-radius: 7px; border: 1px solid rgba(255,255,255,.28); padding: 0; cursor: pointer; }
.cableDlg .cgrid .cs:hover { outline: 2px solid var(--dim); }
.cableDlg .cgrid .cs.on { outline: 2px solid var(--accent); outline-offset: 1px; }
.cableDlg .topMenu.cpick .topDrop .mi.act { margin-top: 8px; width: 100%; }
.cableDlg .cp { width: 216px; display: flex; flex-direction: column; gap: 10px; }
.cableDlg .cpsv { position: relative; height: 148px; border-radius: 8px; cursor: crosshair; touch-action: none; border: 1px solid var(--line); background-image: linear-gradient(to top, #000, rgba(0,0,0,0)), linear-gradient(to right, #fff, rgba(255,255,255,0)); }
.cableDlg .cph { position: relative; height: 14px; border-radius: 7px; cursor: pointer; touch-action: none; border: 1px solid var(--line); background: linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00); }
.cableDlg .cpt { position: absolute; width: 16px; height: 16px; border-radius: 50%; border: 2px solid #fff; box-shadow: 0 0 0 1px rgba(0,0,0,.55), 0 1px 4px rgba(0,0,0,.5); transform: translate(-50%, -50%); pointer-events: none; }
.cableDlg .cph .cpt { top: 50%; }
.cableDlg .cprow { display: flex; align-items: center; gap: 8px; }
.cableDlg .cprow .sw { width: 26px; height: 26px; border-radius: 6px; flex: none; }
.cableDlg .cprow .fld { width: 86px; flex: none; font-variant-numeric: tabular-nums; text-transform: lowercase; }
.cableDlg .cpbtns { display: flex; gap: 8px; justify-content: flex-end; }
.cableDlg .cpbtns .btn { height: 28px; }

/* ---- cable types and colors: the Cable Length window (tools/cable-length-ui.js) ---- */
/* the totals table: a line with no cable type is muted, the last line adds them up */
#cableLenDlg table.t { margin-top: 0; }
#cableLenDlg table.t tr.ns td { color: var(--muted); }
#cableLenDlg table.t tr.tot td { font-weight: 600; border-top: 2px solid var(--line); border-bottom: 0; }
