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 src/hg/htdocs/staticStyle/gbStatic.css src/hg/htdocs/staticStyle/gbStatic.css
index f841e8cebac..537dacd1055 100644
--- src/hg/htdocs/staticStyle/gbStatic.css
+++ src/hg/htdocs/staticStyle/gbStatic.css
@@ -305,30 +305,82 @@
 
 ul.nice-menu ul li a {
     font-weight: normal !important;
     font-family: Lato,Arial,Helvetica,sans-serif !important;
 }
 
 /* Override (for now -- until gb.css can be updated in a release cycle */
 
 .gbDonateButton {
     margin-top: 3px;
     width: auto;
     height: auto;
     padding: 5px 20px;
 }
 
+/* Sticky sidebar table of contents for /docs/ pages */
+
+/* Flex row so the TOC column stretches to content height (Bootstrap 3 uses floats) */
+.docs-toc-row {
+    display: flex;
+}
+
+.docs-toc {
+    position: sticky;
+    top: 10px;
+    max-height: calc(100vh - 40px);
+    overflow-y: auto;
+    padding: 10px 0;
+    font-size: 14px;
+    border-right: 1px solid #ddd;
+}
+
+.docs-toc ul {
+    list-style: none;
+    padding-left: 0;
+    margin: 0;
+}
+
+.gbsPage .docs-toc ul li {
+    margin: 0;
+    padding: 0;
+}
+
+.gbsPage .docs-toc ul li::before {
+    content: none;
+}
+
+.gbsPage .docs-toc li a {
+    display: block;
+    padding: 4px 12px;
+    color: #333;
+    font-weight: normal;
+    text-decoration: none;
+    border-left: 3px solid transparent;
+}
+
+.gbsPage .docs-toc li a:hover {
+    color: #4c759c;
+    border-left-color: #ddd;
+}
+
+.gbsPage .docs-toc li.active > a {
+    color: #4c759c;
+    font-weight: bold;
+    border-left-color: #4c759c;
+}
+
 /* Bootstrap collapse component CSS (not included in our customized bootstrap.min.css) */
 .collapse {
     display: none;
 }
 
 .collapse.in {
     display: block;
 }
 
 .collapsing {
     position: relative;
     height: 0;
     overflow: hidden;
     transition-property: height, visibility;
     transition-duration: .35s;