/* Tokens that are the site's own. Palette-derived tokens live in palette.css. */
:root {
  --ground: #fbfbfb;
  --ink: #1a1a1a;
  --rule: #1a1a1a;
  /* Mona Sans and Monaspace Neon are drawn to the same x-height, so code
     needs almost none of the customary setting down. Measured in the
     browser 2026-09-09, at a nominal 17px: x-heights 8.92 and 8.73, cap
     heights 12.39 and 12.41, ten glyphs 98.95pt and 105.41pt wide. The
     step left is for the width, not the height. */
  --code-size: 0.95em;
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root {
    --ground: #151515;
    --ink: #dcdcdc;
    --rule: #dcdcdc;
    color-scheme: dark;
  }
}

/* Fonts */
@font-face {
  font-family: "Mona Sans";
  font-style: normal;
  font-display: swap;
  font-weight: 200 900;
  src: url(fonts/mona-sans-latin-wght-normal.woff2) format("woff2-variations");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Mona Sans";
  font-style: normal;
  font-display: swap;
  font-weight: 200 900;
  src: url(fonts/mona-sans-latin-ext-wght-normal.woff2) format("woff2-variations");
  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 {
  font-family: "Monaspace Neon";
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(fonts/monaspace-neon-latin-400-normal.woff2) format("woff2");
}
@font-face {
  font-family: "Monaspace Neon";
  font-style: italic;
  font-display: swap;
  font-weight: 400;
  src: url(fonts/monaspace-neon-latin-400-italic.woff2) format("woff2");
}

/* Type */
html {
  font-family: "Mona Sans", system-ui, sans-serif;
  font-size: 17px;
  line-height: 1.6;
  font-weight: 450;
  font-variant-numeric: oldstyle-nums;
  background: var(--ground);
  color: var(--ink);
  counter-reset: sidenote;
}
body { margin: 0; }
.page { max-width: 1100px; padding: 2.5rem 4rem 4rem; }
article { max-width: 66ch; }
p { margin: 0 0 1.1rem; text-wrap: pretty; }
h1, h2, h3 { text-wrap: balance; line-height: 1.25; }
h1 { font-size: 1.6rem; font-weight: 700; margin: 2.2rem 0 0.3rem; }
h2 { font-size: 1.25rem; font-weight: 700; font-style: italic; margin: 2.6rem 0 0.6rem; }
h3 { font-size: 1.0625rem; font-weight: 600; font-style: italic; margin: 1.8rem 0 0.4rem; }
.subtitle, h1 + p > em:only-child, article > p:first-child > em:only-child { font-style: italic; color: var(--ink-soft); }
h1 + p { margin-bottom: 2rem; }
article > p:first-child { margin: 2.2rem 0 2rem; }

/* Permalink: a quiet pilcrow that surfaces only when its heading is
   hovered or focused, so a reader can grab the anchor without it
   sitting beside every heading the rest of the time. */
.headerlink {
  opacity: 0;
  margin-left: 0.3em;
  font-weight: 400;
  font-style: normal;
  color: var(--ink-soft);
  transition: opacity 0.12s;
}
h1:hover > .headerlink, h2:hover > .headerlink, h3:hover > .headerlink,
.headerlink:focus { opacity: 0.55; }
a { color: var(--link); text-decoration: none; }
a:hover { color: var(--link-hover); }
hr { border: 0; height: 1px; background: var(--rule); margin: 3rem 0; }
blockquote { margin: 1.5rem 0 1.5rem 2.5rem; font-style: italic; }
blockquote footer { font-style: normal; font-size: 0.9em; text-align: right; }
ul, ol { padding-left: 1.4rem; }
li { margin-bottom: 0.3rem; }

/* Nav: the site, its sections, the page, a size apart at each step.
   The current one is marked in the link colour and by a rule set clear
   of the descenders, so the mark does not rest on colour alone. */
.brand {
  display: inline-block;
  font-size: 1.2rem; font-weight: 700; letter-spacing: 0.02em;
  color: var(--ink);
  margin-bottom: 0.8rem;
}
nav { display: flex; flex-wrap: wrap; gap: 0.8rem 1.6rem; align-items: baseline; font-size: 0.95rem; }
nav a { color: var(--ink); }
nav a.current {
  color: var(--link);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.3em;
}
nav.siblings { margin-top: 0.6rem; font-size: 0.85rem; color: var(--ink-soft); }
nav.siblings a { color: var(--ink-soft); }
nav.siblings a.current { color: var(--link); }
/* Last, so it outranks the sibling row's quieter ink at equal weight. */
nav a:hover, nav a.current:hover { color: var(--link-hover); }

/* The repo link is a mark, not a section: an icon among the words says so
   without needing a place of its own. It takes the nav's ink, so the dark
   ground turns it over with everything else. */
.repo { align-self: center; display: flex; }
.repo svg { width: 1.05em; height: 1.05em; }

/* Sidenotes */
.sidenote-number { counter-increment: sidenote; }
.sidenote-number::after, .sidenote::before {
  content: counter(sidenote);
  font-size: 0.75em;
  font-variant-numeric: lining-nums;
  position: relative; top: -0.45em; vertical-align: baseline;
}
.sidenote-number::after { margin-left: 0.1em; }
.sidenote::before { margin-right: 0.35em; }
.sidenote {
  float: right; clear: right;
  margin-right: -52%; width: 42%;
  margin-top: 0.3rem; margin-bottom: 0;
  font-size: 0.85rem; line-height: 1.45;
  color: var(--ink-soft);
}
.sidenote p { display: inline; margin: 0; }

/* Figures */
figure { margin: 2rem 0; display: flow-root; }
figure svg, figure img { display: block; width: 100%; height: auto; }
figcaption { font-size: 0.85rem; line-height: 1.45; color: var(--ink-soft); margin-top: 0.5rem; }
figcaption p { margin: 0; }
@media (min-width: 1001px) {
  figure svg, figure img { float: left; width: 100%; }
  figcaption { float: right; clear: right; margin-right: -52%; width: 42%; margin-top: 0; }
}

/* Tables */
.table-scroll { overflow-x: auto; margin: 1.5rem 0 2rem; }
table { border-collapse: collapse; font-size: 0.95rem; font-variant-numeric: tabular-nums; }
th, td { text-align: left; padding: 0.25rem 1.2rem 0.25rem 0; font-weight: normal; vertical-align: top; }
th { border-bottom: 1px solid var(--rule); font-style: italic; }

/* The palette sheet: a scheme per group, its name over blocks of colour
   with the name to type under each. The block carries the colour and the
   name reads at reading size, so the thing you scan by and the thing you
   copy are both doing their own job. Every block is as wide as the
   longest name, since one sized to its own name would give light_yellow
   four times the colour of red and mean nothing by it.

   Wider than the measure, into the sidenote margin, like a code block.
   Capped at the viewport less the page's 4rem of padding each side, plus
   a rem for a scrollbar, so a window too narrow for the full width drops
   a column instead of running off the edge. */
.palettes {
  width: calc(100% + 45%);
  max-width: min(calc(100% + 45%), calc(100vw - 9rem));
  margin: 2rem 0 2.4rem;
}
.palettes dt { margin: 0 0 0.6rem; }
.palettes dd { margin: 0 0 2.2rem; }
.palettes dd:last-of-type { margin-bottom: 0; }
.palettes ul {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 0.7rem;
}
.palettes li { display: flex; flex-direction: column; align-items: stretch; }
/* The measure is set on the name, whose own font makes ch the right unit;
   the block above stretches to whatever that comes to. */
.palettes li code { min-width: 13ch; text-align: center; padding-top: 0.25rem; }
.palettes .swatch {
  height: 2.2em; border-radius: 2px;
  /* The frame ink as a hairline, so a colour that matches the page ground
     still reads as a block: pale yellow on white, dark blue on black.
     Inset, so the ring costs no width. */
  box-shadow: inset 0 0 0 1px var(--ink-line);
}

/* Code: blocks on the page ground, no box, and they may run into the
   margin; an indent, air and syntax colour already set them apart. A name
   in a sentence gets a tint of the ink into the ground, since the two
   faces share an x-height and the face alone did not mark it. */
code, pre {
  font-family: "Monaspace Neon", ui-monospace, Menlo, monospace;
  font-size: var(--code-size);
  font-feature-settings: "calt", "liga";
}
:not(pre) > code {
  background: color-mix(in srgb, var(--ink) 6%, var(--ground));
  padding: 0.05em 0.3em;
  border-radius: 3px;
}
/* Apparatus that is all code, the palette sheet and a parameter list, sets
   code as structure rather than as a name among words, and a box under
   every entry would say nothing. */
.palettes code, .doc-section-item > code, .doc-section-item > b > code, .doc-annotation code {
  background: none;
  padding-inline: 0;
}
pre {
  margin: 1.4rem 0 1.6rem 1.5rem;
  line-height: 1.5;
  color: var(--ink);
  overflow-x: auto;
  width: max-content;
  max-width: calc(100% + 45%); /* the measure plus the sidenote margin */
}
.highlight { background: none; }

/* mkdocstrings (markup verified: material templates under a nameless theme)
   Each rank gets its own instrument rather than a wider gap: a size for the
   member name, an indent for the signature and the arguments it takes, air
   for the section label. */
.doc-heading { margin-top: 3rem; }
/* One member ends where the next begins, and space alone cannot say so
   on a page that spaces everything. A rule can; the border stops the
   heading's margin collapsing through, so the air below it is set to
   match the air above, seating the hairline midway. */
.doc-object + .doc-object { border-top: 1px solid var(--rule); margin-top: 2.4rem; }
.doc-object + .doc-object > .doc-heading { margin-top: 2.4rem; }
/* A method parts from a method less than a class parts from a class, so
   the rule between them takes the quieter ink and less air, as the two
   heading ranks above it already do. */
.doc-children .doc-object + .doc-object { border-top-color: var(--ink-soft); margin-top: 1.75rem; }
.doc-children .doc-object + .doc-object > .doc-heading { margin-top: 1.75rem; }
.doc-heading .doc-object-name { font-family: "Monaspace Neon", ui-monospace, monospace; font-style: normal; font-size: 1.1em; }
.doc-signature { margin-left: 0; }
.doc-signature pre { margin-left: 1.5rem; margin-top: 0.5rem; }
/* The label is a span inside a paragraph, and vertical margins do not apply
   to an inline box, so the paragraph is the one that can carry the air. It
   leans on what follows: the list is its own, the prose above is not. */
p:has(> .doc-section-title) { margin: 1.9rem 0 0.35rem; }
.doc-section-title { color: var(--ink); font-weight: 800; }
/* An entry is a name and its gloss; the parentheses and the default are
   apparatus, and take the quieter ink. The dash that once joined the two
   is the entry's only uncoloured text, so it drops against the ground and
   leaves the gloss to open its own line. */
.doc-section-item { list-style: none; margin: 0 0 1.1rem 1.5rem; color: transparent; }
.doc-section-item > b, .doc-section-item .doc-md-description { color: var(--ink); }
/* A return has no name, so its type stands in the name's place and takes
   the name's ink. */
.doc-section-item > code:first-child { font-weight: 600; color: var(--ink); }
/* mkdocstrings sets only the type and the default as code, leaving the
   parentheses, the comma and the word "default:" bare, so the fragment
   alternates faces. docs_hooks.type_annotations wraps it to be set in one. */
.doc-annotation { font-family: "Monaspace Neon", ui-monospace, Menlo, monospace; font-size: var(--code-size); color: var(--ink-soft); }
.doc-annotation code { font-size: 1em; }
/* The description drops onto its own line under the name and type. */
.doc-md-description { display: block; margin-top: 0.1rem; }
.doc-md-description p { display: inline; margin: 0; }
.doc-contents ul { padding-left: 0; }
.admonition { margin: 1.4rem 0; }
.admonition-title { font-style: italic; color: var(--ink-soft); display: inline; margin-right: 0.4em; }
.admonition-title::after { content: "."; }
.admonition > p { display: inline; }

/* Reference pages carry a table of contents in the right margin, where
   prose pages float their sidenotes. align-items keeps the list its own
   height so it can ride along, sticky, as the reader scrolls a long page
   of functions. */
.with-toc {
  display: grid;
  grid-template-columns: minmax(0, 66ch) 1fr;
  column-gap: 2.5rem;
  align-items: start;
}
/* The margin here is the TOC's, so a wide signature stays in the measure
   and scrolls rather than spilling under the list, as code does elsewhere. */
.with-toc pre { max-width: 100%; }
/* margin-top seats the list level with the h1, which carries the same top
   margin; top is the offset it sticks at once the h1 scrolls past. */
.page-toc { position: sticky; top: 2.5rem; margin-top: 2.2rem; font-size: 0.85rem; line-height: 1.4; }
.page-toc ul { list-style: none; margin: 0; padding: 0; }
.page-toc li { margin-bottom: 0.45rem; }
.page-toc a { color: var(--ink-soft); }
.page-toc a:hover { color: var(--link-hover); }

.colophon { margin-top: 5rem; font-size: 0.8rem; color: var(--ink-soft); }
.colophon a { color: var(--ink-soft); }

/* Narrow screens */
@media (max-width: 1000px) {
  .page { padding: 1.5rem 1.25rem 3rem; }
  .sidenote { float: none; display: block; width: auto; margin: 0.5rem 0 0.9rem 1.5rem; }
  pre { width: auto; max-width: 100%; margin-left: 0; }
  /* No sidenote margin to borrow, so the colours wrap in the measure. */
  .palettes { width: 100%; max-width: 100%; }
  /* The class rule beats the bare pre above it, so the signature needs
     naming to go flush with the rest of the code. */
  .doc-signature pre { margin-left: 0; }
  /* No margin to ride in, so the reference TOC steps aside and the top
     nav carries the page. */
  .with-toc { display: block; }
  .page-toc { display: none; }
}
