-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
123 lines (90 loc) · 3.37 KB
/
script.js
File metadata and controls
123 lines (90 loc) · 3.37 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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
(() => {
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
const revealTargets = document.querySelectorAll(".reveal, .stagger-group");
const showElement = (el) => el.classList.add("visible");
if ("IntersectionObserver" in window) {
const revealObserver = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
showElement(entry.target);
observer.unobserve(entry.target);
});
}, { threshold: 0.1 });
revealTargets.forEach((el) => revealObserver.observe(el));
} else {
revealTargets.forEach(showElement);
}
document.querySelectorAll(".stagger-group").forEach((group) => {
const stagger = Number.parseInt(group.dataset.stagger || "100", 10);
group.querySelectorAll(".stagger-child").forEach((child, index) => {
child.style.transitionDelay = `${index * stagger}ms`;
});
});
document.querySelectorAll(".reveal[data-delay]").forEach((el) => {
el.style.transitionDelay = `${el.dataset.delay}ms`;
});
const nav = document.querySelector(".nav");
if (nav) {
let wasScrolled = false;
const onScroll = () => {
const isScrolled = window.scrollY > 40;
if (isScrolled === wasScrolled) return;
nav.classList.toggle("scrolled", isScrolled);
wasScrolled = isScrolled;
};
window.addEventListener("scroll", onScroll, { passive: true });
onScroll();
}
const heroContent = document.querySelector(".hero-content");
if (heroContent && !prefersReducedMotion) {
let ticking = false;
window.addEventListener("scroll", () => {
if (ticking) return;
requestAnimationFrame(() => {
heroContent.style.transform = `translateY(${window.scrollY * 0.04}px)`;
ticking = false;
});
ticking = true;
}, { passive: true });
}
const mobileBtn = document.querySelector(".nav-mobile-btn");
const mobileMenu = document.querySelector(".nav-mobile-menu");
const mobileIcon = document.querySelector(".nav-mobile-icon");
const setMobileMenuOpen = (open) => {
if (!mobileBtn || !mobileMenu || !mobileIcon) return;
mobileMenu.hidden = !open;
mobileMenu.classList.toggle("open", open);
mobileBtn.setAttribute("aria-expanded", String(open));
mobileIcon.textContent = open ? "✕" : "☰";
};
if (mobileBtn && mobileMenu) {
setMobileMenuOpen(false);
mobileBtn.addEventListener("click", () => {
setMobileMenuOpen(mobileMenu.hidden);
});
document.addEventListener("keydown", (event) => {
if (event.key === "Escape") setMobileMenuOpen(false);
});
mobileMenu.querySelectorAll("a").forEach((link) => {
link.addEventListener("click", () => setMobileMenuOpen(false));
});
}
document.querySelectorAll('a[href^="#"]').forEach((link) => {
link.addEventListener("click", (event) => {
const href = link.getAttribute("href");
if (!href || href === "#") return;
const target = document.querySelector(href);
if (!target) return;
event.preventDefault();
target.scrollIntoView({
behavior: prefersReducedMotion ? "auto" : "smooth",
block: "start"
});
setMobileMenuOpen(false);
});
});
const currentYear = document.querySelector("#current-year");
if (currentYear) {
currentYear.textContent = new Date().getFullYear();
}
})();