da335975e0d5712f47ee0d19b0eb5003d1a1b7f0
lrnassar
  Mon Apr 27 14:16:44 2026 -0700
Add sticky sidebar table of contents to /docs/ pages, ReadTheDocs-style. refs #36894

staticPage.lua: wrap doc body in a Bootstrap row with a col-md-2 sidebar
holding a .docs-toc nav list and a col-md-10 content column. Collect both
lev==1 and lev==2 headings into the TOC and emit id attributes on <h2>
elements (replacing the prior inline <a name=> anchors).

staticPage.html: add a small vanilla-JS scroll-spy that toggles .active
on the TOC <li> matching the section currently scrolled past the top.
No-ops on pages without #docs-toc.

gbStatic.css: add styles for .docs-toc / .docs-toc-row (position: sticky,
flex row for equal-height columns, link styling with active-state border).
All rules are scoped to the .docs-toc class so non-docs pages sharing
gbStatic.css are unaffected.

diff --git docs/staticPage.html docs/staticPage.html
index 2af3e51c539..59eab36c8e0 100755
--- docs/staticPage.html
+++ docs/staticPage.html
@@ -6,16 +6,50 @@
 pre {
     margin-bottom: 1em !important;
 }
 </style>
 
 $for(include-before)$
 $include-before$
 $endfor$
 
 $body$
 
 $for(include-after)$
 $include-after$
 $endfor$
 
+<script>
+// Scroll-spy: highlight the current section in the sidebar TOC
+(function() {
+    var toc = document.getElementById('docs-toc');
+    if (!toc) return;
+    var links = toc.querySelectorAll('a[href^="#"]');
+    if (!links.length) return;
+    var sections = [];
+    for (var i = 0; i < links.length; i++) {
+        var id = links[i].getAttribute('href').slice(1);
+        var el = document.getElementById(id);
+        if (el) sections.push({link: links[i], target: el});
+    }
+    if (!sections.length) return;
+
+    function onScroll() {
+        var scrollY = window.scrollY || window.pageYOffset;
+        var current = sections[0];
+        for (var i = 0; i < sections.length; i++) {
+            if (sections[i].target.offsetTop <= scrollY + 80) {
+                current = sections[i];
+            }
+        }
+        for (var i = 0; i < sections.length; i++) {
+            sections[i].link.parentNode.classList.remove('active');
+        }
+        current.link.parentNode.classList.add('active');
+    }
+
+    window.addEventListener('scroll', onScroll);
+    onScroll();
+})();
+</script>
+
 <!--#include virtual="$$ROOT/inc/gbPageEnd.html" -->