ded2c974b7
- Hero: Maldonado aerial como background sutil (opacity 0.12) - DifferenceCards: fotos en cards Soporte (manos) e Infraestructura (monitor) - nosotros + en/about: bento grid de 5 fotos con captions honestos - ProcessSteps: background sutil de manos escribiendo (opacity 0.05) - Imágenes en public/images/photos/ (JPG + WebP + mobile resizes)
258 lines
8.5 KiB
Plaintext
258 lines
8.5 KiB
Plaintext
---
|
|
import type { TranslationKey } from '@/i18n/ui';
|
|
|
|
interface Props {
|
|
t: (key: TranslationKey) => string;
|
|
whatsappUrl: string;
|
|
}
|
|
|
|
const { t, whatsappUrl } = Astro.props;
|
|
---
|
|
<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>
|
|
|
|
<!-- Background photo: Maldonado coastline (subtle) -->
|
|
<div class="absolute inset-0 pointer-events-none" aria-hidden="true">
|
|
<picture>
|
|
<source type="image/webp" srcset="/images/photos/Bahía-aérea-atardecer-mar_1920x800.webp 1920w, /images/photos/Bahía-aérea-atardecer-mar_750.webp 750w" sizes="100vw" />
|
|
<img
|
|
src="/images/photos/Bahía-aérea-atardecer-mar_1920x800.jpg"
|
|
alt=""
|
|
width="1920" height="800"
|
|
class="w-full h-full object-cover"
|
|
style="opacity: 0.12;"
|
|
loading="eager"
|
|
fetchpriority="high"
|
|
decoding="async"
|
|
/>
|
|
</picture>
|
|
<!-- Gradient overlay for text readability -->
|
|
<div class="absolute inset-0" style="background: linear-gradient(180deg, var(--hds-bg) 0%, transparent 30%, transparent 60%, var(--hds-bg) 100%);"></div>
|
|
</div>
|
|
|
|
<!-- 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>
|
|
|
|
<!-- 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>
|
|
|
|
<!-- 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 id="hero-eyebrow" class="eyebrow mb-7 opacity-0">
|
|
<span>{t('hero.eyebrow')}</span>
|
|
</div>
|
|
|
|
<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
|
|
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 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>
|
|
<a href={whatsappUrl} target="_blank" rel="noopener noreferrer" class="btn-secondary">
|
|
{t('hero.ctaSecondary')}
|
|
</a>
|
|
</div>
|
|
|
|
<div id="hero-badges" class="flex flex-wrap items-center gap-x-8 gap-y-3 text-base 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')}
|
|
</span>
|
|
<span class="flex items-center gap-2">
|
|
<span style="color: var(--color-hds-naranja);">●</span>
|
|
{t('hero.badgeUptime')}
|
|
</span>
|
|
<span class="flex items-center gap-2">
|
|
<span style="color: var(--color-hds-naranja);">●</span>
|
|
{t('hero.badgeSupport')}
|
|
</span>
|
|
<span class="flex items-center gap-2">
|
|
<span style="color: var(--color-hds-naranja);">●</span>
|
|
{t('hero.badgeLocation')}
|
|
</span>
|
|
</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>
|