/* The program's stylesheet. It began as md2html-default's and is the program's
own now; the light palette is the user's design. */
/* The page colours. The syntax colours below are pandoc's. */
:root {
color-scheme: light dark;
--page: #f6f6f6;
--text: #1a1a1a;
--muted: #666666;
--rule: #cccccc;
--danger: #902000;
--target: #fff3b0;
--gutter: #aaaaaa;
--faint: #b8b8b8;
--added: #e4f2e4;
--removed: #f8e6e2;
--added-strong: #bfe0bf;
--removed-strong: #efc6bc;
--shadow: #a8a8a8;
--light: #ffffff;
--shade: #ebebeb;
}
/* The dark palette, a draft by the model for the user to adjust. Text is
light grey on near black, not white on black, so a long read does not
glare; each tint keeps the role it has in the light palette. */
@media (prefers-color-scheme: dark) {
:root {
--page: #1c1c1c;
--text: #d6d6d6;
--muted: #999999;
--rule: #3d3d3d;
--danger: #e07a5a;
--target: #4a4020;
--gutter: #5e5e5e;
--faint: #555555;
--added: #1f3322;
--removed: #3b2420;
--added-strong: #2f5934;
--removed-strong: #6a3a30;
--shadow: #050505;
--light: #3a3a3a;
--shade: #111111;
}
}
/* The fonts come from the machine when installed, else from the
program's subsets, which assets/fonts.css declares; never from the
network. The mono stack leaves out ui-monospace, which is SF Mono on a
Mac, so mono looks the same on every system. */
/* The header holds still from page to page: every page keeps one width,
and the scrollbar's space is kept on short pages too, so the centred
column does not shift when a long page brings a scrollbar. */
/* A jump to a line or heading stops below the search row, which the
script measures into --search-h. */
html { background: var(--page); scrollbar-gutter: stable; scroll-padding-top: var(--search-h, 0); }
body {
max-width: 58ch;
margin: 2em auto;
background: var(--page);
color: var(--text);
font-family: "STIX Two Text", "STIX Two Text web", Georgia, serif;
font-size: clamp(16px, 3.0vw, 38px);
line-height: 1.2;
text-align: justify;
hyphens: auto;
padding: 0 1em;
}
/* Every gap between blocks is the same, whether the block is a paragraph,
list, table or code. Headings sit close to their text. */
p, ul, ol, table, div.sourceCode { margin: 0.7em 0; }
li > ul, li > ol { margin: 0; }
h1, h2, h3, h4, h5, h6 {
font-family: "STIX Two Text", "STIX Two Text web", Georgia, serif;
font-weight: bold;
text-align: left;
hyphens: none;
margin-top: 0.7em;
margin-bottom: 0.2em;
}
h1 { font-size: 1.3em; }
h2 { font-size: 1.1em; }
h3 { font-size: 1em; font-style: italic; font-weight: normal; }
/* :is(*, div.sourceCode) outranks the div.sourceCode rule. */
:is(h1, h2, h3, h4, h5, h6) + :is(*, div.sourceCode) { margin-top: 0.1em; }
blockquote {
margin: 0.7em 0 0.7em 2em;
padding-left: 1em;
border-left: 2px solid currentColor;
opacity: 0.75;
}
/* An alert asks to be read, so it keeps full strength; its label is the program's
word for the [!KIND] marker. */
blockquote.alert { opacity: 1; }
p.own.alert { margin-bottom: 0.2em; }
p.own.alert + * { margin-top: 0; }
@media (pointer: coarse), (max-width: 768px) {
body { max-width: 100%; }
}
/* Page chrome, code, tables, listings */
/* raw and the stop button keep one place, top right: long crumbs wrap in
their own column. Only a phone, too narrow for both, drops the buttons
to a line of their own, still at the right. */
header {
display: flex;
justify-content: space-between;
align-items: baseline;
gap: 0.5em 1em;
text-align: left;
hyphens: none;
font-size: 0.8em;
border-bottom: 1px solid var(--rule);
padding-bottom: 0.6em;
margin-bottom: 1.5em;
}
header nav { flex: 1 1 auto; min-width: 0; }
/* The build stamp sits above the header, small and faint, so a glance
tells which build served the page. */
p.built { font-size: 0.45em; color: var(--faint); margin: -1.6em 0 0.6em; text-align: left; }
/* A crumb, or a name in a path on the index, stays whole: lines break
between names, after the slash, and inside a name only when it alone is
wider than the column. */
header nav > *, .seg { display: inline-block; max-width: 100%; overflow-wrap: anywhere; }
/* A box does not take its link's underline unless asked. */
.seg { text-decoration: inherit; }
@media (max-width: 480px) {
header { flex-wrap: wrap; }
}
header > span { display: inline-flex; gap: 1em; align-items: baseline; flex: none; margin-left: auto; }
header form { display: inline; }
/* Buttons are flat, as on printed paper: one border in the text's
colour, square corners, no bevel. */
header button, table.locks button, p.bug button.bug {
font: inherit;
color: inherit;
background: var(--page);
border: 1px solid var(--text);
border-radius: 0;
padding: 0.15em 0.7em;
cursor: pointer;
white-space: nowrap;
}
/* The bug button sits at the page's foot, flat as every button is, but
small, faint and with little padding, so it never draws the eye from
the page. After a report, a field beside it takes a comment. */
p.bug { font-family: "Iosevka", "Iosevka web", monospace; font-size: 0.45em; color: var(--faint); text-align: right; margin: 3em 0 0; }
p.bug button.bug { color: inherit; border-color: currentColor; padding: 0 0.4em; }
p.bug input { font: inherit; color: var(--text); background: var(--page); border: 1px solid var(--faint); border-radius: 0; padding: 0 0.4em; margin-right: 0.6em; width: 30ch; max-width: 60%; }
/* What the program says, marked own, is mono, file names in a listing included; what the
document says is serif. */
pre, code, header, div.search, .own, ul.listing, p.built, div.found p, p.unfound, table.gone { font-family: "Iosevka", "Iosevka web", monospace; }
/* Mono shows each character as typed: Iosevka's ligatures, eg <= drawn
as one sign, are off wherever mono is set. Serif text keeps its own. */
pre, code, header, div.search, .own, ul.listing, p.built, div.found p, p.unfound, table.gone,
p.bug, main a.web, ul.decls, p.coin, .lead, div.view, div.syntax { font-variant-ligatures: none; }
/* Code is half the body size, so about 115 columns fit the doc's measure
and no page needs to be wider. It never drops below 11px, where small
screens set the body at 16px. */
/* A code block has no margin of its own, since its em is half the body's:
the blocks around it make the gap. */
pre {
margin: 0;
font-size: max(0.5em, 11px);
line-height: 1.35;
text-align: left;
hyphens: none;
overflow-x: auto;
}
:not(pre) > code { font-size: 0.85em; }
table { border-collapse: collapse; }
th, td { border-bottom: 1px solid var(--rule); padding: 0.2em 0.6em; text-align: left; }
img { max-width: 100%; }
/* A graph dot drew sits centred and never wider than the column. dot draws
in black on a white sheet; the page's own colours replace both, so a
graph reads in either theme. */
div.graph { margin: 0.7em 0; text-align: center; }
div.graph svg { max-width: 100%; height: auto; }
div.graph svg polygon[fill="white"] { fill: none; }
div.graph svg [stroke="black"] { stroke: var(--text); }
div.graph svg [fill="black"] { fill: var(--text); }
div.graph svg text { fill: var(--text); font-family: "STIX Two Text", "STIX Two Text web", Georgia, serif; }
ul.listing { list-style: none; padding: 0; text-align: left; }
ul.listing li { padding: 0.075em 0; overflow-wrap: anywhere; }
/* A row is one target: its link covers the whole row, the words beside it
and the space to its right included, so where on the row a click lands
does not matter. Padding, not margin, spaces the rows, so no gap
between them is dead. A button in the row, eg Delete lock, sits above. */
ul.listing li, ol.versions > li, div.backlinks li, table.locks tr { position: relative; }
ul.listing li > a:first-child::after, ol.versions > li > a::after, div.backlinks li > a::after,
table.locks td:first-child > a::after { content: ""; position: absolute; inset: 0; }
table.locks form { position: relative; z-index: 1; }
ul.listing li:hover > a, ol.versions > li:hover > a, div.backlinks li:hover > a, table.locks tr:hover a { text-decoration-color: currentColor; }
/* The program's own links, in the header, listings and the index, are quiet,
not lost: the text colour with a faint underline, which tells a link
from the current crumb or a refused entry on a share. The underline
turns full under the pointer, and a visited link turns grey. */
/* A link in a document keeps the text colour and a grey underline, dark
enough to find among words. Visited, the underline fades; the words
stay readable. */
main a { color: inherit; text-decoration-color: var(--muted); }
main a:visited { text-decoration-color: var(--rule); }
main a:hover { text-decoration-color: currentColor; }
/* A link whose target is missing keeps its words and wears a dotted
underline in the danger colour; its title names the missing path. */
main a.broken { text-decoration-style: dotted; text-decoration-color: var(--danger); }
/* The mark after a forge link reads that repo on the web address. */
main a.web { font-family: "Iosevka", "Iosevka web", monospace; font-size: 0.6em; vertical-align: super; line-height: 0; margin-left: 0.2em; color: var(--muted); text-decoration: none; }
main a.web:hover { color: inherit; }
header a, ul.listing a, table.gone a, table.locks a, .latest a, .own a { color: inherit; text-decoration-color: var(--rule); }
header a:visited, ul.listing a:visited, table.gone a:visited, table.locks a:visited, .latest a:visited, .own a:visited { color: var(--muted); }
header a:hover, ul.listing a:hover, table.gone a:hover, table.locks a:hover, .latest a:hover, .own a:hover { text-decoration-color: currentColor; }
ul.listing li.refused span { color: var(--muted); font-size: 0.8em; }
/* A history: hash and date are the program's and mono, subject and body the
author's and serif. A page's top line leads to its history. */
/* Each commit is a fold: one line closed, message and diff open. */
ol.log { list-style: none; padding: 0; }
ol.log > li { margin: 0 0 0.4em; }
ol.log summary { cursor: pointer; text-align: left; }
ol.log summary > .own { color: var(--muted); font-size: 0.8em; }
ol.log details[open] { margin-bottom: 2em; }
ol.log details > p { margin: 0.45em 0 0.45em 1.2em; text-align: left; }
ol.log div.diffs > p.own:only-child, ol.log p.links { margin-left: 1.2em; }
ol.log p.links { color: var(--muted); font-size: max(0.5em, 11px); }
div.commit p.subject { font-weight: bold; margin-top: 0.2em; }
div.commit p { text-align: left; }
div.commit p.own { color: var(--muted); margin-bottom: 0; }
/* A commit's diff: added and removed lines on a faint tint, git's own
lines muted. */
p.file { margin: 2em 0 0.3em; }
/* Each line is a block, so its tint spans the page. */
pre.diff span { display: block; min-height: 1.35em; }
pre.diff span.add { background: var(--added); }
pre.diff span.del { background: var(--removed); }
pre.diff span.hunk, pre.diff span.meta { color: var(--muted); }
/* The tokens a changed line changed, on a stronger tint. */
pre.diff mark { color: inherit; }
pre.diff span.add mark { background: var(--added-strong); }
pre.diff span.del mark { background: var(--removed-strong); }
/* The declarations a commit changed, one row each under its file. */
div.semantic { margin-top: 1.5em; }
div.semantic p.file { margin: 1em 0 0.2em; }
ul.decls { list-style: none; padding: 0; margin: 0; font-family: "Iosevka", "Iosevka web", monospace; font-size: max(0.5em, 11px); line-height: 1.35; text-align: left; }
ul.decls span.what { color: var(--muted); display: inline-block; min-width: 9ch; }
/* A page's top line names its commit and opens the timeline, the menu
of its versions, which drops over the page and scrolls on its own. The
version shown is marked. */
details.latest { position: relative; margin-bottom: 2em; border-bottom: 1px solid var(--rule); padding-bottom: 0.6em; color: var(--muted); }
/* The top line keeps the browser's disclosure marker, ▸ closed and ▾
open, so a line that says only current still shows that it opens. */
details.latest > summary { cursor: pointer; }
details.latest a, details.latest span.subject, details.latest span.state { color: var(--text); }
details.latest > summary:hover span.state { text-decoration: underline; text-decoration-color: var(--rule); }
/* On a version, the link to the page as it is sits at the top line's
right end, outside the line's one target. */
a.now { float: right; position: relative; z-index: 1; margin-left: 1em; font-size: max(0.5em, 11px); }
details.latest > summary:hover span.subject { text-decoration: underline; text-decoration-color: var(--rule); }
details.latest > div.versions, details.latest > ol.versions { position: absolute; z-index: 1; top: 100%; left: 0; margin: 0;
max-height: 60vh; overflow-y: auto; min-width: 20em; max-width: 100%; padding: 0.4em 0; list-style: none;
background: var(--page); border: 1px solid var(--text); }
details.latest > div.versions { padding: 0.4em 0.8em; }
ol.versions > li { padding: 0.15em 0.8em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
ol.versions > li.here { background: var(--target); }
ol.versions > li.log { border-top: 1px solid var(--rule); margin-top: 0.3em; padding-top: 0.3em; }
/* An error reads at a listing's size, not code's. It wraps, so it needs
no scroll box, which a pre has by default. */
pre.error { white-space: pre-wrap; font-size: inherit; line-height: inherit; overflow: visible; }
/* A 404's table: a lead column of labels, then values that wrap beside
it, so a long URL or subject keeps its column. Rows are spaced as a
listing's. */
table.gone { margin: 0; text-align: left; }
table.gone th, table.gone td { border: 0; padding: 0.075em 0; vertical-align: top; text-align: left; font-weight: normal; }
table.gone th { padding-right: 1em; white-space: nowrap; }
/* A missing path's 404 turns like a coin: the digits go edge-on and back,
slow down, rock once and stop facing the reader. Each face is text. */
p.coin { margin: 0.2em 0 0.1em; line-height: 1; text-align: center; perspective: 18em; font-family: "Iosevka", "Iosevka web", monospace; font-size: 6em; color: var(--text); }
p.coin > span { display: inline-grid; transform-style: preserve-3d; animation: coin 2.4s cubic-bezier(.12,.62,.25,1) both; }
p.coin > span > span { grid-area: 1 / 1; backface-visibility: hidden; }
p.coin > span > span + span { transform: rotateY(180deg); }
@keyframes coin {
0% { transform: rotateY(0); }
82% { transform: rotateY(1818deg); }
91% { transform: rotateY(1792deg); }
100% { transform: rotateY(1800deg); }
}
/* While git reads a repo, its page names each step git takes and the
dots after "reading" keep moving, so a slow clone shows it is alive. */
pre.steps { white-space: pre-wrap; color: var(--muted); }
p.reading::after { content: "..."; display: inline-block; vertical-align: bottom; overflow: hidden; width: 0; animation: dots 1.2s steps(4, jump-none) infinite; }
@keyframes dots { to { width: 3ch; } }
@media (prefers-reduced-motion: reduce) { p.reading::after { animation: none; width: 3ch; } }
ul.listing .desc { color: var(--muted); font-size: 0.8em; margin-left: 1em; }
header .age { color: var(--muted); }
/* Kill server reaches every tree, so it alone wears the danger colour. */
header button.kill { background: var(--danger); border-color: var(--danger); color: var(--page); }
p.own { font-size: 0.8em; text-align: left; hyphens: none; }
p.own code { font-size: inherit; }
h2.own { font-size: 0.8em; font-weight: normal; color: var(--muted); margin-top: 2.5em; }
table.locks { font-size: 0.8em; width: 100%; }
table.locks td { overflow-wrap: anywhere; vertical-align: baseline; }
table.locks td:first-child { padding-left: 0; }
table.locks td:last-child { padding-right: 0; }
table.locks td:first-child:last-child { padding-right: 0; }
table.locks td:first-child { width: 100%; }
table.locks .since { white-space: nowrap; color: var(--muted); margin-left: 1em; }
/* In a list, a field of fixed form, a stardate, hash, time or size,
leads its row, so it lines up down the list even where the natural
order would put it last. The server sets the list's --lead to its
longest label; numbers align right. */
.lead { display: inline-block; min-width: var(--lead, 0); margin-right: 0.6em; font-family: "Iosevka", "Iosevka web", monospace; white-space: nowrap; }
table.locks .lead { margin: 0 1em 0 0; }
.lead.num { text-align: right; }
table.locks td + td { text-align: right; }
table.locks form { display: inline; }
/* A block that changed with the last save fills with the target colour
and fades to none in 3 s, so the eye finds where the change landed. */
main > .changed { animation: changed 3s ease-in; }
@keyframes changed { from { background-color: var(--target); } to { background-color: transparent; } }
/* The search box has a row of its own under the header and leaves the
row's right end to the button that copies the page's text and the one
that copies a link. All three are flat, as on printed paper: one
border in the text's colour, square corners, the page's colour inside.
The box holds the keyboard on every page, so focus changes nothing. */
div.search {
display: flex;
gap: 1em;
align-items: stretch;
margin: -1em 0 1.2em;
padding: 0.3em 0;
font-size: 0.8em;
/* The row follows the page down: it sticks to the window's top, on
the page's colour so text scrolls under it, and the box, copy and
share stay at hand. */
position: sticky;
top: 0;
z-index: 1;
background: var(--page);
}
input.search, button.copy, button.share {
font: inherit;
border: 1px solid var(--text);
border-radius: 0;
}
input.search {
flex: 1 1 auto;
min-width: 0;
color: inherit;
background: var(--page);
padding: 0.15em 0.4em;
}
input.search:focus { outline: none; }
span.tools { display: flex; gap: 1em; flex: none; }
button.copy, button.share {
flex: none;
color: inherit;
background: var(--page);
padding: 0.15em 0.7em;
cursor: pointer;
white-space: nowrap;
}
button.copy:focus-visible, button.share:focus-visible { outline: none; }
/* Controls not needed fade out and keep their space, so the header holds
still: the box, copy and share, raw, the stop button and a code page's
views. The script marks the page calm; without it they stay. A faded
control takes no pointer, so nothing presses it unseen. The box keeps
the keyboard. The sticky rows turn clear too, so text scrolls through
them unhidden. */
input.search, span.tools, header > span > a, header form, div.view > * { transition: opacity 0.3s; }
div.search, div.view { transition: background-color 0.3s; }
html.calm :is(input.search, span.tools, header > span > a, header form, div.view > *) { opacity: 0; pointer-events: none; }
html.calm :is(div.search, div.view) { background-color: transparent; pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
input.search, span.tools, header > span > a, header form, div.view > *, div.search, div.view { transition: none; }
}
/* While the copy button reads the page's text, the program's own lines and links
leave the layout, so only the page's content is copied: a listing's
history and parent entries, a code page's view links and scope boxes,
which the text would count as breaks, and a 404's coin. Line numbers are generated
content, which the text never holds. */
body.copying main .own, body.copying main div.view, body.copying main div.backlinks,
body.copying main li.log, body.copying main li:has(> a[href="../"]), body.copying main i.scope, body.copying main a.web, body.copying main div.semantic, body.copying main p.coin { display: none; }
/* Search results: the path is the program's and mono, a matching line is
the file's and stays mono too, in the muted colour. */
div.found .line { color: var(--muted); font-size: 0.8em; hyphens: none; }
div.found p.note { color: var(--muted); font-size: 0.8em; margin-top: 0.8em; }
/* A page the box filters keeps its matching lines stacked, each with its
own number, and marks the matches. The directory's results follow a
blank line, dimmed as one block, so a visited link stays a step lighter
within it. hidden wins over any display a rule gives. */
[hidden] { display: none !important; }
pre.filtering > code.sourceCode { white-space: normal; }
pre.filtering > code.sourceCode > span { display: block; white-space: pre; }
pre.numberSource.filtering code > span > a:first-child::before { content: attr(data-n); }
::highlight(search) { background-color: var(--target); }
div.found ul.wider { opacity: 0.6; margin-top: 1.4em; }
div.found p.note:first-child { margin-top: 0; }
div.found ul.recent, div.found ul.web { margin-bottom: 1.4em; }
/* Below a doc, the docs that link to it, in the program's quiet voice. */
div.backlinks ul { list-style: none; padding: 0; text-align: left; font-size: 0.8em; }
div.backlinks li { padding: 0.075em 0; overflow-wrap: anywhere; }
p.unfound { color: var(--muted); font-size: 0.8em; }
/* The entry or match the keys act on shows a quiet ring, as does a link
Tab reached. */
.sel, ul.listing a:focus-visible { outline: 1px solid var(--muted); outline-offset: 0.15em; }
/* In a list the highlight frames the row a key would open, not the
link's words, since the whole row is the target. */
li:has(> a.sel), ul.listing li:has(> a:focus-visible) { outline: 1px solid var(--muted); outline-offset: 0.15em; }
ol.versions > li:has(> a.sel) { outline-offset: -1px; }
li > a.sel, ul.listing li > a:focus-visible { outline: none; }
/* The line that says the server is gone floats over the top of the page,
so nothing moves, and stays until a server answers. The one that says
a new server answered fades over three seconds. */
p.conn { position: fixed; top: 0; left: 50%; transform: translateX(-50%); z-index: 2; margin: 0; padding: 0.2em 0.8em;
background: var(--target); color: var(--text); font-size: 0.6em; white-space: nowrap; }
p.conn.fade { animation: conn 3s ease-in forwards; }
@keyframes conn { from { opacity: 1; } to { opacity: 0; } }
/* Technical background, what a page says about its data rather than the
data itself, is set at code size: half the body, never under 11px. It
follows the rules above, which set these at 0.8em. */
details.latest, ol.log summary > .own, div.commit > p.own, div.found p.note { font-size: max(0.5em, 11px); }
/* the line a #L42 link points at, and the lines a range such as #L10-L20 marks */
pre > code.sourceCode > span:target, pre > code.sourceCode > span.marked { background: var(--target); }
/* Pandoc's highlighting style, as pandoc 3.9 emits it for standalone HTML.
render.go emits the same markup and classes from chroma's tokens. */
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
/* The number sits in its line's padding, not before its text, so the
text starts where the line's tab stops start: a line with no leading
tab and a line indented by tabs share one grid of cells. Pandoc set the
number inline, 4em and 8px wide, which put untabbed text 8px off the
tab grid. The number stays inline, so an empty line keeps its height,
but a negative margin as wide as the number cancels its advance. */
pre.numberSource code > span
{ position: relative; margin-left: -4em; padding-left: calc(4em + 8px); counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block; margin-left: calc(-4em - 8px);
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: var(--gutter);
}
/* No rule between the numbers and the code; the space between them
suffices, and the padding takes the rule's pixel so the text stays put. */
pre.numberSource { margin-left: 3em; padding-left: 5px; }
/* Scopes: each block of code is a sunken box behind its text, like a
pressed Windows 3.1 button: shadow above and left, light below and
right. render.go places each box in its first line and sizes it in
cells and rows, so the boxes take no room and no character moves. A
line's text starts 4em and 8px into its span, past the line number, and a box
starts half a cell before its first row's text. A row is the pre's line
height, 1.35em, and a line's span sits 0.05em below its row's top, so a
box covers whole rows and its borders clear the glyphs. Boxes nest
without limit; deeper ones' edges fade, so the code stays readable.
Fills alternate: a box at an odd depth is shaded, one at an even depth
has the page's colour. Both are opaque, so each box hides the one
behind it and the page never darkens with depth. A leaf, a bracket pair
within a line, spans its brackets' cells and its whole row: brackets
fill nearly the row's height, so a shorter box would cut them. */
pre.scopes { isolation: isolate; }
/* A code page's views and raw link take a row of their own above the
code's top right corner and, once the page scrolls past it, stay just
under the search row until the code ends. The row has the code's size
and line height and the page's colour across its width, so a long
first line never runs under the links, and code scrolling beneath is
hidden a row at a time rather than mixed with them. */
div.code { margin: 0.7em 0; }
div.code > div.sourceCode { margin: 0; }
div.view { position: sticky; top: var(--search-h, 0); z-index: 1; text-align: right; background: var(--page);
font-family: "Iosevka", "Iosevka web", monospace; font-size: max(0.5em, 11px); line-height: 1.35; }
div.view a, div.view span { padding: 0 0.4em; margin-left: 0.4em; color: var(--muted); text-decoration-color: var(--rule); }
div.view span { color: inherit; }
div.view a:hover { text-decoration-color: currentColor; }
/* A JSON file's gron view starts at the row's left edge. */
div.view .left { float: left; margin-left: 0; padding-left: 0; }
/* Browsers round each row's height, so a box over hundreds of rows can
end a pixel or two past its last line; the scrolling div around the pre
clips that rather than grow a scroll bar. */
div.sourceCode:has(> pre.scopes) { overflow-y: hidden; }
pre.scopes i.scope {
position: absolute; z-index: -1;
left: calc(4em + 8px + (var(--c) - 0.5) * 1ch);
top: -0.05em;
width: calc((var(--w) + 1) * 1ch);
height: calc(var(--r) * 1.35em);
box-sizing: border-box;
--f: max(30%, 100% - (var(--d) - 1) * 15%);
border: 1px solid;
border-color: color-mix(in srgb, var(--shadow) var(--f), var(--page)) color-mix(in srgb, var(--light) var(--f), var(--page))
color-mix(in srgb, var(--light) var(--f), var(--page)) color-mix(in srgb, var(--shadow) var(--f), var(--page));
background: var(--page);
pointer-events: none;
}
pre.scopes i.scope.shade { background: var(--shade); }
pre.scopes i.scope.leaf {
left: calc(4em + 8px + var(--c) * 1ch);
width: calc(var(--w) * 1ch);
height: 1.35em;
}
pre.filtering i.scope { display: none; }
/* A syntax tree is nested folds, one row per named node: its field in
its parent, its kind, its text on one line and a link to its lines.
Each level indents by two cells beside a rule, so depth reads as on a
code page with scopes, and the text is code's size. */
div.syntax { font-family: "Iosevka", "Iosevka web", monospace; font-size: max(0.5em, 11px); line-height: 1.35; padding-top: 1.35em; }
div.syntax details > :not(summary) { margin-left: 2ch; padding-left: 1ch; border-left: 1px solid var(--rule); }
div.syntax > div, div.syntax details > div { padding-left: 2ch; }
div.syntax summary { cursor: pointer; }
div.syntax i { font-style: normal; color: var(--muted); }
div.syntax b { font-weight: normal; }
div.syntax code { color: var(--muted); font-size: 1em; }
div.syntax a { color: var(--gutter); text-decoration-color: var(--rule); margin-left: 0.5ch; }
div.syntax a:hover { text-decoration-color: currentColor; }
/* A box is a link to its lines. The box under the pointer is tinted with
the target colour and its edges show at full strength, so it shows
what a click marks; a marked box and the boxes in it fill with the
target colour, their edges kept, so the block stays one shape. */
pre.scopes i.scope.hover { --f: 100%; background: color-mix(in srgb, var(--target) 45%, var(--page)); }
pre.scopes i.scope.shade.hover { background: color-mix(in srgb, var(--target) 45%, var(--shade)); }
pre.scopes i.scope.marked, pre.scopes i.scope.shade.marked { background: var(--target); }
div.sourceCode
{ }
/* A number links to its line, eg #L42; it shows as a link on hover. */
@media screen {
pre > code.sourceCode > span > a:first-child:hover::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { color: #008000; } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { color: #008000; font-weight: bold; } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
/* Pandoc's roles in the dark palette: each colour is the light one's hue,
lifted to read on the dark page. */
@media (prefers-color-scheme: dark) {
code span.al { color: #ff6b6b; }
code span.an { color: #7fa9b5; }
code span.at { color: #b5c46a; }
code span.bn { color: #7fc4a0; }
code span.bu { color: #82c482; }
code span.cf { color: #8fc47f; }
code span.ch { color: #8fb3d9; }
code span.cn { color: #e48080; }
code span.co { color: #7fa9b5; }
code span.cv { color: #7fa9b5; }
code span.do { color: #e07070; }
code span.dt { color: #e0906e; }
code span.dv { color: #7fc4a0; }
code span.er { color: #ff6b6b; }
code span.fl { color: #7fc4a0; }
code span.fu { color: #8eaaf0; }
code span.im { color: #82c482; }
code span.in { color: #7fa9b5; }
code span.kw { color: #8fc47f; }
code span.op { color: #999999; }
code span.ot { color: #8fc47f; }
code span.pp { color: #d9a85a; }
code span.sc { color: #8fb3d9; }
code span.ss { color: #d494b4; }
code span.st { color: #8fb3d9; }
code span.va { color: #a9a8f0; }
code span.vs { color: #8fb3d9; }
code span.wa { color: #7fa9b5; }
}