diff --git a/projects/website/_src/_sass/main.scss b/projects/website/_src/_sass/main.scss index 3e12e260..63e9144d 100644 --- a/projects/website/_src/_sass/main.scss +++ b/projects/website/_src/_sass/main.scss @@ -114,6 +114,38 @@ h6 { font-size: 1rem; } +:is(h2, h3, h4, h5, h6) { + .heading-permalink { + display: inline-block; + margin-left: 0.4em; + color: var(--primary); + font-size: 0.55em; + line-height: 1; + opacity: 0; + text-decoration: none; + text-shadow: var(--glow-soft); + transform: scale(0.75); + transition: opacity 130ms linear, text-shadow 130ms linear, transform 130ms ease-out; + vertical-align: middle; + + @media (hover: none) { + opacity: 0.65; + transform: scale(0.9); + } + + @media print { + display: none; + } + } + + &:hover .heading-permalink, + .heading-permalink:focus-visible { + opacity: 1; + text-shadow: var(--glow-strong); + transform: scale(1); + } +} + ul, ol { padding-left: 1.35rem; @@ -797,6 +829,7 @@ body > footer { @media (prefers-reduced-motion: reduce) { :is(h1, h2, h3, h4, h5, h6):target, a, + .heading-permalink, button, input, select, diff --git a/projects/website/_src/assets/main.js b/projects/website/_src/assets/main.js index e468522a..b93b3820 100644 --- a/projects/website/_src/assets/main.js +++ b/projects/website/_src/assets/main.js @@ -88,6 +88,16 @@ var storedTheme = getTheme(); if (storedTheme) setTheme(storedTheme, false); document.addEventListener("DOMContentLoaded", function () { + var headings = document.querySelectorAll("main :is(h2, h3, h4, h5, h6)[id]"); + for (var i = 0; i < headings.length; i++) { + var permalink = document.createElement("a"); + permalink.className = "heading-permalink"; + permalink.href = "#" + encodeURIComponent(headings[i].id); + permalink.setAttribute("aria-label", "Permalink to " + headings[i].textContent.trim()); + permalink.textContent = "✦"; + headings[i].appendChild(permalink); + } + var constellation = document.querySelector(".theme-constellation"); if (!constellation) return; @@ -95,8 +105,8 @@ document.addEventListener("DOMContentLoaded", function () { updateThemeControls(storedTheme || "{{ site.default_scheme }}"); var buttons = constellation.querySelectorAll("[data-scheme]"); - for (var i = 0; i < buttons.length; i++) { - buttons[i].addEventListener("click", function () { + for (var j = 0; j < buttons.length; j++) { + buttons[j].addEventListener("click", function () { setTheme(this.getAttribute("data-scheme")); }); }