/* =========================================================================
   Shared editor bench
   -------------------------------------------------------------------------
   Loaded by every "paste on the left, read on the right" tool. Add the
   .qdt-bench class to the page wrapper and the whole shell applies.

/* Defaults every bench page inherits. A page may override any of these in
   its own stylesheet - the JSON page does, for its syntax palette. */
.qdt-bench{
  --code: 12.5px/1.6 var(--font-mono);
  --font-ui: var(--font-body);

  --sx-key: #b3261e;   /* element / property names */
  --sx-str: #0a7355;   /* strings and text content */
  --sx-num: #9a4a06;   /* numbers */
  --sx-lit: #8a1a7a;   /* true / false / null */
}
html[data-theme="dark"] .qdt-bench{
  --sx-key: #ff8a80;
  --sx-str: #6cd3a6;
  --sx-num: #e0a35f;
  --sx-lit: #dd8fd6;
}

   It deliberately owns no colours of its own beyond the code surface: the
   palette comes from site.css, so these panes follow the site theme and its
   dark mode without any per-page work.
   ========================================================================= */


/* ==========================  PORTED DESIGN  ==========================
   Panels, bars, buttons, editor, tabs, tree, status line, notes and
   toasts. Shared verbatim so every bench page looks identical.
   ================================================================== */
/* The design shipped its own .wrap width cap. Inside the site shell the
   column is already constrained by --qdt-shell, so a second cap would just
   make the page narrower than every other tool page. */
.qdt-bench .wrap{ width: 100%; margin-inline: 0; }

.qdt-bench button, .qdt-bench input, .qdt-bench select, .qdt-bench textarea{ font: inherit; color: inherit; }
.qdt-bench button{ -webkit-tap-highlight-color: transparent; }
.qdt-bench :focus-visible{ outline: 2px solid var(--mark); outline-offset: 2px; border-radius: var(--r-sm); }
.qdt-bench .icon{ width: 1em; height: 1em; display: block; flex: 0 0 auto; }
.qdt-bench .sr{ position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.qdt-bench .wrap{ width: min(1440px, calc(100% - 40px)); margin-inline: auto; }
/* The shared FAQ component sits inside .qdt-bench but sizes itself from
   --qdt-shell (1400). Match .wrap here so its left edge lines up with every
   section above it instead of being inset by 20px. */
.qdt-bench .qdt-faq-shell{ width: min(1440px, calc(100% - 40px)); }
.qdt-bench .mono{ font-family: var(--font-mono); font-variant-ligatures: none; font-feature-settings: "tnum" 1; }
.qdt-bench .tag{ font-family: var(--font-mono); font-size: 10.5px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); }
.qdt-bench .hero{ padding: 28px 0 24px; max-width: 800px; }
.qdt-bench h1{ margin: 0; font-size: clamp(38px, 5.8vw, 64px); font-weight: 700; line-height: .96; letter-spacing: -.042em; }
.qdt-bench h1 .arrow{
  display: inline-block; color: var(--mark);
  font-family: var(--font-mono); font-weight: 400; font-size: .56em;
  transform: translateY(-.14em); margin: 0 .12em;
}
.qdt-bench .lead{ margin: 16px 0 0; max-width: 62ch; font-size: 16.5px; line-height: 1.6; color: var(--ink-2); }
.qdt-bench .spec-strip{ display: flex; flex-wrap: wrap; margin-top: 24px; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.qdt-bench .spec-strip > div{ padding: 11px 20px 11px 0; margin-right: 20px; border-right: 1px solid var(--rule); }
.qdt-bench .spec-strip > div:last-child{ border-right: 0; margin-right: 0; padding-right: 0; }
.qdt-bench .spec-strip dt{ font-family: var(--font-mono); font-size: 9.5px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3); }
.qdt-bench .spec-strip dd{ margin: 4px 0 0; font-family: var(--font-mono); font-size: 12px; color: var(--ink); }
.qdt-bench .bench{ display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px; padding: 24px 0 0; align-items: start; }
.qdt-bench .panel{ background: var(--paper); border: 1px solid var(--rule); border-radius: var(--r-lg); box-shadow: var(--lift); overflow: hidden; }
.qdt-bench .panel-head{
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 14px; border-bottom: 1px solid var(--rule-2);
}
.qdt-bench .panel-head h2{ margin: 0; font-size: 13px; font-weight: 600; letter-spacing: -.01em; }
.qdt-bench .panel-head .tag{ display: block; margin-bottom: 3px; }
.qdt-bench .head-tools{ display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.qdt-bench .pane-bar{
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-wrap: wrap;
  padding: 9px 14px;
  border-bottom: 1px solid var(--rule-2);
  background: var(--paper-2);
}
.qdt-bench .pane-bar-group{ display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.qdt-bench .pane-note{ font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-3); letter-spacing: .02em; }
.qdt-bench .pane-note b{ color: var(--ink-2); font-weight: 500; }
.qdt-bench .mini-btn{
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 10px;
  border: 1px solid var(--rule); border-radius: var(--r-sm);
  background: var(--paper);
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .02em;
  color: var(--ink-2); cursor: pointer; white-space: nowrap;
  transition: border-color .15s, color .15s, background .15s;
}
.qdt-bench .mini-btn:hover:not(:disabled){ border-color: var(--ink-3); color: var(--ink); }
.qdt-bench .mini-btn:disabled{ opacity: .4; cursor: not-allowed; }
.qdt-bench .mini-btn .icon{ font-size: 13px; }
.qdt-bench .mini-btn[aria-pressed="true"]{ background: var(--ink); border-color: var(--ink); color: var(--paper); }
.qdt-bench .mini-btn.danger:hover:not(:disabled){ border-color: var(--bad); color: var(--bad); background: var(--bad-soft); }
.qdt-bench .mini-btn.go{ background: var(--ink); border-color: var(--ink); color: var(--paper); }
.qdt-bench .mini-btn.go:hover:not(:disabled){ opacity: .88; color: var(--paper); }
.qdt-bench .seg{ display: inline-flex; border: 1px solid var(--rule); border-radius: var(--r-sm); overflow: hidden; background: var(--paper); }
.qdt-bench .seg button{
  min-height: 30px; padding: 0 10px; border: 0; background: transparent;
  font-family: var(--font-mono); font-size: 11px; color: var(--ink-2);
  cursor: pointer; white-space: nowrap; transition: background .15s, color .15s;
}
.qdt-bench .seg button + button{ border-left: 1px solid var(--rule); }
.qdt-bench .seg button:hover{ color: var(--ink); }
.qdt-bench .seg button[aria-pressed="true"]{ background: var(--ink); color: var(--paper); }
.qdt-bench .seg-label{ font-family: var(--font-mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); margin-right: 2px; }
.qdt-bench .editor{
  display: flex;
  align-items: stretch;
  height: clamp(300px, 46vh, 620px);
  background: var(--paper);
}
.qdt-bench .gutter{
  flex: 0 0 auto;
  min-width: 46px;
  padding: 12px 9px 12px 12px;
  text-align: right;
  font: var(--code);
  color: var(--ink-3);
  background: var(--paper-2);
  border-right: 1px solid var(--rule-2);
  overflow: hidden;
  user-select: none;
  white-space: pre;
}
.qdt-bench .gutter i{ display: block; font-style: normal; }
.qdt-bench .gutter i.bad{ color: var(--mark); font-weight: 600; }
.qdt-bench .gutter i.bad::after{ content: " \25C0"; font-size: 8px; vertical-align: 1px; }
.qdt-bench #input,
.qdt-bench .editor > textarea{
  flex: 1 1 auto;
  min-width: 0;
  padding: 12px;
  border: 0;
  outline: none;
  resize: none;
  background: transparent;
  font: var(--code);
  color: var(--ink);
  white-space: pre;
  overflow: auto;
  tab-size: 2;
}
.qdt-bench #input::placeholder,
.qdt-bench .editor > textarea::placeholder{ color: var(--ink-3); }
.qdt-bench .editor:focus-within{ box-shadow: inset 0 0 0 2px var(--mark-soft); }
.qdt-bench .drop-hint{
  position: absolute; inset: 0; z-index: 3;
  display: none; place-items: center;
  border: 1.5px dashed var(--mark); border-radius: var(--r);
  background: var(--mark-soft);
  font-family: var(--font-mono); font-size: 12px; letter-spacing: .06em; color: var(--mark);
}
.qdt-bench .editor-wrap{ position: relative; }
.qdt-bench .editor-wrap.hot .drop-hint{ display: grid; }
.qdt-bench .tabstrip{
  display: flex;
  gap: 0;
  padding: 0 14px;
  border-bottom: 1px solid var(--rule-2);
  overflow-x: auto;
  scrollbar-width: none;
}
.qdt-bench .tabstrip::-webkit-scrollbar{ display: none; }
.qdt-bench .tabstrip button{
  position: relative;
  padding: 11px 12px;
  border: 0; background: transparent;
  font-size: 13px; font-weight: 500; color: var(--ink-3);
  cursor: pointer; white-space: nowrap;
  transition: color .15s;
}
.qdt-bench .tabstrip button:hover{ color: var(--ink); }
.qdt-bench .tabstrip button[aria-selected="true"]{ color: var(--ink); font-weight: 600; }
.qdt-bench .tabstrip button[aria-selected="true"]::after{
  content: ""; position: absolute; left: 8px; right: 8px; bottom: -1px; height: 2px;
  background: var(--mark);
}
.qdt-bench .tabstrip .count{
  display: inline-block; margin-left: 6px;
  font-family: var(--font-mono); font-size: 9.5px; color: var(--ink-3);
}
.qdt-bench .view-host{ height: clamp(300px, 46vh, 620px); overflow: hidden; display: flex; flex-direction: column; }
.qdt-bench .view{ flex: 1; min-height: 0; display: none; }
.qdt-bench .view.on{ display: flex; flex-direction: column; }
.qdt-bench .empty-view{
  flex: 1; display: grid; place-items: center; padding: 30px; text-align: center;
}
.qdt-bench .empty-view p{ margin: 0; font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
.qdt-bench .code-view{
  flex: 1; min-height: 0;
  display: flex; align-items: stretch;
  overflow: auto;
  background: var(--paper);
  scrollbar-width: thin;
}
.qdt-bench .code-view::-webkit-scrollbar{ width: 10px; height: 10px; }
.qdt-bench .code-view::-webkit-scrollbar-thumb{ background: var(--rule); border-radius: 99px; }
.qdt-bench .col-ln, .qdt-bench .col-depth, .qdt-bench .col-code{ font: var(--code); white-space: pre; }
.qdt-bench .col-ln{
  position: sticky; left: 0; z-index: 2;
  flex: 0 0 auto; min-width: 44px;
  padding: 12px 8px 12px 12px;
  text-align: right; color: var(--ink-3);
  background: var(--paper-2);
  border-right: 1px solid var(--rule-2);
  user-select: none;
}
.qdt-bench .col-depth{
  position: sticky; left: 44px; z-index: 2;
  flex: 0 0 auto; width: 46px;
  padding: 12px 0;
  background: var(--paper-2);
  border-right: 1px solid var(--rule-2);
  user-select: none;
  overflow: hidden;
}
.qdt-bench .col-depth s{
  display: block; height: 1.6em; text-decoration: none;
  padding-top: .45em;
}
.qdt-bench .col-depth s::before{
  content: ""; display: block; height: .7em;
  background: var(--mark);
  border-radius: 0 1px 1px 0;
  width: var(--w, 0);
  opacity: var(--o, .2);
}
.qdt-bench .col-code{ flex: 1 1 auto; padding: 12px 16px 12px 12px; }
.qdt-bench .t-p{ color: var(--ink-3); font-weight: 400; }
.qdt-bench .t-k{ color: var(--sx-key); font-weight: 500; }
.qdt-bench .t-s{ color: var(--sx-str); font-weight: 400; }
.qdt-bench .t-n{ color: var(--sx-num); font-weight: 400; }
.qdt-bench .t-l{ color: var(--sx-lit); font-weight: 500; }
.qdt-bench .t-warn{ background: var(--warn-soft); box-shadow: 0 0 0 1px var(--warn); border-radius: 2px; }
.qdt-bench .plain-view{
  flex: 1; min-height: 0; margin: 0; padding: 12px 14px;
  overflow: auto; font: var(--code);
  white-space: pre-wrap; word-break: break-all;
  background: var(--paper);
}
.qdt-bench .truncated{
  padding: 8px 14px; border-top: 1px solid var(--rule-2);
  background: var(--warn-soft); color: var(--warn);
  font-family: var(--font-mono); font-size: 10.5px;
}
.qdt-bench .tree-bar{ display: flex; align-items: center; gap: 8px; padding: 9px 14px; border-bottom: 1px solid var(--rule-2); background: var(--paper-2); }
.qdt-bench .search{
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 7px;
  height: 30px; padding: 0 10px;
  border: 1px solid var(--rule); border-radius: var(--r-sm); background: var(--paper);
}
.qdt-bench .search .icon{ font-size: 13px; color: var(--ink-3); }
.qdt-bench .search input{ flex: 1; min-width: 0; border: 0; outline: none; background: transparent; font-family: var(--font-mono); font-size: 11.5px; }
.qdt-bench .tree{ flex: 1; min-height: 0; overflow: auto; padding: 8px 0 14px; font: var(--code); }
.qdt-bench .tree ul{ list-style: none; margin: 0; padding: 0 0 0 15px; border-left: 1px solid var(--rule-2); }
.qdt-bench .tree > ul{ padding-left: 12px; border-left: 0; }
.qdt-bench .tree li{ position: relative; }
.qdt-bench .node{
  display: flex; align-items: baseline; gap: 6px;
  padding: 1px 14px 1px 0;
  border-radius: 3px;
}
.qdt-bench .node:hover{ background: var(--paper-2); }
.qdt-bench .twist{
  width: 14px; height: 14px; margin-right: -2px;
  display: grid; place-items: center; flex: 0 0 auto;
  border: 0; background: transparent; color: var(--ink-3);
  cursor: pointer; font-size: 9px; line-height: 1;
  transform: translateY(2px);
}
.qdt-bench .twist:hover{ color: var(--ink); }
.qdt-bench .twist.leaf{ visibility: hidden; }
.qdt-bench .n-key{ color: var(--sx-key); font-weight: 500; }
.qdt-bench .n-idx{ color: var(--ink-3); }
.qdt-bench .n-str{ color: var(--sx-str); }
.qdt-bench .n-num{ color: var(--sx-num); }
.qdt-bench .n-lit{ color: var(--sx-lit); font-weight: 500; }
.qdt-bench .n-meta{ color: var(--ink-3); font-size: 10.5px; }
.qdt-bench .n-path{
  margin-left: auto; flex: 0 0 auto;
  border: 1px solid var(--rule); border-radius: 3px;
  background: var(--paper);
  padding: 0 5px; height: 17px;
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .06em;
  color: var(--ink-3); cursor: pointer; opacity: 0;
}
.qdt-bench .node:hover .n-path, .qdt-bench .n-path:focus-visible{ opacity: 1; }
.qdt-bench .n-path:hover{ color: var(--ink); border-color: var(--ink-3); }
.qdt-bench .hit{ background: var(--mark-soft); box-shadow: inset 2px 0 0 var(--mark); }
.qdt-bench .matches{ flex: 1; min-height: 0; overflow: auto; padding: 6px 0; }
.qdt-bench .match{
  display: flex; align-items: baseline; gap: 10px;
  width: 100%; text-align: left;
  padding: 6px 14px; border: 0; border-bottom: 1px solid var(--rule-2);
  background: transparent; cursor: pointer; font: var(--code);
}
.qdt-bench .match:hover{ background: var(--paper-2); }
.qdt-bench .match code{ color: var(--ink-2); }
.qdt-bench .match .mv{ margin-left: auto; color: var(--sx-str); max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qdt-bench .table-scroll{ flex: 1; min-height: 0; overflow: auto; }
.qdt-bench table.grid{ border-collapse: separate; border-spacing: 0; width: max-content; min-width: 100%; font: var(--code); }
.qdt-bench table.grid th, .qdt-bench table.grid td{
  padding: 5px 10px;
  border-bottom: 1px solid var(--rule-2);
  border-right: 1px solid var(--rule-2);
  text-align: left; vertical-align: top;
  max-width: 340px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.qdt-bench table.grid thead th{
  position: sticky; top: 0; z-index: 2;
  background: var(--paper-2);
  color: var(--ink); font-weight: 600;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
.qdt-bench table.grid tbody tr:hover td{ background: var(--paper-2); }
.qdt-bench table.grid td.rn{
  position: sticky; left: 0; z-index: 1;
  background: var(--paper-2); color: var(--ink-3);
  text-align: right; border-right: 1px solid var(--rule);
}
.qdt-bench table.grid thead th.rn{ z-index: 3; left: 0; }
.qdt-bench table.grid td.num{ text-align: right; color: var(--sx-num); }
.qdt-bench table.grid td.lit{ color: var(--sx-lit); }
.qdt-bench table.grid td.blank{ color: var(--ink-3); }
.qdt-bench select.pick{
  height: 30px; max-width: 320px;
  padding: 0 8px;
  border: 1px solid var(--rule); border-radius: var(--r-sm);
  background: var(--paper);
  font-family: var(--font-mono); font-size: 11px;
  outline: none;
}
.qdt-bench select.pick:focus{ border-color: var(--mark); }
.qdt-bench .frame-host{ flex: 1; min-height: 0; background: #fff; }
.qdt-bench .frame-host iframe{ width: 100%; height: 100%; border: 0; display: block; }
.qdt-bench .statusbar{
  margin-top: 18px;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--ink-3);
  border-radius: var(--r);
  background: var(--paper);
  box-shadow: var(--lift);
  overflow: hidden;
}
.qdt-bench .statusbar[data-state="ok"]{ border-left-color: var(--ok); }
/* "err" and "bad" are the same thing spelled two ways across the tools;
   both must colour, or a page silently shows a neutral status bar. */
.qdt-bench .statusbar[data-state="err"],
.qdt-bench .statusbar[data-state="bad"]{ border-left-color: var(--bad); }
.qdt-bench .statusbar[data-state="warn"]{ border-left-color: var(--warn); }
.qdt-bench .statusbar[data-state="empty"]{ border-left-color: var(--ink-3); }
.qdt-bench .status-top{
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 15px;
}
.qdt-bench .status-dot{ width: 8px; height: 8px; border-radius: 50%; background: var(--ink-3); flex: 0 0 auto; }
.qdt-bench .statusbar[data-state="ok"] .status-dot{ background: var(--ok); }
.qdt-bench .statusbar[data-state="err"] .status-dot,
.qdt-bench .statusbar[data-state="bad"] .status-dot{ background: var(--bad); }
.qdt-bench .statusbar[data-state="warn"] .status-dot{ background: var(--warn); }
.qdt-bench .status-title{ font-size: 14px; font-weight: 600; letter-spacing: -.01em; }
.qdt-bench .statusbar[data-state="err"] .status-title,
.qdt-bench .statusbar[data-state="bad"] .status-title{ color: var(--bad); }
.qdt-bench .statusbar[data-state="warn"] .status-title{ color: var(--warn); }
.qdt-bench .status-msg{ font-size: 13.5px; color: var(--ink-2); }
.qdt-bench .status-stats{
  margin-left: auto; display: flex; gap: 14px; flex-wrap: wrap;
  font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-3); letter-spacing: .02em;
}
.qdt-bench .status-stats b{ color: var(--ink); font-weight: 500; }
.qdt-bench .caret-box{
  margin: 0; padding: 12px 15px;
  border-top: 1px solid var(--rule-2);
  background: var(--paper-2);
  font: var(--code);
  overflow-x: auto;
  color: var(--ink-2);
}
.qdt-bench .caret-box u{ text-decoration: none; color: var(--mark); font-weight: 600; }
.qdt-bench .warn-row{ display: flex; gap: 8px; flex-wrap: wrap; padding: 0 15px 12px; }
.qdt-bench .warn-chip{
  display: inline-flex; align-items: center; gap: 7px;
  height: 27px; padding: 0 10px;
  border: 1px solid var(--warn); border-radius: 999px;
  background: var(--warn-soft); color: var(--warn);
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .02em;
  cursor: pointer;
}
.qdt-bench .warn-chip .icon{ font-size: 12px; }
.qdt-bench .warn-chip:hover{ filter: brightness(.96); }
.qdt-bench .section-title{ display: flex; align-items: baseline; gap: 12px; margin: 0 0 14px; }
.qdt-bench .section-title h2{ margin: 0; font-size: 19px; font-weight: 600; letter-spacing: -.025em; }
.qdt-bench .section-title::after{ content: ""; flex: 1; height: 1px; background: var(--rule); transform: translateY(-3px); }
.qdt-bench .notes{ padding: 40px 0 8px; }
.qdt-bench .note-grid{ display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 26px; border-top: 1px solid var(--rule); }
.qdt-bench .note{ padding: 18px 0; border-bottom: 1px solid var(--rule-2); }
.qdt-bench .note h3{ margin: 0 0 6px; font-size: 14px; font-weight: 600; letter-spacing: -.01em; }
.qdt-bench .note p{ margin: 0; font-size: 13.5px; line-height: 1.55; color: var(--ink-2); }
.qdt-bench .note code{
  font-family: var(--font-mono); font-size: 12px;
  background: var(--paper-2); border: 1px solid var(--rule-2);
  border-radius: 3px; padding: 1px 4px;
}
.qdt-bench .links{ padding: 34px 0 44px; }
.qdt-bench .link-grid{ display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.qdt-bench .link-card{
  display: block; padding: 15px;
  border: 1px solid var(--rule); border-radius: var(--r);
  background: var(--paper); text-decoration: none; color: var(--ink);
  transition: border-color .15s, transform .15s, box-shadow .15s;
}
.qdt-bench .link-card:hover{ border-color: var(--ink-3); transform: translateY(-2px); box-shadow: var(--lift); }
.qdt-bench .link-card .icon{ font-size: 19px; color: var(--ink-2); margin-bottom: 11px; }
.qdt-bench .link-card strong{ display: block; font-size: 13.5px; font-weight: 600; }
.qdt-bench .link-card span{ display: block; margin-top: 4px; font-size: 12px; line-height: 1.45; color: var(--ink-2); }
.qdt-bench .toasts{
  position: fixed; left: 20px; bottom: 20px; z-index: 60;
  display: flex; flex-direction: column; gap: 8px;
  width: min(360px, calc(100vw - 40px)); pointer-events: none;
}
.qdt-bench .toast{
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 13px;
  border: 1px solid var(--rule); border-left: 3px solid var(--ink-3); border-radius: var(--r);
  background: var(--paper); box-shadow: var(--lift-lg);
  pointer-events: auto;
  animation: toast-in .28s cubic-bezier(.2,.8,.3,1) both;
}
@keyframes toast-in { from { opacity: 0; transform: translateY(10px) scale(.98); } to { opacity: 1; transform: none; } }
.qdt-bench .toast.out{ animation: toast-out .22s ease forwards; }
@keyframes toast-out { to { opacity: 0; transform: translateY(6px); } }
.qdt-bench .toast.ok{ border-left-color: var(--ok); }
.qdt-bench .toast.warn{ border-left-color: var(--warn); }
.qdt-bench .toast.bad{ border-left-color: var(--bad); }
.qdt-bench .toast .icon{ font-size: 15px; margin-top: 1px; }
.qdt-bench .toast.ok .icon{ color: var(--ok); }
.qdt-bench .toast.warn .icon{ color: var(--warn); }
.qdt-bench .toast.bad .icon{ color: var(--bad); }
.qdt-bench .toast-body strong{ display: block; font-size: 13px; font-weight: 600; }
.qdt-bench .toast-body span{ display: block; margin-top: 2px; font-size: 12px; color: var(--ink-2); line-height: 1.45; }
.qdt-bench .live{ position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }


@media (max-width: 1080px) {
.qdt-bench .bench{ grid-template-columns: minmax(0, 1fr); }
.qdt-bench .editor, .qdt-bench .view-host{ height: clamp(280px, 40vh, 460px); }
}
@media (max-width: 760px) {
.qdt-bench .wrap,
.qdt-bench .qdt-faq-shell{ width: calc(100% - 28px); }
.qdt-bench h1{ font-size: clamp(32px, 9.5vw, 44px); }
.qdt-bench .lead{ font-size: 15px; }
.qdt-bench .spec-strip > div{ padding-right: 14px; margin-right: 14px; }
.qdt-bench .note-grid{ grid-template-columns: 1fr; }
.qdt-bench .link-grid{ grid-template-columns: 1fr; }
.qdt-bench .toasts{ left: 14px; right: 14px; width: auto; }
.qdt-bench .status-stats{ margin-left: 0; width: 100%; }
.qdt-bench .panel-head{ flex-wrap: wrap; }
.qdt-bench .head-tools{ width: 100%; justify-content: flex-start; }
}
@media (prefers-reduced-motion: reduce) {
}


/* =========================================================================
   PANEL ALIGNMENT
   -------------------------------------------------------------------------
   The original layout put a tabstrip on the output panel only, so the right
   editor started roughly 40px lower than the left one and the two panels
   ended at different heights. Fixing it takes three things:

     1. stretch the panels so both are the same height,
     2. lay each panel out as a grid whose last row absorbs the slack,
     3. give the input panel a mode strip matching the output's tabstrip,
        so the chrome above each editor is the same height.

   The left strip is not a spacer - it holds the parsing mode toggles, which
   belong with the input anyway.
   ========================================================================= */
/* Three columns: input · splitter · output. The two side widths are driven
   by custom properties the drag handler writes, so resizing never touches
   layout code. */
.qdt-bench .bench{
  align-items: stretch;
  grid-template-columns: minmax(0, var(--lw, 1fr)) 14px minmax(0, var(--rw, 1fr));
  gap: 0;
}

.qdt-bench .bench-split{
  position: relative;
  display: grid;
  place-items: center;
  cursor: col-resize;
  background: transparent;
  border: 0;
  touch-action: none;
}
/* the visible hairline, widened on hover so it is easy to grab */
.qdt-bench .bench-split::before{
  content: "";
  width: 1px; height: 100%;
  background: var(--rule);
  transition: width .14s, background .14s;
}
.qdt-bench .bench-split:hover::before,
.qdt-bench .bench-split:focus-visible::before,
.qdt-bench .bench-split.is-dragging::before{
  width: 3px; background: var(--mark);
}
.qdt-bench .bench-split .grip{
  position: absolute;
  width: 8px; height: 46px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--paper);
  box-shadow: var(--lift);
  transition: border-color .14s, box-shadow .14s;
}
.qdt-bench .bench-split .grip::after{
  content: "";
  position: absolute; inset: 0;
  margin: auto;
  width: 2px; height: 18px;
  border-top: 1px solid var(--ink-3);
  border-bottom: 1px solid var(--ink-3);
}
.qdt-bench .bench-split:hover .grip,
.qdt-bench .bench-split:focus-visible .grip{ border-color: var(--mark); }
.qdt-bench .bench-split:focus-visible{ outline: none; }
/* while dragging, stop the panes swallowing the pointer */
.qdt-bench.is-resizing{ cursor: col-resize; user-select: none; }
.qdt-bench.is-resizing .panel{ pointer-events: none; }

@media (max-width: 900px){
  .qdt-bench .bench{ grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .qdt-bench .bench-split{ display: none; }
}

.qdt-bench .panel{
  display: grid;
  grid-template-rows: auto auto auto 1fr;   /* head · strip · bar · body */
  min-height: 0;
}

/* The output panel carries several stacked bars, only one visible at a time,
   so its rows are declared as auto and the body still takes the remainder. */
.qdt-bench .panel:has(.tabstrip){
  grid-template-rows: auto auto auto auto auto auto auto 1fr;
}

/* Both editor bodies fill whatever is left, so they start and end together
   instead of each holding its own fixed height. */
.qdt-bench .editor-wrap{ min-height: 0; display: flex; }
.qdt-bench .editor{ height: auto; flex: 1 1 auto; min-height: 0; }
.qdt-bench .view-host{ height: auto; min-height: 0; }

/* One height for the pair, and it must be a real height rather than a
   min-height. With min-height the grid's 1fr row resolved against the
   content, so a 61,000-line document made the panel 61,000 lines tall and
   the scrollbar spanned the whole page. A fixed height forces the overflow
   into the panes, which is where the scrollbar belongs. */
/* Height lives on the bench, and the panels stretch to it - so one number
   drives both editors and they cannot drift apart. --bench-h is written by
   the drag handle; without it the clamp below is the default. Taller than it
   used to be, because these panes are the point of the page. */
.qdt-bench .bench{ height: var(--bench-h, clamp(520px, 72vh, 1000px)); }
.qdt-bench .panel{ overflow: hidden; }

/* Input-side mode strip, sized to match .tabstrip exactly. */
.qdt-bench .mode-strip{
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 14px;
  min-height: 41px;                 /* = tabstrip button 11px + 11px + text */
  border-bottom: 1px solid var(--rule-2);
  overflow-x: auto;
  scrollbar-width: none;
}
.qdt-bench .mode-strip::-webkit-scrollbar{ display: none; }
.qdt-bench .mode-strip .strip-label{
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-right: 2px;
  white-space: nowrap;
}

/* Fall back to a fixed body height where :has() is unavailable, so the panes
   are still usable even if they are no longer perfectly matched. */
@supports not selector(:has(*)){
  .qdt-bench .editor,
  .qdt-bench .view-host{ height: clamp(300px, 46vh, 620px); }
}

@media (max-width: 900px){
  /* Stacked, so equal heights stop mattering and a fixed one reads better. */
  .qdt-bench .bench{ min-height: 0; }
  .qdt-bench .editor,
  .qdt-bench .view-host{ height: clamp(280px, 44vh, 520px); }
}

/* =========================================================================
   SHARED EDITOR BENCH
   -------------------------------------------------------------------------
   The two-pane editor shell used by the JSON and XML formatters: neutral code
   surface, contained scrolling, draggable splitter, tree, busy overlay and
   full-screen output. Any page carrying .qdt-bench gets all of it.
   ========================================================================= */

/* ---- 1. neutral editor surface ------------------------------------------
   The site canvas is a warm paper (#F5F4F1). Code on a warm ground reads
   slightly yellow and syntax colours drift; every editor people trust is
   neutral. So the panels get their own cool-neutral surface, independent of
   the page around them, while the chrome stays warm and on-brand. */
.qdt-bench{
  --edit-bg:      #fdfdfe;
  --edit-bg-2:    #f5f6f8;
  --edit-rule:    #e6e8ec;
  --edit-gutter:  #f7f8fa;
}
html[data-theme="dark"] .qdt-bench{
  --edit-bg:      #14161b;
  --edit-bg-2:    #191c22;
  --edit-rule:    #262a33;
  --edit-gutter:  #171a20;
}

.qdt-bench .editor,
.qdt-bench .view-host,
.qdt-bench .code-view,
.qdt-bench #input,
.qdt-bench .editor > textarea{ background: var(--edit-bg); }
.qdt-bench .gutter{
  background: var(--edit-gutter);
  border-right-color: var(--edit-rule);
}

/* ---- 2. both editors scroll, and stop ----------------------------------
   Previously the panes grew with the content, so a big document produced one
   endless page. Each pane now owns its scrollbar and the page itself stays
   the same height whatever you paste. */
.qdt-bench #input,
.qdt-bench .editor > textarea,
.qdt-bench .code-view,
.qdt-bench .view-host .tree,
.qdt-bench .view-host .table-scroll,
.qdt-bench .view-host .frame-host{
  overflow: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--rule) transparent;
}
.qdt-bench .view.on{ overflow: hidden; min-height: 0; }
.qdt-bench .view-host .tree{ flex: 1; min-height: 0; padding: 10px 12px 16px; }

.qdt-bench ::-webkit-scrollbar{ width: 11px; height: 11px; }
.qdt-bench ::-webkit-scrollbar-thumb{
  background: var(--rule); border: 3px solid var(--edit-bg); border-radius: 99px;
}
.qdt-bench ::-webkit-scrollbar-thumb:hover{ background: var(--ink-3); }

/* ---- 3. tabs with icons -------------------------------------------------- */
.qdt-bench .tabstrip button{
  display: inline-flex; align-items: center; gap: 7px;
}
.qdt-bench .tabstrip .icon{ width: 14px; height: 14px; opacity: .65; }
.qdt-bench .tabstrip button[aria-selected="true"] .icon{ opacity: 1; color: var(--mark); }

/* ---- 4. premium tree ----------------------------------------------------
   Square +/- affordances rather than triangles: they read as "there is more
   inside" at a glance, and they hold a hairline like the rest of the site. */
.qdt-bench .tree ul{ list-style: none; margin: 0; padding-left: 17px; }
.qdt-bench .tree > ul{ padding-left: 0; }

/* guide rail down each level */
.qdt-bench .tree ul ul{
  border-left: 1px solid var(--edit-rule);
  margin-left: 8px;
}

/* The expander. Drawn rather than typed: a glyph never centres reliably at
   this size across fonts, which is what made the old ones look crooked. The
   bars are pseudo-elements, so + and - are always pixel-centred. */
.qdt-bench .tree .twist{
  position: relative;
  flex: 0 0 auto;
  width: 17px; height: 17px;
  margin-right: 8px;
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--paper);
  box-shadow: 0 1px 0 rgba(21,23,27,.03);
  cursor: pointer;
  transition: border-color .14s, background .14s, box-shadow .14s;
}
.qdt-bench .tree .twist::before,
.qdt-bench .tree .twist::after{
  content: "";
  position: absolute; inset: 0; margin: auto;
  background: var(--ink-2);
  border-radius: 1px;
  transition: transform .16s cubic-bezier(.4,0,.2,1), background .14s;
}
.qdt-bench .tree .twist::before{ width: 9px; height: 1.5px; }   /* the bar of + and - */
.qdt-bench .tree .twist::after{ width: 1.5px; height: 9px; }    /* the stem, hidden when open */
.qdt-bench .tree .twist[aria-expanded="true"]::after{ transform: scaleY(0); }
.qdt-bench .tree .twist.leaf{ visibility: hidden; }
.qdt-bench .tree .twist:hover{
  border-color: var(--mark); background: var(--mark-soft); box-shadow: none;
}
.qdt-bench .tree .twist:hover::before,
.qdt-bench .tree .twist:hover::after{ background: var(--mark); }

.qdt-bench .tree .node{
  display: flex; align-items: center; gap: 6px;
  padding: 3px 6px; border-radius: var(--r-sm);
  cursor: default;
}
.qdt-bench .tree .node:hover{ background: var(--edit-bg-2); }

/* colour by type, matching the formatted view */
.qdt-bench .tree .n-key{ color: var(--sx-key); font-weight: 600; }
.qdt-bench .tree .n-idx{ color: var(--ink-3); font-weight: 500; }
.qdt-bench .tree .n-str{ color: var(--sx-str); }
.qdt-bench .tree .n-num{ color: var(--sx-num); }
.qdt-bench .tree .n-lit{ color: var(--sx-lit); }
.qdt-bench .tree .t-p{ color: var(--ink-3); margin: 0 2px 0 -2px; }
.qdt-bench .tree .n-str.t-warn,
.qdt-bench .tree .n-num.t-warn{ color: var(--warn); text-decoration: underline dotted; }
.qdt-bench .tree .n-meta{
  font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-3);
  padding: 1px 7px; border: 1px solid var(--edit-rule); border-radius: 999px;
}
.qdt-bench .tree .n-path{
  margin-left: auto; opacity: 0;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-3);
  background: transparent; border: 1px solid var(--edit-rule);
  border-radius: 999px; padding: 1px 8px; cursor: pointer;
  transition: opacity .14s, color .14s, border-color .14s;
}
.qdt-bench .tree .node:hover .n-path{ opacity: 1; }
.qdt-bench .tree .n-path:hover{ color: var(--mark); border-color: var(--mark-line); }

/* ---- 5. search hits stay visible in context ----------------------------- */
.qdt-bench .tree li.is-hit > .node,
.qdt-bench .tree .row-hit{
  background: var(--mark-soft);
  box-shadow: inset 2px 0 0 var(--mark);
}
.qdt-bench .search-summary{
  position: sticky; top: 0; z-index: 2;
  padding: 8px 14px;
  border-bottom: 1px solid var(--edit-rule);
  background: var(--edit-bg-2);
  font-family: var(--font-mono); font-size: 11px; color: var(--ink-2);
}
.qdt-bench .search-summary strong{ color: var(--mark); }

/* ---- 6. busy overlay ----------------------------------------------------- */
.qdt-bench .json-busy{
  position: fixed; inset: 0; z-index: 1400;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--ink) 34%, transparent);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
}
@supports not (background: color-mix(in srgb, red 50%, blue)){
  .qdt-bench .json-busy{ background: rgba(21,23,27,.4); }
}
.qdt-bench .json-busy[hidden]{ display: none; }
.qdt-bench .busy-card{
  display: grid; justify-items: center; gap: 10px;
  padding: 30px 40px;
  border: 1px solid var(--rule); border-radius: var(--r-lg);
  background: var(--paper); box-shadow: var(--lift-lg);
  text-align: center;
}
.qdt-bench .busy-title{ font-size: 15px; font-weight: 600; color: var(--ink); }
.qdt-bench .busy-sub{ font-family: var(--font-mono); font-size: 11px; color: var(--ink-3); }
.qdt-bench .busy-ring{
  width: 30px; height: 30px; border-radius: 50%;
  border: 2px solid var(--rule); border-top-color: var(--mark);
  animation: jsonSpin .7s linear infinite;
}
@keyframes jsonSpin{ to{ transform: rotate(360deg); } }

/* ---- 7. full screen output ---------------------------------------------
   Table and HTML output are the two views that never fit in half a column. */
.qdt-bench .panel.is-full{
  position: fixed; inset: 12px; z-index: 1300;
  border-radius: var(--r-lg);
  box-shadow: var(--lift-lg);
  grid-template-rows: auto auto auto auto auto auto auto 1fr;
}
body.qdt-bench-fs{ overflow: hidden; }
.qdt-bench .panel.is-full .view-host{ height: auto; }
.qdt-bench .panel.is-full #fsBtn{ border-color: var(--mark); color: var(--mark); }

@media (max-width: 700px){ .qdt-bench .fs-label{ display: none; } }

/* ---- 8. table + html views fill their pane ------------------------------ */
.qdt-bench .table-scroll,
.qdt-bench .frame-host{ flex: 1; min-height: 0; }
.qdt-bench .table-scroll .grid{ border-collapse: separate; border-spacing: 0; }
.qdt-bench .table-scroll .grid thead th{
  position: sticky; top: 0; z-index: 1;
  background: var(--edit-bg-2);
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
.qdt-bench .table-scroll .grid tbody tr:hover td{ background: var(--edit-bg-2); }

/* =========================================================================
   BENCH CANVAS
   -------------------------------------------------------------------------
   The site canvas is warm paper. On a page that is mostly code a cool grey
   ground is better: it stops the white panels reading yellow and lets the
   syntax colours sit true. Values from the reference design.

   This recolours the body rather than painting over it, which matters: the
   graph-paper grid is drawn by site.css on <body> using --grid-line, so
   covering the body with a flat panel would erase the grid. Overriding two
   custom properties keeps the grid, keeps it full-bleed, and touches no
   layout at all.
   ========================================================================= */
body:has(.qdt-bench){
  background-color: #e9ebef;
  --grid-line: rgba(14, 17, 22, .045);
}
/* Published on the page too, so anything sitting on the canvas (the height
   handle's chips) can match it exactly instead of guessing. */
.qdt-bench{ --bench-canvas: #e9ebef; }
html[data-theme="dark"] body:has(.qdt-bench){
  background-color: #10131a;
  --grid-line: rgba(255, 255, 255, .032);
}
html[data-theme="dark"] .qdt-bench{ --bench-canvas: #10131a; }

/* Without :has() the body cannot be reached from here, so the column alone
   is recoloured. The grid is lost in that case, but nothing shifts. */
@supports not selector(:has(*)){
  .qdt-bench{ background-color: #e9ebef; }
  html[data-theme="dark"] .qdt-bench{ background-color: #10131a; }
}

/* =========================================================================
   PANEL STATUS LIGHTS
   -------------------------------------------------------------------------
   Three dots in the output panel header. They read as familiar window chrome,
   but the lit one tracks the tool's state, so the panel is glanceable: red
   means the last input was rejected, amber means it worked with a caveat,
   green means clean.
   ========================================================================= */
.qdt-bench .pane-lights{
  display: inline-flex; align-items: center; gap: 6px;
  margin-right: 12px; padding: 2px;
  cursor: pointer;
  flex: 0 0 auto;
}
.qdt-bench .pane-lights i{
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--dot); border: 1px solid rgba(21,23,27,.10);
  /* Unlit dots keep their hue but drain to near-grey, so the row still reads
     as three coloured lights rather than three grey blobs. */
  filter: saturate(.18) opacity(.42);
  transition: filter .3s cubic-bezier(.4,0,.2,1), box-shadow .3s, transform .3s;
}
html[data-theme="dark"] .qdt-bench .pane-lights i{ border-color: rgba(255,255,255,.10); }

.qdt-bench .pane-lights i:nth-child(1){ --dot: #ec6a5e; }   /* red   */
.qdt-bench .pane-lights i:nth-child(2){ --dot: #f4bf4f; }   /* amber */
.qdt-bench .pane-lights i:nth-child(3){ --dot: #61c454; }   /* green */

/* The lit one: full colour, a soft halo in its own hue, slightly raised. */
.qdt-bench .pane-lights[data-state="bad"]  i:nth-child(1),
.qdt-bench .pane-lights[data-state="warn"] i:nth-child(2),
.qdt-bench .pane-lights[data-state="ok"]   i:nth-child(3){
  filter: none;
  transform: scale(1.12);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--dot) 26%, transparent),
              0 0 10px color-mix(in srgb, var(--dot) 55%, transparent);
}
@supports not (background: color-mix(in srgb, red 50%, blue)){
  .qdt-bench .pane-lights[data-state="bad"]  i:nth-child(1),
  .qdt-bench .pane-lights[data-state="warn"] i:nth-child(2),
  .qdt-bench .pane-lights[data-state="ok"]   i:nth-child(3){
    box-shadow: 0 0 9px var(--dot);
  }
}

/* Idle: nothing lit, but the green breathes gently so the panel does not look
   switched off before you have typed anything. */
.qdt-bench .pane-lights[data-state="empty"] i:nth-child(3){
  animation: qdtDotBreathe 3.2s ease-in-out infinite;
}
@keyframes qdtDotBreathe{
  0%, 100% { filter: saturate(.18) opacity(.42); }
  50%      { filter: saturate(.55) opacity(.72); }
}

/* A single pop on the frame the state actually changes. */
.qdt-bench .pane-lights.is-changed i{ animation: qdtDotPop .42s cubic-bezier(.34,1.56,.64,1); }
.qdt-bench .pane-lights.is-changed i:nth-child(2){ animation-delay: .05s; }
.qdt-bench .pane-lights.is-changed i:nth-child(3){ animation-delay: .1s; }
@keyframes qdtDotPop{
  0%   { transform: scale(1); }
  45%  { transform: scale(1.34); }
  100% { transform: scale(1); }
}
/* The pop must not fight the lit state's own transform. */
.qdt-bench .pane-lights[data-state="bad"].is-changed  i:nth-child(1),
.qdt-bench .pane-lights[data-state="warn"].is-changed i:nth-child(2),
.qdt-bench .pane-lights[data-state="ok"].is-changed   i:nth-child(3){
  animation: qdtDotPopLit .42s cubic-bezier(.34,1.56,.64,1);
}
@keyframes qdtDotPopLit{
  0%   { transform: scale(1.12); }
  45%  { transform: scale(1.42); }
  100% { transform: scale(1.12); }
}

@media (prefers-reduced-motion: reduce){
  .qdt-bench .pane-lights i,
  .qdt-bench .pane-lights.is-changed i{ animation: none !important; }
}

@media (max-width: 620px){ .qdt-bench .pane-lights{ display: none; } }


/* =========================================================================
   BENCH HEIGHT HANDLE
   -------------------------------------------------------------------------
   The bar under the workspace. Drag it, use the buttons, or focus it and
   press the arrow keys. Both panels follow because both are sized by the
   bench, not individually.
   ========================================================================= */
.qdt-bench .bench-resize{
  display: flex; align-items: center; justify-content: center; gap: 10px;
  position: relative;
  height: 22px; margin: 6px 0 2px;
  cursor: ns-resize;
  touch-action: none;
  user-select: none;
}

/* Hairline across the full width, so the control reads as the edge of the
   workspace rather than a floating widget. */
.qdt-bench .bench-resize::before{
  content: "";
  position: absolute; left: 0; right: 0; top: 50%;
  height: 1px; background: var(--rule);
  transition: background .15s;
}
.qdt-bench .bench-resize:hover::before,
.qdt-bench .bench-resize:focus-visible::before,
.qdt-bench .bench-resize.is-dragging::before{ background: var(--mark-line); }

.qdt-bench .bench-resize > *{ position: relative; z-index: 1; }

/* The grip: same language as the vertical splitter, turned through 90°. */
.qdt-bench .bench-resize .grip-h{
  width: 46px; height: 8px;
  border: 1px solid var(--rule); border-radius: 999px;
  background: var(--paper); box-shadow: var(--lift);
  display: grid; place-items: center;
  transition: border-color .15s;
}
.qdt-bench .bench-resize .grip-h::after{
  content: "";
  width: 18px; height: 2px;
  border-top: 1px solid var(--ink-3); border-bottom: 1px solid var(--ink-3);
}
.qdt-bench .bench-resize:hover .grip-h,
.qdt-bench .bench-resize:focus-visible .grip-h,
.qdt-bench .bench-resize.is-dragging .grip-h{ border-color: var(--mark); }
.qdt-bench .bench-resize:focus-visible{ outline: none; }

/* Step buttons and the readout sit on the paper so the rule appears to pass
   behind them. They stay out of the way until the row is hovered. */
.qdt-bench .bench-resize .h-tools{
  display: flex; align-items: center; gap: 6px;
  padding: 0 8px;
  background: var(--bench-canvas, var(--bench));
  opacity: 0; transition: opacity .16s;
}
.qdt-bench .bench-resize:hover .h-tools,
.qdt-bench .bench-resize:focus-within .h-tools,
.qdt-bench .bench-resize.is-dragging .h-tools{ opacity: 1; }

.qdt-bench .bench-resize .h-btn{
  width: 22px; height: 22px;
  display: grid; place-items: center;
  border: 1px solid var(--rule); border-radius: var(--r-sm);
  background: var(--paper); color: var(--ink-2);
  font: 600 13px/1 var(--font-mono);
  cursor: pointer;
  transition: border-color .14s, color .14s, background .14s;
}
.qdt-bench .bench-resize .h-btn:hover{
  border-color: var(--mark); color: var(--mark); background: var(--mark-soft);
}
.qdt-bench .bench-resize .h-readout{
  min-width: 52px; text-align: center;
  font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

/* Dragging vertically must not let the pointer land in a textarea. */
.qdt-bench.is-resizing-y{ cursor: ns-resize; user-select: none; }
.qdt-bench.is-resizing-y .panel{ pointer-events: none; }

@media (max-width: 900px){
  /* Panels are stacked here and size themselves, so the control is moot. */
  .qdt-bench .bench-resize{ display: none; }
}
