/*
  The look of the site.

  DocFX serves the "modern" template and then this file last, so everything here is an override
  of Bootstrap 5 variables the template already uses. Nothing is copied out of the template and
  nothing is reimplemented: a DocFX upgrade brings its own fixes and this keeps applying on top.
  Where a rule targets a class rather than a variable, the class is one of the handful the
  template's master layout declares.

  Two typefaces and one accent. Fraunces for headings, IBM Plex Sans for text, IBM Plex Mono for
  code, and a deep green on warm ivory. No Inter, no Roboto, no gradient: the point is a page that
  does not read as the default anything.
*/

@import url("https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,600&family=IBM+Plex+Mono:wght@400;500&family=IBM+Plex+Sans:wght@400;500;600&display=swap");

:root {
  --mp-display: Fraunces, Georgia, "Times New Roman", serif;
  --mp-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mp-mono: "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
}

[data-bs-theme="light"] {
  --mp-ink: #1a1a18;
  --mp-muted: #5e5c55;
  --mp-muted-rgb: 94, 92, 85;
  --mp-ground: #fbf9f5;
  --mp-raised: #ffffff;
  --mp-line: #e3dfd5;
  --mp-accent: #1d6b57;
  --mp-accent-rgb: 29, 107, 87;
  --mp-accent-strong: #14503f;
  --mp-accent-strong-rgb: 20, 80, 63;
  --mp-ink-rgb: 26, 26, 24;
  --mp-ground-rgb: 251, 249, 245;
  --mp-accent-wash: #eaf1ee;
  --mp-code-bg: #f4f1ea;
}

[data-bs-theme="dark"] {
  --mp-ink: #f4f1ea;
  --mp-muted: #9fada8;
  --mp-muted-rgb: 159, 173, 168;
  --mp-ground: #16211e;
  --mp-raised: #1d2b27;
  --mp-line: #2b3a35;
  --mp-accent: #8fd1b8;
  --mp-accent-rgb: 143, 209, 184;
  --mp-accent-strong: #b4e3cf;
  --mp-accent-strong-rgb: 180, 227, 207;
  --mp-ink-rgb: 244, 241, 234;
  --mp-ground-rgb: 22, 33, 30;
  --mp-accent-wash: #1d3b31;
  --mp-code-bg: #10201a;
}

/* The template reads these; setting them is most of the work. */
[data-bs-theme="light"],
[data-bs-theme="dark"] {
  --bs-font-sans-serif: var(--mp-sans);
  --bs-font-monospace: var(--mp-mono);
  --bs-body-font-family: var(--mp-sans);
  --bs-body-bg: var(--mp-ground);
  --bs-body-color: var(--mp-ink);
  --bs-emphasis-color: var(--mp-ink);
  --bs-secondary-color: var(--mp-muted);
  --bs-secondary-bg: var(--mp-raised);
  --bs-tertiary-bg: var(--mp-raised);
  --bs-border-color: var(--mp-line);
  --bs-border-color-translucent: var(--mp-line);
  --bs-link-color: var(--mp-accent);
  --bs-link-hover-color: var(--mp-accent-strong);
  /*
    Bootstrap paints a link with rgba(var(--bs-link-color-rgb), …) rather than with the colour
    variable, so setting the colour alone leaves every link the default blue. Same for the body
    pair, which backgrounds built with rgba() read.
  */
  --bs-link-color-rgb: var(--mp-accent-rgb);
  --bs-link-hover-color-rgb: var(--mp-accent-strong-rgb);
  --bs-body-color-rgb: var(--mp-ink-rgb);
  --bs-body-bg-rgb: var(--mp-ground-rgb);
  --bs-emphasis-color-rgb: var(--mp-ink-rgb);
  /*
    The same trap a second time, and the reason this is worth a note: .link-secondary and
    .text-secondary read the rgb pair, not --bs-secondary-color. Left unset, the "View source"
    link and the namespace line on every API page kept Bootstrap's grey, which measured 3.53:1
    on the dark ground — under the 4.5:1 that body-sized text needs. Set both halves of a pair.
  */
  --bs-secondary-color-rgb: var(--mp-muted-rgb);
  --bs-tertiary-color-rgb: var(--mp-muted-rgb);
  /*
    And a third name for what looks like the same thing: .text-secondary reads
    --bs-secondary-color-rgb while .link-secondary reads --bs-secondary-rgb, which is the theme
    colour rather than the text colour. Both are set, because both appear on an API page.
  */
  --bs-secondary-rgb: var(--mp-muted-rgb);
  --bs-secondary: var(--mp-muted);
  --bs-primary: var(--mp-accent);
  --bs-code-color: var(--mp-accent-strong);
  --bs-border-radius: 0.625rem;
  --bs-border-radius-sm: 0.5rem;
  --bs-border-radius-lg: 0.875rem;
  --bs-body-font-size: 1rem;
  --bs-body-line-height: 1.7;
}

body {
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* The mark is the package icon, which comes at its own size and is not a 20px template svg. */
.navbar-brand #logo {
  width: 1.7rem;
  height: 1.7rem;
  margin-right: 0.55rem;
  border-radius: 0.35rem;
}

/* Headings carry the display face; everything else stays in the body face. */
h1,
h2,
h3,
h4,
.navbar-brand {
  font-family: var(--mp-display);
  font-weight: 600;
  letter-spacing: -0.015em;
}

h1 {
  font-size: clamp(2.1rem, 1.5rem + 2vw, 2.9rem);
  line-height: 1.1;
  letter-spacing: -0.022em;
  margin-bottom: 1rem;
}

h2 {
  font-size: 1.7rem;
  line-height: 1.2;
  margin-top: 2.75rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--mp-line);
}

h3 {
  font-size: 1.3rem;
  margin-top: 2rem;
}

.content article h2:first-of-type {
  border-top: 0;
  padding-top: 0;
}

.navbar-brand {
  font-size: 1.4rem;
  letter-spacing: -0.01em;
}

/*
  The bar and the sidebar sit on the ground colour rather than a panel of their own, so the page
  reads as one surface instead of three stacked ones.
*/
header .navbar {
  background: var(--mp-ground) !important;
  border-bottom: 1px solid var(--mp-line) !important;
}

.toc-offcanvas,
nav.toc {
  background: var(--mp-ground);
}

nav.toc .nav-link {
  border-radius: 0.5rem;
  padding: 0.4rem 0.7rem;
  color: var(--mp-muted);
}

nav.toc .nav-link:hover {
  background: var(--mp-accent-wash);
  color: var(--mp-accent-strong);
}

nav.toc .nav-link.active {
  background: var(--mp-accent-wash);
  color: var(--mp-accent-strong);
  font-weight: 600;
}

/* "In this article" is a plain list of links, not a nav-link list like the sidebar. */
#affix h5 {
  font-family: var(--mp-sans);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--mp-muted);
  border-bottom: 1px solid var(--mp-line) !important;
  padding-bottom: 0.6rem;
}

#affix ul {
  list-style: none;
  padding-left: 0;
  border-left: 1px solid var(--mp-line);
}

#affix ul li a {
  display: block;
  padding: 0.3rem 0 0.3rem 0.9rem;
  margin-left: -1px;
  border-left: 2px solid transparent;
  color: var(--mp-muted) !important;
  font-size: 0.9rem;
  text-decoration: none;
}

#affix ul li a:hover,
#affix ul li a.active {
  border-left-color: var(--mp-accent);
  color: var(--mp-accent-strong) !important;
}

/*
  A code block gets its surface from the theme rather than a fixed dark one. The mockup had dark
  snippets on the light page and they look better, but highlight.js ships one token palette per
  theme and picks it by lightness: forcing a dark surface under the light palette turns comments
  and strings unreadable. Recolouring every token by hand would work until the next highlight.js
  adds one nobody covered, and an unreadable snippet is a worse page than a plainer one.

  The class is on the code element, so the background has to be beaten on the class, not on the
  element — .hljs outranks a bare `pre code`.
*/
pre {
  background: var(--mp-code-bg);
  border: 0;
  border-radius: 0.75rem;
  padding: 1.15rem 1.25rem;
  font-size: 0.875rem;
  line-height: 1.75;
}

pre code.hljs,
pre > code {
  background: transparent;
  padding: 0;
}

:not(pre) > code {
  background: var(--mp-accent-wash);
  color: var(--mp-accent-strong);
  padding: 0.12em 0.38em;
  border-radius: 0.3rem;
  font-size: 0.875em;
}

/*
  A measurement table is read by scanning a column, so the numbers line up and the boxes go. The
  template hands tables Bootstrap's .table-bordered, which rules every cell; that is turned off
  here rather than left to fight the rows below.
*/
.content article table.table {
  --bs-table-bg: transparent;
  border-collapse: collapse;
  font-size: 0.94rem;
}

.content article table.table-bordered > :not(caption) > * > * {
  border-width: 0;
  box-shadow: none;
}

.content article table.table > thead > tr > th {
  border-bottom: 1px solid var(--mp-line);
  border-top: 0;
  font-weight: 600;
  font-size: 0.82rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--mp-muted);
  padding: 0.7rem 1rem;
}

.content article table.table > tbody > tr > td {
  border-top: 1px solid var(--mp-line);
  border-bottom: 0;
  padding: 0.8rem 1rem;
  vertical-align: top;
}

.content article table.table > tbody > tr > td:not(:first-child) {
  font-variant-numeric: tabular-nums;
}

blockquote {
  border-left: 3px solid var(--mp-accent);
  background: var(--mp-accent-wash);
  border-radius: 0 0.625rem 0.625rem 0;
  padding: 1rem 1.25rem;
  margin: 1.5rem 0;
}

blockquote > :last-child {
  margin-bottom: 0;
}

.search .form-control,
#search-query {
  background: var(--mp-raised);
  border: 1px solid var(--mp-line);
  border-radius: 0.625rem;
}

footer,
footer .border-top {
  border-top: 1px solid var(--mp-line) !important;
  color: var(--mp-muted);
}

/* Comfortable measure: prose past about 80 characters a line is harder to come back to. */
.content article {
  max-width: 54rem;
}

.content article > p,
.content article > ul,
.content article > ol {
  margin-bottom: 1.15rem;
}

/*
  The language switch. The template renders it as an icon and a tooltip; a tooltip is no use to
  someone scanning for the other language, so the title is shown as the label. Only the direct
  anchor child is the switch — the theme picker beside it is a dropdown, not an anchor.
*/
.icons > a[title] {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--mp-muted);
  font-family: var(--mp-sans);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.02em;
}

.icons > a[title]::after {
  content: attr(title);
}

.icons > a[title]:hover,
.icons > a[title]:focus-visible {
  color: var(--mp-accent);
}
