/* The fonts are served from here (SIL OFL, licences in fonts/). Geist Mono is one variable file for
   every weight, with its arrows in a second, tiny one; Martian Mono only ever appears at 800,
   semi-expanded, so only that instance is shipped. */
@font-face{font-family:"Geist Mono";font-weight:100 900;font-display:swap;src:url(fonts/geist-mono.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}
@font-face{font-family:"Geist Mono";font-weight:100 900;font-display:swap;src:url(fonts/geist-mono-arrows.woff2) format("woff2");
  unicode-range:U+00D7,U+2026,U+2190-2193,U+2197,U+2713}
@font-face{font-family:"Martian Mono";font-weight:800;font-stretch:112.5%;font-display:swap;src:url(fonts/martian-mono-800-semi-expanded.woff2) format("woff2")}
/* --spring is replaced at load with a linear() curve sampled from a damped spring */
:root{--fg:#ECEAF5;--dim:#8A879A;--vio:#9D8CFF;--spring:cubic-bezier(.2,.8,.2,1);--spring-soft:ease-out}
html,body{margin:0;height:100%;background:#000;color:var(--fg);overflow:hidden}
body{font:14px/1.5 "Geist Mono",ui-monospace,monospace}
/* sized to the visible viewport, as field.js draws it: on a phone 100vh also counts the address bar,
   which stretched the field under the page */
#field{position:fixed;inset:0;width:100%;height:100%;display:block}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
[hidden]{display:none!important}
a{color:inherit;text-decoration:none}
a:focus-visible{outline:2px solid var(--vio);outline-offset:4px}

.top,.under,main{opacity:0;transition:opacity .6s var(--spring-soft),filter .5s var(--spring)}
a,.under h2{transition:color .35s var(--spring),text-shadow .5s var(--spring)}
/* a file held over the page: the interface brightens with the field */
body.drop .top,body.drop .under{filter:saturate(1.15) brightness(1.08)}
body.drop .under h2{color:#fff;text-shadow:0 0 18px rgba(157,140,255,.35)}
body.ui .top,body.ui .under,body.ui main{opacity:1}
body.ui .under{transition-delay:.15s}
/* moving between pages: the old content fades out fast, the new one starts hidden and fades in */
body.leaving main,body.leaving .under{opacity:0;transition:opacity .24s ease;transition-delay:0s}
body.entering main,body.entering .under{opacity:0!important;transition:none!important}

.top{position:fixed;top:0;left:0;right:0;display:flex;align-items:center;gap:20px;padding:22px 32px;z-index:2}
.brand{display:flex;align-items:center;gap:10px;font-weight:500}
.brand .tld{color:var(--dim)}
.mk{display:block;width:15px;height:15px}
.top nav{display:flex;gap:26px;margin-left:auto;color:var(--dim)}
[data-box]{padding:14px 26px;display:inline-block}
.top nav a:hover,.top nav a[aria-current]{color:var(--fg)}

.under{position:fixed;left:50%;transform:translateX(-50%);width:min(680px,92vw);text-align:center}
.under h2{font-size:22px;font-weight:500;margin:0;letter-spacing:-.015em;min-height:1.45em}
.under .or{margin:10px 0 0;color:var(--dim);font-size:15px}
.under .or a{color:var(--vio);border-bottom:1px dashed currentColor;padding-bottom:1px}
.under .or a:hover{color:var(--fg)}
.under .tag{margin:30px auto 0;color:#6f6b82;font-size:13px;max-width:52ch}
.under .tag .more{display:block;margin-top:6px}
.under .tag a{color:#8f8aa8;border-bottom:1px dotted #4a4470;transition:color .35s var(--spring),border-color .35s var(--spring)}
.under .tag a:hover{color:var(--vio);border-color:currentColor}
/* what's left of today's free decompiles, and the wall once they're gone */
.under .quota{margin:14px auto 0;color:#4f4b66;font-size:12px;min-height:1.5em}
.under .walled{display:none}
body.wall .under .or:not(.walled){display:none}
body.wall .under .walled{display:block;animation:rise .45s var(--spring-soft)}
body.wall .under .quota{color:var(--vio)}
@keyframes rise{from{opacity:0;transform:translateY(6px)}}
/* a place file's panel (place-page.js): a stand-in until the owner's design pass */
body.placing .under .or,body.placing .under .tag{display:none}
.under .place{margin:14px auto 0;color:var(--dim);font-size:14px}
.under .place p{margin:8px 0}
.under .place input{font:inherit;width:min(340px,70vw);padding:4px 8px;color:var(--fg);background:transparent;border:1px solid #4a4470}
.under .place button,.under .place a{font:inherit;margin:0 8px;padding:0;color:var(--vio);background:none;border:0;border-bottom:1px dashed currentColor;cursor:pointer}
body.busy .under,body.busy .top{opacity:0;pointer-events:none;transition-delay:0s;transition-duration:.45s}
/* what is happening to the dropped file, shown just above the box: a line a stage, the newest at the
   bottom; each earlier one lifts a line (--up) and dims, on a spring, and a new one rises in */
.status{position:fixed;left:50%;transform:translate(-50%,-100%);font-size:16px;white-space:nowrap;height:1.5em;
        opacity:0;transition:opacity .4s var(--spring-soft)}
.status.on{opacity:1}
.status .stage{--up:0;position:absolute;left:50%;bottom:0;margin:0;color:var(--fg);
  transform:translate(-50%,calc(var(--up) * -1.6em)) scale(calc(1 - min(var(--up),2) * .06));
  opacity:calc(1 - min(var(--up),2) * .3);
  transition:transform .6s var(--spring),opacity .5s var(--spring-soft),color .5s var(--spring-soft);animation:stagein .5s var(--spring-soft)}
.status .stage.past{color:#a9a5bd}
.status .pct{color:var(--vio);margin-left:14px;font-variant-numeric:tabular-nums}
@keyframes stagein{from{opacity:0;translate:0 .5em}}
/* the logo box is clickable too: it opens the file picker */
.stage{position:fixed;cursor:pointer}
body.viewing .stage,body.busy .stage{pointer-events:none}
body.viewing .under,body.viewing .top{opacity:0;pointer-events:none;transition-delay:0s;transition-duration:.45s}
.under p{text-wrap:balance}
@media (hover:none){.under .or .mouse{display:none}}
/* Phones: the links fold behind "menu" and open as one row under the top bar, in a single box,
   while the page behind them dims. */
.menu{display:none;font:inherit;color:var(--dim);background:none;border:0;cursor:pointer;transition:color .35s var(--spring)}
.menu:hover,body.menu-open .menu{color:var(--fg)}
@media (max-width:640px){
  .top{padding:16px 18px}
  .menu{display:inline-block;margin-left:auto;padding:12px 22px}
  .top nav{position:fixed;top:72px;left:18px;right:18px;justify-content:space-between;gap:0;margin:0;padding:8px 12px;font-size:13px;
           opacity:0;visibility:hidden;transition:opacity .3s var(--spring-soft),visibility 0s .3s}
  .top nav a[data-box]{padding:10px 8px}
  body.menu-open .top nav{opacity:1;visibility:visible;transition-delay:.08s,0s}
  body.menu-open main,body.menu-open .under,body.menu-open .stage{opacity:.12;transition:opacity .3s var(--spring-soft);pointer-events:none}
}

/* the viewer: the label's box, opened to fill the screen around the decompiled output */
/* (minmax(0,…) everywhere: a long line of code scrolls inside its pane instead of widening the viewer) */
.viewer{position:fixed;display:none;grid-template-rows:auto minmax(0,1fr);grid-template-columns:minmax(0,1fr);opacity:0;transition:opacity .32s var(--spring-soft)}
.viewer.show{opacity:1}
.vbar{display:flex;align-items:center;gap:8px 22px;flex-wrap:wrap;padding:20px 34px 8px;font-size:13px}
.vbar .fname{font-weight:500}
.vbar .vsize{color:var(--dim)}
.vact{margin-left:auto;display:flex;gap:30px;color:var(--dim)}
.vact a:hover{color:var(--fg)}
/* the source fills the viewer; the switches' drawer opens beside it (none wide while shut), and the
   source narrows to make room rather than being covered */
.panes{display:grid;grid-template-columns:minmax(0,1fr) 0px;padding:10px 34px 26px;min-height:0;
  transition:grid-template-columns .55s var(--spring-crit)}
.viewer.panel .panes{grid-template-columns:minmax(0,1fr) 340px}
.pane{display:flex;flex-direction:column;min-height:0;min-width:0}
.pane pre{margin:0;overflow:auto;font:12.5px/1.7 "Geist Mono",ui-monospace,monospace;flex:1;min-height:0;
          scrollbar-width:thin;scrollbar-color:#2a2740 transparent}
/* the source in the site's violets: keywords violet, values pale violet, strings orchid, the names
   of called and declared functions brightest, types muted, comments dim */
.vsrc{color:#cfcbe0}
.vsrc .ln{display:inline-block;width:var(--ln,4ch);color:#3a3750;user-select:none;text-indent:0}
.vsrc .kw{color:#a99bff}
.vsrc .num,.vsrc .con{color:#c4b9ff}
.vsrc .str{color:#e3b5f2}
.vsrc .fn{color:#f6f4ff}
.vsrc .ty{color:#8a82b6}
.vsrc .com{color:#5c5873}
.vsrc .mark{background:rgba(157,140,255,.09)}
.vsrc .mark .ln{color:var(--vio)}
.vsrc .note{color:var(--vio)}
.vsrc .wrap{display:block;white-space:pre-wrap}
/* a very long line's pieces (highlight in field.js), so hovering it doesn't stall the page */
.vsrc .run{display:inline-block}
.vsrc .rows{display:block}
.vsrc .rows.far{content-visibility:auto;contain-intrinsic-height:auto calc(var(--n) * 1.7em)}
/* what the decompile came back as, beside the file name */
.verdict{display:flex;gap:12px;align-items:baseline}
.verdict span:last-child{color:var(--dim)}
.verdict.v-decompiled-unverified b{color:#F3F1FF;font-weight:500}
.verdict.v-marked b{color:var(--vio);font-weight:500}
.verdict.v-refused b{color:#ff9db0;font-weight:500}
/* The choice. Before a file, "options" beside the file link unfolds the presets and switches under
   it. In the viewer, the presets are one segmented control on the bar (picking one runs it), and
   "switches" opens the drawer beside the source. */
.under .or .opts{all:unset;cursor:pointer;color:var(--vio);border-bottom:1px dashed currentColor;padding-bottom:1px;transition:color .3s var(--spring)}
.under .or .opts:hover,.under .or .opts[aria-expanded=true]{color:var(--fg)}
.under .or .opts:focus-visible{outline:1px dotted var(--vio);outline-offset:4px}
/* too narrow for one line: options gets its own, without the dot that would start it */
@media (max-width:560px){.under .or .sep{display:none}.under .or .og{display:block;margin-top:6px}}
.vchoose{display:inline-flex;align-items:center;gap:16px}
.seg{display:inline-flex;flex:none;outline:1px dotted #3a3656;outline-offset:-1px}
.seg button{all:unset;cursor:pointer;box-sizing:border-box;display:inline-flex;align-items:center;height:28px;padding:0 13px;
  font-size:13px;line-height:1;color:var(--dim);transition:color .3s var(--spring),background-color .35s var(--spring),box-shadow .35s var(--spring)}
.seg button+button{box-shadow:-1px 0 0 #2c2944}
.seg button:hover{color:var(--fg)}
.seg button:focus-visible{outline:1px dotted var(--vio);outline-offset:-3px}
.seg button[aria-checked=true]{color:var(--fg);background:rgba(157,140,255,.13);box-shadow:inset 0 0 0 1px rgba(157,140,255,.55)}
.seg button:disabled{cursor:default}
.vsw{all:unset;cursor:pointer;white-space:nowrap;color:#c4b9ff;text-decoration:underline 1px rgba(157,140,255,.45);text-underline-offset:3px;
  transition:color .3s var(--spring),text-decoration-color .3s var(--spring)}
.vsw:hover,.vsw[aria-expanded=true]{color:var(--fg);text-decoration-color:var(--vio)}
.vsw:focus-visible{outline:1px dotted var(--vio);outline-offset:4px}
.vsw .over{color:var(--vio)}
/* re-run: a small box in violet while the switches differ from what shows, dim and inert otherwise */
.switches button{font:inherit}
.switches .vapply{all:unset;cursor:pointer;box-sizing:border-box;height:30px;display:inline-flex;align-items:center;line-height:1;padding:0 16px;outline:1px dotted var(--vio);outline-offset:-1px;color:var(--fg);transition:color .3s var(--spring),outline-color .3s var(--spring)}
.switches .vapply:hover{color:var(--vio)}
.switches .vapply:focus-visible{outline-style:solid}
.switches .vapply:disabled{cursor:default;color:#4f4b66;outline-color:#2c2944}
.vstate{color:#6f6b82;font-size:12px;transition:color .35s var(--spring)}
.vbar .vstate{order:5;flex-basis:100%;margin-top:-4px}
.vbar .vnote{order:6}
.vstate:empty{display:none}
.vstate.why{color:#ff9db0}
.vnote{flex-basis:100%;color:var(--vio);font-size:12px}
.vnote:empty{display:none}
/* while the file decompiles again, the source dims and waits */
.vsrc{transition:opacity .4s var(--spring-soft)}
.viewer.redoing .vsrc{opacity:.32}
.viewer.redoing .vstate{color:var(--vio)}
/* The switches: one list. In the viewer it is the drawer beside the source, fading in as the drawer
   widens; at home it unfolds under the picker, in a box of its own, and scrolls if it must. */
.drawer{min-height:0;min-width:0;overflow:hidden;display:flex}
.drawer .switches{box-sizing:border-box;flex:none;width:340px;height:100%;margin-left:0;padding:0 2px 0 26px;border-left:1px dotted #2c2944;
  overflow-y:auto;scrollbar-width:thin;scrollbar-color:#2a2740 transparent;opacity:0;transition:opacity .25s var(--spring-soft)}
.viewer.panel .drawer .switches{opacity:1;transition:opacity .4s var(--spring-soft) .12s}
/* Home's options take the tagline's place: one fades out as the other fades in, in the same spot,
   while the room between them springs to the new height (field.js sets it for the move). */
.swap{position:relative;overflow:visible clip;overflow-clip-margin:8px;transition:height .5s var(--spring-crit)}
.swap>.swfold,.swap>.blurb{display:flow-root;transition:opacity .35s var(--spring-soft) .12s,visibility 0s}
.swap>.swfold,body.choosing .swap>.blurb{position:absolute;top:0;left:0;right:0;opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .22s var(--spring-soft),visibility 0s .22s}
body.choosing .swap>.swfold{position:static;opacity:1;visibility:visible;pointer-events:auto;transition:opacity .35s var(--spring-soft) .12s,visibility 0s}
/* the options sit on the page itself, no frame: the presets on one line, then the switches as a
   grid of toggles by name (what each does is in the docs, linked under them) */
/* (three columns are wider than the text under the box: the options centre on it and spill past
   both its sides, and only the swap's height clips them) */
.swhome{position:relative;left:50%;transform:translateX(-50%);width:min(940px,96vw);margin:18px 0 0}
.swhome .switches{display:grid;grid-template-columns:repeat(3,auto);justify-content:center;gap:9px 28px;margin-top:18px;padding:3px 6px;
  max-height:min(44vh,420px);overflow-y:auto;scrollbar-width:thin;scrollbar-color:#2a2740 transparent}
.swhome .swg,.swhome .sm,.swhome .sw .by,.swhome .swfoot,body.placing .swfold,body.og .swfold{display:none}
.swhome .sw{border:0;font-size:12px;text-align:left}
.swhome .swr{display:flex;align-items:center;gap:9px;padding:0}
.swhome .swr .tg{padding-top:0}
.swhome .sw .nm{text-transform:lowercase}
.swhome .swhead{grid-column:1/-1;order:1;justify-content:center;margin:8px 0 2px}
/* the presets: the chosen one lit, with its dot */
.plist{display:flex;justify-content:center;flex-wrap:wrap;font-size:13px}
.plist button{all:unset;cursor:pointer;display:inline-flex;align-items:center;gap:7px;padding:2px 0}
.plist button:not(:last-child)::after{content:'·';margin:0 14px 0 7px;color:#3a3656}
.plist button::before{content:'';width:5px;height:5px;border-radius:50%;background:transparent;transition:background-color .3s var(--spring)}
.plist b{font-weight:400;color:var(--dim);transition:color .3s var(--spring)}
.plist span{display:none}
.plist button:hover b,.plist [aria-checked=true] b{color:var(--fg)}
.plist [aria-checked=true]::before{background:var(--vio)}
.plist button:focus-visible{outline:1px dotted var(--vio);outline-offset:3px}
@media (max-width:560px){.swhome .switches{grid-template-columns:repeat(2,auto);gap:9px 18px}}
.swhead{display:flex;justify-content:space-between;gap:16px;align-items:baseline;margin:10px 0 4px;font-size:12px;line-height:1.6;color:#6f6b82}
.swhead a{color:#8f8aa8;border-bottom:1px dotted #4a4470;transition:color .35s var(--spring)}
.swhead a:hover{color:var(--vio)}
#swreset{all:unset;cursor:pointer;flex:none;color:var(--vio);transition:color .3s var(--spring)}
#swreset:hover{color:var(--fg)}
/* re-run stays in reach at the drawer's foot while the list scrolls */
.swfoot{position:sticky;bottom:0;margin:0;padding:12px 0 2px;background:#000}
/* a group's heading, then its rows: the toggle, then the label over what it does, every row whole */
.swg{margin:16px 0 2px;font-size:11px;font-weight:400;color:#57536c;letter-spacing:.04em}
.sw{border-top:1px dotted #2c2944;font-size:13px}
.swr{display:grid;grid-template-columns:30px minmax(0,1fr);gap:2px 12px;align-items:baseline;padding:9px 0;cursor:pointer}
.swr .tg{grid-row:span 2;align-self:start;padding-top:4px}
.sm{grid-column:2;font-size:12px;line-height:1.55;color:#7d7894}
.sm code{color:#a9a1d6;font:inherit}
.tg{display:block;cursor:pointer;line-height:0}
.tg input{position:absolute;opacity:0;width:1px;height:1px;margin:0}
.tg i{display:inline-block;width:24px;height:12px;border-radius:7px;outline:1px dotted #4a4470;position:relative;transition:outline-color .3s var(--spring)}
.tg i::after{content:'';position:absolute;top:2px;left:2px;width:8px;height:8px;border-radius:50%;background:#4a4470;
  transition:transform .5s var(--spring),background .3s var(--spring)}
.tg input:checked+i{outline-color:var(--vio)}
.tg input:checked+i::after{transform:translateX(12px);background:var(--vio)}
.tg input:focus-visible+i{outline:1px solid var(--vio);outline-offset:2px}
.sw .nm{color:#c9c5da;transition:color .3s var(--spring)}
.sw:hover .nm,.sw:has(input:checked) .nm{color:var(--fg)}
.sw.changed .nm::after{content:' •';color:var(--vio)}
.sw .by{display:block;margin:-4px 0 10px 42px;font-size:12px;color:var(--vio)}
.sw .by:empty{display:none}
/* a switch's example: without and with, side by side (stacked on a phone), lit like the viewer's source */
.panes2{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:10px}
.panes2 h5{margin:0 0 4px;font-size:11px;font-weight:400;color:#57536c}
.panes2 pre{margin:0;padding:10px 12px;font:12px/1.65 "Geist Mono",ui-monospace,monospace;color:#cfcbe0;tab-size:4;
  overflow-x:auto;scrollbar-width:thin;scrollbar-color:#2a2740 transparent;outline:1px dotted #2c2944;outline-offset:-1px;background:rgba(10,8,22,.6)}
.panes2 pre .ln{display:inline-block;width:var(--ln,4ch);color:#3a3750;user-select:none}
pre.lua .kw{color:#a99bff}pre.lua .num,pre.lua .con{color:#c4b9ff}pre.lua .str{color:#e3b5f2}
pre.lua .fn{color:#8ecbff}pre.lua .gl{color:#f4a4a4}pre.lua .ty{color:#8a82b6}pre.lua .com,pre.lua .note{color:#6d6888}
/* Narrow screens: the drawer opens above the source instead of beside it, taking half the height. */
@media (max-width:760px){
  .panes,.viewer.panel .panes{grid-template-columns:minmax(0,1fr);grid-template-rows:0fr minmax(0,1fr);transition:grid-template-rows .55s var(--spring-crit)}
  .viewer.panel .panes{grid-template-rows:minmax(0,1fr) minmax(0,1fr)}
  .drawer{order:-1}
  .drawer .switches{width:100%;padding:0;border-left:0;border-bottom:1px dotted #2c2944;margin-bottom:12px}
  .drawer .swfoot{padding-bottom:8px}
}
/* Phones: the bar is the file and the verdict, then the choice on a row of its own, then the actions;
   the code keeps its lines whole and scrolls sideways, except marker comments, which wrap. */
@media (max-width:640px){
  .vbar{padding:18px 20px 4px;gap:8px 18px}
  .vbar .verdict span:last-child{flex-basis:100%}
  .vbar .verdict{flex-wrap:wrap;gap:2px 12px}
  .vchoose{order:2;flex-basis:100%;justify-content:space-between}
  .vbar .vstate{order:3;flex-basis:100%}
  .vact{order:4;margin-left:0;flex-basis:100%;gap:26px;padding-top:4px}
  .vbar .vnote{order:5}
  .panes{padding:8px 20px 18px}
  .seg button{padding:0 10px;font-size:12px}
  .pane pre{font-size:12px}
}

/* ---- reading pages ----
   The page scrolls inside <main>, over the fixed field; its top edge fades out under the top bar. */
main{position:fixed;inset:0;overflow-y:auto;overflow-x:hidden;z-index:1;
     -webkit-mask-image:linear-gradient(to bottom,transparent 60px,#000 118px);mask-image:linear-gradient(to bottom,transparent 60px,#000 118px);
     scrollbar-width:thin;scrollbar-color:#2a2740 transparent}
@media (prefers-reduced-motion:no-preference){main{scroll-behavior:smooth}}
/* the room below the text lets even the last section scroll up to where the contents list reads it */
.doc{display:grid;grid-template-columns:180px minmax(0,700px);gap:72px;justify-content:center;padding:132px 40px 70vh}
.toc{position:sticky;top:180px;align-self:start;display:flex;flex-direction:column;gap:10px;font-size:13px;color:#5f5b75}
.toc a::before{content:'#';display:inline-block;width:2ch;color:transparent;transition:color .3s var(--spring)}
.toc a:hover{color:var(--fg)}
.toc a.on{color:var(--fg)}
.toc a.on::before{color:var(--vio)}
/* reading pages are quieter than home: the title is set in the label's face, as plain text */
.page-title{font:800 46px/1.1 "Martian Mono",ui-monospace,monospace;font-stretch:semi-expanded;letter-spacing:-.03em;margin:0 0 26px}
.lede{font-size:16px;line-height:1.75;color:#d8d5e4;margin:0;max-width:58ch}
.lede p{font:inherit;color:inherit;margin:0;max-width:none}
.lede p+p{margin-top:12px}
/* the docs' pages, above each one's title; the one showing is underlined in violet */
.docnav{display:flex;flex-wrap:wrap;gap:6px 22px;margin:0 0 30px;font-size:13px;color:#6f6b82}
.docnav a{padding-bottom:3px;border-bottom:1px dotted transparent;transition:color .3s var(--spring),border-color .3s var(--spring)}
.docnav a:hover{color:var(--fg)}
.docnav a[aria-current]{color:var(--fg);border-color:var(--vio)}
/* the overview's list of the other pages, each with its sections (older links' ids land on these) */
.docmap{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:30px 40px;margin:8px 0 26px}
.docmap>div{display:flex;flex-wrap:wrap;align-content:flex-start;gap:6px 16px;padding-top:16px;border-top:1px dotted #2c2944;font-size:13px}
.docmap .pg{flex-basis:100%;font-size:15px;font-weight:500;color:var(--fg)}
.docmap .pg::before{content:'/docs/';color:#6f6b82;font-weight:400}
.docmap p{flex-basis:100%;margin:0 0 4px;font-size:13px}
.docmap a:not(.pg){color:#8f8aa8;scroll-margin-top:120px;transition:color .3s var(--spring)}
.docmap a:hover{color:var(--vio)}
@media (max-width:640px){.docmap{grid-template-columns:minmax(0,1fr)}}
article h2{font-size:19px;font-weight:500;letter-spacing:-.01em;margin:84px 0 18px;scroll-margin-top:120px}
article h2::before{content:'# ';color:var(--vio)}
article p{font-size:14px;line-height:1.85;color:#aaa6bc;margin:0 0 16px;max-width:64ch}
article h3{font-size:15px;font-weight:500;margin:40px 0 12px;scroll-margin-top:120px}
article ul{font-size:14px;line-height:1.85;color:#aaa6bc;margin:0 0 16px;padding-left:1.4em;max-width:64ch}
article code{color:#c4b9ff;font-size:.95em}
/* links inside prose read as links: violet, with a dotted rule under them */
article p a:not([class]),article td a:not([class]),article li a:not([class]){color:var(--vio);border-bottom:1px dotted #4a4470;transition:color .35s var(--spring),border-color .35s var(--spring)}
article p a:not([class]):hover,article td a:not([class]):hover,article li a:not([class]):hover{color:var(--fg);border-color:var(--fg)}
article a code{color:inherit}
.endpoint{font-size:16px;color:var(--fg);margin:0 0 18px;overflow-wrap:anywhere}
.endpoint .m{color:var(--vio);margin-right:1ch}
/* code sits in a box the field draws; the padding keeps the box's lines clear of it */
.code{display:block;position:relative;padding:24px 28px;margin:20px 0 26px}
.code pre{margin:0;font:13px/1.75 "Geist Mono",ui-monospace,monospace;color:#d9d6e6;white-space:pre;overflow-x:auto;scrollbar-width:none}
.code .copy{position:absolute;top:10px;right:14px;font-size:12px;color:var(--dim)}
.code .copy:hover{color:var(--fg)}
.code .k{color:#a99bff}.code .s{color:#e3b5f2}.code .c{color:#5c5873}.code .n{color:#c4b9ff}
.code pre{tab-size:4}
/* tabs: the chosen one is underlined in violet; the panes stack, only the chosen one in flow */
.code .tabbar{display:flex;flex-wrap:wrap;gap:6px 20px;margin:-8px 64px 16px 0;font-size:12px}
.code .tabbar button{all:unset;cursor:pointer;color:var(--dim);padding-bottom:3px;border-bottom:1px dotted transparent;
  transition:color .3s var(--spring),border-color .3s var(--spring)}
.code .tabbar button:hover{color:var(--fg)}
.code .tabbar button[aria-selected=true]{color:var(--fg);border-color:var(--vio)}
.code .tabbar button:focus-visible{outline:1px dotted var(--vio);outline-offset:3px}
.code [role=tablist]{display:flex;flex-wrap:wrap;gap:6px 20px}
/* A shell command's box also picks the system (right of the tabs, in violet, so it doesn't read as
   another tab). It fades while a tab without a command shows. Only the system's spelling is shown. */
.code .os{display:flex;gap:16px;margin-left:auto;transition:opacity .3s var(--spring-soft),visibility 0s}
.code:not(.shell) .os{opacity:0;visibility:hidden;transition:opacity .2s var(--spring-soft),visibility 0s .2s}
.code .os button{color:#57536c}
.code .os button:hover{color:var(--fg)}
.code .os button[aria-pressed=true]{color:var(--vio)}
html[data-os=windows] .code .nix,html:not([data-os=windows]) .code .win{display:none}
.code .nix,.code .win{animation:osin .35s var(--spring-soft)}
@keyframes osin{from{opacity:0}}
.code .tabpanes{position:relative;transition:height .5s var(--spring-crit)}
.code .tabpanes pre{transition:opacity .32s var(--spring-soft),visibility 0s}
.code .tabpanes pre:not(.on){position:absolute;inset:0 0 auto 0;opacity:0;visibility:hidden;transition:opacity .2s var(--spring-soft),visibility 0s .2s}
article .cap{font-size:12.5px;color:#6f6b82;margin:26px 0 -8px}
table.ref{width:100%;border-collapse:collapse;margin:8px 0 26px;font-size:13.5px}
table.ref th{font-weight:400;color:#57536c;text-align:left;padding:0 18px 10px 0;font-size:12px}
table.ref td{padding:14px 18px 14px 0;border-top:1px dotted #2c2944;vertical-align:top;color:#aaa6bc;line-height:1.7}
table.ref td:first-child{color:var(--fg);white-space:nowrap}
table.ref td.d{color:#6f6b82;white-space:nowrap}
.v-ok{color:#F3F1FF}.v-mark{color:var(--vio)}.v-ref{color:#7d7894}
table.ref td.yes{color:#F3F1FF}
/* a streamed exchange as a transcript: what you send, then each line you get, a note beside each;
   a dimmed line is one only some answers have */
.nd{position:relative;padding:24px 28px;margin:18px 0 22px;max-width:76ch;font-size:13px;line-height:1.75}
.nd .who{display:flex;align-items:center;gap:10px;font-size:11.5px;letter-spacing:.04em;color:#6f6b82;margin:0 0 8px}
.nd .who::after{content:"";flex:1;border-top:1px dotted #2c2944}
.nd .who b{font-weight:400;color:var(--vio)}
.nd .who.in{margin-top:22px}
.nd .who.in b{color:#8ecbff}
.nd .ln{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:0 24px;align-items:baseline;padding:2px 0 2px 14px;border-left:2px solid transparent}
.nd .in~.ln{border-left-color:#1c2636}
.nd .ln code{color:#d9d6e6;font-size:inherit;overflow-wrap:anywhere}
.nd .ln small{font-size:12px;color:#6f6b82;text-align:right;white-space:nowrap}
.nd .opt{margin:6px 0;padding:6px 0 8px;border-left:2px dashed #4a4470;background:linear-gradient(90deg,rgba(157,140,255,.07),transparent 75%)}
.nd .opt .ln{border-left:0}
.nd .opt .ln code{opacity:.8}
.nd .if{padding:0 0 4px 14px;font-size:11.5px;color:var(--vio)}
.nd .if code{color:#c4b9ff;font-size:inherit}
.nd a{color:var(--vio);border-bottom:1px dotted #4a4470}
.nd .k{color:#a99bff}.nd .s{color:#e3b5f2}.nd .n{color:#c4b9ff}.nd .m{color:var(--fg)}
@media (max-width:640px){.nd{padding:20px 18px;font-size:12px}.nd .ln{grid-template-columns:1fr}.nd .ln small{text-align:left}}
/* a readability switch in the options: label, API name and the presets that turn it on, a line of
   what it does, then what the decompiler prints without and with it */
.opt{padding:22px 0 26px;border-top:1px dotted #2c2944}
.opth{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 12px}
.opth b{font-weight:500;color:var(--fg);font-size:15px}
.opth .api{color:#6f6b82;font-size:12px}
.opth .chips{margin-left:auto;font-size:12px;color:#57536c}
.opth .chips i{font-style:normal;color:#c4b9ff;background:rgba(157,140,255,.12);padding:1px 8px;margin-left:6px}
.opt .sum{margin:6px 0 14px;font-size:13px;color:#8a879a}
/* which preset turns on which switch: a filled dot or a faint one */
table.pgrid{width:100%;border-collapse:collapse;margin:10px 0 22px;font-size:13px}
table.pgrid th{font-weight:400;text-align:center;padding:0 8px 12px;vertical-align:bottom}
table.pgrid th b{display:block;font-weight:500;color:var(--fg)}
table.pgrid th small{display:block;font-size:11px;color:#6f6b82}
table.pgrid td{padding:8px;border-top:1px dotted #2c2944;text-align:center;color:#aaa6bc}
table.pgrid td:first-child{text-align:left;color:var(--fg);padding-left:0}
.dot{display:inline-block;width:9px;height:9px;border-radius:50%;background:#2c2944}
.dot.on{background:var(--vio);box-shadow:0 0 8px rgba(157,140,255,.45)}
/* The footer sits in the room below the text, low enough that the last section can still scroll up
   to where the contents list reads it. */
.doc{padding-bottom:0}
.foot{grid-column:1/-1;margin-top:max(140px,calc(70vh - 230px));padding:36px 0 60px;border-top:1px dotted #2c2944;
      display:grid;grid-template-columns:minmax(0,1.5fr) repeat(3,minmax(0,1fr));gap:32px;font-size:13px;color:#6f6b82}
.foot .brand{color:var(--fg)}
.foot p{margin:16px 0 0;max-width:36ch;line-height:1.7}
.foot h3{font-size:12px;font-weight:400;color:#4f4b66;margin:2px 0 14px}
.foot nav{display:flex;flex-direction:column;align-items:flex-start;gap:9px}
.foot a:hover{color:var(--fg)}
.foot .fine{grid-column:1/-1;margin:20px 0 0;font-size:12px;color:#3f3b52}
@media (max-width:900px){.doc{grid-template-columns:minmax(0,1fr);gap:0;padding:112px 22px 0}.toc{display:none}
  .foot{grid-template-columns:repeat(3,minmax(0,1fr));gap:28px 20px;margin-top:140px}.foot>div:first-child{grid-column:1/-1}}
/* Phones: a reference table's rows stack, the name and its type on one line and what it does under
   them, rather than squeezing the prose into a column a few words wide. */
@media (max-width:640px){
  table.ref.stack thead{display:none}
  .opth .chips{margin-left:0;flex-basis:100%}
  table.pgrid th,table.pgrid td{padding-left:4px;padding-right:4px}
  table.ref.stack tr{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 14px;padding:14px 0;border-top:1px dotted #2c2944}
  table.ref.stack td{display:block;border:0;padding:0}
  table.ref.stack td:last-child{flex-basis:100%}
  .code{padding:20px 18px}
  .code pre{font-size:12px}
  .code .os{flex-basis:100%;margin-left:0}
  .lede{font-size:15px}
  .foot{grid-template-columns:repeat(2,minmax(0,1fr))}.foot>nav:last-of-type{grid-column:1/-1}
}

/* ---- the changelog ----
   Each release is a title, its version and a short dashed list. Above them, the activity: days as
   squares on the logo's ramp (dark violet to near white), an empty day a dot like the field's. */
.nb{white-space:nowrap}
.log ul{margin:0;padding:0;list-style:none}
.log li{position:relative;padding-left:2.4ch;font-size:14px;line-height:1.85;color:#aaa6bc;margin:0 0 10px;max-width:64ch}
.log li::before{content:'-';position:absolute;left:0;color:var(--vio)}
.log li b{color:var(--fg);font-weight:500}
.log li a{color:var(--vio);border-bottom:1px dotted #4a4470;transition:color .35s var(--spring),border-color .35s var(--spring)}
.log li a:hover{color:var(--fg);border-color:var(--fg)}
.log .ver{margin:-8px 0 20px;font-size:12.5px}
.log .ver a{color:#6f6b82;border:0;transition:color .3s var(--spring)}
.log .ver a:hover{color:var(--fg)}
.act{display:block;margin:22px 0 10px;padding:24px 28px 20px;font-size:11px;color:#57536c}
.act-grid{display:grid;grid-template-columns:3.6ch repeat(var(--weeks,53),minmax(0,1fr));gap:3px;align-items:center}
.act-grid .mo{grid-row:1;white-space:nowrap;line-height:1;padding-bottom:5px}
.act-grid .wd{grid-column:1;line-height:1}
/* Hundreds of cells, and every transition or animation one holds costs the swap that shows the page
   frames: only a release's ring eases, and only the lit days sweep in (the empty days' dots fade in
   with the page). Backwards, not both: a finished animation keeps no layer. */
.act i{display:block;aspect-ratio:1;background:linear-gradient(#2c2944,#2c2944) center/2px 2px no-repeat}
.act i.l1{background:#5348a2}.act i.l2{background:#8c7dea}.act i.l3{background:#c1b6ff}.act i.l4{background:#f3f1ff}
.act-grid i:hover{outline:1px solid #6f6b82;outline-offset:1px}
.act-grid i.rel{outline:1px solid var(--vio);outline-offset:1px;cursor:pointer;transition:outline-color .25s var(--spring)}
.act-grid i.rel:hover{outline-color:var(--fg)}
.act-grid.in i:is(:not(.l0),.rel){animation:cell .7s var(--spring-crit) calc(.15s + var(--w)*10ms) backwards}
@keyframes cell{from{opacity:0;transform:scale(.3)}}
@media (prefers-reduced-motion:reduce){.act-grid.in i{animation:none}}
.act figcaption{display:flex;flex-wrap:wrap;justify-content:space-between;gap:8px 20px;margin-top:16px;font-size:12px}
.act-say{color:var(--dim);font-variant-numeric:tabular-nums}
.act-key{display:flex;align-items:center;gap:3px}
.act-key i{width:9px;margin:0 1px}.act-key i:first-of-type{margin-left:7px}.act-key i:last-of-type{margin-right:7px}
@media (max-width:640px){.act{padding:20px 16px 16px}}

/* ---- one column, no contents list ---- */
.doc.solo{grid-template-columns:minmax(0,700px)}
/* buttons are text in a box the field draws, like the links in the top bar */
.btn{display:inline-block;padding:16px 34px;font:500 15px "Geist Mono",ui-monospace,monospace;color:var(--fg);
     background:none;border:0;cursor:pointer;transition:color .3s var(--spring)}
.actions{display:flex;align-items:center;gap:28px;margin:36px 0 34px}
.note{font-size:13px;line-height:1.7;color:#7d7894;max-width:60ch;margin:0 0 16px}
/* ---- the account page ----
   Signed out: two boxes side by side, new account and sign in. A number or key shown once sits in a
   box of its own, lit. Buttons inside a box are dotted, violet text; the field draws the boxes. */
.acct .cards{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:26px;margin:40px 0 0}
/* Until the sign-in is known the signed-out cards hold their place unseen, and the "checking" line
   takes none, so a signed-out visitor's page never moves; a change of view eases the box's height. */
.acct .views{position:relative}
.acct .views>#asking{position:absolute;left:0;right:0;margin:16px 0 0}
.acct .cards.pending{visibility:hidden}
.acct .views.gliding{overflow:hidden;transition:height .45s var(--spring)}
.acct .card{display:flex;flex-direction:column;align-items:flex-start;gap:12px;padding:24px 28px;margin:0}
.acct .card h2{margin:0;font-size:15px;font-weight:500}
.acct .card h2::before{content:none}
.acct .card p{margin:0;font-size:13px;line-height:1.7}
.acct .card label{font-size:12px;color:#6f6b82}
.acct .once{margin:40px 0 0}
.acct input[type=password],.acct input[type=text]:not(.sr),.acct input[type=number]{box-sizing:border-box;width:100%;max-width:420px;padding:8px 10px;font:14px "Geist Mono",ui-monospace,monospace;
  color:var(--fg);background:rgba(10,8,22,.7);border:0;outline:1px dotted #4a4470;outline-offset:-1px;transition:outline-color .3s var(--spring)}
.acct input:focus-visible{outline:1px solid var(--vio)}
.acct input::placeholder{color:#4f4b66}
#madenum{font-size:16px;letter-spacing:.04em}
.acct .go,.acct .ln{all:unset;cursor:pointer;color:var(--fg);transition:color .3s var(--spring),outline-color .3s var(--spring)}
.acct .go{box-sizing:border-box;height:32px;display:inline-flex;align-items:center;padding:0 16px;outline:1px dotted var(--vio);outline-offset:-1px}
.acct .go:hover,.acct .ln:hover{color:var(--vio)}
.acct .go:focus-visible,.acct .ln:focus-visible{outline:1px solid var(--vio);outline-offset:2px}
.acct .go:disabled,.acct .ln:disabled{cursor:default;color:#4f4b66;outline-color:#2c2944}
.acct .ln{color:#c4b9ff;border-bottom:1px dotted #4a4470;font-size:13px}
.acct .row{display:flex;gap:22px}
.acct .why{color:#ff9db0;font-size:12px;min-height:1.5em}
.acct .why:empty{min-height:0}
.acct #keywhy{margin:0}
/* Signed in: two panels framed like the cards, membership then keys, each titled with its action
   on the right; the status reads as one line with what it means under it. */
.acct .panel{display:flex;flex-direction:column;gap:14px;padding:24px 28px;margin:26px 0 0}
.acct #in>.panel:first-child{margin-top:40px}
.acct .panel h2{margin:0;font-size:15px;font-weight:500}
.acct .panel h2::before{content:none}
.acct .phead{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:32px}
.acct .sub{margin:0;font-size:13px;line-height:1.7;color:var(--dim)}
/* (the drop flow's `.status` is a fixed, hidden overlay: here it is a line in the panel) */
.acct .status{position:static;transform:none;height:auto;white-space:normal;opacity:1;transition:none;
  display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;margin:0;max-width:none;font-size:15px;color:#bdb8d0}
.acct .status b{font-weight:500;color:var(--fg)}
.acct .status .ln{margin-left:auto}
.acct .status .d{flex-basis:100%;font-size:13px;color:var(--dim)}
/* today's use: a label and the figures over a bar, drawn like the owner's page draws a member's */
.acct .use{display:block;flex-basis:100%;margin:10px 0 4px}
.acct .use .row{display:flex;justify-content:space-between;gap:4px 16px;flex-wrap:wrap;margin:0 0 8px;font-size:13px;color:#bdb8d0}
.acct .use .n{color:var(--dim);font-variant-numeric:tabular-nums}
.acct .use .track{display:block;height:8px;background:#1c1a2e}
.acct .use i{display:block;height:100%;background:var(--vio);transform-origin:0 50%;animation:growx .8s var(--spring) both}
.acct .use i.over{background:#e0607e}
@media (prefers-reduced-motion:reduce){.acct .use i{animation:none}}
/* memberships: a card a tier, then what every membership gets beside the free tier
   (div: the admin page is .acct too, and its table.tiers stays a table) */
.acct div.tiers{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px;margin:26px 0 14px}
/* (not a field box: a dotted border like the buttons', clearer than the field's frames) */
.acct .tier{display:flex;flex-direction:column;padding:24px 24px 22px;margin:0;
  border:1px dotted rgba(157,140,255,.8);background:rgba(0,0,0,.6);
  transition:border-color .4s var(--spring),transform .55s var(--spring),background-color .4s var(--spring-soft)}
.acct .tier:hover{border-color:var(--vio);transform:translateY(-4px);background-color:rgba(157,140,255,.06)}
.acct .tier .price b{transition:color .4s var(--spring-soft)}
.acct .tier:hover .price b{color:#fff}
/* they rise in one after another the first time they scroll into view (account.js) */
.acct .tiers.waiting .tier{opacity:0;transform:translateY(14px)}
.acct .tiers.risen .tier{animation:tierin .7s var(--spring) backwards}
.acct .tiers.risen .tier:nth-child(2){animation-delay:.09s}
.acct .tiers.risen .tier:nth-child(3){animation-delay:.18s}
@keyframes tierin{from{opacity:0;transform:translateY(14px)}}
@media (prefers-reduced-motion:reduce){.acct .tiers .tier{animation:none!important;opacity:1!important;transform:none!important}}
.acct .tier h3{display:flex;align-items:baseline;gap:10px;margin:0 0 14px;font-size:15px;font-weight:500;color:var(--fg)}
.acct .tier p{margin:0;font-size:13px;line-height:1.7;color:var(--dim)}
.acct .tier .price{display:flex;align-items:baseline;gap:8px;color:var(--dim)}
.acct .tier .price b{font:800 34px/1 "Martian Mono",ui-monospace,monospace;font-stretch:semi-expanded;letter-spacing:-.03em;color:var(--fg)}
.acct .tier .count{margin-top:20px;padding-top:16px;border-top:1px dotted #2c2944;font-size:14px;color:#bdb8d0}
.acct .tier .count b{display:block;font-size:17px;font-weight:500;color:var(--fg);font-variant-numeric:tabular-nums}
.acct .tier .time{margin-top:4px;font-size:12px;line-height:1.6}
.acct .tier .time a{color:#bdb8d0;border-bottom:1px dotted #4a4470;white-space:nowrap}
.acct .plans>h3{margin-top:34px}
.acct .plans>p{max-width:none}
.acct table.plan td:not(:first-child){color:#bdb8d0}
.acct table.keys{margin:0}
.acct table.keys td:last-child{text-align:right;white-space:nowrap}
.acct table.keys td:last-child .ln+.ln{margin-left:18px}
.acct .newkey{display:flex;gap:14px;align-items:center;flex-wrap:wrap;margin:2px 0 0}
.acct .newkey input{flex:1;min-width:180px;max-width:none}
/* a new key, shown once: set apart by a violet edge inside the keys panel */
.acct .fresh{display:flex;flex-direction:column;gap:10px;padding:14px 18px;border-left:2px solid var(--vio);background:rgba(157,140,255,.06)}
.acct .fresh p{margin:0}
.acct #keytext{display:block;max-width:100%;overflow-wrap:anywhere;font-size:15px;color:var(--fg)}
@media (max-width:640px){.acct .cards,.acct div.tiers{grid-template-columns:minmax(0,1fr)}.acct .card,.acct .panel,.acct .tier{padding:20px 18px}}
/* the account page moves like the rest of the site: what appears rises in (the second card a beat
   after the first, new key rows one after another), what goes fades out first, and a message rises */
.acct .enter{animation:rise .45s var(--spring-soft) both}
.acct .enter .card+.card,.acct .enter .panel+.panel{animation:rise .45s var(--spring-soft) .08s both}
.acct tr.enter{animation-delay:calc(var(--i,0)*50ms)}
.acct .leave{opacity:0;transform:translateY(-4px);transition:opacity .18s ease,transform .18s ease}
.acct .why:not(:empty){animation:rise .3s var(--spring-soft)}
/* ---- the owner's page (admin.js) ----
   The account page's panels, wider for the tables: today's budget as a meter, a stacked bar a day by
   tier (free, member, owner, colours checked for colour-blind contrast on black), and the members. */
.doc.solo.wide{grid-template-columns:minmax(0,1080px)}
.admin .panel p{margin:0;max-width:none}
.admin .phead{flex-wrap:wrap}
.admin .phead .row{align-items:center}
.admin .meter{height:6px;background:#1c1a2e}
.admin .meter i{display:block;height:100%;width:0;background:var(--vio);transition:width .9s var(--spring)}
.admin .line{font-size:15px;color:#bdb8d0}
.admin .line b{font-weight:500;color:var(--fg)}
.admin .line .d{margin-left:14px;font-size:13px;color:var(--dim)}
.admin .t-free{fill:#8c7dea;background:#8c7dea}.admin .t-member{fill:#c9608f;background:#c9608f}.admin .t-owner{fill:#2f9ec4;background:#2f9ec4}
.admin .key,.admin #tiers{display:flex;flex-wrap:wrap;align-items:center;gap:6px 20px;font-size:12px;color:var(--dim)}
.admin #tiers{font-size:13px;color:#bdb8d0}
.admin .key i,.admin #tiers i{display:inline-block;width:9px;height:9px;margin-right:7px}
.admin .key output{margin-left:auto;color:#bdb8d0;font-variant-numeric:tabular-nums}
.admin .chart svg{display:block;width:100%;height:180px;border-bottom:1px dotted #4a4470}
.admin .chart .bar{transform-box:fill-box;transform-origin:50% 100%;animation:grow .8s var(--spring) var(--d,0s) both;transition:opacity .3s var(--spring-soft)}
.admin .chart svg:hover .bar:not(.on){opacity:.5}
.admin .chart .hit{fill:transparent}
.admin .chart .grid{stroke:#2c2944;stroke-dasharray:2 3;vector-effect:non-scaling-stroke}
.admin .axis{display:flex;justify-content:space-between;gap:12px;margin:6px 0 0;font-size:11px;color:#57536c}
@keyframes grow{from{transform:scaleY(0)}}
@media (prefers-reduced-motion:reduce){.admin .chart .bar{animation:none}}
.admin .scroll{overflow-x:auto;scrollbar-width:thin;scrollbar-color:#2a2740 transparent}
/* (a year of days scrolls inside its panel, under its header) */
.admin .scroll.tall{max-height:560px;overflow-y:auto}
.admin .scroll.tall th{position:sticky;top:0;z-index:1;padding-top:4px;background:#000}
.admin table.ref{margin:0;font-size:12.5px}
.admin table.ref th,.admin table.ref td{padding-right:16px;white-space:nowrap;font-variant-numeric:tabular-nums}
.admin table.days :is(th,td):not(:first-child){text-align:right}
.admin tr.sum td{color:var(--fg)}
.admin details summary{cursor:pointer;color:#c4b9ff}
.admin details span{display:block;font-size:11.5px;color:var(--dim)}
/* a member's detail row: since, grants and keys side by side, wrapping rather than widening the table */
.admin table.ref tr.detail td{border-top:0;padding-top:0;white-space:normal}
.admin tr.detail .more{display:flex;flex-wrap:wrap;gap:6px 40px;font-size:12px}
.admin tr.detail .part{display:flex;flex-direction:column;min-width:0}
.admin tr.detail i{font-style:normal;font-size:11px;color:#57536c}
.admin tr.detail span{display:block;color:var(--dim)}
.admin td.gone{color:#ff9db0}
.admin td.spark span{display:inline-block;width:90px;height:16px;margin-left:10px;vertical-align:middle}
.admin td.spark svg{display:block;width:100%;height:100%;fill:var(--vio)}
.admin tr.adding td{border-top:0;padding-top:0}
/* (a row's form stays in view however far its wide table is scrolled) */
.admin table.ref tr.adding td{white-space:normal}
.admin tr.adding form{position:sticky;left:0;max-width:min(640px,calc(100vw - 90px))}
.admin .fields{display:flex;flex-wrap:wrap;align-items:flex-end;gap:12px 16px}
.admin .fields label{display:flex;flex-direction:column;gap:6px;flex:1 1 220px;font-size:12px;color:#6f6b82}
.admin .fields label.n{flex:0 0 96px}
.admin .fields .why{flex-basis:100%;margin:0}
.admin .fields input{max-width:none}
/* failures in amber, apart from the tiers' pinks, flagged on a day's bar; quality in four hues checked
   for colour-blind separation on black; usage shape as bars a range long, inputs as a histogram */
.admin .t-fail,.admin .flag{fill:#f5a33b;background:#f5a33b}
.admin .q-clean{fill:#4fa47f;background:#4fa47f}.admin .q-marked{fill:#8c7dea;background:#8c7dea}
.admin .q-standIns{fill:#b8843a;background:#b8843a}.admin .q-refused{fill:#d65c9a;background:#d65c9a}
.admin .chart.short svg{height:110px}
.admin .line .out{color:#ff9db0}
.admin .share{display:flex;gap:2px;height:12px;background:#1c1a2e;transform-origin:0 50%;animation:growx .8s var(--spring) both}
.admin .share i{flex:0 1 0;min-width:2px}
@keyframes growx{from{transform:scaleX(0)}}
.admin .shape{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px 36px}
.admin .shape h3{margin:0 0 10px;font-size:12px;font-weight:400;color:#6f6b82}
.admin .hb{display:grid;grid-template-columns:9ch minmax(0,1fr) 14ch;gap:10px;align-items:center;font-size:12px;line-height:1.9;color:#bdb8d0}
.admin .hb .track{height:6px;background:#1c1a2e}
.admin .hb i{display:block;height:100%;background:var(--vio);transform-origin:0 50%;animation:growx .8s var(--spring) both}
.admin .hb .n,.admin .hist .n{color:var(--dim);font-variant-numeric:tabular-nums}
.admin .hb .n{text-align:right}
.admin .hist{display:grid;grid-template-columns:repeat(var(--n,8),minmax(0,1fr));gap:4px}
.admin .hist .col{display:flex;flex-direction:column;gap:5px;text-align:center;font-size:10.5px;line-height:1.3}
.admin .hist .well{display:flex;align-items:flex-end;height:64px;border-bottom:1px dotted #4a4470}
.admin .hist .well i{display:block;width:100%;background:var(--vio);transform-origin:50% 100%;animation:grow .8s var(--spring) both}
.admin .hist .l{color:#6f6b82}
.admin .uhist{margin-bottom:22px}
.admin .uhist .hist .well{height:180px}
@media (prefers-reduced-motion:reduce){.admin .share,.admin .hb i,.admin .hist i{animation:none}}
.admin tr.failed td:first-child,.admin td.fail{color:#ff9db0}
.admin table.days td[title]{text-decoration:underline dotted #4a4470;text-underline-offset:4px;cursor:help}
.admin .keys b{font-weight:400;color:#bdb8d0}
.admin .keys .ln,.admin td.acts .ln{font-size:12px}
.admin .keys .ln,.admin td.acts .ln+.ln{margin-left:12px}
/* the second click a destructive act needs, risen in beside the first */
.admin .sure{display:inline-block;margin-left:12px;color:#ff9db0;border-bottom-color:#6b3445}
.admin .sure:hover{color:#ffc4d0}
.admin .go.danger:not(:disabled){color:#ff9db0;outline-color:#e0607e}
.admin .fields .warn{flex-basis:100%}
/* member economics: plain sentences beside a table by tier, a bar a member against its allowance
   (a histogram past 20), the table folded away; a member its tier's price doesn't cover is in rose */
.admin .ehead{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:18px 36px;align-items:start;margin-top:4px}
.admin .esay{display:flex;flex-direction:column;gap:10px;min-width:0}
.admin .esay #econmore{display:flex;flex-direction:column;gap:8px;margin-top:6px}
.admin .esay .big{font-size:19px;line-height:1.45;color:#bdb8d0}
.admin .esay .big b{font-weight:600;color:var(--fg)}
.admin .esay .calm{font-size:16px;line-height:1.6;color:#bdb8d0;max-width:64ch}
.admin .esay .meter{max-width:560px;height:4px}
.admin .esay .line{font-size:13px;color:var(--dim)}
.admin .fields label.t{flex:0 0 250px}
.admin select{box-sizing:border-box;width:100%;padding:8px 10px;font:14px "Geist Mono",ui-monospace,monospace;color:var(--fg);
  background:#0a0816;border:0;outline:1px dotted #4a4470;outline-offset:-1px;transition:outline-color .3s var(--spring)}
.admin select:focus-visible{outline:1px solid var(--vio)}
.admin .etiers{min-width:0}
.admin .etiers h3{margin:0 0 6px;font-size:12px;font-weight:400;color:#6f6b82}
.admin table.tiers{font-size:12.5px}
.admin table.tiers :is(th,td):not(:first-child){text-align:right}
.admin table.tiers td b{font-weight:500;color:var(--fg)}
.admin table.tiers tr.loss td:last-child{color:#ff9db0}
.admin .ub .l small{margin-left:8px;font-size:11px;color:var(--dim)}
.admin .ebars{margin-top:10px}
.admin .ebars h3{margin:0 0 6px;font-size:12px;font-weight:400;color:#6f6b82}
.admin .ub{display:grid;grid-template-columns:16ch minmax(0,1fr) 30ch;gap:0 14px;align-items:center;font-size:12px;line-height:2;color:#bdb8d0}
.admin .ub .track{position:relative;height:8px;background:#1c1a2e}
.admin .ub i{display:block;height:100%;background:var(--vio);transform-origin:0 50%;animation:growx .8s var(--spring) both}
.admin .ub i.over{background:#e0607e}
.admin .ub .cap{position:absolute;top:-4px;bottom:-4px;width:1px;margin-left:-1px;background:#bdb8d0}
.admin .ub .n{color:var(--dim);font-variant-numeric:tabular-nums}
.admin .ub.axis{font-size:10.5px;line-height:1.4;color:#57536c}
.admin .ub .scale{position:relative;height:1.4em}
.admin .ub .scale span{position:absolute;left:0}
.admin .ub .scale span+span{transform:translateX(-50%)}
.admin .ub .scale span.end{transform:translateX(-100%)}
@media (prefers-reduced-motion:reduce){.admin .ub i{animation:none}}
.admin #econspread{font-size:12px;color:#6f6b82}
.admin details.more>summary{width:max-content;font-size:12.5px}
.admin details.more[open]>.scroll{margin-top:10px;animation:rise .45s var(--spring-soft)}
.admin table.econ :is(th,td):not(:first-child){text-align:right}
.admin table.econ th button{all:unset;cursor:pointer;transition:color .3s var(--spring)}
.admin table.econ th button:hover,.admin table.econ th[aria-sort] button{color:var(--fg)}
.admin table.econ th button:focus-visible{outline:1px dotted var(--vio);outline-offset:2px}
.admin table.econ th[aria-sort=descending] button::after{content:" ↓"}
.admin table.econ th[aria-sort=ascending] button::after{content:" ↑"}
.admin tr.loss td:last-child{color:#ff9db0}
@media (max-width:760px){.admin .shape,.admin .ehead{grid-template-columns:minmax(0,1fr)}
  .admin .esay .big{font-size:17px}.admin .ub{grid-template-columns:minmax(0,1fr) auto}.admin .ub .track,.admin .ub .scale{grid-column:1/-1;grid-row:2}
  .admin .ub.axis>span:not(.scale){display:none}}
.admin #gate{margin-top:40px;max-width:520px}
.admin #desk>.panel:first-child{margin-top:40px}
/* ---- without WebGL 2 ----
   No field: the label is set as text in the label's face, and boxes are dotted outlines. */
body.nogl [data-box],body.nogl .viewer{outline:1px dotted #3a3656;outline-offset:-1px;transition:outline-color .35s var(--spring)}
body.nogl [data-box]:hover,body.nogl [data-box][aria-current],body.nogl [data-box][data-primary]{outline-color:#6d5fc4}
body.nogl #nav[hidden],body.nogl:not(.menu-open) #nav{outline:0}
body.nogl.menu-open #nav{outline:1px dotted #3a3656}
body.nogl h1.sr{position:fixed;left:50%;top:33vh;top:33svh;transform:translate(-50%,-50%);width:auto;height:auto;overflow:visible;clip-path:none;
  margin:0;padding:.32em .62em;white-space:nowrap;font:800 min(8.4vw,110px)/1 "Martian Mono",ui-monospace,monospace;font-stretch:semi-expanded;
  letter-spacing:-.02em;outline:1px dotted #3a3656;transition:opacity .45s var(--spring-soft),outline-color .35s var(--spring)}
body.nogl.drop h1.sr{outline-color:var(--vio)}
body.nogl.busy h1.sr,body.nogl.viewing h1.sr{opacity:0}
body.nogl .stage{left:50%;top:33vh;top:33svh;transform:translate(-50%,-50%);width:min(84vw,1000px);height:min(15vw,190px)}
body.nogl .under{top:calc(33vh + min(8.4vw,110px)*.82 + 44px);top:calc(33svh + min(8.4vw,110px)*.82 + 44px)}
body.nogl .status{top:33vh;top:33svh;transform:translate(-50%,-50%)}
/* the home label, set as type where the field cleared room for its letters (field.js places,
   uncovers and fades it); clicks go through to the box under it. It is filled on the logo's ramp,
   violet into near white, and glows violet: a drop-shadow, since a text-shadow would paint over a
   gradient fill. */
h1.sr.shown{position:fixed;margin:0;width:auto;height:auto;overflow:visible;white-space:nowrap;text-align:center;
  font-family:"Martian Mono",ui-monospace,monospace;font-weight:800;font-stretch:semi-expanded;
  color:transparent;background:linear-gradient(100deg,#8c7dea,#c1b6ff 40%,#f3f1ff 78%);-webkit-background-clip:text;background-clip:text;
  --glow:drop-shadow(0 0 .08em rgba(193,182,255,.45)) drop-shadow(0 0 .35em rgba(157,140,255,.35));
  filter:var(--glow);pointer-events:none;opacity:0;transition:filter .3s var(--spring-soft)}
h1.sr.shown .tld{color:var(--dim)}
body.menu-open h1.sr.shown{filter:opacity(.12) var(--glow)}
/* the link-preview frame: the label and what it does, nothing to click */
body.og .top,body.og .under .or,body.og .under .quota,body.og .under .more{display:none}
body.og .under .tag{margin-top:16px;font-size:14px}
body.og h1.sr{position:fixed;transform:translate(-50%,-50%);width:auto;height:auto;overflow:visible;clip-path:none;margin:0;
  white-space:nowrap;font-family:"Martian Mono",ui-monospace,monospace;font-weight:800;font-stretch:semi-expanded;line-height:1;color:#F3F1FF}
/* the 404 page: the title alone in the middle of the screen */
.doc.lost{min-height:100vh;min-height:100svh;box-sizing:border-box;align-content:center;padding-top:0}
.doc.lost .page-title{font-size:min(28vw,180px);margin-bottom:18px}
.doc.lost .actions{gap:48px}
