
:root{--space:#0b1120;--surface:#131c2f;--subtle:#1a2740;--line:#3d5573;
--fg:#eaf2ff;--muted:#9fb3cc;--accent:#22d3ee;--gold:#7dd3fc;--warn:#fb7185;
--sans:Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;
--mono:"SFMono-Regular","SF Mono",ui-monospace,Consolas,monospace;
--hard:5px 5px 0 rgba(2,6,16,.5)}
*{box-sizing:border-box}
body{margin:0;color:var(--fg);font-family:var(--sans);font-size:16px;line-height:1.65;
background:radial-gradient(circle at 12% 6%,#22d3ee1f,transparent 30rem),
radial-gradient(circle at 88% 10%,#7dd3fc16,transparent 28rem),
linear-gradient(135deg,var(--space),#0e1830 56%,var(--subtle));background-attachment:fixed}
.wrap{max-width:64rem;margin:0 auto;padding:0 1.25rem 5rem}
.eyebrow{font-family:var(--mono);font-size:.72rem;letter-spacing:.14em;
text-transform:uppercase;color:var(--accent)}
h1{font-weight:900;font-size:clamp(1.7rem,4vw,2.6rem);line-height:1.1;margin:.4rem 0 1rem}
h2,h3,h4,h5,h6{font-weight:800;line-height:1.25;margin:2rem 0 .6rem}
h2{font-size:1.5rem;padding-bottom:.35rem;border-bottom:2px solid var(--line)}
h3{font-size:1.2rem}
a{color:var(--accent)}
a.ext::after{content:" \2197";font-size:.8em;opacity:.7}
a.dead{color:var(--warn);text-decoration:line-through dotted}
a.wb{color:var(--gold);border-bottom:1px dotted currentColor;text-decoration:none}
.banner{border:2px solid var(--line);background:var(--surface);box-shadow:var(--hard);
padding:1rem 1.1rem;margin:1.5rem 0 2rem;font-size:.9rem;color:var(--muted)}
.banner strong{color:var(--fg)}
.banner .row{margin-top:.5rem;font-family:var(--mono);font-size:.78rem;word-break:break-all}
article{padding-top:2rem}
figure{margin:1.5rem 0;border:2px solid var(--line);background:var(--surface);
box-shadow:var(--hard);padding:.6rem}
figure img{max-width:100%;height:auto;display:block}
figcaption{color:var(--muted);font-size:.86rem;padding:.5rem .2rem 0}
.lost{color:var(--warn);font-size:.9rem;margin:.3rem}
code,pre{font-family:var(--mono);font-size:.88em}
pre{background:#0a1526;border:2px solid var(--line);padding:.9rem;overflow-x:auto}
code{background:#0a1526;padding:.1rem .3rem;border-radius:3px}
.tablewrap{overflow-x:auto;border:2px solid var(--line);box-shadow:var(--hard);
background:var(--surface);margin:1.5rem 0}
table{border-collapse:collapse;width:100%;font-size:.88rem}
th,td{border:1px solid var(--line);padding:.45rem .6rem;text-align:left;vertical-align:top}
th{background:var(--subtle);font-weight:700;position:sticky;top:0}
tr:nth-child(even) td{background:#0f1930}
ul,ol{padding-left:1.4rem}
li{margin:.25rem 0}
.tmpl{font-family:var(--mono);font-size:.8em;color:var(--muted);opacity:.7}
.toc{border:2px solid var(--line);background:var(--surface);padding:.9rem 1.1rem;
margin:1.5rem 0;box-shadow:var(--hard)}
.toc div{font-family:var(--mono);font-size:.72rem;letter-spacing:.12em;
text-transform:uppercase;color:var(--accent);margin-bottom:.4rem}
.toc a{display:block;color:var(--muted);text-decoration:none;padding:.12rem 0}
.toc a:hover{color:var(--accent)}
.toc .l3{padding-left:1rem;font-size:.92em}
.idx{display:grid;gap:.5rem;grid-template-columns:repeat(auto-fill,minmax(min(100%,17rem),1fr));
padding:0;list-style:none}
.idx a{display:block;border:2px solid var(--line);background:var(--surface);
padding:.6rem .75rem;text-decoration:none;color:var(--fg);font-weight:600;font-size:.92rem}
.idx a:hover{border-color:var(--accent);box-shadow:var(--hard)}
.idx a small{display:block;color:var(--muted);font-weight:400;font-family:var(--mono);
font-size:.7rem;margin-top:.15rem}
.sheet{display:grid;gap:1rem;list-style:none;padding:0;
grid-template-columns:repeat(auto-fill,minmax(min(100%,13rem),1fr))}
.sheet li{border:2px solid var(--line);background:var(--surface)}
.sheet li:hover{border-color:var(--accent);box-shadow:var(--hard)}
.sheet a.pic{display:block;text-decoration:none}
.sheet a.desc{display:inline-block;margin-top:.3rem;font-family:var(--mono);
font-size:.68rem;color:var(--gold)}
.sheet img{width:100%;aspect-ratio:4/3;object-fit:contain;display:block;
background:#0a1526}
.sheet .noimg{aspect-ratio:4/3;display:flex;align-items:center;justify-content:center;
background:#0a1526;color:var(--muted);font-family:var(--mono);font-size:.75rem}
.sheet .cap{display:block;padding:.5rem .6rem}
.sheet .cap b{display:block;font-size:.8rem;font-weight:600;word-break:break-word}
.sheet .cap small{display:block;color:var(--muted);font-family:var(--mono);
font-size:.68rem;margin-top:.15rem}
footer{margin-top:4rem;padding-top:1.5rem;border-top:2px solid var(--line);
color:var(--muted);font-size:.85rem}

.version-foot{display:inline-flex;align-items:center;gap:.5rem;
font-family:var(--mono);font-size:.7rem;margin-left:.75rem}
.version-foot:empty{display:none}
.vf-rev{display:inline-flex;align-items:center;gap:.35rem;text-decoration:none}
.vf-pill{border:1px solid var(--line);background:var(--subtle);color:var(--accent);
padding:.1rem .4rem;letter-spacing:.04em}
.vf-hash{color:var(--muted)}
.vf-rev:hover .vf-pill{border-color:var(--accent)}
.vf-rev:hover .vf-hash{color:var(--fg)}
.vf-built{color:var(--muted)}
.vf-built::before{content:"·";margin-right:.5rem;opacity:.6}

.site-head{position:sticky;top:0;z-index:30;backdrop-filter:blur(12px);
background:color-mix(in srgb,var(--space) 86%,transparent);
border-bottom:2px solid color-mix(in srgb,var(--line) 55%,transparent)}
.site-head .wrap{position:relative;padding-top:0;padding-bottom:0;max-width:78rem}
.site-head nav{display:flex;align-items:center;gap:.9rem;height:4.25rem}
.site-head a{text-decoration:none}
.mark{font-weight:900;font-size:1.1rem;letter-spacing:-.02em;color:var(--fg);
white-space:nowrap;display:inline-flex;align-items:center;gap:.5rem}
.mark .n{font-family:var(--mono);font-weight:700;color:var(--accent)}
.mark .tagword{font-family:var(--mono);font-size:.58rem;font-weight:700;
letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
border:1px solid color-mix(in srgb,var(--line) 70%,transparent);
border-radius:.25rem;padding:.15rem .35rem}
.navlinks{display:none}
.navlinks a{display:block;padding:.5rem .3rem;border-radius:.25rem;color:var(--fg)}
.navlinks a:hover{background:color-mix(in srgb,var(--accent) 12%,transparent)}
.navlinks a:hover .navlink-label{color:var(--gold)}
.navgroup{min-width:0;padding-bottom:.5rem}
.navgroup-title{margin:.35rem 0 .3rem;font-family:var(--mono);font-size:.62rem;
font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
padding-bottom:.3rem;
border-bottom:1px solid color-mix(in srgb,var(--line) 45%,transparent)}
.navlink-label{display:block;font-weight:700;font-size:.95rem}
.navlink-hint{display:block;margin-top:.1rem;color:var(--muted);font-size:.76rem;
line-height:1.35}
.navlinks a[aria-current=page]{background:color-mix(in srgb,var(--accent) 9%,transparent)}
.navlinks a[aria-current=page] .navlink-label{color:var(--accent)}
.site-head .nav-cta{margin-left:auto;display:inline-flex;align-items:center;
justify-content:center;min-height:2.75rem;padding:.4rem .95rem;font-size:.85rem;
font-weight:800;border:2px solid var(--accent);border-radius:.375rem;
background:var(--accent);color:#06121f;box-shadow:5px 5px 0 rgba(2,6,16,.5);
transition:.15s;white-space:nowrap}
.site-head .nav-cta:hover{border-color:var(--gold);background:var(--gold)}
.site-head .nav-cta:active{transform:translate(2px,2px);
box-shadow:3px 3px 0 rgba(2,6,16,.5)}
.menu-btn{display:inline-flex;align-items:center;gap:.5rem;min-height:2.75rem;
padding:.4rem .8rem;border:2px solid color-mix(in srgb,var(--line) 80%,transparent);
border-radius:.375rem;background:transparent;color:var(--muted);cursor:pointer;
font-family:var(--mono);font-size:.7rem;font-weight:700;letter-spacing:.12em;
text-transform:uppercase;transition:.15s}
.menu-btn:hover{border-color:var(--gold);color:var(--gold)}
/* What changed since the previous archive deploy, rendered by the shared
   version-footer.js. Here rather than in each builder's own CSS because the
   three of them already carry three copies of the footer rules, and a fourth
   copy in three places is how those drifted in the first place. A literal
   middot, not an escape: see the simulator's notes on the ␀b7 bug. */
.vf-changed{color:var(--muted);min-width:0;overflow:hidden;text-overflow:ellipsis}
.vf-changed::before{content:"·";margin-right:.5rem;opacity:.6}
.vf-changed a{color:var(--gold);text-decoration:none}
.vf-changed a:hover{color:var(--fg);text-decoration:underline}
/* The "changed since the previous deploy" section on the overview, filled at
   runtime by version-footer.js from the same stamp the footer reads. Hidden
   until filled, and hidden again when there is nothing to compare against. */
/* Not a panel. On the gallery it sits directly above the attribution banner,
   which IS a panel -- 2px rule, hard shadow, the licence compliance -- and two
   bordered boxes stacked with a hair between them read as peers fighting for
   the same job. This is a courtesy and ranks below that banner, so it is a
   left-ruled aside: no box, no shadow, and enough margin beneath it that the
   banner starts as its own thing. */
.changed-since{margin:2.2rem 0 2rem;padding:.6rem 0 .6rem 1rem;
border-left:3px solid var(--gold)}
/* Two left-ruled asides one above the other read as one quotation, and on the
   overview this sits directly under a callout ruled in the accent colour: the
   note looked like the callout's last paragraph. The rule is solid gold, not a
   washed accent, and the top margin is deliberately larger than the gap inside
   any of the archive's own blocks, so it breaks rather than continues. */
.changed-since[hidden]{display:none}
.changed-since .eyebrow{margin-top:0}
.changed-list{margin:.5rem 0 .6rem;padding-left:1.2rem;line-height:1.7}
.changed-list a{color:var(--gold);text-decoration:none}
.changed-list a:hover{text-decoration:underline}
.changed-none,.changed-diff{margin:.4rem 0 0;color:var(--muted);font-size:.92rem}
.changed-diff a{color:var(--gold)}
.changed-many summary{cursor:pointer;color:var(--fg);font-weight:600;margin:.4rem 0}
/* The source link is inserted by web/site-nav.js, which this site shares
   verbatim, so it appears here without any markup of ours. The style has to be
   restated because this page carries its own stylesheet rather than the
   simulator's; the three tokens it needs happen to exist under the same names
   on both sides. */
.gh-link{display:inline-flex;align-items:center;justify-content:center;
width:2.75rem;height:2.75rem;flex:none;
border:2px solid color-mix(in srgb,var(--line) 80%,transparent);
border-radius:.375rem;background:transparent;color:var(--muted);transition:.15s}
.gh-link:hover{border-color:var(--gold);color:var(--gold)}
.gh-link svg{width:1.15rem;height:1.15rem;display:block}
.gh-lib{width:auto;padding:0 .6rem;gap:.4rem}
.gh-lib span{font-family:var(--mono);font-size:.72rem;letter-spacing:.04em}
@media(max-width:34rem){.gh-lib{display:none}}
.menu-btn .mi{display:grid;gap:3px;width:.95rem}
.menu-btn .mi i{display:block;height:2px;background:currentColor;border-radius:2px;
transition:.15s}
.menu-btn[aria-expanded=true]{border-color:var(--accent);color:var(--fg);
background:color-mix(in srgb,var(--accent) 16%,transparent)}
.menu-btn[aria-expanded=true] .mi i:nth-child(1){transform:translateY(5px) rotate(45deg)}
.menu-btn[aria-expanded=true] .mi i:nth-child(2){opacity:0}
.menu-btn[aria-expanded=true] .mi i:nth-child(3){transform:translateY(-5px) rotate(-45deg)}
/* One organized panel at every width, matching the simulator. The inline row
   this replaced could carry neither a heading nor a description, and it meant a
   phone and a desktop were navigating differently shaped sites. site-nav.js
   sets max-height from the header's measured bottom. */
.site-head.open .navlinks{display:grid;position:absolute;top:100%;left:0;right:0;
z-index:40;grid-template-columns:repeat(auto-fit,minmax(12.5rem,1fr));
gap:.25rem 1.5rem;align-items:start;padding:1rem 1.25rem 1.25rem;
max-height:100vh;overflow-y:auto;overscroll-behavior:contain;
background:color-mix(in srgb,var(--space) 96%,transparent);backdrop-filter:blur(12px);
border-bottom:2px solid color-mix(in srgb,var(--line) 55%,transparent);
box-shadow:0 14px 24px rgba(2,6,16,.5)}
/* Below 384px the wordmark, call to action and menu together want more width
   than the viewport has, and the overflow escapes the header rather than being
   clipped. The CTA goes: the menu still lists the simulator. */
@media(max-width:24rem){.site-head .nav-cta{display:none}
.mark .tagword{display:none}}
