feat: oklch color system, hamburger nav, theme toggle, footer, CSS fixes

Color system:
- Replace all --color-N references in dark mode with oklch()
- Fine-grained surface steps (12%→15%→18%→21%→22%)
- Smooth text gradient (92%→78%→62%→48%)
- Heading hierarchy (95%→65%)
- All palette-driven via --palette-hue and --palette-chroma

Navigation:
- Hamburger menu for mobile (data-nav-toggle + JS)
- Theme toggle button (sun/moon, localStorage persistence)
- data-theme="light|dark" override on <html>
- Cleaned nav CSS, removed old dropdown conflicts

Footer:
- Three-column nav grid (Framework, Resources, Project)
- Branding header + tagline
- Proper semantic structure (header + 3 nav + p)

Fixes:
- Sidebar: compact spacing, --sidebar-link-max token
- TOC: compact, scroll spy with IntersectionObserver
- Prev/next: inline arrows, data-role="prev-next" restored
- Section dividers scoped to article/main only
- Grid columns use tokens not hardcoded values

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ludo 2026-04-11 20:43:56 +02:00
parent e0bda45953
commit 6d654e884b
Signed by: ludo
GPG key ID: F6E479DEFAB84D6E
12 changed files with 390 additions and 195 deletions

View file

@ -29,7 +29,7 @@
{{ .Content }}
{{- if or .PrevInSection .NextInSection -}}
<footer>
<footer data-role="prev-next">
{{- with .NextInSection -}}
<a href="{{ .RelPermalink }}" rel="prev">
<span aria-hidden="true"></span> {{ .LinkTitle }}
@ -52,4 +52,33 @@
{{- end -}}
</section>
<script>
// TOC scroll spy — highlights current section in the aside
(function(){
var toc = document.querySelector('[data-toc]');
if (!toc) return;
var links = toc.querySelectorAll('a');
if (!links.length) return;
var headings = [];
links.forEach(function(a) {
var id = a.getAttribute('href');
if (id && id.startsWith('#')) {
var el = document.getElementById(id.slice(1));
if (el) headings.push({ el: el, link: a });
}
});
if (!headings.length) return;
var observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
links.forEach(function(a) { a.removeAttribute('aria-current'); });
headings.forEach(function(h) {
if (h.el === entry.target) h.link.setAttribute('aria-current', 'true');
});
}
});
}, { rootMargin: '0px 0px -70% 0px' });
headings.forEach(function(h) { observer.observe(h.el); });
})();
</script>
{{ end }}