feat: Awwwards transformation Phases 1-6
Phase 1 — Design System: - Glassmorphism tokens (--glass-bg, --glass-border, --blur-glass) - Gradient tokens (--hds-gradient-hero, --hds-gradient-section) - Motion tokens (--ease-spring, --ease-out-expo) - .glass-card component class with hover uplift + mouse-tracking glow - .noise-overlay: SVG feTurbulence texture at 0.025 opacity - Buttons with spring easing, prefers-reduced-motion support Phase 2 — Preloader + Hero: - Preloader.astro: vanilla JS logo fade-in + loading bar + slide-up - Uses sessionStorage to skip on repeat visits - Hero.astro: full-bleed 100dvh, GSAP timeline, glass ring decoration - Parallax floating SVG shapes (sine yoyo animation) - i18n: hero.scrollDown key Phase 3 — 'Por qué elegirnos' Bento Grid: - DifferenceCards.astro: asymmetric 3-column bento grid - Glass cards with mouse-tracking glow (--mouse-x/--mouse-y) - GSAP ScrollTrigger stagger reveal (opacity 0→1, y: 40→0) Phase 4 — Pricing + Process: - planes.astro: 5 visible + 4 in details accordion - Empresarial as hero card, price annual only (no toggle) - ProcessSteps.astro: timeline + ScrollTrigger progress bar Phase 5 — Global Polish: - LenisScroll.astro: smooth scroll (duration 1.2, cubic easing) - GSAP ticker sync, noise overlay in BaseLayout Phase 6 — Deploy: - deploy.sh: auto-detects repo path, auto-builds if stale - Relative paths instead of hardcoded /root/opencode/development
This commit is contained in:
+186
-31
@@ -8,50 +8,90 @@ interface Props {
|
||||
|
||||
const { t, whatsappUrl } = Astro.props;
|
||||
---
|
||||
<section class="relative overflow-hidden pt-20 pb-28 md:pt-32 md:pb-40">
|
||||
<div class="absolute inset-0 particle-grid" aria-hidden="true"></div>
|
||||
<div class="absolute inset-0" style="background: linear-gradient(180deg, transparent 0%, var(--hds-bg) 100%);" aria-hidden="true"></div>
|
||||
<section
|
||||
id="hero"
|
||||
class="relative overflow-hidden flex items-center"
|
||||
style="min-height: 100dvh; background: var(--hds-bg);"
|
||||
>
|
||||
<!-- Atmospheric radial gradient -->
|
||||
<div
|
||||
class="absolute inset-0 pointer-events-none"
|
||||
style="background: var(--hds-gradient-hero);"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
|
||||
<div class="absolute top-32 right-8 md:right-16 opacity-50" aria-hidden="true">
|
||||
<svg width="120" height="120" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0" y="0" width="12" height="12" fill="#EE7623" rx="1"/>
|
||||
<rect x="14" y="0" width="12" height="12" fill="#FA9F5C" rx="1"/>
|
||||
<rect x="28" y="0" width="12" height="12" fill="#FFCBA1" rx="1"/>
|
||||
<rect x="0" y="14" width="12" height="12" fill="#FA9F5C" rx="1"/>
|
||||
<rect x="14" y="14" width="12" height="12" fill="#EE7623" rx="1"/>
|
||||
<rect x="28" y="14" width="12" height="12" fill="#FA9F5C" rx="1"/>
|
||||
<rect x="0" y="28" width="12" height="12" fill="#FFCBA1" rx="1"/>
|
||||
<rect x="14" y="28" width="12" height="12" fill="#FA9F5C" rx="1"/>
|
||||
<rect x="28" y="28" width="12" height="12" fill="#EE7623" rx="1"/>
|
||||
</svg>
|
||||
<!-- Floating decorative shapes (parallax) -->
|
||||
<div class="absolute inset-0 overflow-hidden pointer-events-none" aria-hidden="true">
|
||||
<div id="hero-float-top" class="absolute opacity-30" style="top: 15%; right: 12%;">
|
||||
<svg width="120" height="120" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0" y="0" width="12" height="12" fill="#EE7623" rx="1"/>
|
||||
<rect x="14" y="0" width="12" height="12" fill="#FA9F5C" rx="1"/>
|
||||
<rect x="28" y="0" width="12" height="12" fill="#FFCBA1" rx="1"/>
|
||||
<rect x="0" y="14" width="12" height="12" fill="#FA9F5C" rx="1"/>
|
||||
<rect x="14" y="14" width="12" height="12" fill="#EE7623" rx="1"/>
|
||||
<rect x="28" y="14" width="12" height="12" fill="#FA9F5C" rx="1"/>
|
||||
<rect x="0" y="28" width="12" height="12" fill="#FFCBA1" rx="1"/>
|
||||
<rect x="14" y="28" width="12" height="12" fill="#FA9F5C" rx="1"/>
|
||||
<rect x="28" y="28" width="12" height="12" fill="#EE7623" rx="1"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div id="hero-float-mid" class="absolute opacity-25" style="top: 55%; left: 8%;">
|
||||
<svg width="80" height="80" viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0" y="0" width="10" height="10" fill="#FA9F5C" rx="1"/>
|
||||
<rect x="12" y="0" width="10" height="10" fill="#EE7623" rx="1"/>
|
||||
<rect x="0" y="12" width="10" height="10" fill="#FFCBA1" rx="1"/>
|
||||
<rect x="12" y="12" width="10" height="10" fill="#FA9F5C" rx="1"/>
|
||||
<rect x="0" y="24" width="10" height="10" fill="#EE7623" rx="1"/>
|
||||
<rect x="12" y="24" width="10" height="10" fill="#FFCBA1" rx="1"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div id="hero-float-bot" class="absolute opacity-20" style="bottom: 20%; right: 20%;">
|
||||
<svg width="64" height="64" viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0" y="0" width="8" height="8" fill="#EE7623" rx="1"/>
|
||||
<rect x="10" y="0" width="8" height="8" fill="#FFCBA1" rx="1"/>
|
||||
<rect x="0" y="10" width="8" height="8" fill="#FA9F5C" rx="1"/>
|
||||
<rect x="10" y="10" width="8" height="8" fill="#EE7623" rx="1"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-12 left-8 md:left-16 opacity-40" aria-hidden="true">
|
||||
<svg width="80" height="80" viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0" y="0" width="10" height="10" fill="#FA9F5C" rx="1"/>
|
||||
<rect x="12" y="0" width="10" height="10" fill="#EE7623" rx="1"/>
|
||||
<rect x="0" y="12" width="10" height="10" fill="#FFCBA1" rx="1"/>
|
||||
<rect x="12" y="12" width="10" height="10" fill="#FA9F5C" rx="1"/>
|
||||
<rect x="0" y="24" width="10" height="10" fill="#EE7623" rx="1"/>
|
||||
<rect x="12" y="24" width="10" height="10" fill="#FFCBA1" rx="1"/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- Decorative glass ring (subtle) -->
|
||||
<div
|
||||
id="hero-glass-ring"
|
||||
class="absolute pointer-events-none rounded-full opacity-0"
|
||||
style="width: min(600px, 80vw); height: min(600px, 80vw);
|
||||
top: 50%; left: 70%; transform: translate(-50%, -50%);
|
||||
border: 1px solid var(--glass-border);
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: blur(40px);
|
||||
-webkit-backdrop-filter: blur(40px);"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
|
||||
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<!-- Content -->
|
||||
<div class="relative z-10 w-full max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-32 md:py-40">
|
||||
<div class="max-w-4xl">
|
||||
<div class="eyebrow mb-7">
|
||||
<div id="hero-eyebrow" class="eyebrow mb-7 opacity-0">
|
||||
<span>{t('hero.eyebrow')}</span>
|
||||
</div>
|
||||
|
||||
<h1 class="font-display leading-[0.98] mb-8" style="font-size: clamp(2.75rem, 7vw, 5.5rem); color: var(--hds-fg); letter-spacing: -0.025em; font-weight: 400;">
|
||||
<h1
|
||||
id="hero-headline"
|
||||
class="font-display leading-[0.98] mb-8 opacity-0"
|
||||
style="font-size: clamp(2.75rem, 7vw, 5.5rem); color: var(--hds-fg); letter-spacing: -0.025em; font-weight: 400;"
|
||||
>
|
||||
{t('hero.title')}
|
||||
</h1>
|
||||
|
||||
<p class="text-lg md:text-xl leading-relaxed mb-10 max-w-2xl" style="color: var(--hds-fg-soft);">
|
||||
<p
|
||||
id="hero-body"
|
||||
class="text-lg md:text-xl leading-relaxed mb-10 max-w-2xl opacity-0"
|
||||
style="color: var(--hds-fg-soft);"
|
||||
>
|
||||
{t('hero.body')}
|
||||
</p>
|
||||
|
||||
<div class="flex flex-col sm:flex-row gap-4 mb-14">
|
||||
<div id="hero-ctas" class="flex flex-col sm:flex-row gap-4 mb-14 opacity-0">
|
||||
<a href="/planes/" class="btn-primary">
|
||||
{t('hero.ctaPrimary')}
|
||||
</a>
|
||||
@@ -60,7 +100,7 @@ const { t, whatsappUrl } = Astro.props;
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap items-center gap-x-8 gap-y-3 text-sm" style="color: var(--hds-fg-muted);">
|
||||
<div id="hero-badges" class="flex flex-wrap items-center gap-x-8 gap-y-3 text-sm opacity-0" style="color: var(--hds-fg-muted);">
|
||||
<span class="flex items-center gap-2">
|
||||
<span style="color: var(--color-hds-naranja);">●</span>
|
||||
{t('hero.badge26')}
|
||||
@@ -80,4 +120,119 @@ const { t, whatsappUrl } = Astro.props;
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Scroll indicator -->
|
||||
<div id="hero-scroll-indicator" class="absolute bottom-8 left-1/2 -translate-x-1/2 opacity-0 pointer-events-none" aria-hidden="true">
|
||||
<div class="flex flex-col items-center gap-2" style="color: var(--hds-fg-muted);">
|
||||
<span class="text-[10px] uppercase tracking-[0.3em] font-semibold">{t('hero.scrollDown')}</span>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M12 5v14M19 12l-7 7-7-7"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
import gsap from 'gsap';
|
||||
|
||||
const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
|
||||
if (!prefersReduced) {
|
||||
const heroTimeline = gsap.timeline({ delay: 0.3 });
|
||||
|
||||
heroTimeline
|
||||
.to('#hero-glass-ring', {
|
||||
opacity: 1,
|
||||
scale: 1.05,
|
||||
duration: 1.4,
|
||||
ease: 'power3.out',
|
||||
})
|
||||
.to('#hero-eyebrow', {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
duration: 0.6,
|
||||
ease: 'power2.out',
|
||||
}, '-=0.8')
|
||||
.to('#hero-headline', {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
duration: 0.8,
|
||||
ease: 'power3.out',
|
||||
}, '-=0.1')
|
||||
.to('#hero-body', {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
duration: 0.7,
|
||||
ease: 'power2.out',
|
||||
}, '-=0.2')
|
||||
.to('#hero-ctas', {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
duration: 0.6,
|
||||
ease: 'power2.out',
|
||||
}, '-=0.3')
|
||||
.to('#hero-badges', {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
duration: 0.5,
|
||||
}, '-=0.4')
|
||||
.to('#hero-scroll-indicator', {
|
||||
opacity: 1,
|
||||
duration: 0.6,
|
||||
}, '-=0.2');
|
||||
|
||||
// Parallax floating shapes
|
||||
gsap.to('#hero-float-top', {
|
||||
y: -30,
|
||||
x: -15,
|
||||
duration: 3,
|
||||
ease: 'sine.inOut',
|
||||
repeat: -1,
|
||||
yoyo: true,
|
||||
});
|
||||
gsap.to('#hero-float-mid', {
|
||||
y: 25,
|
||||
x: 12,
|
||||
duration: 4,
|
||||
ease: 'sine.inOut',
|
||||
repeat: -1,
|
||||
yoyo: true,
|
||||
delay: 0.5,
|
||||
});
|
||||
gsap.to('#hero-float-bot', {
|
||||
y: -20,
|
||||
x: -10,
|
||||
duration: 3.5,
|
||||
ease: 'sine.inOut',
|
||||
repeat: -1,
|
||||
yoyo: true,
|
||||
delay: 1,
|
||||
});
|
||||
} else {
|
||||
// Show everything without animation
|
||||
document.querySelectorAll('#hero-eyebrow, #hero-headline, #hero-body, #hero-ctas, #hero-badges, #hero-scroll-indicator, #hero-glass-ring').forEach(el => {
|
||||
(el as HTMLElement).style.opacity = '1';
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#hero-eyebrow {
|
||||
transform: translateY(16px);
|
||||
}
|
||||
#hero-headline {
|
||||
transform: translateY(24px);
|
||||
}
|
||||
#hero-body {
|
||||
transform: translateY(20px);
|
||||
}
|
||||
#hero-ctas {
|
||||
transform: translateY(16px);
|
||||
}
|
||||
#hero-badges {
|
||||
transform: translateY(12px);
|
||||
}
|
||||
#hero-glass-ring {
|
||||
transform: translate(-50%, -50%) scale(0.85);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user