/* Wide-content frame + right-hand "On this page" table of contents.

   ── The frame ──────────────────────────────────────────────────────────────
   One layout for every doc page, so the sidebar and content column never shift
   position between page types. A page carries the `main--framed` class on its
   .main element, added server-side in _layouts/default.html to every page with
   the nav sidebar (only the sidebar-less language selector is left out). The
   frame rules below are defined once and keyed only on `.main--framed`, so no
   page type can drift. When a page also has a right column — a TOC rail or the
   request/response example (.api-page endpoint pages, see api-params.css) — the
   content block widens to hold it; otherwise it stays at the theme's
   $content-width, left-aligned to the same edge.

   ── The TOC rail ───────────────────────────────────────────────────────────
   assets/js/toc.js fills #toc-rail from the page's h2/h3 headings and adds
   .toc-rail--ready only when there are enough to be worth showing. The rail's
   two-track grid is keyed on that class and sticks in view while the article
   scrolls past it.

   Browsers without :has() support never opt any page into the frame, so they
   fall back to the theme's plain layout. */

:root {
  /* Shared frame geometry. Keep --frame-content in sync with $content-width in
     _sass/custom/setup.scss — that is the only cross-file coupling; everything
     else derives from these four base values. */
  --frame-nav: 16.5rem;     /* theme $nav-width — the pinned sidebar width */
  --frame-content: 60rem;   /* theme $content-width — the article/params column */
  --frame-gap: 2rem;        /* space between content and the right column */
  --frame-rail: 14rem;      /* TOC rail width; API pages size their own example column */
  --frame-block: calc(var(--frame-content) + var(--frame-gap) + var(--frame-rail));
  --frame-total: calc(var(--frame-block) + var(--frame-nav));
  /* Viewport x of the framed content's left edge (mirrors the margin-left rule). */
  --frame-main-left: max(
    var(--frame-nav),
    calc((100vw - var(--frame-total)) / 2 + var(--frame-nav))
  );
}

.toc-rail {
  display: none;
}

/* 87.5rem = 1400px (the theme's own xl breakpoint): where the frame turns on.
   Below it every page keeps the theme's centered layout. */
@media (min-width: 87.5rem) {
  /* The theme lets the sidebar grow to fill half the leftover space (it centers
     the nav rail). Pin it back to its base width so the reclaimed space goes to
     the content — otherwise the wider sidebar would overlap the framed content. */
  .side-bar:has(+ .main--framed) {
    width: var(--frame-nav);
    min-width: var(--frame-nav);
  }

  /* Anchor every framed page's content to the same left edge — positioned as if
     the full content+rail block were present — so nothing shifts horizontally
     when navigating between pages with and without a right column. */
  .side-bar + .main--framed {
    margin-left: max(
      var(--frame-nav),
      calc((100% - var(--frame-total)) / 2 + var(--frame-nav))
    );
  }

  /* Widen the block only when there is a right column to hold: a TOC rail on
     content pages, or the request/response example on API endpoint pages. */
  .main--framed:has(.toc-rail--ready),
  .main--framed:has(.api-page) {
    max-width: var(--frame-block);
  }

  /* The header (search bar) stays within the framed content, but the rule beneath
     it spans full width — from the pinned sidebar's right edge to the viewport
     edge — via a pseudo-element that breaks out of the content block. Offsets are
     derived from the frame geometry, so nothing new can drift. */
  /* position:relative activates the theme's dormant `z-index: 0` on the header,
     making it a stacking context. The page's h1/h2 are themselves positioned
     (position:relative, for anchor links) and paint at the same level, so on
     DOM order they'd cover the search dropdown. A positive z-index lifts the
     whole header — search input and its results panel — above the content. */
  .main--framed .main-header {
    position: relative;
    z-index: 3;
  }
  /* The header keeps its own border-bottom under the search form (a real border
     paints below the input, where a pseudo-element would be hidden by it). This
     pseudo only extends the same line past the header's edges — left to the
     sidebar, right to the viewport — aligned to the real border (bottom: -1px). */
  .main--framed .main-header::after {
    content: "";
    position: absolute;
    bottom: -1px;
    left: calc(var(--frame-nav) - var(--frame-main-left));
    right: calc(var(--frame-main-left) + var(--frame-content) - 100vw);
    border-bottom: 1px solid #0d1a5e;
  }
  /* Wider block (TOC rail / API example) reaches further right, so extend less. */
  .main--framed:has(.toc-rail--ready) .main-header::after,
  .main--framed:has(.api-page) .main-header::after {
    right: calc(var(--frame-main-left) + var(--frame-block) - 100vw);
  }

  /* TOC rail: split the widened content into article + sticky rail. */
  .main-content-wrap:has(.toc-rail--ready) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--frame-rail);
    column-gap: var(--frame-gap);
    align-items: start;
  }

  /* Breadcrumbs / "View as Markdown" row spans the full width, above both columns. */
  .main-content-wrap:has(.toc-rail--ready) > .doc-topbar {
    grid-column: 1 / -1;
  }

  .main-content-wrap:has(.toc-rail--ready) > #main-content {
    grid-column: 1;
    min-width: 0; /* let the article shrink within its track instead of overflowing */
  }

  .main-content-wrap:has(.toc-rail--ready) > .toc-rail {
    display: block;
    grid-column: 2;
    position: sticky;
    top: 4rem;
    align-self: start;
    max-height: calc(100vh - 6rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 0 0 1rem 1rem;
    border-left: 1px solid #0d1a5e;
  }
}

.toc-rail-heading {
  margin: 0 0 0.75rem;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #8899cc;
}

.toc-rail-nav {
  font-size: 0.8rem;
  line-height: 1.35;
}

.toc-rail-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.toc-rail-item {
  margin: 0;
}

.toc-rail-item a {
  display: block;
  margin-left: -1rem; /* pull the active bar onto the rail's own left border */
  padding: 0.25rem 0 0.25rem calc(1rem - 2px);
  color: #c8d0e8;
  text-decoration: none;
  border-left: 2px solid transparent;
  opacity: 0.75;
  transition: color 0.15s ease, opacity 0.15s ease, border-color 0.15s ease;
}

/* Nested (h3) entries indent under their h2. */
.toc-rail-h3 a {
  padding-left: calc(1.85rem - 2px);
  font-size: 0.95em;
}

.toc-rail-item a:hover,
.toc-rail-item a:focus {
  opacity: 1;
  color: #ffffff;
}

.toc-rail-item a.is-active {
  opacity: 1;
  color: #7aa4f0;
  border-left-color: #e3007e;
}
