From 4e974f51957b550c76a46b34a5db9eb3a4f74faf Mon Sep 17 00:00:00 2001 From: lgoyal6 Date: Wed, 26 Aug 2026 16:19:11 -0700 Subject: [PATCH] Give the page a nav bar and section tabs Every project page now carries the same shell: a sticky bar with my name and the two links a reader actually wants, then tabs that follow scroll. Nothing else is shared. The nav is written entirely in this page's own CSS variables, so it takes the palette it is dropped into rather than importing a second one. Section anchors are prefixed sec- because the obvious slugs collide with ids the pages already use for tables and pickers, and two elements sharing an id hands the JS the wrong one. --- docs/index.html | 23 +++++++++++++++++++---- docs/nav.js | 21 +++++++++++++++++++++ docs/style.css | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 docs/nav.js diff --git a/docs/index.html b/docs/index.html index 5f135d1..37a4c23 100644 --- a/docs/index.html +++ b/docs/index.html @@ -17,7 +17,21 @@ -
+ + + +
lsm-tree storage engine · c++20 · zero-dependency core · booting engine…
@@ -42,7 +56,7 @@

strata.

-
+
01

Break it

write real records, arm a power cut a few hundred KB ahead, and reboot into recovery @@ -76,7 +90,7 @@

strata.

number; the measured numbers above come from real hardware, see docs/BENCHMARKS.md.

-
+
02

Poke it

your own keys land in the same memtable; the counters are the engine's own @@ -113,7 +127,7 @@

strata.

-
+
03

What you just saw

every behavior above is a specific piece of the engine @@ -164,5 +178,6 @@

strata.

+ diff --git a/docs/nav.js b/docs/nav.js new file mode 100644 index 0000000..f8d41cd --- /dev/null +++ b/docs/nav.js @@ -0,0 +1,21 @@ +// Marks the tab for whichever section you are looking at. +// +// Its own scope on purpose: these pages load app.js as a classic script in the +// global scope, and a second one declaring the same helper names would take the +// instrument down with it. +(() => { + const tabs = [...document.querySelectorAll('.tabs a')]; + const seen = tabs + .map((a) => document.querySelector(a.getAttribute('href'))) + .filter(Boolean); + if (!seen.length) return; + const spy = new IntersectionObserver((entries) => { + const best = entries + .filter((e) => e.isIntersecting) + .sort((a, b) => b.intersectionRatio - a.intersectionRatio)[0]; + if (!best) return; + tabs.forEach((a) => + a.setAttribute('aria-current', String(a.getAttribute('href') === `#${best.target.id}`))); + }, { rootMargin: '-90px 0px -55% 0px', threshold: [0.05, 0.3] }); + seen.forEach((el) => spy.observe(el)); +})(); diff --git a/docs/style.css b/docs/style.css index c96d030..36060d0 100644 --- a/docs/style.css +++ b/docs/style.css @@ -172,3 +172,39 @@ footer .links a { color: var(--ink); } html { scroll-behavior: auto; } .rail-fill { transition: none; } } + +/* ---- shared nav shell ------------------------------------------------ + Written entirely in this page's own variables, so it takes the palette + it is dropped into instead of importing a second one. */ +html { scroll-padding-top: 96px; } +.topbar { + position: sticky; top: 0; z-index: 20; + background: color-mix(in srgb, var(--paper) 92%, transparent); + backdrop-filter: blur(8px); border-bottom: 1px solid var(--rule); + display: flex; align-items: center; justify-content: space-between; gap: 16px; + padding: 10px clamp(20px, 3vw, 44px); +} +.brand { font: 15px/1 var(--serif); text-decoration: none; color: var(--ink); } +.brand span { color: var(--ox); } +.navlinks { display: flex; gap: 18px; font: 12px/1 var(--mono); letter-spacing: .06em; } +.navlinks a { color: var(--sub); text-decoration: none; transition: color .18s ease; } +.navlinks a:hover { color: var(--ox); } +.tabs { + position: sticky; top: 40px; z-index: 19; + background: color-mix(in srgb, var(--paper) 92%, transparent); + backdrop-filter: blur(8px); border-bottom: 1px solid var(--rule); + display: flex; gap: 2px; overflow-x: auto; padding: 0 clamp(20px, 3vw, 44px); +} +.tabs a { + flex: 0 0 auto; display: flex; align-items: center; min-height: 44px; + padding: 0 13px; font: 11px/1 var(--mono); letter-spacing: .1em; + text-transform: uppercase; color: var(--faint); text-decoration: none; + border-bottom: 2px solid transparent; + transition: color .18s ease, border-color .18s ease; +} +.tabs a:hover { color: var(--sub); } +.tabs a[aria-current="true"] { color: var(--ox); border-bottom-color: var(--ox); } +@media (prefers-reduced-motion: reduce) { + html { scroll-behavior: auto; } + .tabs a, .navlinks a { transition: none; } +}