/* Reusable component styles: form controls, result rows, tree nodes,
   the per-view status line. Layout-agnostic — should look the same
   wherever a component lands. */

input,
select,
button {
  padding: 0.3em 0.5em;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: white;
}

input {
  flex: 1;
  min-width: 200px;
}

button {
  background: var(--accent);
  color: white;
  border-color: var(--accent);
}

button:hover {
  filter: brightness(0.95);
}

button.btn-secondary {
  background: var(--bg);
  color: var(--fg);
  border-color: var(--border);
}

button.btn-secondary:hover:not(:disabled) {
  background: var(--bg-alt);
  filter: none;
}

button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Header action buttons take the brand-red palette. Primary (submit)
   is filled red; the detail-pane "make root" button is the only
   red-outlined secondary that remains in the header strip. */
header button {
  background: var(--brand);
  border-color: var(--brand);
}

.detail-actions button.btn-secondary {
  background: var(--bg);
  color: var(--brand);
  border-color: var(--brand);
}

.detail-actions button.btn-secondary:hover:not(:disabled) {
  background: var(--bg-alt);
}

/* Hamburger: three red bars (the ☰ glyph) on transparent ground —
   no fill, no border. The override has to beat the generic header
   button rule that paints children solid-red. */
header button.menu-btn {
  background: transparent;
  border: none;
  color: var(--brand);
  padding: 0.2em 0.4em;
  font-size: 1.4em;
  line-height: 1;
}

header button.menu-btn[aria-expanded="false"]:hover:not(:disabled) {
  background: transparent;
  filter: none;
  opacity: 0.8;
}

/* When the menu is open the hamburger picks up the panel's grey
   wash so the button + panel read as one connected surface, and
   stays grey regardless of mouse position. JS toggles
   `aria-expanded` on the button in lock-step with the panel's
   `hidden` attribute. */
header button.menu-btn[aria-expanded="true"],
header button.menu-btn[aria-expanded="true"]:hover {
  background: #3a3a3a;
  filter: none;
  opacity: 1;
}

/* Dropdown rows: plain white-on-grey text, no button chrome. Hover
   lifts the row a touch via a lighter grey wash. Disabled rows dim
   to a muted grey so they read as "not now". */
#app-menu .menu-item {
  background: transparent;
  color: #fff;
  border: none;
  border-radius: 0;
  text-align: left;
  padding: 0.45em 0.9em;
  font-size: 1em;
}

#app-menu .menu-item:hover:not(:disabled) {
  background: #4a4a4a;
  filter: none;
}

#app-menu .menu-item:disabled {
  background: transparent;
  color: #999;
  opacity: 1;
}

/* "Graph View" parent: a disclosure caret that flips when expanded. */
#app-menu .menu-parent::after {
  content: "\25B8"; /* ▸ */
  float: right;
  margin-left: 1em;
  opacity: 0.7;
}
#app-menu .menu-parent[aria-expanded="true"]::after {
  content: "\25BE"; /* ▾ */
}

/* The Graph View submenu: indented rows under the parent, with a gutter
   for the active-layout check mark. */
#app-menu .submenu {
  display: flex;
  flex-direction: column;
  background: rgba(0, 0, 0, 0.18);
}
#app-menu .submenu .subitem {
  position: relative;
  padding-left: 2.2em;
  font-size: 0.95em;
}
#app-menu .submenu .subitem[aria-checked="true"]::before {
  content: "\2713"; /* ✓ */
  position: absolute;
  left: 0.9em;
}

.detail-actions {
  margin-top: var(--space-md);
  padding-top: var(--space-md);
  border-top: 1px solid var(--border);
}

.placeholder {
  color: var(--muted);
  font-style: italic;
  margin: 1em;
}

/* Force-directed graph view — SVG node-link diagram. Fills the
   centre pane; arc-family colours mirror the tree's `--arc-*`
   palette so the two views stay visually coherent. */
.graph-svg {
  width: 100%;
  height: 100%;
  display: block;
  user-select: none;
  cursor: grab; /* empty canvas — drag to pan, wheel to spread */
  touch-action: none; /* let pointer drag/pan work on touch devices */
}

.graph-svg.panning {
  cursor: grabbing;
}

.graph-svg .node {
  cursor: grab; /* drag to reposition + pin */
}

.graph-svg .node.dragging {
  cursor: grabbing;
}

.graph-svg .node circle {
  fill: var(--bg);
  stroke: var(--muted);
  stroke-width: 1.5;
  cursor: inherit;
}

.graph-svg .node:hover circle {
  stroke: var(--accent);
}

.graph-svg .node.focus circle {
  fill: var(--brand);
  stroke: var(--brand);
  r: 9;
}

.graph-svg .node.selected circle {
  stroke: var(--accent);
  stroke-width: 3;
}

.graph-svg .node text {
  font-size: 11px;
  font-family: var(--font-ui);
  fill: var(--fg);
  pointer-events: none;
}

.graph-svg .edge {
  stroke-width: 1.5;
  opacity: 0.65;
}

.graph-svg .edge.arc-family-up    { stroke: var(--arc-up); }
.graph-svg .edge.arc-family-down  { stroke: var(--arc-down); }
.graph-svg .edge.arc-family-side  { stroke: var(--arc-side); }
.graph-svg .edge.arc-family-quiet { stroke: var(--arc-quiet); }

.graph-svg marker.arrow.arc-family-up    path { fill: var(--arc-up); }
.graph-svg marker.arrow.arc-family-down  path { fill: var(--arc-down); }
.graph-svg marker.arrow.arc-family-side  path { fill: var(--arc-side); }
.graph-svg marker.arrow.arc-family-quiet path { fill: var(--arc-quiet); }

/* Full-window overlay shown while a file is being dragged over the
   page. `pointer-events: none` lets the underlying drop event fire
   on document.body. Hidden by default; .active class shows it. */
#drop-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  pointer-events: none;
}

#drop-overlay.active {
  display: flex;
}

.drop-overlay-msg {
  background: var(--bg);
  padding: 1.5em 2.5em;
  border-radius: 8px;
  font-size: 1.1em;
  font-weight: 500;
  border: 2px dashed var(--accent);
  color: var(--accent);
}

/* Bounds editor — appears between the header and the main panes
   when [edit] is clicked. Hidden via [hidden] attribute. */
#bounds-editor {
  background: var(--bg-alt);
  border-bottom: 1px solid var(--border);
  padding: var(--space-md) var(--space-lg);
}

.bounds-editor-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-sm);
}

.bounds-editor-row:last-child {
  margin-bottom: 0;
}

/* Action buttons share the app's brand-red language rather than the
   default blue --accent button: evaluate (primary) is filled like the
   header search button; save/close (secondary) are red-outlined like the
   detail-pane actions. */
#bounds-editor button {
  background: var(--brand);
  border-color: var(--brand);
}
#bounds-editor button.btn-secondary {
  background: var(--bg);
  color: var(--brand);
  border-color: var(--brand);
}
#bounds-editor button.btn-secondary:hover:not(:disabled) {
  background: var(--bg-alt);
  filter: none;
}

.bounds-editor-controls label {
  font-size: var(--font-size-small);
  color: var(--muted);
}

.bounds-editor-hint {
  color: var(--muted);
  font-size: var(--font-size-small);
  margin-left: auto;
}

.bounds-editor-hint code {
  font-family: var(--font-mono);
  background: var(--bg);
  padding: 0.05em 0.3em;
  border-radius: 3px;
  border: 1px solid var(--border);
}

#bounds-editor-text {
  width: 100%;
  min-height: 6em;
  margin-bottom: var(--space-sm); /* match the inter-row rhythm above */
  font-family: var(--font-mono);
  font-size: var(--font-size-small);
  padding: var(--space-sm);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--fg);
  resize: vertical;
  box-sizing: border-box;
}

.bounds-editor-status {
  color: var(--muted);
  font-size: var(--font-size-small);
  font-family: var(--font-mono);
  margin-left: auto;
}

.bounds-editor-status.error {
  color: #b91c1c;
}

.result {
  padding: 0.5em 0.6em;
  cursor: pointer;
  border-radius: var(--radius);
  margin-bottom: var(--space-xs);
}

.result:hover {
  background: var(--bg-alt);
}

.result.selected {
  background: var(--selected);
}

.result-label {
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Tree layout — flat div hierarchy with explicit connector glyphs
   in each row. Indent comes from the prefix `│`/`├─`/`└─` glyphs,
   not from CSS padding. Line-height is tight so deep trees stay
   scannable. */
.tree-root {
  font-size: var(--font-size);
  line-height: 1.25;
}

.node-wrap,
.group,
.group-body {
  margin: 0;
}

.node-row,
.group-header {
  display: flex;
  align-items: baseline;
  gap: 0.25em;
  padding: 0 0.25em;
  border-radius: var(--radius);
  white-space: nowrap;
}

/* Connector prefix: monospace so the `│`/`├`/`└` grid lines up
   pixel-perfect across rows. Muted so it reads as scaffolding,
   not content. */
/* Single contiguous gutter holding the connector prefix and the
   disclosure. Wrapping both in one inline-flex span with no internal
   gap keeps the monospace grid intact — the row's flex gap only
   applies between the gutter and the arc-glyph / label that follow. */
.tree-gutter {
  display: inline-flex;
  align-items: baseline;
  flex: none;
}

.tree-prefix {
  font-family: var(--font-mono);
  color: #9ca3af;            /* slate-400 — darker than --border so the
                                 grid reads as scaffolding, not a hint */
  white-space: pre;
  flex: none;
  user-select: none;
}

/* `[+]`/`[−]` disclosure box on every collapsible row. Leaves get
   a blank of the same width so columns stay aligned. */
.tree-disclosure {
  font-family: var(--font-mono);
  color: var(--muted);
  flex: none;
  cursor: pointer;
  user-select: none;
  padding: 0 0.05em;
}

.tree-disclosure.leaf {
  cursor: default;
  visibility: hidden;
}

.tree-disclosure:hover:not(.leaf) {
  color: var(--accent);
}

/* When a node-wrap or group is collapsed, its descendant rows
   (other than the row that carries the disclosure) are hidden. */
.node-wrap.collapsed > .group,
.group.collapsed > .group-body {
  display: none;
}

.node-arc {
  color: var(--muted);
  font-family: var(--font-mono);
  display: inline-block;
  width: 1.2em;
  text-align: center;
  margin-right: 0.3em;       /* breathing room before label / #ordinal */
}

/* Arc-type colour families. Same shades across the tree, group
   headers, histogram pills, and arcs-table rows. */
.node-arc.arc-family-up    { color: var(--arc-up); }
.node-arc.arc-family-down  { color: var(--arc-down); }
.node-arc.arc-family-side  { color: var(--arc-side); }
.node-arc.arc-family-quiet { color: var(--arc-quiet); }

.node-label {
  font-weight: 500;
}

.node-id {
  color: var(--muted);
  font-size: var(--font-size-small);
  font-family: var(--font-mono);
  margin-left: 0.5em;
}

/* Shadow leaves stay quiet regardless of arc family — they're a
   "you've already seen this" affordance and shouldn't pull focus. */
.shadow .node-label,
.shadow .node-arc.arc-family-up,
.shadow .node-arc.arc-family-down,
.shadow .node-arc.arc-family-side,
.shadow .node-arc.arc-family-quiet,
.shadow .node-arc {
  color: var(--shadow);
  font-style: italic;
}

.shadow .node-arc::before {
  content: "↩ ";
}

/* Arc-type bucket header: a row under a node that groups siblings by
   `from_parent` arc type. Carries its own connector prefix +
   disclosure (see .tree-prefix / .tree-disclosure above). */
.group-header:hover {
  background: var(--bg-alt);
  cursor: pointer;
}

.group-label {
  color: var(--muted);
  font-size: var(--font-size-small);
  text-transform: lowercase;
  letter-spacing: 0.02em;
}

.group-count {
  color: var(--muted);
  font-size: var(--font-size-small);
  font-family: var(--font-mono);
}

.group-count::before {
  content: "(";
}
.group-count::after {
  content: ")";
}

.node-row {
  cursor: pointer;
}

.node-row:hover {
  background: var(--bg-alt);
}

.node-row.selected {
  background: var(--selected);
}

/* Agent-driven highlight (ui_highlight). Amber so it stays distinct
   from the user's blue selection; both can apply at once. */
.node-row.agent-highlight,
.result.agent-highlight {
  background: var(--agent-highlight);
  box-shadow: inset 2px 0 0 var(--agent-highlight-stroke);
}
.graph-svg .node.agent-highlight circle {
  stroke: var(--agent-highlight-stroke);
  stroke-width: 3px;
}

/* "click for more" row appended when a bucket exceeds the per-render
   cap. Italic + muted so it reads as a UI affordance, not data. */
.show-more-label {
  font-style: italic;
  color: var(--muted);
  font-weight: normal;
}

.node-row.show-more:hover .show-more-label {
  color: var(--accent);
}

/* Detail panel — right-pane vertex inspector. */
.detail-header {
  border-bottom: 1px solid var(--border);
  padding-bottom: var(--space-md);
  margin-bottom: var(--space-md);
}

.detail-primary {
  font-size: 1.15em;
  font-weight: 600;
}

.detail-meta {
  color: var(--muted);
  font-size: var(--font-size-small);
  font-family: var(--font-mono);
  margin-top: 0.15em;
}

.detail-block {
  margin-bottom: var(--space-md);
}

.detail-block-title {
  text-transform: lowercase;
  letter-spacing: 0.04em;
  font-size: var(--font-size-small);
  color: var(--muted);
  margin-bottom: 0.3em;
}

.detail-list {
  list-style: none;
  padding-left: 0;
  margin: 0;
}

.detail-list li {
  padding: 0.1em 0;
}

.label-text {
  font-weight: 500;
}

.label-id {
  color: var(--muted);
  font-size: var(--font-size-small);
  font-family: var(--font-mono);
  margin-left: 0.5em;
}

.detail-digest {
  font-style: italic;
  line-height: 1.4;
  color: var(--fg);
}

.detail-histogram {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4em;
}

.hist-pill {
  display: inline-flex;
  align-items: baseline;
  gap: 0.25em;
  padding: 0.1em 0.5em;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
  font-size: var(--font-size-small);
}

.hist-pill.arc-family-up    { border-color: var(--arc-up);    background: var(--arc-up-soft); }
.hist-pill.arc-family-down  { border-color: var(--arc-down);  background: var(--arc-down-soft); }
.hist-pill.arc-family-side  { border-color: var(--arc-side);  background: var(--arc-side-soft); }
.hist-pill.arc-family-quiet { border-color: var(--arc-quiet); background: var(--arc-quiet-soft); }

.hist-pill em {
  color: var(--muted);
  font-style: normal;
  font-family: var(--font-mono);
}

.arcs-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-small);
}

.arcs-table thead th {
  text-align: left;
  font-weight: normal;
  color: var(--muted);
  text-transform: lowercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--border);
  padding: 0.2em 0.4em;
}

.arcs-table tbody tr.arc-row {
  cursor: pointer;
}

.arcs-table tbody tr.arc-row:hover {
  background: var(--selected);
}

.arcs-table td {
  padding: 0.15em 0.4em;
  border-bottom: 1px solid var(--border);
}

.arc-cell-type {
  width: 1.5em;
  border-left: 3px solid transparent;
}

/* Coloured left edge on the type cell per arc family — same idea
   as the group headers in the tree. */
.arc-row.arc-family-up    .arc-cell-type { border-left-color: var(--arc-up); }
.arc-row.arc-family-down  .arc-cell-type { border-left-color: var(--arc-down); }
.arc-row.arc-family-side  .arc-cell-type { border-left-color: var(--arc-side); }
.arc-row.arc-family-quiet .arc-cell-type { border-left-color: var(--arc-quiet); }

.arc-far-id {
  color: var(--muted);
  font-family: var(--font-mono);
  margin-left: 0.5em;
}

/* Value payload (coordinate, URL, …) on a value-vertex arc target. */
.arc-far-payload {
  font-family: var(--font-mono);
}

.arc-cell-role {
  font-size: 0.9em;
}

/* Role chips in the detail arcs table. Solid coloured pill with
   white text — same shape as the "Convert Now" pill in the
   reference but coloured by derived role. */
.role-chip {
  display: inline-block;
  padding: 0.05em 0.55em;
  border-radius: 999px;
  color: white;
  font-size: var(--font-size-small);
  font-style: normal;
  background: var(--role-other);
}

.role-chip.role-concept { background: var(--role-concept); }
.role-chip.role-label   { background: var(--role-label); }
.role-chip.role-digest  { background: var(--role-digest); }
