/* ── the web fonts' stand-ins (site decision S21, 2026-10-21) ─────────────────────────────────────────────────
   Until IBM Plex arrives (about three seconds into a first visit on a slow phone) the browser sets the page in a
   local face; a wider stand-in broke the headlines and paragraphs into more lines, and they jumped back when Plex
   came (a layout shift of about 0.1 on the Polish Rtorrent 16 page). These faces are Arial (Windows, Apple; Liberation
   Sans on Linux, the same metrics) and Roboto (Android) resized to Plex's widths, measured over the site's own
   text (26,000 characters of nine pages in seven languages, hinting off as on Apple and Windows screens): Plex Sans
   Condensed 700 is 88.8 % of Arial Bold and 94.6 % of Roboto Bold, 600 is 87.6 and 93.3 %; Plex Sans 400 is 100.4 % of
   Arial and 101.4 % of Roboto, 500 is 102.6 and 102.7 % (Roboto Medium), 600 is 97.3 % of Arial Bold and 103.3 % of
   Roboto Bold. Their ascent and descent are Plex's (1.025 and 0.275 em; the browser scales
   the overrides by size-adjust, so each is divided by it). A device with neither face keeps the old fallbacks.
   Text measures are in em, not ch: a ch is the width of the face's zero, 0.54 em in Plex Sans Condensed and 0.6 em
   in Plex Sans but about 0.49 and 0.56 em in a stand-in, so a 19ch headline was 8 % narrower until Plex came and
   broke into one more line (the Japanese Download page, 0.06 to 0.09). Each width below is its old ch times Plex's
   zero, the same on screen once Plex is there. */
@font-face{font-family:"QU Cond A";font-weight:600;src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold"),local("LiberationSans-Bold");size-adjust:87.58%;ascent-override:117.04%;descent-override:31.40%;line-gap-override:0%}
@font-face{font-family:"QU Cond A";font-weight:700;src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold"),local("LiberationSans-Bold");size-adjust:88.82%;ascent-override:115.40%;descent-override:30.96%;line-gap-override:0%}
@font-face{font-family:"QU Cond R";font-weight:600;src:local("Roboto Bold"),local("Roboto-Bold");size-adjust:93.27%;ascent-override:109.90%;descent-override:29.48%;line-gap-override:0%}
@font-face{font-family:"QU Cond R";font-weight:700;src:local("Roboto Bold"),local("Roboto-Bold");size-adjust:94.60%;ascent-override:108.35%;descent-override:29.07%;line-gap-override:0%}
@font-face{font-family:"QU Sans A";font-weight:400;src:local("Arial"),local("ArialMT"),local("Liberation Sans"),local("LiberationSans");size-adjust:100.39%;ascent-override:102.10%;descent-override:27.39%;line-gap-override:0%}
@font-face{font-family:"QU Sans A";font-weight:500;src:local("Arial"),local("ArialMT"),local("Liberation Sans"),local("LiberationSans");size-adjust:102.63%;ascent-override:99.87%;descent-override:26.80%;line-gap-override:0%}
@font-face{font-family:"QU Sans A";font-weight:600 700;src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold"),local("LiberationSans-Bold");size-adjust:97.26%;ascent-override:105.39%;descent-override:28.27%;line-gap-override:0%}
@font-face{font-family:"QU Sans R";font-weight:400;src:local("Roboto"),local("Roboto-Regular");size-adjust:101.42%;ascent-override:101.06%;descent-override:27.11%;line-gap-override:0%}
@font-face{font-family:"QU Sans R";font-weight:500;src:local("Roboto Medium"),local("Roboto-Medium");size-adjust:102.72%;ascent-override:99.79%;descent-override:26.77%;line-gap-override:0%}
@font-face{font-family:"QU Sans R";font-weight:600 700;src:local("Roboto Bold"),local("Roboto-Bold");size-adjust:103.31%;ascent-override:99.22%;descent-override:26.62%;line-gap-override:0%}

/* ─────────────────────────────────────────────────────────────────────────
   Palette taken off the hardware, not off a swatch: dim rack metal, and the
   amber of a drive-activity LED. Amber is the ONLY accent. The health scale
   below it appears where a state is being described and nowhere else.
   ───────────────────────────────────────────────────────────────────────── */
:root{
  --rack:#0F1418;
  --panel:#151C21;
  --panel-2:#1A2329;
  --rule:#222D34;
  --rule-hi:#33424B;
  --ink:#D8E0E4;
  --dim:#7C8B93;
  --led:#FFB020;
  --led-soft:rgba(255,176,32,.13);
  --lime:#A6E22E;
  --orange:#E8590C;
  --pink:#E8468C;

  --ok:#4FB477;
  --warn:#FFB020;
  --fail:#E05252;

  --sans:'IBM Plex Sans','QU Sans A','QU Sans R',ui-sans-serif,system-ui,'Segoe UI',Helvetica,Arial,sans-serif;
  --cond:'IBM Plex Sans Condensed','QU Cond A','QU Cond R','IBM Plex Sans',ui-sans-serif,system-ui,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,'Cascadia Mono','SF Mono',Consolas,monospace;

  /* The enclosure: outer tray radius, tray wall, and the one easing curve. Used
     by the showcase cards AND by every dialog, so they live here and not inside
     the showcase's own :root further down. */
  --ease-seat:cubic-bezier(.32,.72,0,1);
  --tray:14px;
  --lip:5px;

  --page:min(1720px,100%);
  --gut:clamp(14px,4.5vw,72px);
}
*{box-sizing:border-box}
html{color-scheme:dark;-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--rack);color:var(--ink);
  font-family:var(--sans);font-size:16px;line-height:1.6;
  -webkit-font-smoothing:antialiased;
  -webkit-tap-highlight-color:rgba(255,176,32,.18);
}
button,a{touch-action:manipulation}
a{color:var(--ink)}
:focus-visible{outline:2px solid var(--led);outline-offset:3px;border-radius:2px}

.wrap{max-width:var(--page);margin:0 auto;padding-inline:var(--gut)}

.skip{
  position:absolute;left:-9999px;top:0;background:var(--led);color:#0B0F12;
  padding:10px 16px;font-family:var(--cond);font-weight:700;z-index:99;
}
.skip:focus{left:0}

/* ── masthead ─────────────────────────────────────────────────────────── */
.mast{
  border-bottom:1px solid var(--rule);
  position:sticky;top:0;z-index:40;
  background:rgba(15,20,24,.86);backdrop-filter:blur(10px);
}
.mast .wrap{display:flex;align-items:center;gap:14px;min-height:66px;padding-block:8px}
.brand{
  font-family:var(--cond);font-weight:700;font-size:19px;letter-spacing:.01em;
  margin:0;color:var(--ink);white-space:nowrap;
}
.chip{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--led);border:1px solid rgba(255,176,32,.42);padding:3px 8px 2px;
  border-radius:2px;white-space:nowrap;
}
.mast .sp{flex:1}
/* the mark: the owner's logo of 2026-09-23 as inline SVG (the sheen is SMIL, paused under reduced motion by
   site.js). The full mark carries UNOFFICIAL, so the chip beside it shows only where the icon stands in. */
.qu-d{font-family:'Barlow Semi Condensed',var(--cond),sans-serif;font-weight:800}
.qu-m{font-family:'JetBrains Mono',var(--mono),monospace}
.logo{display:block;height:50px;width:auto;flex:none}
.logo-icon{display:none;height:38px;width:38px;border-radius:9px}
.qu-ink{fill:var(--logo-ink,#e9e7e2)}
.qu-dim{fill:var(--logo-dim,#8b8d93)}
.mast .chip{display:none}
/* the site is dark whatever the browser prefers; a light theme, when it comes, sets --logo-ink:#111214 and --logo-dim:#5c5e64 */
@media (max-width:640px){.logo-full{display:none}.logo-icon{display:block}.mast .chip{display:inline-block}}
.mast .stmt{
  font-family:var(--cond);font-weight:600;font-size:14.5px;letter-spacing:.02em;
  background:none;border:1px solid var(--rule-hi);color:var(--ink);
  padding:7px 14px;border-radius:2px;cursor:pointer;white-space:nowrap;
  transition:border-color .15s ease,background-color .15s ease,color .15s ease;
}
.mast .stmt:hover{border-color:var(--led);color:var(--led);background:var(--led-soft)}

/* ── hero ─────────────────────────────────────────────────────────────── */
/* Compact by construction: at desk widths the headline and the standfirst sit
   side by side, so the hero costs a band rather than a screen. */
.hero{
  padding-block:clamp(26px,3vw,40px) clamp(24px,3vw,38px);
  border-bottom:1px solid var(--rule);
}
@media (min-width:1000px){
  .hero{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(28px,4vw,64px);align-items:center}
}
/* THE SIGNATURE. Eight bays, one of them lit: the whole point of this site in
   one object. Only opacity and transform animate, and the pulse is dropped
   entirely under prefers-reduced-motion — the lit bay stays lit. */
/* The mark: eight bays, one lit. Small enough to sit beside the wordmark and
   still be the thing you recognise the site by. */
.bays{display:flex;gap:2px;height:26px;flex:0 0 auto}
.bay{
  flex:0 0 5px;background:var(--panel-2);
  border:1px solid var(--rule);border-radius:1px;
  position:relative;overflow:hidden;
}
.bay::after{
  content:"";position:absolute;left:1px;right:1px;bottom:2px;height:3px;
  background:var(--rule-hi);border-radius:1px;
}
.bay::after{transition:background-color .3s ease}
.bay.on::after{background:rgba(255,176,32,.42)}
.bay.lit{border-color:rgba(255,176,32,.5);background:#20211B}
.bay.lit::after{background:var(--led);box-shadow:0 0 7px 1px rgba(255,176,32,.7)}
@media (prefers-reduced-motion:no-preference){
  .bay.on::after,.bay.lit::after{animation:blip 3.4s ease-in-out infinite}
  .bay:nth-child(2)::after{animation-delay:-.5s}
  .bay:nth-child(4)::after{animation-delay:-1.1s}
  .bay:nth-child(5)::after{animation-delay:-2.2s}
  .bay:nth-child(7)::after{animation-delay:-1.7s}
  @keyframes blip{0%,100%{opacity:1}44%{opacity:.4}}
}
h1{
  font-family:var(--cond);font-weight:700;
  font-size:clamp(28px,3.4vw,46px);line-height:1.06;letter-spacing:-.015em;
  margin:0;max-width:10.26em;text-wrap:balance;
}
@media (max-width:999px){h1{margin:0 0 16px}}
h1 .amb{color:var(--led)}
/* The creed: each statement is its own line, set tighter than a headline that
   wraps (they are sentences, not one sentence in pieces), and each one steps very
   slightly brighter so the block reads downward. No balance/pretty — the breaks
   are in the markup and nothing may re-flow them. */
h1.creed{max-width:none;line-height:1.12;text-wrap:nowrap}
h1.creed .ln{display:block;color:var(--ink)}
h1.creed .ln:nth-child(1){color:color-mix(in srgb,var(--ink) 78%,transparent)}
h1.creed .ln:nth-child(2){color:color-mix(in srgb,var(--ink) 86%,transparent)}
h1.creed .ln:nth-child(3){color:color-mix(in srgb,var(--ink) 94%,transparent)}
h1.creed .ln.amb{color:var(--led)}
@media (max-width:400px){h1.creed{font-size:26px}}
/* the standfirst fills its column beside the headline, and the full width under it on a narrow screen */
.lede{
  font-size:clamp(15px,1.15vw,17px);color:var(--dim);line-height:1.55;
  margin:0;text-wrap:pretty;
}
.lede p{margin:0 0 14px}
.lede p:last-child{margin-bottom:0}
/* the sign-off: the product's own name, and the name it used to answer to */
.lede .sign{color:var(--ink);font-family:var(--cond);font-weight:600;
  font-size:clamp(15px,1.2vw,18px);letter-spacing:.005em;margin-top:18px;
  padding-top:14px;border-top:1px solid var(--rule)}
.lede .sign small{display:block;margin-top:3px;
  font-family:var(--mono);font-size:11.5px;font-weight:400;letter-spacing:.04em;
  color:var(--dim)}

/* ── section frame ────────────────────────────────────────────────────── */
section{padding-bottom:clamp(56px,8vw,92px)}
#start{padding-top:clamp(34px,4vw,52px)}
.eyebrow{
  display:flex;align-items:baseline;gap:14px;
  margin:0 0 6px;padding-bottom:12px;border-bottom:1px solid var(--rule);
}
.eyebrow h2{
  font-family:var(--cond);font-weight:700;font-size:14px;
  letter-spacing:.19em;text-transform:uppercase;margin:0;color:var(--ink);
}
.eyebrow .note{font-family:var(--mono);font-size:12px;color:var(--dim);margin-left:auto}
.eyebrow-sub{margin-top:26px;border-bottom-color:transparent;padding-bottom:4px}
.eyebrow-sub h3{font-family:var(--cond);font-weight:700;font-size:13px;letter-spacing:.16em;text-transform:uppercase;margin:0;color:var(--dim)}
.films-pair{display:grid;grid-template-columns:1fr 1fr;gap:28px;align-items:start}
@media (max-width:999px){.films-pair{grid-template-columns:1fr}}
/* a lead or note above a row of cards, films or steps spans that row, so their right edges line up (owner 2026-10-20) */
.blurb{color:var(--dim);margin:14px 0 26px;font-size:15px}

/* ── start here: the tutorials ────────────────────────────────────────── */
.films{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(min(268px,100%),1fr));
  gap:18px;margin-top:26px;align-items:stretch;
}
.film{
  display:flex;flex-direction:column;text-align:left;
  background:var(--panel);border:1px solid var(--rule);border-radius:3px;
  overflow:hidden;color:inherit;font:inherit;text-decoration:none;
  transition:border-color .16s ease,transform .16s ease;
}
.film:hover{border-color:var(--rule-hi);transform:translateY(-2px)}
.frame{
  position:relative;aspect-ratio:16/9;background:var(--panel-2);
  border-bottom:1px solid var(--rule);display:grid;place-items:center;overflow:hidden;
}
.frame img{grid-area:1/1;width:100%;height:100%;object-fit:cover;object-position:top center;display:block}
.frame .dur{
  position:absolute;right:8px;bottom:8px;font-family:var(--mono);font-size:10.5px;
  background:rgba(8,11,13,.82);color:var(--ink);padding:2px 6px;border-radius:2px;z-index:2;
  font-variant-numeric:tabular-nums;
}
/* the play badge sits over the poster, so it needs its own ground to stay legible */
.frame .play{background:rgba(11,16,20,.78)}
.film.has-video .frame::after{
  content:"";grid-area:1/1;z-index:1;width:100%;height:100%;background:rgba(11,16,20,.28);
  transition:background-color .16s ease;
}
.film.has-video:hover .frame::after{background:rgba(11,16,20,.06)}
.film.has-video .play{z-index:1}
.film.has-video .dur{z-index:1}

/* the card is the wrapper; the link is everything you click to watch */
.film{position:relative}
.fmain{
  display:flex;flex-direction:column;flex:1 1 auto;
  color:inherit;font:inherit;text-decoration:none;
}
/* share: always visible, never hover-only — a phone has no hover */
.fshare{
  position:absolute;top:8px;right:8px;z-index:3;display:flex;align-items:center;gap:5px;
  font-family:var(--mono);font-size:10.5px;line-height:1;
  background:rgba(8,11,13,.82);color:var(--dim);border:1px solid var(--rule-hi);
  padding:4px 7px;border-radius:2px;cursor:pointer;
  transition:color .15s ease,border-color .15s ease;
}
.fshare:hover,.fshare:focus-visible{color:var(--led);border-color:var(--led)}
/* .film clips its children, so the anchor's own outline never shows — ring the card */
.film:focus-within{border-color:var(--led)}
.fmain:focus-visible{outline:none}
.fshare.done{color:var(--led);border-color:var(--led)}

/* ── the player: one dialog, borderless, as big as the screen allows ───── */
#player{
  border:0;background:#07090B;padding:0;
  width:min(1600px,96vw);max-width:none;max-height:none;border-radius:4px;
}
#player::backdrop{background:rgba(5,7,9,.92);backdrop-filter:blur(4px)}
#player video{display:block;width:100%;max-height:82vh;background:#07090B}
#player .pbar{
  display:flex;align-items:center;gap:14px;padding:12px 16px;
  border-top:1px solid var(--rule);
}
#player .ptitle{
  font-family:var(--cond);font-weight:600;font-size:15.5px;margin:0;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;
}
#player .pinstr{font-family:var(--mono);font-size:11.5px;color:var(--dim);white-space:nowrap}
#player .pshare{margin-left:auto}
#player .pshare,#player .pclose{
  background:none;border:1px solid var(--rule-hi);color:var(--dim);
  font:inherit;font-size:13px;padding:6px 12px;border-radius:2px;cursor:pointer;flex:0 0 auto;
}
#player .pclose:hover{border-color:var(--fail);color:var(--fail)}
#player .pshare{display:flex;align-items:center;gap:6px}
#player .pshare:hover,#player .pshare.done{border-color:var(--led);color:var(--led)}
@media (max-width:640px){
  #player .pinstr{display:none}
  #player video{max-height:60vh}
}
.frame .play{
  grid-area:1/1;z-index:2;width:44px;height:44px;border-radius:50%;
  border:1px solid var(--rule-hi);background:rgba(15,20,24,.7);
  display:grid;place-items:center;color:var(--dim);
  transition:border-color .16s ease,color .16s ease;
}
.film:hover .play{border-color:var(--led);color:var(--led)}
.frame .soon{
  position:absolute;left:10px;top:10px;font-family:var(--mono);
  font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--dim);
  border:1px solid var(--rule-hi);padding:2px 6px;border-radius:2px;
}
.film .txt{display:block;padding:15px 16px 17px;flex:1 1 auto}
.film .sym{display:block;
  font-family:var(--cond);font-weight:600;font-size:17px;line-height:1.25;
  margin:0 0 8px;color:var(--ink);text-wrap:balance;
}
.film .instr{display:block;
  font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;
  color:var(--dim);margin:0;
}
.film:hover .instr{color:var(--led)}

/* ── tools: the primary set ───────────────────────────────────────────── */
.tools{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(min(322px,100%),1fr));
  gap:16px;margin-top:26px;
}
.tool{
  display:flex;gap:16px;align-items:flex-start;
  background:var(--panel);border:1px solid var(--rule);border-radius:3px;
  padding:30px 20px 19px;text-decoration:none;color:inherit;font:inherit;text-align:left;
  cursor:pointer;position:relative;
  transition:border-color .16s ease,background-color .16s ease;
}
.tool:hover{border-color:var(--rule-hi);background:var(--panel-2)}
.tool > span:last-child{display:block;min-width:0}
.tool .ic{width:52px;height:52px;flex:0 0 52px;object-fit:contain;display:block}
.tool .nm{display:block;
  font-family:var(--cond);font-weight:700;font-size:18px;letter-spacing:.005em;
  margin:0 0 5px;color:var(--ink);
}
.tool .ds{display:block;margin:0;font-size:14px;color:var(--dim);line-height:1.5}
.tool .go{
  font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--dim);margin-top:10px;display:inline-flex;align-items:center;gap:6px;
}
.tool:hover .go{color:var(--led)}
/* One filled chip on the page — the free one — and everything else outlined, so
   "free forever" reads as the highlight it is instead of palette drift. */
.tags{position:absolute;top:0;right:0;display:flex;gap:0;z-index:1}
/* Two filled chips on the page and no more: deep orange marks the one thing you
   cannot just download, lime marks the one that costs nothing. Everything else is
   a plain outline, so neither highlight has to compete. */
.tag{
  font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;
  background:rgba(15,20,24,.72);color:var(--dim);border:1px solid var(--rule-hi);
  padding:3px 8px 2px;white-space:nowrap;
}
.tag:last-child{border-radius:0 3px 0 3px}
.tag + .tag{margin-left:-1px}
.tag.gate{background:var(--orange);border-color:var(--orange);color:#1F0E03;font-weight:500}
.tag.free{background:var(--lime);border-color:var(--lime);color:#101507;font-weight:500}
.tag.hot{background:var(--pink);border-color:var(--pink);color:#210610;font-weight:500}

/* SDU is the thing this page is for, so it gets the width and the detail. */
.tool.lead{grid-column:span 2;background:var(--panel-2);border-color:var(--rule-hi)}
.tool.lead .ic{width:64px;height:64px;flex:0 0 64px}
.tool.lead .nm{font-size:22px}
.tool.lead .ds{font-size:15px}
.kit{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(min(178px,100%),1fr));
  gap:5px 20px;margin:14px 0 0;padding:0;list-style:none;
}
.kit li{font-size:13.5px;color:var(--dim);display:flex;gap:8px;align-items:baseline}
.kit li::before{content:"";flex:0 0 5px;height:5px;background:var(--lime);border-radius:1px}
.kit li b{color:var(--ink);font-weight:600;white-space:nowrap}
@media (max-width:760px){.tool.lead{grid-column:auto}}

/* ── second plane: admin tools + links ────────────────────────────────── */
.plane{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(330px,100%),1fr));gap:clamp(30px,5vw,60px)}
.rows{margin-top:20px;border-top:1px solid var(--rule)}
.row{
  display:flex;align-items:baseline;gap:12px;width:100%;
  padding:12px 4px;border-bottom:1px solid var(--rule);
  background:none;border-left:0;border-right:0;border-top:0;
  color:inherit;font:inherit;text-align:left;text-decoration:none;cursor:pointer;
  transition:background-color .14s ease,padding-left .14s ease;
}
.row:hover{background:var(--panel);padding-left:10px}
.row .rn{
  font-family:var(--cond);font-weight:600;font-size:15.5px;color:var(--ink);
  flex:0 0 auto;
}
.row:hover .rn{color:var(--led)}
.row .rd{font-size:13.5px;color:var(--dim);margin-left:auto;text-align:right;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:60%}
.row .ext{font-family:var(--mono);font-size:11px;color:var(--rule-hi);flex:0 0 auto}
.row:hover .ext{color:var(--led)}
.row[aria-disabled="true"]{opacity:.42;cursor:not-allowed}
.row[aria-disabled="true"]:hover{background:none;padding-left:4px}

/* ── footer ───────────────────────────────────────────────────────────── */
footer{border-top:1px solid var(--rule);padding:26px 0 40px;color:var(--dim);font-size:13.5px}
footer .wrap{display:flex;flex-wrap:wrap;gap:8px 20px;align-items:baseline}
footer a{color:var(--dim);text-decoration:none;border-bottom:1px solid var(--rule-hi)}
footer a:hover{color:var(--led);border-color:var(--led)}
footer .sp{flex:1}
footer .un{font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase}

/* ── dialogs ──────────────────────────────────────────────────────────── */
dialog{
  border:1px solid var(--rule);border-radius:var(--tray);padding:var(--lip);
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.012) 42%,transparent) var(--rack);
  color:var(--ink);
  max-width:760px;width:calc(100% - 32px);
  box-shadow:0 30px 90px rgba(0,0,0,.7);
}
dialog::backdrop{background:rgba(6,9,11,.82);backdrop-filter:blur(3px)}

/* ── #dlg-stmt: the DOS alert box, on purpose ──────────────────────────────
   The statement is the one panel on this page that is a DECISION to acknowledge
   rather than a product to read about, so it is drawn the way the memhound
   benchmark draws its alerts (www/assets/css/memhound-doctor.css): a Norton Disk
   Doctor plate in console blue, in the middle of the screen, waiting for the
   operator. Same palette and same measurements as that dialog, copied here
   because this page shares no tokens with the app.
   Scoped to #dlg-stmt: the other seven dialogs keep the page's own block look. */
dialog#dlg-stmt{
  --nd-ground:#0D1A46; --nd-panel:#112156; --nd-panel2:#0B163B;
  --nd-border:#3D5FA8; --nd-edge:#7FD9EC; --nd-ink:#DCE6FF; --nd-dim:#93A5DE;
  --nd-cyan:#6FD3E7; --nd-yellow:#FFD75E;
  --nd-mono:"IBM Plex Mono","Cascadia Mono","JetBrains Mono",Consolas,"DejaVu Sans Mono",monospace;
  max-width:720px;padding:0;border:2px solid var(--nd-edge);border-radius:2px;
  background:var(--nd-panel);color:var(--nd-ink);
  box-shadow:12px 12px 0 #050B22;          /* blur 0 - a plate drawn on the screen */
  font-family:var(--nd-mono);
}
dialog#dlg-stmt .dhd{
  display:flex;align-items:center;justify-content:center;gap:10px;
  padding:7px 12px;background:var(--nd-panel2);border:0;
  border-bottom:1px solid var(--nd-border);border-radius:0;
}
dialog#dlg-stmt .dhd h3{
  margin:0;font:700 13px/1.2 var(--nd-mono);letter-spacing:2px;text-transform:uppercase;
  color:var(--nd-yellow);text-align:center;
}
dialog#dlg-stmt .dbd{
  padding:16px 20px 6px;background:var(--nd-panel);
  font-family:var(--nd-mono);font-size:12.5px;line-height:1.6;color:var(--nd-ink);
  max-height:min(76vh,760px);overflow:auto;
  /* A DOS box says out loud that there is more below: a blocky track in the console
     palette instead of the host's thin overlay bar, which on a dark plate is invisible
     and makes the last cut-off line read as clipping rather than as scrolling. */
  scrollbar-color:var(--nd-edge) var(--nd-panel2);scrollbar-width:thin;
}
dialog#dlg-stmt .dbd::-webkit-scrollbar{width:12px}
dialog#dlg-stmt .dbd::-webkit-scrollbar-track{background:var(--nd-panel2);border-left:1px solid var(--nd-border)}
dialog#dlg-stmt .dbd::-webkit-scrollbar-thumb{background:var(--nd-border);border:2px solid var(--nd-panel2)}
dialog#dlg-stmt .dbd::-webkit-scrollbar-thumb:hover{background:var(--nd-edge)}
dialog#dlg-stmt .dbd p{margin:0 0 12px}
dialog#dlg-stmt .dbd .nd-lead{
  border:1px solid var(--nd-border);background:var(--nd-panel2);
  padding:10px 12px;margin-bottom:14px;color:var(--nd-ink);
}
dialog#dlg-stmt .dbd h4{
  margin:16px 0 6px;font:700 11.5px/1.3 var(--nd-mono);letter-spacing:1.5px;
  text-transform:uppercase;color:var(--nd-cyan);
}
dialog#dlg-stmt .dbd h4::before{content:"\2500\2500 ";color:var(--nd-border)}
dialog#dlg-stmt .dbd a{color:var(--nd-yellow);text-decoration:underline}
dialog#dlg-stmt .dbd b{color:#fff}
dialog#dlg-stmt .nd-marks{color:var(--nd-dim)}
dialog#dlg-stmt .nd-ft{
  display:flex;gap:10px;justify-content:center;align-items:center;
  padding:10px 18px 14px;background:var(--nd-panel);
}
dialog#dlg-stmt .ndbtn{
  font-family:var(--nd-mono);font-size:12px;padding:5px 16px;
  background:var(--nd-panel2);color:var(--nd-ink);
  border:1px solid var(--nd-edge);border-radius:2px;cursor:pointer;
}
dialog#dlg-stmt .ndbtn.primary{
  background:var(--nd-cyan);color:var(--nd-ground);font-weight:700;border-color:var(--nd-cyan);
}
dialog#dlg-stmt .ndbtn:hover{background:var(--nd-border);color:#fff}
dialog#dlg-stmt .ndbtn.primary:hover{background:#9BE6F5;color:var(--nd-ground)}
dialog#dlg-stmt .ndbtn:focus-visible{outline:2px solid var(--nd-yellow);outline-offset:2px}
dialog.small{max-width:440px}
dialog .dhd{
  display:flex;align-items:center;gap:12px;
  padding:15px 18px;
  background:var(--panel);
  border:1px solid var(--rule);border-bottom-color:var(--rule);
  border-radius:calc(var(--tray) - var(--lip)) calc(var(--tray) - var(--lip)) 0 0;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.055);
}
dialog .dhd h3{
  font-family:var(--cond);font-weight:700;font-size:16px;letter-spacing:.02em;margin:0 auto 0 0;
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
dialog .dhd .x{
  order:2;background:none;border:1px solid var(--rule-hi);color:var(--dim);
  width:28px;height:28px;border-radius:2px;cursor:pointer;font-size:15px;line-height:1;
  display:grid;place-items:center;
  transition:border-color .15s ease,color .15s ease;
}
dialog .dhd .x:hover{border-color:var(--fail);color:var(--fail)}
dialog .dhd .sh{
  order:1;flex:0 0 auto;display:flex;align-items:center;gap:6px;background:none;
  border:1px solid var(--rule-hi);color:var(--dim);height:28px;padding:0 9px;border-radius:2px;
  cursor:pointer;font-family:var(--mono);font-size:11px;line-height:1;
  transition:border-color .15s ease,color .15s ease;
}
dialog .dhd .sh:hover,dialog .dhd .sh.done{border-color:var(--led);color:var(--led)}
dialog .dbd{
  padding:20px 22px 24px;max-height:min(74vh,660px);overflow:auto;
  overscroll-behavior:contain;
  background:var(--panel);
  border:1px solid var(--rule);border-top:0;
  border-radius:0 0 calc(var(--tray) - var(--lip)) calc(var(--tray) - var(--lip));
}
dialog h4{
  font-family:var(--cond);font-weight:700;font-size:12.5px;letter-spacing:.17em;
  text-transform:uppercase;color:var(--dim);
  margin:24px 0 10px;padding-bottom:8px;border-bottom:1px solid var(--rule);
}
dialog h4:first-child{margin-top:0}
dialog p{margin:0 0 12px;font-size:15px}
dialog b{color:var(--ink);font-weight:600}
dialog a{color:var(--led)}
dialog ul{margin:0 0 12px;padding-left:20px;font-size:15px}
dialog li{margin-bottom:6px}
dialog code{font-family:var(--mono);font-size:13px;color:var(--led);overflow-wrap:anywhere}
dialog .lead{
  border-left:2px solid var(--led);background:var(--led-soft);
  padding:12px 14px;margin:0 0 16px;
}
dialog .lead b{color:var(--ink)}
/* Installation blocks in the product panels: the App Center route inside a .lead frame,
   the file underneath it. dialog had a ul rule and no ol rule, so the steps get one. */
dialog ol{margin:0 0 12px;padding-left:20px;font-size:15px}
dialog .ins>:last-child{margin-bottom:0}
dialog .ins .ins-more{font-size:13.5px;margin-top:10px}
.shot{display:block;width:100%;height:auto;border:1px solid var(--rule);border-radius:2px;margin:0 0 8px}
.shot.tall{max-height:400px;object-fit:cover;object-position:top center}
.cap{color:var(--dim);font-size:12.5px;margin:0 0 18px}
pre{
  font-family:var(--mono);background:#0B1014;border:1px solid var(--rule);border-radius:2px;
  color:var(--ink);padding:14px 16px;overflow-x:auto;font-size:13px;line-height:1.6;margin:0 0 14px;
}
pre .c{color:var(--dim)}
pre .o{color:var(--ok)}
.dl{display:flex;flex-wrap:wrap;gap:9px;margin:0 0 8px}
.dl a{
  display:flex;flex-direction:column;gap:3px;text-decoration:none;min-width:0;
  background:var(--panel-2);border:1px solid var(--rule);border-radius:9px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04);
  color:var(--ink);padding:12px 15px;min-width:156px;
  transition:border-color .4s var(--ease-seat),background-color .4s var(--ease-seat),transform .4s var(--ease-seat)}
.dl a:hover,.dl a:focus-visible{border-color:var(--led);background:var(--led-soft);transform:translateY(-1px)}
.dl a b{font-family:var(--cond);font-weight:600;font-size:14.5px;color:var(--ink)}
.dl a small{font-family:var(--mono);font-size:11px;color:var(--dim)}
.dl.pick a{flex:1 1 0;align-items:center;text-align:center;padding:16px 12px}
/* App Center repository panel: the address in a box with its own copy button, and the
   list App Center will show, read from repo.json when the panel opens. */
.ac-url{display:flex;align-items:center;gap:10px;background:#0B1014;border:1px solid var(--rule);border-radius:6px;padding:10px 12px;margin:0 0 16px}
.ac-url code{flex:1;min-width:0;overflow-wrap:anywhere;font-size:13.5px}
.ac-url button{
  flex:0 0 auto;background:none;border:1px solid var(--rule-hi);color:var(--dim);height:28px;padding:0 10px;border-radius:2px;
  cursor:pointer;font-family:var(--mono);font-size:11px;line-height:1;transition:border-color .15s ease,color .15s ease;
}
.ac-url button:hover,.ac-url button.done{border-color:var(--led);color:var(--led)}
.ac-list{margin:0 0 14px}
.ac-list table{width:100%;border-collapse:collapse;font-size:14px}
.ac-list th{text-align:left;font-family:var(--cond);font-weight:700;font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--dim);padding:12px 0 6px;border-bottom:1px solid var(--rule)}
.ac-list tr:first-child th{padding-top:0}
.ac-list td{padding:7px 8px 7px 0;border-bottom:1px solid var(--rule);vertical-align:top}
.ac-list td.n{color:var(--ink);font-weight:600}
.ac-list td.n small{display:block;font-family:var(--mono);font-size:11px;font-weight:400;color:var(--dim)}
.ac-list td.v{font-family:var(--mono);font-size:12.5px;color:var(--led);white-space:nowrap}
.ac-list td.a{font-family:var(--mono);font-size:11.5px;color:var(--dim);white-space:nowrap;text-align:right}
.quote{border-left:2px solid var(--led);padding:10px 14px;margin:16px 0;color:var(--ink);font-size:15px}
.quote .who{display:block;font-family:var(--mono);font-size:11.5px;color:var(--led);margin-top:8px}
.meta{color:var(--dim);font-size:12.5px;margin-top:18px;padding-top:12px;border-top:1px solid var(--rule)}
.tnum{font-variant-numeric:tabular-nums}

@media (max-width:400px){
  .brand{font-size:17px}
  .mast .stmt{padding:6px 9px;font-size:13px}
}
@media (max-width:640px){
  .mast .wrap{min-height:0;padding-block:12px;gap:10px}
  .mast .stmt{padding:6px 11px;font-size:13.5px}
  .brand{min-width:0;overflow:hidden;text-overflow:ellipsis}
  /* The mark comes off on a phone. Shrinking it was tried twice and the wordmark
     still landed on it on real hardware, where the condensed face and the browser
     chrome are not what a desktop measures. A name that always reads beats a
     signature that sometimes collides with it. */
  .bays{display:none}
  .row .rd{display:none}
}
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
}

/* ── site menu ────────────────────────────────────────────────────────────
   The page grew past the point where a visitor could find things by scrolling:
   tutorials, tools, downloaders, notifications, admin tools, links and the
   donate band. Since 2026-09-26 it is four lists and About (.mm-*, below); these
   rules style the entries that sit straight in the bar (About), never the lists. */
.menu{display:flex;gap:2px;align-items:center;overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}
.menu::-webkit-scrollbar{display:none}
.menu>a{
  font-family:var(--cond);font-weight:600;font-size:13.5px;letter-spacing:.02em;
  color:var(--dim);text-decoration:none;padding:7px 11px 6px;border:1px solid transparent;border-radius:3px;
  white-space:nowrap;transition:color .15s ease,border-color .15s ease,background-color .15s ease;
}
.menu>a:hover{color:var(--ink);border-color:var(--rule);background:var(--panel-2)}
.menu>a.give{color:var(--led);border-color:rgba(255,176,32,.35)}
.menu>a.give:hover{background:var(--led-soft);border-color:var(--led)}
/* "Read this first" shows only where the bar has room for it beside the menu (1200 px): below that it would
   drop to a line of its own (Polish and Japanese need about 1160 px). The statement stays in About. */
@media (max-width:1200px){.mast .stmt{display:none}}
/* One row where the bar fits, a planned second row where it does not (root-b6's review of 2026-10-31, site S42). From
   1201 px the items stand 10 px apart (14 before) and an entry's name has 7 px each side (9 before), so the bar holds
   one row at 1440 px in every language, a desktop scrollbar included. Between 1041 and 1439 px the six entries do not fit beside the wordmark, the language button and
   the statement button in every language: the menu takes a line of its own under them, as it does up to 1040 px.
   Before, the last item, the statement's LEGAL icon, wrapped alone onto a second row under the wordmark.
   With WebPortico's entry (site decision S73) all seven fit one row from 1590 px in Polish and French, the longest
   (Chromium; the others from 1440 to 1585 px), and 1610 px leaves room for a 17 px desktop scrollbar. From 1440 to
   1609 px About leaves the bar instead (the owner's rule for it: where it does not fit, it is not shown), so the bar
   keeps its one row there; up to 1439 px the menu has a line of its own with all seven. */
@media (min-width:1201px){.mast .wrap{column-gap:10px}.mast .menu .mm-top,.mast .menu .mm-plain{padding-inline:7px}}
@media (min-width:1041px) and (max-width:1439px){.menu{width:100%;order:3;margin-top:8px;padding-bottom:2px}.mast .home{flex:1}}
@media (min-width:1440px) and (max-width:1609px){.menu .mm-plain.mm-about{display:none}html .mast .wrap{flex-wrap:nowrap}}
@media (max-width:1040px){.menu{width:100%;order:3;margin-top:8px;padding-bottom:2px}}
/* On a phone the menu wraps onto a second line instead of scrolling sideways: the scroll had no visible
   scrollbar, so "App Center" was cut in half and "About" could not be seen at all (2026-09-25). */
@media (max-width:560px){.menu{flex-wrap:wrap;overflow:visible;row-gap:4px}}

/* ── the dropdown menu (2026-09-26, the owner's structure; tools/node/site-menu.mjs writes it) ─────────
   Diagnostic, Benchmark and Developers open a list; App Center is a link (the App Center page) with a list
   beside it. A pointer that can hover opens a list by hovering; a touch opens it with the button (site.js
   toggles .open). The lists hang under their own entry, so .menu must not clip: it no longer scrolls. */
.menu{overflow:visible}
/* the four lists and About need 410-545px: where the bar has less beside the wordmark (up to 900px in Polish
   and Japanese), the menu takes a line of its own under it instead of pushing the page sideways */
.mast .wrap{flex-wrap:wrap;row-gap:2px}
.mm{position:relative;display:flex;align-items:center}
.mm-top,.mm-car,.menu .mm-plain{
  font-family:var(--cond);font-weight:600;font-size:13.5px;letter-spacing:.02em;
  color:var(--dim);background:none;padding:7px 11px 6px;border:1px solid transparent;border-radius:3px;
  white-space:nowrap;cursor:pointer;text-decoration:none;
  transition:color .15s ease,border-color .15s ease,background-color .15s ease;
}
.mm-top i{font-style:normal;font-size:9px;margin-left:6px;opacity:.7;vertical-align:1px}
.mm-car{padding:7px 7px 6px;margin-left:-3px}
.mm-car i{font-style:normal;font-size:9px;opacity:.7}
.mm-top:hover,.mm-car:hover,.menu .mm-plain:hover,.mm.open>.mm-top,.mm.open>.mm-car{color:var(--ink);border-color:var(--rule);background:var(--panel-2)}
.mm-list{
  display:none;position:absolute;top:100%;left:0;z-index:41;width:max-content;min-width:260px;max-width:min(440px,calc(100vw - 32px));
  /* the header's own height (--mast, site.js) under the list: on a phone the header is three lines tall, and a
     fixed 96 px left the last lines of a long list below the screen's edge */
  max-height:calc(100vh - var(--mast,66px) - 12px);max-height:calc(100dvh - var(--mast,66px) - 12px);
  overflow-y:auto;overscroll-behavior:contain;
  background:var(--rack);border:1px solid var(--rule);border-top-color:var(--rule-hi);border-radius:0 0 9px 9px;
  box-shadow:0 22px 50px rgba(0,0,0,.55);padding:6px;
}
/* a hover bridge: the list starts at the bottom edge of its entry, so the pointer never leaves the entry */
.mm-r .mm-list{left:auto;right:0}
/* where site.js runs the side menus (.menu.fly) it opens a list on hover itself (.hov), with a grace period on leaving */
@media (hover:hover){
  .menu:not(.fly) .mm:hover>.mm-list{display:block}
  .menu:not(.fly) .mm:hover>.mm-top,.menu:not(.fly) .mm:hover>.mm-car{color:var(--ink);border-color:var(--rule);background:var(--panel-2)}
}
.mm.open>.mm-list,.mm.hov>.mm-list{display:block}
.mm.hov>.mm-top,.mm.hov>.mm-car{color:var(--ink);border-color:var(--rule);background:var(--panel-2)}
/* the page itself: its line in the list in amber, its list's name in full ink and underlined in amber (also where
   the page is a guide its list's How-to line stands for), and where its line sits in a closed side menu, that menu's
   heading in amber */
.mm-top[aria-current="page"],.menu .mm-plain[aria-current="page"],.mm.mm-in>.mm-top{color:var(--ink)}
.mm.mm-in>.mm-top,.menu .mm-plain[aria-current="page"]{box-shadow:inset 0 -2px 0 var(--led)}
.mm-i[aria-current="page"],.menu.fly .mm-fly.mm-in>.mm-h{color:var(--led)}
.mm-list,.menu.fly .mm-gl{scrollbar-width:thin;scrollbar-color:var(--rule-hi) transparent}
/* App Center's page as the list's first entry, only where a tap opened the list: a finger has no hover, and the
   tap on the name opened the list instead of the page (site.js) */
.mm-i.mm-page{display:none}
.mm.touch .mm-i.mm-page{display:flex;border-bottom:1px solid var(--rule);border-radius:6px 6px 0 0;margin-bottom:4px}
.mm-i{
  display:flex;align-items:center;gap:10px;padding:8px 11px;border-radius:6px;
  color:var(--ink);font-family:var(--sans);font-size:14px;line-height:1.3;text-decoration:none;
}
.mm-i:hover,.mm-i:focus-visible{background:var(--panel-2);color:var(--led)}
.mm-t{display:flex;align-items:baseline;gap:7px;min-width:0;flex:1}
/* a hint wraps between its words where a side menu is narrowed, never inside a Japanese or Chinese word */
.mm-t small{font-family:var(--mono);font-size:11px;color:var(--dim);word-break:keep-all}
.mm-x{color:var(--dim);font-size:12px}
.mm-ic{width:18px;height:18px;flex:none;object-fit:contain;border-radius:3px}
.mm-i:not(:has(.mm-ic)){padding-left:39px}
.mm-h{
  margin:8px 6px 4px;padding:9px 5px 0;border-top:1px solid var(--rule);
  font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--dim);
}
.mm-sep{border:0;border-top:1px solid var(--rule);margin:6px 6px}
/* a rule inside a group starts at the text, so it parts the group's lines without reading as a new group */
.mm-gl>.mm-sep{margin-left:39px}
/* a list that opens with a heading needs no rule under its own top edge */
.mm-list>.mm-g:first-child>.mm-h{border-top:0;margin-top:2px;padding-top:4px}
/* Japanese and Chinese have no capitals to space out: the wide tracking only pulls the characters apart */
:lang(ja) .mm-h,:lang(zh-TW) .mm-h{letter-spacing:.04em}
/* inactive entries read as such; Team Members looks the same but opens the sign-in dialog */
.mm-off{color:var(--dim)}
span.mm-off{cursor:default}
span.mm-off:hover{background:none;color:var(--dim)}
.mm-tag{
  font-style:normal;font-family:var(--mono);font-size:10px;letter-spacing:.08em;
  color:var(--dim);border:1px solid var(--rule-hi);border-radius:2px;padding:1px 5px;white-space:nowrap;
}
/* a branch of the entry above: a line drawn from its icon */
.mm-sub{position:relative;margin-left:22px;padding-left:24px}
.mm-sub::before{
  content:"";position:absolute;left:8px;top:-4px;width:9px;height:calc(50% + 4px);
  border-left:1px solid var(--rule-hi);border-bottom:1px solid var(--rule-hi);border-bottom-left-radius:4px;
}
.mm-sub .mm-ic{width:15px;height:15px}
.mm-sub:not(:has(.mm-ic)){padding-left:24px}
/* the gold Safety badge */
.mm-badge,.sf-badge{
  display:inline-flex;align-items:center;gap:4px;font-style:normal;white-space:nowrap;
  font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  color:#2A1C00;background:linear-gradient(180deg,#FFD66B,#E9A91C);border:1px solid #B97F07;
  border-radius:20px;padding:2px 7px 2px 5px;box-shadow:inset 0 1px 0 rgba(255,255,255,.5);
}
/* verified: the lime of the site (--lime), a tick instead of the star */
.mm-badge.mm-ok{color:#101507;background:var(--lime);border-color:#7FB318;box-shadow:inset 0 1px 0 rgba(255,255,255,.35)}
.mm-warn{color:var(--led)}
.mm-warn::after{content:"!";margin-left:auto;font-family:var(--mono);font-weight:700;color:var(--rack);
  background:var(--led);border-radius:50%;width:16px;height:16px;display:grid;place-items:center;font-size:11px}
@media (max-width:1040px){
  .menu{flex-wrap:wrap;row-gap:4px}
  .mm{position:static}
  .mm-list{left:var(--gut);right:var(--gut);width:auto;max-width:none;min-width:0}
  .mm-r .mm-list{left:var(--gut);right:var(--gut)}
}

/* ── the bar as a rack faceplate (2026-10-23; S26, and the design pass of S28) ───────────────────────────
   Each entry is a bay: a line icon (tools/node/site-menu.mjs draws them inline, Lucide's geometry, ISC,
   assets/LICENSE-lucide.txt; 1.5 stroke in currentColor), its name, and under the name the bay's LED. The LED is
   dark at rest, half-lit while the pointer rests on the entry, lit while its list is open (it blinks once as it
   opens) and lit steadily on the entry of the page's own section. One part of each icon (.mi-a) lights with it and
   moves once: the chest piece beats, the needle sweeps round its hub, the cursor blinks, the arrow drops onto its
   line, the box hops, the question mark tilts. On a wide screen one carriage (.mm-glide, site.js) glides under the
   entry the pointer or the keyboard is on and becomes the tab of the open list; the list opens downward from it as a
   drawer, an amber rail running out from under the tab along its top edge and its first rows following one after
   another. Under reduced motion nothing moves: the LEDs and the amber parts only light, the drawer just shows. */
.mm-top,.menu .mm-plain{display:inline-flex;align-items:center;gap:7px;position:relative}
/* on a wide screen the bay is a little tighter than the old text entry, so the bar with its icons is as wide as it was
   without them and the header keeps one row */
@media (min-width:1041px){.mm-top,.menu .mm-plain{padding-inline:9px}}
.mm-ico{width:18px;height:18px;flex:none;overflow:visible;fill:none;stroke:currentColor;stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round;transition:filter .25s ease}
.mm-ico .mi-a{transition:stroke .2s ease}
.mm-ico .mi-dot{stroke-width:2.6}
.mm:is(:hover,.open,.hov,.mm-in) .mi-a,.mm :focus-visible .mi-a,
.menu .mm-plain:is(:hover,:focus-visible,[aria-current="page"]) .mi-a{stroke:var(--led)}
.mm:is(.open,.hov,.mm-in) .mm-ico,.menu .mm-plain[aria-current="page"] .mm-ico{filter:drop-shadow(0 0 5px rgba(255,176,32,.28))}
.mm-car>i{display:block;line-height:0;opacity:.7}
.mm-cv{width:10px;height:10px;display:block;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;
  stroke-linejoin:round;transition:transform .32s cubic-bezier(.16,1,.3,1)}
.mm:is(.open,.hov)>.mm-car .mm-cv{transform:rotate(180deg)}
.mm-car .mm-tile{display:none}
.mi-diag .mi-a,.mi-ac .mi-b,.mi-about .mi-q,.mi-dls .mi-a{transform-box:fill-box}
.mi-diag .mi-a{transform-origin:center}
.mi-bench .mi-a{transform-box:view-box;transform-origin:12px 14px}
.mi-ac .mi-b{transform-origin:50% 100%}
.mi-about .mi-q{transform-origin:50% 62%}
/* WebPortico (site decision S83, the owner 2026-11-13: "only a globe, turning, with parts lighting up"): a globe of
   three meridians 60 degrees apart. --mi-t is the globe's turn; each meridian's width is the cosine of its longitude,
   so a turn of 120 degrees brings the drawing back to where it started. The meridians (.mi-a) light amber like the
   other icons' moving parts; once after the page loads the globe turns and lights by itself. A browser without CSS
   geometry (rx) or registered properties keeps the still globe of the attributes. */
@property --mi-t{syntax:'<angle>';inherits:true;initial-value:0deg}
.mi-web .mi-m ellipse{rx:calc(10px * max(cos(var(--mi-t,0deg) + var(--mi-p)), -1 * cos(var(--mi-t,0deg) + var(--mi-p)), .001))}
.mi-web .mi-m1{--mi-p:0deg}.mi-web .mi-m2{--mi-p:60deg}.mi-web .mi-m3{--mi-p:120deg}
/* the bay's LED: under the name on a wide screen, at the foot of the tile on a phone (below) */
.mm-top::after,.menu .mm-plain::after{content:"";position:absolute;left:50%;bottom:1px;width:4px;height:4px;margin-left:-2px;
  border-radius:50%;background:rgba(255,255,255,.07);pointer-events:none;transition:background-color .2s ease,box-shadow .2s ease}
.mm:hover>.mm-top::after,.menu .mm-plain:hover::after{background:rgba(255,176,32,.45)}
.mm:is(.open,.hov)>.mm-top::after,.mm.mm-in>.mm-top::after,.menu .mm-plain[aria-current="page"]::after{
  background:var(--led);box-shadow:0 0 6px 1px rgba(255,176,32,.6),0 0 14px 2px rgba(255,176,32,.22)}
/* the page's section was underlined in amber; its LED says it now */
.mm.mm-in>.mm-top,.menu .mm-plain[aria-current="page"]{box-shadow:none}
@media (prefers-reduced-motion:no-preference){
  :is(.mm:hover,.mm.open,.mm.hov,.mm:focus-within) .mi-diag .mi-a{animation:mi-beat .72s cubic-bezier(.16,1,.3,1)}
  :is(.mm:hover,.mm.open,.mm.hov,.mm:focus-within) .mi-bench .mi-a{animation:mi-sweep .8s cubic-bezier(.16,1,.3,1)}
  :is(.mm:hover,.mm.open,.mm.hov,.mm:focus-within) .mi-dev .mi-a{animation:mi-blink .9s steps(1,end)}
  :is(.mm:hover,.mm.open,.mm.hov,.mm:focus-within) .mi-dev .mi-p{animation:mi-nudge .5s cubic-bezier(.16,1,.3,1)}
  :is(.mm:hover,.mm.open,.mm.hov,.mm:focus-within) .mi-web{animation:mi-globe 1.1s cubic-bezier(.45,0,.55,1)}
  /* the run after the page loads lives on the meridians' group, the hover on the icon: leaving the entry never starts
     the load's run again */
  .mi-web .mi-m{animation:mi-globe 1.6s cubic-bezier(.45,0,.55,1) .6s,mi-globe-lit 1.6s ease .6s}
  :is(.mm:hover,.mm.open,.mm.hov,.mm:focus-within) .mi-dls .mi-a{animation:mi-drop .62s cubic-bezier(.16,1,.3,1)}
  :is(.mm:hover,.mm.open,.mm.hov,.mm:focus-within) .mi-ac .mi-b{animation:mi-hop .66s cubic-bezier(.16,1,.3,1)}
  .menu .mm-plain:is(:hover,:focus-visible) .mi-about .mi-q{animation:mi-tilt .7s cubic-bezier(.16,1,.3,1)}
  .mm:is(.open,.hov)>.mm-top::after,.mm.open>.mm-car::after{animation:mm-led .5s steps(1,end)}
}
@keyframes mi-beat{0%{transform:none}16%{transform:scale(1.42)}32%{transform:none}48%{transform:scale(1.2)}100%{transform:none}}
@keyframes mi-sweep{0%{transform:none}38%{transform:rotate(-82deg)}72%{transform:rotate(12deg)}100%{transform:none}}
@keyframes mi-blink{0%,33%,66%{opacity:0}16%,50%,100%{opacity:1}}
@keyframes mi-nudge{45%{transform:translateX(1.6px)}}
@keyframes mi-globe{from{--mi-t:0deg}to{--mi-t:120deg}}
@keyframes mi-globe-lit{25%,75%{stroke:var(--led)}}
@keyframes mi-drop{0%{transform:translateY(-4px);opacity:0}58%{transform:translateY(1.2px);opacity:1}100%{transform:none}}
@keyframes mi-hop{0%{transform:none}34%{transform:translateY(-2.8px) rotate(-6deg)}70%{transform:translateY(.4px)}100%{transform:none}}
@keyframes mi-tilt{0%{transform:none}30%{transform:rotate(-17deg)}62%{transform:rotate(9deg)}100%{transform:none}}
@keyframes mm-led{0%,40%{opacity:1}20%,60%{opacity:.3}}

/* the drawer: a list is always laid out and hidden by visibility, so opening it can be a motion. It opens downward
   from its entry (a clip that runs once and then lets go: the side menus beside a list must not be clipped), an amber
   rail runs out along its top edge from under the entry (--rail-o, site.js), and its first ten rows (site.js numbers them, --r)
   come in one after another; it closes in a quarter of the time, a short fade up. */
.mm-list{display:block;visibility:hidden;opacity:0;transform:translateY(-4px);
  background-image:linear-gradient(var(--led),var(--led));background-repeat:no-repeat;background-size:0 2px;
  background-position:var(--rail-o,50%) 0;
  transition:opacity .12s ease,transform .12s ease,background-size .1s ease,visibility 0s linear .12s}
.mm.open>.mm-list,.mm.hov>.mm-list{visibility:visible;opacity:1;transform:none;background-size:100% 2px;
  box-shadow:0 22px 50px rgba(0,0,0,.55),0 -10px 26px -16px rgba(255,176,32,.5);
  transition:opacity 0s,transform 0s,background-size .5s cubic-bezier(.16,1,.3,1) .05s,visibility 0s}
@media (hover:hover){
  .menu:not(.fly) .mm:hover>.mm-list{visibility:visible;opacity:1;transform:none;background-size:100% 2px;
    transition:opacity 0s,transform 0s,background-size .5s cubic-bezier(.16,1,.3,1) .05s,visibility 0s}
}
@media (prefers-reduced-motion:no-preference){
  .mm:is(.open,.hov)>.mm-list{animation:mm-drawer .44s cubic-bezier(.16,1,.3,1) backwards}
  .mm:is(.open,.hov)>.mm-list :is(.mm-i,.mm-h,.mm-sep){animation:mm-row .34s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--r,10)*17ms + 60ms)}
}
@keyframes mm-drawer{from{clip-path:inset(0 0 100% 0);transform:translateY(-4px)}to{clip-path:inset(-24px -48px -80px -48px);transform:none}}
@keyframes mm-row{from{opacity:0;transform:translateY(-6px)}}
/* links that leave the site: an arrow drawn in the same stroke */
.mm-x svg{width:10px;height:10px;display:inline-block;vertical-align:0;fill:none;stroke:currentColor;stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round}
/* one accent: the verified mark in amber, like every other mark on the site; the safety note's triangle says enough */
.mm-badge.mm-ok{color:var(--led);background:none;border-color:rgba(255,176,32,.45);box-shadow:none}
.mm-warn::after{content:none}

/* the carriage (wide screens with a pointer; site.js makes it and puts .glide on the bar): one lit surface under the
   entry being pointed at or focused, gliding from entry to entry; on the open entry it is a tab whose foot meets the
   drawer. Where it runs, the entries draw no boxes of their own, and the caret is the tab's right-hand part. */
.mm-glide{display:none}
@media (min-width:1041px){
  .mm-glide{display:block}
  .menu.glide{position:relative}
  .menu.glide>.mm,.menu.glide>.mm-plain{position:relative;z-index:1}
  .menu.glide .mm-top,.menu.glide .mm-car,.menu.glide .mm-plain{background:transparent!important;border-color:transparent!important}
  .menu.glide .mm-car{align-self:stretch;display:flex;align-items:center;margin-left:0;padding:0 7px}
  .menu.glide .mm:is(:hover,.open,.hov)>.mm-car{box-shadow:inset 1px 0 0 var(--rule-hi)}
  .mm-glide{position:absolute;left:0;top:0;z-index:0;width:var(--gw,0);height:var(--gh,0);pointer-events:none;
    transform:translate(var(--gx,0),var(--gy,0));opacity:0;border-radius:7px;
    background:linear-gradient(180deg,#1F2A31,#172027);box-shadow:inset 0 0 0 1px var(--rule-hi),inset 0 1px 0 rgba(255,255,255,.06),0 10px 24px -14px rgba(0,0,0,.7);
    transition:transform .36s cubic-bezier(.16,1,.3,1),width .36s cubic-bezier(.16,1,.3,1),opacity .18s ease,border-radius .2s ease}
  .mm-glide.on{opacity:1}
  .mm-glide.tab{border-radius:7px 7px 0 0}
}

/* a phone, a tablet, a narrow window (up to 1040 px): the bar is its icons in one row (the grid of S21, below, one
   cell per entry). Each entry's caret is its tile (the name beside it hides; the list's first line is the section's
   own page), About is a tile of its own, and each tile carries its bay's LED at its foot. While a list is open
   (site.js puts .lab on the bar) every name comes out under its icon, one after another, over the top edge of the
   open list, which keeps room for them: the page under the header never moves. The names share one size that keeps
   any two neighbours apart (fitLabs); Japanese and Chinese ones may take two lines. A tile the keyboard focuses
   shows its own name on a small plate. The names stay in the buttons' aria-label and in About's link either way. */
@media (max-width:1040px){
  .menu{margin-top:6px;align-items:start}
  .mm{min-width:0;justify-content:center}
  .mm-top{display:none}
  .mm-car,.menu .mm-plain{position:relative;flex:1 1 auto;min-width:0;min-height:44px;margin:0;padding:8px 2px 9px;gap:0;
    display:flex;flex-direction:column;align-items:center;justify-content:center;border-radius:10px}
  .mm-car>i{display:none}
  .mm-car .mm-tile{display:flex;flex-direction:column;align-items:center;min-width:0;width:100%}
  .mm-car .mm-ico,.menu .mm-plain .mm-ico{width:22px;height:22px}
  .mm.mm-in>.mm-car{color:var(--ink)}
  .mm-car::after{content:"";position:absolute;left:50%;bottom:3px;width:4px;height:4px;margin-left:-2px;border-radius:50%;
    background:rgba(255,255,255,.07);pointer-events:none;transition:background-color .2s ease,box-shadow .2s ease}
  .menu .mm-plain::after{bottom:3px}
  .mm.open>.mm-car::after,.mm.mm-in>.mm-car::after{background:var(--led);box-shadow:0 0 6px 1px rgba(255,176,32,.6),0 0 14px 2px rgba(255,176,32,.22)}
  .mm-lab{position:absolute;left:50%;top:calc(100% + var(--lab-top,14px));z-index:43;width:max-content;max-width:var(--lab-room,none);
    transform:translateX(-50%);pointer-events:none}
  .mm-lab>span{display:block;white-space:nowrap;text-align:center;font-family:var(--cond);font-weight:600;
    font-size:var(--lab-fs,11px);line-height:1.12;letter-spacing:0;color:var(--dim);
    opacity:0;transform:translateY(-6px);
    transition:opacity .12s ease,transform .16s ease}
  :lang(ja) .mm-lab>span,:lang(zh-TW) .mm-lab>span{white-space:normal;line-break:strict;text-wrap:balance}
  /* a Japanese or Chinese name stays within its own icon's width until fitLabs (site.js) gives it the room between its
     neighbours: centred on the last icon, "サイトについて" ran 1 px past a 320 px window and the page scrolled sideways */
  :lang(ja) .mm-lab,:lang(zh-TW) .mm-lab{max-width:var(--lab-room,100%)}
  .mm.open>.mm-car .mm-lab>span{color:var(--led)}
  /* opacity and a slide only: a blur going out on these names, one after another, crashed WebKit's page (2026-11-03) */
  .menu.lab .mm-lab>span{opacity:1;transform:none;
    transition:opacity .34s cubic-bezier(.16,1,.3,1) calc(var(--i,0)*38ms + 80ms),
      transform .46s cubic-bezier(.16,1,.3,1) calc(var(--i,0)*38ms + 80ms)}
  .menu.lab .mm-list{padding-top:calc(var(--lab-h,16px) + 18px)}
  /* the keyboard on a tile with no list open: its own name on a plate under it */
  .menu:not(.lab) :is(.mm-car,.mm-plain):focus-visible .mm-lab>span{opacity:1;transform:none;
    background:var(--rack);border:1px solid var(--rule-hi);border-radius:999px;padding:3px 9px;color:var(--ink);
    box-shadow:0 8px 20px rgba(0,0,0,.5)}
}

/* About on a narrow phone (site decision S73, the owner: "if it does not fit, do not show it"): with WebPortico the bar has
   seven tiles, and below 429 px their names can no longer keep fitLabs's 6 px apart at its 9 px floor (measured in
   Chromium and WebKit, all ten languages, Dutch's "Ontwikkelaars" the widest: 8.99 px at 428 px, 9.02 at 429). There
   About leaves the bar; the footer and the sitemap link it. */
@media (max-width:428px){.menu .mm-plain.mm-about{display:none}}

/* ── side menus (2026-10-12, the owner: the lists grew too long to read in one drop) ─────────────────────
   tools/node/site-menu.mjs wraps each heading and its items in .mm-g (.mm-h the heading, .mm-gl the items); in a list
   of more than 20 lines every group also carries .mm-fly. site.js puts .fly on the menu where a fine pointer can hover and the
   window is wider than 1040 px. There each .mm-fly heading is a button, a row with a chevron, and its items a side
   menu beside it: fixed in place by site.js (so the list's own scroll cannot clip it), flipped to the left where the
   right edge is near, and scrolling inside itself when taller than the window. Without .fly (touch, a phone, no
   script) a group reads as before: a heading over its items. */
.menu.fly .mm-fly{margin-top:6px;padding-top:6px;border-top:1px solid var(--rule)}
.menu.fly .mm-fly+.mm-fly,.menu.fly .mm-list>.mm-fly:first-child{margin-top:0;padding-top:0;border-top:0}
.menu.fly .mm-fly>.mm-h{
  display:flex;align-items:center;gap:10px;width:100%;margin:0;padding:8px 11px 8px 39px;
  border:0;border-radius:6px;background:none;color:var(--ink);cursor:pointer;text-align:left;
  font-family:var(--sans);font-size:14px;font-weight:500;letter-spacing:0;text-transform:none;line-height:1.3;
  transition:color .15s ease,background-color .15s ease;
}
.menu.fly .mm-fly>.mm-h:hover,.menu.fly .mm-fly.on>.mm-h{background:var(--panel-2);color:var(--led)}
.mm-chev{flex:none;width:12px;height:12px;margin-left:auto;opacity:.75;transition:transform .2s var(--ease-seat)}
.menu.fly .mm-fly.on>.mm-h .mm-chev{opacity:1;transform:translateX(2px)}
.menu.fly .mm-fly>.mm-gl{
  display:none;position:fixed;left:0;top:0;margin:0;z-index:1;
  width:max-content;min-width:250px;max-width:min(420px,calc(100vw - 16px));
  overflow-y:auto;overscroll-behavior:contain;
  background:var(--rack);border:1px solid var(--rule);border-top-color:var(--rule-hi);border-radius:9px;
  box-shadow:0 22px 50px rgba(0,0,0,.55);padding:6px;
}
.menu.fly .mm-fly.on>.mm-gl{display:block}
.menu.fly .mm-fly.in>.mm-gl{animation:mm-fly-in .18s var(--ease-seat) both}
@keyframes mm-fly-in{from{opacity:0;transform:translateX(var(--mm-fx,-6px))}}

/* App Center's hosting categories link their How-to and the How-to list in the heading row; on a phone the row wraps */
.ac-pane .eyebrow{flex-wrap:wrap;row-gap:6px}
.eyebrow .ey-how{font-family:var(--mono);font-size:12px;color:var(--led);text-decoration:none;white-space:nowrap}
.eyebrow .ey-how:hover{text-decoration:underline;text-underline-offset:3px}

/* ── the dialogs the menu opens: the safety note, the MyQNAP repository, the team sign-in ──────────── */
.sf-hd{display:flex;align-items:center;gap:10px;margin:0 0 12px}
.sf-hd .cap{margin:0}
.sf-legal{border-top:1px solid var(--rule);margin-top:18px;padding-top:4px;font-size:14px;color:var(--dim)}
.sf-legal p{font-size:14px;color:var(--dim)}
.sf-legal b{color:var(--ink)}
dialog .sf-legal h4{margin-top:18px}
.sf-sign{font-family:var(--mono);font-size:12.5px;line-height:1.7;color:var(--dim)}
.mq-steps{list-style:none;padding:0;margin:0 0 14px;counter-reset:mq}
.mq-steps li{counter-increment:mq;margin:0 0 16px;padding-left:34px;position:relative}
.mq-steps li::before{
  content:counter(mq);position:absolute;left:0;top:0;width:24px;height:24px;border-radius:50%;
  display:grid;place-items:center;font-family:var(--mono);font-size:12px;font-weight:600;
  background:var(--led);color:var(--rack);
}
.mq-steps img{display:block;width:100%;height:auto;margin-top:8px;border:1px solid var(--rule);border-radius:4px;background:#fff}
.mq-kv{display:grid;grid-template-columns:auto 1fr auto;gap:6px 10px;align-items:center;margin:8px 0 4px;font-size:14px}
.mq-kv code{font-size:13px;word-break:break-all}
.mq-kv button{
  background:none;border:1px solid var(--rule-hi);color:var(--dim);border-radius:2px;cursor:pointer;
  font-family:var(--mono);font-size:11px;padding:3px 8px;
}
.mq-kv button:hover,.mq-kv button.done{border-color:var(--led);color:var(--led)}
.tm-form{display:grid;gap:10px;max-width:360px;margin:6px 0 10px}
.tm-form label{display:grid;gap:4px;font-size:13.5px;color:var(--dim)}
.tm-form input{
  font:inherit;font-size:15px;color:var(--ink);background:var(--rack);border:1px solid var(--rule-hi);
  border-radius:3px;padding:8px 10px;
}
.tm-form input:focus{outline:2px solid var(--led);outline-offset:1px}
.tm-form button{
  justify-self:start;font-family:var(--cond);font-weight:600;font-size:14.5px;cursor:pointer;
  color:var(--rack);background:var(--led);border:1px solid var(--led);border-radius:3px;padding:7px 16px;
}
.tm-msg{min-height:1.4em;font-size:13.5px;color:var(--led)}

/* ── the donate band ──────────────────────────────────────────────────────
   One project pays for the rest of the time: it is named, and the amounts are
   real Stripe links rather than a mailto. */
.give-band{background:var(--panel);border-block:1px solid var(--rule);padding:clamp(34px,5vw,60px) 0;margin-top:clamp(40px,6vw,80px)}
.give-grid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:clamp(24px,4vw,56px);align-items:start}
@media (max-width:900px){.give-grid{grid-template-columns:1fr}}
.give-grid h2{font-family:var(--cond);font-weight:700;font-size:clamp(24px,3.2vw,34px);margin:0 0 12px;color:var(--ink)}
.give-grid p{margin:0 0 12px;font-size:15.5px;line-height:1.6;color:var(--dim)}
.give-grid p b{color:var(--ink)}
.give-list{list-style:none;margin:0 0 14px;padding:0;display:grid;gap:9px}
.give-list li{position:relative;padding-left:22px;font-size:15px;line-height:1.55;color:var(--dim)}
.give-list li::before{content:"";position:absolute;left:2px;top:.62em;width:8px;height:8px;border-radius:50%;background:var(--led)}
.give-list b{color:var(--ink);font-weight:600}
.amounts{display:grid;grid-template-columns:repeat(auto-fit,minmax(104px,1fr));gap:8px;margin:14px 0 10px}
/* display:grid beats the browser's own [hidden] rule, so the switched-off currency stayed on screen */
.amounts[hidden]{display:none}
.amounts a{
  display:flex;flex-direction:column;gap:2px;text-decoration:none;text-align:center;
  background:var(--panel-2);border:1px solid var(--rule);border-radius:3px;padding:12px 8px 10px;color:var(--ink);
  font-family:var(--cond);font-weight:700;font-size:19px;transition:border-color .15s ease,background-color .15s ease}
.amounts a small{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--dim);font-weight:400}
.amounts a:hover{border-color:var(--led);background:var(--led-soft)}
.amounts a.lead{border-color:rgba(255,176,32,.45)}
.cur{display:flex;gap:6px;margin-bottom:2px}
.cur button{
  font-family:var(--mono);font-size:11px;letter-spacing:.08em;background:transparent;color:var(--dim);
  border:1px solid var(--rule);border-radius:3px;padding:5px 10px;cursor:pointer}
.cur button[aria-pressed="true"]{color:var(--rack);background:var(--led);border-color:var(--led);font-weight:600}

/* ── what's new ───────────────────────────────────────────────────────── */
.news{display:grid;gap:10px;margin-top:20px}
.news li{display:flex;gap:14px;align-items:baseline;font-size:14.5px;color:var(--dim);line-height:1.55;list-style:none}
.news .when{font-family:var(--mono);font-size:11px;letter-spacing:.06em;color:var(--led);flex:0 0 76px;text-transform:uppercase}
.news b{color:var(--ink);font-weight:600}

/* ═══════════════════════════════════════════════════════════════════════════
   THE SHOWCASE  ·  StorageDiag Workbench & Utilities, six instruments
   ---------------------------------------------------------------------------
   Same hardware palette as the rest of the page — dim rack metal, one amber
   LED. What changes here is DEPTH: every panel is a machined enclosure (an
   outer tray with a hairline lip, an inner plate seated inside it on its own
   highlight), the section breathes at twice the usual rhythm, and nothing
   arrives statically — cards rise into place on one shared easing curve.
   Motion is transform/opacity only, and it is dropped whole under
   prefers-reduced-motion; the content never depends on it.
   ═══════════════════════════════════════════════════════════════════════════ */
/* Every in-page anchor (#new, #start, #tools, #more, #watch/…) landed underneath
   the sticky masthead. scroll-padding on the scroll container fixes all of them: 16 px
   below the header's real height (--mast, measured by site.js; the menu takes a second
   line between 721 and 900 px in the longer languages). */
html{scroll-padding-top:calc(var(--mast,66px) + 16px)}
/* on a phone the header tucks away while the page scrolls down and comes back on the way up (site.js), so an
   in-page link lands just under the top edge instead of under a header that is about to leave */
@media (max-width:720px){
  html{scroll-padding-top:16px}
  .mast{transition:transform .35s cubic-bezier(.32,.72,0,1)}
  .mast.tuck{transform:translateY(calc(-100% - 1px))}
}
@media (max-width:720px) and (prefers-reduced-motion:reduce){.mast{transition:none}}

/* ── section shell ───────────────────────────────────────────────────────── */
.sd{
  padding-block:clamp(40px,4.6vw,74px) clamp(56px,7vw,110px);
  border-bottom:1px solid var(--rule);
  position:relative;
  /* A single soft panel light above the rack — no mesh, no orbs, no second hue. */
  background:
    radial-gradient(120% 62% at 50% -8%, rgba(255,176,32,.055), transparent 62%),
    radial-gradient(80% 40% at 88% 4%, rgba(255,255,255,.022), transparent 70%);
}
/* The amber pill labels the product the hero's standfirst already describes, so it
   lives in the hero now. The showcase itself uses the page's own .eyebrow label —
   one headline per page, and the section reads as native rather than bolted on. */
.sd-brow{
  display:inline-flex;align-items:center;gap:9px;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--led);background:var(--led-soft);
  border:1px solid rgba(255,176,32,.34);border-radius:999px;
  padding:5px 12px 4px;margin:0 0 18px;width:max-content;max-width:100%;
}
.sd-brow i{
  width:5px;height:5px;border-radius:50%;background:var(--led);flex:0 0 auto;
  box-shadow:0 0 0 3px rgba(255,176,32,.18);
}
/* The brow names the product and the edition; "free forever" is a CLAIM, so it gets a
   chip of its own beside it. This is the one deliberately decorative element on the
   page: a colour runs around its border (@property on the gradient's angle), the word
   carries a gloss sweep, and the LED blinks. The .tag.free chip down in the tools grid
   is untouched - there lime MEANS free and must not compete with this. Everything here
   is animation only, so the page's prefers-reduced-motion block stops all of it and
   leaves a legible chip. */
.sd-browrow{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 18px}
.sd-browrow .sd-brow{margin:0}
@property --ff-ang{syntax:'<angle>';inherits:false;initial-value:0deg}
.sd-ff{
  position:relative;display:inline-flex;align-items:center;gap:6px;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink);padding:5px 13px 4px;border-radius:999px;
  border:2px solid transparent;
  /* two boxes in one background: the ground paints inside the border, the moving
     colour paints ON it. A browser without @property still gets the full ring - it
     simply does not turn. */
  background:
    linear-gradient(var(--rack),var(--rack)) padding-box,
    conic-gradient(from var(--ff-ang),
      var(--lime) 0deg, #7CF6D0 60deg, #8FB8FF 130deg, var(--pink) 200deg,
      var(--led) 270deg, var(--lime) 360deg) border-box;
  /* The halo cycles WITH the ring. Colour inside a keyframe interpolates in every
     browser, so this half of the effect does not depend on @property. */
  animation:ff-spin 4.5s linear infinite, ff-halo 4.5s linear infinite;
  white-space:nowrap;
}
.sd-ff b{
  font-weight:600;
  background:linear-gradient(100deg,var(--lime) 0%,#FFFFFF 42%,var(--led) 58%,var(--lime) 100%);
  background-size:280% 100%;
  -webkit-background-clip:text;background-clip:text;color:transparent;
  animation:ff-sheen 3.2s ease-in-out infinite;
}
.sd-ff i{
  width:5px;height:5px;border-radius:50%;background:var(--lime);flex:0 0 auto;
  box-shadow:0 0 7px rgba(166,226,46,.9);animation:ff-blink 1.7s steps(1,end) infinite;
}
@keyframes ff-spin{to{--ff-ang:360deg}}
@keyframes ff-sheen{0%{background-position:120% 0}100%{background-position:-60% 0}}
@keyframes ff-blink{0%,62%{opacity:1}63%,100%{opacity:.22}}
@keyframes ff-halo{
    0%{box-shadow:0 0 0 1px rgba(0,0,0,.45), 0 1px 20px rgba(166,226,46,.34)}
   25%{box-shadow:0 0 0 1px rgba(0,0,0,.45), 0 1px 20px rgba(124,246,208,.34)}
   50%{box-shadow:0 0 0 1px rgba(0,0,0,.45), 0 1px 22px rgba(232,70,140,.34)}
   75%{box-shadow:0 0 0 1px rgba(0,0,0,.45), 0 1px 22px rgba(255,176,32,.36)}
  100%{box-shadow:0 0 0 1px rgba(0,0,0,.45), 0 1px 20px rgba(166,226,46,.34)}
}
.hero-l{min-width:0}

/* ── the bento ───────────────────────────────────────────────────────────── */
.sd-grid{
  display:grid;grid-template-columns:1fr;gap:clamp(14px,1.5vw,22px);
  margin-top:clamp(32px,4vw,60px);
}
@media (min-width:820px){
  .sd-grid{grid-template-columns:repeat(6,1fr)}
  .mod{grid-column:span 3}
  .mod.wide{grid-column:span 6}
  .mod.two3{grid-column:span 4}
  .mod.third{grid-column:span 2}
}

/* ── the enclosure: outer tray + inner plate, concentric ─────────────────── */
.mod{
  position:relative;display:block;width:100%;text-align:left;
  padding:var(--lip);
  border-radius:var(--tray);
  border:1px solid var(--rule);
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.012) 42%,transparent);
  box-shadow:0 1px 0 rgba(255,255,255,.045) inset, 0 18px 44px -30px rgba(0,0,0,.9);
  transition:border-color .5s var(--ease-seat), transform .5s var(--ease-seat), box-shadow .5s var(--ease-seat);
  color:inherit;text-decoration:none;
  -webkit-tap-highlight-color:transparent;
}
.mod:hover,.mod:focus-within{
  border-color:var(--rule-hi);
  transform:translateY(-2px);
  box-shadow:0 1px 0 rgba(255,255,255,.07) inset, 0 28px 56px -30px rgba(0,0,0,.95);
}
.mod:active{transform:translateY(-1px) scale(.997)}
.mod-core{
  border-radius:calc(var(--tray) - var(--lip));
  background:var(--panel);
  border:1px solid var(--rule);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.055);
  overflow:hidden;
  display:flex;flex-direction:column;height:100%;
}

/* ── the shot ────────────────────────────────────────────────────────────── */
.mod figure{margin:0;position:relative;background:var(--rack);overflow:hidden}
.mod figure::after{                      /* seats the image into the plate     */
  content:"";position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 -1px 0 var(--rule), inset 0 0 40px -18px rgba(0,0,0,.85);
}
.mod img{
  display:block;width:100%;height:auto;
  transition:transform .8s var(--ease-seat);
  transform-origin:50% 0;
}
.mod-main:hover img{transform:scale(1.018)}

/* A card carries a SET of screenshots rather than one still. The FIRST image stays in
   flow so it keeps sizing the plate (the grid must not jump when the set advances);
   every other image is stacked over it and cross-faded. Same 1400×780 for all of them,
   so nothing shifts. */
.mod figure.shots img{
  position:absolute;inset:0;width:100%;height:100%;opacity:0;
  transition:opacity .75s var(--ease-seat), transform .8s var(--ease-seat);
}
.mod figure.shots img:first-child{position:relative;inset:auto;height:auto}
.mod figure.shots img.on{opacity:1}
.shot-dots{
  position:absolute;right:12px;bottom:11px;z-index:2;
  display:flex;gap:5px;padding:5px 7px;border-radius:99px;
  background:rgba(8,11,14,.55);backdrop-filter:blur(3px);
}
.shot-dots i{
  width:5px;height:5px;border-radius:50%;background:var(--ink);opacity:.3;
  transition:opacity .3s, background-color .3s;
}
.shot-dots i.on{opacity:1;background:var(--led)}
@media (prefers-reduced-motion:reduce){
  .mod figure.shots img{transition:none}
}

/* ── the plate text ──────────────────────────────────────────────────────── */
/* The plate splits in two: everything above the pills is ONE link to the
   product page, the pills below are links of their own. A card cannot be a
   single <a> any more — "See it running" and "Download" go somewhere else.
   Same shape as .film (wrapper / .fmain / .fshare) further up this sheet. */
.mod-main{
  display:flex;flex-direction:column;flex:1;min-width:0;
  color:inherit;text-decoration:none;
}
/* The card used to BE the link, so its focus ring sat on the tray. The link is
   .mod-main now, which fills .mod-core{overflow:hidden} to the pixel — a ring at
   the global +3px offset is drawn outside that box and clipped away entirely.
   Tabbing through the showcase landed on six cards with no visible focus at all.
   Negative offset draws it inside the plate, where nothing can cut it off. */
.mod-main:focus-visible{outline-offset:-3px;border-radius:calc(var(--tray) - var(--lip))}
.mod-txt{padding:clamp(16px,1.6vw,24px) clamp(16px,1.6vw,24px) 0;display:flex;flex-direction:column;gap:9px;flex:1;min-width:0}
.mod-nm{
  font-family:var(--cond);font-weight:700;font-size:clamp(17px,1.5vw,21px);
  letter-spacing:.005em;color:var(--ink);margin:0;
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
}
.mod-nm small{
  font-family:var(--mono);font-size:10px;letter-spacing:.15em;text-transform:uppercase;
  color:var(--dim);font-weight:400;
}
.mod-hook{
  font-family:var(--cond);font-weight:600;font-size:clamp(15px,1.35vw,18px);
  line-height:1.3;color:var(--led);margin:0;text-wrap:balance;
}
.mod-ds{margin:0;color:var(--dim);font-size:14.5px;line-height:1.58;min-width:0;text-wrap:pretty}
.mod-ds b{color:var(--ink);font-weight:500}
/* Key capabilities: three short lines under the description. Spans, not a <ul> — .mod-txt
   sits inside the card's <a>, and a list inside a span is not valid HTML. */
.mod-caps{display:flex;flex-direction:column;gap:3px;margin:2px 0 0;min-width:0}
.mod-caps-h{font-family:var(--mono);font-size:10px;letter-spacing:.15em;text-transform:uppercase;color:var(--dim);margin-bottom:2px}
.mod-caps .cap{position:relative;display:block;margin:0;padding:0 0 0 15px;color:var(--dim);font-size:13.5px;line-height:1.5;text-wrap:pretty}
.mod-caps .cap::before{content:"";position:absolute;left:1px;top:.6em;width:5px;height:5px;border-radius:50%;background:var(--led)}
.mod-foot{
  padding:14px clamp(16px,1.6vw,24px) clamp(16px,1.6vw,24px);
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
}

/* ── island link: the arrow lives in its own well ────────────────────────── */
.isl{
  display:inline-flex;align-items:center;gap:10px;
  font-family:var(--cond);font-weight:600;font-size:14px;letter-spacing:.01em;
  color:var(--ink);text-decoration:none;
  background:rgba(255,255,255,.045);border:1px solid var(--rule-hi);
  border-radius:999px;padding:6px 6px 6px 16px;
  transition:background-color .45s var(--ease-seat), border-color .45s var(--ease-seat), color .45s var(--ease-seat);
}
.isl .wl{
  width:26px;height:26px;border-radius:50%;flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.07);
  transition:transform .45s var(--ease-seat), background-color .45s var(--ease-seat);
}
.isl svg{width:13px;height:13px;display:block}
.isl:hover,.isl:focus-visible{background:var(--led-soft);border-color:rgba(255,176,32,.5);color:var(--led)}
.isl:hover .wl,.isl:focus-visible .wl{transform:translate(2px,-1px) scale(1.06);background:rgba(255,176,32,.2)}
/* Download is the one action on this page that ends in a file, so it carries the
   accent standing still. Amber stays the only accent. */
.isl-dl{background:var(--led-soft);border-color:rgba(255,176,32,.42);color:var(--led)}
.isl-dl .wl{background:rgba(255,176,32,.18)}

/* ── download rail ───────────────────────────────────────────────────────── */
.sd-get{
  margin-top:clamp(30px,3.6vw,52px);
  padding:var(--lip);border-radius:var(--tray);
  border:1px solid var(--rule);
  background:linear-gradient(180deg,rgba(255,176,32,.07),rgba(255,255,255,.012) 40%,transparent);
  box-shadow:0 1px 0 rgba(255,255,255,.05) inset;
}
.sd-get-core{
  border-radius:calc(var(--tray) - var(--lip));
  background:var(--panel);border:1px solid var(--rule);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.055);
  padding:clamp(20px,2.4vw,34px);
}
.sd-get h3{
  font-family:var(--cond);font-weight:700;font-size:clamp(19px,2vw,26px);
  margin:0 0 6px;letter-spacing:-.005em;
}
.sd-get .why{margin:0 0 20px;color:var(--dim);font-size:14.5px;line-height:1.6}
.sd-get .why code{
  font-family:var(--mono);font-size:12.5px;background:rgba(255,255,255,.05);
  border:1px solid var(--rule);border-radius:3px;padding:1px 5px;color:var(--ink);
}
.arch{display:grid;gap:10px;grid-template-columns:1fr}
@media (min-width:720px){.arch{grid-template-columns:repeat(3,1fr)}}
.arch a{
  display:flex;flex-direction:column;gap:3px;text-decoration:none;
  padding:13px 15px;border-radius:9px;
  background:var(--panel-2);border:1px solid var(--rule);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04);
  transition:border-color .4s var(--ease-seat), background-color .4s var(--ease-seat), transform .4s var(--ease-seat);
}
.arch a:hover,.arch a:focus-visible{border-color:var(--led);background:var(--led-soft);transform:translateY(-1px)}
.arch b{font-family:var(--cond);font-weight:700;font-size:15px;color:var(--ink);letter-spacing:.01em}
.arch small{color:var(--dim);font-size:12px;font-variant-numeric:tabular-nums}
.sd-get .also{
  margin:16px 0 0;color:var(--dim);font-size:13px;line-height:1.6;
  display:flex;flex-wrap:wrap;gap:6px 18px;align-items:baseline;
}
.sd-get .also a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--rule-hi)}
.sd-get .also a:hover,.sd-get .also a:focus-visible{color:var(--led);border-bottom-color:var(--led)}

/* ── scroll entry: one curve, staggered, opt-out honoured ────────────────── */
.rv{opacity:0;transform:translateY(22px)}
.rv.in{opacity:1;transform:none;transition:opacity .75s var(--ease-seat),transform .75s var(--ease-seat)}
@media (prefers-reduced-motion:reduce){
  .rv,.rv.in{opacity:1;transform:none;transition:none}
  .mod,.mod img,.isl,.isl .wl,.arch a{transition:none}
  .mod:hover{transform:none}
  .mod-main:hover img{transform:none}
}
/* No JS, no observer, no risk: content is never left hidden. A failsafe timer in
   the script reveals everything after 1.2 s even if IntersectionObserver never fires. */
@media (scripting: none){ .rv{opacity:1;transform:none} }

/* ═══════════════════════════════════════════════════════════════════════════
   THE SAME ENCLOSURE, EVERYWHERE  ·  walkthrough cards and tool cards
   ---------------------------------------------------------------------------
   The showcase cards read as machined panels; these did not, so the page looked
   like two designs stacked. Same tray-and-plate construction, same easing, no
   markup changes — which matters, because the walkthrough cards are wired to
   the player (films[slug], .fmain, .fshare) and the tool cards to the dialogs
   (data-dlg), and neither may be re-nested.

   .film already contains .fmain (the anchor holding the still and the caption),
   so .film becomes the tray and .fmain the plate. .tool has no single inner
   wrapper, so its plate is a ::before painted at z-index:-1 under isolation.

   🔴 Badge colours are deliberately untouched: .tag.free (lime), .tag.gate
   (orange), .tag.hot (pink) and the plain .tag carry meaning, not decoration.
   Only their POSITION moves, inward by the tray wall, so they sit on the plate
   instead of straddling the rim.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── walkthrough cards ───────────────────────────────────────────────────── */
.film{
  padding:var(--lip);
  border-radius:var(--tray);
  border:1px solid var(--rule);
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.012) 42%,transparent);
  box-shadow:0 1px 0 rgba(255,255,255,.045) inset, 0 18px 44px -30px rgba(0,0,0,.9);
  overflow:visible;                       /* the plate clips now, not the tray */
  transition:border-color .5s var(--ease-seat), transform .5s var(--ease-seat), box-shadow .5s var(--ease-seat);
}
.film:hover{
  border-color:var(--rule-hi);
  transform:translateY(-2px);
  box-shadow:0 1px 0 rgba(255,255,255,.07) inset, 0 28px 56px -30px rgba(0,0,0,.95);
}
.film:focus-within{border-color:var(--led)}
.film .fmain{
  border-radius:calc(var(--tray) - var(--lip));
  background:var(--panel);
  border:1px solid var(--rule);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.055);
  overflow:hidden;
  display:flex;flex-direction:column;flex:1;min-width:0;
}
/* the still sits flush in the plate's top corners */
.film .frame{border-radius:calc(var(--tray) - var(--lip) - 1px) calc(var(--tray) - var(--lip) - 1px) 0 0;overflow:hidden}
/* share button and duration ride inside the plate, not on the rim */
.film .fshare{top:calc(var(--lip) + 6px);right:calc(var(--lip) + 6px)}

/* ── tool cards ──────────────────────────────────────────────────────────── */
.tool{
  position:relative;
  /* isolate + a negative-z plate keeps the card the positioning context. Giving the
     children position:relative instead made the inner <span> the containing block,
     and .tags (absolute, top/right) jumped from the card corner onto the title. */
  isolation:isolate;
  border-radius:var(--tray);
  border:1px solid var(--rule);
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.012) 42%,transparent);
  box-shadow:0 1px 0 rgba(255,255,255,.045) inset, 0 18px 44px -30px rgba(0,0,0,.9);
  padding:calc(30px + var(--lip)) calc(20px + var(--lip)) calc(19px + var(--lip));
  transition:border-color .5s var(--ease-seat), transform .5s var(--ease-seat), box-shadow .5s var(--ease-seat);
}
.tool::before{                             /* the inner plate */
  content:"";position:absolute;inset:var(--lip);
  border-radius:calc(var(--tray) - var(--lip));
  background:var(--panel);
  border:1px solid var(--rule);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.055);
  transition:background-color .5s var(--ease-seat);
  z-index:-1;
}
.tool:hover,.tool:focus-visible{
  background:linear-gradient(180deg,rgba(255,255,255,.07),rgba(255,255,255,.018) 42%,transparent);
  border-color:var(--rule-hi);
  transform:translateY(-2px);
  box-shadow:0 1px 0 rgba(255,255,255,.07) inset, 0 28px 56px -30px rgba(0,0,0,.95);
}
.tool:hover::before{background:var(--panel-2)}
.tool:active{transform:translateY(-1px) scale(.997)}
/* the lead tile stays the lit one */
.tool.lead{background:linear-gradient(180deg,rgba(255,176,32,.09),rgba(255,255,255,.015) 40%,transparent);border-color:var(--rule-hi)}
.tool.lead::before{background:var(--panel-2)}

/* Badges keep every colour they had; they only move in off the rim so they sit
   on the plate, and the outer corner follows the plate's radius. */
.tool .tags{top:var(--lip);right:var(--lip);border-top-right-radius:calc(var(--tray) - var(--lip));overflow:hidden}
.film .tags{top:var(--lip);right:var(--lip);border-top-right-radius:calc(var(--tray) - var(--lip));overflow:hidden}

@media (prefers-reduced-motion:reduce){
  .film,.tool,.tool::before{transition:none}
  .film:hover,.tool:hover{transform:none}
}


/* ─────────────────────────────────────────────────────────────────────────
   The hero reel. A muted loop of the app actually running, directly under the
   creed it illustrates. It is the SHORT cut (act openers only) because the
   hero autoplays it on every visit; the full reel is behind the click, in the
   same dialog the walkthroughs use.
   ───────────────────────────────────────────────────────────────────────── */
.reel{margin-top:clamp(22px,3vw,40px)}
.reel .reel-film{position:relative;isolation:isolate}
.reel .fmain{display:block;position:relative;border-radius:calc(var(--tray) - var(--lip));
  overflow:hidden;background:#07090B;border:1px solid var(--rule);
  transition:border-color .2s var(--ease-seat),transform .2s var(--ease-seat)}
.reel .fmain:hover{border-color:var(--rule-hi)}
.reel .fmain:focus-visible{outline:2px solid var(--led);outline-offset:-3px}
.reel .reel-v{display:block;width:100%;aspect-ratio:16/9;object-fit:cover;background:#07090B}
/* The call to action sits ON the picture, bottom-right, over its own scrim. */
.reel .reel-cta{position:absolute;right:14px;bottom:13px;display:flex;align-items:center;gap:8px;
  font-family:var(--mono);font-size:12px;letter-spacing:.08em;color:var(--ink);
  background:rgba(8,11,13,.78);border:1px solid var(--rule-hi);border-radius:8px;
  padding:7px 11px;backdrop-filter:blur(3px)}
.reel .fmain:hover .reel-cta{border-color:var(--led);color:var(--led)}
.reel .reel-cta i{font-style:normal;color:var(--led);font-size:10px}
.reel .reel-cap{margin:10px 2px 0;font-family:var(--mono);font-size:11.5px;color:var(--dim)}
/* Motion is the whole point of this block, so when motion is refused the poster
   is what remains — not a frozen first frame of a video element that still
   downloaded. The markup ships `preload="none"`; this stops the loop as well. */
@media (prefers-reduced-motion:reduce){
  .reel .reel-v{animation:none}
}
@media (max-width:700px){
  .reel .reel-cta{right:9px;bottom:9px;font-size:11px;padding:6px 9px}
}


/* ═══════════════════════════════════════════════════════════════════════════
   2026-09-20: the site became four pages sharing this one stylesheet.
   Everything above is the front page's stylesheet as it was; everything below
   is what the new shape added: the masthead's home link, the App Center
   window (appcenter.html), the download steps (download.html), the about page,
   and the front page's tail (the price list, why it is free, the FAQ, the big
   download line) with its scroll storytelling.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── masthead: the mark and the wordmark are one link home ─────────────── */
.mast .home{display:flex;align-items:center;gap:14px;text-decoration:none;color:inherit;border-radius:3px}
.mast .home .brand{margin:0}
.mast .home:hover .brand{color:var(--led)}
.menu>a.on{color:var(--ink);border-color:var(--rule)}
.menu>a small{font-family:var(--mono);font-size:10px;font-weight:400;letter-spacing:.06em;color:var(--dim);margin-left:5px;opacity:.85}
.menu>a:hover small{color:inherit}
/* a phone: the menu takes a line of its own under the wordmark instead of scrolling sideways under it */
@media (max-width:1040px){.mast .wrap{flex-wrap:wrap;row-gap:4px}.mast .home{flex:1}}

/* ── the price list ──────────────────────────────────────────────────────── */
.pitch{padding-top:clamp(40px,7vw,110px)}
.pitch .big{
  font-family:var(--cond);font-weight:700;line-height:1.02;letter-spacing:-.015em;
  font-size:clamp(34px,6.4vw,92px);margin:0 0 18px;max-width:9.72em;color:var(--ink);text-wrap:balance;
}
.pitch .big em{font-style:normal;color:var(--led)}
.pitch .lede-p{color:var(--dim);font-size:clamp(15px,1.4vw,19px);margin:0 0 clamp(28px,4vw,54px);line-height:1.6}
.plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(320px,100%),1fr));gap:clamp(16px,2.2vw,28px);align-items:stretch}
.plan{
  padding:var(--lip);border-radius:var(--tray);border:1px solid var(--rule);
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.012) 42%,transparent);
  box-shadow:0 1px 0 rgba(255,255,255,.045) inset, 0 18px 44px -30px rgba(0,0,0,.9);
  display:flex;
}
.plan-core{
  flex:1;border-radius:calc(var(--tray) - var(--lip));background:var(--panel);border:1px solid var(--rule);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.055);padding:clamp(22px,3vw,36px);display:flex;flex-direction:column;gap:16px;
}
.plan.hot{border-color:rgba(255,176,32,.42);background:linear-gradient(180deg,rgba(255,176,32,.12),rgba(255,255,255,.015) 40%,transparent)}
.plan.hot .plan-core{background:var(--panel-2);border-color:rgba(255,176,32,.25)}
.plan .pn{font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--dim);margin:0}
.plan.hot .pn{color:var(--led)}
.plan .pt{font-family:var(--cond);font-weight:700;font-size:clamp(22px,2.4vw,30px);margin:0;color:var(--ink);line-height:1.15}
.plan .pp{font-family:var(--cond);font-weight:700;font-size:clamp(44px,5vw,72px);line-height:1;margin:6px 0 2px;color:var(--ink);letter-spacing:-.02em}
.plan .pp small{font-family:var(--mono);font-size:12px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;color:var(--dim);margin-left:8px}
.plan.hot .pp{color:var(--led)}
.plan ul{list-style:none;margin:6px 0 0;padding:0;display:grid;gap:9px}
.plan li{font-size:14.5px;color:var(--dim);display:flex;gap:10px;align-items:baseline;line-height:1.45}
.plan li::before{content:"";flex:0 0 5px;height:5px;background:var(--rule-hi);border-radius:1px;position:relative;top:-2px}
.plan.hot li::before{background:var(--lime)}
.plan li b{color:var(--ink);font-weight:600}
.plan .pf{margin-top:auto;padding-top:10px}
.isl.xl{font-size:16px;padding:10px 10px 10px 22px}
.isl.xl .wl{width:32px;height:32px}
.isl.xl svg{width:15px;height:15px}
.isl.mute{color:var(--dim)}

/* ── why it is free ──────────────────────────────────────────────────────── */
.why-free{margin-top:clamp(44px,6vw,90px)}
/* the essay spans the section like the plans above it and the FAQ below; on a wide screen it runs in two columns
   with the plans' gap, so each column lines up with a plan card and a line stays readable; a paragraph stays whole */
@media (min-width:1100px){
  .why-free .txt{columns:2;column-gap:clamp(16px,2.2vw,28px)}
  .why-free .txt p.q,.why-free .txt .facts{column-span:all}
  .why-free .txt p{break-inside:avoid}
}
.why-free .txt p{margin:0 0 16px;font-size:clamp(15px,1.25vw,17.5px);line-height:1.65;color:var(--dim)}
.why-free .txt p b{color:var(--ink);font-weight:600}
.why-free .txt p.q{
  font-family:var(--cond);font-weight:600;font-size:clamp(17px,1.5vw,21px);color:var(--ink);
  border-left:3px solid var(--led);padding-left:16px;margin:22px 0;
}
.facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(200px,100%),1fr));gap:12px;margin:22px 0 4px}
.fact{
  border:1px solid var(--rule);border-radius:calc(var(--tray) - var(--lip));background:var(--panel);
  padding:14px 16px;box-shadow:inset 0 1px 0 rgba(255,255,255,.055);
}
.fact b{display:block;font-family:var(--cond);font-weight:700;font-size:26px;color:var(--led);line-height:1;margin-bottom:6px;letter-spacing:-.01em}
.fact span{font-size:13px;color:var(--dim);line-height:1.45;display:block}

/* ── the FAQ ─────────────────────────────────────────────────────────────── */
.faq{margin-top:clamp(44px,6vw,90px)}
.faq details{
  border-top:1px solid var(--rule);padding:0;
}
.faq details:last-of-type{border-bottom:1px solid var(--rule)}
.faq summary{
  cursor:pointer;list-style:none;display:flex;gap:16px;align-items:baseline;padding:20px 0;
  font-family:var(--cond);font-weight:600;font-size:clamp(17px,1.6vw,22px);color:var(--ink);
  transition:color .3s var(--ease-seat);
}
.faq summary::-webkit-details-marker{display:none}
.faq summary::before{
  content:"+";flex:0 0 26px;width:26px;height:26px;border-radius:50%;border:1px solid var(--rule-hi);
  display:inline-flex;align-items:center;justify-content:center;font-family:var(--mono);font-size:15px;color:var(--dim);
  position:relative;top:-2px;transition:transform .45s var(--ease-seat),color .3s,border-color .3s;
}
.faq details[open] summary::before{transform:rotate(45deg);color:var(--led);border-color:var(--led)}
.faq summary:hover{color:var(--led)}
.faq .a{padding:0 0 22px 42px;color:var(--dim);font-size:15.5px;line-height:1.65;max-width:42em}
.faq .a p{margin:0 0 10px}
.faq .a b{color:var(--ink);font-weight:600}
.faq .a code{font-family:var(--mono);font-size:13px;background:rgba(255,255,255,.06);padding:1px 6px;border-radius:3px;color:var(--ink)}

/* ── the big line at the end ─────────────────────────────────────────────── */
.get-now{
  /* auto sides: the element is also a .wrap, and a 0 here took its centring away, so on a screen wider than
     --page (1720 px) the line sat against the left of the page (100 px off at 1920, 2026-09-25) */
  margin:clamp(50px,8vw,120px) auto clamp(30px,5vw,70px);text-align:center;
}
.get-now a{
  display:inline-block;text-decoration:none;
  font-family:var(--cond);font-weight:700;letter-spacing:-.02em;line-height:1;
  font-size:clamp(38px,8.4vw,128px);color:var(--ink);
  transition:color .5s var(--ease-seat),transform .6s var(--ease-seat);
}
.get-now a em{font-style:normal;color:var(--led)}
.get-now a:hover{color:var(--led);transform:translateY(-3px)}
.get-now a:hover em{color:var(--ink)}
.get-now .sub{font-family:var(--mono);font-size:12.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--dim);margin:18px 0 0}

/* ── scroll storytelling: the reel stays put and steps back while the
      instruments roll up over it. Only opacity and transform ever change, and
      the classes are set by an IntersectionObserver on a sentinel, never by a
      scroll handler. Below 1000px and under reduced motion it is the plain flow. */
@media (min-width:1000px) and (prefers-reduced-motion:no-preference){
  .reel-stage{min-height:132vh;position:relative;z-index:0}
  .reel-stage .reel{position:sticky;top:78px;transform-origin:50% 20%;
    transition:opacity .8s var(--ease-seat),transform .8s var(--ease-seat)}
  .reel-stage.s1 .reel{opacity:.8;transform:scale(.982)}
  .reel-stage.s2 .reel{opacity:.42;transform:scale(.95) translateY(-10px)}
  .reel-stage.s3 .reel{opacity:.08;transform:scale(.91) translateY(-26px);pointer-events:none}
  /* the sentinel starts a screen below the stage's top: at the top of the page nothing has moved yet */
  .reel-sent{position:absolute;left:0;right:0;top:92vh;bottom:0;pointer-events:none}
  .sd.over{position:relative;z-index:2;margin-top:-40vh;isolation:isolate}
  /* the heading rolls up over the dimmed reel: a soft floor under it so it reads. It spans the screen and no
     more (it used to run a screen further each side, and from 1024px up the page scrolled sideways); main clips
     what a classic scrollbar's width still adds to 100vw */
  main{overflow-x:clip}
  .sd.over::before{content:"";position:absolute;left:calc(50% - 50vw);right:calc(50% - 50vw);top:-140px;height:260px;z-index:-1;pointer-events:none;
    background:linear-gradient(180deg,rgba(15,20,24,0),rgba(15,20,24,.92) 55%,var(--rack))}
}
.mod-brow{font-family:var(--mono);font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--led);display:block;margin-bottom:6px}

/* ── the App Center window ───────────────────────────────────────────────── */
.ac-page{padding-top:clamp(20px,3vw,40px)}
.ac-below{margin-top:clamp(40px,5vw,72px)}
.acw{
  padding:var(--lip);border-radius:var(--tray);border:1px solid var(--rule);
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.012) 42%,transparent);
  box-shadow:0 1px 0 rgba(255,255,255,.045) inset, 0 30px 70px -36px rgba(0,0,0,.95);
}
.acw-core{
  border-radius:calc(var(--tray) - var(--lip));border:1px solid var(--rule);background:var(--panel);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.055);overflow:hidden;display:flex;flex-direction:column;
}
.ac-title{
  display:flex;align-items:center;gap:14px;padding:12px 16px;border-bottom:1px solid var(--rule);
  background:linear-gradient(180deg,rgba(255,255,255,.04),transparent);
}
.ac-title .dots{display:flex;gap:6px}
.ac-title .dots i{width:11px;height:11px;border-radius:50%;background:var(--rule-hi);display:block}
.ac-title .dots i:first-child{background:#E05252;opacity:.8}.ac-title .dots i:nth-child(2){background:var(--led);opacity:.8}.ac-title .dots i:last-child{background:var(--ok);opacity:.8}
.ac-title h1{font-family:var(--cond);font-weight:700;font-size:17px;margin:0;letter-spacing:.01em;color:var(--ink)}
.ac-title h1 small{font-family:var(--mono);font-weight:400;font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--dim);margin-left:10px}
.ac-title .sp{flex:1}
.ac-title .win{display:flex;gap:10px;font-family:var(--mono);font-size:12px;color:var(--rule-hi)}
.ac-addr{
  display:flex;align-items:center;gap:10px;padding:9px 16px;border-bottom:1px solid var(--rule);background:var(--rack);
  font-family:var(--mono);font-size:12.5px;color:var(--dim);flex-wrap:wrap;
}
.ac-addr .lab{letter-spacing:.14em;text-transform:uppercase;font-size:10.5px}
.ac-addr code{color:var(--ink);background:rgba(255,255,255,.05);border:1px solid var(--rule);padding:3px 9px;border-radius:4px;font-size:12.5px;overflow:auto;max-width:100%}
.ac-addr button{
  font-family:var(--cond);font-weight:600;font-size:12.5px;background:var(--led-soft);color:var(--led);
  border:1px solid rgba(255,176,32,.42);border-radius:999px;padding:4px 12px;cursor:pointer;
}
.ac-addr button.done{background:var(--lime);color:#101507;border-color:var(--lime)}
.ac-addr .how{margin-left:auto;text-decoration:none;color:var(--dim);border-bottom:1px solid var(--rule-hi)}
.ac-addr .how:hover{color:var(--led);border-bottom-color:var(--led)}
.ac-body{display:grid;grid-template-columns:230px minmax(0,1fr);min-height:60vh}
@media (max-width:860px){.ac-body{grid-template-columns:1fr}}
.ac-rail{border-right:1px solid var(--rule);background:var(--rack);padding:14px 10px;display:flex;flex-direction:column;gap:2px}
@media (max-width:860px){.ac-rail{flex-direction:row;overflow-x:auto;border-right:0;border-bottom:1px solid var(--rule);padding:10px}}
.ac-rail .rl{font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--dim);padding:6px 12px 8px}
@media (max-width:860px){.ac-rail .rl{display:none}}
.ac-tab{
  display:flex;align-items:center;gap:11px;text-align:left;width:100%;
  font-family:var(--cond);font-weight:600;font-size:14.5px;letter-spacing:.01em;color:var(--dim);
  background:none;border:1px solid transparent;border-radius:8px;padding:10px 12px;cursor:pointer;
  transition:color .25s var(--ease-seat),background-color .25s var(--ease-seat),border-color .25s var(--ease-seat);
  white-space:nowrap;
}
.ac-tab .ti{width:22px;height:22px;flex:0 0 22px;display:inline-flex;align-items:center;justify-content:center;border-radius:6px;background:rgba(255,255,255,.05);border:1px solid var(--rule)}
.ac-tab .ti svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.ac-tab small{font-family:var(--mono);font-size:10.5px;font-weight:400;color:var(--rule-hi);margin-left:auto;padding-left:10px}
.ac-tab:hover{color:var(--ink);background:var(--panel-2);border-color:var(--rule)}
.ac-tab[aria-selected="true"]{color:var(--led);background:var(--led-soft);border-color:rgba(255,176,32,.35)}
.ac-tab[aria-selected="true"] .ti{border-color:rgba(255,176,32,.45);background:rgba(255,176,32,.12)}
.ac-tab[aria-selected="true"] small{color:var(--led);opacity:.8}
.ac-panes{padding:clamp(16px,2.4vw,30px);min-width:0}
.ac-pane[hidden]{display:none}
.ac-pane{animation:pane-in .55s var(--ease-seat) both}
@keyframes pane-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.ac-pane{animation:none}}
.ac-pane .eyebrow:first-child{margin-top:0}
.ac-pane .eyebrow{margin-top:34px}
.ac-pane .tools{margin-top:18px}
/* compact cards: the download stack has eight of them and a window to sit in */
.tools.compact{grid-template-columns:repeat(auto-fill,minmax(min(280px,100%),1fr));gap:12px}
.tools.compact .tool{padding:calc(24px + var(--lip)) calc(16px + var(--lip)) calc(15px + var(--lip));gap:13px}
.tools.compact .tool .ic{width:44px;height:44px;flex-basis:44px}
.tools.compact .tool .nm{font-size:16px}
.tools.compact .tool .ds{font-size:13px;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.tools.compact .tool .kit{display:none}
.tools.compact .tool.lead{grid-column:1 / -1}
.tools.compact .tool.lead .ds{-webkit-line-clamp:4}
.tools.compact .tool.lead .kit{display:grid}
.tools.compact .tool.lead .ic{width:56px;height:56px;flex-basis:56px}
.tools.compact .tool.lead .nm{font-size:20px}

/* ── the download page ───────────────────────────────────────────────────── */
.dl-page{padding-top:clamp(28px,4vw,56px)}
.dl-page .big{
  font-family:var(--cond);font-weight:700;line-height:1.02;letter-spacing:-.015em;
  font-size:clamp(32px,5.6vw,76px);margin:0 0 14px;max-width:8.64em;color:var(--ink);text-wrap:balance;
}
.dl-page .big em{font-style:normal;color:var(--led)}
/* one column no wider than the page: the implicit auto column took the steps' longest line, and at 390 px the
   three cards were 8 px wider than the screen */
.steps{counter-reset:step;display:grid;grid-template-columns:minmax(0,1fr);gap:14px;margin-top:clamp(24px,3vw,40px)}
.step{
  counter-increment:step;
  padding:var(--lip);border-radius:var(--tray);border:1px solid var(--rule);
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.012) 42%,transparent);
  box-shadow:0 1px 0 rgba(255,255,255,.045) inset, 0 18px 44px -30px rgba(0,0,0,.9);
}
.step-core{
  border-radius:calc(var(--tray) - var(--lip));background:var(--panel);border:1px solid var(--rule);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.055);padding:clamp(18px,2.4vw,28px) clamp(18px,2.4vw,30px);
  display:grid;grid-template-columns:64px minmax(0,1fr);gap:18px;align-items:start;
}
@media (max-width:640px){.step-core{grid-template-columns:1fr}}
.step-core::before{
  content:counter(step,decimal-leading-zero);font-family:var(--cond);font-weight:700;font-size:40px;line-height:1;
  color:var(--led);letter-spacing:-.02em;
}
.step h3{font-family:var(--cond);font-weight:700;font-size:clamp(19px,2vw,24px);margin:2px 0 8px;color:var(--ink)}
.step p{margin:0 0 8px;color:var(--dim);font-size:15px;line-height:1.6}
.step p b{color:var(--ink);font-weight:600}
.step .path{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin:10px 0 12px;font-family:var(--mono);font-size:12.5px;color:var(--dim)}
.step .path span{border:1px solid var(--rule-hi);border-radius:4px;padding:3px 9px;color:var(--ink);background:var(--rack)}
.step .path i{font-style:normal;color:var(--rule-hi)}
.step .copyrow{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:8px 0 4px}
.step .copyrow code{font-family:var(--mono);font-size:14px;color:var(--ink);background:var(--rack);border:1px solid var(--rule-hi);padding:8px 12px;border-radius:6px;overflow:auto;max-width:100%}
.step .copyrow button{
  font-family:var(--cond);font-weight:600;font-size:13.5px;background:var(--led-soft);color:var(--led);
  border:1px solid rgba(255,176,32,.42);border-radius:999px;padding:7px 16px;cursor:pointer;
}
.step .copyrow button.done{background:var(--lime);color:#101507;border-color:var(--lime)}
.step .note{font-family:var(--mono);font-size:12px;color:var(--dim);margin:6px 0 0}
.dl-or{display:flex;align-items:center;gap:16px;margin:clamp(34px,5vw,64px) 0 14px;font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--dim)}
.dl-or::before,.dl-or::after{content:"";flex:1;height:1px;background:var(--rule)}
.dl-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(300px,100%),1fr));gap:12px;margin-top:18px}
.dl-item{
  border:1px solid var(--rule);border-radius:calc(var(--tray) - var(--lip));background:var(--panel);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.055);padding:14px 16px;display:grid;gap:8px;
}
.dl-item .n{font-family:var(--cond);font-weight:700;font-size:16px;color:var(--ink);display:flex;gap:10px;align-items:baseline}
.dl-item .n small{font-family:var(--mono);font-size:11px;font-weight:400;color:var(--dim)}
.dl-item .g{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}
.dl-item .as{display:flex;flex-wrap:wrap;gap:6px}
.dl-item .as a{
  font-family:var(--mono);font-size:12px;text-decoration:none;color:var(--ink);
  border:1px solid var(--rule-hi);border-radius:999px;padding:4px 11px;background:var(--rack);
  transition:border-color .3s var(--ease-seat),color .3s var(--ease-seat),background-color .3s var(--ease-seat);
}
.dl-item .as a:hover{border-color:var(--led);color:var(--led);background:var(--led-soft)}
.dl-item .as a small{color:var(--dim);margin-left:6px}
.dl-go{margin:clamp(34px,5vw,64px) 0 clamp(20px,4vw,50px);display:flex;flex-wrap:wrap;gap:16px;align-items:center}
.dl-go p{margin:0;color:var(--dim);font-size:15px;flex:1 1 18em}

/* ── the about page ──────────────────────────────────────────────────────── */
.about{padding-top:clamp(28px,4vw,56px);display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);gap:clamp(28px,5vw,80px);align-items:start}
@media (max-width:900px){.about{grid-template-columns:1fr}}
.about h1{font-family:var(--cond);font-weight:700;font-size:clamp(30px,4.6vw,60px);line-height:1.04;margin:0 0 20px;letter-spacing:-.015em;color:var(--ink)}
.about h1 em{font-style:normal;color:var(--led)}
.about h2{font-family:var(--cond);font-weight:700;font-size:15px;letter-spacing:.16em;text-transform:uppercase;color:var(--dim);margin:30px 0 10px}
.about p{margin:0 0 14px;color:var(--dim);font-size:15.5px;line-height:1.65}
.about p b{color:var(--ink);font-weight:600}
.about .nd-lead{font-size:17px;color:var(--ink)}
.who{
  padding:var(--lip);border-radius:var(--tray);border:1px solid var(--rule);
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.012) 42%,transparent);
  box-shadow:0 1px 0 rgba(255,255,255,.045) inset, 0 18px 44px -30px rgba(0,0,0,.9);position:sticky;top:90px;
}
.who-core{border-radius:calc(var(--tray) - var(--lip));background:var(--panel);border:1px solid var(--rule);box-shadow:inset 0 1px 0 rgba(255,255,255,.055);padding:clamp(20px,2.6vw,30px)}
.who h3{font-family:var(--cond);font-weight:700;font-size:20px;margin:0 0 4px;color:var(--ink)}
.who .role{font-family:var(--mono);font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--led);margin:0 0 16px}
.who .rows{margin-top:10px}
.give-band{margin-top:clamp(40px,6vw,80px)}

/* ── horizontal scroll showcase ────────────────────────────────────────── */
.h-scroll-wrapper {
  position: relative;
  height: 400vh; /* Scroll distance */
  margin: 40px 0 80px;
}
.h-scroll-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: center;
  overflow: hidden;
  padding-left: max(var(--gut), calc((100vw - var(--page)) / 2 + var(--gut)));
}
.h-scroll-track {
  display: flex;
  gap: 30px;
  will-change: transform;
  /* Start with no transform, JS takes over */
}
.h-scroll-item {
  flex: 0 0 auto;
  width: min(85vw, 1100px);
  margin-right: 30px;
}
.h-scroll-item:last-child {
  margin-right: max(var(--gut), calc((100vw - var(--page)) / 2 + var(--gut))); /* End padding */
}
@media (max-width: 820px) {
  .h-scroll-wrapper {
    height: auto;
  }
  .h-scroll-sticky {
    position: static;
    height: auto;
    padding: 0 var(--gut);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }
  .h-scroll-sticky::-webkit-scrollbar { display: none; }
  .h-scroll-track {
    transform: none !important;
  }
  .h-scroll-item {
    scroll-snap-align: start;
    width: 90vw;
  }
}

/* ── the player's quality control: an adaptive stream (HLS) picks the level from the connection; the reader
   can pin one. The badge says what is playing now. ─────────────────────────────────────────────────────── */
#player .pq{display:none;align-items:center;gap:8px;margin-left:12px}
#player .pq.on{display:flex}
#player .pq select{
  font-family:var(--mono);font-size:11.5px;letter-spacing:.04em;color:var(--ink);
  background:var(--panel-2);border:1px solid var(--rule-hi);border-radius:2px;padding:4px 8px;cursor:pointer;
}
#player .pq select:hover,#player .pq select:focus-visible{border-color:var(--led);color:var(--led)}
#player .pq .plevel{font-family:var(--mono);font-size:11px;letter-spacing:.08em;color:var(--dim);white-space:nowrap;min-width:9ch}
#player .pq .plevel.up{color:var(--led)}
@media (max-width:640px){#player .pq .plevel{display:none}}

/* App Center browsing (2026-10-10): the find field above the panes and a caret a finger can hit */
.ac-find{margin:0 0 clamp(16px,2vw,24px)}
.ac-find input{width:100%;box-sizing:border-box;font:inherit;font-size:14px;color:var(--ink);background:rgba(255,255,255,.04);border:1px solid var(--rule);border-radius:8px;padding:10px 14px}
.ac-find input::placeholder{color:var(--dim)}
.ac-find input:focus{outline:none;border-color:rgba(255,176,32,.55);box-shadow:0 0 0 3px var(--led-soft)}
.ac-none{margin:12px 2px 0;color:var(--dim);font-size:13.5px}
.tool[hidden],.ac-pane .eyebrow[hidden],.ac-pane .blurb[hidden]{display:none}
@media (hover:none){.mm-car{padding:9px 11px 8px;margin-left:-1px}}

/* ── code blocks (assets/site.js "code blocks", docs/site/code-blocks.md; the owner, 2026-10-20) ────────────────
   A block sits in a tray around a plate, the way the films and cut-outs sit. The plate's top 40 px are its bar: the
   language on the left, Copy on the right, both held still while a long line scrolls under them. Colours come off the
   rack: the amber LED for keywords, then the softer status LEDs, green for strings, blue for names (keys and
   variables), pink for numbers and literals; comments and a program's output stay dim. .ht-cmd is a How-to's block,
   styled the same before the script frames it, so nothing moves when it does. */
.cb,.ht-cmd{
  position:relative;min-width:0;max-width:100%;margin:16px 0 24px;padding:var(--lip);
  border:1px solid var(--rule);border-radius:var(--tray);
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.012) 42%,transparent);
  box-shadow:0 1px 0 rgba(255,255,255,.045) inset,0 18px 44px -30px rgba(0,0,0,.9);
  transition:border-color .4s var(--ease-seat);
}
.cb:focus-within,.ht-cmd:focus-within{border-color:var(--rule-hi)}
.cb::before,.ht-cmd::before{
  content:'';position:absolute;left:calc(var(--lip) + 1px);right:calc(var(--lip) + 1px);top:calc(var(--lip) + 40px);
  height:1px;background:var(--rule);pointer-events:none;
}
.cb>pre,.ht-cmd>pre{
  margin:0;padding:54px 20px 18px;border:1px solid var(--rule);border-radius:calc(var(--tray) - var(--lip));
  background:#0B1014;box-shadow:inset 0 1px 0 rgba(255,255,255,.04);color:#CDD6DB;
  font-family:var(--mono);font-size:13.5px;line-height:1.7;white-space:pre;overflow-x:auto;tab-size:4;
  scrollbar-width:thin;scrollbar-color:var(--rule-hi) transparent;
}
.cb>pre:focus-visible,.ht-cmd>pre:focus-visible{outline:2px solid var(--led);outline-offset:-2px}
.cb>pre code{font:inherit;color:inherit;background:none;padding:0;border:0;border-radius:0}
.cb>pre::-webkit-scrollbar{height:10px}
.cb>pre::-webkit-scrollbar-thumb{background:var(--rule-hi);border-radius:10px;border:3px solid #0B1014}
.cb>pre::-webkit-scrollbar-track{background:transparent}
.cb pre ::selection,.ht-cmd pre ::selection{background:rgba(255,176,32,.3);color:#fff}
.cb-lang{
  position:absolute;top:calc(var(--lip) + 13px);left:calc(var(--lip) + 21px);display:flex;align-items:center;gap:9px;
  font:600 10.5px/14px var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--dim);pointer-events:none;
}
.cb-lang::before{content:'';width:6px;height:6px;border-radius:50%;background:var(--led);opacity:.85}
.cb>button,.ht-cmd>button{
  position:absolute;top:calc(var(--lip) + 7px);right:calc(var(--lip) + 8px);min-height:28px;padding:3px 14px;
  font:600 12.5px/1 var(--cond);letter-spacing:.02em;cursor:pointer;
  color:var(--led);background:var(--led-soft);border:1px solid rgba(255,176,32,.42);border-radius:999px;
  transition:background .2s,color .2s,border-color .2s;
}
.cb>button:hover{background:rgba(255,176,32,.22)}
.cb>button.done,.ht-cmd>button.done{background:var(--lime);color:#101507;border-color:var(--lime)}
.cb pre .c,.cb .hljs-comment,.cb .hljs-quote{color:var(--dim)}
.cb pre .o{color:var(--ok)}
.cb pre .p{color:var(--lime);user-select:none}
.cb .hljs-keyword,.cb .hljs-selector-tag,.cb .hljs-section,.cb .hljs-meta,.cb .hljs-doctag{color:var(--led)}
.cb .hljs-built_in,.cb .hljs-title,.cb .hljs-name,.cb .hljs-selector-id,.cb .hljs-selector-class{color:#F5CC7A}
.cb .hljs-string,.cb .hljs-regexp,.cb .hljs-addition,.cb .hljs-code,.cb .hljs-template-tag{color:#9DCC8A}
.cb .hljs-attr,.cb .hljs-attribute,.cb .hljs-property,.cb .hljs-variable,.cb .hljs-template-variable,
.cb .hljs-subst,.cb .hljs-link{color:#8EC3E3}
.cb .hljs-number,.cb .hljs-literal,.cb .hljs-symbol,.cb .hljs-bullet{color:#E58FB0}
.cb .hljs-deletion{color:var(--fail)}
.cb .hljs-emphasis{font-style:italic}
.cb .hljs-strong{font-weight:600}
@media (max-width:560px){
  .cb>pre,.ht-cmd>pre{padding:52px 16px 16px;font-size:12.5px}
}
@media (prefers-reduced-motion:reduce){.cb,.ht-cmd,.cb>button{transition:none}}

/* ── menu: a group heading's icon (sitefx-icons, 2026-10-20) ─────────────────────────────────────────────────────
   tools/node/site-menu.mjs puts an icon in a heading that names one (Developers' Sample programs and How-to for
   developers). Where the group is a fly-out row (.menu.fly) it sits like an item's icon; where the heading is a
   small-caps label (a phone, a short list) it stays hidden. */
.mm-h>.mm-ic{display:none}
.menu.fly .mm-fly>.mm-h>.mm-ic{display:block}
.menu.fly .mm-fly>.mm-h:has(>.mm-ic){padding-left:11px}

/* ── the phone menu: a grid of whole cells (site decision S21, 2026-10-21) ─────────────────────────────────────
   On a phone the menu wrapped into two or three rows by the width of its words, and when the web fonts arrived
   (about three seconds into a first visit) the condensed face took a row away: the whole page jumped up by a row
   (layout shift 0.233 on every page). A row that scrolled sideways (01:42-02:40 UTC that day) kept the height but
   hid half the menu past the screen's edge. Here every entry gets a cell at least 160 px wide (the longest,
   Japanese "ダウンローダー", needs 147 with its caret): how many cells fit a row depends on the screen alone, never
   on the face, so the header has the same height before and after the fonts, and every entry shows. The lists still
   open under the whole header (.mm is static here).
   Since S26 (2026-10-23, the owner: icons on a phone) the cells are one row, one per entry, each as wide as the
   others: an entry is its icon (the bar's icons, above), so the row holds them all at 320 px and its height still
   owes nothing to the fonts. A name shows under its icon only while a list is open or its tile has the keyboard's
   focus, which a visitor starts; that moves no content the visitor has not asked for. */
@media (max-width:1040px){
  .menu{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);grid-template-columns:none;gap:2px;
    overflow:visible;flex-wrap:nowrap}
  .menu>*{min-width:0}
}

/* ── reading progress and the way back up (the owner, 2026-10-21 02:20; site.js makes both) ─────────────────────
   The bar sits on the header's lower edge like the How-to pages' own, and at the very top once a phone's header has
   tucked away; it only moves with transform, so it never shifts the page. The button keeps clear of the iPhone's
   home bar and rounded corners (safe-area insets), and the footer leaves room for it at the end of the page. */
.sp-bar{position:fixed;left:0;right:0;top:var(--mast,66px);height:2px;z-index:39;pointer-events:none;visibility:hidden;
  transition:top .25s ease}
.sp-bar.on{visibility:visible}
.sp-bar i{display:block;height:100%;background:var(--led);transform-origin:0 50%;transform:scaleX(var(--p,0));will-change:transform}
body:has(.mast.tuck) .sp-bar{top:0}
.to-top{position:fixed;z-index:38;
  right:max(16px,calc(env(safe-area-inset-right) + 12px));bottom:max(16px,calc(env(safe-area-inset-bottom) + 12px));
  width:44px;height:44px;display:grid;place-items:center;padding:0;cursor:pointer;
  color:var(--ink);background:var(--panel-2);border:1px solid var(--rule-hi);border-radius:50%;
  box-shadow:0 10px 26px rgba(0,0,0,.5);
  opacity:0;visibility:hidden;transform:translateY(10px);
  transition:opacity .2s ease,transform .25s var(--ease-seat),visibility 0s linear .25s,color .15s ease,border-color .15s ease}
.to-top.on{opacity:1;visibility:visible;transform:none;
  transition:opacity .2s ease,transform .25s var(--ease-seat),visibility 0s,color .15s ease,border-color .15s ease}
.to-top:hover{color:var(--led);border-color:var(--led)}
.to-top:focus-visible{outline:2px solid var(--led);outline-offset:3px}
footer{padding-bottom:max(84px,calc(env(safe-area-inset-bottom) + 76px))}
@media (prefers-reduced-motion:reduce){.sp-bar{transition:none}.to-top,.to-top.on{transition:none;transform:none}}
@media print{.sp-bar,.to-top{display:none}}

/* ── the product glows (site decision S83; the owner, 2026-11-13) ─────────────────────────────────────────────────
   WebPortico's hero stands in a blue light (webportico.css, .wp-hx). The other products get a light of their own
   colour under their picture: Rtorrent 16 the panel's lime, Bucket & Code the green of its panel, StorageDiag an
   emergency red that pulses slowly; the front page gives each product row its colour, fainter, and the benchmark
   row orange. One layer per picture: a pseudo-element the size of the picture's tray, behind it, lit by a coloured
   shadow that spills out under and around it (a shadow adds nothing to the page's width, so a phone never scrolls
   sideways). The pulse animates the layer's opacity and transform only; under reduced motion the light stands. */
:root{--glow-rt:166 226 46;--glow-bvs:61 220 151;--glow-sd:255 56 48;--glow-bench:255 138 36}
html[data-v3] .rt-stage .rt-tray{--glow:var(--glow-rt)}
.bv-stage .bv-tray{--glow:var(--glow-bvs)}
.reel .reel-film{--glow:var(--glow-sd)}
.rt-feat#torrents>.rt-tray{--glow:var(--glow-rt)}
.rt-feat#storagediag>.rt-tray{--glow:var(--glow-sd)}
.rt-feat#bench>.rt-tray{--glow:var(--glow-bench)}
.rt-feat#workshop>.rt-tray{--glow:var(--glow-bvs)}
:is(html[data-v3] .rt-stage .rt-tray,.bv-stage .bv-tray,.rt-feat:is(#torrents,#storagediag,#bench,#workshop)>.rt-tray){
  position:relative;isolation:isolate;
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.012) 42%,rgb(var(--glow) / .06))}
:is(html[data-v3] .rt-stage .rt-tray,.bv-stage .bv-tray,.reel .reel-film,.rt-feat:is(#torrents,#storagediag,#bench,#workshop)>.rt-tray)::before{
  content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;
  box-shadow:0 34px 110px -30px rgb(var(--glow) / .55),0 0 64px -18px rgb(var(--glow) / .3)}
/* the front page: the same light, fainter, so five rows of colour stay a page */
.rt-feat:is(#torrents,#storagediag,#bench,#workshop)>.rt-tray::before{opacity:.6}
/* StorageDiag: the alarm. The reel's light breathes like a warning lamp, a little brighter and wider at its peak */
.reel .reel-film::before{box-shadow:0 30px 120px -26px rgb(var(--glow) / .6),0 0 80px -16px rgb(var(--glow) / .36)}
@media (prefers-reduced-motion:no-preference){
  .reel .reel-film::before{animation:glow-alarm 3.2s ease-in-out infinite}
}
@keyframes glow-alarm{0%,100%{opacity:.45;transform:scale(.985)}50%{opacity:1;transform:scale(1.015)}}
