/* ============================================================================
   EverydayDev — json.css
   JSON Formatter & Viewer only. Loaded via the registry's 'css' key, so it does
   not weigh down the encode/decode pages.

   Tokens come from site.css; shared tool UI (.card, .btn, .panel, .chips,
   .tabs, .drop, .opts, .err) comes from tools.css. Neither is redeclared here.

   All CSS for this site lives in assets/css/ — no <style> blocks, no style=""
   attributes. Anything that would need a computed length uses a real element
   (<progress>) or a depth class instead of an inline style.
   ============================================================================ */

/* ------------------------------------------------------------- toolbar ---- */
/* Format / Minify / Validate are verbs, not modes, so this is a button row
   rather than the .modes radiogroup the encode/decode tools use. */
.jbar{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px;
  margin:0 0 14px;padding:0 0 14px;border-bottom:1px solid var(--paper-line);
}
.jbar .grow{margin-left:auto}
/* Sort keys is a toggle, so it needs a visible on state — .btn alone has no
   [aria-pressed] styling, and .chip's is the wrong shape for a button here. */
.jbar .btn[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:#fff}

/* ------------------------------------------------------------ two panes --- */
.split{display:grid;gap:14px;grid-template-columns:1fr}
@media (min-width:992px){.split{grid-template-columns:1fr 1fr;gap:16px}}

.pane{display:flex;flex-direction:column;min-width:0}
.pane-top{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-height:32px;margin:0 0 6px}
.pane-top .lbl{margin-right:auto}

/* ---------------------------------------------------------- code surface -- */
/* Dark, like the .payload block the image tools already use: JSON needs a
   line-number gutter and per-token colour, which a light <textarea> cannot
   carry. The gutter and the code share --cfs/--clh so their lines stay locked
   together at both font sizes.

   The scroll container is .code itself, not the textarea — that way the gutter
   scrolls with the code for free and no JS scroll-syncing is needed. */
.code{
  --cfs:16px;      /* >=16px is mandatory on mobile: iOS Safari zooms the page
                      when a focused field is smaller */
  --clh:1.7;
  --gut:#46586E;
  position:relative;display:flex;align-items:stretch;min-width:0;
  max-height:30em;overflow:auto;
  background:var(--ink);border:1px solid var(--ink);border-radius:var(--radius);
}
@media (min-width:768px){.code{--cfs:13px;max-height:42em}}
.code:focus-within{border-color:var(--blueprint-light);box-shadow:0 0 0 3px rgba(127,209,224,.18)}
.code.is-bad{border-color:var(--danger)}
/* Past the gutter cap there is no gutter to keep aligned, so the panes take
   over their own vertical scrolling. */
.code.is-scroll .edit,
.code.is-scroll .codebody{overflow-y:auto;max-height:30em}
@media (min-width:768px){.code.is-scroll .edit,.code.is-scroll .codebody{max-height:42em}}

.gutter{
  flex:none;padding:12px 10px 12px 12px;
  color:var(--gut);text-align:right;-webkit-user-select:none;user-select:none;
  border-right:1px solid rgba(127,209,224,.12);
  font:400 var(--cfs)/var(--clh) var(--mono);
}
.gutter b{display:block;font-weight:400}
/* the error line is flagged with a symbol as well as a colour (§35) */
.gutter b.hit{color:var(--amber-hi);font-weight:500}

/* the editable input */
.edit{
  flex:1 1 auto;min-width:0;display:block;margin:0;padding:12px;
  background:none;border:0;resize:none;
  color:#E8F3F7;font:400 var(--cfs)/var(--clh) var(--mono);
  white-space:pre;overflow-x:auto;overflow-y:hidden;
}
.edit:focus{outline:0}
.edit::placeholder{color:#5A6E85}

/* the read-only highlighted output */
.codebody{
  flex:1 1 auto;min-width:0;margin:0;padding:12px;
  color:#CFE6EE;font:400 var(--cfs)/var(--clh) var(--mono);
  white-space:pre;overflow-x:auto;
}
.codebody:empty::after{content:"(output appears here)";color:#5A6E85}

/* --------------------------------------------------------------- tokens --- */
.tk-k{color:#7FD1E0}                        /* key         */
.tk-s{color:#7FD08A}                        /* string      */
.tk-n{color:#FFB43D}                        /* number      */
.tk-b{color:#8B98AA;font-weight:500}        /* true / false */
.tk-x{color:#8B98AA;font-style:italic}      /* null        */
.tk-p{color:#8092A6}                        /* punctuation */

/* --------------------------------------------------------- status strip --- */
.jstat{
  display:flex;flex-wrap:wrap;align-items:center;gap:6px 16px;
  margin:14px 0 0;padding:10px 12px;
  background:var(--paper);border:1px solid var(--paper-line);border-radius:var(--radius);
  font:400 12px/1.5 var(--mono);color:var(--slate-light);
}
.jstat .verdict{display:inline-flex;align-items:center;gap:6px;font-weight:500}
.jstat .ok{color:var(--success-ink)}
.jstat .bad{color:var(--danger-ink)}
.jstat .sep{color:var(--paper-line)}
.jstat .grow{margin-left:auto}

/* ---------------------------------------------------------- error panel --- */
.jerr{
  margin:14px 0 0;padding:12px;
  background:var(--danger-bg);border:1px solid rgba(192,57,43,.35);
  border-left:3px solid var(--danger);border-radius:var(--radius);
}
.jerr h3{margin:0 0 4px;font:600 14px/1.3 var(--sans);color:var(--danger-ink)}
.jerr .where{margin:0 0 10px;font:500 12px/1.5 var(--mono);color:var(--danger-ink)}
.jerr .msg{margin:0 0 10px;font-size:14px;color:var(--slate)}
/* code frame: the offending line in context, caret under the column */
.frame{
  margin:0 0 12px;padding:10px 12px;overflow-x:auto;
  background:var(--ink);border-radius:2px;
  font:400 12.5px/1.7 var(--mono);color:#CFE6EE;white-space:pre;
}
.frame .fno{color:#46586E}
.frame .fbad{color:var(--danger);font-weight:500}
.frame .caret{color:var(--amber-hi)}
.jerr .acts{display:flex;flex-wrap:wrap;gap:6px}

/* ----------------------------------------------------------- tree view ---- */
/* The tree is rendered as one flat list of visible rows, not nested markup:
   collapsed branches cost nothing, children are built on first expand, and a
   50k-node document never lands in the DOM at once (§24). Depth is drawn with
   spacer spans because an inline style is not an option here. */
.tree{
  margin:0;padding:12px;list-style:none;overflow:auto;max-height:26em;
  background:var(--ink);border-radius:var(--radius);
  font:400 13px/1.9 var(--mono);color:#CFE6EE;
}
.tnode{display:flex;align-items:baseline;gap:8px;white-space:nowrap;cursor:pointer}
.tnode:hover{background:rgba(127,209,224,.07)}
.tnode.is-sel{background:rgba(127,209,224,.13);box-shadow:inset 3px 0 0 var(--blueprint-light)}
.tnode:focus-visible{outline:2px solid var(--blueprint-light);outline-offset:-2px}
.tind{flex:none;width:16px;border-left:1px dotted rgba(127,209,224,.18)}
.twig{
  flex:none;width:18px;padding:0;text-align:center;
  background:none;border:0;color:#7A8FA6;cursor:pointer;
  font:inherit;
}
.twig:hover{color:var(--blueprint-light)}
.tnode .tkey{color:#7FD1E0}
.tnode .tval{min-width:0;overflow:hidden;text-overflow:ellipsis}
.tnode .ttype{margin-left:auto;padding-left:18px;font-size:11px;color:#6B7889}
.tmore{
  display:block;margin:4px 0 0 20px;padding:4px 10px;cursor:pointer;
  background:none;border:1px dashed rgba(127,209,224,.3);border-radius:2px;
  color:#8B98AA;font:400 12px/1.5 var(--mono);
}
.tmore:hover{border-color:var(--blueprint-light);color:var(--blueprint-light)}

/* ----------------------------------------------------------- inspector ---- */
.inspect{
  display:grid;gap:10px;grid-template-columns:1fr;
  margin:12px 0 0;padding:12px;
  background:var(--paper);border:1px solid var(--paper-line);border-radius:var(--radius);
}
@media (min-width:768px){.inspect{grid-template-columns:2fr 1fr 1fr}}
.inspect dt{margin:0 0 3px;font:500 11px/1 var(--mono);letter-spacing:.1em;
  text-transform:uppercase;color:var(--blueprint)}
.inspect dd{margin:0;font:400 13px/1.5 var(--mono);color:var(--ink);overflow-wrap:anywhere}
.inspect .acts{grid-column:1/-1;display:flex;flex-wrap:wrap;gap:6px}

/* --------------------------------------------------------------- stats ---- */
/* Two columns until the viewport is wide enough that the half-width output
   pane can actually hold three. */
.statgrid{display:grid;gap:8px;grid-template-columns:repeat(2,1fr);margin:0}
@media (min-width:992px){.statgrid{grid-template-columns:repeat(3,1fr)}}
.stat{padding:12px;background:#fff;border:1px solid var(--paper-line);border-radius:var(--radius)}
.stat dt{margin:0 0 6px;font:500 10px/1.3 var(--mono);letter-spacing:.1em;
  text-transform:uppercase;color:var(--slate-light)}
.stat dd{margin:0;font:500 19px/1 var(--display);color:var(--ink)}

/* ------------------------------------------------------- size savings ----- */
.saved{
  display:flex;flex-wrap:wrap;align-items:center;gap:10px 16px;
  margin:14px 0 0;padding:12px;
  background:rgba(76,175,125,.07);border:1px solid rgba(76,175,125,.4);
  border-radius:var(--radius);font:400 12px/1.5 var(--mono);color:var(--slate);
}
.saved b{color:var(--success-ink);font-weight:600}
/* a real <progress>, so the ratio needs no inline width and reads correctly to
   assistive tech */
.bar{
  flex:1 1 160px;min-width:120px;height:6px;
  -webkit-appearance:none;appearance:none;
  background:var(--paper-line);border:0;border-radius:999px;overflow:hidden;
}
.bar::-webkit-progress-bar{background:var(--paper-line)}
.bar::-webkit-progress-value{background:var(--success)}
.bar::-moz-progress-bar{background:var(--success)}

/* ---------------------------------------------------------- shortcuts ----- */
.keys{display:flex;flex-wrap:wrap;gap:6px 18px;margin:14px 0 0;font-size:13px;color:var(--slate-light)}
.keys kbd{
  padding:2px 6px;background:#fff;
  border:1px solid var(--paper-line);border-bottom-width:2px;border-radius:3px;
  font:500 11px/1.4 var(--mono);color:var(--ink);
}
