/* Harness — styles. Tokens first, then layout, then canvas drawing. */
:root {
  --bg: #f4f6f9; --panel: #ffffff; --panel-2: #f8f9fb; --line: #e1e5eb; --line-2: #cfd5de;
  --text: #1c2330; --text-2: #5b6574; --text-3: #8a93a1;
  --accent: #2f5bd8; --accent-2: #e8eefc; --accent-text: #fff;
  --ok: #1f9d55; --warn: #c97a0a; --err: #d23a3a; --info: #5b6b85;
  --canvas: #fbfcfd; --grid: #d3d9e2; --node: #ffffff; --node-line: #4a5466; --node-head: #eef1f6; --node-text: #1c2330;
  --sel: #2f5bd8; --sel-glow: rgba(47, 91, 216, .28); --net-glow: rgba(255, 170, 0, .35);
  --bundle: #3b4250; --shadow: 0 6px 24px rgba(20, 30, 50, .14);
  --radius: 8px; --font: system-ui, -apple-system, "Segoe UI", Roboto, Inter, sans-serif; --mono: ui-monospace, SFMono-Regular, Menlo, monospace;
  color-scheme: light;
}
:root[data-theme="dark"] {
  --bg: #12151b; --panel: #1a1e26; --panel-2: #20252e; --line: #2b313c; --line-2: #3a4250;
  --text: #e4e8ef; --text-2: #a3acba; --text-3: #707a89;
  --accent: #5b82ff; --accent-2: #233055; --accent-text: #fff;
  --canvas: #161a21; --grid: #2c333f; --node: #1f242d; --node-line: #9aa5b8; --node-head: #2a303b; --node-text: #e4e8ef;
  --sel: #6d90ff; --sel-glow: rgba(109, 144, 255, .35); --bundle: #aeb7c6; --shadow: 0 8px 30px rgba(0, 0, 0, .5);
  color-scheme: dark;
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--text); font: 13px/1.4 var(--font); }
body.editing { overflow: hidden; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
button { font: inherit; color: inherit; }
kbd { font: 11px var(--mono); background: var(--panel-2); border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 4px; padding: 0 4px; }
.muted { color: var(--text-3); }
.small { font-size: 11.5px; }
.sp { flex: 1; }
.err { color: var(--err); }
.warn { color: var(--warn); }
.hidden { display: none !important; }
.loading { display: grid; place-items: center; height: 100vh; color: var(--text-3); }
.empty { padding: 28px; text-align: center; color: var(--text-3); }

/* ---------- controls ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 32px; padding: 0 14px; border-radius: 7px; border: 1px solid var(--line-2); background: var(--panel); cursor: pointer; white-space: nowrap; transition: background .12s, border-color .12s; }
.btn:hover:not(:disabled) { background: var(--panel-2); border-color: var(--text-3); }
.btn:disabled { opacity: .5; cursor: default; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }
.btn.primary:hover:not(:disabled) { filter: brightness(1.08); background: var(--accent); }
.btn.danger { color: var(--err); border-color: color-mix(in srgb, var(--err) 40%, var(--line)); }
.btn.sm { height: 26px; padding: 0 10px; font-size: 12px; }
.btn.wide { width: 100%; }
.icon-btn { display: inline-grid; place-items: center; min-width: 30px; height: 30px; border: 0; background: transparent; border-radius: 7px; cursor: pointer; color: var(--text-2); }
.icon-btn:hover:not(:disabled) { background: var(--panel-2); color: var(--text); }
.icon-btn:disabled { opacity: .35; cursor: default; }
.icon-btn.on { background: var(--accent-2); color: var(--accent); }
.icon-btn.xs { min-width: 20px; height: 20px; font-size: 11px; }
.inp { height: 30px; width: 100%; padding: 0 8px; border: 1px solid var(--line-2); border-radius: 6px; background: var(--panel); color: var(--text); font: inherit; min-width: 0; }
textarea.inp { height: auto; padding: 6px 8px; resize: vertical; }
.inp:focus { outline: 2px solid var(--sel-glow); border-color: var(--accent); }
.inp.xs { height: 24px; font-size: 12px; padding: 0 5px; }
.inp:disabled, .inp[readonly] { background: var(--panel-2); color: var(--text-3); }
.field { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.field > span { font-size: 11px; color: var(--text-2); font-weight: 500; }
.field.check { flex-direction: row; align-items: center; gap: 6px; font-size: 12.5px; }
.field.wide, .form-grid .wide { grid-column: 1 / -1; }
.pair { display: flex; gap: 4px; }
.pair .unit { width: 74px; flex: none; }
.hint { display: inline-grid; place-items: center; width: 13px; height: 13px; border-radius: 50%; background: var(--line); font-size: 9px; font-style: normal; cursor: help; }
.color-sel { display: flex; align-items: center; gap: 6px; }
.swatch { width: 18px; height: 18px; flex: none; border-radius: 4px; border: 1px solid var(--line-2); }
.dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 4px; border: 1px solid rgba(0, 0, 0, .25); vertical-align: -1px; }
.fsec { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--text-3); margin: 14px 0 6px; grid-column: 1 / -1; }
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 14px; }
.form-grid .fsec { margin: 8px 0 0; }
.btn-row { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; }
.seg { display: inline-flex; border: 1px solid var(--line-2); border-radius: 7px; overflow: hidden; }
.seg button { border: 0; background: var(--panel); padding: 5px 12px; cursor: pointer; }
.seg button.on { background: var(--accent-2); color: var(--accent); font-weight: 600; }

/* ---------- brand ---------- */
.brand { display: inline-flex; align-items: center; gap: 8px; font-weight: 700; font-size: 15px; color: var(--text); text-decoration: none !important; }
.brand.big { font-size: 22px; }
.logo .lg-a { fill: var(--accent); }
.logo .lg-w1 { stroke: #f2b705; stroke-width: 2.2; fill: none; }
.logo .lg-w2 { stroke: #e04f3f; stroke-width: 2.2; fill: none; }
.logo .lg-w3 { stroke: #23a55a; stroke-width: 2.2; fill: none; }

/* ---------- login ---------- */
.login { min-height: 100vh; display: grid; place-items: center; padding: 16px; background: radial-gradient(1200px 600px at 20% 0%, var(--accent-2), transparent), var(--bg); }
.login-card { width: 100%; max-width: 340px; background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 28px; box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 12px; }
.login-card p { margin: -6px 0 6px; }
.login-err { color: var(--err); min-height: 18px; font-size: 12px; }

/* ---------- home ---------- */
.home { min-height: 100vh; }
.home-top { display: flex; align-items: center; gap: 10px; padding: 12px 24px; background: var(--panel); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 2; }
.home-main { max-width: 1100px; margin: 0 auto; padding: 24px 16px; }
.home-head { display: flex; align-items: center; gap: 16px; margin-bottom: 16px; }
.home-head h1 { margin: 0; font-size: 22px; flex: 1; }
.home-head .inp { max-width: 260px; }
.proj-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 14px; }
.proj { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; cursor: pointer; display: flex; flex-direction: column; overflow: hidden; position: relative; transition: border-color .12s, box-shadow .12s; }
.proj:hover { border-color: var(--accent); box-shadow: var(--shadow); }
.proj-thumb { height: 110px; display: grid; place-items: center; background: var(--panel-2); border-bottom: 1px solid var(--line); opacity: .8; }
.proj-info { padding: 10px 12px; }
.proj-title { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 26px; }
.proj .icon-btn { position: absolute; right: 6px; bottom: 14px; }
.empty-home { grid-column: 1 / -1; text-align: center; padding: 60px 0; color: var(--text-2); }

/* ---------- editor shell ---------- */
.editor { display: flex; flex-direction: column; height: 100vh; }
.topbar { display: flex; align-items: center; gap: 6px; height: 46px; padding: 0 8px; background: var(--panel); border-bottom: 1px solid var(--line); flex: none; }
.topbar .brand { padding: 4px; border-radius: 7px; }
.topbar .brand:hover { background: var(--panel-2); }
.title-wrap { display: flex; flex-direction: column; min-width: 120px; max-width: 260px; }
.title-inp { border: 1px solid transparent; background: transparent; font: 600 14px var(--font); color: var(--text); padding: 1px 4px; border-radius: 5px; width: 100%; }
.title-inp:hover { border-color: var(--line); }
.title-inp:focus { border-color: var(--accent); outline: none; background: var(--panel); }
.save-state { font-size: 10.5px; color: var(--text-3); padding-left: 5px; line-height: 1.1; }
.save-state.err { color: var(--err); }
.menus { display: flex; margin-left: 4px; }
.menus button { border: 0; background: transparent; padding: 5px 9px; border-radius: 6px; cursor: pointer; color: var(--text-2); }
.menus button:hover { background: var(--panel-2); color: var(--text); }
.search-btn { display: flex; align-items: center; gap: 6px; height: 30px; padding: 0 8px; border: 1px solid var(--line); border-radius: 7px; background: var(--panel-2); color: var(--text-3); cursor: pointer; margin: 0 4px; }
.search-btn:hover { border-color: var(--line-2); }
.search-btn kbd { margin-left: 8px; }
.issues-btn { display: flex; align-items: center; gap: 4px; height: 30px; padding: 0 8px; border: 1px solid var(--line); border-radius: 7px; background: var(--panel); cursor: pointer; color: var(--ok); font-weight: 600; }
.issues-btn .b { border-radius: 9px; padding: 0 6px; font-size: 11px; color: #fff; line-height: 17px; }
.b.err { background: var(--err); } .b.warn { background: var(--warn); } .b.info { background: var(--info); }
.view-tabs { display: flex; background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 2px; margin: 0 4px; }
.view-tabs button { border: 0; background: transparent; padding: 4px 11px; border-radius: 6px; cursor: pointer; color: var(--text-2); font-weight: 500; }
.view-tabs button.on { background: var(--panel); color: var(--text); box-shadow: 0 1px 2px rgba(0, 0, 0, .1); }
.workspace { flex: 1; display: flex; min-height: 0; position: relative; }
.toolbar { width: 46px; flex: none; background: var(--panel); border-right: 1px solid var(--line); display: flex; flex-direction: column; align-items: center; padding: 6px 0; gap: 2px; overflow-y: auto; }
.tool { width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; cursor: pointer; display: grid; place-items: center; color: var(--text-2); }
.tool:hover { background: var(--panel-2); color: var(--text); }
.tool.on { background: var(--accent); color: #fff; }
.tool-sep { height: 1px; width: 26px; background: var(--line); margin: 4px 0; }
.panes { flex: 1; display: flex; min-width: 0; }
.pane { flex: 1; display: flex; flex-direction: column; min-width: 0; position: relative; }
.panes.split .pane.active::after { content: ""; position: absolute; inset: 0; border: 2px solid var(--sel-glow); pointer-events: none; z-index: 3; }
.pane-head { display: flex; gap: 2px; padding: 4px; background: var(--panel); border-bottom: 1px solid var(--line); }
.pane-head button { border: 0; background: transparent; padding: 3px 9px; border-radius: 6px; cursor: pointer; color: var(--text-2); font-size: 12px; }
.pane-head button.on { background: var(--accent-2); color: var(--accent); font-weight: 600; }
.pane-body { flex: 1; min-height: 0; position: relative; display: flex; flex-direction: column; }
.pane-resizer, .insp-resizer { width: 5px; flex: none; cursor: col-resize; background: var(--line); }
.pane-resizer:hover, .insp-resizer:hover { background: var(--accent); }
.insp-resizer { width: 1px; position: relative; }
.insp-resizer::after { content: ""; position: absolute; inset: 0 -3px; }
.inspector { flex: none; background: var(--panel); overflow-y: auto; padding: 12px 14px 40px; }
.editor.no-insp .inspector, .editor.no-insp .insp-resizer { display: none; }
.issues-panel { position: absolute; right: 12px; top: 54px; width: 420px; max-width: calc(100vw - 24px); max-height: 60vh; display: flex; flex-direction: column; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow); z-index: 20; }
.ip-head { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-bottom: 1px solid var(--line); }
.ip-list { overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 4px; }
.ip-list .issue { cursor: pointer; }
.issue { padding: 6px 8px 6px 10px; border-radius: 6px; font-size: 12px; border-left: 3px solid; background: var(--panel-2); margin: 3px 0; }
.issue.error { border-color: var(--err); } .issue.warning { border-color: var(--warn); } .issue.info { border-color: var(--info); color: var(--text-2); }
body.readonly .toolbar .tool[data-tool] { opacity: .4; pointer-events: none; }

/* ---------- inspector ---------- */
.insp-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
.insp-kind { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 600; }
.insp-id { font-size: 16px; font-weight: 650; word-break: break-word; }
.insp-actions { display: flex; }
.insp-note { font-size: 12px; background: var(--panel-2); padding: 6px 8px; border-radius: 6px; margin-bottom: 8px; color: var(--text-2); }
.fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px 10px; }
.fields .field:not(.check) { grid-column: span 1; }
.fields .field.wide, .fields .field:has(textarea) { grid-column: 1 / -1; }
.fields .field.check { grid-column: 1 / -1; }
.chk-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 8px; }
.chk-grid .field.check { font-size: 12px; }
.cav-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.cav-table th { text-align: left; font-weight: 600; color: var(--text-3); font-size: 10.5px; padding: 3px 4px; border-bottom: 1px solid var(--line); }
.cav-table td { padding: 3px 4px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.cav-table td.des { font-weight: 600; width: 34px; }
.cav-table td.des .inp { width: 34px; }
.cav-table td.wires { font-size: 11.5px; line-height: 1.5; }
.cav-table td.contact { width: 16px; text-align: center; color: var(--text-3); }
.cav-table tr.csel td { background: var(--accent-2); }
.cav-table tr[data-cav] { cursor: pointer; }
.kv { display: grid; grid-template-columns: 1fr; gap: 3px; font-size: 12.5px; margin: 6px 0; }
.kv > div { display: flex; gap: 8px; align-items: baseline; }
.kv > div > span:first-child { color: var(--text-3); width: 84px; flex: none; font-size: 11.5px; }
.conn-list { font-size: 12.5px; line-height: 1.7; margin-bottom: 6px; }
.conn-list a { margin-right: 6px; }
.tag-list { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 6px; }
.tag { display: inline-flex; align-items: center; gap: 4px; padding: 2px 4px 2px 8px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px; font-size: 12px; }
.tag button { border: 0; background: transparent; cursor: pointer; color: var(--text-3); }
.help { margin-top: 14px; font-size: 12.5px; color: var(--text-2); }
.help p { margin: 0 0 8px; }

/* ---------- menus, modals, toasts ---------- */
.menu { position: fixed; z-index: 1000; min-width: 200px; background: var(--panel); border: 1px solid var(--line); border-radius: 9px; box-shadow: var(--shadow); padding: 4px; }
.menu-item { display: flex; align-items: center; width: 100%; border: 0; background: transparent; padding: 6px 8px; border-radius: 6px; cursor: pointer; text-align: left; position: relative; }
.menu-item:hover:not(:disabled) { background: var(--accent-2); }
.menu-item:disabled { opacity: .4; cursor: default; }
.menu-item.danger { color: var(--err); }
.mi-check { width: 16px; color: var(--accent); flex: none; }
.mi-label { flex: 1; white-space: nowrap; }
.mi-key { color: var(--text-3); font-size: 11px; margin-left: 18px; white-space: nowrap; }
.menu-sep { height: 1px; background: var(--line); margin: 4px 2px; }
.menu-head { font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); padding: 5px 8px 3px; font-weight: 600; }
.submenu { display: none; position: absolute; left: 100%; top: -5px; max-height: 70vh; overflow-y: auto; }
.has-sub:hover > .submenu { display: block; }
.toasts { position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; gap: 6px; z-index: 2000; align-items: center; pointer-events: none; }
.toast { background: #222833; color: #fff; padding: 8px 14px; border-radius: 8px; box-shadow: var(--shadow); font-size: 12.5px; transition: opacity .4s, transform .4s; max-width: 90vw; }
.toast.err { background: var(--err); }
.toast.out { opacity: 0; transform: translateY(8px); }
.modal-back { position: fixed; inset: 0; background: rgba(15, 20, 30, .42); display: grid; place-items: center; z-index: 900; padding: 16px; }
.modal { width: 100%; max-width: 480px; max-height: calc(100vh - 32px); display: flex; flex-direction: column; background: var(--panel); border-radius: 12px; box-shadow: var(--shadow); border: 1px solid var(--line); }
.modal.wide { max-width: 860px; }
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.modal-head h3 { margin: 0; font-size: 15px; }
.modal-body { padding: 16px; overflow-y: auto; }
.modal-body p { margin: 0 0 10px; }
.modal-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 10px 16px; border-top: 1px solid var(--line); }
.modal-foot:empty { display: none; }
.search-modal { max-width: 560px; align-self: start; margin-top: 10vh; }
.search .inp { height: 38px; font-size: 15px; }
.search-res { margin-top: 8px; max-height: 50vh; overflow-y: auto; }
.sr { padding: 7px 10px; border-radius: 7px; cursor: pointer; }
.sr.on, .sr:hover { background: var(--accent-2); }
.pad { padding: 10px; }
.revs { display: flex; flex-direction: column; gap: 6px; }
.rev { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; }

/* ---------- tables ---------- */
.grid-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.grid-table th { position: sticky; top: 0; background: var(--panel-2); text-align: left; font-weight: 600; color: var(--text-2); font-size: 11.5px; padding: 7px 8px; border-bottom: 1px solid var(--line); z-index: 1; white-space: nowrap; }
.grid-table td { padding: 5px 8px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.grid-table tbody tr:hover td { background: var(--panel-2); }
.grid-table tr.on td { background: var(--accent-2); }
.grid-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.grid-table tfoot td { font-weight: 600; border-top: 2px solid var(--line-2); }
.sel-rows tbody tr, .grid-table tr[data-part], .grid-table tr[data-sel] { cursor: pointer; }
.refs { color: var(--text-3); font-size: 11.5px; max-width: 260px; }
.nowrap { white-space: nowrap; }
th.sortable { cursor: pointer; user-select: none; }
th.sorted { color: var(--accent); }

/* ---------- connections ---------- */
.conn-host { background: var(--panel); }
.ctoolbar { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-bottom: 1px solid var(--line); }
.ctoolbar .inp { max-width: 340px; }
.conn-scroll { flex: 1; overflow: auto; }
.conn-table .cell { width: auto; max-width: 150px; border-color: transparent; background: transparent; }
.conn-table .cell:hover, .conn-table .cell:focus { border-color: var(--line-2); background: var(--panel); }
.cadd { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 8px 12px; border-top: 1px solid var(--line); background: var(--panel-2); }
.cadd .inp { width: auto; max-width: 180px; }

/* ---------- parts ---------- */
.parts-host { background: var(--panel); }
.parts { display: flex; height: 100%; min-height: 0; }
.parts-side { width: 190px; flex: none; border-right: 1px solid var(--line); overflow-y: auto; padding: 8px; background: var(--panel-2); }
.pside { display: flex; justify-content: space-between; width: 100%; border: 0; background: transparent; padding: 6px 9px; border-radius: 6px; cursor: pointer; text-align: left; color: var(--text); }
.pside span { color: var(--text-3); font-size: 11.5px; }
.pside:hover { background: var(--line); }
.pside.on { background: var(--accent-2); color: var(--accent); font-weight: 600; }
.pside.dim { color: var(--text-2); }
.pside-head { font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); padding: 12px 9px 4px; font-weight: 600; }
.parts-main { flex: 1; overflow: auto; padding: 0 0 20px; min-width: 0; }
.parts-main > p { padding: 0 14px; }
.ptoolbar { display: flex; align-items: center; gap: 8px; padding: 10px 14px; position: sticky; top: 0; background: var(--panel); z-index: 2; border-bottom: 1px solid var(--line); }
.ptoolbar h2 { margin: 0; font-size: 15px; }
.parts-editor { width: 360px; flex: none; border-left: 1px solid var(--line); overflow-y: auto; padding: 12px 14px 40px; }
.pthumb { width: 22px; height: 22px; object-fit: contain; vertical-align: middle; margin-right: 6px; border-radius: 3px; background: #fff; }
.pimg img { max-width: 100%; max-height: 140px; display: block; margin: 0 auto 6px; border-radius: 6px; background: #fff; }
.cfg { border: 1px solid var(--line); border-radius: 8px; padding: 8px; margin-bottom: 8px; display: flex; flex-direction: column; gap: 5px; }
.cfg-head { display: flex; gap: 4px; }
.acc { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.acc .inp { width: auto; flex: 1; min-width: 100px; }
.acc-type { font-size: 11px; color: var(--text-3); width: 72px; }
.mini { font-size: 11px; color: var(--text-2); display: inline-flex; gap: 3px; align-items: center; }
.pinout-prev { display: block; margin: 0 auto; background: var(--canvas); border-radius: 6px; }
.catalog { display: flex; flex-direction: column; gap: 10px; height: 64vh; }
.cat-top { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.cat-top .inp { width: auto; flex: 1; min-width: 150px; }
.cat-list { flex: 1; overflow: auto; border: 1px solid var(--line); border-radius: 8px; }
.cat-foot { display: flex; gap: 6px; }

/* ---------- canvas ---------- */
.canvas-host { position: relative; flex: 1; min-height: 0; overflow: hidden; background: var(--canvas); }
svg.canvas { display: block; width: 100%; height: 100%; outline: none; user-select: none; -webkit-user-select: none; touch-action: none; font-family: var(--font); background: var(--canvas); }
svg.canvas.panning, body.space-pan svg.canvas { cursor: grab; }
svg.canvas.placing { cursor: crosshair; }
.grid-dot { fill: var(--grid); }
.arrow-head { fill: var(--text-3); }
.zoom-ctl { position: absolute; right: 10px; bottom: 10px; display: flex; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, .08); overflow: hidden; }
.zoom-ctl button { border: 0; background: transparent; min-width: 30px; height: 28px; cursor: pointer; color: var(--text-2); }
.zoom-ctl button:hover { background: var(--panel-2); }
.zoom-ctl .zpct { font-size: 11px; min-width: 46px; font-variant-numeric: tabular-nums; }
.marquee { fill: var(--sel-glow); fill-opacity: .4; stroke: var(--sel); stroke-width: 1; stroke-dasharray: 4 3; vector-effect: non-scaling-stroke; }
.ghost { fill: var(--sel-glow); stroke: var(--sel); stroke-dasharray: 4 3; pointer-events: none; }
.temp-wire { fill: none; stroke: var(--sel); stroke-width: 2; stroke-dasharray: 6 4; pointer-events: none; }
.temp-bundle { stroke: var(--bundle); stroke-width: 6; stroke-linecap: round; opacity: .5; pointer-events: none; }
svg text { fill: var(--node-text); }

/* nodes (shared) */
.node { cursor: move; }
.node .body { fill: var(--node); stroke: var(--node-line); stroke-width: 1.3; }
.node .head { fill: var(--node-head); }
.node .title { font-size: 12px; font-weight: 650; }
.node .gender { font-weight: 400; fill: var(--text-3); }
.node .sub { font-size: 10px; fill: var(--text-3); }
.node .lbl { font-size: 11px; font-weight: 600; fill: var(--text-2); }
.node .sel-frame { fill: none; stroke: transparent; stroke-width: 2; pointer-events: none; }
.node.sel .sel-frame { stroke: var(--sel); }
.node .hit { fill: transparent; }
.resize-grip { fill: transparent; cursor: ew-resize; }
.resize-grip.corner { cursor: nwse-resize; }
.node.sel .resize-grip.corner { fill: var(--sel); }
/* connector rows */
.cav .cav-hit { fill: transparent; }
.cav:hover .cav-hit { fill: var(--accent-2); fill-opacity: .55; }
.cav.csel .cav-hit { fill: var(--accent-2); fill-opacity: 1; }
.cav .div { stroke: var(--line-2); stroke-width: 1; }
.cav .des { font-size: 10.5px; font-weight: 600; fill: var(--text-2); font-variant-numeric: tabular-nums; }
.cav .sig { font-size: 11px; }
.cav .sig.inh { fill: var(--text-3); font-style: italic; }
.cav.nc .des { fill: var(--text-3); }
/* connection handles */
.h { fill: var(--panel); stroke: var(--node-line); stroke-width: 1.2; opacity: 0; cursor: crosshair; transition: opacity .1s; }
.node:hover .h, svg.wiring .h, .node.sel .h { opacity: 1; }
.h:hover, .h.hot { fill: var(--sel); stroke: var(--sel); opacity: 1; r: 6; }
.h.h-center { fill: transparent; stroke: transparent; }
.h.h-center:hover, .h.h-center.hot { fill: var(--sel-glow); stroke: var(--sel); }
.core-h { opacity: .9; }
/* terminals, splices, components */
.glyph { fill: none; stroke: var(--node-line); stroke-width: 1.5; }
.splice-dot { fill: var(--node-line); }
.sym { fill: var(--node); stroke: var(--node-line); stroke-width: 1.5; }
.twopin .sym { fill: none; }
.twopin path.sym { fill: var(--node-line); }
.core-line { stroke-width: 2.4; }
.cable .sheath { fill: none; stroke: var(--node-line); stroke-width: 1.4; }
.twist { fill: none; stroke: var(--node-line); stroke-width: 1.3; opacity: .7; }
.twist.sm { opacity: .9; }
/* wires */
.w, .w-outline, .w-glow { fill: none; stroke-linejoin: round; pointer-events: none; }
.w-outline { stroke: #555c68; }
.w-glow { stroke: var(--net-glow); stroke-width: 9; stroke-linecap: round; }
.w-glow.s { stroke: var(--sel-glow); stroke-width: 10; }
.wire-hit { fill: none; stroke: transparent; stroke-width: 12; cursor: pointer; }
.wire-hit:hover { stroke: var(--sel-glow); }
.wlabel { font-size: 9.5px; fill: var(--text-2); paint-order: stroke; stroke: var(--canvas); stroke-width: 3px; pointer-events: none; font-variant-numeric: tabular-nums; }
.wp { fill: var(--panel); stroke: var(--sel); stroke-width: 1.5; cursor: move; }
.wgrip { fill: var(--sel); stroke: var(--panel); stroke-width: 2; cursor: crosshair; }
/* notes & images */
.note-bg { fill: #fff8d6; stroke: #e5d58a; }
:root[data-theme="dark"] .note-bg { fill: #3a3520; stroke: #6b5f2a; }
.note-text { font-size: 12px; }
.img-bg { fill: var(--panel); stroke: var(--line-2); }
.image .sel-frame { fill: none; }
.muted { fill: var(--text-3); }
/* wiring table */
.wt-bg { fill: var(--node); stroke: var(--node-line); stroke-width: 1; }
.wt-title { fill: var(--node-head); }
.wt-title-t { font-size: 11px; font-weight: 650; }
.wt-h { font-size: 10px; font-weight: 600; fill: var(--text-2); }
.wt-c { font-size: 10px; }
.wt-c.muted { fill: var(--text-3); }
.wt-line { stroke: var(--line-2); stroke-width: .8; }
.wtable.sel .wt-bg, .pimage.sel .img-bg, .pinout.sel .img-bg { stroke: var(--sel); stroke-width: 2; }
/* groups */
.group-box { fill: var(--accent); fill-opacity: .035; stroke: var(--accent); stroke-opacity: .45; stroke-width: 1.3; stroke-dasharray: 6 4; pointer-events: none; }
.group-head { fill: var(--accent); fill-opacity: .12; cursor: move; }
.group-title { font-size: 12px; font-weight: 650; fill: var(--accent); pointer-events: none; }
.group.sel .group-box { stroke-opacity: 1; stroke-dasharray: none; stroke-width: 2; }
.group.sel .group-head { fill-opacity: .22; }
/* pinout */
.po-outline { fill: #e9ecf1; stroke: #59626f; stroke-width: .35; }
:root[data-theme="dark"] .po-outline { fill: #2c323c; stroke: #8f99a8; }
.po-feat { fill: #cfd5de; stroke: #59626f; stroke-width: .25; }
.po-feat.front { fill: #59626f; }
.po-pin { fill: #fff; stroke: #3b424d; stroke-width: .3; }
.po-pin.hot { stroke: var(--sel); stroke-width: .8; }
.po-pin.nc { fill: #c9ced6; }
.po-lbl { font-weight: 600; pointer-events: none; }
.po-title { font-size: 10px; fill: var(--text-2); font-weight: 600; }

/* layout view */
.fb-panel { fill: #fff; stroke: #9aa3b1; stroke-width: 1; stroke-dasharray: 8 6; }
:root[data-theme="dark"] .fb-panel { fill: #1b1f27; }
.fb-panel-t { font-size: 14px; fill: var(--text-3); }
.bundle { fill: none; stroke: var(--bundle); stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
.bundle.empty { stroke-dasharray: 2 8; opacity: .55; }
.bundle-cover { fill: none; stroke-linecap: butt; stroke-linejoin: round; pointer-events: none; }
.bundle-cover-pat { fill: none; stroke: rgba(255, 255, 255, .28); pointer-events: none; }
.b-glow { fill: none; stroke: var(--net-glow); stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
.b-glow.s { stroke: var(--sel-glow); }
.bundle-hit { fill: none; stroke: transparent; cursor: pointer; stroke-linecap: round; }
.bundle-hit:hover { stroke: var(--sel-glow); }
.blabel text { font-size: 11px; font-weight: 600; paint-order: stroke; stroke: var(--canvas); stroke-width: 3.5px; cursor: pointer; font-variant-numeric: tabular-nums; }
.blabel.unset text { fill: var(--text-3); font-weight: 400; }
.blabel.mismatch text { fill: var(--warn); }
.bend-label rect { fill: var(--panel); stroke: var(--line-2); }
.bend-label text { font-size: 11px; font-weight: 600; }
.mate-line { stroke: var(--text-2); stroke-width: 3; stroke-dasharray: 2 3; }
.mate-hit { stroke: transparent; stroke-width: 12; cursor: pointer; }
.mate-dot { fill: var(--panel); stroke: var(--text-2); stroke-width: 1.5; }
.mate.sel .mate-line, .mate.sel .mate-dot { stroke: var(--sel); }
.lnode .bport { fill: none; stroke: transparent; stroke-width: 12; cursor: crosshair; pointer-events: stroke; }
.lnode:hover .bport { stroke: var(--sel-glow); }
.lnode .bport:hover { stroke: var(--sel-glow); }
.lnode-body { fill: var(--node); stroke: var(--node-line); stroke-width: 1.5; }
.lnode-n { font-size: 11px; font-weight: 700; }
.lnode-label { font-size: 12px; font-weight: 650; paint-order: stroke; stroke: var(--canvas); stroke-width: 3px; }
.lnode-label.sm { font-size: 10.5px; }
.lnode-sub { font-size: 10px; fill: var(--text-3); paint-order: stroke; stroke: var(--canvas); stroke-width: 3px; }
.lterm-bg { fill: var(--node); stroke: var(--node-line); stroke-width: 1; }
.bp-dot { fill: var(--bundle); stroke: var(--canvas); stroke-width: 2; }
.bp-dot.boot { fill: var(--accent); }
.inline-bg { fill: var(--node); stroke: var(--node-line); stroke-width: 1; }
.loc-arrow { stroke: var(--text-3); stroke-width: 1.2; }
.loc-arrow.auto { stroke-dasharray: 3 3; }
.cdraw { fill: #d9dde4; stroke: #3b424d; stroke-width: 1; }
.cdraw-line { fill: none; stroke: #3b424d; stroke-width: .8; }

/* print */
body.print { background: #fff; }
body.print .canvas { background: #fff; }

/* ---------- responsive ---------- */
@media (max-width: 1100px) {
  .search-btn span, .search-btn kbd { display: none; }
  .menus button { padding: 5px 6px; }
}
@media (max-width: 820px) {
  .title-wrap { min-width: 0; flex: 1; }
  .view-tabs button { padding: 4px 7px; font-size: 12px; }
  .inspector { position: absolute; right: 0; bottom: 0; left: 46px; top: auto; width: auto !important; max-height: 45vh; border-top: 1px solid var(--line); box-shadow: var(--shadow); z-index: 5; }
  .insp-resizer { display: none; }
  .parts-side { width: 140px; }
  .parts-editor { position: absolute; inset: 0 0 0 auto; width: min(360px, 100%); background: var(--panel); z-index: 4; box-shadow: var(--shadow); }
  .form-grid { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .topbar [data-a=split], .topbar [data-a=redo] { display: none; }
  .home-top { padding: 10px 16px; flex-wrap: wrap; }
}

@media (max-width: 820px) {
  .topbar { height: auto; flex-wrap: wrap; row-gap: 4px; padding: 6px 8px; }
  .topbar .menus, .topbar .view-tabs { order: 10; }
  .topbar .menus { margin-left: 0; }
  .topbar .view-tabs { margin-left: auto; overflow-x: auto; max-width: 100%; }
  .view-tabs button { white-space: nowrap; }
}
@media (max-width: 560px) {
  .topbar .menus { flex: 1 0 100%; justify-content: space-between; }
  .topbar .view-tabs { flex: 1 0 100%; margin: 0; }
  .topbar .view-tabs button { flex: 1; }
}

/* no accidental text selection while editing (inputs still selectable) */
.editor { user-select: none; -webkit-user-select: none; }
.editor input, .editor textarea, .editor .grid-table td { user-select: text; -webkit-user-select: text; }
/* shared read-only viewer */
body.shared .toolbar, body.shared [data-menu=file], body.shared [data-menu=edit], body.shared [data-menu=insert],
body.shared [data-a=undo], body.shared [data-a=redo], body.shared .cadd { display: none; }
body.shared .title-inp { pointer-events: none; }
