Boundless/frontend/src/routes/+page.svelte
2025-01-29 00:18:39 +01:00

238 lines
8.4 KiB
Svelte

<script lang="ts">
import { onMount } from 'svelte';
import { animate, stagger, inView } from 'motion';
import { goto } from '$app/navigation';
onMount(() => {
// Hero section animations
const heroTextAnimation = {
initial: { opacity: 0, y: 50 },
animate: {
opacity: 1,
y: 0,
duration: 0.8,
delay: 0.2,
easing: [0.17, 0.55, 0.55, 1] // Smooth easing curve instead of spring
}
};
const heroImageAnimation = {
initial: { opacity: 0, scale: 0.9 },
animate: {
opacity: 1,
scale: 1,
duration: 1.2,
easing: 'ease-out'
}
};
// Initialize hero animations
animate('.hero-text', heroTextAnimation.initial);
animate('.hero-text', heroTextAnimation.animate);
animate('.hero-image', heroImageAnimation.initial);
animate('.hero-image', heroImageAnimation.animate);
// Feature cards animation
const featureCardAnimation = {
initial: { opacity: 0, y: 30 },
animate: {
opacity: 1,
y: 0,
duration: 0.6,
easing: 'ease-out'
}
};
// Setup intersection observer for feature grid
inView('.feature-grid', (info: any) => {
const cards = info.target.querySelectorAll('.feature-card');
cards.forEach((card: any, index: any) => {
animate(card,
featureCardAnimation.initial,
{
...featureCardAnimation.animate,
delay: index * 0.15 // Manual stagger implementation
}
);
});
}, {
amount: 0.2 // Trigger when 20% of element is visible
});
// CTA section animation
const ctaAnimation = {
initial: { opacity: 0, scale: 0.95 },
animate: {
opacity: 1,
scale: 1,
duration: 0.8,
easing: 'ease-out'
}
};
inView('.cta-section', (info: any) => {
animate(info.target, ctaAnimation.initial);
animate(info.target, ctaAnimation.animate);
}, {
amount: 0.3 // Trigger when 30% of element is visible
});
});
</script>
<svelte:head>
<title>Boundless | Travel with Soul</title>
<meta name="description" content="Where strangers become allies and journeys create magic. Travel Together, Stay Boundless." />
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&display=swap" rel="stylesheet" />
</svelte:head>
<div class="font-[Space+Grotesk] bg-base-100 overflow-hidden">
<!-- Navigation -->
<nav class="navbar bg-base-100/90 backdrop-blur-sm sticky top-0 z-50 shadow-sm px-4 md:px-8">
<div class="flex-1">
<a class="btn btn-ghost text-xl gap-2 hover:-translate-y-1 transition-transform">
<span class="text-3xl">🌍</span>
<span class="font-bold bg-gradient-to-r from-primary to-accent bg-clip-text text-transparent">
Boundless
</span>
</a>
</div>
<div class="flex-none">
<ul class="menu menu-horizontal px-1 gap-4 hidden md:flex">
<li>
<a class="font-medium hover:text-primary transition-colors">
How it works
</a>
</li>
<li>
<a class="font-medium hover:text-primary transition-colors">
Stories
</a>
</li>
<li>
<button on:click={() => {goto('/onboarding')}} class="btn btn-primary btn-sm hover:scale-105 transition-transform">
Join Beta
</button>
</li>
</ul>
<div class="dropdown dropdown-end md:hidden">
<div tabindex="0" role="button" class="btn btn-ghost btn-circle">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h7" /></svg>
</div>
<ul tabindex="0" class="menu menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-100 rounded-box w-52">
<li><a>How it works</a></li>
<li><a>Stories</a></li>
<li><button on:click={() => {goto('/onboarding')}}>Join Beta</button></li>
</ul>
</div>
</div>
</nav>
<!-- Hero Section -->
<section class="hero min-h-[90vh] relative">
<div class="absolute inset-0 bg-gradient-to-br from-primary/10 to-secondary/10 -skew-y-3 scale-125 opacity-50"></div>
<div class="hero-content flex-col lg:flex-row-reverse gap-8 lg:gap-16 relative z-10 px-4 md:px-8">
<div class="hero-image">
<div class="mask-parallelogram relative group">
<img
src="src\lib\assets\h.png"
class="w-full max-w-2xl rounded-2xl shadow-2xl transform hover:rotate-1 transition-[transform] duration-300"
alt="Happy travelers"
/>
<div class="absolute inset-0 bg-gradient-to-r from-primary/20 to-secondary/20 rounded-2xl"></div>
</div>
</div>
<div class="hero-text text-center lg:text-left">
<h1 class="text-4xl md:text-6xl font-bold leading-tight mb-6">
Find Your
<span class="relative inline-block">
<span class="bg-gradient-to-r from-primary to-accent text-transparent bg-clip-text">
Wander Tribe
</span>
<div class="absolute -bottom-2 left-0 w-full h-2 bg-primary/20 -skew-x-12"></div>
</span>
</h1>
<p class="text-lg md:text-xl mb-8 opacity-90 leading-relaxed">
Where strangers become allies and every journey leaves the world kinder.
</p>
<div class="flex flex-col md:flex-row gap-4 justify-center lg:justify-start">
<button on:click={() => {goto('/onboarding')}} class="btn btn-primary px-8 gap-2 hover:scale-[1.02] transition-transform">
<span class="text-xl"></span>
Start Your Journey
</button>
<button class="btn btn-outline btn-secondary px-8 group">
How It Works
<span class="group-hover:translate-x-1 transition-transform"></span>
</button>
</div>
</div>
</div>
</section>
<!-- Features Grid -->
<div class="container mx-auto px-4 py-16 md:py-24">
<div class="feature-grid grid grid-cols-1 md:grid-cols-3 gap-8 text-center">
<div class="feature-card card bg-base-100 p-8 border border-base-300/20 hover:border-primary/20 transition-all transform hover:-translate-y-2">
<div class="text-6xl mb-6 animate-pulse">🗺️</div>
<h3 class="text-2xl font-bold mb-4">Community Routes</h3>
<p class="text-gray-500">Follow trails blazed by fellow wanderers</p>
</div>
<div class="feature-card card bg-base-100 p-8 border border-base-300/20 hover:border-primary/20 transition-all transform hover:-translate-y-2">
<div class="text-6xl mb-6 animate-pulse">🔮</div>
<h3 class="text-2xl font-bold mb-4">Magic Detours</h3>
<p class="text-gray-500">Algorithm-curated serendipity</p>
</div>
<div class="feature-card card bg-base-100 p-8 border border-base-300/20 hover:border-primary/20 transition-all transform hover:-translate-y-2">
<div class="text-6xl mb-6 animate-pulse">❤️</div>
<h3 class="text-2xl font-bold mb-4">Impact Legacy</h3>
<p class="text-gray-500">Travel that gives back</p>
</div>
</div>
</div>
<!-- CTA Section -->
<div class="cta-section bg-gradient-to-br from-primary to-secondary text-primary-content py-16 md:py-24">
<div class="text-center max-w-2xl mx-auto px-4">
<h2 class="text-3xl md:text-4xl font-bold mb-8 leading-tight">
Ready to Travel<br>
<span class="text-4xl md:text-5xl font-black">Like You Mean It?</span>
</h2>
<button on:click={() => {goto('/onboarding')}} class="btn btn-accent btn-lg gap-2 transform hover:scale-105 transition-transform">
🚀 Claim Beta Spot
</button>
</div>
</div>
<!-- Footer -->
<footer class="footer items-center p-8 bg-neutral text-neutral-content">
<!-- ... (keep previous footer content) ... -->
</footer>
</div>
<style global>
:root {
--font-family: 'Space Grotesk', system-ui;
}
body {
font-family: var(--font-family);
}
.mask-parallelogram {
mask-image: linear-gradient(to bottom right, transparent 2%, black 15%);
-webkit-mask-image: linear-gradient(to bottom right, transparent 2%, black 15%);
}
@keyframes gradient-pulse {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
.animate-gradient-pulse {
background-size: 200% auto;
animation: gradient-pulse 8s ease infinite;
}
</style>