From f1c1f54ef92d79a8a70b1573f20e50012aa3835c Mon Sep 17 00:00:00 2001 From: Manuel Date: Sun, 10 May 2026 15:41:03 +0200 Subject: [PATCH] feat: page transitions, scroll progress bar, and staggered value cards --- src/layouts/MainLayout.astro | 54 ++++++++++++++++++++++++++++++------ src/pages/nosotros.astro | 41 +++++++++++++++++++++++++-- src/styles/animations.css | 30 ++++++++++++++++++++ 3 files changed, 113 insertions(+), 12 deletions(-) diff --git a/src/layouts/MainLayout.astro b/src/layouts/MainLayout.astro index 6956f4a..01c5f10 100644 --- a/src/layouts/MainLayout.astro +++ b/src/layouts/MainLayout.astro @@ -42,7 +42,11 @@ const { rel="stylesheet" /> - + + + +
+
@@ -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'); } diff --git a/src/pages/nosotros.astro b/src/pages/nosotros.astro index 391dd5a..02e994c 100644 --- a/src/pages/nosotros.astro +++ b/src/pages/nosotros.astro @@ -63,17 +63,17 @@ import MainLayout from '../layouts/MainLayout.astro';

Valores que nos definen

-
+
verified

Calidad

Innegociable. Desde la frescura del producto hasta el último detalle del servicio de sala.

-
+
history_edu

Tradición

Honramos las técnicas clásicas que han forjado la gran cocina, aplicándolas con respeto.

-
+
architecture

Vanguardia

Innovamos en presentaciones y texturas para sorprender a los paladares contemporáneos.

@@ -147,4 +147,39 @@ import MainLayout from '../layouts/MainLayout.astro'; } .quote-card-desktop { display: block !important; } } + + /* ─── VALUE CARD TIMELINE ANIMATION ──────────── */ + .value-card-animate { + opacity: 0; + transform: translateY(20px) rotate(var(--card-tilt, 0deg)); + transition: + opacity 600ms cubic-bezier(0.22, 1, 0.36, 1), + transform 600ms cubic-bezier(0.22, 1, 0.36, 1); + transition-delay: calc(var(--value-delay, 0) * 1ms); + } + + .value-card-animate.visible { + opacity: 1; + transform: translateY(0) rotate(0deg); + } + + .value-card-animate:nth-child(1) { --card-tilt: 0deg; } + .value-card-animate:nth-child(2) { --card-tilt: 0deg; } + .value-card-animate:nth-child(3) { --card-tilt: 0deg; } + + /* subtle stacking effect */ + @media (min-width: 48rem) { + .value-card-animate:nth-child(1) { --card-tilt: -1.5deg; } + .value-card-animate:nth-child(2) { --card-tilt: 0deg; } + .value-card-animate:nth-child(3) { --card-tilt: 1.5deg; } + } + + diff --git a/src/styles/animations.css b/src/styles/animations.css index 0947d67..5612825 100644 --- a/src/styles/animations.css +++ b/src/styles/animations.css @@ -255,3 +255,33 @@ transition-duration: 0.01ms !important; } } + +/* ─── PAGE TRANSITIONS ────────────────────────── */ + +body { + opacity: 0; + transition: opacity 400ms cubic-bezier(0.22, 1, 0.36, 1); +} + +body.page-ready { + opacity: 1; +} + +/* ─── SCROLL PROGRESS ────────────────────────── */ + +.scroll-progress { + position: fixed; + top: 0; + left: 0; + height: 2px; + width: 0%; + background: linear-gradient(90deg, var(--color-primary) 0%, var(--color-primary-container) 100%); + z-index: 9999; + transition: width 100ms linear; +} + +@media (prefers-reduced-motion: reduce) { + .scroll-progress { + display: none; + } +}