:root {
  color-scheme: light;
  --ink: #18212b;
  --muted: #5c6774;
  --line: #dce2e8;
  --paper: #fffff8;
  --wash: #f4f7fa;
  --accent: #1769aa;
  --accent-dark: #0e4c7d;
  --alarm: #a3271c;
  /* Running text is capped by its own measure rather than by the column, so a
     display formula or a figure still has the full track to spread into. */
  --measure: 54ch;
  /* Every metadata label on the page. 14px is the floor for uppercase or
     small-caps runs; below it the letterforms stop resolving. */
  --label: 0.875rem;
  --bs-font-monospace: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --bs-border-color: var(--line);
  --bs-tertiary-bg: var(--wash);
  font-family:
    "ETBook", Charter, "Bitstream Charter", "Iowan Old Style", Georgia, serif;
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
}

/* ETBook — Edward Tufte's book font, adapted from edwardtufte/tufte-css. */
@font-face {
  font-family: "ETBook";
  src: url("fonts/et-book-roman-line-figures.woff") format("woff");
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "ETBook";
  src: url("fonts/et-book-bold-line-figures.woff") format("woff");
  font-weight: bold;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "ETBook";
  src: url("fonts/et-book-display-italic-old-style-figures.woff") format("woff");
  font-weight: normal;
  font-style: italic;
  font-display: swap;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  min-width: 20rem;
}

a {
  color: var(--accent);
  text-decoration-thickness: 0.08em;
  text-underline-offset: 0.16em;
}

a:hover {
  color: var(--accent-dark);
}

/* A term at its defining occurrence (`\dfn{term}`, DEF-26): one style for every
   definiendum, whatever emphasis the source it came from used. */
dfn.qual-dfn {
  font-style: italic;
  font-weight: normal;
  color: var(--ink);
}

/* One ring for every link, button, field and disclosure on the site. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 0.2rem;
}

code,
kbd {
  font-family: var(--bs-font-monospace);
}

code {
  padding: 0.1rem 0.3rem;
  border-radius: 0.2rem;
  background: var(--wash);
}

img,
svg {
  max-width: 100%;
}

.tikzcd svg,
.tikzpic svg,
.tikzcode svg,
.pdftex svg {
  width: 100%;
  height: auto;
}

mjx-container {
  max-width: 100%;
}

mjx-container:not([display="true"]) {
  display: inline-block;
  overflow: visible;
  vertical-align: middle;
}

mjx-container[display="true"] {
  overflow-x: auto;
  overflow-y: hidden;
  padding-block: 0.2rem;
}

.site-header {
  position: sticky;
  z-index: 20;
  top: 0;
  border-bottom: 1px solid var(--line);
  /* Opaque: a translucent bar let scrolled mathematics smudge through the
     brand, and a blurred ghost of the page is not a legible background. */
  background: var(--paper);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 1.75rem;
  width: min(100% - 2rem, 86rem);
  min-height: 3.75rem;
  margin-inline: auto;
}

.site-brand {
  color: var(--ink);
  font-size: 1.05rem;
  font-weight: 750;
  letter-spacing: -0.02em;
  text-decoration: none;
}

.site-links {
  display: flex;
  gap: 1.25rem;
  margin-right: auto;
}

.site-links a {
  color: var(--muted);
  font-size: 0.92rem;
  font-weight: 600;
  text-decoration: none;
}

.search-open {
  padding: 0.4rem 0.65rem;
  border: 1px solid var(--line);
  border-radius: 0.35rem;
  color: var(--muted);
  background: var(--paper);
  cursor: pointer;
}

.search-open kbd {
  margin-left: 0.35rem;
  color: var(--ink);
}

.page-layout {
  display: grid;
  grid-template-columns: minmax(0, 45rem) minmax(11rem, 15rem);
  gap: 4rem;
  width: min(100% - 3rem, 74rem);
  margin: 3.5rem auto 7rem;
}

.page-layout.subject-layout {
  grid-template-columns: minmax(12rem, 16rem) minmax(0, 45rem) minmax(
      10rem,
      13rem
    );
  gap: 2.75rem;
  width: min(100% - 3rem, 88rem);
}

/* A page with no in-page headings leaves the aside empty, and hiding an empty
   box does not release the grid track it sits in: a three-line page read as a
   third of a page beside a reserved void. Drop the track itself. */
.page-layout:has(> .page-toc:empty) {
  grid-template-columns: minmax(0, 45rem);
}

.page-layout.subject-layout:has(> .page-toc:empty) {
  grid-template-columns: minmax(12rem, 16rem) minmax(0, 45rem);
}

.site-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: min(100% - 3rem, 88rem);
  padding: 1.1rem 0 2.25rem;
  margin: -4.5rem auto 0;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.8rem;
}

.site-footer p {
  margin: 0;
}

.site-footer a {
  color: inherit;
  text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
  text-underline-offset: 0.15em;
}

.footer-repository {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 600;
  text-decoration: none;
}

.footer-repository svg {
  width: 1rem;
  height: 1rem;
}

.subject-sidebar {
  position: sticky;
  top: 5.5rem;
  align-self: start;
  max-height: calc(100vh - 7rem);
  overflow: auto;
  padding-right: 1rem;
  color: var(--muted);
  font-size: 0.875rem;
}

.subject-label {
  display: block;
  margin-bottom: 0.7rem;
  color: var(--ink);
  font-size: 0.8rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.sidebar-narrow {
  display: none;
}

.subject-sidebar ol {
  display: grid;
  gap: 0.4rem;
  padding: 0;
  margin: 0;
  list-style: none;
}

.subject-sidebar ol ol {
  gap: 0.35rem;
  padding: 0.4rem 0 0 0.85rem;
  border-left: 1px solid var(--line);
  margin-left: 0.3rem;
}

.subject-sidebar a {
  display: block;
  padding: 0.22rem 0.4rem;
  border-radius: 0.25rem;
  line-height: 1.35;
  text-decoration: none;
}

.subject-sidebar a[aria-current="page"] {
  color: var(--accent-dark);
  background: color-mix(in srgb, var(--accent) 10%, var(--paper));
  font-weight: 700;
}

.wiki-sidebar summary {
  padding: 0.22rem 0.4rem;
  color: var(--ink);
  line-height: 1.35;
  cursor: pointer;
}

/* A folder's summary is its own page's link. Sidebar links are blocks, which
   put the disclosure marker on the line above the label; inside a summary the
   link sits beside the marker instead. */
.wiki-sidebar summary > a {
  display: inline;
  padding-left: 0;
}

.wiki-sidebar summary:hover,
.wiki-sidebar summary:focus-visible {
  color: var(--accent-dark);
}

.wiki-sidebar details[open] > summary {
  font-weight: 700;
}

.breadcrumbs {
  margin-bottom: 1rem;
  color: var(--muted);
  font-size: var(--label);
}

.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  padding: 0;
  margin: 0;
  list-style: none;
}

.breadcrumbs li:not(:last-child)::after {
  content: "/";
  padding-left: 0.35rem;
  color: var(--line);
}

.breadcrumbs a {
  color: inherit;
  text-decoration: none;
}

.breadcrumbs a[aria-current="page"] {
  color: var(--ink);
  font-weight: 650;
}

.page-heading {
  padding-bottom: 1.75rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: 2rem;
}

.page-heading h1 {
  max-width: 46rem;
  margin: 0;
  font-family: Charter, "Bitstream Charter", "Iowan Old Style", Georgia, serif;
  font-size: clamp(2rem, 5vw, 3.4rem);
  line-height: 1.08;
  letter-spacing: -0.035em;
}

.page-subtitle {
  margin: 0.75rem 0 0;
  color: var(--muted);
  font-family: var(--bs-font-monospace);
  font-size: var(--label);
  /* A wiki page's subtitle is its source path, and the deep ones are longer
     than a narrow column. Without this the path sets the page width. */
  overflow-wrap: anywhere;
}

.page-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.75rem;
  margin: 1.35rem 0 0;
}

.page-fact {
  display: grid;
  gap: 0.1rem;
}

.page-fact dt {
  color: var(--muted);
  font-size: var(--label);
  font-weight: 750;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.page-fact dd {
  margin: 0;
  font-size: 0.9rem;
}

.page-source-links {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 1.55rem;
}

.page-source-link {
  display: inline-grid;
  place-items: center;
  min-width: 2rem;
  height: 1.55rem;
  padding: 0 0.35rem;
  border: 1px solid var(--line);
  border-radius: 0.25rem;
  color: var(--accent-dark);
  background: var(--wash);
  font-family: ui-sans-serif, system-ui, sans-serif;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  line-height: 1;
  text-decoration: none;
}

.page-source-link:hover,
.page-source-link:focus-visible {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, var(--paper));
}

.page-source-web {
  min-width: 1.55rem;
  padding-inline: 0.25rem;
  font-size: 0.9rem;
}

.page-body {
  --ol-gutter: 2.5rem;
  overflow-wrap: anywhere;
  /* A formula wider than a narrow column has nowhere to go: `mjx-container`
     scrolls display math, but inline math is sized by its run and paints past
     the column, which set the width of the whole document at 375px. Scrolling
     the article keeps that inside the page instead. */
  overflow-x: auto;
  font-size: 1.05rem;
  line-height: 1.65;
}

/* Drop cap: the first paragraph of a page body starts with a large initial
   letter, Tufte-style. Only when the first child is a paragraph (not a
   heading, table, or math block). */
.page-body > p:first-of-type::first-letter {
  font-size: 3.2em;
  line-height: 0.85;
  float: left;
  margin-right: 0.08em;
  margin-top: 0.05em;
  font-weight: 700;
  color: var(--ink);
}

/* The prose is measured, the mathematics is not: a paragraph stops at about
   seventy characters while a display formula, a figure and a table keep the
   whole column, which is what they need and what a narrower column would take
   away from them. */
.page-body :is(p, li, dt, dd, h2, h3, h4, blockquote) {
  max-width: var(--measure);
}

.page-body
  :is(
    figure,
    table,
    mjx-container[display="true"],
    .dt-container
  ) {
  max-width: 100%;
}

/* Figure component: centred image with a caption beneath it. Tufte-style
   figures sit inside the content measure; the caption is smaller, muted,
   and indented to align with the image rather than the text column. */
.page-body figure {
  margin: 1.5rem auto;
  text-align: center;
}

.page-body figure img,
.page-body figure svg {
  display: block;
  margin: 0 auto;
}

.page-body figure figcaption {
  margin-top: 0.4rem;
  font-size: 0.9rem;
  color: var(--muted);
  line-height: 1.4;
}

/* A footnote is a sidenote: the note sits in the margin beside the line that    raises it. Running text stops at the measure while the column runs to 45rem,
   so the margin is the space the prose already leaves -- the note costs no
   width and moves nothing. Both the mark and the note draw their number from
   one counter, so nothing has to thread an index through the AST. */
.page-body {
  counter-reset: sidenote;
}

.sidenote-number {
  counter-increment: sidenote;
}

.sidenote-number::after {
  content: counter(sidenote);
  font-size: 0.75em;
  vertical-align: super;
  line-height: 0;
  color: var(--accent);
}

.sidenote {
  float: right;
  clear: right;
  width: 12rem;
  margin-right: -13.5rem;
  margin-bottom: 0.6rem;
  color: var(--muted);
  font-size: var(--label);
  line-height: 1.45;
  text-align: left;
}

.sidenote::before {
  content: counter(sidenote) " ";
  color: var(--accent);
  font-size: 0.75em;
  vertical-align: super;
  line-height: 0;
}

/* Narrow enough that the column is the measure and there is no margin to sit
   in: the note follows its paragraph instead of floating beside it. */
@media (max-width: 64rem) {
  .sidenote {
    float: none;
    width: auto;
    margin: 0.5rem 0 0.9rem 1.5rem;
    display: block;
    border-left: 2px solid var(--line);
    padding-left: 0.75rem;
  }
}

/* A display formula inherits the measure from whatever holds it, and a formula
   is not prose: three equations on the conformal-maps page were wider than the
   54ch a paragraph gets and were reachable only by scrolling them sideways.
   The block that carries one keeps the column instead. */
.page-body :is(p, li, dd, blockquote):has(.math.display) {
  max-width: 100%;
}

.page-body h2,
.page-body h3 {
  margin-top: 2.25rem;
  line-height: 1.2;
}

/* Pandoc wraps the items of a loose list in `<p>` and leaves a tight list's
   items bare, so two pages one click apart had list rhythms that differed by
   the height of a line. The item owns the spacing; the paragraph inside it
   owns none. */
.page-body li {
  margin-block: 0.35rem;
}

.page-body li > p {
  margin-block: 0;
}

.page-body li > p + p {
  margin-top: 0.5rem;
}

/* List rhythm: normalise the spacing browsers apply inconsistently between
   consecutive list items, whether loose (multiple paragraphs) or tight (bare
   text). The single margin value keeps prose and math lists visually even. */
.page-body :is(ul, ol) {
  padding-inline-start: 1.5rem;
  margin-block: 0.5rem;
}

/* An ordered-list marker is wider than a bullet, and `.page-body` scrolls
   horizontally to hold inline mathematics wider than the column -- which also
   clips an outside marker that overruns its gutter. Two- and three-digit
   markers ("10.", "831.") were losing their leading digit against the article
   edge. Ordered lists get a gutter (`--ol-gutter`) that clears the widest
   marker in the corpus; the marker and its text move right together, so the
   hanging indent a wrapped item keeps is unchanged. */
.page-body ol {
  padding-inline-start: var(--ol-gutter);
}

.page-body :is(ul, ol) > li + li {
  margin-top: 0.25rem;
}

.page-body blockquote {
  margin-inline: 0;
  padding-left: 1rem;
  border-left: 3px solid var(--line);
  color: var(--muted);
}

/* A quote inside an environment or inside another quote would repeat the rule
   already at its left, which read as a grey box drawn inside a grey box. The
   inner one is set in italic and indented instead. */
.page-body :is(.qual-section, blockquote) blockquote {
  padding-left: 0;
  border-left: 0;
  margin-inline-start: 1.25rem;
  font-style: italic;
}

.page-body table {
  width: 100%;
  border-collapse: collapse;
}

.page-body th,
.page-body td {
  padding: 0.55rem 0.7rem;
  border-bottom: 1px solid var(--line);
  text-align: left;
}

.page-toc {
  position: sticky;
  top: 5.5rem;
  align-self: start;
  max-height: calc(100vh - 7rem);
  overflow: auto;
  color: var(--muted);
  font-size: 0.9rem;
}

.page-toc:empty {
  display: none;
}

.page-toc ol,
.page-toc-narrow ol {
  display: grid;
  gap: 0.4rem;
  padding: 0;
  list-style: none;
}

.page-toc a,
.page-toc-narrow a {
  color: inherit;
  text-decoration: none;
}

.page-toc .toc-subsection,
.page-toc-narrow .toc-subsection {
  padding-left: 0.85rem;
}

/* The same headings as a disclosure, where the layout has no room for the
   rail. It carries no fill and no border: the filled box beside it is the
   wiki navigation, and two disclosures that look alike are one object to a
   reader. Shown exactly where the rail is hidden -- the rules below mirror
   the two breakpoints that hide it. */
.page-toc-narrow {
  display: none;
  color: var(--muted);
  font-size: 0.9rem;
  margin-bottom: 2rem;
}

.page-toc-narrow > summary {
  color: var(--ink);
  cursor: pointer;
  font-weight: 700;
}

.page-toc-narrow[open] > summary {
  margin-bottom: 0.8rem;
}

.search-dialog {
  width: min(42rem, calc(100% - 2rem));
  max-height: min(42rem, calc(100% - 4rem));
  padding: 1.25rem;
  border: 1px solid var(--line);
  border-radius: 0.65rem;
  box-shadow: 0 1.5rem 4rem rgb(24 33 43 / 20%);
}

.search-dialog::backdrop {
  background: rgb(24 33 43 / 42%);
  backdrop-filter: blur(2px);
}

.search-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.search-heading h2 {
  margin: 0;
  font-size: 1rem;
}

.search-heading button {
  border: 0;
  font-size: 1.6rem;
  background: transparent;
  cursor: pointer;
}

#site-search-input,
#problem-filter {
  width: 100%;
  padding: 0.75rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: 0.4rem;
  font: inherit;
}

#site-search-input {
  margin-top: 1rem;
}

#site-search-results {
  display: grid;
  gap: 0.25rem;
  padding: 0;
  list-style: none;
}

#site-search-results li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--line);
}

#site-search-results span {
  color: var(--muted);
  font-size: var(--label);
}

.search-result-meta {
  display: grid;
  flex: 0 0 auto;
  justify-items: end;
  line-height: 1.25;
}

.search-result-kind {
  color: var(--accent-dark) !important;
  font-weight: 750;
}

/* The path tail is where two rows titled "Residues" differ, so it wraps
   rather than truncating: an ellipsis here eats the part that identifies the
   row. */
.search-result-detail {
  max-width: 20rem;
  overflow-wrap: anywhere;
}

.catalog-table {
  margin-top: 1rem;
}

.dt-container {
  margin-top: 1rem;
}

#problem-table td:nth-child(2) {
  min-width: 8rem;
  overflow-wrap: normal;
  word-break: normal;
}

.practice-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
  align-items: end;
  margin-top: 0.85rem;
}

.practice-actions label {
  color: var(--muted);
  font-size: var(--label);
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.practice-actions input {
  display: block;
  width: 5rem;
  margin-top: 0.25rem;
  padding: 0.45rem;
  border: 1px solid var(--line);
  border-radius: 0.25rem;
  background: var(--paper);
  color: var(--ink);
}

.practice-actions button {
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: 0.3rem;
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
}

.practice-actions button:disabled {
  cursor: default;
  opacity: 0.45;
}

.practice-sheet {
  margin-top: 2rem;
  border-top: 1px solid var(--line);
  padding-top: 1rem;
}

.practice-sheet h2 {
  text-align: center;
}

.practice-question {
  display: flex;
  gap: 0.85rem;
  margin: 1.5rem 0;
  break-inside: avoid;
}

.practice-number {
  flex: 0 0 auto;
  min-width: 1.75rem;
  font-weight: 750;
}

.practice-body {
  min-width: 0;
  flex: 1 1 auto;
  overflow-x: auto;
}

.practice-source {
  margin-top: 0.45rem;
  color: var(--muted);
  font-size: var(--label);
  font-style: italic;
}

.quarto-title .subtitle {
  font-family: var(--bs-font-monospace);
  font-size: var(--label);
  opacity: 0.6;
}

/* One rule for every semantic section. The label text comes from `data-label`,
   written by the emitter off the same class map the indexer uses, so a new card
   kind is labelled without touching this file — and cannot be added here and
   nowhere else, which is how `.theorem` and `.concept` came to render as plain
   prose. Hints and solutions never reach this rule: reveal.lua replaces those
   divs with a collapsed <details>. */
div.qual-section {
  border-left: 3px solid var(--bs-border-color);
  padding: 0.1rem 0 0.1rem 1rem;
  margin-block: 1rem;
}
div.qual-section::before {
  content: attr(data-label);
  display: block;
  font-variant: small-caps;
  letter-spacing: 0.04em;
  font-weight: 600;
  color: var(--muted);
  font-size: var(--label);
}

/* The card kinds fall into the four registers amsthm already gives a
   mathematician: a statement, its proof, an aside, and a warning. Weight and
   slope carry the distinction -- a statement in italic under a bold label, a
   proof under a hairline ending in a tombstone, an aside flush with the prose
   -- and only the warning spends a colour. Colouring each kind separately was
   considered and rejected: one hue per kind is less scannable than the grey it
   would replace. */
div:is(
  .qual-definition,
  .qual-theorem,
  .qual-proposition,
  .qual-corollary,
  .qual-lemma,
  .qual-fact,
  .qual-claim,
  .qual-problem
) {
  border-left-color: var(--ink);
}

div:is(
    .qual-definition,
    .qual-theorem,
    .qual-proposition,
    .qual-corollary,
    .qual-lemma,
    .qual-fact,
    .qual-claim,
    .qual-problem
  )::before {
  color: var(--ink);
  font-weight: 750;
}

/* amsthm's plain style: the assertion itself is set in italic. A definition
   and a problem stay upright, as amsthm's definition style has them -- they
   are read through, not recalled. */
div:is(
  .qual-theorem,
  .qual-proposition,
  .qual-corollary,
  .qual-lemma,
  .qual-fact,
  .qual-claim
) {
  font-style: italic;
}

/* Mathematics and code carry their own slope and must not inherit one. */
div.qual-section :is(code, kbd, mjx-container) {
  font-style: normal;
}

div.qual-proof {
  border-left-width: 1px;
}

div.qual-proof::before {
  font-variant: normal;
  font-style: italic;
  font-weight: 500;
  letter-spacing: 0;
}

div.qual-proof > p:last-child::after {
  content: " \25A0";
}

/* An aside runs alongside the argument rather than inside it: no rule, one
   step down in size, and a label that does not compete with a statement's. */
div:is(
  .qual-remark,
  .qual-example,
  .qual-slogan,
  .qual-strategy,
  .qual-concept
) {
  padding-left: 0;
  border-left: 0;
  font-size: 0.95em;
}

div:is(
    .qual-remark,
    .qual-example,
    .qual-slogan,
    .qual-strategy,
    .qual-concept
  )::before {
  font-variant: normal;
  font-style: italic;
  font-weight: 600;
  letter-spacing: 0;
}

div.qual-warning {
  border-left-color: var(--alarm);
}

div.qual-warning::before {
  color: var(--alarm);
  font-variant: normal;
  font-weight: 750;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* The authored `title=`, emitted as body text so its mathematics typesets.
   It sits under the kind label and reads as the rest of that heading. */
div.qual-section > .qual-section-title {
  margin: 0 0 0.35rem;
  font-weight: 600;
}

/* The authored `title=`: which part of a multi-part problem this block answers.
   It qualifies the label, so it belongs on the label's line. It is a separate
   element only because it carries mathematics that MathJax typesets at runtime,
   which `content: attr()` would print as TeX source -- so the pseudo-element
   joins it on the line rather than the other way round. */
div.qual-section:has(> .qual-section-qualifier)::before {
  display: inline;
}

div.qual-section > .qual-section-qualifier {
  display: inline;
  margin: 0 0 0 0.4em;
  color: var(--muted);
  font-size: var(--label);
  font-style: normal;
}

/* A review question is apparatus about the card, not part of it, so it joins
   the metadata band the id already uses. The run-in label is
   what separates it from them: in that band a bare sentence would read as
   another locator, and the sentence itself has to stay plain text so MathJax
   can typeset the mathematics inside it. */
.review-question {
  margin-block: 0.75rem;
  color: var(--muted);
  font-size: var(--label);
  font-style: normal;
}

.review-question::before {
  content: "Asked as ";
  font-variant: small-caps;
  font-weight: 700;
}

.result-slogan {
  display: flex;
  align-items: baseline;
  gap: 0.65rem;
  margin-block: 0.6rem 1rem;
  font-size: var(--label);
}

.result-slogan-badge {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border: 1px solid var(--accent);
  border-radius: 999px;
  color: var(--accent-dark);
  font-weight: 700;
}

.result-slogan-suggest {
  color: var(--muted);
}

/* A revealed answer is a section of the card, not a panel bolted to it: the
   rule at its left is the one the environments above it use, and the accent is
   there because the summary is the only part of it you click. The grey filled
   box it used to be was indistinguishable from the navigation disclosure and
   from the backlink list at the foot of the page. */
details.reveal {
  border-left: 3px solid var(--accent);
  padding: 0.1rem 0 0.1rem 1rem;
  margin-block: 1rem;
}
details.reveal > summary {
  cursor: pointer;
  color: var(--accent-dark);
  font-variant: small-caps;
  font-weight: 700;
  letter-spacing: 0.04em;
  font-size: var(--label);
}
details.reveal[open] > summary {
  margin-bottom: 0.5rem;
}

/* Lamport-structured steps: a nested outline, each step labelled by its
   authored number and indented one stop per level so the proof skeleton reads
   at a scan. The `<1>…<2>…` markers arrive as literal text without this. */
.pf-group {
  margin: 0.4rem 0;
}
.pf-step {
  margin: 0.35rem 0;
  padding-left: 1.4rem;
  text-indent: -1.4rem;
}
.pf-step .pf-group {
  margin-left: 1.4rem;
  padding-left: 0;
  text-indent: 0;
}
.pf-step .pf-group .pf-step {
  padding-left: 1.6rem;
  text-indent: -1.6rem;
}
.pf-step .pf-group .pf-step .pf-group .pf-step {
  padding-left: 1.8rem;
  text-indent: -1.8rem;
}

/* A proof div can separate sibling Lamport markers in the Pandoc block tree.
   Such a marker still carries its authored level even when it cannot remain
   physically nested under the preceding pf-step, so preserve the visual depth
   from the level class itself. Nested groups already receive their indentation
   from the parent step and therefore reset this extra margin. */
.pf-group > .pf-step.pf-level-2 {
  margin-left: 1.4rem;
}
.pf-group > .pf-step.pf-level-3 {
  margin-left: 2.8rem;
}
.pf-step > .pf-group > .pf-step {
  margin-left: 0;
}
/* Proofs written in the Lamport filter's syntax (`.pf` root, `.pf-step` and
   `.pf-qed` steps, `.pf-proof` bodies). The filter prints the numbers; each
   proof body sits one indentation stop inside the step it proves. */
.pf {
  margin: 0.4rem 0;
}
.pf-qed {
  margin: 0.35rem 0;
  padding-left: 1.4rem;
  text-indent: -1.4rem;
}
.pf-proof {
  margin-left: 0;
  padding-left: 0;
  text-indent: 0;
}
.pf-number {
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  margin-right: 0.25rem;
}

div.panel {
  margin-block: 1rem;
}
div.panel > ul {
  margin-bottom: 0;
}

.relation-groups {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.75rem;
  margin-top: 3rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}

/* End-of-page apparatus: a rule and a label, not a filled card. */
.relation-group {
  min-width: 0;
  padding-top: 0.6rem;
  border-top: 1px solid var(--line);
}

.relation-group h2 {
  margin: 0 0 0.65rem;
  font-family: inherit;
  font-size: var(--label);
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

/* The apparatus lists carry their own gap and must not also take the prose
   list rhythm. */
.relation-group li {
  margin-block: 0;
}

.relation-group ul {
  display: grid;
  gap: 0.65rem;
  padding: 0;
  margin: 0;
  list-style: none;
}

.relation-group li {
  display: grid;
  gap: 0.12rem;
  min-width: 0;
}

.relation-group li > span,
.relation-group small,
.relation-empty {
  color: var(--muted);
  font-size: var(--label);
}

.relation-empty {
  margin: 0;
}

.reading-order {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
  margin-top: 3rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}

.reading-order span {
  display: grid;
  gap: 0.15rem;
}

.reading-order small {
  color: var(--muted);
  font-size: var(--label);
  font-weight: 750;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.reading-following {
  grid-column: 2;
  text-align: right;
}

/* Reading runs on past the end of a folder, so a next or previous link often
   lands somewhere else. This says where. */
.reading-order .reading-section {
  color: var(--muted);
  font-size: var(--label);
}

@media (max-width: 64rem) {
  .page-layout.subject-layout {
    display: block;
    width: min(100% - 2rem, 45rem);
    margin-top: 2.5rem;
  }

  .subject-sidebar {
    position: static;
    max-height: none;
    padding: 0.85rem 1rem;
    border: 1px solid var(--line);
    border-radius: 0.4rem;
    margin-bottom: 2rem;
    overflow: visible;
    background: var(--wash);
  }

  .sidebar-wide {
    display: none;
  }

  .sidebar-narrow {
    display: block;
  }

  .sidebar-narrow > summary {
    color: var(--ink);
    cursor: pointer;
    font-weight: 700;
  }

  .sidebar-narrow[open] > summary {
    margin-bottom: 0.8rem;
  }

  .wiki-sidebar {
    max-height: 50vh;
    overflow: auto;
  }

  .subject-sidebar ol ol {
    border-color: color-mix(in srgb, var(--line) 70%, var(--muted));
  }

  .wiki-sidebar summary,
  .subject-sidebar a {
    min-height: 2.75rem;
    padding-block: 0.8rem;
  }

  .subject-layout .page-toc {
    display: none;
  }

  .subject-layout .page-toc-narrow {
    display: block;
  }
}

@media (max-width: 56rem) {
  .site-nav {
    flex-wrap: wrap;
    gap: 0.75rem 1rem;
    padding-block: 0.65rem;
  }

  .site-links {
    order: 3;
    width: 100%;
    gap: 1rem;
    overflow-x: auto;
  }

  .search-open {
    margin-left: auto;
  }

  .page-layout {
    display: block;
    width: min(100% - 2rem, 45rem);
    margin-top: 2.5rem;
  }

  .page-toc {
    display: none;
  }

  .page-toc-narrow {
    display: block;
  }

  .relation-groups {
    grid-template-columns: 1fr;
  }

  .site-footer {
    width: min(100% - 2rem, 45rem);
    margin-top: -4rem;
  }
}

@media (max-width: 38rem) {
  .site-nav {
    width: min(100% - 1.25rem, 86rem);
  }

  .page-layout {
    width: min(100% - 1.25rem, 45rem);
  }

  .site-footer {
    align-items: flex-start;
    width: min(100% - 1.25rem, 45rem);
  }

  /* The detail is the only thing separating two rows that both read
     "Algebra / Page", so the narrow layout stacks it under the title instead
     of dropping it. */
  #site-search-results li {
    display: grid;
    gap: 0.15rem;
  }

  .search-result-meta {
    grid-template-columns: auto minmax(0, 1fr);
    gap: 0.5rem;
    justify-items: start;
  }

  .search-result-detail {
    max-width: 100%;
  }
}

/* The palette is the only thing that changes: every rule above paints with the
   tokens, so the dark page is the same document under a different ground. */
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --ink: #e3e9ef;
    --muted: #9fadbb;
    --line: #2b343d;
    --paper: #11171d;
    --wash: #1a222a;
    --accent: #6fb3ee;
    --accent-dark: #a8d1f7;
    --alarm: #f08e82;
  }

  /* Figures are black ink, most of them on a transparent ground, and a black
     drawing on a dark page is an empty rectangle. Inverting turns the ink
     white and turns a scan's white ground dark; the hue rotation puts the
     colours in a coloured plot back where they started. */
  .page-body :is(img, svg) {
    filter: invert(1) hue-rotate(180deg);
  }
}

/* Printed, the page is a document: the navigation, the rails and the search
   affordances are screen apparatus and do not belong on paper. */
@media print {
  :root {
    color-scheme: light;
    --ink: #000000;
    --muted: #333333;
    --line: #b6bcc2;
    --paper: #ffffff;
    --wash: #ffffff;
    --accent: #000000;
    --accent-dark: #000000;
    --alarm: #000000;
  }

  @page {
    margin: 2cm;
  }

  .site-header,
  .page-toc,
  .page-toc-narrow,
  .subject-sidebar,
  .search-dialog,
  .search-open {
    display: none;
  }

  body.printing-practice :is(.page-heading, .dt-container, .practice-actions, .site-footer) {
    display: none;
  }

  .page-layout,
  .page-layout.subject-layout {
    display: block;
    width: auto;
    margin: 0;
  }

  /* On screen an over-wide formula scrolls; on paper there is nowhere to
     scroll to, so it must be allowed to print outside the measure. */
  .page-body,
  mjx-container[display="true"] {
    overflow: visible;
  }

  .page-body {
    font-size: 11pt;
  }

  a {
    color: inherit;
    text-decoration: none;
  }

  /* A formula, a figure or a table split across a page fold is unreadable. A
     long proof is not: forbidding a break there would push whole environments
     to the next sheet and leave the fold blank. */
  figure,
  table,
  mjx-container[display="true"] {
    break-inside: avoid;
  }

  h1,
  h2,
  h3 {
    break-after: avoid;
  }
}

.header-random-problem {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.header-random-problem label {
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 650;
  white-space: nowrap;
}

.header-random-problem select,
.header-random-problem button {
  height: 2.15rem;
  padding: 0.35rem 0.55rem;
  border: 1px solid var(--line);
  border-radius: 0.35rem;
  background: var(--paper);
  color: var(--ink);
}

.header-random-problem select {
  max-width: 11.5rem;
}

.header-random-problem button {
  cursor: pointer;
}

.random-problem-status {
  position: absolute;
  overflow: hidden;
  width: 1px;
  height: 1px;
  clip: rect(0 0 0 0);
}

@media (max-width: 70rem) {
  .header-random-problem label {
    position: absolute;
    overflow: hidden;
    width: 1px;
    height: 1px;
    clip: rect(0 0 0 0);
  }
}

@media (max-width: 56rem) {
  .header-random-problem {
    order: 3;
    width: 100%;
  }

  .header-random-problem select {
    flex: 1;
    max-width: 16rem;
  }

  .site-links {
    order: 4;
  }
}
