/* subsystem.co. Tokens are composed from static/themes; nothing below names a colour. */

:root, [data-theme="dark"] {
	color-scheme: dark;
	--page: #0A0A0B;
	--surface: #141313;
	--raised: #1D1C1A;
	--sunken: #1D1C1A;
	--head-ground: #262421;
	--code-inline: #1D1C1A;
	--rule: #302D29;
	--rule-strong: #807A70;
	--focus: #7FB0EC;
	--ink: #F2EFE6;
	--ink-body: #E3E0D7;
	--ink-quiet: #A9A399;
	--ink-faint: #7C766D;
	--link: #7FB0EC;
	--link-visited: #5A87BE;
	--zebra: #101010;
	--select-ground: #1F3A5C;
	--target-ground: #3A3113;
	--field-ground: #1D1C1A;
	--placeholder: #9A948A;
	--hit-ground: #5A4A1E;
	--hit-ink: #F2EFE6;
	--syn-text: #D6D2C8;
	--syn-comment: #BCB5A6;
	--syn-keyword: #EFE0BC;
	--syn-string: #E8A247;
	--syn-name: #7FB0EC;
	--syn-number: #6FD08A;
	--syn-meta: #9A948A;
	--syn-error: #F07070;
	--syn-linenum: #969086;
	--syn-emph-ground: #262420;
	--syn-add-ground: #1B2A1E;
	--syn-del-ground: #2A1C1B;
	--flow-audio: #98CAA2;
	--flow-midi: #E8A247;
	--flow-events: #5BADEB;
	--flow-other: #C96598;
	--sig-ground: #141313;
	--sig-name: #F2EFE6;
	--sig-param: #EFE0BC;
	--sig-type: #A9A399;
	--sig-default: #E8A247;
	--sig-badge-ink: #E3E0D7;
	--sig-badge-ground: #302D29;
	--picture-light: none;
	--picture-dark: block;
}

[data-theme="light"] {
	color-scheme: light;
	--page: #F7F5F0;
	--surface: #EDEAE2;
	--raised: #FFFFFF;
	--sunken: #060606;
	--head-ground: #E2DED4;
	--code-inline: #EDEAE2;
	--rule: #DCD7CB;
	--rule-strong: #767065;
	--focus: #1F5AA8;
	--ink: #17140D;
	--ink-body: #231F18;
	--ink-quiet: #5C564A;
	--ink-faint: #7C766D;
	--link: #1F5AA8;
	--link-visited: #0E3466;
	--zebra: #F1EEE7;
	--select-ground: #CBDCF2;
	--target-ground: #F6E7B0;
	--field-ground: #FFFFFF;
	--placeholder: #6B655A;
	--hit-ground: #F3D9A6;
	--hit-ink: #17140D;
	--syn-text: #D6D2C8;
	--syn-comment: #BCB5A6;
	--syn-keyword: #EFE0BC;
	--syn-string: #E8A247;
	--syn-name: #7FB0EC;
	--syn-number: #6FD08A;
	--syn-meta: #9A948A;
	--syn-error: #F07070;
	--syn-linenum: #969086;
	--syn-emph-ground: #1C1A15;
	--syn-add-ground: #0B1A0E;
	--syn-del-ground: #1C0B0B;
	--flow-audio: #2C7868;
	--flow-midi: #95560A;
	--flow-events: #2743A3;
	--flow-other: #6E1749;
	--sig-ground: #141313;
	--sig-name: #F2EFE6;
	--sig-param: #EFE0BC;
	--sig-type: #A9A399;
	--sig-default: #E8A247;
	--sig-badge-ink: #E3E0D7;
	--sig-badge-ground: #302D29;
	--picture-light: block;
	--picture-dark: none;
}

@media (prefers-color-scheme: light) {
	:root:not([data-theme]) {
		color-scheme: light;
		--page: #F7F5F0;
		--surface: #EDEAE2;
		--raised: #FFFFFF;
		--sunken: #060606;
		--head-ground: #E2DED4;
		--code-inline: #EDEAE2;
		--rule: #DCD7CB;
		--rule-strong: #767065;
		--focus: #1F5AA8;
		--ink: #17140D;
		--ink-body: #231F18;
		--ink-quiet: #5C564A;
		--ink-faint: #7C766D;
		--link: #1F5AA8;
		--link-visited: #0E3466;
		--zebra: #F1EEE7;
		--select-ground: #CBDCF2;
		--target-ground: #F6E7B0;
		--field-ground: #FFFFFF;
		--placeholder: #6B655A;
		--hit-ground: #F3D9A6;
		--hit-ink: #17140D;
		--syn-text: #D6D2C8;
		--syn-comment: #BCB5A6;
		--syn-keyword: #EFE0BC;
		--syn-string: #E8A247;
		--syn-name: #7FB0EC;
		--syn-number: #6FD08A;
		--syn-meta: #9A948A;
		--syn-error: #F07070;
		--syn-linenum: #969086;
		--syn-emph-ground: #1C1A15;
		--syn-add-ground: #0B1A0E;
		--syn-del-ground: #1C0B0B;
		--flow-audio: #2C7868;
		--flow-midi: #95560A;
		--flow-events: #2743A3;
		--flow-other: #6E1749;
		--sig-ground: #141313;
		--sig-name: #F2EFE6;
		--sig-param: #EFE0BC;
		--sig-type: #A9A399;
		--sig-default: #E8A247;
		--sig-badge-ink: #E3E0D7;
		--sig-badge-ground: #302D29;
		--picture-light: block;
		--picture-dark: none;
	}
}

/* Layout and type. Every colour is a token from static/themes; naming one here fails the build. */

/* Fonts (#2795). Each family is a folder in static/fonts holding its licence, and only the faces
   declared here are published. Three variables in :root choose the family for headings, text and
   code, so trying another font is a folder and an edit to this file. A weight a family lacks is
   drawn in its nearest, so the 600 asked of a family cut at 400 and 700 draws its true 700. */

@font-face {
	font-family: "Lexend";
	src: url("/s/fonts/lexend/lexend-latin-400-normal.0601e0a909.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: "Lexend";
	src: url("/s/fonts/lexend/lexend-latin-600-normal.c3c291158a.woff2") format("woff2");
	font-weight: 600;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: "Inter";
	src: url("/s/fonts/inter/inter-latin-400-normal.8909904ab6.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: "Inter";
	src: url("/s/fonts/inter/inter-latin-400-italic.7ea9d2f127.woff2") format("woff2");
	font-weight: 400;
	font-style: italic;
	font-display: swap;
}

@font-face {
	font-family: "Inter";
	src: url("/s/fonts/inter/inter-latin-700-normal.6f56409fd3.woff2") format("woff2");
	font-weight: 700;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: "Inter";
	src: url("/s/fonts/inter/inter-latin-700-italic.facd8f930c.woff2") format("woff2");
	font-weight: 700;
	font-style: italic;
	font-display: swap;
}

/* Code asks for three faces: its text, comments in italic, and keywords and signature names at 600. */

@font-face {
	font-family: "JetBrains Mono";
	src: url("/s/fonts/jetbrains-mono/jetbrains-mono-latin-400-normal.14425ba9c6.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: "JetBrains Mono";
	src: url("/s/fonts/jetbrains-mono/jetbrains-mono-latin-400-italic.87ddac4a62.woff2") format("woff2");
	font-weight: 400;
	font-style: italic;
	font-display: swap;
}

@font-face {
	font-family: "JetBrains Mono";
	src: url("/s/fonts/jetbrains-mono/jetbrains-mono-latin-600-normal.400c6bfda1.woff2") format("woff2");
	font-weight: 600;
	font-style: normal;
	font-display: swap;
}

/* Metric fallbacks (#3683). Until a family's file arrives a page is drawn in a font the reader already
   has, and drawn plain it takes a different width, so the text reflows when the family lands: 0.1 to
   0.3 of layout shift on a desktop page, measured. Each fallback below is a local font scaled so its
   average advance over the site's own words matches its family's, with its family's line metrics
   divided by that scale, as a browser applies them: Arial, or its metric twins Arimo and Liberation
   Sans, on Windows, macOS and iOS; Roboto on Android; DejaVu Sans on Linux. Measured from the files
   in static/fonts against Arimo, Roboto and DejaVu Sans on 2026-09-27: set as those systems set text,
   each is within 0.1 per cent of its family's width over the site's 6,824 paragraphs. DejaVu comes
   first in each stack, because Linux has it where the others do not, and Chrome there rounds each
   letter to a whole pixel, which only DejaVu survives: Ubuntu's Liberation Sans, scaled for Arial,
   measured 3.5 per cent wide. Code needs only Consolas, on Windows, which advances 0.55 em to
   JetBrains Mono's 0.6: Menlo and DejaVu Sans Mono are within half a percent of it already. */
@font-face {
	font-family: "Inter fallback Arial";
	src: local("Arial"), local("ArialMT"), local("Arimo Regular"), local("Arimo-Regular"), local("Liberation Sans"), local("LiberationSans");
	font-weight: 400;
	font-style: normal;
	size-adjust: 107.01%;
	ascent-override: 90.53%;
	descent-override: 22.54%;
	line-gap-override: 0.0%;
}
@font-face {
	font-family: "Inter fallback Roboto";
	src: local("Roboto"), local("Roboto Regular"), local("Roboto-Regular");
	font-weight: 400;
	font-style: normal;
	size-adjust: 107.42%;
	ascent-override: 90.18%;
	descent-override: 22.45%;
	line-gap-override: 0.0%;
}
@font-face {
	font-family: "Inter fallback DejaVu";
	src: local("DejaVu Sans"), local("DejaVuSans");
	font-weight: 400;
	font-style: normal;
	size-adjust: 93.67%;
	ascent-override: 103.42%;
	descent-override: 25.75%;
	line-gap-override: 0.0%;
}
@font-face {
	font-family: "Inter fallback Arial";
	src: local("Arial Bold"), local("Arial-BoldMT"), local("Arimo Bold"), local("Arimo-Bold"), local("Liberation Sans Bold"), local("LiberationSans-Bold");
	font-weight: 700;
	font-style: normal;
	size-adjust: 102.29%;
	ascent-override: 94.71%;
	descent-override: 23.58%;
	line-gap-override: 0.0%;
}
@font-face {
	font-family: "Inter fallback Roboto";
	src: local("Roboto Bold"), local("Roboto-Bold");
	font-weight: 700;
	font-style: normal;
	size-adjust: 108.69%;
	ascent-override: 89.13%;
	descent-override: 22.19%;
	line-gap-override: 0.0%;
}
@font-face {
	font-family: "Inter fallback DejaVu";
	src: local("DejaVu Sans Bold"), local("DejaVuSans-Bold");
	font-weight: 700;
	font-style: normal;
	size-adjust: 85.26%;
	ascent-override: 113.63%;
	descent-override: 28.29%;
	line-gap-override: 0.0%;
}
@font-face {
	font-family: "Lexend fallback Arial";
	src: local("Arial"), local("ArialMT"), local("Arimo Regular"), local("Arimo-Regular"), local("Liberation Sans"), local("LiberationSans");
	font-weight: 400;
	font-style: normal;
	size-adjust: 109.42%;
	ascent-override: 91.39%;
	descent-override: 22.85%;
	line-gap-override: 0.0%;
}
@font-face {
	font-family: "Lexend fallback Roboto";
	src: local("Roboto"), local("Roboto Regular"), local("Roboto-Regular");
	font-weight: 400;
	font-style: normal;
	size-adjust: 110.21%;
	ascent-override: 90.73%;
	descent-override: 22.68%;
	line-gap-override: 0.0%;
}
@font-face {
	font-family: "Lexend fallback DejaVu";
	src: local("DejaVu Sans"), local("DejaVuSans");
	font-weight: 400;
	font-style: normal;
	size-adjust: 96.37%;
	ascent-override: 103.77%;
	descent-override: 25.94%;
	line-gap-override: 0.0%;
}
@font-face {
	font-family: "Lexend fallback Arial";
	src: local("Arial Bold"), local("Arial-BoldMT"), local("Arimo Bold"), local("Arimo-Bold"), local("Liberation Sans Bold"), local("LiberationSans-Bold");
	font-weight: 600;
	font-style: normal;
	size-adjust: 106.23%;
	ascent-override: 94.14%;
	descent-override: 23.53%;
	line-gap-override: 0.0%;
}
@font-face {
	font-family: "Lexend fallback Roboto";
	src: local("Roboto Bold"), local("Roboto-Bold");
	font-weight: 600;
	font-style: normal;
	size-adjust: 113.18%;
	ascent-override: 88.36%;
	descent-override: 22.09%;
	line-gap-override: 0.0%;
}
@font-face {
	font-family: "Lexend fallback DejaVu";
	src: local("DejaVu Sans Bold"), local("DejaVuSans-Bold");
	font-weight: 600;
	font-style: normal;
	size-adjust: 88.99%;
	ascent-override: 112.37%;
	descent-override: 28.09%;
	line-gap-override: 0.0%;
}
@font-face {
	font-family: "JetBrains Mono fallback Consolas";
	src: local("Consolas");
	font-weight: 400;
	font-style: normal;
	size-adjust: 109.13%;
	ascent-override: 93.47%;
	descent-override: 27.49%;
	line-gap-override: 0.0%;
}
@font-face {
	font-family: "JetBrains Mono fallback Consolas";
	src: local("Consolas Bold"), local("Consolas-Bold");
	font-weight: 600;
	font-style: normal;
	size-adjust: 109.13%;
	ascent-override: 93.47%;
	descent-override: 27.49%;
	line-gap-override: 0.0%;
}
:root {
	--font-heading: "Lexend", "Lexend fallback DejaVu", "Lexend fallback Arial", "Lexend fallback Roboto", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	--font-text: "Inter", "Inter fallback DejaVu", "Inter fallback Arial", "Inter fallback Roboto", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	--font-code: "JetBrains Mono", "JetBrains Mono fallback Consolas", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
	--measure: 50rem;            /* a reading column: 800 px at a browser's default text size, whatever the font (#2815) */
	--reading: 1rem;             /* the one size every reading column is set in (#2711) */
	--space-1: 0.25rem;
	--space-2: 0.5rem;
	--space-3: 0.75rem;
	--space-4: 1rem;
	--space-6: 1.5rem;
	--space-8: 2rem;
	--space-12: 3rem;
}

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	background-color: var(--page);
	color: var(--ink-body);
	font-family: var(--font-text);
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
}

body {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
	min-height: 100dvh;
	margin: 0;
	font-size: 1rem;
	line-height: 1.62;
}

/* A page's own column fills the width it is given up to its measure, as it would in a plain block. */
body > .layout,
body > main {
	width: 100%;
}

/* Every heading, and the site's and the apps' names in the masthead, are set in the heading family. */
h1,
h2,
h3,
h4,
h5,
h6,
.wordmark,
.apps {
	font-family: var(--font-heading);
}

::selection {
	background-color: var(--select-ground);
	color: var(--ink);
}


/* Links. Always underlined, so colour is never the only sign; hover thickens the line. */

a {
	color: var(--link);
	text-decoration-line: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.18em;
}

a:visited {
	color: var(--link-visited);
}

a:hover {
	text-decoration-thickness: 2px;
}

/* A visited link is never drawn on the target ground: no ground that dark stays visible. */
:target a,
:target a:visited {
	color: var(--link);
}

/* The focus ring is the link blue, so its offset and thickness carry what colour cannot. */
:focus-visible {
	outline: 2px solid var(--focus);
	outline-offset: 3px;
	border-radius: 2px;
}

.skip {
	position: absolute;
	left: -9999px;
}

/* Read by a screen reader, drawn nowhere: a label whose field already says what it is for. */
.visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.skip:focus {
	left: var(--space-4);
	top: var(--space-4);
	z-index: 10;
	padding: var(--space-2) var(--space-4);
	background-color: var(--raised);
	color: var(--ink);
}


/* Masthead */

/* The masthead takes one of three shapes, each drawn on purpose (#3677): one row where everything
   fits; two on a laptop, the name, search and theme above the apps; and on a phone one row of the
   name, Search and Menu, with the apps behind Menu. The marks the names carry ask for room, so the
   space between one part of the masthead and the next is the narrower step: a mark separates two
   names by itself (#2861). */
.masthead {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto auto;
	grid-template-areas:
		"name . search theme"
		"apps apps apps apps";
	align-items: center;
	gap: var(--space-3) var(--space-6);
	padding: var(--space-4) var(--space-6);
	background-color: var(--surface);
	border-bottom: 1px solid var(--rule);
}

.wordmark {
	grid-area: name;
}

/* Where there is room for them, what a phone keeps behind Menu is the masthead's own. */
.masthead-menu {
	display: contents;
}

.masthead-apps {
	grid-area: apps;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-3) var(--space-6);
}

/* Only a phone has Search and Menu buttons, and only where the script runs to answer them. */
.search-link,
.search-toggle,
.menu-toggle {
	display: none;
}

/* Where everything fits, one row: from 87rem, 1,392 px at a browser's own text size, measured with
   every part of the masthead in the site's own faces (#3677). */
@media (min-width: 87rem) {

	.masthead {
		grid-template-columns: auto auto minmax(0, 1fr) auto auto;
		grid-template-areas: "name apps . search theme";
	}
}

.wordmark,
.wordmark:visited {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	color: var(--ink);
	font-weight: 600;
	letter-spacing: 0.02em;
	text-decoration: none;
}

/* The site's own mark stands beside its name, and carries a little more weight because the name
   beside it is set bolder than the apps' are. */
.wordmark .nav-icon {
	stroke-width: 2;
}

.apps ul {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2) var(--space-4);
	margin: 0;
	padding: 0;
	list-style: none;
}

.apps a,
.apps a:visited,
.sidebar a,
.sidebar a:visited {
	color: var(--ink-quiet);
	text-decoration: none;
}

.apps a:hover,
.sidebar a:hover {
	color: var(--ink);
	text-decoration: underline;
}

.apps a[aria-current="page"],
.sidebar a[aria-current="page"] {
	color: var(--ink);
	text-decoration: underline;
	text-decoration-color: var(--link);
	text-decoration-thickness: 2px;
}

/* An app's mark stands before its name in the masthead (#2861), and the line that marks a link
   runs under the name alone: drawn under the mark as well, it reads as part of the drawing. */
.apps a {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
}

.apps a:hover,
.apps a[aria-current="page"] {
	text-decoration: none;
}

.apps a:hover span,
.apps a[aria-current="page"] span {
	text-decoration: underline;
}

.apps a[aria-current="page"] span {
	text-decoration-color: var(--link);
	text-decoration-thickness: 2px;
}

/* Smaller than the name beside it, as furniture is, with a heavier stroke than the home page's
   mark because the file's own 2 thins out as the drawing shrinks. */
.nav-icon {
	width: 1.15em;
	height: 1.15em;
	stroke-width: 1.75;
}

/* The theme toggle. The analytics button a reader's answer leaves is in the footer (#3209, #3677). */
.theme-slot {
	grid-area: theme;
	display: flex;
	gap: var(--space-2);
}

/* The masthead's search is a plain form: it reaches the search page without JavaScript (#2605). */
.masthead-search {
	grid-area: search;
}

.masthead-search input,
.search-form input {
	padding: var(--space-1) var(--space-3);
	border: 1px solid var(--rule-strong);
	border-radius: 4px;
	background-color: var(--field-ground);
	color: var(--ink);
	font: inherit;
}

.masthead-search input {
	width: 12rem;
	font-size: 0.875rem;
}

.masthead-search input::placeholder {
	color: var(--placeholder);
	opacity: 1;
}

/* A phone's masthead is one row: the name, then Search and Menu, each a finger's height (#3677).
   Menu opens the apps, the libraries and the theme, a row each; Search opens its field across the
   row, where the name was. Without the script there are no buttons: Search is a link to the search
   page, and the apps show open, a row each. */
@media (max-width: 56rem) {

	.masthead {
		grid-template-columns: minmax(0, 1fr) auto auto;
		grid-template-areas:
			"name find menu"
			"panel panel panel";
		gap: 0 var(--space-2);
		padding: var(--space-2) var(--space-4);
	}

	.search-link,
	.search-toggle {
		grid-area: find;
	}

	.menu-toggle {
		grid-area: menu;
	}

	.search-link,
	.search-toggle,
	.menu-toggle {
		align-items: center;
		gap: var(--space-3);
		min-height: 3rem;
		padding: 0 var(--space-3);
		border: 1px solid var(--rule-strong);
		border-radius: 4px;
		background-color: transparent;
		color: var(--ink);
		font: inherit;
		font-size: 0.9375rem;
		text-decoration: none;
		cursor: pointer;
	}

	.search-link {
		display: inline-flex;
	}

	[data-nav-script] .search-link {
		display: none;
	}

	[data-nav-script] .search-toggle,
	[data-nav-script] .menu-toggle {
		display: inline-flex;
	}

	/* The field is Search's to open: closed, it takes no room. */
	.masthead-search {
		display: none;
	}

	[data-nav-script] .masthead[data-open="search"] {
		grid-template-areas:
			"form form find"
			"panel panel panel";
	}

	[data-nav-script] .masthead[data-open="search"] .wordmark,
	[data-nav-script] .masthead[data-open="search"] .menu-toggle {
		display: none;
	}

	[data-nav-script] .masthead[data-open="search"] .masthead-search {
		display: block;
		grid-area: form;
	}

	/* A phone zooms into a field set smaller than its own text, so this one is set at the reader's size. */
	.masthead-search input {
		width: 100%;
		min-height: 3rem;
		font-size: 1rem;
	}

	/* The apps, the libraries and the theme, a row each: open where no script runs, behind Menu where one does. */
	.masthead-menu {
		display: flex;
		flex-direction: column;
		grid-area: panel;
		padding-block: var(--space-2);
	}

	[data-nav-script] .masthead:not([data-open="menu"]) .masthead-menu {
		display: none;
	}

	.masthead-apps {
		flex-direction: column;
		align-items: stretch;
		gap: 0;
	}

	.masthead-apps .apps ul {
		flex-direction: column;
		gap: 0;
	}

	.masthead-apps .apps a {
		display: flex;
		min-height: 3rem;
	}

	/* The libraries are set apart from the apps, as they are on a wider screen. */
	.masthead-apps .apps + .apps {
		margin-top: var(--space-2);
		padding-top: var(--space-2);
		border-top: 1px solid var(--rule);
	}

	.theme-slot {
		padding-top: var(--space-3);
	}

	.theme-slot .theme-toggle {
		min-height: 3rem;
	}
}

/* The site's one chevron, drawn from two borders in the text's colour: pointing right while what it
   opens is closed, and down while it is open. On this site a chevron always means something opens in
   place, on this page, and it sits at the right-hand end of what opens it (#3677, #3685). */
.menu-toggle::after,
.sidebar-toggle::after,
.nav-chevron::before,
.prose summary::after {
	content: "";
	flex: none;
	width: 0.45em;
	height: 0.45em;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: translateX(-0.1em) rotate(-45deg);
}

.menu-toggle[aria-expanded="true"]::after,
.sidebar-toggle[aria-expanded="true"]::after,
.nav-chevron[aria-expanded="true"]::before,
.prose details[open] > summary::after {
	transform: translateY(-0.15em) rotate(45deg);
}

.theme-toggle,
.consent-toggle,
.consent button {
	padding: var(--space-1) var(--space-3);
	border: 1px solid var(--rule-strong);
	border-radius: 4px;
	background-color: transparent;
	color: var(--ink-quiet);
	font: inherit;
	font-size: 0.875rem;
	cursor: pointer;
}

.theme-toggle:hover,
.consent-toggle:hover,
.consent button:hover {
	color: var(--ink);
}

/* The question Google's tag waits on (#3209). Fixed to the foot of the window, so it moves nothing on
   the page, and hidden until the script that answers it has run. Its two answers look the same,
   because refusing must be as easy to find as agreeing. */
.consent {
	position: fixed;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 10;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--space-3) var(--space-4);
	padding: var(--space-4) var(--space-6);
	border-top: 1px solid var(--rule-strong);
	background-color: var(--raised);
	color: var(--ink);
	font-size: 0.875rem;
}

.consent[hidden] {
	display: none;
}

.consent p {
	flex: 1 1 20rem;
	max-width: var(--measure);
	margin: 0;
}


/* Page layout */

/* The page is the sidebar, the gap, the measure and the padding (#2712), worked out rather than typed.
   None of them is measured in the text font, so trying a font never moves the page (#2815). */
.layout {
	display: grid;
	grid-template-columns: minmax(10rem, 15rem) minmax(0, 1fr);
	gap: var(--space-12);
	max-width: calc(15rem + var(--space-12) + var(--measure) + 2 * var(--space-6));
	margin: 0 auto;
	padding: var(--space-8) var(--space-6);
}

.sidebar > ul {
	position: sticky;
	top: var(--space-6);
	display: grid;
	gap: var(--space-2);
	max-height: calc(100vh - 2 * var(--space-6));
	margin: 0;
	padding: 0;
	overflow-y: auto;
	list-style: none;
	font-size: 0.9375rem;
	line-height: 1.4;
}

/* A chevron reaches past its row so rows stay level (#3677). Where the list's last row is a closed
   section's, at either level, the list holds room for that reach, half a chevron, or the list would
   scroll by those few pixels (#4077); a list ending on any other row needs none. A phone's list never
   scrolls, and its chevrons reach nowhere. */
@media (width > 56rem) {

	.sidebar > ul:has(> .nav-section:last-child > .nav-pages[hidden]),
	.sidebar > ul:has(> .nav-section:last-child > .nav-pages:not([hidden]) > .nav-section:last-child > .nav-pages[hidden]) {
		padding-bottom: calc(var(--nav-mark) / 2);
	}
}

/* The column at the right-hand end of a row, where a mark says what else an entry does: a
   section's chevron opens its pages here, and the external mark leaves the site (#3677). */
.sidebar {
	--nav-mark: 1.75rem;
}

/* The pages beneath a section, such as a guide's chapters or the modules of an API reference. */
.nav-pages {
	display: grid;
	gap: var(--space-2);
	margin: var(--space-2) 0 0;
	padding: 0 0 0 var(--space-3);
	list-style: none;
	font-size: 0.875rem;
}

/* A section closed as the page loads stays closed until its chevron opens it, script or none. */
.nav-pages[hidden] {
	display: none;
}

/* A section's name, which goes to its own page, and the chevron that opens its pages in place. Its
   target reaches into the space between rows rather than pushing them apart. */
.nav-row {
	display: flex;
	align-items: center;
	gap: var(--space-2);
}

.nav-row > a {
	flex: 1 1 auto;
	min-width: 0;
}

/* The section the reader is in, while they are on one of its pages rather than on its own. */
.sidebar a.nav-within {
	color: var(--ink);
}

.nav-chevron {
	display: none;
}

[data-nav-script] .nav-chevron {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: none;
	width: var(--nav-mark);
	height: var(--nav-mark);
	margin-block: calc((1.4em - var(--nav-mark)) / 2);
	padding: 0;
	border: 0;
	border-radius: 4px;
	background-color: transparent;
	color: var(--ink-quiet);
	cursor: pointer;
}

.nav-chevron:hover {
	color: var(--ink);
}

/* An app's sidebar ends with its repository, on another site (#3669): set apart from the app's own
   pages, and marked with the mark the web uses for a link that leaves, centred in the chevrons'
   column (#3677). */
.sidebar .nav-external {
	margin-top: var(--space-4);
}

/* A page of another kind from the rows above it closes the list set apart from them, with a rule as
   well as the repository's gap, since it is still a page of this site: a library's Python page after
   its instruments' makers (#4265). */
.sidebar .nav-apart {
	margin-top: var(--space-4);
	padding-top: var(--space-3);
	border-top: 1px solid var(--rule);
}

.nav-external a {
	display: flex;
	align-items: center;
}

.nav-external-icon {
	flex: none;
	width: 0.8em;
	height: 0.8em;
	margin-right: calc((var(--nav-mark) - 0.8em) / 2);
	margin-left: auto;
	stroke-width: 2;
}

/* A label that names code, such as a module or a setting, is set in the code font at the entry's own
   size, without the chip and the smaller size code has in running text (#2813). */
.sidebar code {
	padding: 0;
	background-color: initial;
	font-size: inherit;
}

/* The button a narrow screen shows in the list's place (#2609). */
.sidebar-toggle {
	display: none;
}

@media (max-width: 56rem) {

	.layout {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--space-6);
		padding: var(--space-6) var(--space-4);
	}

	/* A chevron's target is a finger's width, beside the link, as the link is a finger's height. */
	.sidebar {
		--nav-mark: 3rem;
	}

	/* One link a row, each a finger's height, so no link can be tapped by touching its neighbour. */
	.sidebar > ul {
		position: static;
		gap: 0;
		max-height: none;
		overflow-y: visible;
	}

	.sidebar a {
		display: flex;
		align-items: center;
		min-height: 3rem;
	}

	.nav-pages {
		gap: 0;
		margin: 0;
	}

	/* A row is a finger's height here, which the chevron fills. */
	[data-nav-script] .nav-chevron {
		margin-block: 0;
	}

	.sidebar .nav-external {
		margin-top: var(--space-2);
	}

	.sidebar .nav-apart {
		margin-top: var(--space-2);
		padding-top: var(--space-2);
	}

	/* Where the page's script runs, the list waits behind its button, which names whose pages they are
	   with its mark, as the masthead does (#3677); where it does not, the list stays open. */
	[data-nav-script] .sidebar-toggle {
		display: flex;
		align-items: center;
		gap: var(--space-3);
		width: 100%;
		min-height: 3rem;
		padding: 0 var(--space-4);
		border: 1px solid var(--rule-strong);
		border-radius: 4px;
		background-color: transparent;
		color: var(--ink);
		font: inherit;
		cursor: pointer;
	}

	[data-nav-script] .sidebar-toggle[aria-expanded="false"] + ul {
		display: none;
	}

	[data-nav-script] .sidebar-toggle + ul {
		margin-top: var(--space-2);
	}

	.sidebar-toggle::after {
		margin-left: auto;
	}
}


/* Which part of a guide a chapter is in (#3115). A guide is entered by situation rather than read
   from the first chapter, so a reader who arrives in the middle is told where they are. */
.page-part {
	margin: 0;
	color: var(--ink-quiet);
	font-size: 0.875rem;
	letter-spacing: 0.02em;
	text-transform: uppercase;
}

.page-part span {
	color: var(--ink);
	text-transform: none;
	letter-spacing: normal;
}

/* A section that is not an app says what it is, whom it is for and where its source is, above
   every page of it (#2578). */
.page-note {
	margin: 0 0 var(--space-4);
	padding: var(--space-3) var(--space-4);
	border-left: 3px solid var(--rule-strong);
	background-color: var(--raised);
	font-size: 0.95em;
}


/* Prose. Siblings are spaced by gap, so a block dropped in never doubles a margin. */

.prose {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	min-width: 0;
	max-width: var(--measure);
	font-size: var(--reading);
	overflow-wrap: break-word;   /* a bare URL in running text is one long word, and a phone is narrower than it */
}

.prose > * {
	margin: 0;
}

.prose h1,
.prose h2,
.prose h3,
.prose h4 {
	color: var(--ink);
	font-weight: 600;
	line-height: 1.25;
	text-wrap: balance;
	overflow-wrap: anywhere;   /* a qualified name like `subsequence.composition` is one long word */
}

.prose h1 {
	font-size: 2em;
}

.prose h2 {
	margin-top: var(--space-6);
	padding-top: var(--space-4);
	border-top: 1px solid var(--rule);
	font-size: 1.4em;
}

.prose h3 {
	margin-top: var(--space-2);
	font-size: 1.15em;
}

.prose h4 {
	font-size: 1em;
}

/* What a reader landed on, marked until they move. The ground needs room, or the text sits on its
   own edge and the mark reads as a box drawn round it; the negative margins keep that room outside
   the column, so a heading does not move sideways when it is the target. */
.prose :target {
	padding: var(--space-2) var(--space-3);
	margin-left: calc(-1 * var(--space-3));
	margin-right: calc(-1 * var(--space-3));
	border-radius: 4px;
	background-color: var(--target-ground);

	/* Landing on it puts it at the very top of the window, where its own top edge is the window's. */
	scroll-margin-top: var(--space-4);
}

.prose ul,
.prose ol {
	padding-left: 1.5rem;
}

.prose li + li {
	margin-top: var(--space-1);
}

.prose blockquote {
	padding: var(--space-3) var(--space-4);
	border-left: 3px solid var(--rule-strong);
	background-color: var(--surface);
}

.prose blockquote > * {
	margin: 0;
}

.prose blockquote > * + * {
	margin-top: var(--space-3);
}

.prose hr {
	width: 100%;
	border: 0;
	border-top: 1px solid var(--rule);
}

.prose sub {
	color: var(--ink-quiet);
	font-size: 0.8em;
	line-height: 1.5;
	vertical-align: baseline;
}

/* Facts, such as a setting's type and default (#2611): each term beside what it is, in two columns.
   The terms' column has a floor, so one entry's facts line up with the next one's. */
.prose dl {
	display: grid;
	grid-template-columns: minmax(5rem, max-content) minmax(0, 1fr);
	gap: var(--space-1) var(--space-4);
	font-size: 0.95em;
	line-height: 1.5;
}

.prose dt {
	color: var(--ink-quiet);
}

.prose dd {
	margin: 0;
	min-width: 0;
	overflow-wrap: anywhere;
}


/* Code */

code,
pre {
	font-family: var(--font-code);
}

:not(pre) > code {
	padding: 0.1em 0.35em;
	border-radius: 3px;
	background-color: var(--code-inline);
	color: var(--ink);
	font-size: 0.875em;
	overflow-wrap: anywhere;
}

a > code {
	color: inherit;
}

.prose pre.code {
	padding: var(--space-4);
	overflow-x: auto;
	border-radius: 6px;
	background-color: var(--sunken);
	color: var(--syn-text);
	font-size: 0.875em;
	line-height: 1.55;
	tab-size: 4;
}


/* A guide's code (#2742). A line above a block the build does not run, close to the block it is
   about; what an example made, set apart from code as output; and the piece so far, folded. */

/* A step waiting for a recording says so as quietly as a block the build does not run (#3845). */
.prose .code-note,
.prose .recording-note {
	color: var(--ink-quiet);
	font-size: 0.875em;
}

.prose .code-note + pre.code {
	margin-top: calc(var(--space-2) - var(--space-4));
}

.prose pre.code.summary {
	border-left: 3px solid var(--rule-strong);
	border-radius: 0 6px 6px 0;
	background-color: var(--surface);
	color: var(--ink-body);
}

.prose details {
	border: 1px solid var(--rule);
	border-radius: 6px;
}

.prose details > * {
	margin: 0 var(--space-4);
}

.prose details > * + * {
	margin-top: var(--space-4);
}

.prose details[open] {
	padding-bottom: var(--space-4);
}

/* An app's own image, published from its pinned release (#3957, #3958), at the column's width at
   most. A picture framed like a folded box, so a light screenshot keeps its edge on a light page;
   one that comes in a light and a dark version shows the one the reader's theme asks for, which
   the composed theme sheet says from each theme's own colour scheme. */

.prose img {
	max-width: 100%;
	height: auto;
}

.prose .picture img {
	display: block;
	border: 1px solid var(--rule);
	border-radius: 6px;
}

.prose .picture .picture-light {
	display: var(--picture-light, block);
}

.prose .picture .picture-dark {
	display: var(--picture-dark, none);
}

/* A folded box opens by its whole top row, a finger's height, and wears the site's chevron at the
   row's right-hand end in place of the browser's own triangle, as everything that opens in place
   on this site does (#3685). It needs no script: the box opens by itself. */
.prose summary {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	min-height: 3rem;
	margin: 0;
	padding: 0 var(--space-4);
	color: var(--ink);
	font-weight: 600;
	list-style: none;
	cursor: pointer;
}

.prose summary::-webkit-details-marker {
	display: none;
}

.prose summary::after {
	margin-left: auto;
}

/* API signatures: the name, each parameter, its type and its default on their own tokens (#2340).
   Punctuation takes the type's ink, so the parts that vary are the ones that stand out. */

.prose pre.sig {
	padding: var(--space-3) var(--space-4);
	overflow-x: auto;
	border-radius: 6px;
	background-color: var(--sig-ground);
	color: var(--sig-type);
	font-size: 0.875em;
	line-height: 1.55;
}

.sig .sig-name {
	color: var(--sig-name);
	font-weight: 600;
}

.sig .sig-param {
	color: var(--sig-param);
}

.sig .sig-type {
	color: var(--sig-type);
}

.sig .sig-default {
	color: var(--sig-default);
}

.sig .sig-badge {
	padding: 0 0.35em;
	border-radius: 3px;
	background-color: var(--sig-badge-ground);
	color: var(--sig-badge-ink);
}


/* Tables. Wide ones scroll inside their own box rather than widening the page. */

.table-scroll {
	max-width: 100%;
	overflow-x: auto;
}

.prose table {
	border-collapse: collapse;
	font-size: 0.95em;
	line-height: 1.5;
	font-variant-numeric: tabular-nums;
}

.prose th,
.prose td {
	padding: var(--space-2) var(--space-3);
	border-bottom: 1px solid var(--rule);
	text-align: left;
	vertical-align: top;
}

.prose th {
	border-bottom-color: var(--rule-strong);
	background-color: var(--head-ground);
	color: var(--ink);
	font-weight: 600;
}

.prose tbody tr:nth-child(even) {
	background-color: var(--zebra);
}

/* An instrument's controls, a table to a group (#4074): each spans the column with its columns set
   alike, so the chart reads as one down the page however long each group's names are (#4077). A
   control takes a third, a number an eighth, and what its values mean the rest; a model with NRPNs
   gives a table a column for them, wide enough for an NRPN's two halves, at a little of the rest. */
.instrument table {
	width: 100%;
	table-layout: fixed;
}

.instrument th:first-child {
	width: 34%;
}

.instrument th:nth-child(2):not(:last-child) {
	width: 12%;
}

.instrument table:has(th:nth-child(4)) th:first-child {
	width: 32%;
}

.instrument table:has(th:nth-child(4)) th:nth-child(2) {
	width: 10%;
}

.instrument table:has(th:nth-child(4)) th:nth-child(3) {
	width: 18%;
}

/* A notes table is not a chart of controls: after what each note plays, it has a column for the notes
   that play it and one for each set of notes the instrument itself sends (#5066). So after the first,
   its columns share the table's width evenly, however many sets a model has. It is the table under a
   heading that ends in "notes", after its opening paragraph. */
.instrument h2[id$="notes"] + p + .table-scroll th:not(:first-child) {
	width: auto;
}

/* A phone's column is too narrow for an eighth to hold a number and its fine half, so the control
   and its numbers take more, and a cell keeps less room either side of what it holds. */
@media (max-width: 40rem) {

	.instrument th,
	.instrument td {
		padding-inline: var(--space-2);
	}

	.instrument th:first-child {
		width: 38%;
	}

	.instrument th:nth-child(2):not(:last-child) {
		width: 22%;
	}

	.instrument table:has(th:nth-child(4)) th:first-child {
		width: 30%;
	}

	.instrument table:has(th:nth-child(4)) th:nth-child(2) {
		width: 18%;
	}

	.instrument table:has(th:nth-child(4)) th:nth-child(3) {
		width: 21%;
	}
}

/* The band library's tables, one for each reception class, share their columns at every width, so
   a frequency lines up from one table to the next (#4531). A frequency and a modulation never break,
   and a heading breaks only between its words; a band's name holds no space, so it alone breaks
   where it must. On a phone the type is a little smaller and the cells tighter, which is what lets
   446.00625 stand whole beside its band at 360 pixels across. */
.bands table {
	width: 100%;
	table-layout: fixed;
}
.bands th:first-child {
	width: 42%;
}
.bands th:nth-child(2),
.bands th:nth-child(3) {
	width: 19%;
}
.bands th {
	overflow-wrap: normal;
}
.bands td:nth-child(n+2) {
	white-space: nowrap;
}
.bands td:first-child code {
	overflow-wrap: anywhere;
}
@media (max-width: 40rem) {
	.bands table {
		font-size: 0.85em;
	}
	.bands th,
	.bands td {
		padding-inline: var(--space-1);
	}
	.bands th:first-child {
		width: 28%;
	}
	.bands th:nth-child(2),
	.bands th:nth-child(3) {
		width: 24%;
	}
}
/* The narrowest phones, 320 pixels across, need the type smaller still to keep a frequency whole. */
@media (max-width: 22rem) {
	.bands table {
		font-size: 0.75em;
	}
}
/* A topic the library opens in capitals heads its paragraph of where the facts come from, set bold,
   a little smaller and spaced, as a run-in heading in capitals is set, so it reads as the paragraph's
   subject without shouting (#4202). Only bold that opens its paragraph is one, which the renderer
   marks as a run-in: the library's own emphasis inside a sentence stays as the text sets it (#4270). */
.instrument #where-these-facts-come-from ~ p.run-in > strong:first-child {
	font-size: 0.85em;
	letter-spacing: 0.04em;
}

.prose .align-left {
	text-align: left;
}

.prose .align-center {
	text-align: center;
}

.prose .align-right {
	text-align: right;
}


/* Where a page came from */

.page-source {
	margin-top: var(--space-8);
	padding-top: var(--space-4);
	border-top: 1px solid var(--rule);
	color: var(--ink-quiet);
	font-size: 0.875rem;
}


/* The chapters either side of a guide page. Two columns where both are there, one where the
   first or the last chapter has only a neighbour on one side, so neither ever drifts inwards. */

.page-neighbours {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--space-4);
	margin-top: var(--space-8);
	padding-top: var(--space-6);
	border-top: 1px solid var(--rule);
}

.neighbour {
	display: block;
	padding: var(--space-4);
	border: 1px solid var(--rule);
	border-radius: 4px;
	text-decoration: none;
}

.neighbour span {
	display: block;
	margin-bottom: var(--space-1);
	color: var(--ink-quiet);
	font-size: 0.875rem;
}

.neighbour.before {
	grid-column: 1;
}

.neighbour.after {
	grid-column: 2;
	text-align: right;
}

@media (max-width: 40rem) {

	.page-neighbours {
		grid-template-columns: 1fr;
	}

	.neighbour.after {
		grid-column: 1;
		text-align: left;
	}
}


/* Home. One reading column, as the search page is: the introduction fills it, and each app
   is a section under a heading of its own (#2706). */

.home {
	max-width: calc(var(--measure) + 2 * var(--space-6));
	margin: 0 auto;
	padding: var(--space-12) var(--space-6);
	font-size: var(--reading);
}

.home h1 {
	margin: 0 0 var(--space-8);
	color: var(--ink);
	font-size: 2em;
	line-height: 1.25;
}

/* The introduction from the source brief (#2557): a page's prose, filling the home column. */
.home-intro {
	max-width: none;
	margin: 0 0 var(--space-8);
}

/* Where the introduction picks up after the app list (#3092). Without this it begins hard against
   the last app's description, and its first sentence reads as part of that app's entry. */
.app-section + .home-intro {
	margin-top: var(--space-8);
}

/* An app is its mark, its name and what it is (#2861). The mark stands to the left of both, and
   the rule that separates one app from the next runs the width of the column. */
.app-section {
	--app-mark: calc(1.4em * 1.25 + var(--space-2) + 1.62em);   /* the name's line, the gap, and the first line under it */

	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	column-gap: var(--space-4);
	margin-top: var(--space-6);
	padding-top: var(--space-4);
	border-top: 1px solid var(--rule);
}

/* An app's name reads as a section heading: a step above a page's h2, beside the larger
   introduction. */
.app-section h2 {
	grid-column: 2;
	margin: 0;
	color: var(--ink);
	font-size: 1.4em;
	font-weight: 600;
	line-height: 1.25;
}

.app-section p {
	grid-column: 2;
	margin: var(--space-2) 0 0;
	color: var(--ink-quiet);
}

/* The mark is drawn in the text's own colour, so it is right in every theme (#2340), and the file
   says nothing about its size or its stroke: both are set here. */
.app-icon {
	grid-row: 1 / span 2;
	align-self: start;
	width: var(--app-mark);
	height: var(--app-mark);
	color: var(--ink);
	stroke-width: 1.5;
}

/* A narrow screen gives its text less room around it; its reading size is the token's (#2711). */
@media (max-width: 56rem) {

	.home {
		padding: var(--space-8) var(--space-4);
	}
}


/* Search. A result is a page, with the sections of it that matched beneath it. */

.search {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	max-width: calc(var(--measure) + 2 * var(--space-6));
	margin: 0 auto;
	padding: var(--space-12) var(--space-6);
	font-size: var(--reading);
}

.search h1 {
	margin: 0;
	color: var(--ink);
	font-size: 2em;
	line-height: 1.25;
}

.search-form {
	display: grid;
	gap: var(--space-2);
}

.search-form label {
	color: var(--ink-quiet);
}

.search-form input {
	width: 100%;
	padding: var(--space-2) var(--space-3);
	font-size: 1em;
}

.search-apps {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2) var(--space-6);
	margin: 0;
	padding: 0;
	border: 0;
	color: var(--ink-quiet);
	font-size: 0.9em;
}

.search-status {
	margin: 0;
	color: var(--ink-quiet);
}

.search-results {
	display: grid;
	gap: var(--space-6);
	margin: 0;
	padding: 0;
	list-style: none;
}

.search-result {
	display: grid;
	gap: var(--space-1);
	padding-top: var(--space-4);
	border-top: 1px solid var(--rule);
	overflow-wrap: anywhere;
}

.search-app,
.search-excerpt {
	margin: 0;
}

.search-app {
	color: var(--ink-quiet);
	font-size: 0.8em;
}

.search-title {
	font-size: 1.05em;
	font-weight: 600;
}

.search-sections {
	display: grid;
	gap: var(--space-3);
	margin: var(--space-2) 0 0;
	padding-left: var(--space-4);
	border-left: 1px solid var(--rule);
	list-style: none;
}

/* A hit is a ground swap and a weight, so it never rests on colour alone. */
.search mark {
	padding: 0 0.1em;
	border-radius: 2px;
	background-color: var(--hit-ground);
	color: var(--hit-ink);
	font-weight: 600;
}

.search-more {
	justify-self: start;
	align-self: flex-start;
	padding: var(--space-1) var(--space-3);
	border: 1px solid var(--rule-strong);
	border-radius: 4px;
	background-color: transparent;
	color: var(--ink-quiet);
	font: inherit;
	cursor: pointer;
}

.search-more:hover {
	color: var(--ink);
}


/* The page's foot (#3677): the author's line, and beside it the analytics answer a reader can
   change, once they have given one. It sits at the foot of the window however short the page. */
.site-footer {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3) var(--space-6);
	margin-top: auto;
	padding: var(--space-6);
	border-top: 1px solid var(--rule);
	background-color: var(--surface);
	color: var(--ink-quiet);
	font-size: 0.875rem;
}

/* One line of credit wherever there is room for it, so it never breaks inside its own words. */
.site-footer p {
	flex: 1 1 20rem;
	margin: 0;
}

.site-footer a,
.site-footer a:visited {
	color: inherit;
}

.consent-slot:empty {
	display: none;
}

.code .syn-comment { color: var(--syn-comment); }
.code .syn-keyword { color: var(--syn-keyword); }
.code .syn-string { color: var(--syn-string); }
.code .syn-name { color: var(--syn-name); }
.code .syn-number { color: var(--syn-number); }
.code .syn-meta { color: var(--syn-meta); }
.code .syn-error { color: var(--syn-error); }
.code .syn-comment { font-style: italic; }
.code .syn-keyword { font-weight: 600; }
