feat: page transitions, scroll progress bar, and staggered value cards

This commit is contained in:
Manuel
2026-05-10 15:41:03 +02:00
parent 97c05ff620
commit f1c1f54ef9
3 changed files with 113 additions and 12 deletions
+45 -9
View File
@@ -42,7 +42,11 @@ const {
rel="stylesheet"
/>
</head>
<body>
<body class="page-ready">
<!-- Scroll progress bar -->
<div class="scroll-progress" id="scrollProgress" role="progressbar" aria-label="Progreso de lectura" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
<SiteHeader activeNav={activeNav} />
<main>
<slot />
@@ -68,17 +72,49 @@ const {
{ threshold: 0.1, rootMargin: '0px 0px -48px 0px' }
);
document.querySelectorAll('.reveal, .reveal-left, .reveal-scale, .gold-line, .section-eyebrow').forEach((el) => {
document.querySelectorAll('.reveal, .reveal-left, .reveal-scale, .gold-line, .section-eyebrow, .value-card-animate').forEach((el) => {
io.observe(el);
});
}
// ─── HEADER SCROLL ELEVATION ─────────────────
const header = document.querySelector('.site-header') as HTMLElement | null;
if (header) {
window.addEventListener('scroll', () => {
header.classList.toggle('is-scrolled', window.scrollY > 16);
}, { passive: true });
// ─── SCROLL PROGRESS ────────────────────────
const progressBar = document.getElementById('scrollProgress') as HTMLElement | null;
if (progressBar) {
const updateProgress = () => {
const scrollTop = window.scrollY;
const docHeight = document.documentElement.scrollHeight - window.innerHeight;
const progress = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0;
progressBar.style.width = `${progress}%`;
progressBar.setAttribute('aria-valuenow', String(Math.round(progress)));
};
window.addEventListener('scroll', updateProgress, { passive: true });
updateProgress();
}
// ─── PAGE TRANSITIONS ───────────────────────
// Fade IN: page loads → body gets .page-ready → CSS handles fade-in
document.body.classList.add('page-ready');
// Fade OUT: intercept internal navigation links
const handleNavClick = (e: MouseEvent) => {
const target = e.target as HTMLElement;
const anchor = target.closest('a');
if (!anchor) return;
const href = anchor.getAttribute('href');
if (!href || href.startsWith('#') || href.startsWith('http') || href.startsWith('mailto') || href.startsWith('tel') || anchor.target === '_blank') return;
e.preventDefault();
document.body.classList.remove('page-ready');
setTimeout(() => {
window.location.href = href;
}, 300);
};
document.addEventListener('click', handleNavClick);
} else {
// Reduced motion: show immediately, no transitions
document.body.classList.add('page-ready');
}
</script>
</body>