/* Layout: three-pane workbench. Parts bin | elevation sheet on graph paper | datasheet inspector. */
:root {
  --bg: #e6eaee;
  --surface: #fbfcfd;
  --surface-2: #f1f4f7;
  --surface-3: #e7ebf0;
  --line: #d3d9e0;
  --line-strong: #b7c0ca;
  --ink: #18212b;
  --ink-2: #4e5a67;
  --ink-3: #7c8997;
  --tape: #f2c230;
  --tape-hover: #f6cd4c;
  --tape-edge: #c99b12;
  --tape-ink: #1b1f24;
  --danger: #c23a3a;
  --danger-soft: #fbeaea;
  --ok: #1f8f4e;
  --unassigned: #8c96a3;
  --rack-frame: #2a3038;
  --rack-bay: #e8ecf0;
  --scrim: rgb(14 18 23 / 0.46);
  --shadow-1: 0 1px 2px rgb(20 28 38 / 0.06), 0 2px 10px rgb(20 28 38 / 0.05);
  --shadow-pop: 0 18px 50px rgb(20 28 38 / 0.2), 0 2px 6px rgb(20 28 38 / 0.08);
  --scroll-shade: rgb(20 28 38 / 0.16);

  --font-ui: "Barlow", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-display: "Barlow Condensed", "Arial Narrow", "Barlow", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --r-sm: 4px;
  --r-md: 6px;
  --bin-w: 252px;
  --insp-w: 292px;
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0d1115;
    --surface: #151a20;
    --surface-2: #1b2128;
    --surface-3: #232a32;
    --line: #29313a;
    --line-strong: #3a444f;
    --ink: #e6ebf0;
    --ink-2: #a5b0bc;
    --ink-3: #737f8d;
    --tape: #f2c230;
    --tape-hover: #f6cd4c;
    --tape-edge: #a07a0c;
    --tape-ink: #1b1f24;
    --danger: #f06a6a;
    --danger-soft: #3a1f22;
    --ok: #43c47a;
    --unassigned: #7d8794;
    --rack-frame: #48515c;
    --rack-bay: #1e242b;
    --scrim: rgb(0 0 0 / 0.6);
    --shadow-1: 0 1px 2px rgb(0 0 0 / 0.3), 0 2px 10px rgb(0 0 0 / 0.25);
    --shadow-pop: 0 18px 50px rgb(0 0 0 / 0.55), 0 2px 6px rgb(0 0 0 / 0.3);
    --scroll-shade: rgb(0 0 0 / 0.55);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #0d1115;
  --surface: #151a20;
  --surface-2: #1b2128;
  --surface-3: #232a32;
  --line: #29313a;
  --line-strong: #3a444f;
  --ink: #e6ebf0;
  --ink-2: #a5b0bc;
  --ink-3: #737f8d;
  --tape: #f2c230;
  --tape-hover: #f6cd4c;
  --tape-edge: #a07a0c;
  --tape-ink: #1b1f24;
  --danger: #f06a6a;
  --danger-soft: #3a1f22;
  --ok: #43c47a;
  --unassigned: #7d8794;
  --rack-frame: #48515c;
  --rack-bay: #1e242b;
  --scrim: rgb(0 0 0 / 0.6);
  --shadow-1: 0 1px 2px rgb(0 0 0 / 0.3), 0 2px 10px rgb(0 0 0 / 0.25);
  --shadow-pop: 0 18px 50px rgb(0 0 0 / 0.55), 0 2px 6px rgb(0 0 0 / 0.3);
  --scroll-shade: rgb(0 0 0 / 0.55);
  color-scheme: dark;
}

/* ------------------------------------------------------------------ base */

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { height: 100%; }
body {
  height: 100%;
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 14px/1.45 var(--font-ui);
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}
button, input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3 { margin: 0; text-wrap: balance; }
p { margin: 0; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.ic {
  width: 16px; height: 16px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
.ic-sm { width: 13px; height: 13px; }
.mono { font-family: var(--font-mono); }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* --------------------------------------------------------------- buttons */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 32px; padding: 0 12px;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink);
  font-weight: 500; font-size: 13.5px; line-height: 1; white-space: nowrap;
  cursor: pointer;
  transition: background-color .12s, border-color .12s, color .12s;
}
.btn:hover { background: var(--surface-2); border-color: var(--ink-3); }
.btn:active { background: var(--surface-3); }
.btn:disabled { opacity: .42; cursor: default; background: var(--surface); border-color: var(--line-strong); }
.btn.icon { width: 32px; padding: 0; }
.btn.sm { height: 28px; padding: 0 10px; font-size: 13px; }
.btn.icon.sm { width: 28px; padding: 0; }
.btn.primary { background: var(--tape); border-color: var(--tape-edge); color: var(--tape-ink); font-weight: 600; }
.btn.primary:hover { background: var(--tape-hover); }
.btn.danger-text { border-color: transparent; background: transparent; color: var(--danger); padding-inline: 8px; }
.btn.danger-text:hover { background: var(--danger-soft); border-color: transparent; }
.btn.subtle { border-color: transparent; background: transparent; color: var(--ink-2); }
.btn.subtle:hover { background: var(--surface-2); color: var(--ink); }

/* ------------------------------------------------------------ app layout */

.app {
  height: 100%;
  display: grid;
  grid-template-columns: var(--bin-w) minmax(0, 1fr) var(--insp-w);
  grid-template-rows: auto minmax(0, 1fr);
  gap: 12px;
  padding-inline: 16px;
  padding-block: 10px 16px;
}

.topbar {
  grid-column: 1 / -1;
  display: flex; align-items: center; gap: 16px;
  min-width: 0;
}
.brand { display: flex; align-items: center; gap: 9px; flex: none; }
.brand-mark { width: 26px; height: 26px; }
.bm-frame { fill: var(--ink); }
.bm-tape { fill: var(--tape); }
.bm-a { fill: #2f6fdb; }
.bm-b { fill: #0f9d8a; }
.brand-name {
  font: 600 20px/1 var(--font-display);
  letter-spacing: .06em; text-transform: uppercase;
}
.plan-name-wrap { flex: 1 1 200px; min-width: 0; display: flex; align-items: center; gap: 10px; }
.plan-name-wrap::before { content: ""; width: 1px; height: 22px; background: var(--line-strong); flex: none; }
.plan-name {
  width: 100%; max-width: 420px; min-width: 0;
  height: 34px; padding: 0 8px;
  border: 1px solid transparent; border-radius: var(--r-sm);
  background: transparent;
  font: 500 17px/1 var(--font-ui);
  text-overflow: ellipsis;
}
.plan-name:hover { border-color: var(--line-strong); }
.plan-name:focus { border-color: var(--ink-3); background: var(--surface); outline: none; }
.tb-actions { display: flex; align-items: center; gap: 8px; flex: none; }
.tb-group { display: flex; gap: 4px; margin-right: 6px; }

/* Search */
.search { position: relative; flex: 0 1 340px; min-width: 180px; display: flex; align-items: center; }
.search input {
  width: 100%; height: 34px; padding: 0 34px 0 34px;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink);
}
.search input::placeholder { color: var(--ink-3); }
.search input:focus { outline: 2px solid var(--ink); outline-offset: -1px; border-color: transparent; }
.search-ic { position: absolute; left: 10px; color: var(--ink-3); pointer-events: none; }
.search-key { position: absolute; right: 8px; pointer-events: none; }
.search input:focus ~ .search-key, .search input:not(:placeholder-shown) ~ .search-key { display: none; }
.search-results {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 40;
  min-width: 320px; max-height: min(70vh, 520px); overflow: auto; padding: 6px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--shadow-pop);
}
.sr-group {
  display: flex; justify-content: space-between; padding: 8px 8px 4px;
  font: 600 11.5px/1 var(--font-display); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3);
}
.sr-group .mono { font-size: 11px; letter-spacing: 0; }
.sr-item {
  display: grid; grid-template-columns: 18px minmax(0, 1fr); column-gap: 8px; align-items: center;
  padding: 6px 8px; border-radius: var(--r-sm); cursor: pointer;
}
.sr-item:hover, .sr-item.is-active { background: var(--surface-2); }
.sr-item.is-active { box-shadow: inset 2px 0 0 var(--tape-edge); }
.sr-kind { grid-row: span 2; color: var(--ink-3); display: flex; }
.sr-name { font: 500 13.5px/1.25 var(--font-mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sr-detail { font-size: 12px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sr-more, .sr-empty, .sr-foot { padding: 6px 8px; font-size: 12.5px; color: var(--ink-3); }
.sr-foot { border-top: 1px solid var(--line); margin-top: 6px; padding-top: 8px; }

/* Menus */
.menu-wrap { position: relative; }
.menu {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 30;
  min-width: 240px; padding: 6px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--shadow-pop);
  display: flex; flex-direction: column; gap: 1px;
}
.menu-right { left: auto; right: 0; }
.menu-up { top: auto; bottom: calc(100% + 6px); }
.menu-rows { max-height: 60vh; overflow: auto; }
#cat-pg-menu { overflow-y: auto; overscroll-behavior: contain; }
.menu button[aria-checked="true"] { background: var(--surface-3); }
.menu button[aria-checked="true"] span { font-weight: 600; }
.menu button span .ic { vertical-align: -2px; }
.menu button {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  padding: 7px 10px; border: 0; border-radius: var(--r-sm);
  background: transparent; text-align: left; cursor: pointer;
}
.menu button span { font-weight: 500; }
.menu button small { color: var(--ink-3); font-size: 12px; }
.menu button:hover, .menu button:focus-visible { background: var(--surface-2); outline: none; }
.menu hr { width: 100%; border: 0; border-top: 1px solid var(--line); margin: 5px 0; }

/* Side panels */
.bin, .inspector {
  min-height: 0; overflow: auto;
  background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-md);
}
.panel-sec { padding: 14px 14px 16px; display: flex; flex-direction: column; gap: 10px; }
.panel-sec + .panel-sec { border-top: 1px solid var(--line); }
.sec-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 28px; }
.sec-head h2, .insp-sec h3 {
  font: 600 13px/1 var(--font-display);
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-2);
}
.sec-hint { color: var(--ink-3); font-size: 12.5px; line-height: 1.4; }

/* Beside the drawing, the device list scrolls on its own so the clusters stay in view. */
@media (min-width: 961px) {
  .bin { display: flex; flex-direction: column; }
  .bin-parts { flex: 0 1 auto; min-height: 0; }
  .bin-clusters { flex: none; max-height: 50%; min-height: 0; }
  .parts, .clusters { min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
  /* Shades at an edge with more rows beyond it: the covers scroll with the rows, the shades stay put. */
  .clusters {
    background:
      linear-gradient(var(--surface) 30%, transparent) top / 100% 24px no-repeat local,
      linear-gradient(transparent, var(--surface) 70%) bottom / 100% 24px no-repeat local,
      radial-gradient(farthest-side at 50% 0, var(--scroll-shade), transparent) top / 100% 8px no-repeat,
      radial-gradient(farthest-side at 50% 100%, var(--scroll-shade), transparent) bottom / 100% 8px no-repeat;
  }
  /* Room for hover shadows and focus rings inside the scroll box. */
  .parts { margin: -4px; padding: 4px; }
}

/* Parts bin */
.parts { display: flex; flex-direction: column; gap: 8px; }
.part {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto auto; gap: 8px 8px;
  padding: 10px 10px 9px;
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface); text-align: left;
  cursor: grab; touch-action: pan-x pan-y;
  transition: border-color .12s, box-shadow .12s, background-color .12s;
}
.part:hover { border-color: var(--line-strong); box-shadow: var(--shadow-1); }
.part:active { cursor: grabbing; }
.part.is-armed { border-color: var(--tape-edge); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--tape-edge); }
.part-art { grid-column: 1 / -1; height: 52px; display: flex; align-items: center; }
.part-reserved { border-style: dashed; }
.part-art svg { display: block; height: 100%; width: auto; max-width: min(100%, 188px); }
.part-meta { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.part-name { font-weight: 600; font-size: 14px; line-height: 1.2; }
.part-spec { font: 400 11.5px/1.3 var(--font-mono); color: var(--ink-3); }
.part-count {
  align-self: end;
  min-width: 26px; padding: 2px 6px; border-radius: 3px;
  background: var(--surface-3); color: var(--ink-2);
  font: 500 11.5px/1.3 var(--font-mono); text-align: center;
  font-variant-numeric: tabular-nums;
}
.part-count.is-zero { background: transparent; color: var(--ink-3); }

/* Cluster list */
.clusters { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.cl-row { display: flex; align-items: center; gap: 2px; border-radius: var(--r-sm); }
.cl-row:hover, .cl-row:focus-within { background: var(--surface-2); }
.cl-main {
  flex: 1; min-width: 0;
  display: flex; align-items: center; gap: 9px;
  padding: 6px 6px; border: 0; border-radius: var(--r-sm);
  background: transparent; text-align: left; cursor: pointer;
}
.cl-main[aria-pressed="true"] { background: var(--surface-3); }
.cl-main[aria-pressed="true"] .cl-name { font-weight: 600; }
.cl-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cl-count { font: 500 12px/1 var(--font-mono); color: var(--ink-3); font-variant-numeric: tabular-nums; }
.cl-edit, .cl-select { opacity: 0; }
.cl-row:hover .cl-edit, .cl-row:focus-within .cl-edit, .cl-row:hover .cl-select, .cl-row:focus-within .cl-select { opacity: 1; }
.sw {
  width: 16px; height: 12px; flex: none; border-radius: 2px;
  background: var(--c, var(--unassigned));
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.18);
}
.sw.sw-res { background: repeating-linear-gradient(135deg, var(--c) 0 2px, transparent 2px 4px); }
.cl-empty { color: var(--ink-3); font-size: 13px; padding: 4px 0; }

/* ---------------------------------------------------------------- stage */

.stage {
  position: relative; min-width: 0; min-height: 0;
  display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface-2);
  overflow: hidden;
}
/* The drawing area below the nav bar; the placement hint and zoom float over it. */
.viewport { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
.canvas {
  flex: 1; min-height: 0; overflow: auto;
  display: flex; padding: 22px 22px 64px;
  overscroll-behavior: contain;
}
.canvas.is-panning { cursor: grabbing; }
.canvas.is-map { display: block; padding: 0; }

/* Floor and row navigation */
.nav {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 10px; background: var(--surface); border-bottom: 1px solid var(--line);
}
.floor-tabs { display: flex; gap: 4px; flex-wrap: wrap; min-width: 0; }
.ftab {
  height: 28px; padding: 0 10px; border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink-2); cursor: pointer; font-size: 13px; font-weight: 500; white-space: nowrap;
  max-width: 170px; overflow: hidden; text-overflow: ellipsis;
}
.ftab:hover { background: var(--surface-2); color: var(--ink); }
.ftab[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--surface); }
.ftab.is-selected { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--tape-edge); }
.ftab-add { width: 28px; padding: 0; display: grid; place-items: center; border-style: dashed; }
.row-nav { display: flex; align-items: center; gap: 4px; }
.row-btn { min-width: 110px; justify-content: space-between; font-weight: 600; }
.row-btn span { max-width: 160px; overflow: hidden; text-overflow: ellipsis; }
.nav-spacer { flex: 1; }
.view-toggle { background: var(--surface); --seg-pad: 10px; }

.floormap { padding: 18px 20px 72px; display: flex; flex-direction: column; gap: 16px; min-width: max-content; }
.fm-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.fm-title { min-width: 0; max-width: min(720px, 100%); }
.fm-title h2 { font: 600 22px/1.1 var(--font-display); letter-spacing: .01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fm-title p { color: var(--ink-2); font-size: 13px; margin-top: 3px; }
.fm-metric { background: var(--surface); }
.fm-rows { display: flex; flex-direction: column; gap: 12px; }
.fm-row {
  padding: 10px 12px 12px; border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface);
}
.fm-row.is-current { border-color: var(--tape-edge); box-shadow: inset 3px 0 0 var(--tape); }
.fm-row.is-selected { box-shadow: 0 0 0 2px var(--tape-edge); }
.fm-row-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.fm-row-open {
  display: inline-flex; align-items: center; gap: 4px; padding: 2px 4px; margin-left: -4px;
  border: 0; border-radius: 3px; background: none; cursor: pointer;
  font: 600 16px/1.2 var(--font-display); letter-spacing: .02em;
  max-width: 320px; min-width: 0;
}
.fm-row-open > :first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fm-row-open:hover { background: var(--surface-2); }
.fm-row-meta { flex: 1; color: var(--ink-3); font-size: 12.5px; }
.fm-racks { display: flex; align-items: flex-end; gap: 8px; }
.fm-rack {
  position: relative; width: 62px; flex: none;
  display: flex; flex-direction: column; align-items: stretch; gap: 4px;
  padding: 5px 5px 4px; border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  background: var(--surface-2); cursor: pointer; text-align: center;
}
.fm-rack:hover { border-color: var(--ink-3); box-shadow: var(--shadow-1); }
.fm-rack.is-selected { outline: 2px solid var(--tape-edge); outline-offset: 1px; }
.fm-rack.is-over { border-color: var(--danger); }
.fm-rack.is-over .fm-meter span { background: var(--danger); }
.fm-rack.is-over .fm-val { color: var(--danger); font-weight: 600; }
.fm-rack.is-hit { box-shadow: 0 0 0 3px var(--tape); }
.fm-elev { position: relative; display: block; background: var(--rack-bay); border: 2px solid var(--rack-frame); border-radius: 2px; }
.fm-elev i { position: absolute; left: 1px; right: 1px; background: var(--c, var(--unassigned)); border-radius: 1px; box-shadow: inset 0 -1px 0 rgb(0 0 0 / 0.25); }
.fm-elev i.res { background: repeating-linear-gradient(135deg, var(--c, var(--ink-3)) 0 1.5px, transparent 1.5px 4px); box-shadow: none; opacity: .8; }
.fm-elev i.dim { opacity: .18; }
.fm-meter { height: 4px; border-radius: 2px; background: var(--surface-3); overflow: hidden; display: block; }
.fm-meter span { display: block; height: 100%; background: var(--ink); }
.fm-name { font: 600 11.5px/1.1 var(--font-mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fm-val { font: 500 10.5px/1 var(--font-mono); color: var(--ink-3); }
.fm-hits {
  position: absolute; top: -8px; right: -8px; min-width: 18px; height: 18px; padding: 0 4px;
  border-radius: 9px; background: var(--tape); color: var(--tape-ink); font: 600 11px/18px var(--font-mono);
}
.fm-add {
  width: 36px; align-self: stretch; min-height: 60px; flex: none;
  border: 1.5px dashed var(--line-strong); border-radius: var(--r-sm); background: transparent;
  color: var(--ink-3); cursor: pointer; display: grid; place-items: center;
}
.fm-add:hover { color: var(--ink); border-color: var(--ink-3); }
.fm-add-row { align-self: flex-start; }
.scene {
  display: block; flex: none; margin: auto;
  border-radius: 2px;
  box-shadow: var(--shadow-1);
  user-select: none; -webkit-user-select: none;
}
.scene .dev { cursor: grab; outline: none; }
.scene .dev-hl { opacity: 0; transition: opacity .12s; pointer-events: none; }
.scene .dev:hover .dev-hl, .scene .dev:focus-visible .dev-hl { opacity: .7; }
.scene .dev.is-dragging { opacity: .28; }
.scene .rack-head { cursor: pointer; }
.scene .add-rack { cursor: pointer; outline: none; }
.scene .add-rack:hover rect, .scene .add-rack:focus-visible rect { stroke: var(--ink); fill-opacity: 1; }
.stage.is-armed .scene, .stage.is-armed .scene .dev, .stage.is-armed .scene .rack-head { cursor: crosshair; }
body.is-dragging, body.is-dragging * { cursor: grabbing !important; }

.notice {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  padding: 9px 12px 9px 14px;
  background: var(--surface); border-bottom: 1px solid var(--line);
  font-size: 13.5px;
}
.notice p { min-width: 0; }
.notice-actions { display: flex; gap: 6px; }

.armed-hint {
  position: absolute; left: 50%; top: 12px; transform: translateX(-50%); z-index: 5;
  display: flex; align-items: center; gap: 10px;
  max-width: calc(100% - 32px);
  padding: 6px 8px 6px 12px; border-radius: var(--r-sm);
  background: var(--tape); color: var(--tape-ink);
  box-shadow: var(--shadow-pop);
  font-size: 13px; font-weight: 500;
}
.armed-hint kbd { font: 500 11px/1 var(--font-mono); padding: 2px 5px; border-radius: 3px; background: rgb(0 0 0 / 0.1); }
.armed-hint button {
  border: 0; background: rgb(0 0 0 / 0.1); color: inherit; border-radius: 3px;
  width: 24px; height: 24px; display: grid; place-items: center; cursor: pointer;
}
.armed-hint button:hover { background: rgb(0 0 0 / 0.18); }

.zoom {
  position: absolute; right: 12px; bottom: 12px; z-index: 5;
  display: flex; align-items: center; gap: 4px;
  padding: 4px; border-radius: var(--r-md);
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-1);
}
.zoom-level {
  min-width: 52px; height: 28px; border: 0; border-radius: var(--r-sm);
  background: transparent; cursor: pointer;
  font: 500 12px/1 var(--font-mono); font-variant-numeric: tabular-nums; color: var(--ink-2);
}
.zoom-level:hover { background: var(--surface-2); color: var(--ink); }

.drag-chip {
  position: fixed; left: 0; top: 0; z-index: 60; pointer-events: none;
  display: flex; align-items: center; gap: 7px;
  padding: 5px 9px; border-radius: var(--r-sm);
  background: var(--ink); color: var(--surface);
  font-size: 12.5px; font-weight: 500; white-space: nowrap;
  box-shadow: var(--shadow-pop);
}
.drag-chip::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--ink-3); flex: none; }
.drag-chip.ok::before { background: var(--ok); }
.drag-chip.bad::before { background: var(--danger); }
.drag-chip .mono { font-size: 11.5px; opacity: .85; }

/* ------------------------------------------------------------ inspector */

.inspector { display: flex; flex-direction: column; }
.insp-head { padding: 16px 16px 14px; display: flex; flex-direction: column; gap: 6px; border-bottom: 1px solid var(--line); }
.kicker {
  display: flex; align-items: center; gap: 8px;
  font: 600 12px/1 var(--font-display); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3);
}
.kicker .sw { width: 14px; height: 10px; }
.name-input {
  width: calc(100% + 14px); height: 38px; margin-left: -7px;
  padding: 0 7px; border: 1px solid transparent; border-radius: var(--r-sm);
  background: transparent;
  font: 600 19px/1 var(--font-mono);
}
.name-input.ui { font-family: var(--font-ui); font-size: 20px; }
.name-input:hover { border-color: var(--line-strong); }
.name-input:focus { border-color: var(--ink-3); background: var(--surface-2); outline: none; }
.insp-where { font: 400 13px/1.3 var(--font-mono); color: var(--ink-2); }
.insp-sub { font-size: 12.5px; color: var(--ink-3); }
.multi-title { font: 600 22px/1.1 var(--font-display); }
.warn-note { color: var(--danger); font-size: 13px; }
.field-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px 8px; }
.field-grid .span2 { grid-column: 1 / -1; }
.inline { display: flex; gap: 6px; align-items: center; }
.inline > input, .inline > select { flex: 1; }
.btn-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 6px; }
.stepper { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.stepper-val { min-width: 24px; text-align: center; font-size: 16px; font-weight: 600; }
.meter { display: flex; flex-direction: column; gap: 4px; }
.meter-top { display: flex; justify-content: space-between; gap: 8px; font-size: 12.5px; color: var(--ink-3); }
.meter-top .mono { color: var(--ink); font-size: 12.5px; }
.meter-track { height: 6px; border-radius: 3px; background: var(--surface-3); overflow: hidden; }
.meter-track span { display: block; height: 100%; background: var(--tape-edge); }
.meter.no-max .meter-track { opacity: .5; }
.meter.is-over .meter-top .mono { color: var(--danger); font-weight: 600; }
.meter.is-over .meter-track span { background: var(--danger); }
.insp-note { color: var(--ink-2); font-size: 13.5px; }
.hint-touch { display: none; }
@media (hover: none) {
  /* As specific as .insp-sec, which comes later and would show the shortcuts again. */
  .hint-pointer, .insp-sec.keys-sec, .keys-sec { display: none; }
  .hint-touch { display: inline; }
  /* No hover to reveal that titles are editable: outline them faintly. */
  .plan-name, .name-input:not(.name-static) { border-color: var(--line); }
}
.insp-sec { padding: 14px 16px 16px; display: flex; flex-direction: column; gap: 10px; }
.insp-sec + .insp-sec { border-top: 1px solid var(--line); }
.insp-actions { display: flex; gap: 8px; padding: 14px 16px 18px; border-top: 1px solid var(--line); margin-top: auto; flex-wrap: wrap; }
.insp-actions .btn { flex: 1; }
/* Beside the drawing, a selection's Duplicate and Delete stay in reach below its long form. */
@media (min-width: 961px) {
  .insp-actions.is-pinned { position: sticky; bottom: 0; z-index: 1; background: var(--surface); }
}

.pos-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; }
.nudge { display: flex; gap: 6px; }
.nudge .btn { flex: 1; }

.stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 10px; margin: 0; }
.stats div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.stats dt { font-size: 12px; color: var(--ink-3); }
.stats dd { margin: 0; font: 500 17px/1.2 var(--font-mono); font-variant-numeric: tabular-nums; }
.stats dd small { font-size: 12px; color: var(--ink-3); font-weight: 400; }

.rack-bars { display: flex; flex-direction: column; gap: 10px; }
.rack-bar { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 8px; align-items: baseline; border: 0; background: none; padding: 0; text-align: left; cursor: pointer; }
.rack-bar .rb-name { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rack-bar .rb-val { font: 500 12px/1 var(--font-mono); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.rack-bar .rb-track { grid-column: 1 / -1; height: 6px; border-radius: 3px; background: var(--surface-3); overflow: hidden; display: flex; }
.rack-bar .rb-fill { height: 100%; background: var(--ink); }
.rack-bar .rb-res { height: 100%; background: repeating-linear-gradient(135deg, var(--ink-3) 0 2px, transparent 2px 4px); }
.rack-bar.is-over .rb-val { color: var(--danger); font-weight: 600; }
.rack-bar:hover .rb-name { text-decoration: underline; text-underline-offset: 3px; }

.type-table { width: 100%; border-collapse: collapse; font-size: 13px; font-variant-numeric: tabular-nums; }
.type-table th { font-weight: 500; color: var(--ink-3); font-size: 12px; text-align: right; padding: 0 0 6px; }
.type-table th:first-child { text-align: left; }
.type-table td { padding: 5px 0; border-top: 1px solid var(--line); text-align: right; font-family: var(--font-mono); font-size: 12.5px; }
.type-table td:first-child { text-align: left; font-family: var(--font-ui); font-size: 13px; }
.type-table tfoot td { font-weight: 600; }

.contents { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.contents li + li { border-top: 1px solid var(--line); }
.contents button {
  width: 100%; display: grid; grid-template-columns: minmax(58px, auto) 16px minmax(0, 1fr); gap: 8px; align-items: center;
  padding: 6px 4px; border: 0; background: transparent; text-align: left; cursor: pointer; border-radius: 3px;
}
.contents button:hover { background: var(--surface-2); }
.contents .u { font: 500 11.5px/1 var(--font-mono); color: var(--ink-3); font-variant-numeric: tabular-nums; }
/* A list whose first column is wider than its least (places in a rack, cable types) gives it the width of its longest, so that every row lines up. */
.contents[style*="--u-w"] .u { width: var(--u-w); white-space: nowrap; }
.contents .nm { font: 500 13px/1.2 var(--font-mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.contents .sw { width: 14px; height: 10px; }
.empty-note { color: var(--ink-3); font-size: 13px; }

.keys { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px 12px; margin: 0; font-size: 12.5px; align-items: baseline; }
.keys dt { white-space: nowrap; }
.keys dd { margin: 0; color: var(--ink-2); }
kbd {
  display: inline-block; min-width: 20px; padding: 2px 5px;
  border: 1px solid var(--line-strong); border-bottom-width: 2px; border-radius: 3px;
  background: var(--surface); font: 500 11px/1.2 var(--font-mono); text-align: center; color: var(--ink);
}

/* ---------------------------------------------------------------- forms */

.field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.field > label, .field > .label { font-size: 12.5px; font-weight: 500; color: var(--ink-2); }
.field-row { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; }
.field-qty { width: 96px; }
/* Zero specificity, so a classed field (the plan name, the inspector's name heading) overrides these. */
:where(input[type="text"], input[type="number"], select, textarea) {
  width: 100%; min-width: 0;
  padding: 7px 9px;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink);
}
:where(input[type="text"], input[type="number"], select) { height: 34px; }
:where(textarea) { resize: vertical; line-height: 1.4; }
:where(input, select, textarea):focus { outline: 2px solid var(--ink); outline-offset: -1px; border-color: transparent; }
.dlg input.mono, textarea.mono { font-family: var(--font-mono); font-size: 13px; }
#place-name { font-size: 15px; font-weight: 500; }

.seg { display: inline-flex; border: 1px solid var(--line-strong); border-radius: var(--r-sm); overflow: hidden; height: 34px; }
/* Segments made of buttons: the view toggle, the floor map's meter switch, the catalog tabs. */
.seg > button {
  display: flex; align-items: center; gap: 5px; padding: 0 var(--seg-pad, 11px); border: 0;
  background: transparent; color: var(--ink-2); cursor: pointer; font-size: 13px;
}
.seg > button + button { border-left: 1px solid var(--line-strong); }
.seg > button[aria-pressed="true"], .seg > button[aria-selected="true"] { background: var(--ink); color: var(--surface); }
.seg > button:focus-visible { outline: 2px solid var(--tape); outline-offset: -3px; }
.seg label { position: relative; display: flex; }
.seg input { position: absolute; opacity: 0; pointer-events: none; }
.seg span { display: flex; align-items: center; gap: 5px; padding: 0 11px; cursor: pointer; font-size: 13px; color: var(--ink-2); }
.seg label + label span { border-left: 1px solid var(--line-strong); }
.seg input:checked + span { background: var(--ink); color: var(--surface); }
.seg input:focus-visible + span { outline: 2px solid var(--tape); outline-offset: -3px; }

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip { position: relative; display: flex; }
.chip input { position: absolute; opacity: 0; pointer-events: none; }
.chip span {
  display: inline-flex; align-items: center; gap: 7px;
  height: 30px; padding: 0 10px 0 8px; max-width: 220px;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  background: var(--surface); cursor: pointer; font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chip span:hover { border-color: var(--ink-3); }
.chip input:checked + span { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); font-weight: 600; }
.chip input:focus-visible + span { outline: 2px solid var(--ink); outline-offset: 2px; }
.chip.chip-new span { border-style: dashed; color: var(--ink-2); }
.chip.chip-check span { height: 26px; font: 500 12px/1 var(--font-mono); padding: 0 8px; }
.check { display: flex; align-items: center; gap: 8px; font-size: 13.5px; cursor: pointer; }
.check input, .radio input { width: 16px; height: 16px; margin: 0; accent-color: var(--ink); flex: none; }
.radios { display: flex; flex-direction: column; gap: 6px; }
.radio { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 14px; }
.radio small { color: var(--ink-3); font-size: 12.5px; margin-left: 4px; }
.spread { display: flex; flex-direction: column; gap: 8px; }

.swatches { display: flex; flex-wrap: wrap; gap: 6px; }
.swatch { position: relative; display: flex; }
.swatch input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
.swatch span {
  width: 28px; height: 28px; border-radius: var(--r-sm);
  background: var(--c); cursor: pointer;
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.18);
  display: grid; place-items: center;
}
.swatch input:checked + span { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--ink); }
.swatch input:focus-visible + span { outline: 2px solid var(--ink); outline-offset: 4px; }
.swatch.custom { position: relative; }
.swatch.custom input[type="color"] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; border: 0; padding: 0; }
.swatch.custom span { background: conic-gradient(from 0deg, #d64545, #d9a21b, #3aa655, #1f9fc9, #5b62d6, #d94c8a, #d64545); color: #fff; }
.swatch.custom.is-on span { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--ink); background: var(--c); }
.swatch.custom input[type="color"]:focus-visible + span { outline: 2px solid var(--ink); outline-offset: 4px; }

.preview-line { font: 400 12.5px/1.4 var(--font-mono); color: var(--ink-2); min-height: 1.4em; }
.preview-line.bad, .form-error { color: var(--danger); }
.form-error { font-size: 13px; }
.new-cluster { display: flex; flex-direction: column; gap: 12px; padding: 12px; border-radius: var(--r-sm); background: var(--surface-2); border: 1px solid var(--line); }
.cluster-preview svg { display: block; width: 100%; height: auto; }

/* --------------------------------------------------------------- dialogs */

.dlg {
  width: min(460px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  padding: 0; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-pop);
}
.dlg-sm { width: min(400px, calc(100vw - 32px)); }
.dlg-wide { width: min(760px, calc(100vw - 32px)); }
.dlg-shell { display: flex; flex-direction: column; max-height: inherit; }
.dlg .tabs { margin-top: 6px; height: 32px; --seg-pad: 12px; max-width: 100%; flex: none; overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; }
.dlg .tabs > button { flex: none; white-space: nowrap; }
/* Wide enough for a cable type's sub line and the port table beside the list. */
#dlg-catalog { width: min(880px, calc(100vw - 32px)); }
.dlg-body.catalog { display: grid; grid-template-columns: 290px minmax(0, 1fr); grid-auto-rows: max-content; gap: 16px; align-items: start; min-height: 360px; }
.cat-list { display: flex; flex-direction: column; gap: 4px; max-height: 50vh; overflow: auto; padding: 2px; }
.cat-item {
  position: relative;
  display: grid; grid-template-columns: 14px 64px minmax(0, 1fr) auto; gap: 8px; align-items: center;
  padding: 6px 8px; border: 1px solid transparent; border-radius: var(--r-sm); background: transparent; text-align: left; cursor: pointer;
}
.cat-item:hover { background: var(--surface-2); }
.cat-item[aria-selected="true"] { border-color: var(--ink); background: var(--surface-2); }
.cat-grip { align-self: stretch; display: grid; place-items: center; margin-left: -4px; color: var(--ink-3); cursor: grab; touch-action: none; }
.cat-item:hover .cat-grip { color: var(--ink); }
.cat-list.is-sorting, .cat-list.is-sorting * { cursor: grabbing; }
.cat-item.is-dragging { opacity: .4; }
.cat-item.drop-before::before, .cat-item.drop-after::after {
  content: ""; position: absolute; left: 4px; right: 4px; height: 3px; border-radius: 2px; background: var(--tape-edge); pointer-events: none;
}
.cat-item.drop-before::before { top: -4px; }
.cat-item.drop-after::after { bottom: -4px; }
.cat-art { width: 64px; height: auto; max-height: 26px; display: block; }
.cat-rack { display: block; width: 18px; height: calc(var(--u) * 0.5px); margin: 0 auto; border: 3px solid var(--rack-frame); border-radius: 2px; background: var(--rack-bay); }
.cat-meta { display: flex; flex-direction: column; min-width: 0; }
.cat-name { font-weight: 600; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cat-sub { font: 400 11.5px/1.3 var(--font-mono); color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Cable types and transceivers say more: their sub line takes two lines when it needs them. */
#cat-list:is([data-tab="cables"], [data-tab="transceivers"]) .cat-sub { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
.cat-count { font: 500 11.5px/1 var(--font-mono); color: var(--ink-3); padding: 3px 6px; border-radius: 3px; background: var(--surface-3); }
.cat-form { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.cat-preview { padding: 12px; border-radius: var(--r-sm); background: var(--surface-2); border: 1px solid var(--line); display: grid; place-items: center; }
.cat-preview svg { width: 100%; max-width: 360px; height: auto; max-height: 200px; }
.cat-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cat-form input:disabled { opacity: .55; }
.field-hint { font-size: 11.5px; color: var(--ink-3); }

/* Catalog: a device type's General | Ports switch, its ports, and the drawings of cables and transceivers. */
.cat-subs { height: 30px; align-self: flex-start; flex: none; }
.cat-subs > button { font-size: 13px; }
.cat-preview-2 { grid-template-columns: 34px minmax(0, 1fr); gap: 10px 8px; align-items: center; justify-items: start; }
.cat-preview-2 svg { max-width: 380px; }
.cat-side { font: 600 10.5px/1 var(--font-display); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); }
/* On a phone the port table scrolls sideways rather than squeezing the names. */
.pt-wrap { position: relative; overflow-x: auto; margin: 0 -4px; }
.pt-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.pt-table td:first-child input { min-width: 104px; }
.pt-table th { text-align: left; font-weight: 500; font-size: 11.5px; color: var(--ink-3); padding: 0 4px 6px; }
.pt-table td { padding: 3px 4px; }
.pt-table :where(input, select) { height: 30px; padding: 0 6px; font-size: 13px; }
.pt-table td:first-child { width: 30%; }
.pt-table td:nth-child(2) select { min-width: 90px; }
.pt-table td:nth-child(3) select { min-width: 64px; }
.pt-table td:nth-child(4) select { min-width: 66px; }
.pt-table .pt-count { text-align: right; color: var(--ink-2); padding-right: 6px; }
.pt-table td:last-child { width: 32px; }
.cat-slack-hint { align-self: end; padding-bottom: 8px; }
.cat-note { display: flex; gap: 8px; align-items: flex-start; font-size: 12.5px; color: var(--ink-2); padding: 8px 10px; border-radius: var(--r-sm); background: var(--surface-2); }
.cat-note .ic { flex: none; margin-top: 2px; color: var(--ink-3); }
.cat-art .ca-cord { fill: none; stroke: var(--ink-2); stroke-width: 2.6; stroke-linecap: round; }
.cat-art .ca-leg { stroke-width: 1.7; }
.cat-art .ca-plug { fill: var(--surface-3); stroke: var(--ink-3); stroke-width: .8; }
.cat-art .ca-fin { fill: none; stroke: var(--ink-3); stroke-width: .6; opacity: .7; }
.cat-art .ca-face { fill: var(--ink-3); }
.cat-art .ca-socket { fill: var(--surface); }
.cat-art .ca-bail { fill: none; stroke-width: 2; stroke-linejoin: round; }
/* A radio segment that fills its field: Front to front | Back to front. */
.seg-fill { display: flex; }
.seg-fill label { flex: 1; }
.seg-fill span { flex: 1; justify-content: center; white-space: nowrap; }
.plan-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.plan-item { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--r-sm); }
.plan-item.is-current { border-color: var(--tape-edge); background: var(--surface-2); }
.plan-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.plan-name-l { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-sub { font-size: 12.5px; color: var(--ink-3); }
.plan-actions { display: flex; align-items: center; gap: 6px; }
.plan-now { font: 600 11px/1 var(--font-mono); text-transform: uppercase; letter-spacing: .06em; color: var(--ink-2); padding: 0 6px; }
.report-list { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--ink-2); max-height: 50vh; overflow: auto; }
#share-url { font-size: 12px; word-break: break-all; }
.dlg::backdrop { background: var(--scrim); }
.dlg form { display: flex; flex-direction: column; max-height: inherit; }
.dlg-head { padding: 18px 20px 12px; display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.dlg-head h2 { font: 600 22px/1.15 var(--font-display); letter-spacing: .01em; }
.dlg-sub { color: var(--ink-2); font-size: 13.5px; }
.dlg-sub.mono { font-family: var(--font-mono); font-size: 12.5px; }
.dlg-body { padding: 4px 20px 16px; display: flex; flex-direction: column; gap: 14px; overflow: auto; }
.dlg-body p { color: var(--ink-2); }
.dlg-body .form-error { color: var(--danger); }
.dlg-foot {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 20px; border-top: 1px solid var(--line); background: var(--surface-2);
  border-radius: 0 0 8px 8px;
}
.dlg-foot .spacer, .dlg-foot > :first-child:not(.spacer):not(.danger-text):not(.menu-wrap) { margin-left: auto; }
.spacer { flex: 1; }
.tape {
  display: inline-block; padding: 3px 8px 2px;
  background: var(--tape); color: var(--tape-ink);
  box-shadow: 1px 1px 0 var(--tape-edge);
  font: 600 11px/1.3 var(--font-mono); letter-spacing: .06em; text-transform: uppercase;
  border-radius: 2px;
}

/* ---------------------------------------------------------------- toasts */

.toasts {
  position: fixed; left: 50%; bottom: calc(20px + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%);
  z-index: 80; display: flex; flex-direction: column; align-items: center; gap: 8px;
  width: max-content; max-width: calc(100vw - 32px); pointer-events: none;
}
.toast {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 8px 8px 14px; border-radius: var(--r-sm);
  background: var(--ink); color: var(--surface);
  box-shadow: var(--shadow-pop); font-size: 13.5px;
  pointer-events: auto;
  animation: toast-in .16s ease-out;
}
.toast.warn { border-left: 4px solid var(--danger); }
.toast:not(:has(button)) { padding-right: 14px; }
.toast button {
  border: 0; border-radius: 3px; padding: 5px 9px; cursor: pointer;
  background: var(--tape); color: var(--tape-ink); font-weight: 600; font-size: 13px;
}
@keyframes toast-in { from { opacity: 0; transform: translateY(6px); } }

/* ----------------------------------------------------------------- print */

.print-root { display: none; }
@media print {
  html, body { height: auto; overflow: visible; background: #fff; }
  body > :not(.print-root) { display: none !important; }
  .print-root { display: block; }
  .print-page { height: 100vh; display: flex; align-items: center; justify-content: center; break-after: page; break-inside: avoid; }
  .print-page:last-child { break-after: auto; }
  .print-page svg { display: block; width: 100%; height: 100%; }
}

/* ------------------------------------------------------------ responsive */

/* Icons alone only where the labels would crowd out the plan name, or wrap the toolbar. */
@media (min-width: 961px) and (max-width: 1080px), (max-width: 700px) {
  .tb-actions .btn:not(.icon) span { display: none; }
  .tb-actions .btn:not(.icon) { padding: 0 9px; }
}
@media (max-width: 1180px) {
  :root { --bin-w: 228px; --insp-w: 264px; }
  .brand-name { display: none; }
  .search { flex-basis: 240px; }
}

@media (max-width: 960px) {
  body { overflow: auto; }
  .app {
    height: auto; min-height: 100%;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto;
  }
  .brand-name { display: inline; }
  .topbar { flex-wrap: wrap; gap: 10px 12px; }
  .plan-name-wrap { order: 3; flex-basis: 100%; }
  .search { order: 4; flex: 1 1 100%; }
  .dlg-body.catalog { grid-template-columns: minmax(0, 1fr); }
  .cat-list { max-height: 30vh; }
  .plan-name-wrap::before { display: none; }
  .plan-name { max-width: none; }
  .tb-actions { margin-left: auto; flex: 0 1 auto; min-width: 0; flex-wrap: wrap; justify-content: flex-end; row-gap: 8px; }
  .stage { height: 72vh; min-height: 420px; }
  .bin { overflow: visible; }
  .parts { flex-direction: row; overflow-x: auto; padding-bottom: 4px; scroll-snap-type: x proximity; }
  .part { flex: 0 0 200px; scroll-snap-align: start; }
  .inspector { overflow: visible; }
  .cl-edit { opacity: 1; }
  /* Clusters in columns where there is room, so the drawing moves up the page. */
  .clusters { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); column-gap: 16px; }
}

@media (max-width: 560px) {
  .tb-actions { flex-basis: 100%; justify-content: flex-start; }
  .tb-actions .btn span { display: none; }
  .tb-actions .btn:not(.icon) { padding: 0 9px; }
  .tb-group { margin-right: 0; }
  .brand-name { font-size: 18px; }
  .zoom .btn.sm span { display: none; }
  .view-toggle { --seg-pad: 8px; }
  .nav-spacer { display: none; }
  .row-btn { min-width: 0; }
  .field-grid { grid-template-columns: minmax(0, 1fr); }
  .plan-item { flex-wrap: wrap; }
  .armed-hint { font-size: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}
