/* ─── Tokens ─────────────────────────────────────────────────────────── */
:root {
  color-scheme: light;

  --paper:       oklch(0.970 0.004 85);
  --paper-2:     oklch(0.950 0.005 85);
  --panel:       oklch(0.996 0.002 85);
  --sunk:        oklch(0.982 0.003 85);

  --ink:         oklch(0.215 0.012 265);
  --ink-2:       oklch(0.445 0.011 265);
  --ink-3:       oklch(0.615 0.009 265);
  --ink-4:       oklch(0.745 0.007 265);

  --line:        oklch(0.915 0.005 85);
  --line-2:      oklch(0.862 0.007 85);
  --line-3:      oklch(0.792 0.009 85);

  --sim:         oklch(0.520 0.098 205);
  --sim-soft:    oklch(0.945 0.03 205);
  --sim-line:    oklch(0.810 0.058 205);

  --gw:          oklch(0.492 0.118 330);
  --gw-soft:     oklch(0.948 0.026 330);
  --gw-line:     oklch(0.822 0.052 330);

  --cable:       oklch(0.340 0.016 265);
  --cable-hi:    oklch(0.560 0.165 42);
  --cable-soft:  oklch(0.945 0.034 42);

  --accent:      oklch(0.545 0.170 42);
  --accent-ink:  oklch(0.995 0.002 85);
  --accent-soft: oklch(0.952 0.030 42);

  --ok:          oklch(0.605 0.132 155);
  --warn:        oklch(0.700 0.150 72);
  --err:         oklch(0.560 0.205 25);
  --off:         oklch(0.760 0.008 265);

  --focus:       oklch(0.500 0.175 265);

  --sh-1: 0 1px 1px oklch(0.24 0.02 265 / .05), 0 2px 6px oklch(0.24 0.02 265 / .05);
  --sh-2: 0 1px 2px oklch(0.24 0.02 265 / .06), 0 8px 22px oklch(0.24 0.02 265 / .09);
  --sh-3: 0 2px 4px oklch(0.24 0.02 265 / .08), 0 24px 60px oklch(0.24 0.02 265 / .18);

  --r-1: 3px;
  --r-2: 5px;
  --r-3: 8px;
  --r-4: 12px;

  --sans: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

  --topbar-h: 54px;
  --ease: cubic-bezier(.22, 1, .36, 1);
  --ease-in: cubic-bezier(.4, 0, 1, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow: hidden;
}

h1, h2, h3, p { margin: 0; }
button, input, select, textarea { font: inherit; color: inherit; }

svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; inset-block-start: -100px; inset-inline-start: 12px; z-index: 100;
  padding: 8px 14px; background: var(--ink); color: var(--panel);
  border-radius: var(--r-2); font-size: 12px; text-decoration: none;
  transition: inset-block-start .15s var(--ease);
}
.skip-link:focus-visible { inset-block-start: 10px; }

:where(button, a, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--r-1);
}

.eyebrow {
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* ─── App frame ──────────────────────────────────────────────────────── */
.app {
  height: 100dvh;
  display: grid;
  grid-template-rows: var(--topbar-h) minmax(0, 1fr);
}

.topbar {
  display: flex;
  align-items: center;
  gap: 20px;
  padding-inline: 16px;
  border-block-end: 1px solid var(--line);
  background: var(--panel);
  position: relative;
  z-index: 40;
}

.brand { display: flex; align-items: center; gap: 10px; flex: none; }

.brand__mark {
  display: grid; grid-template-columns: repeat(3, 3px); gap: 2px;
  align-content: center; justify-content: center;
  width: 26px; height: 26px; border-radius: var(--r-2);
  background: var(--ink);
}
.brand__mark span { display: block; width: 3px; border-radius: 1px; background: var(--accent); }
.brand__mark span:nth-child(1) { height: 7px; }
.brand__mark span:nth-child(2) { height: 13px; }
.brand__mark span:nth-child(3) { height: 10px; }

.brand__text { display: flex; flex-direction: column; line-height: 1.15; }
.brand__name { font-size: 13px; font-weight: 700; letter-spacing: -.01em; }
.brand__sub { font-size: 10.5px; color: var(--ink-3); letter-spacing: .02em; }

.search {
  position: relative;
  display: flex; align-items: center;
  flex: 1 1 auto; max-width: 420px;
  margin-inline: auto;
}
.search__icon {
  position: absolute; inset-inline-start: 10px;
  color: var(--ink-3); pointer-events: none;
}
.search input {
  width: 100%;
  padding: 7px 30px 7px 32px;
  background: var(--sunk);
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  font-size: 12.5px;
  transition: border-color .15s var(--ease), background .15s var(--ease);
}
.search input::placeholder { color: var(--ink-4); }
.search input:hover { border-color: var(--line-2); }
.search input:focus { background: var(--panel); border-color: var(--line-3); outline-offset: 1px; }
.search input::-webkit-search-cancel-button { display: none; }
.search__clear {
  position: absolute; inset-inline-end: 6px;
  display: grid; place-items: center;
  width: 22px; height: 22px; padding: 0;
  border: 0; border-radius: var(--r-1); background: transparent;
  color: var(--ink-3); cursor: pointer;
}
.search__clear:hover { background: var(--paper-2); color: var(--ink); }

.topbar__actions { display: flex; align-items: center; gap: 12px; flex: none; }

.counter {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 10px 5px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--sunk);
  font-family: var(--mono); font-size: 11.5px; font-variant-numeric: tabular-nums;
  color: var(--ink-2);
}
.counter__icon { width: 13px; height: 13px; color: var(--cable-hi); }
.counter__label { font-family: var(--sans); font-size: 11px; color: var(--ink-3); }

/* ─── Buttons ────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-2);
  background: var(--panel);
  color: var(--ink);
  font-size: 12.5px; font-weight: 550;
  cursor: pointer;
  white-space: nowrap;
  transition: background .13s var(--ease), border-color .13s var(--ease),
              color .13s var(--ease), transform .1s var(--ease);
}
.btn svg { width: 14px; height: 14px; }
.btn:hover { background: var(--paper-2); border-color: var(--line-3); }
.btn:active { transform: translateY(.5px); }
.btn[disabled] { opacity: .45; pointer-events: none; }

.btn--primary {
  background: var(--ink); border-color: var(--ink); color: var(--accent-ink);
}
.btn--primary:hover { background: oklch(0.28 0.014 265); border-color: oklch(0.28 0.014 265); }

.btn--ghost { background: transparent; border-color: transparent; color: var(--ink-2); }
.btn--ghost:hover { background: var(--paper-2); border-color: var(--line); color: var(--ink); }

.btn--danger { border-color: var(--line-2); color: var(--err); }
.btn--danger:hover { background: oklch(0.96 0.03 25); border-color: oklch(0.85 0.09 25); }

.btn--sm { padding: 4px 9px; font-size: 11.5px; border-radius: var(--r-1); }

/* ─── Workspace ──────────────────────────────────────────────────────── */
.workspace {
  --insp-w: clamp(336px, 26vw, 440px);   /* inspector: wide enough for the ports table without a scrollbar */
  display: grid;
  grid-template-columns: 268px minmax(0, 1fr) var(--insp-w);
  min-height: 0;
  transition: grid-template-columns .24s var(--ease);
}

/* ─── Inventory ──────────────────────────────────────────────────────── */
.inventory {
  display: flex; flex-direction: column;
  min-height: 0;
  border-inline-end: 1px solid var(--line);
  background: var(--panel);
}
.inventory__head {
  display: flex; align-items: center; gap: 7px;
  padding: 11px 10px 9px 8px;
  min-height: 44px;
}
.inv-toggle {
  display: grid; place-items: center; flex: none;
  width: 26px; height: 26px;
  border: 1px solid transparent; border-radius: var(--r-2);
  background: transparent; color: var(--ink-3);
  cursor: pointer;
  transition: background .13s var(--ease), border-color .13s var(--ease), color .13s var(--ease);
}
.inv-toggle:hover { background: var(--paper-2); border-color: var(--line); color: var(--ink); }
.inv-toggle svg { width: 13px; height: 13px; transform: rotate(180deg); transition: transform .24s var(--ease); }
.inventory.is-collapsed .inv-toggle svg { transform: rotate(0deg); }
.inventory__count {
  margin-inline-start: auto;
  font-family: var(--mono); font-size: 11px; color: var(--ink-3);
  padding: 1px 6px; border-radius: 999px; background: var(--sunk); border: 1px solid var(--line);
}
.inventory__scroll { flex: 1; overflow-y: auto; padding: 0 8px 14px; overscroll-behavior: contain; }

.inv-group { margin-block-start: 10px; }
.inv-group__head {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 6px 6px;
}
.inv-group__dot { width: 7px; height: 7px; border-radius: 2px; flex: none; }
.inv-group--sim .inv-group__dot { background: var(--sim); }
.inv-group--gw  .inv-group__dot { background: var(--gw); }
.inv-group__name { font-size: 10.5px; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.inv-group__n { margin-inline-start: auto; font-family: var(--mono); font-size: 10.5px; color: var(--ink-4); }

.inv-item {
  display: grid;
  grid-template-columns: 4px minmax(0, 1fr) auto;
  align-items: center; gap: 9px;
  width: 100%;
  padding: 7px 8px 7px 6px;
  border: 1px solid transparent;
  border-radius: var(--r-2);
  background: transparent;
  text-align: start;
  cursor: pointer;
  transition: background .13s var(--ease), border-color .13s var(--ease);
}
.inv-item:hover { background: var(--sunk); }
.inv-item.is-active { background: var(--accent-soft); border-color: oklch(0.86 0.06 42); }
.inv-item__rail { width: 4px; align-self: stretch; border-radius: 2px; background: var(--sim); }
.inv-item--gw .inv-item__rail { background: var(--gw); }
.inv-item.is-offline .inv-item__rail { background: var(--off); }
.inv-item__body { min-width: 0; }
.inv-item__tag {
  font-size: 12.5px; font-weight: 600; letter-spacing: -.005em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.inv-item__meta {
  display: flex; gap: 7px; align-items: center;
  font-family: var(--mono); font-size: 10.5px; color: var(--ink-3);
}
.inv-item__ratio { font-family: var(--mono); font-size: 11px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.inv-item__ratio b { color: var(--cable-hi); font-weight: 600; }

/* ─── Inventory: collapsed rail ──────────────────────────────────────── */
.inventory.is-collapsed .inventory__head { justify-content: center; padding-inline: 4px; }
.inventory.is-collapsed .inv-title { display: none; }
.inventory.is-collapsed .inventory__count {
  margin-inline-start: 0; padding: 1px 5px; font-size: 10px;
}
.inventory.is-collapsed .inventory__scroll { padding: 0 10px 14px; }

.rail-group { display: flex; flex-direction: column; align-items: center; gap: 4px; padding-block: 7px; }
.rail-group + .rail-group { border-block-start: 1px solid var(--line); margin-block-start: 7px; }
.rail-group__head { display: grid; place-items: center; padding-block-end: 3px; }
.rail-group__dot { width: 8px; height: 8px; border-radius: 3px; }
.rail-group--sim .rail-group__dot { background: var(--sim); }
.rail-group--gw  .rail-group__dot { background: var(--gw); }

.rail-item {
  position: relative;
  display: grid; place-items: center;
  width: 100%; max-width: 40px; height: 28px;
  padding-inline: 8px 4px;
  border: 1px solid var(--line-2); border-radius: var(--r-2);
  background: var(--panel);
  font-family: var(--mono); font-size: 9.5px; font-variant-numeric: tabular-nums;
  color: var(--ink-3);
  cursor: pointer;
  transition: background .13s var(--ease), border-color .13s var(--ease), color .13s var(--ease);
}
.rail-item:hover { border-color: var(--line-3); background: var(--sunk); color: var(--ink); }
.rail-item.is-active {
  border-color: var(--cable-hi); background: var(--accent-soft); color: var(--ink);
  box-shadow: 0 0 0 1px var(--cable-hi);
}
.rail-item.is-offline { border-style: dashed; background: var(--sunk); color: var(--ink-4); }
.rail-item__bar {
  position: absolute; inset-block: 5px; inset-inline-start: 3px;
  width: 3px; border-radius: 2px;
}
.rail-item--sim .rail-item__bar { background: var(--sim); }
.rail-item--gw  .rail-item__bar { background: var(--gw); }
.rail-item.is-offline .rail-item__bar { background: var(--off); }
.rail-item__n { font-weight: 600; }
.rail-item.is-empty .rail-item__n { color: var(--ink-4); font-weight: 500; }

@keyframes flash {
  0%, 100% { background: transparent; }
  25% { background: var(--accent-soft); }
}
.inv-item.is-flash { animation: flash .9s var(--ease) 1; }

/* ─── Patch area ─────────────────────────────────────────────────────── */
.patch-wrap { display: flex; flex-direction: column; min-width: 0; min-height: 0; background: var(--paper); }

.patchbar {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 16px;
  padding: 12px 16px 11px;
  border-block-end: 1px solid var(--line);
  background: var(--panel);
}
.patchbar__title h1 { font-size: 14px; font-weight: 650; letter-spacing: -.01em; }
.patchbar__title p { font-size: 11.5px; color: var(--ink-3); margin-block-start: 2px; }
.patchbar__tools { display: flex; align-items: center; gap: 10px; }

.segmented {
  display: inline-flex;
  padding: 2px;
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  background: var(--sunk);
}
.segmented button {
  padding: 4px 10px;
  border: 0; border-radius: var(--r-1);
  background: transparent;
  font-size: 11.5px; font-weight: 550; color: var(--ink-3);
  cursor: pointer;
  transition: background .13s var(--ease), color .13s var(--ease);
}
.segmented button:hover { color: var(--ink); }
.segmented button.is-active { background: var(--panel); color: var(--ink); box-shadow: var(--sh-1); }

.patch {
  position: relative;
  flex: 1; min-height: 0;
  overflow: auto;
  overscroll-behavior: contain;
  scroll-behavior: smooth;
}
.patch__inner { position: relative; min-width: 900px; padding: 16px; }

.patch__grid {
  display: grid;
  grid-template-columns: minmax(238px, 300px) minmax(120px, 1fr) minmax(196px, 236px);
  align-items: start;
  gap: 0;
}

.lane { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.lane__spine { position: sticky; inset-block-start: 0; height: 100%; }

.lane__head {
  display: flex; align-items: center; gap: 7px;
  padding: 2px 4px 4px;
}
.lane__dot { width: 8px; height: 8px; border-radius: 3px; }
.lane--sim .lane__dot { background: var(--sim); }
.lane--gw  .lane__dot { background: var(--gw); }
.lane__n { font-size: 11px; font-variant-numeric: tabular-nums; color: var(--ink-3); margin-inline-start: auto; }
.lane--sim .lane__head .eyebrow { color: var(--sim); }
.lane--gw  .lane__head .eyebrow { color: var(--gw); }

.patch__empty {
  position: absolute; inset: 0;
  display: grid; place-content: center; gap: 6px;
  text-align: center; padding: 40px; color: var(--ink-3); pointer-events: none;
}
.patch__empty h3 { font-size: 13px; font-weight: 600; color: var(--ink); }

.patch__hint {
  padding: 8px 16px;
  border-block-start: 1px solid var(--line);
  background: var(--panel);
  font-size: 11.5px; color: var(--ink-3);
}
kbd {
  display: inline-block;
  padding: 0 4px;
  border: 1px solid var(--line-2);
  border-block-end-width: 2px;
  border-radius: var(--r-1);
  background: var(--sunk);
  font-family: var(--mono); font-size: 10.5px; color: var(--ink-2);
}
.hint-grip {
  display: inline-block; vertical-align: -3px;
  width: 8px; height: 14px; margin-inline: 2px;
  color: var(--ink-3);
  background-image: radial-gradient(currentColor 1px, transparent 1.1px);
  background-size: 4px 6px;
}

/* ─── Cables layer ───────────────────────────────────────────────────── */
.cables {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  overflow: visible;
  pointer-events: none;
  z-index: 20;
}
.cable { transition: opacity .16s var(--ease); }
.cable__hit { stroke: transparent; stroke-width: 14; fill: none; pointer-events: stroke; cursor: pointer; }
.cable__path { fill: none; stroke: var(--cable); stroke-width: 1.75; stroke-linecap: round; }
.cable__path--soft { stroke: var(--cable-soft); stroke-width: 5; }
.cable__end { fill: var(--panel); stroke: var(--cable); stroke-width: 1.5; }
.cable--error .cable__path { stroke: var(--err); stroke-dasharray: 4 3; }
.cable--error .cable__end { stroke: var(--err); }
.cable.is-dim { opacity: .12; }
.cable.is-hot .cable__path { stroke: var(--cable-hi); stroke-width: 2.25; }
.cable.is-hot .cable__end { stroke: var(--cable-hi); fill: var(--accent-soft); }

@keyframes draw { from { stroke-dashoffset: var(--len, 600); } to { stroke-dashoffset: 0; } }
.cable.is-new .cable__path { stroke-dasharray: var(--len, 600); animation: draw .5s var(--ease) forwards; }

.cable-drag { fill: none; stroke: var(--cable-hi); stroke-width: 2.25; stroke-linecap: round; stroke-dasharray: 7 5; }
.cable-drag__ghost { fill: var(--accent-soft); stroke: var(--cable-hi); stroke-width: 1.5; stroke-dasharray: 3 3; }
.cable-drag__anchor { fill: var(--cable-hi); stroke: var(--panel); stroke-width: 2; }

/* ─── Device panel ───────────────────────────────────────────────────── */
.device {
  position: relative;
  border: 1px solid var(--line-2);
  border-radius: var(--r-3);
  background: var(--panel);
  box-shadow: var(--sh-1);
  transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.device:hover { border-color: var(--line-3); }
.device.is-active { border-color: var(--cable-hi); box-shadow: 0 0 0 1px var(--cable-hi), var(--sh-2); }
.device.is-offline { background: var(--sunk); }
.device.is-offline .device__tag { color: var(--ink-3); }
.device.is-dim { opacity: .4; }

.device__head {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr) auto auto;
  align-items: center; gap: 9px;
  width: 100%;
  padding: 9px 10px;
  border: 0; border-radius: var(--r-3) var(--r-3) 0 0;
  background: transparent;
  text-align: start;
  cursor: pointer;
}
.device__head:hover { background: var(--sunk); border-radius: var(--r-3); }

.device__grip {
  display: grid; place-items: center;
  align-self: stretch; width: 18px;
  margin-inline: -5px -2px;
  cursor: grab;
  touch-action: none;
}
.device__grip::before {
  content: "";
  width: 8px; height: 18px;
  color: var(--ink-4);
  background-image: radial-gradient(currentColor 1px, transparent 1.1px);
  background-size: 4px 6px;
  opacity: .55;
  transition: opacity .13s var(--ease), color .13s var(--ease);
}
.device__head:hover .device__grip::before { opacity: 1; color: var(--ink-2); }
.device__grip:hover::before { color: var(--cable-hi); opacity: 1; }
.device__grip:active { cursor: grabbing; }

.device__kind {
  display: grid; place-items: center; flex: none;
  width: 24px; height: 24px; border-radius: var(--r-2);
}
.device__kind svg { width: 14px; height: 14px; stroke-width: 1.3; }
.device--sim .device__kind { background: var(--sim-soft); color: var(--sim); }
.device--gw  .device__kind { background: var(--gw-soft);  color: var(--gw); }
.device--sim .device__kind svg, .device--gw .device__kind svg { fill: none; }

.device__id { min-width: 0; }
.device__tag {
  display: block;
  font-size: 12.5px; font-weight: 650; letter-spacing: -.005em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.device__sub {
  display: flex; align-items: center; flex-wrap: wrap; gap: 3px 6px;
  font-family: var(--mono); font-size: 10.5px; color: var(--ink-3);
}
.device__model {
  font-size: 10px; letter-spacing: .02em;
  padding: 0 4px; border-radius: var(--r-1);
  background: var(--sunk); border: 1px solid var(--line);
  color: var(--ink-2);
}
.device--sim .device__model { background: var(--sim-soft); border-color: var(--sim-line); color: var(--sim); }
.device--gw  .device__model { background: var(--gw-soft);  border-color: var(--gw-line);  color: var(--gw); }

.device__ratio {
  font-family: var(--mono); font-size: 11px; font-variant-numeric: tabular-nums;
  color: var(--ink-2);
}
.device__ratio b { color: var(--cable-hi); font-weight: 650; }

.device__chev {
  display: grid; place-items: center;
  width: 20px; height: 20px; color: var(--ink-3);
  transition: transform .2s var(--ease), color .15s var(--ease);
}
.device__chev svg { width: 13px; height: 13px; }
.device.is-open .device__chev { transform: rotate(90deg); color: var(--ink); }

.device__heat { display: flex; flex-wrap: wrap; gap: 2px; padding: 0 10px 10px; cursor: pointer; }
.device.is-open .device__heat { display: none; }
.heat-cell {
  width: 5px; height: 5px; border-radius: 1px;
  background: var(--paper-2); border: 1px solid var(--line);
}
.heat-cell.is-bound { background: var(--cable-hi); border-color: var(--cable-hi); }
.heat-cell.is-err { background: var(--err); border-color: var(--err); }

.device__body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .26s var(--ease);
}
.device.is-open .device__body { grid-template-rows: 1fr; }
.device__body > div { overflow: hidden; }
.device__ports { padding: 2px 10px 10px; }

.port-grid { display: grid; gap: 4px; grid-template-columns: repeat(var(--cols, 8), minmax(0, 1fr)); }

/* ─── Device drag-reorder ────────────────────────────────────────────── */
body.is-reordering { cursor: grabbing; }
body.is-reordering .device, body.is-reordering .inv-item { user-select: none; }
#cables.is-muted { opacity: .16; transition: opacity .18s var(--ease); }

.device.is-reorder-source { opacity: .28; }
.drop-slot {
  border: 1.5px dashed var(--cable-hi);
  border-radius: var(--r-3);
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent-soft);
}
.drag-ghost {
  position: fixed; top: 0; left: 0; z-index: 120;
  pointer-events: none;
  box-shadow: var(--sh-3);
  border-radius: var(--r-3);
  opacity: .94;
  transform-origin: top left;
  will-change: transform;
  transition: opacity .12s var(--ease);
}

/* ─── Port tile ──────────────────────────────────────────────────────── */
.port {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  height: 24px; padding: 0 2px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-1);
  background: var(--panel);
  font-family: var(--mono); font-size: 10px; font-variant-numeric: tabular-nums;
  color: var(--ink-3);
  cursor: grab;
  touch-action: none;
  transition: background .12s var(--ease), border-color .12s var(--ease),
              color .12s var(--ease), transform .1s var(--ease);
}
.port:hover { border-color: var(--line-3); color: var(--ink); background: var(--sunk); z-index: 2; }
.port:active { cursor: grabbing; }

.port--lbl { height: 26px; font-size: 10.5px; padding-inline: 4px; justify-content: space-between; gap: 3px; }

.port.is-bound {
  background: var(--cable-soft);
  border-color: var(--cable-hi);
  color: var(--ink);
  font-weight: 600;
}
.port.is-bound:hover { background: oklch(0.915 0.05 42); }

.port.is-selected { border-color: var(--ink); box-shadow: 0 0 0 1px var(--ink); background: var(--panel); color: var(--ink); z-index: 3; }
.port.is-partner { border-color: var(--cable-hi); border-style: dashed; background: var(--accent-soft); color: var(--ink); z-index: 3; }
.port.is-source { border-color: var(--cable-hi); background: var(--cable-hi); color: var(--accent-ink); z-index: 4; }
.port.is-target { border-color: var(--cable-hi); box-shadow: 0 0 0 2px var(--cable-hi); background: var(--accent-soft); z-index: 4; }
.port.is-dim { opacity: .22; }
.port.is-hidden { display: none; }
.port.is-err { border-color: var(--err); background: oklch(0.96 0.04 25); color: var(--err); }
.port.is-err .port__dot { background: var(--err); }
.port.is-disabled { border-style: dashed; color: var(--ink-4); background: var(--sunk); cursor: not-allowed; }
.port.is-target-armed { border-color: var(--cable-hi); border-style: dashed; }
.patch.is-dragging { cursor: grabbing; }
.patch.is-dragging .device, .patch.is-dragging .inv-item { user-select: none; }

.port__n { pointer-events: none; }
.port__code { pointer-events: none; font-size: 9.5px; letter-spacing: -.02em; }

.port__dot {
  position: absolute; inset-block-start: 50%;
  width: 4px; height: 4px; margin-block-start: -2px;
  border-radius: 50%; background: var(--cable-hi);
  opacity: 0; transition: opacity .14s var(--ease), transform .14s var(--ease);
  transform: scale(.4);
}
.port.is-bound .port__dot { opacity: 1; transform: scale(1); }
.port--sim .port__dot { inset-inline-end: -3px; }
.port--gw  .port__dot { inset-inline-start: -3px; }
.port--sim .port:hover .port__dot, .port--gw .port:hover .port__dot { opacity: 1; transform: scale(1); background: var(--ink-3); }
.port.is-bound .port__dot { background: var(--cable-hi); }

.port--gw { height: 28px; font-size: 10.5px; }

/* selection bar shown when a device is active */
.device__pin {
  display: flex; align-items: center; gap: 6px;
  margin: 0 10px 8px; padding: 5px 8px;
  border-radius: var(--r-2);
  background: var(--accent-soft);
  border: 1px solid oklch(0.88 0.05 42);
  font-size: 11px; color: var(--ink-2);
}
.device__pin b { font-family: var(--mono); color: var(--ink); }
.device__pin .btn { margin-inline-start: auto; }

/* ─── Inspector ──────────────────────────────────────────────────────── */
.inspector {
  display: flex; flex-direction: column;
  min-height: 0;
  border-inline-start: 1px solid var(--line);
  background: var(--panel);
}
.inspector__empty { padding: 28px 18px; color: var(--ink-3); }
.inspector__empty h3 { font-size: 13px; font-weight: 600; color: var(--ink); margin-block-end: 6px; }
.inspector__empty p { font-size: 12px; line-height: 1.55; }

.insp-head { padding: 14px 14px 12px; border-block-end: 1px solid var(--line); }
.insp-head__top { display: flex; align-items: flex-start; gap: 9px; }
.insp-head__kind { display: grid; place-items: center; width: 28px; height: 28px; border-radius: var(--r-2); flex: none; }
.insp-head__kind svg { width: 16px; height: 16px; stroke-width: 1.3; }
.insp-head--sim .insp-head__kind { background: var(--sim-soft); color: var(--sim); }
.insp-head--gw  .insp-head__kind { background: var(--gw-soft);  color: var(--gw); }
.insp-head__id { min-width: 0; flex: 1; }
.insp-head__tag { font-size: 15px; font-weight: 680; letter-spacing: -.015em; line-height: 1.2; }
.insp-head__sub { display: flex; align-items: center; gap: 7px; margin-block-start: 3px; font-family: var(--mono); font-size: 11px; color: var(--ink-3); }
.insp-head__close {
  border: 0; background: transparent; color: var(--ink-3);
  width: 24px; height: 24px; display: grid; place-items: center;
  border-radius: var(--r-1); cursor: pointer; flex: none;
}
.insp-head__close:hover { background: var(--paper-2); color: var(--ink); }

.status-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 7px 2px 6px;
  border-radius: 999px;
  font-family: var(--sans); font-size: 10.5px; font-weight: 550;
  border: 1px solid var(--line-2); background: var(--sunk); color: var(--ink-2);
}
.status-chip::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--off); }
.status-chip--online::before { background: var(--ok); box-shadow: 0 0 0 2px oklch(0.9 0.06 155); }
.status-chip--warn::before { background: var(--warn); box-shadow: 0 0 0 2px oklch(0.93 0.07 72); }
.status-chip--offline::before { background: var(--err); }

.insp-stats {
  display: grid; grid-template-columns: repeat(3, 1fr);
  margin-block-start: 12px;
  border: 1px solid var(--line); border-radius: var(--r-2);
  background: var(--sunk); overflow: hidden;
}
.insp-stat { padding: 7px 8px; text-align: start; }
.insp-stat + .insp-stat { border-inline-start: 1px solid var(--line); }
.insp-stat__v { font-family: var(--mono); font-size: 14px; font-variant-numeric: tabular-nums; font-weight: 600; }
.insp-stat__k { font-size: 10px; color: var(--ink-3); letter-spacing: .04em; text-transform: uppercase; }

.tabs { display: flex; gap: 2px; padding: 8px 10px 0; border-block-end: 1px solid var(--line); }
.tab {
  padding: 6px 10px 7px;
  border: 0; border-block-end: 2px solid transparent;
  background: transparent; color: var(--ink-3);
  font-size: 12px; font-weight: 550; cursor: pointer;
  transition: color .13s var(--ease), border-color .13s var(--ease);
}
.tab:hover { color: var(--ink); }
.tab.is-active { color: var(--ink); border-block-end-color: var(--cable-hi); }
.tab__n {
  margin-inline-start: 5px;
  font-family: var(--mono); font-size: 10px;
  padding: 0 4px; border-radius: 999px; background: var(--sunk); border: 1px solid var(--line);
  color: var(--ink-3);
}

.insp-body { flex: 1; min-height: 0; overflow-y: auto; padding: 14px; overscroll-behavior: contain; }

.field { margin-block-end: 13px; }
.field__label {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-block-end: 4px;
  font-size: 11px; font-weight: 600; color: var(--ink-2); letter-spacing: .01em;
}
.field__hint { font-size: 10px; font-weight: 400; color: var(--ink-4); font-family: var(--mono); }
.field input, .field select, .field textarea {
  width: 100%;
  padding: 6px 9px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-2);
  background: var(--panel);
  font-size: 12.5px;
  transition: border-color .14s var(--ease), background .14s var(--ease);
}
.field input:hover, .field select:hover { border-color: var(--line-3); }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--cable-hi); }
.field input.mono, .field select.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.field__row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.field__err { margin-block-start: 4px; font-size: 11px; color: var(--err); display: flex; gap: 4px; align-items: center; }
.field__err svg { width: 12px; height: 12px; }
.field.has-err input, .field.has-err select { border-color: var(--err); }

.insp-section { margin-block-end: 16px; }
.insp-section__head {
  display: flex; align-items: center; gap: 8px;
  margin-block-end: 8px;
}
.insp-section__head::after { content: ""; flex: 1; height: 1px; background: var(--line); }

.form-actions {
  position: sticky; inset-block-end: -14px;
  display: flex; align-items: center; gap: 8px;
  margin: 14px -14px -14px; padding: 10px 14px;
  border-block-start: 1px solid var(--line);
  background: var(--panel);
}
.form-actions__note { font-size: 11px; color: var(--ink-3); margin-inline-end: auto; }

/* links list */
.link-list { display: flex; flex-direction: column; gap: 6px; }
.link-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 18px minmax(0, 1fr) auto;
  align-items: center; gap: 6px;
  padding: 7px 8px;
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  background: var(--sunk);
  transition: border-color .13s var(--ease), background .13s var(--ease);
}
.link-row:hover { border-color: var(--line-3); background: var(--panel); }
.link-row.is-hot { border-color: var(--cable-hi); background: var(--accent-soft); }
.link-row__end { min-width: 0; }
.link-row__code { font-family: var(--mono); font-size: 11.5px; font-weight: 600; }
.link-row__who {
  font-size: 10.5px; color: var(--ink-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.link-row__who--sim { color: var(--sim); }
.link-row__who--gw { color: var(--gw); }
.link-row__arrow { display: grid; place-items: center; color: var(--ink-4); }
.link-row__arrow svg { width: 13px; height: 13px; }
.link-row__x {
  border: 0; background: transparent; color: var(--ink-3);
  width: 24px; height: 24px; border-radius: var(--r-1);
  display: grid; place-items: center; cursor: pointer;
}
.link-row__x:hover { background: oklch(0.95 0.04 25); color: var(--err); }

.insp-note {
  padding: 10px;
  border: 1px dashed var(--line-2);
  border-radius: var(--r-2);
  font-size: 11.5px; color: var(--ink-3); line-height: 1.55;
  background: var(--sunk);
}

/* port card */
.port-card {
  padding: 11px 12px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-3);
  background: var(--sunk);
  margin-block-end: 14px;
}
.port-card__top { display: flex; align-items: center; gap: 8px; }
.port-card__code { font-family: var(--mono); font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
.port-card__idx { font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); }
.port-card__grid {
  display: grid; grid-template-columns: auto 1fr; gap: 3px 12px;
  margin-block-start: 9px; padding-block-start: 9px;
  border-block-start: 1px solid var(--line);
}
.port-card__k { font-size: 10.5px; color: var(--ink-3); }
.port-card__v { font-family: var(--mono); font-size: 11px; text-align: end; font-variant-numeric: tabular-nums; }
.port-card__v.empty { color: var(--ink-4); font-family: var(--sans); font-style: italic; }

.port-switch { margin-block-start: 12px; padding-block-start: 10px; border-block-start: 1px solid var(--line); }
.port-switch__actions { display: flex; gap: 8px; margin-block-start: 8px; flex-wrap: wrap; }
.port-switch__hint { margin-block-start: 8px; font-size: 10.5px; color: var(--ink-4); line-height: 1.45; }
#port-switch-select { width: 100%; max-height: 160px; }

/* ─── Toasts ─────────────────────────────────────────────────────────── */
.toasts {
  position: fixed; inset-block-end: 16px; inset-inline-start: 50%;
  transform: translateX(-50%);
  display: flex; flex-direction: column-reverse; gap: 8px;
  z-index: 90; pointer-events: none;
}
.toast {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px;
  min-width: 260px; max-width: 460px;
  border-radius: var(--r-3);
  background: var(--ink); color: oklch(0.97 0.004 85);
  box-shadow: var(--sh-3);
  font-size: 12.5px;
  pointer-events: auto;
  animation: toast-in .28s var(--ease) both;
}
.toast.is-out { animation: toast-out .2s var(--ease-in) both; }
.toast__icon { display: grid; place-items: center; width: 18px; height: 18px; flex: none; }
.toast__icon svg { width: 15px; height: 15px; }
.toast--ok .toast__icon { color: oklch(0.82 0.15 155); }
.toast--err .toast__icon { color: oklch(0.78 0.15 25); }
.toast--info .toast__icon { color: oklch(0.85 0.08 85); }
.toast__msg { flex: 1; }
.toast__msg b { font-family: var(--mono); font-weight: 600; }
.toast__act {
  border: 1px solid oklch(0.45 0.02 265);
  background: transparent; color: inherit;
  padding: 3px 9px; border-radius: var(--r-1);
  font-size: 11.5px; font-weight: 600; cursor: pointer; flex: none;
}
.toast__act:hover { background: oklch(0.32 0.015 265); }

@keyframes toast-in { from { opacity: 0; transform: translateY(14px) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(8px) scale(.98); } }

/* ─── Modal ──────────────────────────────────────────────────────────── */
.modal {
  position: fixed; inset: 0; z-index: 80;
  display: grid; place-items: center;
  padding: 20px;
  background: oklch(0.2 0.02 265 / .38);
  animation: fade-in .16s var(--ease) both;
}
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
.modal__box {
  width: min(560px, 100%);
  max-height: min(760px, calc(100dvh - 40px));
  display: flex; flex-direction: column;
  border-radius: var(--r-4);
  background: var(--panel);
  box-shadow: var(--sh-3);
  overflow: hidden;
  animation: modal-in .24s var(--ease) both;
}
@keyframes modal-in { from { opacity: 0; transform: translateY(10px) scale(.98); } to { opacity: 1; transform: none; } }
.modal__head {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px; border-block-end: 1px solid var(--line);
}
.modal__head h2 { font-size: 14px; font-weight: 650; }
.modal__close {
  margin-inline-start: auto; border: 0; background: transparent;
  width: 26px; height: 26px; display: grid; place-items: center;
  border-radius: var(--r-1); color: var(--ink-3); cursor: pointer;
}
.modal__close:hover { background: var(--paper-2); color: var(--ink); }
.modal__body { padding: 16px; overflow-y: auto; }
.modal__foot {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 16px; border-block-start: 1px solid var(--line); background: var(--sunk);
}
.modal__foot .btn:first-child { margin-inline-start: auto; }

.picker { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.picker__opt {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px;
  border: 1px solid var(--line-2); border-radius: var(--r-3);
  background: var(--panel); text-align: start; cursor: pointer;
  transition: border-color .14s var(--ease), background .14s var(--ease);
}
.picker__opt:hover { border-color: var(--line-3); background: var(--sunk); }
.picker__opt.is-active { border-color: var(--cable-hi); background: var(--accent-soft); }
.picker__opt svg { width: 18px; height: 18px; margin-block-start: 1px; flex: none; }
.picker__opt b { display: block; font-size: 12.5px; font-weight: 650; }
.picker__opt span { display: block; font-size: 11px; color: var(--ink-3); margin-block-start: 2px; line-height: 1.4; }

.preview {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 11px; margin-block-start: 4px;
  border: 1px dashed var(--line-2); border-radius: var(--r-2);
  background: var(--sunk);
  font-family: var(--mono); font-size: 11px; color: var(--ink-2);
}
.preview b { color: var(--ink); }
.preview svg { width: 15px; height: 15px; flex: none; color: var(--cable-hi); }

/* ─── Role switcher ──────────────────────────────────────────────────── */
.actor {
  position: relative;
  display: flex; align-items: center; gap: 6px;
  flex: none;
  padding-inline: 10px;
  border-inline-start: 1px solid var(--line);
  border-inline-end: 1px solid var(--line);
  align-self: stretch;
}
.actor__icon { width: 14px; height: 14px; color: var(--ink-3); flex: none; pointer-events: none; }
.actor__select {
  max-width: 210px;
  padding: 5px 2px;
  border: 0; background: transparent;
  font-size: 12px; font-weight: 550; color: var(--ink);
  cursor: pointer;
  appearance: none;
}
.actor__select:hover { color: var(--cable-hi); }

/* ─── Ownership & connection badges ──────────────────────────────────── */
.owner {
  display: inline-block;
  max-width: 100%;
  padding: 0 5px;
  border-radius: var(--r-1);
  border: 1px solid transparent;
  font-size: 9.5px; font-weight: 600; letter-spacing: .02em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  vertical-align: middle;
}
.owner--client { background: oklch(0.955 0.03 265); border-color: oklch(0.87 0.05 265); color: oklch(0.44 0.12 265); }
.owner--shared { background: var(--accent-soft); border-color: oklch(0.87 0.06 42); color: oklch(0.46 0.13 42); }
.owner--platform { background: var(--sunk); border-color: var(--line-2); color: var(--ink-3); }

.inv-item__owner { display: block; margin-block-start: 2px; }
.device__owner { display: block; margin-block-start: 3px; }
.insp-head__owner { display: flex; align-items: center; gap: 6px; margin-block-start: 6px; flex-wrap: wrap; }

.conn {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 0 6px;
  border-radius: 999px;
  font-size: 9.5px; font-weight: 600;
  border: 1px solid var(--line-2);
  background: var(--sunk); color: var(--ink-3);
  white-space: nowrap;
}
.device__sub .conn, .device__sub .status-chip { max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.conn::before { content: ""; flex: none; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.conn--active { background: oklch(0.955 0.035 155); border-color: oklch(0.86 0.06 155); color: oklch(0.42 0.11 155); }
.conn--pending { background: oklch(0.96 0.045 72); border-color: oklch(0.86 0.08 72); color: oklch(0.46 0.12 72); }
.conn--awaiting { background: var(--sunk); border-color: var(--line-2); color: var(--ink-3); }

/* ─── Connection lifecycle & credentials ─────────────────────────────── */
.conn-state {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 9px 10px; margin-block-end: 13px;
  border-radius: var(--r-2);
  border: 1px solid var(--line-2);
  background: var(--sunk);
  font-size: 11.5px; line-height: 1.5; color: var(--ink-2);
}
.conn-state svg { width: 14px; height: 14px; flex: none; margin-block-start: 1px; }
.conn-state b { color: var(--ink); }
.conn-state--ok { background: oklch(0.965 0.03 155); border-color: oklch(0.87 0.055 155); color: oklch(0.38 0.09 155); }
.conn-state--ok svg { color: oklch(0.55 0.13 155); }
.conn-state--warn { background: oklch(0.968 0.04 72); border-color: oklch(0.87 0.075 72); color: oklch(0.42 0.1 72); }
.conn-state--warn svg { color: var(--warn); }
.conn-state--info { background: var(--sim-soft); border-color: var(--sim-line); color: oklch(0.36 0.07 205); }
.conn-state--info svg { color: var(--sim); }

.insp-note--lock {
  display: flex; gap: 8px; align-items: flex-start;
  margin-block-end: 13px;
  background: var(--sunk);
}
.insp-note--lock svg { width: 14px; height: 14px; flex: none; margin-block-start: 1px; color: var(--ink-3); }
.insp-note--lock b { color: var(--ink); }

.creds {
  display: flex; flex-direction: column;
  border: 1px solid var(--line-2); border-radius: var(--r-2);
  overflow: hidden; margin-block-end: 8px;
}
.cred { display: grid; grid-template-columns: 96px minmax(0, 1fr); align-items: center; }
.cred + .cred { border-block-start: 1px solid var(--line); }
.cred__k {
  display: flex; align-items: center; gap: 5px;
  padding: 7px 9px; height: 100%;
  background: var(--sunk);
  font-size: 10.5px; color: var(--ink-3);
}
.cred__k svg { width: 12px; height: 12px; flex: none; }
.cred__v { padding: 7px 9px; font-size: 11.5px; font-weight: 600; word-break: break-all; }
.creds__intro { font-size: 12px; line-height: 1.55; color: var(--ink-2); margin-block-end: 10px; }
.creds__note { font-size: 11px; line-height: 1.5; color: var(--ink-3); margin-block-end: 13px; }
.icon-inline { width: 13px; height: 13px; vertical-align: -2px; margin-inline-end: 3px; }
.inspector__scope {
  margin-block-start: 12px; padding: 9px 10px;
  border: 1px solid var(--line); border-radius: var(--r-2);
  background: var(--sunk);
  font-size: 11.5px; line-height: 1.5;
}

.field__regen {
  border: 0; background: transparent; padding: 0 2px;
  color: var(--cable-hi); font-size: 10.5px; font-weight: 600;
  cursor: pointer; text-decoration: underline;
  text-underline-offset: 2px;
}
.field__regen:hover { color: var(--accent); }

.readonly-value {
  padding: 6px 9px;
  border: 1px dashed var(--line-2); border-radius: var(--r-2);
  background: var(--sunk);
  font-size: 12.5px; color: var(--ink-2);
}
.check {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 9px 10px; margin-block-end: 13px;
  border: 1px solid var(--line-2); border-radius: var(--r-2);
  background: var(--sunk);
  font-size: 11.5px; line-height: 1.45; color: var(--ink-2);
  cursor: pointer;
}
.check input { margin: 1px 0 0; flex: none; accent-color: var(--cable-hi); }
.check:hover { border-color: var(--line-3); }

.link-row__owner {
  grid-column: 1 / -1;
  padding-block-start: 5px; margin-block-start: 5px;
  border-block-start: 1px dashed var(--line);
  font-size: 10px; color: var(--ink-3);
}

/* ─── Platform panel ─────────────────────────────────────────────────── */
.panel-body { padding: 14px 16px; }
.panel-note { font-size: 11.5px; line-height: 1.55; color: var(--ink-3); margin-block-end: 12px; }
.panel-list { display: flex; flex-direction: column; gap: 7px; }
.panel-group { margin-block-end: 16px; }
.panel-group__head {
  display: flex; align-items: center; gap: 8px;
  padding-block-end: 6px; margin-block-end: 6px;
  border-block-end: 1px solid var(--line);
}
.panel-group__name { font-size: 11px; font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-2); }
.panel-group__n { margin-inline-start: auto; font-family: var(--mono); font-size: 11px; color: var(--ink-3); }

.panel-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto auto;
  align-items: center; gap: 9px;
  width: 100%; padding: 7px 9px;
  border: 1px solid transparent; border-radius: var(--r-2);
  background: transparent; text-align: start; cursor: pointer;
  transition: background .13s var(--ease), border-color .13s var(--ease);
}
.panel-row:hover { background: var(--sunk); border-color: var(--line); }
.panel-row__icon {
  display: grid; place-items: center; width: 22px; height: 22px;
  border-radius: var(--r-1); flex: none;
}
.panel-row__icon svg { width: 13px; height: 13px; }
.panel-row__icon--sim { background: var(--sim-soft); color: var(--sim); }
.panel-row__icon--gw { background: var(--gw-soft); color: var(--gw); }
.panel-row__tag { font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.panel-row__sub { font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); white-space: nowrap; }

.claim {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center; gap: 10px;
  padding: 10px 11px;
  border: 1px solid var(--line-2); border-radius: var(--r-3);
  background: var(--panel);
}
.claim__icon { display: grid; place-items: center; width: 26px; height: 26px; border-radius: var(--r-2); }
.claim__icon svg { width: 15px; height: 15px; }
.claim__icon--sim { background: var(--sim-soft); color: var(--sim); }
.claim__icon--gw { background: var(--gw-soft); color: var(--gw); }
.claim__body { min-width: 0; }
.claim__title { display: block; font-size: 12.5px; font-weight: 650; }
.claim__model { font-family: var(--mono); font-size: 10px; font-weight: 400; color: var(--ink-3); }
.claim__meta { display: block; font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); margin-block-start: 2px; }
.claim__owner { font-size: 11px; font-weight: 600; color: var(--ink-2); white-space: nowrap; }
.claim__act { display: flex; gap: 6px; align-items: center; }

.client-card {
  padding: 11px 12px;
  border: 1px solid var(--line); border-radius: var(--r-3);
  background: var(--sunk);
}
.client-card__top { display: flex; align-items: center; gap: 8px; }
.client-card__name { font-size: 13px; font-weight: 650; }
.client-card__status {
  margin-inline-start: auto;
  padding: 1px 7px; border-radius: 999px;
  font-size: 10px; font-weight: 600;
  border: 1px solid var(--line-2); background: var(--panel); color: var(--ink-3);
}
.client-card__status--active { border-color: oklch(0.86 0.06 155); background: oklch(0.965 0.03 155); color: oklch(0.42 0.11 155); }
.client-card__status--suspended { border-color: oklch(0.85 0.09 25); background: oklch(0.96 0.03 25); color: oklch(0.46 0.14 25); }
.client-card__meta { margin-block-start: 4px; font-size: 10.5px; color: var(--ink-3); }
.client-card__stats { display: flex; gap: 14px; margin-block-start: 8px; font-size: 11px; color: var(--ink-3); }
.client-card__stats b { font-family: var(--mono); color: var(--ink); }

/* ─── Access states on devices & ports ───────────────────────────────── */
.device.is-readonly .device__tag { color: var(--ink-2); }
.device.is-readonly { background: var(--sunk); }
.device.is-mine::after {
  content: "";
  position: absolute; inset-block-start: 9px; inset-inline-end: 9px;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--cable-hi);
}
.device.is-mine .device__ratio { margin-inline-end: 8px; }

.port.is-blocked { border-style: dashed; color: var(--ink-4); background: var(--sunk); cursor: not-allowed; }
.port.is-blocked .port__dot { display: none; }
.link-row__x[disabled] { opacity: .3; pointer-events: none; }

/* ─── Skeletons ──────────────────────────────────────────────────────── */
@keyframes shimmer { to { background-position: -200% 0; } }
.sk {
  border-radius: var(--r-2);
  background: linear-gradient(90deg, var(--paper-2) 25%, var(--sunk) 37%, var(--paper-2) 63%);
  background-size: 200% 100%;
  animation: shimmer 1.3s linear infinite;
}
.sk-device { height: 66px; border-radius: var(--r-3); }
.sk-row { height: 40px; margin: 6px 8px; }

/* ─── Responsive ─────────────────────────────────────────────────────── */
@media (max-width: 1180px) {
  .workspace { grid-template-columns: 232px minmax(0, 1fr) 300px; }
  .patch__grid { grid-template-columns: minmax(210px, 260px) minmax(90px, 1fr) minmax(176px, 210px); }
}

/* ─── Responsive ─────────────────────────────────────────────────────── */
@media (min-width: 941px) {
  .workspace.is-inv-collapsed { grid-template-columns: 58px minmax(0, 1fr) var(--insp-w); }
}

@media (max-width: 1180px) {
  .workspace { grid-template-columns: 232px minmax(0, 1fr) 300px; }
  .patch__grid { grid-template-columns: minmax(210px, 260px) minmax(90px, 1fr) minmax(176px, 210px); }
}

@media (min-width: 941px) and (max-width: 1180px) {
  .workspace.is-inv-collapsed { grid-template-columns: 58px minmax(0, 1fr) 300px; }
}

@media (max-width: 940px) {
  body { overflow: auto; }
  .app { height: auto; min-height: 100dvh; grid-template-rows: auto auto; }
  .topbar { flex-wrap: wrap; gap: 10px; padding-block: 10px; }
  .actor {
    order: 2; align-self: auto;
    flex: 1 1 auto; padding-inline: 0;
    border-inline: 0;
  }
  .actor__select { max-width: none; width: 100%; }
  .search { order: 3; flex-basis: 100%; max-width: none; margin: 0; }
  .topbar__actions { order: 4; width: 100%; margin-inline-start: 0; justify-content: space-between; }
  .topbar__actions .btn { flex: 1; justify-content: center; }

  .claim { grid-template-columns: auto minmax(0, 1fr); }
  .claim__owner { grid-column: 2; }
  .claim__act { grid-column: 2; }
  .panel-row { grid-template-columns: auto minmax(0, 1fr) auto; }
  .panel-row__sub { display: none; }

  .workspace { grid-template-columns: minmax(0, 1fr); }
  .inventory { order: 2; border-inline-end: 0; border-block-start: 1px solid var(--line); }
  .inventory__scroll { max-height: 260px; }
  .inventory.is-collapsed { flex-direction: row; align-items: center; gap: 8px; padding-inline: 8px; }
  .inventory.is-collapsed .inventory__head { min-height: 40px; justify-content: flex-start; padding-inline: 0; gap: 7px; }
  .inventory.is-collapsed .inv-title { display: block; }
  .inventory.is-collapsed .inventory__count { margin-inline-start: 0; }
  .inventory.is-collapsed .inventory__scroll { display: none; }
  .patch-wrap { order: 1; }
  .patch { overflow-x: auto; }
  .inspector { order: 3; border-inline-start: 0; border-block-start: 1px solid var(--line); }
  .patch__inner { min-width: 720px; }
  .toasts { inset-inline: 12px; transform: none; }
  .toast { min-width: 0; width: 100%; }
}

@media (max-width: 560px) {
  .patch__grid { grid-template-columns: minmax(170px, 1fr) 56px minmax(150px, 1fr); }
  .patch__inner { min-width: 520px; }
  .patchbar { flex-direction: column; align-items: stretch; }
  .patchbar__tools { justify-content: space-between; }
  .picker { grid-template-columns: 1fr; }
  .field__row { grid-template-columns: 1fr; }
  .insp-stats { grid-template-columns: repeat(3, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

@media (forced-colors: active) {
  .port, .device, .link-row, .cable__path { forced-color-adjust: auto; }
  .port.is-bound { border-color: Highlight; }
}


/* ── operator tools (web/admin.js) ───────────────────────────────────── */
.admin-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 4px 0 10px; }
.admin-bar--sub { margin-top: 18px; }
.admin-bar__t { font-weight: 600; font-size: 12px; color: var(--ink-2, inherit); }
.admin-err { color: var(--bad, #c0392b); }
.admin-scroll { overflow-x: auto; }
.admin-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.admin-table th { text-align: left; font-weight: 600; color: var(--ink-3, #888); padding: 4px 5px; white-space: nowrap; }
.admin-state { white-space: nowrap; }
.admin-state .btn { margin-inline-start: 6px; }
.admin-table td { padding: 4px 5px; border-top: 1px solid var(--line, rgba(128,128,128,.25)); vertical-align: middle; }
.admin-table--events td { font-size: 11px; }
.admin-sub { margin: 10px 0 4px; font-size: 12px; color: var(--ink-3, #888); }
.admin-row { display: flex; align-items: center; gap: 10px; padding: 5px 0; border-top: 1px solid var(--line, rgba(128,128,128,.25)); font-size: 12px; }
.admin-row > span:nth-child(2) { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.admin-state { white-space: nowrap; }
.admin-state .btn { margin-inline-start: 6px; }

/* ─── API console (Swagger-style) ────────────────────────────────────── */
.apic { position: fixed; inset: 0; z-index: 900; display: flex; flex-direction: column; background: var(--paper, #fff); color: var(--ink, #111); }
.apic__bar { display: flex; align-items: center; gap: 12px; padding: 10px 16px; border-bottom: 1px solid var(--line, #ddd); font-size: 13px; }
.apic__sp { flex: 1; }
.apic__body { flex: 1; display: grid; grid-template-columns: 340px minmax(0, 1fr); min-height: 0; }
.apic__side { display: flex; flex-direction: column; min-height: 0; border-inline-end: 1px solid var(--line, #ddd); background: var(--sunk, #f6f6f4); }
.apic-filter { margin: 10px; padding: 7px 9px; border: 1px solid var(--line-2, #ccc); border-radius: var(--r-2, 6px); font: inherit; font-size: 12px; background: var(--paper, #fff); color: inherit; }
.apic__list { overflow: auto; padding: 0 8px 16px; }
.apic-g__t { margin: 12px 4px 4px; font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3, #888); }
.apic-op, .apic-h { display: grid; grid-template-columns: 52px minmax(0, 1fr) auto; align-items: center; gap: 2px 8px; width: 100%; padding: 6px 8px; margin-block-end: 2px; text-align: start; background: transparent; border: 1px solid transparent; border-radius: var(--r-2, 6px); color: inherit; cursor: pointer; font-size: 12px; }
.apic-op:hover, .apic-h:hover { background: var(--paper, #fff); }
.apic-op.is-active { background: var(--paper, #fff); border-color: var(--line-2, #ccc); }
.apic-op__p { overflow-wrap: anywhere; font-size: 11.5px; }
.apic-op__s { grid-column: 2 / 4; font-size: 11px; color: var(--ink-3, #888); }
.apic-w { color: oklch(0.6 0.17 40); font-size: 9px; }
.apic-h { grid-template-columns: 52px minmax(0, 1fr) auto; font-size: 11px; }
.apic-h .mono { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.apic-h__s--ok { color: oklch(0.45 0.12 155); } .apic-h__s--bad { color: oklch(0.5 0.16 30); }
.apic-m { display: inline-block; min-width: 52px; padding: 2px 0; text-align: center; border-radius: 4px; font: 700 10.5px/1.3 var(--mono, monospace); color: #fff; }
.apic-m--get { background: oklch(0.55 0.13 250); } .apic-m--post { background: oklch(0.55 0.13 155); } .apic-m--delete { background: oklch(0.55 0.17 28); }
.apic__main { overflow: auto; padding: 18px 26px 60px; max-width: 980px; }
.apic-empty { color: var(--ink-3, #888); padding: 40px 0; }
.apic-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.apic-head .apic-m { min-width: 64px; font-size: 12px; padding: 4px 0; }
.apic-path { font-size: 15px; font-weight: 600; overflow-wrap: anywhere; }
.apic-tag { padding: 1px 8px; border-radius: 999px; font-size: 10.5px; background: var(--sunk, #eee); border: 1px solid var(--line-2, #ccc); color: var(--ink-3, #777); }
.apic-tag--b { color: oklch(0.45 0.1 250); } .apic-tag--w { color: oklch(0.5 0.16 40); border-color: oklch(0.85 0.08 60); background: oklch(0.97 0.03 70); }
.apic-sum { margin: 8px 0 4px; font-size: 14px; font-weight: 600; }
.apic-desc { font-size: 12.5px; line-height: 1.6; color: var(--ink-2, #444); }
.apic-desc code, .apic-sec code { padding: 0 4px; border-radius: 3px; background: var(--sunk, #eee); font-size: 11.5px; }
.apic-sec { margin: 22px 0 8px; padding-block-end: 4px; border-bottom: 1px solid var(--line, #ddd); font-size: 12px; font-weight: 700; letter-spacing: .02em; }
.apic-t { width: 100%; border-collapse: collapse; font-size: 12px; }
.apic-t th { text-align: start; padding: 4px 8px; font-weight: 600; color: var(--ink-3, #888); }
.apic-t td { padding: 7px 8px; border-top: 1px solid var(--line, #e3e3e3); vertical-align: top; }
.apic-pn { width: 210px; } .apic-pi { width: 250px; }
.apic-req { color: oklch(0.55 0.2 27); margin-inline-start: 3px; font-weight: 700; }
.apic-pt { font-size: 11px; color: var(--ink-3, #888); }
.apic-in-chip { display: inline-block; margin-block-start: 2px; padding: 0 6px; border-radius: 999px; font-size: 9.5px; border: 1px solid var(--line-2, #ccc); color: var(--ink-3, #888); }
.apic-in { width: 100%; padding: 6px 8px; border: 1px solid var(--line-2, #ccc); border-radius: var(--r-2, 6px); font-size: 12px; background: var(--paper, #fff); color: inherit; }
.apic-in.has-err { border-color: oklch(0.6 0.2 27); box-shadow: 0 0 0 2px oklch(0.92 0.06 27); }
.apic-exs { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 10px 0 4px; }
.apic-ex { padding: 3px 10px; border: 1px solid var(--line-2, #ccc); border-radius: 999px; background: var(--paper, #fff); font-size: 11px; color: inherit; cursor: pointer; }
.apic-ex:hover { background: var(--sunk, #eee); }
.apic-modes { display: flex; gap: 16px; margin: 12px 0 6px; font-size: 12px; }
.apic-json { width: 100%; padding: 8px 10px; border: 1px solid var(--line-2, #ccc); border-radius: var(--r-2, 6px); font-size: 11.5px; line-height: 1.5; background: var(--paper, #fff); color: inherit; }
.apic-act { display: flex; gap: 8px; margin: 14px 0 4px; }
.apic-pre { margin: 0; padding: 10px 12px; overflow: auto; max-height: 260px; font-size: 11.5px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; background: var(--sunk, #f3f3f1); border: 1px solid var(--line-2, #ddd); border-radius: var(--r-2, 6px); }
.apic-pre--out { max-height: 460px; }
.apic-t--r td:first-child { width: 60px; }
.apic-t--r tr.is-hit td { background: oklch(0.96 0.05 95); font-weight: 600; }
.apic-t--r tr.is-extra td { background: oklch(0.95 0.05 40); }
.apic-resh { display: flex; align-items: center; gap: 10px; margin-block-end: 8px; }
.apic-hdr { margin-block-end: 8px; font-size: 11.5px; } .apic-hdr summary { cursor: pointer; color: var(--ink-3, #888); }
@media (max-width: 860px) { .apic__body { grid-template-columns: 1fr; } .apic__side { max-height: 40vh; } .apic-pn, .apic-pi { width: auto; } }

/* Sign-in form */
.login { position: fixed; inset: 0; z-index: 1000; display: grid; place-items: center; padding: 16px; background: var(--paper-2, #f4f3f0); }
.login__box { display: flex; flex-direction: column; gap: 6px; width: min(360px, 100%); padding: 26px 26px 22px; background: var(--paper, #fff); border: 1px solid var(--line-2, #ddd); border-radius: 12px; box-shadow: 0 10px 40px rgba(0,0,0,.08); }
.login__t { margin: 0; font-size: 20px; letter-spacing: -.01em; }
.login__s { margin: 0 0 12px; font-size: 12px; color: var(--ink-3, #888); }
.login__in { padding: 9px 10px; margin-block-end: 8px; border: 1px solid var(--line-2, #ccc); border-radius: var(--r-2, 6px); font: inherit; font-size: 14px; background: var(--paper, #fff); color: inherit; }
.login__in:focus { outline: 2px solid var(--accent, #2b6cff); outline-offset: 1px; }
.login__err { margin: 2px 0 6px; padding: 7px 10px; border-radius: 6px; font-size: 12px; color: oklch(0.45 0.17 27); background: oklch(0.96 0.03 27); }
.login__btn { margin-block-start: 4px; padding: 10px; justify-content: center; }
