/* Table of contents — built by js/toc.js, formatted after transformer-circuits.pub
   (2026/workspace): a "Contents" block in the left margin that, scrolled past,
   collapses to its own heading stuck at the top of the screen.
   Colors from the shared theme (js/theme.js), so it follows light/dark. */

.vx-contents {
  --toc-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --toc-ink: var(--vx-ink, #16160f);
  --toc-light: var(--vx-muted, #6b6a63);
  --toc-rule: var(--vx-rule, #d8d7cf);
  --toc-surface: var(--vx-surface, #fcfcfb);
  /* The Contents button's backing: white on the light page; on the dark one it
     keeps the surface, since its muted ink is light there. */
  --toc-head-bg: #ffffff;
  font-family: var(--toc-sans);
  /* Kept quiet: it is a margin note the reader can use, not part of the page. The
     entries sit in the muted ink and come up to full ink only under the pointer or
     while being read. Color rather than opacity, so the stuck dropdown's backing
     stays opaque over the text it covers. */
}

/* ---- the in-page block, in the left margin */
.vx-contents {
  position: absolute;
  z-index: 5;
  box-sizing: border-box;
  --toc-pad-l: 16px;
  --toc-pad-r: 24px;
  padding: 0 var(--toc-pad-r) 0.5em var(--toc-pad-l);
  border-right: 1px solid color-mix(in srgb, var(--toc-rule) 50%, transparent);
  display: flex;
  flex-direction: column;
}
/* Only the list scrolls inside the block (when a wide figure caps its height,
   or in the stuck dropdown); the heading stays outside that scroll. */
.vx-contents nav {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.vx-contents-head {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: none;
  /* Sticky against the page (its `top` is set by toc.js): it holds at the top
     of the screen while the list scrolls under it, so it carries a backing. */
  position: sticky;
  z-index: 1;
  /* Full width of the block, through its side padding, with the same padding
     put back inside so the word stays aligned with the list. In px through
     variables: an em here would be the button's 11px, not the block's. */
  box-sizing: border-box;
  align-self: flex-start;
  width: calc(100% + var(--toc-pad-l) + var(--toc-pad-r));
  margin: 0 0 0.4em calc(-1 * var(--toc-pad-l));
  padding: 4px var(--toc-pad-r) 0.6em var(--toc-pad-l);
  border: 0;
  background: var(--toc-head-bg);
  font: 500 11px/1.3 var(--toc-sans);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--toc-light);
  cursor: pointer;
}
.vx-contents-fold::before {
  content: "▾";
  display: inline-block;
  font-size: 11px;
  color: var(--toc-light);
  transition: transform 150ms ease;
}
.vx-contents.is-folded .vx-contents-fold::before {
  transform: rotate(-90deg);
}
.vx-contents.is-folded nav {
  display: none;
}
/* Folded — in the margin or stuck at the top — there is no list to rule off
   from the text, so the rule goes with it. */
.vx-contents.is-folded {
  border-right-color: transparent;
}

/* ---- the list, shared by the block and the dropdown */
.vx-contents nav {
  font-family: var(--toc-sans);
}
.vx-contents nav > div {
  margin: 0.7em 0 0.3em;
}
.vx-contents nav > div:first-child {
  margin-top: 0;
}
.vx-contents nav ul {
  margin: 0 0 6px;
  padding-left: 1em;
  list-style: none;
}
.vx-contents nav li {
  margin: 0 0 0.25em;
  list-style-type: none;
}
.vx-contents nav a {
  display: inline-block;
  color: var(--toc-light);
  text-decoration: none;
  border-bottom: none;
  line-height: 1.3;
  transition: color 120ms ease;
}
.vx-contents nav > div > a {
  font-size: 12.5px;
  font-weight: 500;
}
.vx-contents nav li > a {
  font-size: 12px;
}
.vx-contents nav a:hover {
  color: var(--toc-ink);
}
.vx-contents nav li.vx-toc-fig > a {
  font-size: 11px;
  color: color-mix(in srgb, var(--toc-light) 75%, transparent);
}

/* Section numbers, as the reference sets them: light, tabular, a fixed column. */
.vx-toc-num {
  display: inline-block;
  min-width: 2.1em;
  margin-right: 0.4em;
  color: color-mix(in srgb, var(--toc-light) 70%, transparent);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}
.vx-toc-fig .vx-toc-num {
  min-width: 3.2em;
}

/* The entry being read: a quiet marker, not a highlight — full ink and a thin
   accent underline, where the rest of the list is muted. */
.vx-contents nav a.is-current {
  color: var(--toc-ink);
}
.vx-contents nav a.is-current .vx-toc-text {
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--vx-accent, #ffa69e) 70%, transparent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* ---- scrolled past: the same block, stuck to the top of the screen as its
   heading, the list dropping down under it on click. Only what being over the
   page needs is added — a backing, so the text it now sits on does not show
   through; the heading and the list keep their style. */
.vx-contents.is-stuck {
  position: fixed;
  z-index: 1000;
  padding-top: 0; /* the heading sits flush at the top of the screen (toc.js HEAD_TOP) */
  background: var(--toc-surface);
}
.vx-contents.is-stuck.is-folded {
  background: transparent; /* the folded tab is only its heading; the backing is for the open list */
  padding-bottom: 0; /* the heading's own margin is the tab's bottom edge */
}

@media print {
  .vx-contents {
    display: none;
  }
}

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) .vx-contents {
    --toc-head-bg: var(--toc-surface);
  }
}
:root[data-theme="dark"] .vx-contents {
  --toc-head-bg: var(--toc-surface);
}
