diff --git a/src/js/08-static-renders.js b/src/js/08-static-renders.js index 989dc26..8f95bd6 100644 --- a/src/js/08-static-renders.js +++ b/src/js/08-static-renders.js @@ -91,6 +91,21 @@ 'adding to the very problem it tracks.'; } + // ---- Add anchor links to section headings ------------------- + function renderSectionAnchors() { + document.querySelectorAll('section[id]').forEach((section) => { + const h2 = section.querySelector('h2'); + if (!h2) return; + if (h2.querySelector('.section-anchor')) return; + const anchor = document.createElement('a'); + anchor.className = 'section-anchor'; + anchor.href = '#' + section.id; + anchor.setAttribute('aria-label', 'Link to section: ' + section.id); + anchor.textContent = '#'; + h2.appendChild(anchor); + }); + } + // ============================================================ // FUN FEATURES // ============================================================ diff --git a/src/js/21-boot.js b/src/js/21-boot.js index ceddecd..d6247c4 100644 --- a/src/js/21-boot.js +++ b/src/js/21-boot.js @@ -27,6 +27,7 @@ renderTips(); renderChangelog(); renderFooterStats(); + renderSectionAnchors(); // Chart init is isolated so a missing date-adapter or other chart error // cannot prevent the counters and life-blocks from running. diff --git a/styles/base.css b/styles/base.css index 176aae4..b267ba1 100644 --- a/styles/base.css +++ b/styles/base.css @@ -49,6 +49,29 @@ h1 { font-size: clamp(1.8rem, 5vw, 3.2rem); font-weight: 900; } h2 { font-size: clamp(1.2rem, 3vw, 1.8rem); font-weight: 700; margin-bottom: 1rem; } h3 { font-size: 1rem; font-weight: 700; } +/* ---- Section anchor links ---- */ +.section-anchor { + display: inline-block; + margin-left: 0.5em; + font-size: 0.7em; + color: var(--text-dim); + text-decoration: none; + opacity: 0; + transition: opacity 0.2s; + vertical-align: middle; + user-select: none; +} +h2:hover .section-anchor, +h2:focus-within .section-anchor, +.section-anchor:focus { + opacity: 1; +} +@media (hover: none) { + .section-anchor { + opacity: 1; + } +} + /* ---- Layout ---- */ .container { max-width: 1200px; diff --git a/tests/e2e/death-clock.spec.js b/tests/e2e/death-clock.spec.js index 7d89fa3..9af802d 100644 --- a/tests/e2e/death-clock.spec.js +++ b/tests/e2e/death-clock.spec.js @@ -288,6 +288,30 @@ test.describe('AI Death Clock — end-to-end', () => { expect(html).not.toContain('