-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
55 lines (49 loc) · 2.29 KB
/
Copy pathscript.js
File metadata and controls
55 lines (49 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
(() => {
'use strict';
const root = document.documentElement;
const header = document.querySelector('[data-header]');
const menuButton = document.querySelector('[data-menu-button]');
const nav = document.querySelector('[data-nav]');
const themeButton = document.querySelector('[data-theme-button]');
const profile = document.querySelector('[data-profile]');
const closeMenu = () => {
if (!menuButton || !nav) return;
menuButton.setAttribute('aria-expanded', 'false');
nav.classList.remove('open');
document.body.style.overflow = '';
};
menuButton?.addEventListener('click', () => {
const isOpen = menuButton.getAttribute('aria-expanded') === 'true';
menuButton.setAttribute('aria-expanded', String(!isOpen));
nav?.classList.toggle('open', !isOpen);
document.body.style.overflow = isOpen ? '' : 'hidden';
});
nav?.querySelectorAll('a').forEach((link) => link.addEventListener('click', closeMenu));
window.addEventListener('keydown', (event) => { if (event.key === 'Escape') closeMenu(); });
const setHeader = () => header?.classList.toggle('scrolled', window.scrollY > 20);
setHeader();
window.addEventListener('scroll', setHeader, { passive: true });
let savedTheme = null;
try { savedTheme = localStorage.getItem('theme'); } catch (_) { /* Storage can be unavailable. */ }
if (savedTheme === 'dark' || savedTheme === 'light') root.dataset.theme = savedTheme;
themeButton?.addEventListener('click', () => {
const next = root.dataset.theme === 'dark' ? 'light' : 'dark';
root.dataset.theme = next;
try { localStorage.setItem('theme', next); } catch (_) { /* Theme still works for this visit. */ }
});
if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) { entry.target.classList.add('visible'); observer.unobserve(entry.target); }
});
}, { threshold: 0.12 });
document.querySelectorAll('.reveal').forEach((item) => observer.observe(item));
} else {
document.querySelectorAll('.reveal').forEach((item) => item.classList.add('visible'));
}
profile?.addEventListener('error', () => {
profile.hidden = true;
const fallback = profile.nextElementSibling;
if (fallback) fallback.hidden = false;
});
})();