Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions docs/assets/js/glitch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Set data-text on every article h1 so the scanline/glitch pseudo-elements
// in main.css can duplicate the text. Also toggles `.glitch-on` via an
// IntersectionObserver so the animation only runs while the h1 is visible.
// Additionally splits the header site name so `-faker` can be styled as a
// two-tone accent.
(function () {
function splitHeaderAccent() {
// Target only the first header__topic (site name), not the page-title
// one that swaps in on scroll.
var el = document.querySelector(
'.md-header__ellipsis > .md-header__topic:first-child .md-ellipsis'
);
if (!el || el.querySelector('.md-ellipsis__accent')) return;
var text = el.textContent;
var idx = text.indexOf('-faker');
if (idx < 0) return;
el.textContent = text.slice(0, idx);
var span = document.createElement('span');
span.className = 'md-ellipsis__accent';
span.textContent = text.slice(idx);
el.appendChild(span);
}

function extractText(el) {
var text = '';
el.childNodes.forEach(function (n) {
if (n.nodeType === Node.TEXT_NODE) {
text += n.textContent;
} else if (n.nodeType === Node.ELEMENT_NODE && !n.classList.contains('headerlink')) {
text += n.textContent;
}
});
return text.trim();
}

function applyGlitch() {
var headings = document.querySelectorAll('article.md-content__inner h1, .md-typeset h1');
if (!headings.length) return;

headings.forEach(function (h) {
if (!h.hasAttribute('data-text')) {
var text = extractText(h);
if (text) h.setAttribute('data-text', text);
}
});

// If the user prefers reduced motion, CSS already hides the glitch layers.
// Skip the observer — no animation means nothing to pause.
if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
return;
}

if (typeof IntersectionObserver === 'undefined') {
// Very old browser: just leave it running by marking all as visible.
headings.forEach(function (h) { h.classList.add('glitch-on'); });
return;
}

var io = new IntersectionObserver(function (entries) {
entries.forEach(function (e) {
e.target.classList.toggle('glitch-on', e.isIntersecting);
});
}, { rootMargin: '50px' });

headings.forEach(function (h) { io.observe(h); });
}

function init() {
splitHeaderAccent();
applyGlitch();
}

if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
46 changes: 15 additions & 31 deletions docs/assets/stylesheets/extra.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
/* ═══════════════════════════════════════════════════════════
Teko display font for headings
═══════════════════════════════════════════════════════════ */
@import url("https://fonts.googleapis.com/css2?family=Teko:wght@400;500;600;700&display=swap");

/* ═══════════════════════════════════════════════════════════
Original extra.css — preserved
═══════════════════════════════════════════════════════════ */

.md-typeset__table {
min-width: 100%;
}
Expand Down Expand Up @@ -30,39 +39,14 @@
--md-text-font: "IBMPlexSans-Regular";
}

/*
markdown and image alignment
ALT tag and a CSS selector on the alt tag
*/
img[src*="#left"] {
float: left;
}
img[src*="#right"] {
float: right;
}
img[src*="#center"] {
display: block;
margin: auto;
}

/*
Tables set to 100% width
*/
.md-typeset__table {
min-width: 100%;
}
/* markdown and image alignment */
img[src*="#left"] { float: left; }
img[src*="#right"] { float: right; }
img[src*="#center"] { display: block; margin: auto; }

.md-typeset table:not([class]) {
display: table;
}

/*
Footer social media icons:
set the size of the svg icons and the espace between them.
*/
.md-social__link {
width: 2rem;
}
.md-social__link svg {
max-height: 1.6rem;
}
.md-social__link { width: 2rem; }
.md-social__link svg { max-height: 1.6rem; }
Loading
Loading