:root {
  --navbar-bg: #ffffff;
  --navbar-fg: #333333;
  --navbar-fg-active: #000000;
  --navbar-border: #e6e6e6;
  --section-nav-h: 0px;   /* set by section-nav.js to the bar's real height */
}

/* ── Top menubar (Quarto navbar) — blue background, white/light-blue text ──
   Quarto pins the header via `header.fixed-top` and offsets the body via
   `body.nav-fixed{padding-top:64px}`; do NOT set position:fixed on .navbar
   here (it would take the nav out of the header's flow, collapse the header
   height to 0, and make Quarto's headerOffset() return 0 → content slides
   under the bar). Only recolor. */
.navbar {
  background-color: var(--navbar-bg) !important;
  border-bottom: 1px solid var(--navbar-border);
}
/* Keep the navbar visible at all times. Quarto's headroom JS normally hides
   the bar (translateY(-100%)) on scroll-down; override the unpinned state so
   it always stays fixed and visible while scrolling. */
header.headroom--unpinned { transform: translateY(0%) !important; }
.navbar .navbar-brand,
.navbar .nav-link,
.navbar .navbar-toggler {
  color: var(--navbar-fg) !important;
}
.navbar .navbar-brand:hover,
.navbar .nav-link:hover,
.navbar .nav-link.active,
.navbar .nav-link:focus {
  color: var(--navbar-fg-active) !important;
}
/* The navbar entry for the section the current page belongs to. Quarto marks
   only exact page matches, so nav-active.js sets this by path prefix. */
.navbar .navbar-nav.me-auto .nav-link.active {
  font-weight: 600;
}
.navbar .navbar-toggler {
  border-color: color-mix(in srgb, var(--navbar-fg) 60%, transparent);
}
.navbar .navbar-toggler-icon {
  filter: none;
}
/* Make the navbar search lens (loupe) white so it is visible against the
   blue bar. Quarto's search injects the icon via an Algolia autocomplete;
   Bootstrap paints the SVG glyph gray. Override the stroke colour on the
   injected icon. */
.navbar #quarto-search.type-overlay .aa-Autocomplete svg.aa-SubmitIcon,
.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-Label svg,
.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-LoadingIndicator svg {
  color: var(--navbar-fg-active) !important;
}
.navbar .dropdown-menu {
  background-color: var(--navbar-bg);
}
.navbar .dropdown-menu .dropdown-item {
  color: var(--navbar-fg) !important;
}
.navbar .dropdown-menu .dropdown-item:hover,
.navbar .dropdown-menu .dropdown-item:focus,
.navbar .dropdown-menu .dropdown-item.active {
  background-color: color-mix(in srgb, var(--navbar-bg) 85%, var(--bs-white));
  color: var(--navbar-fg-active) !important;
}
/* ── Secondary (section) navigation bar — horizontal ──
   Built by section-nav.js from the current section's top-level sidebar
   entries and appended inside #quarto-header, directly below the navbar.
   Quarto measures header.clientHeight for the body offset, so the bar needs
   no manual page padding. --section-nav-h is the bar's measured height. */
.section-nav {
  background: var(--navbar-bg);
  border-bottom: 1px solid var(--navbar-border);
}
.section-nav-list {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0.25rem; list-style: none; margin: 0;
  padding: 0.2rem 1rem;
  overflow-x: auto; scrollbar-width: thin;
}
.section-nav-item { flex: 0 0 auto; }
.section-nav-link {
  display: inline-block;
  padding: 0.3rem 0.65rem;
  font-size: 0.82rem; line-height: 1.2;
  color: var(--navbar-fg); text-decoration: none;
  border-radius: var(--bs-border-radius);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.section-nav-link:hover,
.section-nav-link:focus {
  color: var(--navbar-fg-active);
  background: color-mix(in srgb, var(--navbar-fg) 10%, transparent);
}
.section-nav-link.active {
  color: var(--navbar-fg-active);
  font-weight: 600;
  border-bottom-color: currentColor;
}
/* On small screens the navbar collapses and the sidebar carries the section
   navigation via its own toggle, so the bar is redundant. */
@media (max-width: 991.98px) {
  .section-nav { display: none; }
}

/* Keep the right margin sidebar (TOC) pinned while scrolling. */
 #quarto-margin-sidebar {
   position: sticky !important;
   top: calc(72px + var(--section-nav-h)) !important;   /* below the fixed header + section nav */
   align-self: start;
   overflow-y: auto;
   overscroll-behavior: contain;
   max-height: calc(100vh - 88px) !important;
 }
/* NOTE: these rules are deliberately UNLAYERED. styles.css is linked after
   Bootstrap/Quarto CSS in the site, so unlayered rules win over Quarto's
   unlayered callout styles by source order. Wrapping them in @layer would
   DEMOTE them below unlayered CSS and the overrides would not apply. */
  body, p, li, dd, td, th { text-align: justify; hyphens: auto; }
  h1,h2,h3,h4,h5,h6, nav, .sidebar, pre, code,
  .callout-title-container, .registry-badge, .registry-name,
  dt, caption, figcaption, .quarto-title-meta { text-align: unset; }

  figure img { max-inline-size: 100%; block-size: auto; }
  .math.display, math[display="block"] { overflow-x: auto; padding-block: 0.2em; }
  .sidebar nav[role="doc-toc"] ul { list-style-type: none; padding-inline-start: 0.8em; }

  /* Site search lives in the navbar; the sidebar also renders an empty search
     container that reserves ~25px above the nav. Hide it and tighten the top
     padding so the left nav starts just below the navbar instead of ~60px down. */
  #quarto-sidebar .flex-shrink-0:has(.sidebar-search) { display: none; }
  #quarto-sidebar { padding-top: 0.35rem; }
  #quarto-sidebar .sidebar-menu-container { padding-top: 0.4rem; }

  /* Accent boxes — one shared frame. Each box sets `--box-accent` (a cosmo
     token) and `--box-accent-strong` (a fully saturated, darkened variant),
     from which the border, the tinted fill, and the vivid title badge derive.
     `--box-accent-strong` is set PER FAMILY (below), not computed here, so it
     can be tuned per hue to guarantee WCAG AA contrast (>= 4.5:1) of the
     white title text against the badge. */
  .callout.callout-style-default.callout-warning,
  .callout.callout-style-default.callout-note,
  .callout.callout-style-default.callout-important,
  .callout.callout-style-default.callout-tip,
  .callout.callout-style-default.callout-caution {
    border-inline-start: 4.5px solid var(--box-accent-strong);
    border-top: 1px solid color-mix(in srgb, var(--box-accent) 60%, var(--bs-white));
    border-right: 1px solid color-mix(in srgb, var(--box-accent) 60%, var(--bs-white));
    border-bottom: 1px solid color-mix(in srgb, var(--box-accent) 60%, var(--bs-white));
    background-color: var(--box-bg);
    background-image: linear-gradient(180deg, rgba(255,255,255,0.32), rgba(255,255,255,0) 42%);
    color: var(--box-fg, color-mix(in srgb, var(--box-accent) 60%, var(--bs-black)));
    padding: 0.8rem 1rem;
    margin-block-end: 1rem;
  }
  /* Quarto callout header — icon + title on one line. Transparent so the
     box's own pale fill shows through; only the title badge carries the
     vivid accent. */
  .callout.callout-style-default > .callout-header {
    display: flex; align-items: center; gap: 0.5em; margin-block-end: 0.4em;
    background: transparent !important;
    opacity: 1;
    padding-top: 0; padding-bottom: 0;
  }
  .callout-icon-container { display: inline-flex; align-items: center; }
  .callout.callout-style-default > .callout-header .callout-title-container {
    background: var(--box-accent-strong);
    color: var(--bs-white);
    padding: 0.2em 0.6em;
    border-radius: var(--bs-border-radius);
    display: flex;
    align-items: center;
    flex: 1 1 auto;
    font-weight: 600;
  }
  .callout.callout-style-default > .callout-header .callout-icon {
    color: var(--box-accent-strong);
  }
  .callout.callout-style-default > .callout-header .callout-icon::before {
    background-image: none;
    -webkit-mask-image: var(--callout-icon);
    mask-image: var(--callout-icon);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: contain;
    mask-size: contain;
    background-color: var(--box-accent-strong);
  }
  /* Callouts built with `callout-icon: false` carry no icon element and no
     stray icon glyph in the title. Draw the family icon on the header. */
  .callout.callout-style-default.callout-titled.no-icon > .callout-header::before {
    content: "";
    flex: 0 0 auto;
    height: 0.95rem;
    width: 0.95rem;
    display: inline-block;
    background-color: var(--box-accent-strong);
    -webkit-mask-image: var(--callout-icon);
    mask-image: var(--callout-icon);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: contain;
    mask-size: contain;
  }
  .callout.callout-style-default .callout-body-container {
    color: var(--box-fg, color-mix(in srgb, var(--box-accent) 60%, var(--bs-black)));
  }

  .callout-warning   { --box-accent: #c9c9c9;  --box-accent-strong: #666666; --box-bg: #f4f4f4;  --box-fg: #1c1c1c;  --callout-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path d='M7.938 2.016A.13.13 0 0 1 8.002 2a.13.13 0 0 1 .063.016.146.146 0 0 1 .054.057l6.857 11.667c.036.06.035.124.002.183a.163.163 0 0 1-.054.06.116.116 0 0 1-.066.017H1.146a.115.115 0 0 1-.066-.017.163.163 0 0 1-.054-.06.176.176 0 0 1 .002-.183L7.884 2.073a.147.147 0 0 1 .054-.057zm1.044-.45a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566z'/><path d='M7.002 12a1 1 0 1 1 2 0 1 1 0 0 1-2 0zM7.1 5.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995z'/></svg>"); }
  .callout-note      { --box-accent: #c4c4c4; --box-accent-strong: #6b6b6b; --box-bg: #f7f7f7; --box-fg: #222222;   --callout-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z'/><path d='m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z'/></svg>"); }
  .callout-important { --box-accent: #a8a8a8; --box-accent-strong: #2b2b2b; --box-bg: #f1f1f1; --box-fg: #111111; --callout-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z'/><path d='M7.002 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0zM7.1 4.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 4.995z'/></svg>"); }
  .callout-tip       { --box-accent: #bdbdbd; --box-accent-strong: #5f5f5f; --box-bg: #f5f5f5; --box-fg: #222222;    --callout-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path d='M2 6a6 6 0 1 1 10.174 4.31c-.203.196-.359.4-.453.619l-.762 1.769A.5.5 0 0 1 10.5 13a.5.5 0 0 1 0 1 .5.5 0 0 1 0 1l-.224.447a1 1 0 0 1-.894.553H6.618a1 1 0 0 1-.894-.553L5.5 15a.5.5 0 0 1 0-1 .5.5 0 0 1 0-1 .5.5 0 0 1-.46-.302l-.761-1.77a1.964 1.964 0 0 0-.453-.618A5.984 5.984 0 0 1 2 6zm6-5a5 5 0 0 0-3.479 8.592c.263.254.514.564.676.941L5.83 12h4.342l.632-1.467c.162-.377.413-.687.676-.941A5 5 0 0 0 8 1z'/></svg>"); }
  .callout-caution   { --box-accent: #9a9a9a; --box-accent-strong: #111111; --box-bg: #eeeeee; --box-fg: #111111; --callout-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path d='M9.97 4.88l.953 3.811C10.158 8.878 9.14 9 8 9c-1.14 0-2.159-.122-2.923-.309L6.03 4.88C6.635 4.957 7.3 5 8 5s1.365-.043 1.97-.12zm-.245-.978L8.97.88C8.718-.13 7.282-.13 7.03.88L6.274 3.9C6.8 3.965 7.382 4 8 4c.618 0 1.2-.036 1.725-.098zm4.396 8.613a.5.5 0 0 1 .037.96l-6 2a.5.5 0 0 1-.316 0l-6-2a.5.5 0 0 1 .037-.96l2.391-.598.565-2.257c.862.212 1.964.339 3.165.339s2.303-.127 3.165-.339l.565 2.257 2.391.598z'/></svg>"); }

  /* Epigraphs / blockquotes — theme border width + subtle hue */
  :where(.epigraph, blockquote) {
    border-inline-start: var(--bs-border-width) solid var(--bs-gray-400);
    background: var(--bs-light);
    color: var(--bs-secondary-color);
    font-style: italic;
    padding: 0.6em 1em;
  }

  /* ── Glossary tooltips (custom popover) ── */
  .gt, glossary-term { border-bottom: 1.5px dashed var(--box-fg, #9a9a9a); cursor: help; color: inherit; display: inline; }

  .gt-pop {
    position: fixed; z-index: 99999;     max-inline-size: min(92vw, 640px);
    background: var(--bs-body-bg); border: var(--bs-border-width) solid var(--bs-border-color);
    border-radius: var(--bs-border-radius-lg); box-shadow: var(--bs-box-shadow);
    padding: 12px 14px; font-size: 0.875rem; line-height: 1.5;
    display: flex; flex-direction: column; gap: 4px;
    opacity: 0; visibility: hidden; transform: translateY(4px);
    transition: opacity .15s ease, visibility .15s ease, transform .15s ease;
    pointer-events: none; overflow-wrap: break-word; word-break: break-word;
    max-block-size: min(80vh, 600px); overflow-y: auto;
  }
  .gt-show { opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto; }

  .gt-cat { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; color: var(--bs-secondary-color); }
  .gt-term { font-weight: 700; font-size: 0.95rem; color: var(--bs-body-color); }
  .gt-def { color: var(--bs-body-color); }
  .gt-ol { margin: 2px 0 0 0; padding-inline-start: 1.25em; }
  .gt-ol li { margin-top: 2px; }

  .gt-also, .gt-sources { font-size: 0.8rem; color: var(--bs-secondary-color); border-top: var(--bs-border-width) solid var(--bs-border-color); padding-top: 4px; margin-top: 2px; }
  .gt-sources { font-size: 0.75rem; line-height: 1.6; }
  .gt-sources a { color: var(--bs-link-color, #111111) !important; text-decoration: none; }
  .gt-sources a:hover { text-decoration: underline; }
  .gt-pop b { color: var(--bs-emphasis-color); }

  .unbulleted { list-style-type: none; padding-inline-start: 0; }

  /* Empty placeholder <span> nodes emitted between items by some Quarto
     versions in the grid-listing template. Hide them. */
  .quarto-listing-container-grid .list.grid > span { display: none; }

  /* Quarto's HTML writer injects whitespace-only placeholder <span> nodes as
     direct children of #quarto-content. Hide them. */
  #quarto-content > span { display: none; }

  /* Collapse the right margin sidebar when it holds no content. */
  #quarto-content.no-margin-sidebar {
    grid-template-columns: [screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end];
  }
  #quarto-content.no-margin-sidebar #quarto-margin-sidebar { display: none; }

/* ── Knowledge-Gap Indicators: master–detail post browser ──
   Left pane = list of post references, right pane = the selected post.
   The panes are siblings in a two-column grid; the list stays pinned
   while the post scrolls. Below 900px the grid stacks, list first. */

/* List palette. The list, the family headers and the two controls are chrome,
   so they carry their own colour roles. Do NOT borrow `--navbar-bg` as ink:
   it is a SURFACE colour (#ffffff light, #121212 dark), so an ink derived
   from it vanishes — the light-mode family title came out #d1d1d1 on white,
   the dark-mode one #0f0f0f on #121212, and both controls disappeared in one
   theme or the other. These roles are ink colours, set for light here and
   re-set for dark in the dark-mode block below. */
:root {
  --kg-ink: #1b1b1b;        /* family titles, control labels, tags */
  --kg-ink-soft: #5a5a5a;   /* family counts, item meta */
  --kg-border: #8b939b;     /* control outlines: 3.11:1 on white */
}
.kg-layout {
  display: grid;
  grid-template-columns: minmax(190px, 34fr) 66fr;
  gap: 1.2rem;
  align-items: start;
  margin-block-start: 1.2rem;
}
/* Quarto injects whitespace-only placeholder <span> children between the
   panes. They would claim grid cell 1 and stack both panes in column 2,
   so hide them and pin each pane to its own column. */
.kg-layout > span { display: none; }
.kg-pane-left > span, .kg-pane-right > span { display: none; }
.kg-pane-left {
  grid-column: 1;
  position: sticky;
  top: calc(76px + var(--section-nav-h));      /* clears the fixed header + section nav */
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-height: calc(100vh - 92px);
}
.kg-list {
  display: flex; flex-direction: column; gap: 0.45rem;
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-inline-end: 0.35rem;
}
.kg-item {
  display: flex; flex-direction: column; gap: 0.15rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--bs-border-color);
  border-inline-start: 4px solid transparent;
  border-radius: var(--bs-border-radius);
  background: color-mix(in srgb, var(--kg-ink) 4%, var(--bs-body-bg));
  color: var(--bs-body-color);
  text-decoration: none;
  transition: background-color .12s ease, border-color .12s ease;
}
.kg-item:hover {
  background: color-mix(in srgb, var(--kg-ink) 8%, var(--bs-body-bg));
  border-inline-start-color: var(--kg-border);
  text-decoration: none;
  color: var(--bs-body-color);
}
.kg-item.kg-active {
  background: color-mix(in srgb, var(--kg-ink) 11%, var(--bs-body-bg));
  border-inline-start-color: var(--kg-ink);
}
.kg-name { font-weight: 600; line-height: 1.25; }
/* Family groups in the left pane: a collapsible header plus its posts. */
.kg-group { display: flex; flex-direction: column; gap: 0.3rem; }
.kg-group + .kg-group { margin-block-start: 0.5rem; }
.kg-group-head {
  display: flex; align-items: center; gap: 0.45em;
  width: 100%; text-align: left;
  padding: 0.35rem 0.5rem;
  border: 0; border-radius: var(--bs-border-radius);
  background: color-mix(in srgb, var(--kg-ink) 10%, var(--bs-body-bg));
  color: var(--kg-ink);
  font-size: 0.78rem; font-weight: 700;
  letter-spacing: 0.02em; text-transform: uppercase;
  cursor: pointer;
}
.kg-group-head:hover {
  background: color-mix(in srgb, var(--kg-ink) 17%, var(--bs-body-bg));
}
.kg-group-caret::before { content: "▾"; display: inline-block; }
.kg-group-closed .kg-group-caret::before { content: "▸"; }
.kg-group-label { flex: 1 1 auto; }
.kg-group-count {
  flex: 0 0 auto;
  font-size: 0.7rem; font-weight: 600;
  padding: 0.05em 0.5em;
  border-radius: 999px;
  background: color-mix(in srgb, var(--kg-ink) 15%, var(--bs-body-bg));
  color: var(--kg-ink-soft);
}
.kg-group-body {
  display: flex; flex-direction: column; gap: 0.35rem;
  padding-inline-start: 0.45rem;
  border-inline-start: 2px solid color-mix(in srgb, var(--kg-ink) 22%, transparent);
}
.kg-group-closed .kg-group-body { display: none; }
/* Collapse control, above the post list. Shares the button style below. */
.kg-collapse-btn {
  width: 100%;
  flex: 0 0 auto;
}
/* Filter box, above the collapse control. */
.kg-filter { flex: 0 0 auto; }
.kg-filter-input {
  width: 100%;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--kg-border);
  border-radius: var(--bs-border-radius);
  background: var(--bs-body-bg);
  color: var(--bs-body-color);
  font-size: 0.8rem;
  line-height: 1.3;
}
.kg-filter-input:focus-visible {
  outline: 2px solid var(--kg-ink);
  outline-offset: 1px;
}
.kg-filter-empty {
  margin: 0.4rem 0 0;
  font-size: 0.78rem;
  color: var(--bs-secondary-color);
}
/* The list items, the groups, and the collapse control set an author
   `display`, so the plain [hidden] attribute does not hide them. Spell it
   out, so the filter can hide a non-matching entry or an empty family. */
.kg-item[hidden],
.kg-group[hidden],
.kg-collapse-btn[hidden],
.kg-filter-empty[hidden] { display: none; }
/* Family framing shown above the open post. */
.kg-intro {
  margin-block: 0.2rem 1.1rem;
  padding: 0.7rem 0.9rem;
  border-inline-start: 4px solid var(--kg-border);
  border-radius: var(--bs-border-radius);
  background: color-mix(in srgb, var(--kg-ink) 6%, var(--bs-body-bg));
  color: var(--bs-secondary-color);
  font-size: 0.92rem;
}
.kg-intro > :first-child { margin-block-start: 0; }
.kg-intro > :last-child { margin-block-end: 0; }
.kg-pane-right { grid-column: 2; }
/* Posts are closed with the semantic `hidden` attribute (see post-viewer.js)
   so reader mode and text-only renderers see only the open post. */
.kg-viewer {
  min-height: 60vh;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius-lg);
  background: var(--bs-body-bg);
  padding: 0 1.1rem 1.1rem;
}
.kg-status {
  padding: 2.5rem 1rem;
  text-align: center;
  color: var(--bs-secondary-color);
  font-size: 0.9rem;
}
.kg-status-error { color: var(--box-fg, #666666); }
.kg-post-bar {
  position: sticky; top: calc(64px + var(--section-nav-h)); z-index: 3;
  display: none; align-items: center; gap: 0.8em;
  margin: 0 -1.1rem 0.9rem;
  padding: 0.6rem 1.1rem;
  background: color-mix(in srgb, var(--bs-body-bg) 92%, var(--kg-ink));
  border-bottom: 1px solid var(--bs-border-color);
}
.kg-post-bar.kg-bar-on { display: flex; }
.kg-viewer.kg-empty::before {
  content: "Select a post on the left to open it here.";
  display: block;
  padding: 2.5rem 1rem;
  text-align: center;
  color: var(--bs-secondary-color);
  font-size: 0.9rem;
}
.kg-post-bar-title {
  flex: 1 1 auto;
  font-weight: 600; font-size: 0.9rem;
  color: var(--bs-emphasis-color);
}

/* ── The two chrome controls: one button style ──
   "Collapse all but current" (above the list) and "Copy link" (post bar) are
   the same kind of control, so they share one definition: body-background
   fill, --kg-ink label, and a --kg-border outline that clears 3:1 against the
   page in BOTH themes. Both previously painted their label in --navbar-bg,
   which made the collapse control #d1d1d1 on white and #0f0f0f on #121212,
   and the copy control #ffffff on white and #121212 on #121212 — invisible in
   light and dark alike. */
.kg-collapse-btn,
.kg-copy {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.4em;
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--kg-border);
  border-radius: var(--bs-border-radius);
  background: var(--bs-body-bg);
  color: var(--kg-ink);
  font-size: 0.74rem; font-weight: 600; line-height: 1.2;
  cursor: pointer;
}
.kg-copy { flex: 0 0 auto; }
.kg-collapse-btn:hover,
.kg-copy:hover {
  background: color-mix(in srgb, var(--kg-ink) 9%, var(--bs-body-bg));
  border-color: var(--kg-ink-soft);
}
.kg-collapse-btn:focus-visible,
.kg-copy:focus-visible {
  outline: 2px solid var(--kg-ink);
  outline-offset: 2px;
}
.kg-post-content > :first-child { margin-block-start: 0; }
.kg-post-content h2 { font-size: 1.25rem; margin-block-start: 1.4rem; }
.kg-post-content h3 { font-size: 1.05rem; margin-block-start: 1.2rem; }
.kg-tags {
  display: flex; flex-wrap: wrap; gap: 0.35rem;
  margin-block-start: 1.2rem;
  padding-block-start: 0.9rem;
  border-top: 1px solid var(--bs-border-color);
}
/* The tag pills are `code` inside a `p`, and Bootstrap's
   `p code:not(.sourceCode)` (0,1,2) outranks a bare `.kg-tags code` (0,1,1),
   so it used to repaint the pill with the light inline-code grey — behind
   near-white text in dark mode. Match its specificity to win. */
.kg-tags code:not(.sourceCode) {
  font-size: 0.72rem;
  padding: 0.2em 0.6em;
  border-radius: 999px;
  background: color-mix(in srgb, var(--kg-ink) 8%, var(--bs-body-bg));
  color: var(--kg-ink);
  border: 1px solid color-mix(in srgb, var(--kg-ink) 22%, transparent);
}
@media (max-width: 900px) {
  .kg-layout { grid-template-columns: 1fr; gap: 1rem; }
  .kg-pane-left, .kg-pane-right { grid-column: 1; }
  .kg-pane-left {
    position: static;
    max-height: 12rem;
    border: 1px solid var(--bs-border-color);
    border-radius: var(--bs-border-radius);
    padding: 0.5rem;
    background: color-mix(in srgb, var(--bs-light) 60%, var(--bs-body-bg));
  }
  .kg-viewer { min-height: 40vh; }
}
@media print {
  .kg-pane-left { display: none; }
  .kg-pane-right { grid-column: 1; }
  .kg-layout { grid-template-columns: 1fr; }
  .kg-post { display: block !important; }
  .kg-post-bar { position: static; }
}

/* ── Dark mode ──
   The brand supplies the dark color roles and Quarto's theme pair adds the
   navbar toggle. These rules adapt the navbar and callout colors that the
   light theme sets above; Quarto marks dark mode with the body.quarto-dark
   class (the navbar's own data-bs-theme attribute is separate and must not be
   used as a dark-mode hook). */
body.quarto-dark {
  --navbar-bg: #121212;
  --navbar-fg: #b8b8b8;
  --navbar-fg-active: #f0f0f0;
  --navbar-border: #333333;
  /* Both modes are built on cosmo, so the layout is identical by construction
     and only the colors change. The component colors that cosmo derives from
     its own palette at build time must therefore be set here for dark mode. */
  --bs-body-bg: #121212;
  --bs-body-color: #e6e6e6;
  --bs-secondary-bg: #242424;
  --bs-tertiary-bg: #1c1c1c;
  --bs-secondary-color: rgba(230, 230, 230, 0.75);
  --bs-tertiary-color: rgba(230, 230, 230, 0.5);
  --bs-emphasis-color: #ffffff;
  --bs-heading-color: #ffffff;
  --bs-border-color: #333333;
  --bs-border-color-translucent: rgba(255, 255, 255, 0.15);
  --bs-code-color: #e6e6e6;
  --bs-highlight-bg: #333333;
  --bs-highlight-color: #e6e6e6;
  --bs-link-color: #f0f0f0;
  --bs-link-hover-color: #ffffff;
  --bs-link-color-rgb: 240, 240, 240;
  /* Knowledge-gap list palette. The light values are set in the post-browser
     section above; these are the dark counterparts. Status, test contrast
     against #121212 (and against the 10% ink-tinted header fill): ink #f2f2f2
     is 16.7:1, ink-soft #b0b0b0 is 8.6:1, and the control outline #6e6e6e is
     3.67:1 on the page background. */
  --kg-ink: #f2f2f2;
  --kg-ink-soft: #b0b0b0;
  --kg-border: #6e6e6e;
}
body.quarto-dark .callout-note      { --box-accent: #5a5a5a; --box-accent-strong: #2b2b2b; --box-bg: #1c1c1c; --box-fg: #d0d0d0; }
body.quarto-dark .callout-tip       { --box-accent: #565656; --box-accent-strong: #2f2f2f; --box-bg: #1e1e1e; --box-fg: #d0d0d0; }
body.quarto-dark .callout-important { --box-accent: #6b6b6b; --box-accent-strong: #3a3a3a; --box-bg: #222222; --box-fg: #e0e0e0; }
body.quarto-dark .callout-warning   { --box-accent: #666666; --box-accent-strong: #333333; --box-bg: #202020; --box-fg: #d8d8d8; }
body.quarto-dark .callout-caution   { --box-accent: #7a7a7a; --box-accent-strong: #454545; --box-bg: #242424; --box-fg: #e0e0e0; }
body.quarto-dark .callout.callout-style-default.callout-warning,
body.quarto-dark .callout.callout-style-default.callout-note,
body.quarto-dark .callout.callout-style-default.callout-important,
body.quarto-dark .callout.callout-style-default.callout-tip,
body.quarto-dark .callout.callout-style-default.callout-caution {
  background-image: none;
}
/* Inline code pills. Bootstrap's `p code:not(.sourceCode), li code:not(...),
   td code:not(...) { background-color: rgba(233,236,239,.65) }` rule is in the
   LIGHT and the DARK build alike, so in dark mode near-white code sat on a
   light-grey pill (2.3:1, unreadable). Repaint the pill with the dark
   secondary surface. The light theme is untouched — its near-black code on
   that pale pill already reads at 15.5:1. */
body.quarto-dark p code:not(.sourceCode),
body.quarto-dark li code:not(.sourceCode),
body.quarto-dark td code:not(.sourceCode) {
  background-color: var(--bs-secondary-bg);
}

/* ── Typography roles ──
   Content is serif: the brand sets STIX Two Text for the body and headings,
   and every content surface (navigation, sidebar, listings, captions)
   inherits it. Only form controls and the search box stay in Inter, and math
   is pinned to its STIX companion so inline math matches the text. Print
   inherits the serif body. */
math,
mjx-container {
  font-family: "STIX Two Math", "STIX Two Text", math, serif;
}
.btn, button, input, select, textarea,
#quarto-search, .aa-Autocomplete, .aa-Input {
  font-family: Inter, system-ui, sans-serif;
}

/* ── Star rating ──
   The rating glyph is U+2605 BLACK STAR, a monochrome symbol, not an emoji.
   Inter does not carry it, and an emoji fallback would render WHITE and vanish
   on the light theme. Pin the run to a text-symbol font that draws it in the
   surrounding colour, so it is visible in light and dark alike. */
.stars {
  font-family: "DejaVu Sans", "Liberation Sans", "Noto Sans Symbols 2",
    "Segoe UI Symbol", "Apple Symbols", "FreeSerif", sans-serif;
  letter-spacing: 0.08em;
  white-space: nowrap;
}

/* ── Scoreboard controls ──
   Added by scoreboard-tables.js. Without JavaScript the page shows the same
   four tables, unsorted, and no controls. */
.scoreboard-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.25rem;
  align-items: end;
  margin: 1.25rem 0 0.5rem;
}
.scoreboard-field {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--bs-secondary-color);
}
.scoreboard-field input,
.scoreboard-field select {
  min-width: 12rem;
  font-weight: 400;
}
.scoreboard-status {
  margin: 0 0 1rem;
  font-size: 0.85rem;
  color: var(--bs-secondary-color);
}

/* ── Verdicts tables ──
   Fix the column split (1fr / 4fr) so the short first column keeps a real
   share of the width instead of collapsing to fit its labels. */
.verdict-table table {
  table-layout: fixed;
  width: 100%;
}
.verdict-table th:first-child,
.verdict-table td:first-child {
  width: 20%;
  overflow-wrap: break-word;
}
