/* jsoneditor-theme.css — themes the vendored @json-editor/json-editor ('html' theme, no iconlib)
   to the app look. Drop-in: pair with js/json-editor-ui.js (mountJsonEditor), which builds the
   .je-mount / .je-pathbar markup this file targets. Scoped to classes (no IDs) so any number of
   editors can share a page. Consumes the app palette tokens; --ok / --drift / --tree-guide carry
   inline fallbacks so the theme survives on a surface that hasn't defined them. */

/* --- path calculator bar: sticks to the top of the scroll so it stays visible in deep trees --- */
.je-pathbar{ position:sticky; top:0; z-index:6; font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; font-size:11px; color:var(--muted); background:var(--panel2); border:1px solid var(--border-soft); border-radius:6px; padding:4px 5px 4px 9px; margin-bottom:8px; display:flex; align-items:center; gap:8px; box-shadow:0 3px 8px -5px rgba(0,0,0,.55); }
.je-pathbar .je-trail{ flex:1 1 auto; min-width:0; overflow-x:auto; white-space:nowrap; display:flex; align-items:center; gap:5px; scrollbar-width:thin; }
.je-pathbar .jp-empty{ color:var(--faint); font-style:italic; }
.je-pathbar .jp-seg{ color:var(--muted); } .je-pathbar .jp-cur{ color:var(--accent); font-weight:600; }
.je-pathbar .jp-sep{ color:var(--faint); } .je-pathbar .jp-depth{ margin-left:auto; padding-left:10px; color:var(--faint); font-size:10px; }
.je-pathbar .jp-copy{ flex:0 0 auto; background:var(--panel2); color:var(--muted); border:1px solid var(--border); border-radius:5px; font-size:10px; font-weight:700; letter-spacing:.3px; padding:3px 9px; cursor:pointer; font-family:inherit; }
.je-pathbar .jp-copy:hover:not(:disabled){ color:var(--fg); border-color:var(--faint); }
.je-pathbar .jp-copy:disabled{ opacity:.4; cursor:default; }
.je-pathbar .jp-copy.ok{ color:var(--ok,#1a8a44); border-color:color-mix(in srgb,var(--ok,#1a8a44) 45%,var(--border)); }

/* --- json-editor 'html' theme -> app look --- */
.je-mount{ font-size:13px; overflow-x:auto; }
.je-mount .je-form-input-label,.je-mount label,.je-mount .je-header,.je-mount h3,.je-mount legend,.je-mount input,.je-mount select,.je-mount textarea{ font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; }
.je-mount input:not([type=checkbox]):not([type=radio]),.je-mount select,.je-mount textarea{ background:var(--panel2); border:1px solid var(--border); border-radius:5px; color:var(--fg); font:inherit; font-size:12px; padding:3px 7px; max-width:100%; box-sizing:border-box; line-height:1.35; min-width:0; }
.je-mount input:not([type=checkbox]):not([type=radio]),.je-mount select{ height:26px; }
.je-mount input:focus,.je-mount select:focus,.je-mount textarea:focus{ outline:none; border-color:var(--accent); box-shadow:inset 0 0 0 1px var(--accent); }
.je-mount .je-form-input-label,.je-mount label{ color:var(--faint); font-size:11px; }
.je-mount p,.je-mount .je-desc{ color:var(--muted); font-size:10.5px; margin:1px 0; font-family:system-ui,-apple-system,sans-serif; }
.je-mount .je-indented-panel{ border:none; border-left:2px solid var(--tree-guide,#33455a); border-radius:0; margin:0 0 1px 3px; padding:0 0 0 8px; background:none; }
.je-mount fieldset{ border:none; padding:0; margin:0; }
/* only the left guide line - no boxes/borders/backgrounds around items (the boxing reads as noise) */
.je-mount fieldset,.je-mount .je-object__container,.je-mount .je-child-editor-holder{ border:none; background:none; }
/* schema-unknown (additional/drift) property: json-editor names it in a <b>. Flag it with a left
   accent line only (no box), matching the tree-guide treatment. */
.je-mount .je-child-editor-holder:has(> b){ border-left:2px solid var(--drift,#c2570b); background:none; padding:0 0 0 8px; margin:0 0 1px; }
.je-mount .je-child-editor-holder > b{ color:var(--drift,#c2570b); font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11.5px; font-weight:700; }
/* title row (gold), flex so lifted controls right-justify into the hover highlight */
.je-mount .je-header{ display:flex; align-items:center; gap:6px; margin:1px 0; padding:0 4px; border-radius:5px; color:var(--accent); }
.je-mount .je-header > span:not([class]),.je-mount .je-header h3,.je-mount h3,.je-mount legend{ font-size:12.5px; font-weight:600; color:var(--accent); }
.je-mount .je-header:hover{ background:color-mix(in srgb,var(--fg) 9%,transparent); }
/* null / empty node: dimmed gold so it reads as noticeably empty (still the gold family) */
.je-mount .je-header.je-empty{ color:color-mix(in srgb,var(--accent) 42%,var(--faint)); }
.je-mount .je-header.je-empty > span:not([class]){ color:color-mix(in srgb,var(--accent) 42%,var(--faint)); font-weight:500; }
.je-mount .je-header-button-holder{ display:inline-flex; gap:3px; flex-wrap:wrap; }
.je-mount .je-lifted{ margin-left:auto; display:inline-flex; gap:4px; align-items:center; }
.je-mount .je-status{ color:var(--faint); font-size:10.5px; font-weight:400; margin-left:5px; }
.je-mount .je-status.je-null{ font-style:italic; opacity:.85; }

/* --- caller-supplied hints (json-editor-hints.js). Opt-in: absent unless a host passes hints. --- */
/* A badge the CALLER computed, e.g. a negative number meaning "inherits the global value".
   Distinct class from .je-status so the size badge and a hint never fight over one element. */
.je-mount .je-hint{ color:var(--accent, #7aa2f7); font-size:10.5px; font-weight:500; margin-left:6px; }
/* Replaces the control entirely: the value is shown, editing it is not offered, because
   something else owns it (a map drag, a builder). */
.je-mount .je-summary{ color:var(--faint); font-size:11px; font-style:italic; margin-left:6px; }
/* Shown but not editable - the input stays visible so the value is readable. */
.je-mount input.je-ro, .je-mount textarea.je-ro, .je-mount select.je-ro{ opacity:.6; cursor:not-allowed; }
/* The few fields that matter, lifted above the rest. The host decides what to do with the
   remainder; this only marks them. */
.je-mount [data-schemapath].je-priority > .je-header > span:not([class]){ font-weight:600; }

.je-mount button{ background:var(--panel2); border:1px solid var(--border); color:var(--muted); border-radius:6px; font-size:10.5px; font-weight:600; padding:2px 8px; cursor:pointer; margin:1px 2px 1px 0; }
.je-mount button:hover{ color:var(--fg); border-color:var(--faint); }
/* collapse caret (flips via data-state), no "collapse" text */
.je-mount .json-editor-btntype-toggle{ font-size:0 !important; border:none !important; background:none !important; padding:0 4px !important; line-height:1; }
.je-mount .json-editor-btntype-toggle::before{ content:"\25BE"; font-size:11px; color:var(--faint); }
.je-mount .json-editor-btntype-toggle[data-state="Expand" i]::before{ content:"\25B8"; }
/* field-row + table-row hover */
.je-mount div:has(> label.je-form-input-label):hover{ background:color-mix(in srgb,var(--fg) 6%,transparent); border-radius:5px; }
.je-mount tr:hover{ background:color-mix(in srgb,var(--fg) 5%,transparent); }
.je-mount .je-table td,.je-mount table td{ padding:1px 4px; }
/* icon buttons: hide text, tooltip from the title we stamp */
.je-mount button[class*="json-editor-btntype-"]{ font-size:0 !important; min-width:0; padding:2px 7px !important; position:relative; }
.je-mount button[class*="json-editor-btn"][title]:hover::after{ content:attr(title); position:absolute; bottom:calc(100% + 3px); left:50%; transform:translateX(-50%); background:var(--pre-bg); color:var(--pre-fg); border:1px solid var(--border); border-radius:5px; font-size:10px; font-family:system-ui,-apple-system,sans-serif; font-weight:600; padding:2px 6px; white-space:nowrap; z-index:20; pointer-events:none; }
.je-mount button[class*="json-editor-btntype-"]::before{ font-size:13px; font-weight:400; color:var(--muted); line-height:1; }
.je-mount button[class*="json-editor-btntype-"]:hover::before{ filter:brightness(1.25); }
/* edit-json is disabled via option intent (disable_edit_json:true) but the lib still emits the button - hide it */
.je-mount .json-editor-btntype-editjson{ display:none !important; }
/* the two "+"s, differentiated: array add = muted, object add-property = green by the name */
.je-mount .json-editor-btntype-add::before{ content:"+"; font-size:15px; }
.je-mount .json-editor-btntype-properties::before{ content:"+"; font-size:15px; color:var(--ok,#1a8a44) !important; }
.je-mount .je-props{ border-color:color-mix(in srgb,var(--ok,#1a8a44) 45%,var(--border)) !important; margin-left:4px !important; }
.je-mount .json-editor-btntype-deletelast::before{ content:"\2212"; }
/* delete = red X (bumped past the generic muted); deleteall red too */
.je-mount .json-editor-btntype-delete::before,.je-mount .json-editor-btntype-deleteall::before{ content:"\2715"; color:var(--danger) !important; }
.je-mount .json-editor-btntype-copy::before{ content:"\29C9"; }
/* our object-property twin of that button: same icon, right-justified like the lifted array controls */
.je-mount .je-dup{ margin-left:auto; }
/* move up / down via the runtime btn-moveup/-movedown classes */
.je-mount .json-editor-btn-moveup::before{ content:"\2191"; }
.je-mount .json-editor-btn-movedown::before{ content:"\2193"; }
/* density: inline (default) vs stacked (toggle .je-stacked on the mount) */
.je-mount:not(.je-stacked) div:has(> label.je-form-input-label){ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.je-mount:not(.je-stacked) div:has(> label.je-form-input-label) > label.je-form-input-label{ flex:0 0 148px; margin:0; }
.je-mount:not(.je-stacked) div:has(> label.je-form-input-label) > input:not([type=checkbox]),
.je-mount:not(.je-stacked) div:has(> label.je-form-input-label) > select,
.je-mount:not(.je-stacked) div:has(> label.je-form-input-label) > textarea{ flex:1 1 140px; }
.je-mount.je-stacked div:has(> label.je-form-input-label) > label.je-form-input-label{ display:block; margin:0 0 2px; }

/* ===================== jump-to-node navigator ===================== */
/* ONE height for both navigator panes, declared once on purpose - two literals drift, and the
   moment the panes differ in height you are scrolling one out of alignment with the other,
   which defeats showing them side by side. */
.jn-wrap{ display:flex; flex-direction:column; gap:8px; min-height:340px; --jn-pane-h:62vh; }
.jn-bar{ font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; font-size:11px; display:flex; align-items:center; gap:4px; flex-wrap:wrap; min-height:20px; }
.jn-bar .jn-crumb{ color:var(--muted); cursor:pointer; padding:1px 5px; border-radius:4px; }
.jn-bar .jn-crumb:hover{ background:color-mix(in srgb,var(--fg) 10%,transparent); color:var(--fg); }
.jn-bar .jn-crumb.jn-cur{ color:var(--accent); font-weight:600; cursor:default; }
.jn-bar .jn-sep{ color:var(--faint); }
/* The JSON map is a projection, committed on demand and never rebuilt per keystroke - rebuilding
   the whole document's markup on every change stalls. It says when it is behind; the button
   beside it is how it catches up. */
.jn-bar .jn-mapstate{ color:var(--faint); font-size:10.5px; }
.jn-bar .jn-mapstate.jn-stale{ color:var(--drift); font-weight:600; }
.jn-bar .jn-refresh{ font-size:10.5px; font-weight:600; padding:2px 8px; border-radius:6px;
  background:transparent; color:var(--muted); border:1px solid var(--border); cursor:pointer; }
.jn-bar .jn-refresh:not(:disabled):hover{ color:var(--fg); border-color:var(--accent); }
.jn-bar .jn-refresh:disabled{ opacity:.4; cursor:default; }
/* stretch, not flex-start: flex-start sizes each pane to its own content, so the taller one
   sets the page height and neither scrolls internally. */
.jn-split{ display:flex; gap:12px; align-items:stretch; flex:1; min-height:0; flex-wrap:wrap; }
.jn-editor{ flex:1 1 340px; min-width:0; position:relative; min-height:0; max-height:var(--jn-pane-h,62vh); overflow:auto; }
.jn-mnt{ min-height:1px; }
.jn-json{ flex:1 1 340px; min-width:0; min-height:0; margin:0; font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; font-size:11px; line-height:1.5; color:var(--pre-fg); background:var(--pre-bg); border:1px solid var(--border); border-radius:8px; padding:10px; overflow:auto; max-height:var(--jn-pane-h,62vh); white-space:pre; }
.jn-hint{ color:var(--faint); font-style:italic; font-size:12px; padding:18px 4px; }
/* clickable json nodes */
.jn-json .jn-node{ cursor:pointer; border-radius:3px; padding:0 1px; }
.jn-json .jn-node:hover{ background:color-mix(in srgb,var(--accent) 22%,transparent); }
.jn-json .jn-key{ color:#7ca8ff; } .jn-json .jn-num{ color:#e0a458; } .jn-json .jn-str{ color:#8fd6a0; }
.jn-json .jn-bool{ color:#c792ea; } .jn-json .jn-nul{ color:#6b7a8a; font-style:italic; } .jn-json .jn-punc{ color:var(--faint); cursor:pointer; }
.jn-json .jn-focus{ background:color-mix(in srgb,var(--accent) 30%,transparent); outline:1px solid var(--accent); }
/* spinner: a prominent, centered overlay across the editor pane, up until the editor is ready */
.jn-spin{ position:absolute; inset:0; z-index:5; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px; color:var(--muted); font-size:13px; font-weight:600; letter-spacing:.3px; background:color-mix(in srgb,var(--card) 84%,transparent); backdrop-filter:blur(1px); border-radius:8px; }
.jn-spin .jn-sp{ width:32px; height:32px; border:3px solid var(--border); border-top-color:var(--accent); border-radius:50%; animation:jn-spin .7s linear infinite; flex:none; }
@keyframes jn-spin{ to{ transform:rotate(360deg); } }

/* ── Nesting: ONE left rule per tier, never a box ─────────────────────────────────────────
   json-editor emits a container per node (class names vary by version/theme), and several of
   them carry their own border/background. The result is a box around every object AND another
   around each sub-object - visual noise that hides the structure instead of showing it.
   Kill every container box inside the mount, then draw a single vertical guide on the left of
   each NESTED node. Depth then reads as a stack of parallel rules, one per tier.
   [data-schemapath] is json-editor's own per-node hook, so this does not depend on class names. */
.je-mount div,
.je-mount fieldset,
.je-mount section,
.je-mount table, .je-mount thead, .je-mount tbody, .je-mount tr, .je-mount td, .je-mount th {
  border: none !important;
  background: none !important;
  box-shadow: none !important;
  border-radius: 0 !important;
}
/* Controls keep their own chrome - the reset above is for CONTAINERS only. */
.je-mount input:not([type=checkbox]):not([type=radio]),
.je-mount select,
.je-mount textarea {
  border: 1px solid var(--border) !important;
  border-radius: 5px !important;
  background: var(--panel2) !important;
}
.je-mount input:focus, .je-mount select:focus, .je-mount textarea:focus {
  border-color: var(--accent) !important;
  box-shadow: inset 0 0 0 1px var(--accent) !important;
}
.je-mount button {
  border: 1px solid var(--border) !important;
  border-radius: 6px !important;
  background: var(--panel2) !important;
}
.je-mount .json-editor-btntype-toggle { border: none !important; background: none !important; }
/* The add-property button is LIFTED out of this span (decorate() puts it beside the name), so the
   span is normally left empty - but an empty block still holds a ~15px line box between objects.
   :has() lets us collapse only the ones with nothing in them; a span that kept a button is intact. */
.je-mount .je-object__controls:not(:has(button)) { display: none; }
.je-mount .je-object__controls { margin: 0; padding: 0; }

/* The tier guide: one rule, left side, on every nested node. Root gets none. */
.je-mount [data-schemapath]:not([data-schemapath=""]):not([data-schemapath="root"]) {
  border-left: 1px solid var(--border) !important;
  padding-left: 6px;
  margin-left: 2px;
}
/* Drift nodes (schema-unknown) keep their amber guide - same single-rule language. */
.je-mount .je-child-editor-holder:has(> b) { border-left: 2px solid var(--drift,#c2570b) !important; }
