/* ─────────────────────────────────────────────────────────────────────
   On-this-page nav + airier reading measure for blog posts.
   Loaded ONLY by posts that opt in with class "has-toc" on .ba-body, so
   posts without it are unaffected. Every colour is a theme token, so light
   and dark follow automatically.

   Two modes so the nav is always visible and never crammed:
   - narrow  : a clean "On this page" that collapses at the top of the column.
   - >=1200px: a sticky rail in the generous left margin; the copy stays centred.
   Click-to-scroll comes free from CSS `scroll-behavior` + the in-page anchors;
   post-toc.js only adds active-section highlighting and the open/collapse sync.
   ───────────────────────────────────────────────────────────────────── */

/* Centred, narrower reading column (the "zoomed-out", airy measure) and the
   positioning context the wide-mode rail hangs off. */
.ba-body.has-toc .dp-wrap { position: relative; max-width: 764px; margin-left: auto; margin-right: auto; }
.ba-body.has-toc article.post { max-width: 660px; }
.ba-body.has-toc article.post p { font-size: 18px; line-height: 1.72; }
.ba-body.has-toc article.post > p:first-of-type { font-size: 19.5px; line-height: 1.6; }
.ba-body.has-toc article.post h2 { font-size: clamp(26px, 2.7vw, 31px); }
.ba-body.has-toc article.post h3 { font-size: 19px; }

/* Above the mobile breakpoint the shared rule gives article.post a 104px
   LEFT-only padding (the site's offset measure). With the narrower measure and
   no rail below 1200px, that pushes the text visibly right. Make it symmetric
   so the copy is truly centred (and re-centre any full-bleed diagram). */
@media (min-width: 901px) {
  .ba-body.has-toc article.post { padding-left: 52px; padding-right: 52px; }
  .ba-body.has-toc .post-diagram { margin-left: -52px; margin-right: -52px; }
}

/* Links by colour alone measure ~1.8:1 vs body in dark mode, under the 3:1 WCAG
   wants when colour is the only cue. A hairline underline makes them
   unambiguous without shouting. (.post-cta, the pill, opts out.) */
.ba-body.has-toc article.post p a:not(.post-cta),
.ba-body.has-toc article.post li a,
.ba-body.has-toc article.post td a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
  transition: text-decoration-color 0.15s ease;
}
.ba-body.has-toc article.post p a:not(.post-cta):hover,
.ba-body.has-toc article.post li a:hover { text-decoration-color: currentColor; }

/* .post-toc is a <nav>, so first null the global nav chrome it inherits
   (border-bottom, blurred background, sticky top:0). */
.post-toc {
  border-bottom: 0;
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  z-index: auto;
  position: static; /* the wide media query sets absolute for the rail */
  margin: 0 0 40px;
}
.post-toc-label {
  cursor: pointer;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--idx);
  padding: 6px 0;
}
.post-toc-label::-webkit-details-marker { display: none; }
.post-toc-caret { transition: transform 0.18s ease; opacity: 0.7; }
.post-toc-d[open] .post-toc-caret { transform: rotate(180deg); }
.post-toc ol {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.post-toc a {
  display: block;
  padding: 8px 0 8px 14px;
  border-left: 2px solid var(--cell);
  font-size: 14px;
  line-height: 1.4;
  color: var(--ink3);
  text-decoration: none;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.post-toc a:hover { color: var(--ink); }
.post-toc a.is-active { color: var(--accent); border-left-color: var(--accent); }
.post-toc a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }

/* Wide: lift the nav into the left margin as a sticky rail. The article stays
   centred; the rail is pulled left of it with right:100% + a gap, keeping a real
   inset from the edge and never shifting the copy. Forced open, summary hidden. */
@media (min-width: 1200px) {
  .post-toc {
    margin: 0;
    position: absolute;
    top: 0;
    right: 100%;
    margin-right: 24px;
    width: 156px;
    height: 100%;
  }
  /* Scrollable, but WITHOUT the bar. A long guide (the Windows one runs to
     seventeen sections) overflows the viewport, and a second scrollbar beside
     the page's own reads as a broken frame rather than as a control. The rail
     still scrolls by wheel, trackpad, keyboard and the scroll-spy, and it is
     never the only way to reach a section. */
  .post-toc-d {
    position: sticky; top: 104px; max-height: calc(100vh - 140px);
    overflow-y: auto; scrollbar-width: none; -ms-overflow-style: none;
    overscroll-behavior: contain;
  }
  .post-toc-d::-webkit-scrollbar { width: 0; height: 0; }
  .post-toc-label { display: none; }
  .post-toc-d > ol { margin-top: 0; }
}
@media (prefers-reduced-motion: reduce) { .post-toc a, .post-toc-caret { transition: none; } }
