Repository navigation
Expand file tree
/
Copy pathscript.js
More file actions
98 lines (83 loc) · 3.55 KB
/
Copy pathscript.js
File metadata and controls
98 lines (83 loc) · 3.55 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
(function () {
const body = document.body;
const themeToggle = document.getElementById('theme-toggle');
const themeIcon = themeToggle.querySelector('i');
const sections = document.querySelectorAll('main .section, main #hero');
const storedTheme = localStorage.getItem('site-theme');
const prefersDark =
window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
const defaultTheme = storedTheme || (prefersDark ? 'dark' : 'light');
function applyTheme(theme) {
if (theme === 'dark') {
body.classList.add('theme-dark');
themeIcon.className = 'fa-solid fa-sun';
themeToggle.setAttribute('aria-pressed', 'true');
} else {
body.classList.remove('theme-dark');
themeIcon.className = 'fa-solid fa-moon';
themeToggle.setAttribute('aria-pressed', 'false');
}
localStorage.setItem('site-theme', theme);
}
applyTheme(defaultTheme);
themeToggle.addEventListener('click', () => {
const nowDark = body.classList.toggle('theme-dark');
applyTheme(nowDark ? 'dark' : 'light');
});
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
anchor.addEventListener('click', function (e) {
const target = document.querySelector(this.getAttribute('href'));
if (target) {
e.preventDefault();
const offset = 20;
const top = target.getBoundingClientRect().top + window.pageYOffset - offset;
window.scrollTo({ top, behavior: 'smooth' });
}
});
});
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
const id = entry.target.id;
const link = document.querySelector('.side-nav a[href="#' + id + '"]');
if (entry.isIntersecting) {
document.querySelectorAll('.side-nav a').forEach((a) => a.classList.remove('active'));
if (link) link.classList.add('active');
}
});
},
{ threshold: 0.48 }
);
sections.forEach((section) => observer.observe(section));
const hero = document.getElementById('hero');
const heroCTA = hero.querySelector('.hero-cta');
let floatingCTA = null;
if (heroCTA) {
floatingCTA = heroCTA.cloneNode(true);
floatingCTA.classList.add('floating-cta');
document.body.appendChild(floatingCTA);
const toggleCTA = () => {
const heroBottom = hero.getBoundingClientRect().bottom;
if (heroBottom <= 0) floatingCTA.classList.add('visible');
else floatingCTA.classList.remove('visible');
};
window.addEventListener('scroll', toggleCTA, { passive: true });
toggleCTA();
}
const loopOrder = ['.card-a', '.card-b', '.card-c', '.card-d'];
const loopEls = loopOrder.map((sel) => document.querySelector(sel));
let idx = 0;
if (loopEls.every(Boolean)) {
loopEls.forEach((el, i) => el.classList.toggle('active', i === 0));
setInterval(() => {
loopEls.forEach((el) => el.classList.remove('active'));
loopEls[idx].classList.add('active');
idx = (idx + 1) % loopEls.length;
}, 1800);
}
const yearEl = document.getElementById('year');
if (yearEl) yearEl.textContent = new Date().getFullYear();
document.addEventListener('keyup', (e) => {
if (e.key === 'Tab') document.body.classList.add('user-is-tabbing');
});
})();