/* =========================================================================
   Mockstack — charcoal tool shells (Revision 2)

   Tool pages are NOT navy. They sit on a neutral charcoal so the thing being
   edited is judged against grey rather than a colour cast. Two tiers:

     .ws-app     workspace shell   settings rail + canvas + optional cheat
                                   drawer. For the ten canvas tools.
     .sp-app     simple shell      one centred 680px column. Everything else.

   Both share the toolbar and the status bar. The site nav is replaced by the
   toolbar here; the compact footer still closes the page.

   Loads AFTER chrome.css, which supplies the --ch-* tokens.
   ========================================================================= */

.ws-app, .sp-app { background: var(--ch-bg); min-height: 100vh; }
body:has(.ws-app), body:has(.sp-app) { background: var(--ch-bg); }

/* ---- toolbar ------------------------------------------------------------ */
.ws-bar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 11px 20px;
  padding-top: calc(11px + env(safe-area-inset-top, 0px));
  background: var(--ch-bar); border-bottom: 1px solid rgba(255,255,255,.07);
  position: sticky; top: 0; z-index: 40;
}
.ws-bar .brand { font: 800 15px/1 var(--body); letter-spacing: -0.035em; color: var(--text); border: none; }
.ws-bar .brand .dot { color: var(--gold); }
.ws-div { width: 1px; height: 18px; background: rgba(255,255,255,.12); }
.ws-name { font: 600 13px var(--body); color: var(--text); }
.ws-spec { font: 500 10px var(--mono); color: rgba(255,255,255,.35); letter-spacing: .1em; }
.ws-bar .sp { flex: 1; }
.ws-btn {
  border: 1px solid rgba(255,255,255,.16); color: rgba(255,255,255,.75);
  font: 600 11.5px var(--body); padding: 7px 12px; border-radius: var(--radius-btn);
  background: none; cursor: pointer;
}
.ws-btn:hover { border-color: var(--gold); color: var(--gold); }
.ws-btn.on { border-color: var(--gold); color: var(--gold); background: var(--gold-soft); }
.ws-btn.primary { background: var(--gold); color: var(--ch-shell); border-color: var(--gold); font-weight: 700; }
.ws-btn.primary:hover { background: var(--gold-hi); color: var(--ch-shell); }

/* ---- workspace grid ----------------------------------------------------- */
.ws-grid {
  display: grid; grid-template-columns: 232px 1fr;
  min-height: calc(100vh - 118px);
}
/* The cheat sheet is a drawer: toggling the class adds a third column rather
   than overlaying, so nothing under it is ever covered. */
.ws-grid.cheat-open { grid-template-columns: 232px 1fr 250px; }
.ws-side {
  background: var(--ch-panel); border-right: 1px solid var(--ch-line);
  padding: 16px 14px; overflow-y: auto;
}
.ws-side h3 {
  margin: 0 0 10px; font: 600 9.5px var(--mono);
  letter-spacing: .16em; text-transform: uppercase; color: rgba(255,255,255,.4);
}
.ws-sec { padding-bottom: 16px; margin-bottom: 16px; border-bottom: 1px solid var(--ch-line); }
.ws-sec:last-child { border-bottom: 0; margin-bottom: 0; }

/* Canvas surface: a checkerboard so transparency is visible. */
.ws-stage {
  display: grid; place-items: center; padding: 26px;
  background-color: var(--ch-bg);
  background-image:
    linear-gradient(45deg, #17181C 25%, transparent 25%, transparent 75%, #17181C 75%),
    linear-gradient(45deg, #17181C 25%, transparent 25%, transparent 75%, #17181C 75%);
  background-size: 18px 18px; background-position: 0 0, 9px 9px;
  min-width: 0;
}
.ws-cheat {
  background: var(--ch-panel); border-left: 1px solid var(--ch-line);
  padding: 16px 14px; overflow-y: auto; display: none;
}
.ws-grid.cheat-open .ws-cheat { display: block; }

/* ---- status bar --------------------------------------------------------- */
.ws-status {
  display: flex; align-items: center; gap: 16px;
  padding: 9px 20px; background: var(--ch-bar);
  border-top: 1px solid rgba(255,255,255,.07);
}
.ws-ok { font: 500 9.5px var(--mono); color: var(--ch-ok); }
.ws-status .sp { flex: 1; }
.ws-meta { font: 500 9.5px var(--mono); color: rgba(255,255,255,.35); letter-spacing: .06em; }

/* ---- controls inside either shell --------------------------------------- */
.ws-app .pillset button, .sp-app .pillset button,
.ws-app .btn, .sp-app .btn {
  background: var(--ch-ctrl); border: 1px solid rgba(255,255,255,.1);
  color: rgba(255,255,255,.82); border-radius: var(--radius-btn);
}
.ws-app .pillset button.on, .sp-app .pillset button.on,
.ws-app .btn, .sp-app .btn { }
.ws-app .pillset button.on, .sp-app .pillset button.on {
  background: var(--gold); color: var(--ch-shell); border-color: var(--gold);
}
.ws-app input[type=text], .ws-app textarea, .ws-app select,
.sp-app input[type=text], .sp-app textarea, .sp-app select {
  background: var(--ch-bg); border: 1px solid rgba(255,255,255,.14);
  color: var(--text); border-radius: var(--radius-btn);
}
.ws-app .tool-panel, .sp-app .tool-panel {
  background: transparent; border: 0; border-radius: 0; padding: 0;
}

/* ---- simple shell ------------------------------------------------------- */
.sp-wrap { min-height: calc(100vh - 118px); padding: 34px 20px; }
.sp-col { max-width: 680px; margin: 0 auto; }
.sp-card {
  background: var(--ch-panel); border: 1px solid var(--ch-line);
  border-radius: var(--radius-card); padding: 22px 24px;
}
.sp-head { margin-bottom: 18px; }
.sp-head h1 { margin: 0; font: 800 26px/1 var(--display); letter-spacing: -0.035em; color: var(--text); }
.sp-head p { margin: 7px 0 0; font: 400 13.5px var(--body); color: rgba(255,255,255,.55); }

/* ---- the explainer band under either shell ------------------------------ */
.ws-about { background: var(--ch-shell); border-top: 1px solid var(--ch-line); }
.ws-about-inner {
  max-width: var(--wrap); margin: 0 auto;
  display: grid; grid-template-columns: 1.4fr 1fr; gap: 20px;
  padding: 32px 36px 44px; align-items: start;
}
.ws-about .card {
  background: var(--ch-panel); border: 1px solid var(--ch-line);
  border-radius: var(--radius-card); padding: 22px 24px;
}
.ws-about h2 { margin: 0 0 6px; font: 800 19px var(--display); letter-spacing: -0.025em; color: var(--text); }
.ws-about .eyebrow { font: 600 10px var(--mono); letter-spacing: .18em; color: var(--gold); }
.ws-about p { font: 400 13px/1.65 var(--body); color: rgba(255,255,255,.65); }
.ws-about p b { color: var(--text); font-weight: 600; }
.ws-about details { border-top: 1px solid var(--ch-line); padding: 11px 0; }
.ws-about summary {
  cursor: pointer; list-style: none; font: 600 13.5px var(--body); color: var(--text);
  display: flex; justify-content: space-between; gap: 12px;
}
.ws-about summary::-webkit-details-marker { display: none; }
.ws-about summary::after { content: "+"; color: var(--gold); font: 500 16px var(--mono); line-height: 1; }
.ws-about details[open] summary::after { content: "\2212"; }
.ws-about details p { margin: 8px 0 0; }
.ws-rel { display: flex; flex-direction: column; gap: 9px; }
.ws-rel a {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  background: var(--ch-bg); border: 1px solid var(--ch-line);
  border-radius: 8px; padding: 12px 15px;
  font: 600 13.5px var(--body); color: var(--text);
}
.ws-rel a:hover { border-color: rgba(212,175,55,.5); }
.ws-rel a::after { content: "\2192"; color: var(--gold); font: 400 14px var(--mono); }

/* ---- cheat drawer contents ---------------------------------------------- */
.ws-cheat h3 { margin: 0 0 12px; font: 600 9.5px var(--mono); letter-spacing: .16em; text-transform: uppercase; color: rgba(255,255,255,.4); }
.ws-cheat .row { padding: 9px 0; border-bottom: 1px solid var(--ch-line); }
.ws-cheat .cheat-ins {
  display: inline-block; font: 600 11.5px var(--mono); color: var(--gold);
  background: var(--gold-soft); border: 1px solid rgba(212,175,55,.25);
  padding: 3px 7px; border-radius: 4px; cursor: pointer;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ws-cheat .cheat-ins:hover { background: var(--gold); color: var(--ch-shell); }
.ws-cheat .cheat-ins.ref { cursor: default; }
.ws-cheat .what { display: block; margin-top: 4px; font: 400 11.5px/1.45 var(--body); color: rgba(255,255,255,.5); }

/* ---- mobile ------------------------------------------------------------- */
@media (max-width: 900px) {
  .ws-grid, .ws-grid.cheat-open { grid-template-columns: 1fr; min-height: 0; }
  .ws-side { border-right: 0; border-bottom: 1px solid var(--ch-line); }
  .ws-cheat { border-left: 0; border-top: 1px solid var(--ch-line); }
  .ws-stage { padding: 18px; }
  .ws-about-inner { grid-template-columns: 1fr; padding: 24px 20px 36px; }
  .ws-bar { gap: 10px; padding: 10px 14px; }
  .ws-spec { display: none; }
  .sp-wrap { padding: 22px 14px; }
}

/* ---- tool controls inside a 232px rail -----------------------------------
   tools.css lays .conv-row out as a label column beside its control, which
   assumes a full-width panel. In the rail there is no room for two columns,
   so the label sits above and pillsets wrap as a grid rather than a row. */
.ws-side .conv-opts { display: block; }
.ws-side .conv-row {
  display: block; padding: 0 0 14px; margin: 0 0 14px;
  border-bottom: 1px solid var(--ch-line); border-top: 0;
}
.ws-side .conv-row:last-child { border-bottom: 0; margin-bottom: 0; padding-bottom: 0; }
.ws-side .conv-row > span:first-child {
  display: block; margin-bottom: 7px; width: auto; flex: none;
  font: 600 9.5px var(--mono); letter-spacing: .14em;
  text-transform: uppercase; color: rgba(255,255,255,.4);
}
.ws-side .pillset { display: flex; flex-wrap: wrap; gap: 5px; }
.ws-side .pillset button { flex: 0 0 auto; padding: 6px 10px; font-size: 11.5px; }
.ws-side textarea, .ws-side input[type=text] { width: 100%; font-size: 12.5px; }
.ws-side input[type=range] { width: 100%; }
.ws-side .conv-val { float: right; font: 500 10px var(--mono); color: rgba(255,255,255,.5); }
.ws-side label { font-size: 12px; color: rgba(255,255,255,.7); }

/* The stage is the checkerboard; per-tool output wrappers must not paint
   their own panel colour over it. */
.ws-stage .qr-out, .ws-stage .tool, .ws-stage .conv-opts { background: none; border: 0; padding: 0; }
.ws-stage .qr-stage { background: #fff; border: 0; border-radius: 6px; padding: 14px; }
.ws-stage .qr-out { display: flex; gap: 22px; align-items: flex-start; flex-wrap: wrap; }
.ws-stage .qr-side { display: flex; flex-direction: column; gap: 9px; min-width: 180px; }
.ws-stage canvas { display: block; max-width: 100%; height: auto; }

/* Regex and cron carry a wide inline cheat sheet, so their column is wider
   than the 680px default. */
.sp-col.sp-wide { max-width: 1080px; }
.sp-cheat .row { padding: 8px 0; border-bottom: 1px solid var(--ch-line); }
.sp-cheat { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 24px; }
.sp-cheat .cheat-ins {
  display: inline-block; font: 600 11.5px var(--mono); color: var(--gold);
  background: var(--gold-soft); border: 1px solid rgba(212,175,55,.25);
  padding: 3px 7px; border-radius: 4px; cursor: pointer;
}
.sp-cheat .cheat-ins.ref { cursor: default; }
.sp-cheat .what { display: block; margin-top: 4px; font: 400 11.5px/1.45 var(--body); color: rgba(255,255,255,.5); }
.sp-app .cheat, .sp-app .cheat-col { background: none; border: 0; padding: 0; }
.sp-app dl { margin: 0; }
.sp-app dt { margin-top: 9px; }
.sp-app dd { margin: 3px 0 0; font-size: 12.5px; color: rgba(255,255,255,.55); }
.sp-app .cheat-ex { display: block; font: 500 11px var(--mono); color: rgba(255,255,255,.38); margin-top: 2px; }
@media (max-width: 900px) { .sp-cheat { grid-template-columns: 1fr; } }

/* Revision 4 gives most tools a full-width workspace layout rather than the
   680px column; the column stays only for the tools with no wide reference. */
.sp-col.sp-full { max-width: var(--wrap); }
.sp-col.sp-full .sp-head p { max-width: 640px; }

/* Diff row tints were authored for the light panel; on charcoal the pastels
   sat under near-white text. Dark equivalents with explicit ink. */
.sp-app .tt-diff tr.add td { background: rgba(76, 175, 125, 0.14); color: #C7EED8; }
.sp-app .tt-diff tr.add td.n { background: rgba(76, 175, 125, 0.22); color: #7FCBA0; }
.sp-app .tt-diff tr.del td { background: rgba(220, 76, 76, 0.14); color: #F2C4C4; }
.sp-app .tt-diff tr.del td.n { background: rgba(220, 76, 76, 0.22); color: #E08A8A; }
.sp-app .tt-diff tr.gap td { background: var(--ch-ctrl); color: rgba(255,255,255,.45); }
.sp-app .tt-diff td.n { background: var(--ch-ctrl); color: rgba(255,255,255,.35); }
.sp-app .tt-diff { border-color: var(--ch-line); }

/* Remaining light-era status tints, restated for charcoal. The regex marks
   keep dark ink deliberately: highlighted matches need to look like a
   highlighter over the text. */
.sp-app .cc-cell.pass { background: rgba(76,175,125,.16); color: #A9E3C3; }
.sp-app .cc-cell.fail { background: rgba(220,76,76,.16); color: #EFB6B6; }
.sp-app .tt-pill.good { background: rgba(76,175,125,.2); color: #8FD9B2; }
.sp-app .tt-pill.bad  { background: rgba(220,76,76,.2); color: #E79999; }
.sp-app .tt-pill.warn { background: rgba(212,175,55,.2); color: #E3C980; }
.sp-app .rx-backdrop mark { background: #D4AF37; color: #101114; }
.sp-app .rx-backdrop mark.alt { background: #7FAEE0; color: #101114; }

/* ---- barcode + device-mockup workspaces --------------------------------- */
.sym-groups { display: flex; flex-direction: column; gap: 4px; }
.sym-groups .sym-g {
  margin: 10px 0 3px; font: 600 9px var(--mono);
  letter-spacing: .16em; color: rgba(255,255,255,.35);
}
.sym-groups .sym-g:first-child { margin-top: 0; }
.sym-groups button {
  text-align: left; padding: 8px 11px; cursor: pointer;
  background: var(--ch-ctrl); border: 1px solid rgba(255,255,255,.1);
  color: rgba(255,255,255,.82); border-radius: var(--radius-btn);
  font: 600 12px var(--body);
}
.sym-groups button.on { background: var(--gold); color: var(--ch-shell); border-color: var(--gold); }
.bc-out, .mk-out { width: 100%; max-width: 900px; }
.bc-out .mk-canvas, .mk-out .mk-canvas { background: none; border: 0; padding: 0; }
.bc-out canvas { background: #fff; border-radius: 6px; padding: 14px; max-width: 100%; height: auto; }
.mk-out canvas { max-width: 100%; height: auto; }
.mk-out .dropzone { background: var(--ch-panel); border-color: rgba(255,255,255,.16); }
.ws-side .cc-check { display: inline-flex; margin-right: 10px; color: rgba(255,255,255,.7); }
/* Once a mockup is on the canvas the dropzone shrinks to a slim re-upload bar. */
.mk-out .dropzone { padding: 18px 16px; }
.mk-out .dropzone h3 { font-size: 13px; margin: 6px 0 2px; }
.mk-out .dropzone .dz-ico { width: 26px; height: 26px; }
.mk-out .dropzone p { font-size: 11px; }

/* Full-width workspaces with a toggleable drawer and no settings rail. */
.ws-grid.no-side { grid-template-columns: 1fr; }
.ws-grid.no-side.cheat-open { grid-template-columns: 1fr 300px; }
.ws-grid.no-side .ws-main { min-width: 0; padding: 26px 28px; }
.ws-grid.no-side .ws-main .sp-col { max-width: none; margin: 0; }
.ws-grid.no-side .ws-cheat .sp-card { background: none; border: 0; padding: 0; }
.ws-grid.no-side .ws-cheat .sp-cheat { grid-template-columns: 1fr; }

/* Recovered cheat content, laid out for the 300px drawer. */
.ws-cheat .drawer-cheat h2 { margin: 0 0 4px; font: 800 15px var(--display); letter-spacing: -.02em; color: var(--text); }
.ws-cheat .drawer-cheat .cheat-lead { margin: 0 0 10px; font: 400 11.5px/1.5 var(--body); color: rgba(255,255,255,.5); }
.ws-cheat .drawer-cheat .cheat-grid { display: block; }
.ws-cheat .drawer-cheat .cheat-col h3 {
  margin: 14px 0 6px; font: 600 9px var(--mono);
  letter-spacing: .16em; text-transform: uppercase; color: rgba(255,255,255,.4);
}
.ws-cheat .drawer-cheat dl { margin: 0; }
.ws-cheat .drawer-cheat dt { margin-top: 8px; }
.ws-cheat .drawer-cheat dd { margin: 2px 0 0; font: 400 11.5px/1.45 var(--body); color: rgba(255,255,255,.55); }
.ws-cheat .drawer-cheat .cheat-ex { display: block; font: 500 10.5px var(--mono); color: rgba(255,255,255,.35); margin-top: 1px; }
.ws-cheat .drawer-cheat .cheat-ins {
  font: 600 11.5px var(--mono); color: var(--gold);
  background: var(--gold-soft); border: 1px solid rgba(212,175,55,.25);
  padding: 3px 7px; border-radius: 4px; cursor: pointer;
  font-variant-ligatures: none;   /* JetBrains ligatures corrupt regex syntax */
}
.ws-cheat .drawer-cheat .cheat-ins:hover { background: var(--gold); color: var(--ch-shell); }

/* ---- icon resizer: platform matrix + themed preview ---------------------- */
.plat-list { display: flex; flex-direction: column; gap: 5px; }
.plat {
  display: flex; align-items: center; gap: 9px; width: 100%; cursor: pointer;
  padding: 8px 10px; text-align: left;
  background: var(--ch-ctrl); border: 1px solid rgba(255,255,255,.06);
  border-radius: var(--radius-btn); color: rgba(255,255,255,.4);
}
.plat.on { border-color: rgba(212,175,55,.35); color: var(--text); background: rgba(212,175,55,.06); }
.plat .mark {
  flex: 0 0 30px; text-align: center; padding: 3px 0; border-radius: 3px;
  background: rgba(255,255,255,.06); color: inherit;
  font: 700 9px var(--mono); letter-spacing: .06em;
}
.plat.on .mark { background: rgba(212,175,55,.16); color: var(--gold); }
.plat .nm { flex: 1; min-width: 0; font: 600 12px var(--body); }
.plat .nm i {
  display: block; font: 500 8.5px var(--mono); font-style: normal;
  letter-spacing: .1em; color: rgba(255,255,255,.35); margin-top: 2px;
}
.plat .cnt { font: 600 11px var(--mono); color: rgba(255,255,255,.45); }
.plat.on .cnt { color: var(--gold); }

.ir-stage { display: block; overflow-y: auto; padding: 22px; }
.themed { display: none; margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--ch-line); }
.themed.show { display: block; }
.themed-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.themed-head h3 { margin: 0; font: 800 15px var(--display); letter-spacing: -.02em; color: var(--text); }
.themed-head span { font: 500 9.5px var(--mono); letter-spacing: .14em; color: rgba(255,255,255,.35); }
.themed-tiles { display: flex; gap: 12px; margin-top: 12px; }
.themed-tiles .tile { padding: 14px; border-radius: 12px; line-height: 0; }
.themed-tiles .tile.light { background: #E8E4DC; }
.themed-tiles .tile.dark  { background: #26272D; border: 1px solid var(--ch-line); }
.ws-side .conv-row { display: flex; align-items: center; gap: 8px; margin-bottom: 9px; }
.ws-side .conv-row > span:first-child { flex: 0 0 66px; font: 600 9.5px var(--mono); letter-spacing: .12em; text-transform: uppercase; color: rgba(255,255,255,.4); }
.ws-side input[type=color] { width: 34px; height: 26px; padding: 0; border: 1px solid rgba(255,255,255,.14); border-radius: 4px; background: none; cursor: pointer; }
.ws-side .conv-val { font: 500 10px var(--mono); color: rgba(255,255,255,.5); }

/* =========================================================================
   Full-viewport shells (Revision 4)
   No reference tool page has a footer or an About band, and every one is a
   fixed-height app: the toolbar and status bar pin, and only the panels
   inside scroll. The page itself never does.
   ========================================================================= */
html:has(.ws-app), html:has(.sp-app),
body:has(.ws-app), body:has(.sp-app) {
  height: 100%; overflow: hidden;
}
.ws-app, .sp-app {
  height: 100vh; height: 100dvh;
  display: flex; flex-direction: column;
  min-height: 0;
}
.ws-bar, .ws-status { flex: 0 0 auto; }

/* The workspace grid takes the remaining height; each column scrolls itself. */
.ws-app .ws-grid { flex: 1; min-height: 0; }
.ws-side, .ws-cheat { overflow-y: auto; min-height: 0; }
.ws-stage { overflow: auto; min-height: 0; }
.ws-grid.no-side .ws-main { overflow-y: auto; min-height: 0; }

/* Simple shell: the single column scrolls, the chrome does not. */
.sp-app .sp-wrap { flex: 1; min-height: 0; overflow-y: auto; }

/* ---- type scale, matched to the references ------------------------------
   The references sit almost entirely between 9.5px and 13px for chrome, with
   15px and 17px reserved for card titles. Ours had drifted larger. */
.ws-name { font: 600 13px var(--body); }
.ws-spec { font: 500 10px var(--mono); letter-spacing: .1em; }
.ws-btn { font: 600 11.5px var(--body); padding: 7px 12px; }
.ws-ok, .ws-meta { font: 500 9.5px var(--mono); }
.ws-side h3, .ws-cheat h3 { font: 600 9.5px var(--mono); letter-spacing: .16em; }
.sp-head h1 { font: 800 17px var(--display); letter-spacing: -.03em; }
.sp-head p { font: 400 12.5px var(--body); }
.sp-card { padding: 18px 20px; }
.ws-side .conv-row > span:first-child { font: 600 9.5px var(--mono); }
.ws-side label, .sp-app label { font-size: 11.5px; }
.ws-app .pillset button, .sp-app .pillset button { font: 600 11.5px var(--body); padding: 6px 11px; }
.ws-app .btn, .sp-app .btn { font: 600 12.5px var(--body); padding: 8px 14px; }
.ws-app .conv-row > span:first-child, .sp-app .conv-row > span:first-child {
  font: 600 9.5px var(--mono); letter-spacing: .14em;
}
.ws-app .conv-val, .sp-app .conv-val { font: 500 10px var(--mono); }
.ws-app input[type=text], .ws-app textarea, .ws-app select,
.sp-app input[type=text], .sp-app textarea, .sp-app select { font-size: 12.5px; }
.tt-status, .sp-app .tt-status { font: 500 11px var(--mono); }

/* .fg-hint is defined in feature-graphic.css, which the tools.css pages do not
   load, so hint copy in these rails fell back to the default body size and
   towered over the 11.5px chrome around it. */
.ws-side .fg-hint, .ws-cheat .fg-hint, .sp-app .fg-hint,
.ws-side p, .ws-cheat p {
  margin: 8px 0 0;
  font: 400 11px/1.5 var(--body);
  color: rgba(255,255,255,.45);
}
.ws-side code, .sp-app .ws-side code {
  font: 500 10.5px var(--mono);
  background: var(--ch-bg); padding: 1px 4px; border-radius: 3px;
  color: rgba(255,255,255,.7);
}
.ws-side .cc-check { font-size: 11.5px; color: rgba(255,255,255,.7); }

/* ---- regex tester: design-parity pieces --------------------------------- */
.ws-spec.ok { color: #4CAF7D; }
.ws-spec.bad { color: #E37B7B; }
.rx-flavors { display: inline-flex; gap: 5px; }
.rx-flavors button {
  background: #26272D; color: rgba(255,255,255,.75); border: 0; cursor: pointer;
  font: 600 10.5px var(--mono); padding: 6px 10px; border-radius: 5px;
}
.rx-flavors button.on { background: var(--gold); color: #17181C; }
.rx-presets {
  display: inline-flex; align-items: center; gap: 8px; margin-left: auto;
  font: 400 10.5px var(--body); color: rgba(255,255,255,.4);
}
.pillset.slim button { padding: 4px 7px; font: 600 9.5px var(--mono); letter-spacing: .06em; }
.pillset.slim button:hover { color: var(--gold); }

.rx-split { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 14px; margin-top: 12px; }
.rx-pane { min-width: 0; display: flex; flex-direction: column; }
.rx-out { flex: 1; min-height: 180px; max-height: 420px; overflow-y: auto; }
.rx-card {
  background: #17181C; border: 1px solid rgba(255,255,255,.08); border-radius: 7px;
  padding: 10px 13px; margin-bottom: 7px;
}
.rx-card .head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.rx-card .full { font: 600 11.5px var(--mono); color: var(--gold); word-break: break-all; }
.rx-card .pos { font: 500 9px var(--mono); color: rgba(255,255,255,.35); white-space: nowrap; }
.rx-card .chips { display: flex; gap: 6px; margin-top: 7px; flex-wrap: wrap; }
.rx-card .chip {
  font: 500 9.5px var(--mono); color: rgba(255,255,255,.5);
  background: rgba(255,255,255,.06); padding: 3px 8px; border-radius: 4px; word-break: break-all;
}
.rx-none { padding: 14px 4px; font: 400 12px var(--body); color: rgba(255,255,255,.4); }
.rx-replaced {
  background: #17181C; border: 1px solid rgba(255,255,255,.08); border-radius: 7px;
  padding: 12px 14px; font: 400 12px/2 var(--mono); color: rgba(255,255,255,.75);
  white-space: pre-wrap; word-break: break-word;
}
.rx-rep { color: #7EE0A3; }
.rx-copyout { margin-top: 8px; align-self: flex-start; }

.rx-explain {
  margin-top: 14px; background: #17181C; border: 1px solid rgba(255,255,255,.07);
  border-radius: 7px; padding: 10px 14px;
}
.rx-explain .lab { font: 600 9px var(--mono); letter-spacing: .14em; color: var(--gold); }
.rx-explain .body { font: 400 11px/1.7 var(--mono); color: rgba(255,255,255,.55); margin-top: 5px; }
.rx-explain .tok { color: #7EB3FF; }
.rx-explain .mute { color: rgba(255,255,255,.35); font-family: var(--body); }

@media (max-width: 860px) {
  .rx-split { grid-template-columns: 1fr; }
  .rx-presets { margin-left: 0; }
}

/* ---- json formatter: tree, rail, stats ---------------------------------- */
.jf-grid { grid-template-columns: minmax(0,1fr) 300px; }
.jf-grid .ws-main { min-width: 0; padding: 26px 28px; }
.jf-side h3.gold { color: var(--gold); }
.jf-q {
  width: 100%; background: #101114; border: 1px solid rgba(212,175,55,.35);
  border-radius: 6px; padding: 9px 11px; color: #fff; font: 500 11px var(--mono);
}
.jf-mini {
  width: 100%; min-height: 64px; resize: vertical;
  background: #101114; border: 1.5px dashed rgba(255,255,255,.2); border-radius: 6px;
  padding: 9px 11px; color: #fff; font: 400 10.5px/1.6 var(--mono);
}
.jf-mini:focus { border-style: solid; border-color: rgba(212,175,55,.4); outline: none; }
.jf-qout {
  margin-top: 6px; border-radius: 6px; padding: 0; white-space: pre-wrap; word-break: break-word;
  font: 400 10.5px/1.7 var(--mono); color: rgba(255,255,255,.6);
}
.jf-qout:not(:empty) { background: #26272D; padding: 9px 11px; }
.jf-qout.ok { color: #D8F34E; }
.jf-qout.bad { color: #E37B7B; }
.jf-stats {
  background: #101114; border: 1px solid rgba(255,255,255,.1); border-radius: 6px;
  padding: 10px 11px; display: flex; flex-direction: column; gap: 5px;
}
.jf-stats > span { display: flex; justify-content: space-between; }
.jf-stats .k { font: 500 10px var(--mono); color: rgba(255,255,255,.4); }
.jf-stats .v { font: 500 10px var(--mono); color: #fff; }
.jf-stats .v.gold { color: var(--gold); }

.tt-mini.vw.on { color: var(--gold); }
.jf-tree {
  flex: 1; min-height: 220px; max-height: 480px; overflow: auto;
  background: #101114; border: 1px solid rgba(255,255,255,.1); border-radius: 6px;
  padding: 10px 12px; font: 400 11.5px/1.9 var(--mono);
}
.jf-tree .row { display: flex; align-items: baseline; gap: 8px; white-space: nowrap; }
.jf-tree .row.branch { cursor: pointer; }
.jf-tree .tw { color: rgba(255,255,255,.35); width: 10px; flex: none; }
.jf-tree .k { color: #7EB3FF; }
.jf-tree .b { color: rgba(255,255,255,.5); }
.jf-tree .v.str { color: #D8F34E; }
.jf-tree .v.num { color: #F0B35C; }
.jf-tree .v.bool { color: #7EE0A3; }
.jf-tree .v.null { color: #E37B7B; }
.jf-tree .sp { flex: 1; }
.jf-tree .path {
  border: 0; background: none; cursor: pointer; font: 500 9px var(--mono);
  color: rgba(212,175,55,.75); white-space: nowrap;
}
.jf-tree .path:hover { color: var(--gold); }
.jf-tree .kids.hide { display: none; }

@media (max-width: 900px) {
  .jf-grid { grid-template-columns: 1fr; }
  .jf-side { border-right: 0; border-top: 1px solid var(--ch-line); }
}
.jf-note { margin: 8px 0 0; font: 400 10px/1.5 var(--body); color: rgba(255,255,255,.4); }

/* ---- shared toolbar dropdown (ws pages) ---------------------------------- */
.ws-btn.gold { border-color: rgba(212,175,55,.45); color: var(--gold); }
.ws-btn.gold:hover { border-color: var(--gold); background: var(--gold-soft); color: var(--gold-hi); }
.pe-dd { position: relative; display: inline-flex; }
.pe-menu {
  position: absolute; top: 40px; left: 0; z-index: 40; width: 232px;
  display: flex; flex-direction: column; gap: 4px;
  background: #26272D; border: 1px solid rgba(255,255,255,.12); border-radius: 10px;
  padding: 8px; box-shadow: 0 20px 50px -16px rgba(0,0,0,.8);
}
.pe-menu.right { left: auto; right: 0; }
.pe-menu[hidden] { display: none; }
.pe-mi {
  padding: 9px 12px; border: 0; border-radius: 6px; background: none; cursor: pointer;
  font: 600 12.5px var(--body); color: #fff; text-align: left;
}
.pe-mi:hover { background: var(--gold-soft); }
.pe-mi span { display: block; margin-top: 2px; font: 400 10.5px var(--body); color: rgba(255,255,255,.45); }
.pe-mnote {
  padding: 8px 12px 4px; border-top: 1px solid rgba(255,255,255,.1); margin-top: 4px;
  font: 400 10.5px var(--body); color: rgba(255,255,255,.45);
}

/* ---- image converter queue ----------------------------------------------- */
.ic-toggle {
  border: 0; border-radius: 5px; padding: 5px 10px; cursor: pointer;
  background: #26272D; color: rgba(255,255,255,.4); font: 700 9.5px var(--mono);
}
.ic-toggle.on { background: rgba(76,175,125,.15); color: #4CAF7D; }
.ic-rename {
  width: 150px; background: #101114; border: 1px solid rgba(255,255,255,.12);
  border-radius: 5px; color: rgba(255,255,255,.75); font: 500 10.5px var(--mono); padding: 5px 10px;
}
.ic-convert { border-color: rgba(212,175,55,.5); color: var(--gold); font-weight: 700; }
.conv-row-note { font: 400 10px var(--body); color: rgba(255,255,255,.35); }
.ic-cols, .ic-row {
  display: grid; grid-template-columns: minmax(140px,1.4fr) 52px 52px minmax(60px,1.2fr) minmax(90px,auto);
  gap: 12px; align-items: center;
}
.ic-cols {
  padding: 12px 14px 6px;
  font: 600 9px var(--mono); letter-spacing: .14em; color: rgba(255,255,255,.35);
}
.ic-cols span:last-child { text-align: right; }
.ic-rows { display: flex; flex-direction: column; gap: 5px; }
.ic-row { background: #17181C; border: 1px solid rgba(255,255,255,.08); border-radius: 7px; padding: 10px 14px; }
.ic-row.bad { border-color: rgba(227,123,123,.4); }
.ic-row .nm { display: flex; align-items: center; gap: 10px; min-width: 0; }
.ic-row .th {
  width: 26px; height: 26px; border-radius: 5px; flex: none;
  background: #26272D center / cover no-repeat;
}
.ic-row .t { font: 600 12px var(--body); color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ic-row .badge {
  font: 600 9px var(--mono); color: rgba(255,255,255,.5);
  background: rgba(255,255,255,.06); padding: 3px 7px; border-radius: 4px; text-align: center;
}
.ic-row .badge.out { color: var(--gold); background: var(--gold-soft); }
.ic-row .bar { position: relative; height: 4px; border-radius: 2px; background: #26272D; overflow: hidden; }
.ic-row .fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: #4CAF7D; border-radius: 2px; transition: width .4s; }
.ic-row.bad .fill { background: #E37B7B; }
.ic-row .sz { font: 500 10px var(--mono); color: rgba(255,255,255,.55); text-align: right; white-space: nowrap; }
.ic-row .sz b { color: #4CAF7D; font-weight: 500; }
.ic-total { display: flex; justify-content: space-between; align-items: baseline; margin-top: 12px; flex-wrap: wrap; gap: 8px; }
.ic-total span:first-child { font: 500 10.5px var(--mono); color: rgba(255,255,255,.4); }
.ic-total b { color: #4CAF7D; font-weight: 500; }
.ic-total .note { font: 400 11px var(--body); color: rgba(255,255,255,.4); }

/* ---- barcode: symbology hints, settings bar, guide ------------------------ */
.sym-groups button .hint { float: right; font: 400 9px var(--mono); color: rgba(255,255,255,.35); }
.sym-groups button.on .hint { color: rgba(23,24,28,.6); }
.bc-stage { position: relative; }
.bc-dims {
  position: absolute; left: 16px; bottom: 12px;
  font: 500 9.5px var(--mono); color: rgba(255,255,255,.35); letter-spacing: .04em;
}
.bc-settings {
  display: flex; align-items: center; gap: 18px; padding: 10px 20px; flex-wrap: wrap;
  background: #17181C; border-top: 1px solid var(--ch-line);
}
.bc-settings .cell { display: flex; align-items: center; gap: 8px; }
.bc-settings .k { font: 500 9.5px var(--mono); color: rgba(255,255,255,.4); }
.bc-settings .v {
  background: #26272D; color: #fff; font: 600 10.5px var(--mono);
  padding: 5px 9px; border-radius: 5px; border: 0;
}
.bc-settings .v.pick { cursor: pointer; }
.bc-settings .v.pick.on { background: var(--gold); color: #17181C; font-weight: 700; }
.bc-settings .sp { flex: 1; }
.bc-guide .g {
  background: #26272D; border-radius: 6px; padding: 9px 11px; margin-bottom: 8px;
  font: 400 10.5px/1.5 var(--body); color: rgba(255,255,255,.5);
}
.bc-guide .g b { display: block; font: 600 11px var(--body); color: #fff; margin-bottom: 3px; }
.cron-tz {
  max-width: 200px; background: var(--ch-bg); color: rgba(255,255,255,.75);
  border: 1px solid rgba(255,255,255,.14); border-radius: 4px;
  font: 500 10.5px var(--mono); padding: 4px 6px;
}
.cc-apca { margin-top: 10px; display: flex; flex-direction: column; gap: 2px; }
.cc-apca > span:first-child { font: 700 20px var(--mono); }
.hashv.match { color: #4CAF7D; }

/* json formatter: the cheat drawer is a third column beside the query rail */
.jf-grid.cheat-open { grid-template-columns: minmax(0,1fr) 300px 250px; }

/* On a charcoal stage the dropzone is a plain text prompt, not a navy card:
   the legacy .dropzone card tokens resolve to navy here and read as a
   marketing panel sitting inside the tool. */
.ws-app .dropzone, .sp-app .dropzone {
  background: none;
  border: 1.5px dashed rgba(255,255,255,.2);
  border-radius: 10px;
}
.ws-app .dropzone:hover, .sp-app .dropzone:hover,
.ws-app .dropzone.over, .sp-app .dropzone.over {
  background: none;
  border-color: var(--gold);
  transform: none;
}
.ws-app .dropzone .dz-ico, .sp-app .dropzone .dz-ico { background: rgba(255,255,255,.06); color: rgba(255,255,255,.55); }
.ws-app .dropzone:hover .dz-ico, .sp-app .dropzone:hover .dz-ico { color: var(--gold); }
.ws-app .dropzone h3, .sp-app .dropzone h3 { color: rgba(255,255,255,.85); font-size: 15px; }
.ws-app .dropzone p, .sp-app .dropzone p { color: rgba(255,255,255,.45); font-size: 12.5px; }
.ws-app .dz-note, .sp-app .dz-note { border-top-color: rgba(255,255,255,.1); color: rgba(255,255,255,.35); }

/* Once a file is in, the big prompt collapses to a slim replace bar so the
   result owns the card. */
.sp-app .dropzone.compact { flex-direction: row; justify-content: center; gap: 10px; padding: 11px 16px; }
.sp-app .dropzone.compact .dz-ico { width: 22px; height: 22px; margin: 0; border-radius: 6px; }
.sp-app .dropzone.compact .dz-ico svg { width: 13px; height: 13px; }
.sp-app .dropzone.compact h3 { font-size: 12.5px; font-weight: 600; }
.sp-app .dropzone.compact h3::after { content: " · drop or click to replace"; color: rgba(255,255,255,.4); font-weight: 400; }
.sp-app .dropzone.compact p, .sp-app .dropzone.compact .dz-note { display: none; }

/* ---- contrast checker: design-parity pair + matrix ----------------------- */
.cc-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(280px,100%), 1fr)); gap: 16px; }
.cc-card {
  background: #17181C; border: 1px solid rgba(255,255,255,.08);
  border-radius: 8px; padding: 16px;
}
.cc-h {
  display: flex; align-items: center;
  font: 600 9.5px var(--mono); letter-spacing: .16em; text-transform: uppercase;
  color: rgba(255,255,255,.4);
}
.cc-h .spacer { flex: 1; }
.cc-swap {
  border: 0; background: none; cursor: pointer;
  font: 600 9.5px var(--mono); color: var(--gold); letter-spacing: .06em;
}
.cc-swap:hover { color: var(--gold-hi); }
.cc-inrow { display: flex; align-items: center; gap: 10px; margin-top: 9px; }
.cc-chip {
  width: 38px; height: 38px; padding: 0; border: 1px solid rgba(255,255,255,.2);
  border-radius: 8px; background: none; cursor: pointer;
}
.cc-inrow .hexin {
  flex: 1; background: #101114; border: 1px solid rgba(255,255,255,.12);
  border-radius: 6px; padding: 9px 12px; color: #fff; font: 500 12.5px var(--mono);
}
.cc-inrow .hexin.bad { border-color: rgba(227,123,123,.6); }
.cc-sw { display: flex; gap: 5px; margin-top: 9px; flex-wrap: wrap; }
.cc-sw button {
  width: 22px; height: 22px; border-radius: 5px; cursor: pointer; padding: 0;
  border: 2px solid rgba(255,255,255,.15);
}
.cc-sw button.on { border-color: var(--gold); }
.cc-fixbox {
  margin-top: 14px; background: var(--gold-soft);
  border: 1px solid rgba(212,175,55,.35); border-radius: 6px; padding: 10px 12px;
}
.cc-fixbox .lab { font: 600 10px var(--mono); letter-spacing: .12em; color: var(--gold); }
.cc-fixbox .row { display: flex; align-items: center; gap: 8px; margin-top: 7px; flex-wrap: wrap; }
.cc-fixbox .chip { width: 22px; height: 22px; border-radius: 5px; flex: none; }
.cc-fixbox .hex { font: 500 11.5px var(--mono); color: #fff; }
.cc-fixbox .why { font: 400 10.5px var(--body); color: rgba(255,255,255,.5); }
.cc-fixbox .apply {
  margin-left: auto; border: 0; cursor: pointer;
  font: 700 10px var(--body); color: #17181C; background: var(--gold);
  padding: 5px 10px; border-radius: 5px;
}
.cc-right { display: flex; flex-direction: column; gap: 12px; }
.cc-prevcard { border-radius: 8px; padding: 18px 20px; border: 1px solid rgba(255,255,255,.12); }
.cc-prevcard .h { font: 800 22px/1.25 var(--body); letter-spacing: -.02em; }
.cc-prevcard .b { font: 400 13.5px/1.6 var(--body); margin-top: 6px; }
.cc-prevcard .btn {
  display: inline-block; font: 700 12px var(--body);
  padding: 8px 14px; border-radius: 6px; margin-top: 10px;
}
.cc-ratio-row { display: flex; align-items: baseline; gap: 14px; }
.cc-ratio-row .num { font: 800 40px/1 var(--body); letter-spacing: -.03em; }
.cc-ratio-row .unit { font: 600 11px var(--mono); color: rgba(255,255,255,.4); }
.cc-ratio-row .spacer { flex: 1; }
.cc-ratio-row .apca { font: 600 11px var(--mono); }
.cc-verdicts { display: grid; grid-template-columns: repeat(4,1fr); gap: 6px; margin-top: 12px; }
.cc-verdicts .tile { border-radius: 6px; padding: 8px 4px; text-align: center; }
.cc-verdicts .tile.pass { background: rgba(76,175,125,.12); }
.cc-verdicts .tile.fail { background: rgba(227,123,123,.1); }
.cc-verdicts .m { display: block; font: 700 10px var(--mono); }
.cc-verdicts .tile.pass .m { color: #4CAF7D; }
.cc-verdicts .tile.fail .m { color: #E37B7B; }
.cc-verdicts .r { display: block; font: 400 8.5px var(--mono); color: rgba(255,255,255,.4); margin-top: 2px; }
.cc-summary { font: 400 10.5px/1.6 var(--body); color: rgba(255,255,255,.45); margin-top: 10px; }
.cc-note { font: 400 11px/1.6 var(--body); color: rgba(255,255,255,.45); margin: 0 0 10px; }
.cc-note code { font: 500 10.5px var(--mono); color: rgba(255,255,255,.7); }
.cc-palin {
  width: 100%; min-height: 96px; resize: vertical; margin-bottom: 12px;
  background: #101114; border: 1px solid rgba(255,255,255,.12); border-radius: 6px;
  padding: 10px 12px; color: #fff; font: 500 12px/1.7 var(--mono);
}
.cc-matwrap { overflow-x: auto; }
.cc-grid2 { display: grid; gap: 4px; min-width: 520px; }
.cc-grid2 .head { font: 600 9px var(--mono); color: rgba(255,255,255,.45); text-align: center; padding: 4px 0; }
.cc-grid2 .head.row { display: flex; align-items: center; text-align: left; }
.cc-grid2 .cell { border-radius: 5px; padding: 9px 2px; text-align: center; }
.cc-grid2 .cell.skip { color: rgba(255,255,255,.25); }
.cc-grid2 .cell .v { display: block; font: 700 11px var(--mono); }
.cc-grid2 .cell .g { display: block; font: 600 8px var(--mono); margin-top: 2px; }
.jf-detected { font: 600 9.5px var(--mono); letter-spacing: .08em; color: #4CAF7D; text-transform: uppercase; }
.tt-io.single { grid-template-columns: 1fr; }

/* Any workspace main column scrolls internally when its content outgrows the
   viewport (a tall resized textarea, a long result list). */
.ws-grid .ws-main { overflow-y: auto; min-height: 0; }

/* Click into a pane and it takes the room: the focused side widens and the
   editor gains height, the other side keeps working at a glance. */
.tt-io { transition: grid-template-columns .18s ease; }
.tt-io.focus-in { grid-template-columns: 2.2fr 1fr; }
.tt-io.focus-out { grid-template-columns: 1fr 2.2fr; }
.tt-io.focus-in #in, .tt-io.focus-out #out { min-height: 380px; }
.tt-io.single.focus-in, .tt-io.single.focus-out { grid-template-columns: 1fr; }
