@font-face{src:url(fonts/NunitoSans-cyrillic-ext-italic.woff2) format("woff2");font-family:'Nunito Sans';font-style:italic;font-weight:200 1000;font-stretch:100%;font-display:swap;unicode-range:U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F}
@font-face{src:url(fonts/NunitoSans-cyrillic-italic.woff2) format("woff2");font-family:'Nunito Sans';font-style:italic;font-weight:200 1000;font-stretch:100%;font-display:swap;unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{src:url(fonts/NunitoSans-vietnamese-italic.woff2) format("woff2");font-family:'Nunito Sans';font-style:italic;font-weight:200 1000;font-stretch:100%;font-display:swap;unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB}
@font-face{src:url(fonts/NunitoSans-latin-ext-italic.woff2) format("woff2");font-family:'Nunito Sans';font-style:italic;font-weight:200 1000;font-stretch:100%;font-display:swap;unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{src:url(fonts/NunitoSans-latin-italic.woff2) format("woff2");font-family:'Nunito Sans';font-style:italic;font-weight:200 1000;font-stretch:100%;font-display:swap;unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{src:url(fonts/NunitoSans-cyrillic-ext-normal.woff2) format("woff2");font-family:'Nunito Sans';font-style:normal;font-weight:200 1000;font-stretch:100%;font-display:swap;unicode-range:U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F}
@font-face{src:url(fonts/NunitoSans-cyrillic-normal.woff2) format("woff2");font-family:'Nunito Sans';font-style:normal;font-weight:200 1000;font-stretch:100%;font-display:swap;unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{src:url(fonts/NunitoSans-vietnamese-normal.woff2) format("woff2");font-family:'Nunito Sans';font-style:normal;font-weight:200 1000;font-stretch:100%;font-display:swap;unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB}
@font-face{src:url(fonts/NunitoSans-latin-ext-normal.woff2) format("woff2");font-family:'Nunito Sans';font-style:normal;font-weight:200 1000;font-stretch:100%;font-display:swap;unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{src:url(fonts/NunitoSans-latin-normal.woff2) format("woff2");font-family:'Nunito Sans';font-style:normal;font-weight:200 1000;font-stretch:100%;font-display:swap;unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
/*!
* @preserve
* MonoLisa 3.000
* This font is subject to a EULA. A user-licence can be acquired at:
*   https://www.monolisa.dev/license
* © 2026 FaceType Foundry. All Rights Reserved.
*/
@font-face{src:url(fonts/0-MonoLisaCode-normal.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:normal;unicode-range:U+0020-007F;font-display:swap}
@font-face{src:url(fonts/1-MonoLisaCode-italic.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:italic;unicode-range:U+0020-007F;font-display:swap}
@font-face{src:url(fonts/2-MonoLisaCode-normal.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:normal;unicode-range:U+0080-00FF;font-display:swap}
@font-face{src:url(fonts/3-MonoLisaCode-italic.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:italic;unicode-range:U+0080-00FF;font-display:swap}
@font-face{src:url(fonts/4-MonoLisaCode-normal.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:normal;unicode-range:U+0100-017F;font-display:swap}
@font-face{src:url(fonts/5-MonoLisaCode-italic.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:italic;unicode-range:U+0100-017F;font-display:swap}
@font-face{src:url(fonts/6-MonoLisaCode-normal.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:normal;unicode-range:U+2000-206F;font-display:swap}
@font-face{src:url(fonts/7-MonoLisaCode-italic.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:italic;unicode-range:U+2000-206F;font-display:swap}
@font-face{src:url(fonts/8-MonoLisaCode-normal.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:normal;unicode-range:U+2070-209F;font-display:swap}
@font-face{src:url(fonts/9-MonoLisaCode-italic.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:italic;unicode-range:U+2070-209F;font-display:swap}
@font-face{src:url(fonts/10-MonoLisaCode-normal.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:normal;unicode-range:U+2300-23FF;font-display:swap}
@font-face{src:url(fonts/11-MonoLisaCode-italic.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:italic;unicode-range:U+2300-23FF;font-display:swap}
@font-face{src:url(fonts/12-MonoLisaCode-normal.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:normal;unicode-range:U+2190-21FF;font-display:swap}
@font-face{src:url(fonts/13-MonoLisaCode-italic.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:italic;unicode-range:U+2190-21FF;font-display:swap}
@font-face{src:url(fonts/14-MonoLisaCode-normal.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:normal;unicode-range:U+2B00-2BFF;font-display:swap}
@font-face{src:url(fonts/15-MonoLisaCode-italic.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:italic;unicode-range:U+2B00-2BFF;font-display:swap}
@font-face{src:url(fonts/16-MonoLisaCode-normal.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:normal;unicode-range:U+2200-22FF;font-display:swap}
@font-face{src:url(fonts/17-MonoLisaCode-italic.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:italic;unicode-range:U+2200-22FF;font-display:swap}
@font-face{src:url(fonts/18-MonoLisaCode-normal.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:normal;unicode-range:U+2580-259F;font-display:swap}
@font-face{src:url(fonts/19-MonoLisaCode-italic.woff2) format("woff2");font-family:MonoLisaCode;font-weight:1 900;font-style:italic;unicode-range:U+2580-259F;font-display:swap}

:root{
  color-scheme: light;
  /*  Every colour is oklch: lightness, chroma, hue.  The light surfaces
      share one warm hue (85) and differ only in lightness; the ink leans
      cool (255-260) so text never reads as brown; the accent is brick
      (30).  The dark theme turns the surfaces cool (255) as well -- warm
      darks read as brown -- and lifts the accent to coral (40).
      The syntax colours share one lightness and one chroma and differ
      only in hue, so no token shouts louder than another.  */
  --bg:oklch(0.975 0.006 85); --bg-soft:oklch(0.955 0.008 85);
  --panel:oklch(0.99 0.004 85); --panel-2:oklch(0.945 0.009 85);
  --ink:oklch(0.24 0.018 260); --ink-soft:oklch(0.45 0.02 255);
  --ink-faint:oklch(0.515 0.015 250);
  --rule:oklch(0.88 0.012 85); --rule-soft:oklch(0.92 0.01 85);
  /*  The boundary of a control -- a field, a button -- has to be seen
      to be found: about 3:1 against the surface, where --rule's 1.35:1
      is a hairline between two things that are not interactive.  */
  --rule-strong:oklch(0.64 0.014 85);
  --accent:oklch(0.5 0.15 30); --accent-soft:oklch(0.66 0.1 30);
  --accent-bg:oklch(0.95 0.02 30);
  --code-bg:oklch(0.985 0.005 85); --code-rule:var(--rule);
  --k:oklch(0.48 0.1 350); --t:oklch(0.48 0.1 190); --f:oklch(0.48 0.1 260);
  --n:oklch(0.48 0.1 300); --q:oklch(0.48 0.1 130); --b:oklch(0.48 0.1 60);
  --cd:oklch(0.48 0.06 140);
  /*  A terminal's output is a panel of its own, dark in both themes.  */
  --term-bg:oklch(0.25 0.014 255); --term-ink:oklch(0.92 0.006 250);
  --d:var(--ink); --c:var(--ink-faint); --o:var(--ink-faint);
  --sh:0 8px 24px oklch(0.2 0.02 60 / .12);
  /*  The sticky bar's height, which every scroll target clears.  */
  --bar:3.25rem;
  --ui:"Nunito Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,"Helvetica Neue",sans-serif;
  --mono:MonoLisaCode,ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;
}
/*  The switch is a checkbox, and it inverts: checked means the theme the
    system did not ask for.  CSS cannot read which theme that is, only
    match on it, so the dark values are written under both halves of the
    question -- system dark and not inverted, system light and inverted.
    The choice itself is remembered by THEME_JS, which runs as the box is
    parsed and before anything is painted.
    They are one string substituted twice, so the two copies cannot
    drift apart.  */
@media (prefers-color-scheme: dark){
  :root:not(:has(#theme:checked)){
    color-scheme: dark;
    --bg:oklch(0.2 0.012 255); --bg-soft:oklch(0.215 0.012 255);
    --panel:oklch(0.23 0.013 255); --panel-2:oklch(0.25 0.014 255);
    --ink:oklch(0.93 0.006 250); --ink-soft:oklch(0.8 0.012 250);
    --ink-faint:oklch(0.68 0.014 250);
    --rule:oklch(0.31 0.014 255); --rule-soft:oklch(0.27 0.013 255);
    --rule-strong:oklch(0.53 0.014 255);
    --accent:oklch(0.76 0.12 40); --accent-soft:oklch(0.6 0.1 40);
    --accent-bg:oklch(0.28 0.04 40);
    --code-bg:oklch(0.175 0.012 255);
    --k:oklch(0.8 0.09 350); --t:oklch(0.8 0.08 195); --f:oklch(0.8 0.08 255);
    --n:oklch(0.8 0.09 305); --q:oklch(0.8 0.09 135); --b:oklch(0.82 0.1 75);
    --cd:oklch(0.74 0.06 140);
    --term-bg:oklch(0.16 0.012 255); --term-ink:oklch(0.88 0.01 250);
    --sh:0 8px 24px oklch(0 0 0 / .45);
  }
}
@media (prefers-color-scheme: light), (prefers-color-scheme: no-preference){
  :root:has(#theme:checked){
    color-scheme: dark;
    --bg:oklch(0.2 0.012 255); --bg-soft:oklch(0.215 0.012 255);
    --panel:oklch(0.23 0.013 255); --panel-2:oklch(0.25 0.014 255);
    --ink:oklch(0.93 0.006 250); --ink-soft:oklch(0.8 0.012 250);
    --ink-faint:oklch(0.68 0.014 250);
    --rule:oklch(0.31 0.014 255); --rule-soft:oklch(0.27 0.013 255);
    --rule-strong:oklch(0.53 0.014 255);
    --accent:oklch(0.76 0.12 40); --accent-soft:oklch(0.6 0.1 40);
    --accent-bg:oklch(0.28 0.04 40);
    --code-bg:oklch(0.175 0.012 255);
    --k:oklch(0.8 0.09 350); --t:oklch(0.8 0.08 195); --f:oklch(0.8 0.08 255);
    --n:oklch(0.8 0.09 305); --q:oklch(0.8 0.09 135); --b:oklch(0.82 0.1 75);
    --cd:oklch(0.74 0.06 140);
    --term-bg:oklch(0.16 0.012 255); --term-ink:oklch(0.88 0.01 250);
    --sh:0 8px 24px oklch(0 0 0 / .45);
  }
}

*{box-sizing:border-box}
/*  No smooth scrolling here: a jump across a long document animated
    for seconds, and the reduced-motion setting that switched it off was
    overridden by the rule after it.  JS animates a short in-page jump,
    and only for a reader who has not asked for less motion.  */
@media (prefers-reduced-motion: reduce){
  *{transition-duration:.01ms !important; animation-duration:.01ms !important}
}
a:focus-visible, button:focus-visible, input:focus-visible, summary:focus-visible{
  outline:2px solid var(--accent); outline-offset:2px;
}
a.skip{
  position:absolute; left:.5rem; top:-3rem; z-index:60;
  padding:.45rem .7rem; background:var(--panel); color:var(--ink);
  border:1px solid var(--accent); font-size:.85rem;
}
/*  Below the bar, not over the brand.  */
a.skip:focus{top:calc(var(--bar) + .5rem)}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--bg); color:var(--ink);
  font-family:var(--ui); font-size:16px; line-height:1.6;
  font-feature-settings:"kern" 1,"liga" 1;
}
/*  The code face's features: calt and liga draw `->`, `<>` and `:=` as
    one shape each, and zero slashes the digit.  dlig is the code face's
    own and is switched on only once that face is known to have loaded
    (JS sets .mono-dlig): a fallback face's dlig draws a struck `st`.  */
code,pre,.mono,.tag,.cite,.label{
  font-family:var(--mono);
  font-feature-settings:"kern" 1,"calt" 1,"liga" 1,"zero" 1;
}
.mono-dlig :is(code,pre,.mono,.tag,.cite,.label){
  font-feature-settings:"kern" 1,"calt" 1,"liga" 1,"dlig" 1,"zero" 1;
}
code{
  font-size:.85em; padding:.05rem .18rem; color:var(--ink);
  background:var(--panel-2); border-radius:2px;
}
/*  A field the reader types in is a control and is seen as one.  */
main input:not([type="checkbox"]):not([type="radio"]){border-color:var(--rule-strong)}
/*  A long path in a sentence or a cell may break anywhere rather than
    push the page wider than the phone.  An identifier keeps its case
    wherever an uppercase transform reaches it.  */
/*  A long path in a sentence or a cell may break rather than push the
    page wider than the phone.  In a sentence it breaks only where a word
    cannot fit at all -- `anywhere` split `--level=armv7-m` after its
    dashes and identifiers mid-token -- and on a wide screen a short span
    does not break at all; a span the generator marks long still may.  A
    table cell and a caption's path have no room to spare and keep
    `anywhere`.  */
p code, li code, blockquote code{overflow-wrap:break-word}
td code, th code{overflow-wrap:anywhere}
@media (min-width:48rem){
  p code:not(.long), li code:not(.long){white-space:nowrap}
}
:is(h1,h2,h3,h4,.where,summary) code{text-transform:none}
/*  Code in a heading is part of the title, not a chip inside it.  */
:is(h1,h2,h3,h4) code{background:none; padding:0; font-size:.92em}
a{
  color:var(--accent); text-underline-offset:.18em;
  text-decoration-thickness:1px;
  text-decoration-color:color-mix(in oklch, var(--accent) 40%, transparent);
}
a:hover{text-decoration-color:currentColor}
/*  A mono label: the small lowercase line that says what a thing is.  */
.label{font-size:.75rem; color:var(--ink-faint); letter-spacing:0}

/* ---- top bar ---- */
header.bar{
  position:sticky; top:0; z-index:40;
  display:flex; align-items:center; gap:.9rem;
  height:var(--bar); padding:0 1.5rem 0 1.25rem;
  /*  Opaque: translucent, the text scrolling under it showed through.  */
  background:var(--bg);
  border-bottom:1px solid var(--rule);
}
header.bar .brand{
  font-weight:700; font-size:.98rem; letter-spacing:-.01em;
  color:var(--ink); text-decoration:none; white-space:nowrap;
  display:inline-flex; align-items:baseline; gap:.5rem;
}
/*  The mark is 701 in figures, which stand on the baseline and rise to
    the cap height, so it is set exactly that tall and aligned to the
    baseline: an svg has no baseline of its own, and a flex item without
    one aligns its bottom edge.  Centring the box on the line box put it
    against the line-height rather than the letters.  The crop box is the
    drawing's own extremes, so overflow stays visible or the antialiased
    edge pixels are cut off.  */
header.bar .brand svg{height:.705em; width:auto; color:var(--accent);
  display:block; overflow:visible}
header.bar .brand:hover{color:var(--accent)}
header.bar .where{
  font-family:var(--mono); font-size:.75rem; color:var(--ink-faint);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
header.bar .grow{flex:1}
svg.i{width:1em; height:1em; flex:none; vertical-align:-.12em}
header.bar .src, header.bar label{
  display:inline-flex; align-items:center; gap:.45rem;
  font-family:var(--mono); font-size:.72rem;
  color:var(--ink-soft); background:none; cursor:pointer;
  text-decoration:none; border:1px solid var(--rule-strong);
  padding:.32rem .6rem; white-space:nowrap;
}
header.bar .src:hover, header.bar label:hover,
input.menu-x:checked + label{
  color:var(--accent); border-color:var(--accent-soft);
}
.dark-only{display:none}
.light-only{display:inline-block}
@media (prefers-color-scheme: dark){
  :root:not(:has(#theme:checked)) .dark-only{display:inline-block}
  :root:not(:has(#theme:checked)) .light-only{display:none}
}
@media (prefers-color-scheme: light), (prefers-color-scheme: no-preference){
  :root:has(#theme:checked) .dark-only{display:inline-block}
  :root:has(#theme:checked) .light-only{display:none}
}
.sr-only, input.theme-x, input.menu-x{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  border:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap;
}
/*  `~`, not `+`: the theme box's script sits between it and its label,
    so the adjacent-sibling form never matched and the switch showed no
    focus at all.  */
input.theme-x:focus-visible ~ label[for="theme"],
input.menu-x:focus-visible + label{
  outline:2px solid var(--accent); outline-offset:2px;
}
/*  The menu box is an invisible tab stop where there is no menu.  */
@media (width > 60rem){ input.menu-x{display:none} }
@media (max-width:35rem){
  :root{--bar:3.75rem}
  header.bar{gap:.45rem; padding:0 .65rem}
  /*  A phone keeps its place in the document, cut short, and gets the
      room discuss and source took: those two move to the foot of the
      drawer, where a reader looking for them opens the menu anyway.  */
  header.bar .where{min-width:0; flex:1 1 auto; font-size:.7rem}
  header.bar .grow{display:none}
  header.bar .src{display:none}
  header.bar label{height:2.75rem; justify-content:center; padding:0 .7rem}
  header.bar label[for="theme"]{width:2.75rem; gap:0; padding:0}
  header.bar label[for="theme"] span{
    position:absolute; width:1px; height:1px; margin:-1px; padding:0;
    border:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap;
  }
}
/*  On a phone narrower than the menu's word needs, the icon alone.  */
@media (max-width:22rem){
  header.bar label[for="menu"]{width:2.75rem; gap:0; padding:0}
  header.bar label[for="menu"] span{
    position:absolute; width:1px; height:1px; margin:-1px; padding:0;
    border:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap;
  }
}
header.bar label[for="menu"]{display:none}
/*  The drawer's foot: discuss and source, where a phone's bar has no
    room for them.  Hidden wherever the bar still carries them.  */
nav.side .side-foot{display:none}
label.scrim{display:none}

/* ---- layout ---- */
.wrap{display:grid; grid-template-columns:16.5rem minmax(0,1fr); align-items:start}

/* ---- the sidebar: the documents in five groups, and the sections of
        the one being read nested under it ---- */
nav.side{
  position:sticky; top:var(--bar); align-self:start;
  height:calc(100vh - var(--bar)); overflow:auto; overscroll-behavior:contain;
  padding:1.2rem 0 3rem; border-right:1px solid var(--rule);
  font-size:.875rem; scrollbar-width:thin;
}
nav.side a{display:block; color:var(--ink-soft); text-decoration:none; line-height:1.35;
  text-wrap:pretty}
/*  Inside the link: the drawer and the sidebar clip anything outside.  */
nav.side a:focus-visible{outline-offset:-2px}
nav.side a.doc{padding:.26rem 1rem .26rem 1.25rem; border-left:2px solid transparent}
nav.side a.doc:hover{color:var(--accent)}
nav.side a.doc.here{color:var(--accent); border-left-color:var(--accent); font-weight:650}
nav.side a.doc.retired{color:var(--ink-faint)}
nav.side details{margin-top:1rem}
nav.side summary{
  list-style:none; cursor:pointer; user-select:none;
  display:flex; align-items:center; gap:.5rem;
  padding:.2rem 1rem .4rem 1.25rem;
  font-family:var(--mono); font-size:.72rem; color:var(--ink-faint);
}
nav.side summary::-webkit-details-marker{display:none}
nav.side summary .count{margin-left:auto; font-size:.68rem}
/*  A chevron drawn from two borders, so it needs neither an icon nor a
    glyph the face might not have.  */
nav.side summary::after{
  content:""; width:.34rem; height:.34rem; flex:none;
  border-right:1.5px solid currentColor; border-bottom:1.5px solid currentColor;
  transform:translateY(-.1rem) rotate(45deg); transition:transform .15s;
}
nav.side details:not([open]) > summary::after{transform:rotate(-45deg)}
nav.side details[open] > summary .count{visibility:hidden}
nav.side summary:hover{color:var(--ink)}
nav.side .toc{margin:.2rem 0 .55rem 1.35rem; border-left:1px solid var(--rule)}
/*  The documents write their section titles in three cases -- THE
    GRAMMAR OF THE ENABLED KERNEL, chip/vendor/gpio, Canonical release --
    and the renderer sets the shouted ones in sentence case, so the list
    reads as one without an uppercase transform flattening identifiers.  */
nav.side a.sect{
  padding:.22rem .75rem .22rem .8rem; margin-left:-1px;
  border-left:1px solid transparent;
  font-size:.8rem; line-height:1.4; color:var(--ink-soft);
}
nav.side a.sect:hover{color:var(--ink)}
nav.side a.sect.here{color:var(--ink); border-left-color:var(--accent)}
/*  A section's own entries, under it, where a page lists them: indented,
    smaller, and with the script running, shown only under the section
    being read.  */
nav.side .subs a.sect{padding-left:1.55rem; font-size:.76rem}
nav.side .toc.folding .subs{display:none}
nav.side .toc.folding .subs.open{display:block}
/*  Where a document's teaching ends and its reference begins.  */
nav.side .toc .divide{display:block; margin:.6rem 0 .25rem; padding:.45rem .75rem 0 .8rem;
  border-top:1px solid var(--rule); font-family:var(--mono); font-size:.68rem;
  color:var(--ink-faint)}
nav.side .toc .divide ~ a.sect:not(.here){color:var(--ink-faint)}
nav.side .toc .divide ~ a.sect:not(.here):hover{color:var(--ink)}

main{padding:2.75rem 3rem 6rem; min-width:0; max-width:62rem}

/* ---- hero ---- */
.hero{border-bottom:1px solid var(--rule); padding-bottom:2rem; margin-bottom:.5rem}
/*  A title with nothing under it needs no rule to end it, and the first
    section follows it closely rather than across an empty band.  */
.hero.bare{border-bottom:0; padding-bottom:0; margin-bottom:0}
.hero.bare h1{margin-bottom:0}
.hero + section{padding-top:1.75rem}
.hero.bare + section{padding-top:1.25rem}
.hero h1{
  margin:.45rem 0 1rem; font-size:clamp(1.8rem, 1.3rem + 1.9vw, 2.6rem);
  line-height:1.08; letter-spacing:-.025em; font-weight:650; text-wrap:balance;
}
.hero p{margin:.6rem 0; max-width:42rem; color:var(--ink-soft)}
.hero p:first-of-type{color:var(--ink); font-size:1.1rem; line-height:1.55}
.hero pre{
  margin:.7rem 0; padding:.7rem .9rem; overflow-x:auto;
  background:var(--code-bg); border:1px solid var(--rule);
  font-size:.82rem; line-height:1.55; color:var(--ink-soft);
}
.hero blockquote{
  margin:.7rem 0; padding:.1rem 0 .1rem 1rem;
  border-left:2px solid var(--rule); color:var(--ink-soft); max-width:42rem;
}

/* ---- sections ---- */
section{padding-top:3rem; scroll-margin-top:calc(var(--bar) + 1rem)}
/*  Every addressable heading lands clear of the sticky bar, not under it:
    from-c.html#printf put its heading at the top edge, behind the bar.  */
main [id]{scroll-margin-top:calc(var(--bar) + 1rem)}
main .item[id]{scroll-margin-top:calc(var(--bar) + 1.5rem)}
/*  A section heading outranks the text under it: larger than the body,
    in sentence case, with the rule running out to the column's edge.  */
section > h2{
  margin:0 0 1.2rem; font-size:1.35rem; line-height:1.3; font-weight:700;
  letter-spacing:-.01em; color:var(--ink); text-wrap:balance;
  display:flex; align-items:baseline; gap:.9rem;
}
section > h2::after{content:""; flex:1 0 2rem; height:1px; background:var(--rule);
  align-self:center}
/*  Prose keeps a reading measure; only listings, tables, panels and
    figures take the wider column.  */
section > p{max-width:42rem}

/* ---- one construct ---- */
.item{position:relative; padding:0 0 1.6rem 0;
      scroll-margin-top:calc(var(--bar) + 1.5rem)}
.item .tag{
  display:inline-block; font-size:.75rem; color:var(--ink-faint);
  text-decoration:none; margin-bottom:.2rem;
}
.item .tag:hover{color:var(--accent)}
.item:target .tag, .item.lit .tag{color:var(--accent); font-weight:700}
/*  Arriving at a construct draws a brick rule down its left edge.  */
/*  Only where the gutter holds it: narrower, the rule sat at the
    screen's edge, and the accent tag already marks the landing.  */
@media (min-width:70rem){
  .item:target::before, .item.lit::before{
    content:""; position:absolute; left:-1.1rem; top:.3rem; bottom:1.4rem;
    width:2px; background:var(--accent);
  }
}
.item p{margin:0 0 .75rem; max-width:42rem}
.item p:last-child{margin-bottom:0}
/*  An entry ending in code is spaced like one ending in prose.  */
.item > :last-child{margin-bottom:0}
@media (min-width:70rem){
  .item{padding-left:4.2rem}
  .item .tag{position:absolute; left:0; top:.55rem; margin:0}
}

/* ---- code ---- */
.listing{position:relative; margin:.4rem 0 1.1rem}
.listing pre{
  /*  The right padding is the copy button's corner, so the first line
      clears it rather than running under it.  */
  margin:0; padding:.85rem 3rem .85rem 1rem; overflow-x:auto;
  background:var(--code-bg); border:1px solid var(--code-rule);
  font-size:.82rem; line-height:1.6; tab-size:4;
}
/*  The copy button sits in the panel's top-right corner on every device,
    at full strength with a control's border: faded to .55 at rest it read
    as disabled, and on a phone its strip of its own was 36px of nothing
    above every listing.  */
.listing .copy{
  position:absolute; top:.45rem; right:.45rem;
  display:inline-flex; align-items:center; justify-content:center; gap:.35rem;
  min-width:2rem; min-height:2rem; padding:0 .4rem;
  font:inherit; font-size:.8rem; line-height:1;
  color:var(--ink-soft); background:var(--panel); cursor:pointer;
  border:1px solid var(--rule-strong);
}
.listing .copy:hover{color:var(--accent); border-color:var(--accent)}
.listing .copy .done{display:none}
.listing .copy.done .i{display:none}
.listing .copy.done .done{display:inline-block; color:var(--q)}
/*  Copied: the button says so in words, for two seconds.  */
.listing .copy.done::after{content:"copied"; font-family:var(--mono); font-size:.72rem;
  color:var(--ink)}
/*  No clipboard: the code is selected instead, and the button says so.  */
.listing .copy.manual .i{display:none}
.listing .copy.manual::after{content:"selected 4  copy it"; padding:0 .15rem;
  font-family:var(--mono); font-size:.72rem; color:var(--accent)}
/*  On a phone a listing's comments wrap, and its code keeps its columns:
    102 of the tour's 176 listings scrolled sideways at 390px, most of
    them for a comment.  A listing marked `wraps` -- the first programs a
    reader meets -- wraps whole, each line under its own indentation.  */
@media (max-width:35rem){
  /*  And a listing runs to the screen's edges, as wide as a phone has:
      the copy button's corner costs six columns, and the page's margins
      gave back five of them.  */
  main .listing:not(figure .listing), main pre.sample:not(.listing > pre){
    margin-inline:-1.15rem}
  main .listing:not(figure .listing) pre, main pre.sample:not(.listing > pre){
    border-inline:0; padding-left:1.15rem}
  main figure.panel{margin-inline:-1.15rem; max-width:none; border-inline:0}
  main figure.panel .listing pre{padding-left:1.15rem}
  .listing pre :is(.c, .cd){white-space:pre-wrap}
  .listing.wraps pre{white-space:pre-wrap; overflow-wrap:anywhere}
  .listing.wraps pre .ln{display:block;
    padding-left:calc((var(--i, 0) + 2) * 1ch); text-indent:calc((var(--i, 0) + 2) * -1ch)}
}
/*  A panel that scrolls sideways says so at its right edge (JS marks one
    that overflows, and unmarks it at the end of its scroll).  */
.overflows{
  -webkit-mask-image:linear-gradient(to right, #000 calc(100% - 2.75rem), transparent);
  mask-image:linear-gradient(to right, #000 calc(100% - 2.75rem), transparent);
}
pre.sample:not(.listing > pre){
  margin:.15rem 0 .85rem; padding:.55rem .85rem; overflow-x:auto;
  background:var(--code-bg); border:1px solid var(--rule);
  font-size:.82rem; line-height:1.55;
}
.k{color:var(--k)} .t{color:var(--t)} .f{color:var(--f)} .d{color:var(--d); font-weight:650}
.n{color:var(--n)} .q{color:var(--q)} .v{color:var(--b)} .b{color:var(--b); font-weight:600}
.s{color:var(--ink)} .o{color:var(--o)}
.c{color:var(--c); font-style:italic} .cd{color:var(--cd)}
pre a.cite, pre a.cite:hover{color:inherit; text-decoration-style:dotted}

/* ---- citations ---- */
/*  A citation, and a link whose text is code, is quiet: the ink of the
    prose around it with an accent underline, and the accent itself only
    under the pointer or the keyboard.  Accent text in every sentence --
    three citations a line in places -- outshouted the prose, and the
    navigation and real links, which keep it.  */
a.cite, :is(p,li,td,th,dd,blockquote,figcaption) a:has(> code:only-child){
  color:var(--ink-soft); text-decoration:underline; text-decoration-style:dotted;
  text-decoration-thickness:1px; text-underline-offset:.22em;
  text-decoration-color:var(--accent-soft);
}
a.cite{font-size:.9em}
:is(p,li,td,th,dd,blockquote,figcaption) a:has(> code:only-child) code{color:inherit}
a.cite:is(:hover,:focus-visible),
:is(p,li,td,th,dd,blockquote,figcaption) a:has(> code:only-child):is(:hover,:focus-visible){
  color:var(--accent); text-decoration-style:solid; text-decoration-color:currentColor;
}
a.cite:hover{background:var(--accent-bg)}
#pop{
  position:absolute; z-index:60; max-width:29rem; display:none;
  padding:.65rem .8rem; font-size:.86rem; line-height:1.5;
  color:var(--ink); background:var(--panel); box-shadow:var(--sh);
  border:1px solid var(--rule);
}
#pop .tag{font-size:.72rem; color:var(--accent); display:block; margin-bottom:.2rem}
#pop .go{display:block; margin-top:.45rem; font-family:var(--mono); font-size:.75rem}

/*  The footer's rule starts where main's content starts, not 3rem to the
    left of it in the padding.  */
footer{
  grid-column:2; justify-self:start;
  margin:0 3rem 4rem; padding:1.25rem 0 0;
  border-top:1px solid var(--rule);
  color:var(--ink-faint); font-size:.78rem; line-height:1.7; max-width:56rem;
}
footer code{font-size:.9em; color:var(--ink-soft)}
footer .totop{float:right; margin-left:1rem}
.anchor{position:absolute; scroll-margin-top:calc(var(--bar) + 1rem)}

@media (max-width:60rem){
  .wrap{grid-template-columns:minmax(0,1fr)}
  footer{grid-column:1; margin-left:1.15rem; margin-right:1.15rem}
  /*  The drawer runs the full height under the bar, over a scrim that
      closes it when tapped -- a second label for the box, so that works
      without a script too -- and the page behind it does not scroll.  */
  nav.side{
    position:fixed; inset:var(--bar) auto 0 0; width:min(22rem, 88vw);
    /*  Stretched, not the sidebar's `align-self:start`: a fixed box
        aligned to its start shrinks to its content, and the drawer ran
        past the screen's foot with nothing to scroll.  */
    height:auto; max-height:none; align-self:stretch;
    background:var(--bg); border-right:1px solid var(--rule);
    box-shadow:var(--sh); z-index:35; display:none; padding-bottom:1.5rem;
  }
  /*  A checkbox rather than a button, so the drawer opens without a
      script; the script only closes it again after a link is followed.  */
  :root:has(#menu:checked) nav.side{display:block}
  :root:has(#menu:checked) label.scrim{display:block; position:fixed;
    inset:var(--bar) 0 0 0; z-index:34; cursor:pointer;
    background:oklch(0.2 0.02 255 / .35)}
  :root:has(#menu:checked){overflow:hidden}
  header.bar label[for="menu"]{display:inline-flex}
  main{padding:1.75rem 1.15rem 5rem}
  /*  A finger needs a target: at least 24px a link in the drawer.  */
  nav.side a.doc, nav.side a.sect{padding-block:.5rem; min-height:24px}
}
@media (max-width:35rem){
  nav.side .side-foot{display:flex; gap:.6rem; margin:1.4rem 1.25rem 0;
    padding-top:1rem; border-top:1px solid var(--rule)}
  nav.side .side-foot a{display:inline-flex; align-items:center; gap:.45rem;
    padding:.55rem .75rem; border:1px solid var(--rule-strong);
    font-family:var(--mono); font-size:.75rem; color:var(--ink-soft)}
  nav.side .side-foot a:hover{color:var(--accent); border-color:var(--accent)}
}

/*  An entry's heading outranks its text, as a section's outranks it.  */
.guide h3.sub{font:650 1.15rem/1.4 var(--ui);color:var(--ink);margin:2.2rem 0 .6rem;
  letter-spacing:-.005em}
.item > h3.sub{margin-top:0}
.item{margin-top:1.2rem}
.guide p{margin:0 0 12px}
.guide ul,.guide ol{margin:0 0 14px;padding-left:22px}
.guide li{margin:0 0 6px}
/*  The reading measure: prose, lists and quotes stop at 42rem.  */
.guide p, .guide ul:not([class]), .guide ol, .guide blockquote{max-width:42rem}
/*  A bullet is the small square the panels' captions carry, not the
    browser's disc, which sat heavy beside the mono code it introduces.
    Only a plain list: a list with a class of its own -- what a program
    uses, a library's columns -- draws its own rows.  */
.guide ul:not([class]){list-style:none;padding-left:20px}
.guide ul:not([class]) > li{position:relative}
.guide ul:not([class]) > li::before{content:"";position:absolute;left:-15px;top:.66em;
  width:5px;height:5px;background:var(--accent)}
.guide blockquote{margin:0 0 14px;padding:2px 0 2px 14px;
  border-left:2px solid var(--accent-soft);color:var(--ink-soft)}
.guide blockquote p{margin:0 0 8px}
.guide blockquote p:last-child{margin:0}
/*  A page's banner -- "You probably do not want to read this", "Not
    learning material" -- is the first thing it says and must not read
    as the faintest.  Only the pages that carry one: the README opens
    with its pitch in a quote, and that is not a warning.  */
main.banner .guide#top > blockquote:first-child{
  color:var(--ink); background:var(--panel-2); border:1px solid var(--rule);
  border-left:3px solid var(--accent); padding:.85rem 1.1rem; margin-bottom:1.6rem;
}
/*  The fine print under an entry: the tour's "The fine print:" and its
    list, set smaller and to one side of the teaching.  */
.guide aside.fine{margin:.2rem 0 1rem; padding:.15rem 0 .15rem 1rem;
  border-left:2px solid var(--rule-strong); color:var(--ink-soft);
  font-size:.9rem; max-width:42rem}
.guide aside.fine p.fine-head{margin:0 0 .35rem}
/*  A footnote in a guide: the tour's asterisk under its pitch.  */
.guide p.fine-print{margin:1.4rem 0 0}
.guide aside.fine ul:not([class]){margin-bottom:.2rem}
.guide aside.fine ul:not([class]) > li::before{background:var(--ink-faint)}
.guide p.exact{font-family:var(--mono); font-size:.75rem; color:var(--ink-faint);
  margin:.4rem 0 .9rem}
.guide p.exact a.cite{font-size:1em}
/*  A table with a long path in a cell cannot fit a phone, and nothing
    scrolled: it simply overflowed the page.  */
.scroller{overflow-x:auto; margin:0 0 16px}
/*  As wide as its cells want, up to the column: stretched to the full
    width, a table of two short columns sat its words half a page apart.  */
.guide table{width:auto;min-width:min(100%,42rem);border-collapse:collapse;
  font:400 14px/1.5 var(--ui)}
.guide th{text-align:left;font-weight:600;color:var(--ink-soft);
  border-bottom:1px solid var(--rule);padding:7px 18px 7px 0;
  vertical-align:top}
.guide td{border-bottom:1px solid var(--rule-soft);padding:7px 18px 7px 0;
  vertical-align:top}
.guide th:last-child, .guide td:last-child{padding-right:0}
.guide tr:last-child td{border-bottom:0}
.guide td code,.guide th code{white-space:nowrap}
@media (max-width:48rem){
  .guide td code{white-space:normal}
  /*  A table whose cells hold code is a list of records on a phone:
      each row a block, each cell under its column's name.  */
  .guide table.stack, .guide table.stack tbody, .guide table.stack tr,
  .guide table.stack td{display:block; width:auto}
  .guide table.stack thead{position:absolute; width:1px; height:1px;
    overflow:hidden; clip-path:inset(50%); white-space:nowrap}
  .guide table.stack tr{padding:.55rem 0; border-bottom:1px solid var(--rule)}
  .guide table.stack tr:last-child{border-bottom:0}
  .guide table.stack td{border:0; padding:.12rem 0}
  .guide table.stack td[data-label]::before{content:attr(data-label); display:block;
    font-family:var(--mono); font-size:.68rem; color:var(--ink-faint)}
}

/* ---- listings with a caption: the front page's panel, on every page ---- */
.guide figure.panel{margin:.4rem 0 1.1rem; max-width:100%}
.guide figure.panel figcaption > .source{min-width:0; overflow-wrap:anywhere; white-space:normal}
.guide figure.panel .source code{background:none; padding:0; font-size:1em;
  color:var(--ink-soft)}
figure.panel figcaption .lang{color:var(--ink-soft)}
/*  C beside Landin on the page for C programmers: the same panel, quieter,
    so the eye goes to the Landin.  */
figure.panel.lang-c{background:var(--panel-2); border-style:dashed}
figure.panel.lang-c figcaption .dot{background:var(--ink-faint)}
figure.panel.lang-c .listing pre{color:var(--ink-soft)}
/*  What a program prints: a terminal, under the listing or on its own.  */
figure.panel .foot.prints{font-family:var(--mono)}
figure.panel .out pre, figure.panel.output .listing pre{
  background:var(--term-bg); color:var(--term-ink)}
figure.panel .out .listing, figure.panel.output{background:var(--term-bg)}
figure.panel .out .copy, figure.panel.output .copy{background:var(--term-bg);
  color:var(--term-ink)}

/*  The way on, at the end of a long guide.  */
nav.next{margin:3.5rem 0 0; max-width:42rem}
nav.next a{display:block; padding:1rem 1.2rem; border:1px solid var(--rule-strong);
  text-decoration:none; color:var(--ink-soft)}
nav.next a:hover{border-color:var(--accent)}
nav.next .label{display:block; margin-bottom:.25rem}
nav.next strong{display:block; color:var(--ink); font-size:1.05rem; margin-bottom:.2rem}
nav.next a:hover strong{color:var(--accent)}

/* ---- the front page ---- */
.hero.wide h1{font-size:clamp(2rem, 1.4rem + 2.4vw, 3rem)}
.hero.wide p:first-of-type{font-size:1.15rem; text-wrap:pretty}
.hero-actions{display:flex; flex-wrap:wrap; gap:.6rem; margin:1.4rem 0 0}
.hero-actions a{
  display:inline-flex; align-items:center; min-height:2.5rem;
  padding:.45rem .95rem; border:1px solid var(--rule-strong);
  font-size:.9rem; font-weight:600; text-decoration:none; color:var(--ink);
}
.hero-actions a.primary{color:var(--bg); background:var(--accent); border-color:var(--accent)}
.hero-actions a:hover{border-color:var(--accent)}
.hero-actions a.primary:hover{background:color-mix(in oklch, var(--accent) 88%, var(--ink))}

/*  The hero's one line of status, which the section further down says
    in full.  */
.hero p.status-line{margin:1.3rem 0 0; font-family:var(--mono); font-size:.75rem;
  line-height:1.5; color:var(--ink-faint)}
.hero p.status-line a{white-space:nowrap}
/*  The status: what the README says on the left, where the roadmap is on
    the right.  */
.status{
  display:grid; grid-template-columns:2fr 1fr;
  border:1px solid var(--rule); background:var(--panel);
  color:var(--ink-soft); font-size:.92rem;
}
.status > .said{padding:1.1rem 1.25rem 1.25rem}
.status .said p.status-meta{margin:0 0 .5rem; line-height:1.4}
.status h3{margin:0 0 .6rem; color:var(--ink); font-size:1.05rem;
  line-height:1.4; font-weight:650; text-wrap:balance}
.status .said p:not(.status-meta){margin:0; color:var(--ink-soft); font-size:.92rem; line-height:1.6}
.roadmap-track{border-left:1px solid var(--rule); background:var(--bg-soft);
  padding:.9rem 1.1rem 1rem}
.roadmap-track > div{margin-bottom:.8rem}
.roadmap-head{display:block; margin:0 0 .75rem; padding-bottom:.55rem;
  border-bottom:1px solid var(--rule); font-family:var(--mono);
  font-size:.72rem; color:var(--accent); text-decoration:none}
.roadmap-head:hover{text-decoration:underline}
.status .said p.status-context{margin-top:.4rem}
.status .said p.status-links{margin-top:1rem; font-family:var(--mono);
  font-size:.75rem}
.status .said p.status-links a{color:var(--accent); text-decoration:none;
  margin-right:1.2rem}
.status .said p.status-links a:hover{text-decoration:underline}
.roadmap-track > div:last-child{margin-bottom:0}
.roadmap-label{display:block; margin-bottom:.3rem; font-family:var(--mono);
  font-size:.7rem; color:var(--ink-faint)}
.roadmap-item{display:block;
  padding:.15rem 0; color:var(--ink-soft); text-decoration:none;
  line-height:1.35; font-size:.82rem}
.roadmap-item:hover span{color:var(--accent)}
.roadmap-now .roadmap-item span{color:var(--ink); font-weight:600}

section.landing{padding-top:4rem}
section.landing > p.lead{max-width:42rem; color:var(--ink-soft); margin:-.2rem 0 1.4rem}
section.landing > .program + p.lead{margin-top:2.6rem}
/*  The pitch's asterisk, and where it sends the reader.  */
.hero a.asterisk{text-decoration:none; color:var(--accent)}
p.fine-print{margin:4rem 0 0; max-width:42rem; color:var(--ink-faint);
  font-size:.72rem; line-height:1.5}

/*  The program: one whole fixture, with what it uses beside it.  */
/*  The listing asks for its longest line and gets it: a code panel that
    scrolls sideways on a desktop is a layout that ran out of room, not a
    program that is too wide.  What it uses keeps its column only while
    both fit, and otherwise wraps underneath at full width.  Only a phone
    is left to scroll.  */
.program{display:flex; flex-wrap:wrap; gap:1.75rem; align-items:flex-start}
figure.panel{margin:0; border:1px solid var(--rule); background:var(--code-bg);
  min-width:0; flex:1 1 max-content; max-width:100%}
figure.panel figcaption, figure.panel .foot{
  display:flex; align-items:center; gap:.8rem; padding:.5rem .9rem;
  font-family:var(--mono); font-size:.72rem; color:var(--ink-faint);
  background:var(--panel-2);
}
figure.panel figcaption{border-bottom:1px solid var(--rule)}
figure.panel figcaption .path{min-width:0; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; direction:rtl; text-align:left}
figure.panel figcaption > span:last-child{white-space:nowrap}
figure.panel figcaption .dot{width:.5rem; height:.5rem; background:var(--accent); flex:none}
/*  The file's short name: a link to its source, as quiet as the caption.  */
figure.panel figcaption a.name{color:var(--ink-soft); min-width:0;
  overflow-wrap:anywhere; text-decoration-color:var(--accent-soft)}
figure.panel figcaption a.name:hover{color:var(--accent)}
figure.panel figcaption .grow, figure.panel .foot .grow{flex:1}
figure.panel .foot{border-top:1px solid var(--rule)}
figure.panel .foot code{background:none; padding:0; font-size:1em; color:var(--ink-soft)}
figure.panel .foot a{white-space:nowrap}
figure.panel .listing{margin:0}
figure.panel .listing pre{border:0; padding:1rem 1.1rem; font-size:.82rem}
/*  A panel's own copy button sits in its caption row, at the right, so
    the code under it keeps its whole width.  A terminal under the code
    keeps its button in its own corner.  */
figure.panel{position:relative}
figure.panel > .listing{position:static}
figure.panel > figcaption{padding-right:3.1rem; min-height:2.3rem}
figure.panel > .listing .copy{top:.15rem; right:.3rem}
figure.panel .out .listing pre{padding-right:3rem}
.uses{position:sticky; top:calc(var(--bar) + 1.5rem); flex:1 0 13.5rem}
.uses .label{display:block; margin-bottom:.5rem}
.uses ul{list-style:none; margin:0; padding:0; border-top:1px solid var(--rule);
  columns:13.5rem; column-gap:1.5rem}
.uses li{border-bottom:1px solid var(--rule); break-inside:avoid}
/*  Under a program on a page, rather than beside one.  */
.uses.strip{position:static; margin:.2rem 0 1.4rem}
.uses.strip ul{columns:15rem}
.uses li a{display:grid; grid-template-columns:2.9rem 1fr; gap:.4rem;
  padding:.38rem 0; text-decoration:none; color:var(--ink-soft);
  font-size:.84rem; line-height:1.35}
.uses li a .tag{font-family:var(--mono); font-size:.72rem; color:var(--ink-faint);
  padding-top:.08rem}
.uses li a:hover{color:var(--accent)}
.uses li a:hover .tag{color:var(--accent)}
.uses p{margin:.8rem 0 0; font-size:.8rem; color:var(--ink-faint); line-height:1.5}
.uses p a{color:var(--ink-soft)}

/*  Six ways in, as one block of cells split by hairlines.  */
.routes{display:grid; grid-template-columns:1fr 1fr; gap:1px;
  background:var(--rule); border:1px solid var(--rule)}
.route{display:block; padding:1.1rem 1.25rem 1.2rem; background:var(--bg);
  text-decoration:none; color:inherit}
.route .label{display:block; margin-bottom:.35rem}
.route strong{display:block; color:var(--ink); font-size:1.02rem; margin-bottom:.3rem}
.route span.text{display:block; color:var(--ink-soft); font-size:.88rem; line-height:1.5}
.route:hover{background:var(--panel)}
.route:hover strong{color:var(--accent)}

/*  Every document, as rows under the sidebar's own groups.  */
.shelf{border-top:1px solid var(--rule)}
.shelf .group{display:grid; grid-template-columns:10.5rem minmax(0,1fr);
  border-bottom:1px solid var(--rule)}
.shelf .group > h3{margin:0; padding:.8rem 1rem .8rem 0; font-family:var(--mono);
  font-weight:500; font-size:.75rem; color:var(--ink-faint)}
/*  Every card shares the same three columns, so the shelf reads as one
    table: with the count's column sized to its own card, the blurbs
    started and ended somewhere different on every row.  */
.card{display:grid; grid-template-columns:14.5rem minmax(0,1fr) 9rem; gap:1.25rem;
  padding:.72rem 0; text-decoration:none; color:inherit;
  border-bottom:1px solid var(--rule-soft); align-items:baseline}
.shelf .group .card:last-child{border-bottom:0}
.card strong{font-weight:600; font-size:.92rem; color:var(--ink)}
.card span{color:var(--ink-soft); font-size:.86rem; line-height:1.5}
.card em{font-style:normal; font-family:var(--mono); font-size:.7rem;
  color:var(--ink-faint); text-align:right; text-wrap:balance}
.card:hover strong{color:var(--accent)}
.card.retired strong{color:var(--ink-faint); font-weight:500}

@media (max-width:70rem){
  .uses{position:static}
  .card{grid-template-columns:minmax(0,1fr) auto; row-gap:.2rem}
  .card em{white-space:nowrap}
  .card span{grid-column:1/-1; grid-row:2}
}
@media (max-width:48rem){
  .status{grid-template-columns:1fr}
  .roadmap-track{border-left:0; border-top:1px solid var(--rule)}
  .routes{grid-template-columns:1fr}
  .shelf .group{grid-template-columns:1fr}
  .shelf .group > h3{padding-bottom:0}
  /*  The run command stays on a phone, stacked above the way on.  */
  figure.panel .foot{flex-wrap:wrap; row-gap:.35rem}
  figure.panel .foot code{flex:1 1 100%; overflow-wrap:anywhere}
  figure.panel .foot .grow{display:none}
  .card{row-gap:.3rem}
}

.wrap > nav.side{grid-column:1; grid-row:1}
.wrap > main{grid-column:2; grid-row:1}
@media (max-width:60rem){ .wrap > main{grid-column:1} }

/* ---- without a script: no field to type into, no button that waits for one ---- */
:root:not(.api-js) .api-tools label, :root:not(.api-js) .api-tools input,
:root:not(.api-js) button.api-onpage, :root.api-js label.api-onpage-plain{display:none !important}
/*  The sidebar is on the left but after the page in the source; the
    shared skip link's style, and only where there is a sidebar to reach.  */
@media (max-width:60rem){ a.api-skip-nav{display:none} }

/* ---- search: full on the index, a small field after a module's opening ---- */
.api-tools{position:relative; margin:1.5rem 0 0}
.api-tools label{display:block; margin:0 0 .35rem; font-size:.85rem; color:var(--ink-soft)}
.api-tools input{width:100%; padding:.65rem .8rem; font:inherit; color:var(--ink);
  background:var(--panel); border-radius:0; -webkit-appearance:none; appearance:none;
  border:1px solid var(--rule-strong, color-mix(in oklch, var(--ink-faint) 80%, var(--bg)))}
/*  The browser's own clear button was a blue disc; Escape clears.  */
.api-tools input::-webkit-search-cancel-button{-webkit-appearance:none; appearance:none; display:none}
/*  The browser's own placeholder is the ink at reduced opacity, about 4:1.  */
.api-tools input::placeholder{color:var(--ink-faint); opacity:1}
.api-tools.compact{margin:.25rem 0 1.25rem; max-width:22rem}
.api-tools.compact label{margin:0 0 .25rem; font-family:var(--mono); font-size:.72rem;
  color:var(--ink-faint)}
.api-tools.compact input{padding:.38rem .6rem; font-size:.85rem}
/*  A panel over the page under the field: in the flow, the results
    pushed the page down under the reader.  */
.api-results{position:absolute; z-index:30; top:calc(100% + .25rem); left:0;
  width:min(100%, 40rem); max-height:min(65vh, 34rem); overflow:auto;
  overscroll-behavior:contain; padding:0 .9rem;
  background:var(--panel); border:1px solid var(--rule); box-shadow:var(--sh)}
.api-tools.compact .api-results{width:min(calc(100vw - 2.3rem), 34rem)}
.api-results p{margin:.5rem 0; max-width:none; font-size:.85rem; line-height:1.5;
  color:var(--ink-soft)}
.api-results p.api-count{font-family:var(--mono); font-size:.72rem; color:var(--ink-faint)}
.api-results a.api-hit{display:block; padding:.45rem 0 .5rem; text-decoration:none;
  border-top:1px solid var(--rule-soft)}
.api-results a.api-hit:focus-visible{outline-offset:-2px; background:var(--accent-bg)}
.api-hit-name{font-family:var(--mono); font-size:.85rem; color:var(--accent)}
.api-hit-module{color:var(--ink-faint)}
.api-hit-kind, .api-kind{font-family:var(--mono); font-size:.72rem; font-weight:400;
  text-transform:none; letter-spacing:0; color:var(--ink-faint)}
.api-hit-kind{margin-left:.6rem}
.api-hit-summary{display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2;
  line-clamp:2; overflow:hidden; margin-top:.1rem; font-size:.86rem; line-height:1.45;
  color:var(--ink-soft)}
.api-results a.api-hit:hover .api-hit-name{text-decoration:underline}

/* ---- the page's own contents, in the sidebar and the phone's drawer ---- */
nav.side .api-toc-label{display:block; padding:.3rem .75rem .25rem .8rem;
  font-family:var(--mono); font-size:.68rem; color:var(--ink-faint)}
nav.side a.api-toc-kind, nav.side .api-toc-group > summary{
  padding:.14rem .75rem .14rem 1.6rem; margin-left:-1px;
  border-left:1px solid transparent; font-family:var(--ui); font-size:.8rem;
  line-height:1.35; color:var(--ink-faint)}
nav.side a.api-toc-kind:hover{color:var(--ink)}
nav.side a.api-toc-kind.here, nav.side .api-toc-group > summary.here{
  color:var(--ink); border-left-color:var(--accent)}
nav.side .api-toc .count{margin-left:.3rem; font-family:var(--mono); font-size:.66rem;
  color:var(--ink-faint)}
/*  A kind folds its names: the shared summary's chevron and hidden count
    are for the document groups; a kind keeps its count beside its name.  */
nav.side details.api-toc-group{margin:0}
nav.side .api-toc-group > summary{justify-content:flex-start; gap:0}
nav.side .api-toc-group > summary::after{margin-left:.5rem}
nav.side .api-toc-group[open] > summary .count{visibility:visible}
nav.side a.api-toc-item{padding:.1rem .75rem .1rem 2.35rem; margin-left:-1px;
  border-left:1px solid transparent; font-family:var(--mono); font-size:.72rem;
  color:var(--ink-faint); overflow-wrap:anywhere}
nav.side a.api-toc-item:hover{color:var(--ink)}
nav.side a.api-toc-item.here{color:var(--ink); border-left-color:var(--accent-soft)}
@media (max-width:60rem){
  nav.side a.api-toc-kind, nav.side .api-toc-group > summary,
  nav.side a.api-toc-item{padding-block:.45rem; min-height:24px}
}
.api-onpage{display:none}
@media (max-width:60rem){
  .api-onpage{display:inline-flex; align-items:center; margin:0 0 1rem;
    padding:.4rem .75rem; min-height:2.5rem; cursor:pointer;
    font:inherit; font-family:var(--mono); font-size:.75rem; color:var(--ink-soft);
    background:none; border-radius:0;
    border:1px solid var(--rule-strong, color-mix(in oklch, var(--ink-faint) 80%, var(--bg)))}
  .api-onpage:hover, .api-onpage[aria-expanded="true"]{color:var(--accent);
    border-color:var(--accent-soft)}
}

/* ---- headings: the overview's sections, the items, the example ---- */
/*  A module's title has nothing under it but the skip link: no rule and
    no band between it and the opening.  */
.hero:not(:has(.api-tools)){border-bottom:0; padding-bottom:0; margin-bottom:0}
.hero:not(:has(.api-tools)) h1{margin-bottom:.75rem}
.hero:not(:has(.api-tools)) + section.api-opening{padding-top:.25rem}
.api-opening{padding-top:0}
.api-prose section.guide{margin:0; border:0}
.api-prose div.guide{margin:0; padding:0}
/*  The opening paragraph is the guide's lead, outside its .guide, and ran
    the page's whole width: about 120 characters a line.  */
.api-prose > p{max-width:42rem}
section > h2.api-h, .api-prose section.api-section > h2, .api-modules > h2{
  font-size:1.35rem; font-weight:650; line-height:1.3; letter-spacing:-.01em;
  text-transform:none}
.api-condition{font-size:.85rem; color:var(--ink-soft)}

/* ---- the indexes: items by kind, and the modules ---- */
.api-group-title{margin:1.5rem 0 .45rem; font-size:.85rem; font-weight:600;
  color:var(--ink-soft)}
.api-group-title .count{margin-left:.35rem; font-family:var(--mono); font-size:.7rem;
  font-weight:400; color:var(--ink-faint)}
.api-group-title code{background:none; padding:0}
ul.api-index{list-style:none; margin:0; padding:0; columns:12rem; column-gap:2rem;
  border-top:1px solid var(--rule)}
ul.api-index li{break-inside:avoid; border-bottom:1px solid var(--rule-soft)}
/*  The index is navigation and keeps the accent; the shared rule that
    quiets a link whose text is code is for code in a sentence or cell.  */
ul.api-index li > a{display:block; padding:.3rem 0; color:var(--accent);
  text-decoration:none; font-size:.9rem}
ul.api-index li > a code{padding:0; background:none; font-size:.85rem; color:var(--accent)}
ul.api-index li > a:hover code{text-decoration:underline}
/*  A phone had one column of 127 names.  */
@media (max-width:35rem){
  ul.api-index{columns:2; column-gap:1rem}
  ul.api-index li > a code{font-size:.78rem; overflow-wrap:anywhere}
}
ul.api-modules-list{list-style:none; margin:0; padding:0; border-top:1px solid var(--rule)}
ul.api-modules-list li{display:grid; grid-template-columns:12rem minmax(0,1fr); gap:1.25rem;
  padding:.55rem 0; border-bottom:1px solid var(--rule-soft); align-items:baseline}
ul.api-modules-list li > a{text-decoration:none}
ul.api-modules-list li > a code{padding:0; background:none; font-size:.85rem; color:var(--accent)}
ul.api-modules-list li > a:hover code{text-decoration:underline}
ul.api-modules-list li > span{color:var(--ink-soft); font-size:.9rem; line-height:1.5}
@media (max-width:35rem){
  ul.api-modules-list li{grid-template-columns:minmax(0,1fr); gap:.15rem}
}

/* ---- one declaration: a heading row, the code, the prose ---- */
section.api-item{padding:1.6rem 0 1rem; border-top:1px solid var(--rule)}
.api-head{display:flex; flex-wrap:wrap; align-items:baseline; gap:.25rem .8rem;
  margin:0 0 .7rem}
h3.api-name{margin:0; font-size:1.1rem; line-height:1.3; font-weight:600;
  text-transform:none; letter-spacing:0}
h3.api-name code{padding:0; background:none; font-size:1em; color:var(--ink);
  text-transform:none; letter-spacing:0}
/*  Where it is declared, then the way back, apart: run together at the
    same faint size they read as one link.  */
.api-where{display:flex; flex-wrap:wrap; align-items:baseline; gap:.25rem 1.5rem;
  margin-left:auto}
a.api-source, a.api-back{font-family:var(--mono); font-size:.75rem; color:var(--ink-faint);
  text-decoration:none; white-space:nowrap}
a.api-source:hover, a.api-back:hover, a.api-source:focus-visible, a.api-back:focus-visible{
  color:var(--accent); text-decoration:underline}
@media (max-width:35rem){
  .api-where{flex-basis:100%; margin-left:0; justify-content:space-between}
}
.api-condition a.api-source{margin-left:.6rem}
.api-item .api-prose p{max-width:42rem}

/*  A declaration is one region that scrolls sideways; its members' `---`
    documentation is commentary between its lines, at their indentation.  */
.api-decl{margin:.3rem 0 .9rem; background:var(--code-bg);
  border:1px solid var(--code-rule, var(--rule))}
.api-decl > .scroller{margin:0; padding:.75rem 0}
pre.api-signature{margin:0; white-space:pre; font-size:.82rem; line-height:1.6; tab-size:4}
.api-decl pre.api-signature{padding:.15rem 1rem; overflow:visible}
.api-signature code{padding:0; background:none; border:0; font-size:1em}
/*  A name the declaration uses, quiet like the site's other linked code:
    its own colour with an accent underline, the accent only under the
    pointer or the keyboard.  */
.api-signature a{color:inherit; text-decoration:underline; text-decoration-style:dotted;
  text-decoration-thickness:1px; text-underline-offset:.22em;
  text-decoration-color:var(--accent-soft)}
.api-signature a:is(:hover,:focus-visible), .api-signature a:is(:hover,:focus-visible) span{
  color:var(--accent); text-decoration-style:solid; text-decoration-color:currentColor}
/*  Clear of the fade at the region's right edge, which is for the code.  */
.api-doc{max-width:42rem; margin:.35rem 2.75rem .6rem calc(1rem + var(--indent, 0) * 1ch);
  padding:0 0 0 .75rem; border-left:2px solid var(--rule); white-space:normal}
.api-doc p{margin:0 0 .3rem; max-width:40rem; font-family:var(--ui); font-size:.9375rem;
  line-height:1.55; color:var(--ink-soft)}
.api-doc p:last-child{margin-bottom:0}
.api-doc code{font-size:.85em}
/*  A source page's whole file.  */
main > pre.api-signature{padding:1rem; overflow-x:auto; background:var(--code-bg);
  border:1px solid var(--rule)}
/*  Inline blocks, not blocks: the newline between two blocks in a <pre>
    is a line of its own, and every source page was double-spaced.  */
.api-source-line{display:inline-block; min-width:100%}
.api-source-line:target{background:var(--accent-bg)}
.api-signature a.api-line-number{display:inline-block; min-width:4ch; margin-right:1.2em;
  color:var(--ink-faint); text-decoration:none; user-select:none}

/* ---- the overview's tables ---- */
.api-prose table.api-shaped{table-layout:fixed}
.api-prose table.api-shaped.short{table-layout:auto; width:auto; min-width:min(100%, 28rem)}
.api-prose table.short th, .api-prose table.short td{padding-right:2.5rem}
.api-prose table.api-shaped th[scope=row]{font-weight:600; color:var(--ink);
  border-bottom:1px solid var(--rule-soft); padding:7px 10px 7px 0; vertical-align:top}
.api-prose table.api-shaped tr:last-child th{border-bottom:0}
.api-prose .guide td code, .api-prose .guide th code{white-space:normal; overflow-wrap:break-word}
@media (max-width:48rem){
  .api-prose .guide td code, .api-prose .guide th code{overflow-wrap:anywhere}
}
/*  A phone stacks only a table whose columns cannot share its width (the
    generator marks it): each row a block, each cell, the first too,
    under its column's title.  */
@media (max-width:35rem){
  .api-prose table.api-stack, .api-prose table.api-stack tbody,
  .api-prose table.api-stack tr, .api-prose table.api-stack th[scope=row],
  .api-prose table.api-stack td{display:block; width:auto}
  .api-prose table.api-stack colgroup{display:none}
  .api-prose table.api-stack thead{position:absolute; width:1px; height:1px;
    overflow:hidden; clip-path:inset(50%)}
  .api-prose table.api-stack tr{padding:.55rem 0; border-bottom:1px solid var(--rule-soft)}
  .api-prose table.api-stack tr:last-child{border-bottom:0}
  .api-prose table.api-stack th[scope=row], .api-prose table.api-stack td{
    border:0; padding:.05rem 0}
  .api-prose table.api-stack :is(th[scope=row], td)[data-label]:not([data-label=""])::before{
    content:attr(data-label); display:block;
    margin-top:.25rem; font-family:var(--mono); font-size:.68rem; font-weight:400;
    color:var(--ink-faint)}
  .api-prose table.api-stack th[scope=row]::before{margin-top:0}
  /*  A yes-or-no column is a small tag beside the row's name.  */
  .api-prose table.api-stack tr:has(td.api-flag){display:flex; flex-wrap:wrap;
    align-items:flex-end; column-gap:.6rem}
  .api-prose table.api-stack tr:has(td.api-flag) > *{flex:1 0 100%; order:2}
  .api-prose table.api-stack tr:has(td.api-flag) > th[scope=row]{flex:0 1 auto; order:0}
  .api-prose table.api-stack tr:has(td.api-flag) > td.api-flag{flex:0 0 auto; order:1; padding:0 .35rem;
    font-family:var(--mono); font-size:.7rem; color:var(--ink-soft);
    border:1px solid var(--rule)}
  .api-prose table.api-stack tr > td.api-flag[data-label]:not([data-label=""])::before{content:attr(data-label) ": ";
    display:inline; margin:0; font-size:1em}
}

/* ---- the values-by-target table ---- */
.api-table{border-collapse:collapse; font-size:.9rem}
.api-table th, .api-table td{text-align:left; padding:.25rem .8rem .25rem 0;
  border-bottom:1px solid var(--rule); vertical-align:top}
.api-table th[scope=row]{font-weight:600; font-family:var(--mono); font-size:.85rem}
.api-table tr:target{background:var(--accent-bg)}
.api-table td code, .api-table th code{white-space:nowrap}

/* ---- the example: the site's program panel ---- */
figure.panel.api-program{margin:1rem 0 0}

/*  Paper is light whatever the screen was: the dark values printed pale
    ink on white.  */
@media print{
  :root, :root:has(#theme:checked), :root:not(:has(#theme:checked)){
    color-scheme:light;
    --bg:#fff; --bg-soft:#fff; --panel:#fff; --panel-2:oklch(0.96 0.005 85);
    --ink:#000; --ink-soft:oklch(0.3 0.015 255); --ink-faint:oklch(0.42 0.015 250);
    --rule:oklch(0.8 0.01 85); --rule-soft:oklch(0.88 0.01 85); --rule-strong:oklch(0.6 0.01 85);
    --accent:oklch(0.45 0.15 30); --accent-soft:oklch(0.6 0.1 30); --accent-bg:#fff;
    --code-bg:#fff; --term-bg:#fff; --term-ink:#000;
    --k:oklch(0.42 0.1 350); --t:oklch(0.42 0.1 190); --f:oklch(0.42 0.1 260);
    --n:oklch(0.42 0.1 300); --q:oklch(0.42 0.1 130); --b:oklch(0.42 0.1 60);
    --cd:oklch(0.42 0.06 140); --d:#000; --c:oklch(0.42 0.015 250); --o:oklch(0.42 0.015 250);
  }
  @page{margin:18mm 16mm}
  header.bar, nav.side, .listing .copy, footer .totop, nav.next, #pop{display:none}
  body{background:#fff; color:#000}
  .wrap{display:block}
  main{max-width:42rem; padding:0}
  .listing pre, pre.sample{white-space:pre-wrap; padding-right:1rem}
  .overflows{-webkit-mask-image:none; mask-image:none}
  a{color:inherit}
  h1, h2, h3, .item > .tag{break-after:avoid}
  .item > h3, .listing, figure.panel{break-inside:avoid}
  .guide ul:not([class]){list-style:square; padding-left:1.2rem}
  .guide ul:not([class]) > li::before{display:none}
  .item:target::before, .item.lit::before{display:none}
  label.scrim{display:none}
  footer{margin:2rem 0 0}
}
