:root {
  --bg: #14161a; --panel: #1b1e24; --panel2: #21252d; --line: #2c313b;
  --fg: #e4e7ec; --dim: #a7b0bf; --dim2: #8b95a5;
  --accent: #6ea8fe; --ok: #5dd39e; --warn: #e8b862; --err: #f2777a;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  background: var(--bg); color: var(--fg); font: 13px/1.5 var(--mono);
  display: grid; grid-template-rows: auto auto auto 1fr; overflow: hidden;
}
button, input, select, textarea {
  font: inherit; color: var(--fg); background: var(--panel2);
  border: 1px solid var(--line); border-radius: 4px; padding: 3px 7px;
}
/* Without this, any anchor outside nav fell through to the UA stylesheet's dark
   blue-violet, which on a #14161a background was effectively unreadable. */
a { color: var(--accent); }
a:hover { text-decoration: underline; }

button { cursor: pointer; }
button:hover:not(:disabled) { border-color: var(--accent); }
button:disabled { opacity: .4; cursor: default; }
input:focus, select:focus, textarea:focus { outline: 1px solid var(--accent); border-color: var(--accent); }
.btn-primary { background: #24405f; border-color: #34567d; }

header {
  /* wrap is load bearing: the toolbar's 546px minimum width used to force the
     whole body wider than a narrow window, and because body is overflow:hidden
     that surplus was clipped and unreachable rather than merely scrolled. */
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 7px 10px;
  background: var(--panel); border-bottom: 1px solid var(--line);
}
header .brand { font-weight: 600; letter-spacing: .5px; margin-right: 4px; }
header .file { color: var(--dim); }
header .dot { color: var(--warn); }
header .spacer { flex: 1; }
header .stat { color: var(--dim); }
header .gh {
  color: var(--dim); text-decoration: none; padding: 3px 7px;
  border: 1px solid var(--line); border-radius: 4px;
}
header .gh:hover { color: var(--fg); border-color: var(--accent); text-decoration: none; }
.pill { padding: 1px 6px; border-radius: 9px; border: 1px solid var(--line); }
.pill.err { color: var(--err); border-color: #5a3134; }
.pill.warn { color: var(--warn); border-color: #55442a; }
.pill.ok { color: var(--ok); border-color: #2c5544; }

main { display: grid; grid-template-columns: 268px 1fr; min-height: 0; }
#banner {
  display: flex; gap: 10px; align-items: center; padding: 8px 12px;
  background: #3a2f18; border-bottom: 1px solid #55442a; color: #f0d9a8;
}
#banner .grow { flex: 1; }

/* Toolbar. The application's own navigation lives here so the sidebar can be
   nothing but the user's inventory. Everything is a visible control: burying
   "add a node" one click deep inside a menu was backwards for an editor whose
   whole job is adding nodes. */
#menubar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--panel); border-bottom: 1px solid var(--line);
  padding: 5px 8px;
}
#menubar .tgroup { display: flex; gap: 5px; }
#menubar .tbtn {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--panel2); border: 1px solid var(--line); border-radius: 4px;
  padding: 4px 9px;
}
#menubar .tbtn:hover { border-color: var(--accent); background: #24405f; }
#menubar .tbtn .plus { color: var(--ok); font-weight: 600; }
#menubar .tbtn.icon { font-size: 15px; line-height: 1; padding: 3px 8px; }
#menubar .tbtn.on { background: #24405f; border-color: var(--accent); }

/* wrap: seven tabs plus three buttons have a wide minimum, and body is
   overflow:hidden, so anything past the edge is clipped and unreachable. */
#menubar .tabs { display: flex; flex-wrap: wrap; gap: 2px; border-left: 1px solid var(--line); padding-left: 10px; }
#menubar .tab {
  background: none; border: 1px solid transparent; border-bottom: 2px solid transparent;
  border-radius: 0; padding: 4px 10px; color: var(--dim);
}
#menubar .tab:hover { color: var(--fg); background: var(--panel2); }
#menubar .tab.on { color: var(--fg); border-bottom-color: var(--accent); background: none; }

#menubar .tright { margin-left: auto; display: flex; align-items: center; gap: 8px; }
#menubar .where { color: var(--dim2); }

nav {
  background: var(--panel); border-right: 1px solid var(--line);
  overflow: auto; padding: 8px 0;
  display: flex; flex-direction: column;
}
/* Three regions that must not look alike: app views, your inventory, and the
   buttons that create things. Previously all three were one flat list of
   identical rows, so "+ Node" was indistinguishable from a node. */
nav .navsec { padding-bottom: 6px; }
nav .navsec + .navsec { border-top: 1px solid var(--line); margin-top: 6px; padding-top: 2px; }
nav h4 {
  display: flex; align-items: center;
  margin: 12px 10px 4px; font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--dim2); font-weight: 600;
}
nav h4 .tally {
  margin-left: auto; letter-spacing: 0; font-weight: 400;
  background: var(--panel2); border: 1px solid var(--line);
  border-radius: 8px; padding: 0 6px; font-size: 10px;
}
/* namespace groups come from the user's own ids, so they sit a level below the
   region heading rather than competing with it */
nav h5 {
  margin: 8px 10px 2px 16px; font-size: 10px; font-weight: 400;
  color: var(--dim2); text-transform: lowercase; letter-spacing: .04em;
  border-bottom: 1px dotted #2c313b; padding-bottom: 2px;
}
nav .navinv .row { padding-left: 18px; }
nav .navnote { color: var(--dim2); font-size: 11px; padding: 2px 10px 6px; }

/* actions live at the bottom and are buttons, not rows */
nav .navadd { margin-top: auto; border-top: 1px solid var(--line); padding-top: 10px; }
nav .navbtns { display: flex; flex-direction: column; gap: 5px; padding: 0 10px 4px; }
nav .navbtn {
  display: flex; align-items: center; gap: 7px; width: 100%;
  justify-content: flex-start; text-align: left;
  background: var(--panel2); border: 1px solid var(--line); border-radius: 4px;
  padding: 5px 8px; cursor: pointer;
}
nav .navbtn:hover { border-color: var(--accent); background: #24405f; }
nav .navbtn .plus { color: var(--ok); font-weight: 600; width: 9px; }
nav .row {
  display: flex; align-items: center; gap: 6px; padding: 3px 10px;
  cursor: pointer; white-space: nowrap;
  color: inherit; text-decoration: none;
}
nav .row:focus-visible { outline: 1px solid var(--accent); outline-offset: -1px; }
nav .row:hover { background: var(--panel2); }
nav .row.on { background: #24405f; }
nav .row .count { margin-left: auto; color: var(--dim2); font-size: 11px; }
nav .row .tw { width: 12px; color: var(--dim2); text-align: center; }
/* Both can be cut, and min-width:0 is what lets a flex item shrink below its
   content at all. The purpose gives way before the name does. */
nav .row .lbl { overflow: hidden; text-overflow: ellipsis; flex: 0 1 auto; min-width: 0; }
nav .row .sub {
  color: var(--dim2); font-size: 11px;
  overflow: hidden; text-overflow: ellipsis; flex: 0 2 auto; min-width: 0;
}

section { overflow: auto; padding: 14px 18px 60px; min-width: 0; }
section h2 { margin: 0 0 2px; font-size: 15px; }
section h2 .sub { color: var(--dim); font-weight: 400; font-size: 12px; }
section h3 {
  margin: 22px 0 8px; font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--dim2);
}

table { border-collapse: collapse; width: 100%; }
th {
  text-align: left; font-weight: 600; color: var(--dim2); font-size: 11px;
  border-bottom: 1px solid var(--line); padding: 4px 8px 4px 0;
  text-transform: uppercase; letter-spacing: .06em;
}
td { padding: 3px 8px 3px 0; border-bottom: 1px solid #23262d; vertical-align: top; }
tr:hover > td { background: #191c22; }
td.right { text-align: right; }
.muted { color: var(--dim); }
.faint { color: var(--dim2); }

.grid2 { display: grid; grid-template-columns: 110px 1fr; gap: 6px 10px; align-items: center; max-width: 620px; }
.grid2 label { color: var(--dim); }
.grid2 input, .grid2 select, .grid2 textarea { width: 100%; }
.kv { display: grid; grid-template-columns: 1fr 1fr auto; gap: 5px; max-width: 620px; }
.chip {
  display: inline-block; padding: 0 5px; border-radius: 3px;
  background: var(--panel2); border: 1px solid var(--line); color: var(--dim);
  font-size: 11px;
}
.chip.eth { color: #8fc7ff; } .chip.power { color: #f0c674; }
.chip.usb { color: #b8a2e3; } .chip.free { color: var(--ok); }
.chip.blocked { color: var(--err); }
/* tags read as a distinct kind of chip from `type`, which is a different axis */
.chip.tag { color: #b8a2e3; border-color: #4a3f66; }
.tags { display: inline-flex; gap: 4px; flex-wrap: wrap; align-items: center; }
.tags .tag {
  display: inline-flex; align-items: center; gap: 3px; font-size: 11px;
  background: var(--panel2); border: 1px solid #4a3f66; color: #b8a2e3;
  border-radius: 3px; padding: 0 3px 0 6px;
}
.tags .tag button { border: 0; background: none; padding: 0 2px; color: var(--dim2); }
.tags .tag button:hover { color: var(--err); }
.link-to { color: var(--accent); }
.prob { padding: 4px 0; border-bottom: 1px solid #23262d; }
.prob .k { display: inline-block; width: 52px; }
.prob.e .k { color: var(--err); } .prob.w .k { color: var(--warn); }

dialog {
  background: var(--panel); color: var(--fg); border: 1px solid var(--line);
  border-radius: 8px; padding: 0; min-width: 460px; max-width: 92vw;
}
dialog::backdrop { background: #0009; }
dialog .head { padding: 11px 14px; border-bottom: 1px solid var(--line); font-weight: 600; }
dialog .body { padding: 12px 14px; max-height: 60vh; overflow: auto; }

/* The node editor: a real editor, not a summary, and non-modal so the toolbar
   stays live behind it. Positioned rather than centred, so it does not sit on
   top of the sidebar you are picking nodes from. */
#nodeDlg {
  /* left:auto is load bearing. The UA stylesheet sets inset-inline-start:0 on a
     dialog, which over-constrains it against `right` and `width`, and the same
     thing vertically made `bottom` inert: the panel grew to its content height,
     nearly 2000px, so its own scrollbar never appeared and half the controls sat
     below the fold with nothing able to scroll them into view. Height is stated
     outright instead. */
  position: fixed; margin: 0;
  top: 96px; right: 12px; left: auto;
  width: min(1000px, calc(100vw - 300px));
  height: calc(100vh - 108px);
  max-height: none; max-width: calc(100vw - 24px);
  box-shadow: 0 18px 50px #000a;
}
#nodeDlg[open] { display: flex; flex-direction: column; }
/* min-height:0 lets a flex child actually shrink, which is what allows it to
   scroll rather than pushing the panel taller */
#nodeDlg .body { flex: 1; min-height: 0; max-height: none; overflow: auto; }
@media (max-width: 900px) {
  #nodeDlg { width: calc(100vw - 24px); right: 12px; }
}
dialog .foot { padding: 10px 14px; border-top: 1px solid var(--line); display: flex; gap: 8px; justify-content: flex-end; }
dialog .opt { padding: 5px 8px; cursor: pointer; border-radius: 4px; }
dialog .opt:hover { background: #24405f; }
/* tree: drag to re-parent, and per-row tools that stay out of the way.
   The row highlights on hover and is capped in width, because the buttons used
   to sit at the far right edge of a wide window with nothing tying them to the
   row they belong to. */
.treerow {
  display: flex; gap: 8px; align-items: baseline;
  padding-top: 2px; padding-bottom: 2px;
  border-bottom: 1px solid #22252c; max-width: 860px;
}
.treerow:hover { background: var(--panel2); }
/* deliberately NOT margin-left:auto. Flush right put the buttons at the far edge
   of a wide window with a lane of empty space between them and the row they act
   on, so it was never obvious which row you were about to delete. */
.treetools { margin-left: 12px; display: flex; gap: 4px; opacity: 0; }
.treetools button { padding: 0 6px; font-size: 11px; line-height: 18px; }
.treerow:hover .treetools, .treetools:focus-within { opacity: 1; }
[draggable="true"] { cursor: grab; }
[draggable="true"].dragging { opacity: .45; }
.dropinto { outline: 1px solid var(--accent); outline-offset: -1px; background: #24405f; }
.droproot {
  margin-top: 10px; padding: 10px; text-align: center; color: var(--dim2);
  border: 1px dashed var(--line); border-radius: 6px; font-size: 12px;
}
.droproot.dropinto { color: var(--fg); }

/* combo box: a filterable replacement for a long native dropdown */
.combo { position: relative; display: inline-block; }
.combo input { width: 100%; min-width: 150px; }
.combomenu {
  position: absolute; top: 100%; left: 0; z-index: 30; min-width: 100%;
  max-height: 260px; overflow: auto; margin-top: 2px;
  background: var(--panel2); border: 1px solid var(--line); border-radius: 5px;
  box-shadow: 0 8px 22px #0009;
}
.combomenu .opt { padding: 3px 9px; cursor: pointer; white-space: nowrap; }
.combomenu .opt:hover, .combomenu .opt.active { background: #24405f; }
.combomenu .opt.cur { color: var(--accent); }

/* A view quietly showing a subset is how you conclude something is missing when
   it is only hidden, so say so and offer the way out. */
.filternote {
  margin: 6px 0; padding: 5px 9px; border-radius: 4px;
  background: #24405f; border: 1px solid #34567d; color: var(--fg); font-size: 12px;
}
.filternote button { margin-left: 6px; }

.empty { color: var(--dim2); padding: 18px 0; }
.hint { color: var(--dim2); font-size: 12px; max-width: 760px; margin: -2px 0 8px; }
details.hint > summary {
  cursor: pointer; color: var(--dim2); list-style: none;
  display: inline-flex; align-items: center; gap: 5px; padding: 1px 0;
}
details.hint > summary::-webkit-details-marker { display: none; }
details.hint > summary::before { content: '?'; color: var(--accent); }
details.hint > summary:hover { color: var(--fg); }
details.hint[open] > summary::before { content: '\2212'; }
details.hint > div { margin-top: 4px; }
.hint b { color: var(--dim); font-weight: 600; }
/* Per-control help. Guidance used to live only in a paragraph at the top of the
   view, so an individual input had nothing explaining it. */
.subhelp { color: var(--dim2); font-size: 11px; line-height: 1.4; margin: 2px 0 2px 1px; max-width: 430px; }
.subhelp code { color: var(--accent); }
.hint code { color: var(--accent); }
.toast {
  position: fixed; bottom: 14px; left: 50%; transform: translateX(-50%);
  background: var(--panel2); border: 1px solid var(--line); border-radius: 6px;
  padding: 7px 14px; opacity: 0; transition: opacity .18s; pointer-events: none;
}
.toast.show { opacity: 1; }
