/* Fonts: IBM Plex Mono and VT323, SIL Open Font License 1.1, see fonts/OFL-*.txt */
/* Layout: the tool is one viewport-high terminal (.app). Prompt line on top (it is also the query input),
   stdin | stdout panes that scroll inside themselves, status line at the bottom. On the built tool pages a
   normal page section (.doc) follows below it. Dark phosphor themes only, by choice. */

/* Fonts are served from fonts/, so the page makes no network requests. Both are under the SIL Open Font
   License 1.1 (see fonts/OFL-*.txt). Plex Mono files are IBM's own split subsets, unmodified; the browser
   fetches a subset only when the page uses a character in its range. The first paint needs only the 400 weight
   and VT323; weights 500 and 600 and the symbol subset are in fonts-lazy.css, which loads after it. */
@font-face{font-family:"IBM Plex Mono"; font-weight:400; font-display:swap; src:url("fonts/IBMPlexMono-Regular-Latin1.e8993d9466.woff2") format("woff2");
  unicode-range:U+0020-007E,U+00A0-00FF,U+0131,U+0152-0153,U+02C6,U+02DA,U+02DC,U+2013-2014,U+2018-201A,U+201C-201E,U+2020-2022,U+2026,U+2030,U+2039-203A,U+2044,U+20AC,U+2122,U+2212,U+FB01-FB02}
@font-face{font-family:"IBM Plex Mono"; font-weight:400; font-display:swap; src:url("fonts/IBMPlexMono-Regular-Latin2.8c5e48e4c6.woff2") format("woff2");
  unicode-range:U+0100-0101,U+0104-0130,U+0132-0151,U+0154-017F,U+018F,U+0192,U+01A0-01A1,U+01AF-01B0,U+01FA-01FF,U+0218-021B,U+0237,U+0259,U+1E80-1E85,U+1E9E,U+20A1,U+20A4,U+20A6,U+20A8-20AA,U+20AD-20AE,U+20B1-20B2,U+20B4-20B5,U+20B8-20BA,U+20BD,U+20BF}
@font-face{font-family:"VT323"; font-weight:400; font-display:swap; src:url("fonts/vt323-latin-400-normal.8ddbebcc10.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
:root{
  color-scheme:dark;
  --bg:#040906; --panel:#07110b; --line:#163a27; --fg:#a9efc0; --dim:#5d9d78; --hi:#3dff8f;
  --str:#7fe0d2; --num:#f1c453; --kw:#ff7fc2; --err:#ff5a68;
  --add:#3dff8f; --del:#ff5a68; --chg:#f1c453;
  --hover:#3dff8f12; --sel:#3dff8f26; --errbg:#ff5a6826; --glow:#3dff8f55; --scan:#00000030;
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --disp:"VT323","IBM Plex Mono",ui-monospace,monospace;
  --fs:13px; --lh:20px;
}
:root[data-theme="amber"]{
  --bg:#0a0601; --panel:#120b02; --line:#4a3310; --fg:#ffcf87; --dim:#a87a3c; --hi:#ffb000;
  --str:#ffe7b8; --num:#ff9248; --kw:#f5e663; --err:#ff4a3d;
  --add:#c3e86a; --del:#ff4a3d; --chg:#ffb000;
  --hover:#ffb00012; --sel:#ffb00026; --errbg:#ff4a3d26; --glow:#ffb00055;
}
:root[data-theme="ice"]{
  --bg:#03070b; --panel:#07101a; --line:#17324a; --fg:#b9dcf5; --dim:#6590ad; --hi:#5ad1ff;
  --str:#a5f0c5; --num:#f1c453; --kw:#ff8fd0; --err:#ff5a68;
  --add:#a5f0c5; --del:#ff5a68; --chg:#f1c453;
  --hover:#5ad1ff12; --sel:#5ad1ff26; --errbg:#ff5a6826; --glow:#5ad1ff55;
}
*,*::before,*::after{box-sizing:border-box}
[hidden]{display:none!important}
body{
  margin:0; background:var(--bg); color:var(--fg); font:400 var(--fs)/var(--lh) var(--mono);
  scrollbar-color:var(--line) transparent; scrollbar-width:thin;
}
.app{
  display:grid; grid-template-rows:auto auto minmax(0,1fr) auto; gap:8px;
  height:100vh; height:100svh; min-height:440px; padding:8px 16px 12px;
}
/* the page heading and the privacy line, one thin line above the prompt */
.lede{display:flex; flex-wrap:wrap; align-items:baseline; gap:0 1.5ch; min-width:0; font-size:12px; line-height:18px; color:var(--dim)}
.lede h1{margin:0; font:500 12px/18px var(--mono); color:var(--fg)}
.lede h1::before{content:"# "; color:var(--dim)}
.lede p{margin:0}
.lede p::before{content:"\00b7\00a0"}
body::before{content:""; position:fixed; inset:0; pointer-events:none; z-index:9;
  background:repeating-linear-gradient(0deg,transparent 0 2px,var(--scan) 2px 3px)}
::selection{background:var(--hi); color:var(--bg)}
:focus-visible{outline:1px solid var(--hi); outline-offset:2px}
mark{background:var(--num); color:var(--bg)}
#text mark.now{background:var(--hi); outline:1px solid var(--hi)}
/* scanlines and glow, switched off by the crt button */
:root[data-fx="off"]{--glow:transparent}
:root[data-fx="off"] body::before{display:none}
kbd{font:inherit; padding:0 .6ch; border:1px solid var(--line); color:var(--fg); white-space:nowrap}

/* buttons, shared by every bar */
.acts{display:flex; gap:6px; flex-wrap:wrap; align-items:center}
.seg{display:flex}
.seg button+button{margin-left:-1px}
.acts button,.ea button{
  font:400 12px/1 var(--mono); color:var(--fg); background:transparent; border:1px solid var(--line);
  padding:6px 9px; cursor:pointer; border-radius:0; white-space:nowrap;
}
.acts button:hover:not(:disabled),.ea button:hover{border-color:var(--hi); color:var(--hi); position:relative}
.acts button[aria-pressed="true"],.acts button[aria-pressed="true"]:hover:not(:disabled){background:var(--hi); border-color:var(--hi); color:var(--bg); font-weight:600}
.acts button:disabled{opacity:.35; cursor:default}

/* prompt line */
.top{display:flex; align-items:center; gap:6px 14px; flex-wrap:wrap; min-width:0}
.top .ps1{margin:0; font:400 24px/1 var(--disp); letter-spacing:.02em; color:var(--dim); white-space:nowrap}
.qwrap{position:relative; flex:1 1 220px; min-width:0; height:28px; border-bottom:1px solid transparent}
.qwrap:focus-within{border-bottom-color:var(--line)}
#q,.ph{font:400 24px/28px var(--disp); letter-spacing:.02em; color:var(--hi); text-shadow:0 0 12px var(--glow)}
#q{display:block; width:100%; height:28px; margin:0; padding:0; border:0; outline:0; background:transparent; caret-color:var(--hi)}
.ph{position:absolute; inset:0; pointer-events:none; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.ph .tip{margin-left:2ch; font:400 12px/28px var(--mono); letter-spacing:0; color:var(--dim); text-shadow:none}
.qwrap.has .ph,.qwrap:focus-within #cmd,.qwrap:focus-within .cur{display:none}
.qwrap:focus-within .tip{margin-left:1ch}
.cur{display:inline-block; width:.5em; height:.8em; margin-left:.15em; background:var(--hi); vertical-align:-.05em; animation:blink 1.1s steps(1) infinite}
@keyframes blink{50%{opacity:0}}
.state{margin:0; font:400 20px/1 var(--disp); letter-spacing:.08em; white-space:nowrap}
.state::before{content:"\25CF\00a0"}
.state[data-s="ok"]{color:var(--hi); text-shadow:0 0 10px var(--glow)}
.state[data-s="err"]{color:var(--err)}
.state[data-s="warn"]{color:var(--chg)}
.state[data-s="idle"]{color:var(--dim)}
/* the crt toggle reads as an ordinary button when on, struck through when off */
.top #fx[aria-pressed="true"]{background:transparent; border-color:var(--line); color:var(--fg); font-weight:400}
.top #fx[aria-pressed="false"]{color:var(--dim); text-decoration:line-through}
.top #fx:hover{border-color:var(--hi); color:var(--hi)}

/* panes */
.panes{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:10px; min-height:0}
.pane{display:flex; flex-direction:column; min-width:0; min-height:0; background:var(--panel); border:1px solid var(--line)}
.pane:focus-within,.pane.drop{border-color:var(--dim)}
.bar{display:flex; align-items:center; justify-content:space-between; gap:6px 12px; flex-wrap:wrap; padding:6px 8px 6px 12px; border-bottom:1px solid var(--line)}
.bar h2{margin:0; font:500 12px/1 var(--mono); letter-spacing:.08em; color:var(--hi)}
.bar .ttl{display:flex; align-items:center; gap:10px}
.bar>.acts{margin-left:auto; justify-content:flex-end}
.find{display:flex; align-items:center; gap:6px; flex:1 1 300px; min-width:0}
.find label{color:var(--dim)}
#find{-webkit-appearance:none; appearance:none; flex:1 1 auto; min-width:8ch; width:8ch; margin:0; padding:5px 8px; border:1px solid var(--line); border-radius:0; outline:0;
  background:transparent; color:var(--fg); font:400 12px/1 var(--mono); caret-color:var(--hi)}
#find:focus{border-color:var(--hi)}
#find::placeholder{color:var(--dim)}
#find::-webkit-search-cancel-button{-webkit-appearance:none; appearance:none}
#findN{color:var(--dim); font-size:12px; white-space:nowrap; font-variant-numeric:tabular-nums}

/* stdin editor */
.ed{--efs:13px; --elh:20px; position:relative; flex:1 1 0; display:grid; grid-template-columns:auto minmax(0,1fr); min-height:0; overflow:hidden; font-size:var(--efs); line-height:var(--elh)}
#gut{padding:0 8px; min-width:4ch; overflow:hidden; text-align:right; color:var(--dim); border-right:1px solid var(--line); user-select:none; font-variant-numeric:tabular-nums}
#nums{margin:0; font:inherit}
.ed textarea{grid-column:2; width:100%; height:100%; margin:0; padding:10px 12px; border:0; outline:0; resize:none; background:transparent; color:var(--fg);
  font:inherit; white-space:pre; overflow:auto; tab-size:2; caret-color:var(--hi); scrollbar-color:var(--line) transparent; scrollbar-width:thin}
.ed textarea::placeholder{color:var(--dim)}
#errline{position:absolute; left:0; right:0; top:10px; height:var(--elh); background:var(--errbg); pointer-events:none}

/* stdout */
.out{flex:1 1 0; min-height:0; overflow:hidden}
#tree,#text,#list,#msg{height:100%; overflow:auto; scrollbar-color:var(--line) transparent; scrollbar-width:thin}
/* scrolling to the end of a pane must not start scrolling the page below the tool */
#tree,#text,#list,#msg,#insp,.ed textarea,dialog{overscroll-behavior:contain}
#tree{--ind:2ch; padding:10px 12px 10px 3ch; white-space:pre-wrap; overflow-wrap:anywhere}
#tree:focus-visible{outline-offset:-1px}
#text{margin:0; padding:10px 12px; font:inherit; white-space:pre-wrap; word-break:break-all; tab-size:4}
#tree .ln{position:relative}
#tree .ln:hover{background:var(--hover)}
#tree .ln.sel{background:var(--sel)}
#tree .kids{padding-left:var(--ind); background:linear-gradient(var(--line),var(--line)) no-repeat 0 0/1px 100%}
#tree .n>.kids,#tree .n>.end{display:none}
#tree .n.open>.kids,#tree .n.open>.end{display:block}
#tree .n.open>.ln>.cz{display:none}
#tree .tw{position:absolute; left:-2ch; top:0; width:2ch; height:var(--lh); padding:0; border:0; background:none; color:var(--dim); font:inherit; text-align:center; cursor:pointer}
#tree .tw::before{content:"+"}
#tree .n.open>.ln>.tw::before{content:"-"}
#tree .tw:hover{color:var(--hi)}
#tree .sum{margin-inline:.6ch; color:var(--dim); font-style:italic; cursor:pointer}
#tree .more{display:block; margin:2px 0; padding:0 1ch; background:none; border:1px dashed var(--line); color:var(--dim); font:inherit; cursor:pointer}
#tree .more:hover{color:var(--hi); border-color:var(--hi)}
.out .k{color:var(--hi)}
.out .s{color:var(--str)}
.out .nu{color:var(--num)}
.out .b{color:var(--kw)}
.out .z{color:var(--kw); opacity:.75}
.out .p{color:var(--dim)}
/* value hints: a link, a decoded-time note, a badge that expands what a string holds */
#tree a.lnk{text-decoration:underline; text-decoration-color:var(--dim); text-underline-offset:3px}
#tree a.lnk:hover{color:var(--hi); text-decoration-color:var(--hi)}
#tree .ann{margin-left:1.5ch; color:var(--dim); font-style:italic; user-select:none}
#tree .ann::before{content:"\2192\00a0"}
.tag{display:inline-block; margin-left:1ch; padding:0 .7ch; border:1px solid var(--line); border-radius:0; background:none; color:var(--dim);
  font:400 11px/16px var(--mono); vertical-align:1px; user-select:none}
button.tag{cursor:pointer}
button.tag:hover:not(:disabled),button.tag[aria-expanded="true"]{color:var(--hi); border-color:var(--hi)}
.tag.warn{color:var(--chg); border-color:var(--chg)}
#tree .nest{margin:2px 0 4px; padding-left:3ch; border-left:1px dashed var(--dim)}
#tree .nest::before{content:attr(data-label); display:block; margin-left:-2ch; color:var(--dim); font-size:11px; font-style:italic}

/* diff and validation rows */
#list{padding:10px 12px}
#list .lh{margin:0 0 8px; color:var(--dim)}
#list .lh b{font-weight:500; color:var(--fg)}
.dr{display:flex; gap:0 1ch; width:100%; padding:1px 4px; border:0; background:none; color:inherit; font:inherit; text-align:left; cursor:pointer; overflow-wrap:anywhere}
.dr:hover{background:var(--hover)}
.dr .op{flex:none; width:1ch; font-weight:600}
.dr .dp{flex:none; max-width:55%; color:var(--fg)}
.dr .dv{min-width:0; color:var(--dim)}
.dr.add .op,.dr.add .new{color:var(--add)}
.dr.del .op,.dr.del .old{color:var(--del)}
.dr.chg .op{color:var(--chg)}
.dr.chg .old{color:var(--del)}
.dr.chg .new{color:var(--add)}

/* inspector: details and actions for the selected node */
#insp{flex:none; display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:4px 14px; max-height:42%; overflow:auto;
  padding:6px 8px 6px 12px; border-top:1px solid var(--line); font-size:12px; line-height:18px}
#insp .iw{min-width:0; flex:1 1 240px; overflow-wrap:anywhere}
#insp .ipath{padding:0; border:0; background:none; color:var(--fg); font:inherit; font-weight:500; text-align:left; overflow-wrap:anywhere; cursor:pointer}
#insp .ipath:hover{color:var(--hi)}
#insp .what{margin-left:1.5ch; color:var(--dim)}
#insp .ih{color:var(--dim)}
#insp .dl{flex:1 1 100%; margin:0; padding:0; list-style:none}
#insp .dl button{padding:0; border:0; background:none; color:var(--fg); font:inherit; text-align:left; cursor:pointer}
#insp .dl button:hover{color:var(--hi)}
#insp .dl span{color:var(--dim)}

/* messages: empty, error, nothing found */
#msg{padding:18px 16px}
#msg p{margin:0}
#msg .eh{font:400 28px/1 var(--disp); letter-spacing:.04em; color:var(--err); margin-bottom:8px}
#msg .eh span{color:var(--fg)}
#msg .eh.idle{color:var(--dim)}
#msg .eh.ok{color:var(--hi)}
#msg .em{max-width:65ch; margin-bottom:12px}
#msg .ex{margin:0 0 12px; padding:8px 10px; border:1px solid var(--line); overflow-x:auto; white-space:pre; font:inherit; color:var(--fg)}
#msg .ex .ca{color:var(--err); font-weight:600}
#msg .ea{display:flex; gap:8px; flex-wrap:wrap}
#msg .hint{max-width:65ch; margin-top:10px; color:var(--dim)}
#msg .fh{margin:18px 0 6px; color:var(--hi)}
#msg .fx{margin:0 0 12px; padding:0; list-style:none; max-width:65ch}
#msg .fx button{display:flex; gap:2ch; width:100%; padding:0 4px; border:0; background:none; color:var(--fg); font:inherit; text-align:left; cursor:pointer}
#msg .fx button:hover{background:var(--hover); color:var(--hi)}
#msg .fx b{flex:none; min-width:7ch; font-weight:400; color:var(--dim); font-variant-numeric:tabular-nums}
#msg .fx .rest{padding:0 4px; color:var(--dim)}

/* status line */
.status{display:flex; justify-content:space-between; align-items:baseline; gap:4px 16px; flex-wrap:wrap; min-width:0; font-size:12px; line-height:18px; color:var(--dim); font-variant-numeric:tabular-nums}
.status p{margin:0; min-width:0; overflow-wrap:anywhere}
.status .warn{color:var(--chg)}
.status button.warn{padding:0; border:0; background:none; font:inherit; cursor:pointer; text-decoration:underline; text-underline-offset:3px}
.status button.warn:hover{color:var(--hi)}
#qmsg.err{color:var(--err)}
#note{color:var(--hi)}
#note.err{color:var(--err)}
/* maker's badge: sits at the right end of the status line, same box as the value-hint tags */
#stats{margin-right:auto}
.status .by{flex:none; align-self:center; padding:0 .9ch; border:1px solid var(--line); font-size:11px; line-height:16px; letter-spacing:.04em; white-space:nowrap; user-select:none}
.status .by b{font-weight:500; color:var(--hi)}

/* help */
dialog{width:min(760px,calc(100vw - 32px)); max-height:calc(100vh - 48px); padding:0; border:1px solid var(--dim); background:var(--panel); color:var(--fg); font:400 var(--fs)/var(--lh) var(--mono)}
dialog::backdrop{background:#000000b0}
dialog .bar{position:sticky; top:0; background:var(--panel)}
dialog .body{padding:4px 16px 18px}
dialog h3{margin:16px 0 6px; font:500 12px/1 var(--mono); letter-spacing:.08em; color:var(--hi)}
dialog p{margin:0 0 8px; max-width:70ch; color:var(--dim)}
dialog table{border-collapse:collapse; width:100%}
dialog td{padding:2px 16px 2px 0; vertical-align:top}
dialog td:first-child{white-space:nowrap; color:var(--str)}
dialog td:last-child{color:var(--dim)}

/* the written page below the tool (built tool pages only), and the list of every tool */
.doc{max-width:78ch; padding:28px 16px 8px; border-top:1px solid var(--line); font-size:14px; line-height:22px}
.doc p,.doc li{max-width:72ch}
.doc p{margin:0 0 12px}
.doc .intro{color:var(--hi); margin-bottom:4px}
.doc h2{margin:28px 0 10px; font:500 15px/22px var(--mono); color:var(--hi)}
.doc h2::before{content:"## "; color:var(--dim)}
.doc h3{margin:18px 0 4px; font:500 14px/22px var(--mono); color:var(--fg)}
.doc code{padding:0 .3ch; border:1px solid var(--line); color:var(--str); font:inherit; font-size:13px; overflow-wrap:anywhere}
.doc a,.site a{color:var(--hi); text-decoration:underline; text-decoration-color:var(--dim); text-underline-offset:3px}
.doc a:hover,.site a:hover{text-decoration-color:var(--hi)}
.related{margin:0; padding:0; list-style:none}
.related li::before{content:"> "; color:var(--dim)}
.site{padding:20px 16px 28px; border-top:1px solid var(--line); margin-top:28px; color:var(--dim); font-size:12px; line-height:18px}
.site h2{margin:0 0 8px; font:500 12px/18px var(--mono); letter-spacing:.08em; color:var(--hi)}
.site ul{display:flex; flex-wrap:wrap; gap:4px 18px; margin:0 0 14px; padding:0; list-style:none}
.site a[aria-current="page"]{color:var(--fg); text-decoration:none}
.site p{margin:0}
/* the 404 page */
.nf{max-width:78ch; padding:24px 16px}
.nf pre{margin:18px 0; font:400 20px/26px var(--disp); color:var(--fg); white-space:pre-wrap}
.nf .ps{color:var(--dim)}
.nf .site{margin-top:20px; padding:16px 0 0}

@media (max-width:760px){
  /* on a built tool page the tool takes about 85% of the visible height, so the page below peeks out */
  main.with-doc .app{height:85vh; height:85svh}
  .panes{grid-template-columns:minmax(0,1fr); grid-template-rows:minmax(0,2fr) minmax(0,3fr)}
  /* toolbars become single rows that scroll sideways, so the panes keep their height */
  .bar>.acts{flex:1 1 0; min-width:0; margin-left:0; flex-wrap:nowrap; justify-content:flex-start; overflow-x:auto; scrollbar-width:none}
  .bar>.acts::-webkit-scrollbar{display:none}
  .find{flex:1 1 100%}
  .qwrap{flex-basis:120px}
  .ed{--efs:16px; --elh:24px}
  .top .ps1{font-size:21px}
  #q,.ph{font-size:21px}
  .ph .tip{display:none}
  .state{font-size:18px}
  #find{font-size:16px}
  dialog td:first-child{white-space:normal}
}
@media (prefers-reduced-motion:reduce){.cur{animation:none}}
/* more contrast when the system asks for it: brighter secondary text and borders, no scanlines or glow */
@media (prefers-contrast:more){
  :root[data-theme]{--dim:#9fd8b4; --line:#4f9a72; --glow:transparent}
  :root[data-theme="amber"]{--dim:#e3b679; --line:#a87a3c}
  :root[data-theme="ice"]{--dim:#a6c9e2; --line:#5f8fb5}
  body::before{display:none}
}
