---
// ABOUTME: Custom landing page for Pierre Fitness Intelligence
// ABOUTME: Marketing homepage with modern design, B2B section, and streamlined messaging
import '../styles/global.css';
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pierre - AI-Powered Fitness Intelligence</title>
<meta name="description" content="AI fitness coaching powered by real sports science. Specialized coaches for training, nutrition, recovery, and mobility—connected to your fitness devices.">
<meta name="keywords" content="fitness insights, AI fitness coach, Strava analysis, Garmin insights, training load, recovery score, nutrition tracking, sleep analysis">
<!-- Open Graph -->
<meta property="og:title" content="Pierre - AI-Powered Fitness Intelligence">
<meta property="og:description" content="Smarter insights from your fitness data using real sports science.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://pierre.async-io.org">
<meta property="og:image" content="https://pierre.async-io.org/pierre-logo.svg">
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<!-- Favicon -->
<link rel="icon" type="image/svg+xml" href="/pierre-favicon.svg">
<style>
:root {
--banner-height: 2.5rem;
--hero-padding-with-banner: 11rem;
--hero-padding-without-banner: 8rem;
}
@media (prefers-reduced-motion: reduce) {
#main-nav, #hero-section { transition: none !important; }
}
</style>
</head>
<body class="bg-[#0F0F1A] text-white font-sans antialiased">
<!-- Announcement Banner -->
<div id="announcement-banner" class="fixed top-0 left-0 right-0 z-[60] gradient-pierre text-white text-center py-2.5 px-4 text-sm font-medium">
<div class="max-w-7xl mx-auto flex items-center justify-center gap-1 sm:gap-2 pr-10 sm:pr-0">
<span class="hidden sm:inline">🚀</span>
<span class="text-xs sm:text-sm"><strong class="hidden sm:inline">Pierre Fitness Intelligence</strong><strong class="sm:hidden">Pierre</strong> is coming soon!</span>
<a href="#early-access" class="ml-1 sm:ml-2 underline underline-offset-2 hover:no-underline font-semibold text-xs sm:text-sm whitespace-nowrap">Sign Up →</a>
<button id="banner-dismiss" class="absolute right-1 sm:right-2 top-1/2 -translate-y-1/2 w-9 h-9 sm:w-11 sm:h-11 flex items-center justify-center hover:bg-white/20 rounded transition-colors focus:outline-none focus:ring-2 focus:ring-white/60" aria-label="Dismiss banner">
<svg class="w-4 h-4 sm:w-5 sm:h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</div>
</div>
<!-- Navigation -->
<nav id="main-nav" class="fixed top-10 left-0 right-0 z-50 bg-[#0F0F1A]/90 backdrop-blur-md border-b border-white/10 transition-[top] duration-300 ease-out">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-16">
<div class="flex items-center gap-3">
<img src="/pierre-logo.svg" alt="Pierre" class="h-10 w-10">
<span class="text-xl font-semibold hidden sm:inline">Pierre</span>
</div>
<!-- Desktop Navigation -->
<div class="hidden md:flex items-center gap-8">
<a href="#coaches" class="text-gray-300 hover:text-white transition-colors">AI Coaches</a>
<a href="#features" class="text-gray-300 hover:text-white transition-colors">Features</a>
<a href="#intelligence" class="text-gray-300 hover:text-white transition-colors">Intelligence</a>
<a href="#developers" class="text-gray-300 hover:text-white transition-colors">Developers</a>
<a href="/documentation/" class="text-gray-300 hover:text-white transition-colors">Docs</a>
<a href="#early-access" class="gradient-pierre px-4 py-2 rounded-lg font-medium hover:opacity-90 transition-opacity">
Get Early Access
</a>
</div>
<!-- Mobile Hamburger Button -->
<button id="mobile-menu-btn" class="md:hidden p-2 rounded-lg hover:bg-white/10 transition-colors" aria-label="Open menu" aria-expanded="false">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path id="hamburger-icon" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
<path id="close-icon" class="hidden" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
<!-- Mobile Menu -->
<div id="mobile-menu" class="hidden md:hidden pb-4">
<div class="flex flex-col gap-2 mobile-menu-enter">
<a href="#coaches" class="px-4 py-3 text-gray-300 hover:text-white hover:bg-white/5 rounded-lg transition-colors">AI Coaches</a>
<a href="#features" class="px-4 py-3 text-gray-300 hover:text-white hover:bg-white/5 rounded-lg transition-colors">Features</a>
<a href="#intelligence" class="px-4 py-3 text-gray-300 hover:text-white hover:bg-white/5 rounded-lg transition-colors">Intelligence</a>
<a href="#developers" class="px-4 py-3 text-gray-300 hover:text-white hover:bg-white/5 rounded-lg transition-colors">Developers</a>
<a href="/documentation/" class="px-4 py-3 text-gray-300 hover:text-white hover:bg-white/5 rounded-lg transition-colors">Docs</a>
<a href="#early-access" class="gradient-pierre px-4 py-3 rounded-lg font-medium text-center mt-2">Get Early Access</a>
</div>
</div>
</div>
</nav>
<!-- Hero Section with Gradient Mesh -->
<section id="hero-section" class="relative pt-44 pb-20 px-4 overflow-hidden transition-[padding] duration-300 ease-out">
<!-- Animated Gradient Mesh Background -->
<div class="absolute inset-0 gradient-mesh"></div>
<!-- Floating Logo Elements (decorative) -->
<div class="absolute inset-0 overflow-hidden pointer-events-none">
<img src="/pierre-logo.svg" alt="" class="absolute top-20 left-[10%] w-16 h-16 opacity-10 float-slow" aria-hidden="true">
<img src="/pierre-logo.svg" alt="" class="absolute top-40 right-[15%] w-12 h-12 opacity-10 float-medium" aria-hidden="true">
<img src="/pierre-logo.svg" alt="" class="absolute bottom-32 left-[20%] w-10 h-10 opacity-10 float-fast" aria-hidden="true">
<img src="/pierre-logo.svg" alt="" class="absolute bottom-20 right-[25%] w-14 h-14 opacity-10 float-slow" aria-hidden="true">
</div>
<div class="relative max-w-7xl mx-auto text-center">
<h1 class="text-4xl sm:text-5xl lg:text-6xl font-bold mb-6 leading-tight">
<span class="gradient-pierre-text">Fitness Intelligence</span><br>
for Everyone
</h1>
<p class="text-xl text-gray-300 max-w-3xl mx-auto mb-8">
Expert AI coaching for <strong class="text-emerald-400">training</strong>,
<strong class="text-amber-400">nutrition</strong>, <strong class="text-indigo-400">recovery</strong>, and <strong class="text-rose-400">mobility</strong>—powered by real sports science.
Connect your fitness devices and get personalized guidance tailored to your goals.
</p>
<!-- Device Badges (moved up for visual break) -->
<div class="flex flex-wrap justify-center gap-3 mb-10">
<span class="protocol-badge px-4 py-2 rounded-full bg-orange-500/20 border border-orange-500/30 text-orange-400 text-sm font-medium">
Strava
</span>
<span class="protocol-badge px-4 py-2 rounded-full bg-blue-500/20 border border-blue-500/30 text-blue-400 text-sm font-medium">
Garmin
</span>
<span class="protocol-badge px-4 py-2 rounded-full bg-teal-500/20 border border-teal-500/30 text-teal-400 text-sm font-medium">
Fitbit
</span>
<span class="protocol-badge px-4 py-2 rounded-full bg-red-500/20 border border-red-500/30 text-red-400 text-sm font-medium">
WHOOP
</span>
<span class="protocol-badge px-4 py-2 rounded-full bg-lime-500/20 border border-lime-500/30 text-lime-400 text-sm font-medium">
Coros
</span>
<span class="protocol-badge px-4 py-2 rounded-full bg-purple-500/20 border border-purple-500/30 text-purple-400 text-sm font-medium">
Terra
</span>
</div>
<div class="flex flex-col sm:flex-row gap-4 justify-center">
<a href="#early-access" class="gradient-pierre px-8 py-3 rounded-lg font-semibold text-lg hover:opacity-90 transition-opacity">
Get Early Access
</a>
<a href="#coaches" class="px-8 py-3 rounded-lg font-semibold text-lg border border-white/20 hover:bg-white/5 transition-colors">
Meet Your Coaches
</a>
</div>
</div>
</section>
<!-- Section Divider -->
<div class="section-divider max-w-4xl mx-auto"></div>
<!-- AI Coaches Section - THE MAIN PRODUCT -->
<section id="coaches" class="py-20 px-4">
<div class="max-w-7xl mx-auto">
<div class="text-center mb-12">
<div class="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-violet-600/20 border border-violet-500/30 text-violet-400 text-sm font-medium mb-4">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"/>
</svg>
AI-Powered Expertise
</div>
<h2 class="text-3xl sm:text-4xl font-bold mb-4">Specialized AI Coaches</h2>
<p class="text-gray-400 max-w-2xl mx-auto">
Expert guidance across every aspect of your fitness journey. Each coach brings deep domain knowledge powered by real sports science.
</p>
</div>
<!-- Coach Capabilities Grid -->
<div class="grid sm:grid-cols-2 lg:grid-cols-5 gap-6">
<!-- Training -->
<div class="bg-[#1E1E2E] rounded-xl p-6 border border-emerald-500/20 hover:border-emerald-500/40 transition-all">
<div class="w-12 h-12 rounded-lg gradient-activity flex items-center justify-center mb-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
</div>
<h3 class="text-lg font-semibold text-emerald-400 mb-2">Training</h3>
<p class="text-gray-400 text-sm mb-4">Race-specific coaching from 5K to marathon. Pacing strategies and periodization.</p>
<div class="flex flex-wrap gap-1.5">
<span class="px-2 py-0.5 rounded-full bg-emerald-500/10 text-emerald-400 text-xs">5K-Marathon</span>
<span class="px-2 py-0.5 rounded-full bg-emerald-500/10 text-emerald-400 text-xs">Pacing</span>
</div>
</div>
<!-- Nutrition -->
<div class="bg-[#1E1E2E] rounded-xl p-6 border border-amber-500/20 hover:border-amber-500/40 transition-all">
<div class="w-12 h-12 rounded-lg gradient-nutrition flex items-center justify-center mb-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"/>
</svg>
</div>
<h3 class="text-lg font-semibold text-amber-400 mb-2">Nutrition</h3>
<p class="text-gray-400 text-sm mb-4">Pre/post-workout fueling and race-day nutrition. Meal timing and hydration.</p>
<div class="flex flex-wrap gap-1.5">
<span class="px-2 py-0.5 rounded-full bg-amber-500/10 text-amber-400 text-xs">Meal Timing</span>
<span class="px-2 py-0.5 rounded-full bg-amber-500/10 text-amber-400 text-xs">Race Day</span>
</div>
</div>
<!-- Recovery -->
<div class="bg-[#1E1E2E] rounded-xl p-6 border border-indigo-500/20 hover:border-indigo-500/40 transition-all">
<div class="w-12 h-12 rounded-lg gradient-recovery flex items-center justify-center mb-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/>
</svg>
</div>
<h3 class="text-lg font-semibold text-indigo-400 mb-2">Recovery</h3>
<p class="text-gray-400 text-sm mb-4">Sleep optimization and HRV interpretation. Know when to push and when to rest.</p>
<div class="flex flex-wrap gap-1.5">
<span class="px-2 py-0.5 rounded-full bg-indigo-500/10 text-indigo-400 text-xs">Sleep</span>
<span class="px-2 py-0.5 rounded-full bg-indigo-500/10 text-indigo-400 text-xs">HRV</span>
</div>
</div>
<!-- Mobility -->
<div class="bg-[#1E1E2E] rounded-xl p-6 border border-rose-500/20 hover:border-rose-500/40 transition-all">
<div class="w-12 h-12 rounded-lg gradient-mobility flex items-center justify-center mb-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
</svg>
</div>
<h3 class="text-lg font-semibold text-rose-400 mb-2">Mobility</h3>
<p class="text-gray-400 text-sm mb-4">Stretching routines, yoga for athletes, and injury prevention. Desk athlete solutions.</p>
<div class="flex flex-wrap gap-1.5">
<span class="px-2 py-0.5 rounded-full bg-rose-500/10 text-rose-400 text-xs">Stretching</span>
<span class="px-2 py-0.5 rounded-full bg-rose-500/10 text-rose-400 text-xs">Yoga</span>
</div>
</div>
<!-- Analysis -->
<div class="bg-[#1E1E2E] rounded-xl p-6 border border-violet-500/20 hover:border-violet-500/40 transition-all">
<div class="w-12 h-12 rounded-lg bg-violet-600/30 flex items-center justify-center mb-4">
<svg class="w-6 h-6 text-violet-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
</svg>
</div>
<h3 class="text-lg font-semibold text-violet-400 mb-2">Analysis</h3>
<p class="text-gray-400 text-sm mb-4">Pattern detection and training load trends. Performance insights from your data.</p>
<div class="flex flex-wrap gap-1.5">
<span class="px-2 py-0.5 rounded-full bg-violet-500/10 text-violet-400 text-xs">Patterns</span>
<span class="px-2 py-0.5 rounded-full bg-violet-500/10 text-violet-400 text-xs">Load</span>
</div>
</div>
</div>
<!-- Coach Library Banner -->
<div class="mt-10 bg-gradient-to-r from-violet-500/10 via-cyan-500/10 to-violet-500/10 rounded-xl p-6 border border-violet-500/20">
<div class="flex flex-col sm:flex-row items-center justify-between gap-4">
<div class="text-center sm:text-left">
<h3 class="text-lg font-semibold mb-1">Coach Library & Marketplace</h3>
<p class="text-gray-400 text-sm">Browse expert coaches or create your own. Share and discover community coaches.</p>
</div>
<a href="#early-access" class="gradient-pierre px-5 py-2.5 rounded-lg font-medium text-sm hover:opacity-90 transition-opacity whitespace-nowrap">
Get Early Access
</a>
</div>
</div>
</div>
</section>
<!-- Section Divider -->
<div class="section-divider max-w-4xl mx-auto"></div>
<!-- Four Pillars Section -->
<section id="features" class="py-20 px-4 node-pattern">
<div class="max-w-7xl mx-auto">
<div class="text-center mb-16">
<h2 class="text-3xl sm:text-4xl font-bold mb-4">Complete Fitness Picture</h2>
<p class="text-gray-400 max-w-2xl mx-auto">
Real insights across four pillars of wellness using proven sports science.
</p>
</div>
<div class="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
<!-- Training Pillar -->
<div class="bg-[#0F0F1A]/80 backdrop-blur-sm rounded-xl p-6 border border-emerald-500/20 hover:border-emerald-500/40 transition-all">
<div class="icon-container w-12 h-12 gradient-activity mb-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
</div>
<h3 class="text-lg font-semibold mb-2 text-emerald-400">Training</h3>
<p class="text-gray-400 text-sm mb-3">Know when to push and when to rest.</p>
<ul class="space-y-1.5 text-xs text-gray-500">
<li class="flex items-center gap-2">
<span class="w-1 h-1 rounded-full bg-emerald-500"></span>
Training load scores
</li>
<li class="flex items-center gap-2">
<span class="w-1 h-1 rounded-full bg-emerald-500"></span>
Fitness vs fatigue
</li>
<li class="flex items-center gap-2">
<span class="w-1 h-1 rounded-full bg-emerald-500"></span>
Race predictions
</li>
</ul>
</div>
<!-- Nutrition Pillar -->
<div class="bg-[#0F0F1A]/80 backdrop-blur-sm rounded-xl p-6 border border-amber-500/20 hover:border-amber-500/40 transition-all">
<div class="icon-container w-12 h-12 gradient-nutrition mb-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"/>
</svg>
</div>
<h3 class="text-lg font-semibold mb-2 text-amber-400">Nutrition</h3>
<p class="text-gray-400 text-sm mb-3">Fuel your training properly.</p>
<ul class="space-y-1.5 text-xs text-gray-500">
<li class="flex items-center gap-2">
<span class="w-1 h-1 rounded-full bg-amber-500"></span>
Calorie targets
</li>
<li class="flex items-center gap-2">
<span class="w-1 h-1 rounded-full bg-amber-500"></span>
Meal timing
</li>
<li class="flex items-center gap-2">
<span class="w-1 h-1 rounded-full bg-amber-500"></span>
Recipe library
</li>
</ul>
</div>
<!-- Recovery Pillar -->
<div class="bg-[#0F0F1A]/80 backdrop-blur-sm rounded-xl p-6 border border-indigo-500/20 hover:border-indigo-500/40 transition-all">
<div class="icon-container w-12 h-12 gradient-recovery mb-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/>
</svg>
</div>
<h3 class="text-lg font-semibold mb-2 text-indigo-400">Recovery</h3>
<p class="text-gray-400 text-sm mb-3">Optimize rest and readiness.</p>
<ul class="space-y-1.5 text-xs text-gray-500">
<li class="flex items-center gap-2">
<span class="w-1 h-1 rounded-full bg-indigo-500"></span>
Sleep quality
</li>
<li class="flex items-center gap-2">
<span class="w-1 h-1 rounded-full bg-indigo-500"></span>
HRV readiness
</li>
<li class="flex items-center gap-2">
<span class="w-1 h-1 rounded-full bg-indigo-500"></span>
Rest day guidance
</li>
</ul>
</div>
<!-- Mobility Pillar -->
<div class="bg-[#0F0F1A]/80 backdrop-blur-sm rounded-xl p-6 border border-rose-500/20 hover:border-rose-500/40 transition-all">
<div class="icon-container w-12 h-12 gradient-mobility mb-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
</svg>
</div>
<h3 class="text-lg font-semibold mb-2 text-rose-400">Mobility</h3>
<p class="text-gray-400 text-sm mb-3">Move better, prevent injury.</p>
<ul class="space-y-1.5 text-xs text-gray-500">
<li class="flex items-center gap-2">
<span class="w-1 h-1 rounded-full bg-rose-500"></span>
Stretching routines
</li>
<li class="flex items-center gap-2">
<span class="w-1 h-1 rounded-full bg-rose-500"></span>
Yoga for athletes
</li>
<li class="flex items-center gap-2">
<span class="w-1 h-1 rounded-full bg-rose-500"></span>
Desk athlete fixes
</li>
</ul>
</div>
</div>
</div>
</section>
<!-- Intelligence Section -->
<section id="intelligence" class="pt-20 pb-10 px-4">
<div class="max-w-7xl mx-auto">
<div class="text-center mb-12">
<h2 class="text-3xl sm:text-4xl font-bold mb-4">Real Sports Science, Not Guesswork</h2>
<p class="text-gray-400 max-w-2xl mx-auto">
Pierre uses the same methods trusted by elite coaches and sports scientists around the world.
</p>
</div>
<div class="bg-[#1E1E2E] rounded-xl p-8 border border-white/10">
<div class="grid md:grid-cols-3 gap-8">
<div class="text-center">
<div class="icon-container w-12 h-12 bg-emerald-500/20 mx-auto mb-4">
<svg class="w-6 h-6 text-emerald-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
</svg>
</div>
<h3 class="text-lg font-semibold mb-2">Training Load</h3>
<p class="text-gray-400 text-sm">
Measures how hard each workout is based on intensity and duration so you know exactly how much stress you're putting on your body.
</p>
</div>
<div class="text-center">
<div class="icon-container w-12 h-12 bg-cyan-500/20 mx-auto mb-4">
<svg class="w-6 h-6 text-cyan-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 6l3 1m0 0l-3 9a5.002 5.002 0 006.001 0M6 7l3 9M6 7l6-2m6 2l3-1m-3 1l-3 9a5.002 5.002 0 006.001 0M18 7l3 9m-3-9l-6-2m0-2v2m0 16V5m0 16H9m3 0h3"/>
</svg>
</div>
<h3 class="text-lg font-semibold mb-2">Fitness vs Fatigue</h3>
<p class="text-gray-400 text-sm">
Tracks your long-term fitness gains against short-term fatigue to find the sweet spot for peak performance on race day.
</p>
</div>
<div class="text-center">
<div class="icon-container w-12 h-12 bg-violet-600/20 mx-auto mb-4">
<svg class="w-6 h-6 text-violet-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"/>
</svg>
</div>
<h3 class="text-lg font-semibold mb-2">Race Predictions</h3>
<p class="text-gray-400 text-sm">
Get accurate predictions for 5K, 10K, half marathon, and marathon distances based on your actual training data.
</p>
</div>
</div>
</div>
<!-- Nutrition Feature Highlight -->
<div class="mt-8 bg-[#1E1E2E] rounded-xl p-8 border border-amber-500/20">
<div class="grid md:grid-cols-2 gap-8 items-center">
<div>
<div class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-amber-500/20 border border-amber-500/30 text-amber-400 text-xs font-medium mb-4">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"/>
</svg>
Recipe Management
</div>
<h3 class="text-2xl font-semibold mb-4">Training-Aware Meal Planning</h3>
<p class="text-gray-400 mb-6">
Build your personal recipe collection with meals optimized for your training schedule. Pierre validates nutrition using USDA data and adjusts macros based on whether you're fueling up, recovering, or resting.
</p>
<div class="space-y-3">
<div class="flex items-start gap-3">
<span class="text-amber-500 mt-0.5">✓</span>
<span class="text-gray-300 text-sm"><strong class="text-white">Pre-training meals</strong> — High-carb focus (55%) for energy</span>
</div>
<div class="flex items-start gap-3">
<span class="text-amber-500 mt-0.5">✓</span>
<span class="text-gray-300 text-sm"><strong class="text-white">Post-training meals</strong> — High-protein (30%) for recovery</span>
</div>
<div class="flex items-start gap-3">
<span class="text-amber-500 mt-0.5">✓</span>
<span class="text-gray-300 text-sm"><strong class="text-white">Rest day meals</strong> — Balanced macros with strategic carb reduction</span>
</div>
</div>
</div>
<div class="bg-[#0F0F1A] rounded-lg p-6 border border-white/5">
<div class="text-xs text-gray-500 mb-3 font-mono">Recipe validation based on ISSN guidelines</div>
<div class="space-y-4">
<div>
<div class="flex justify-between text-sm mb-1">
<span class="text-gray-400">Pre-Training</span>
<span class="text-amber-400">55% carbs</span>
</div>
<div class="h-2 bg-[#1E1E2E] rounded-full overflow-hidden">
<div class="h-full bg-gradient-to-r from-amber-600 to-amber-400" style="width: 55%"></div>
</div>
</div>
<div>
<div class="flex justify-between text-sm mb-1">
<span class="text-gray-400">Post-Training</span>
<span class="text-emerald-400">30% protein</span>
</div>
<div class="h-2 bg-[#1E1E2E] rounded-full overflow-hidden">
<div class="h-full bg-gradient-to-r from-emerald-600 to-emerald-400" style="width: 30%"></div>
</div>
</div>
<div>
<div class="flex justify-between text-sm mb-1">
<span class="text-gray-400">Rest Day</span>
<span class="text-indigo-400">35% fat</span>
</div>
<div class="h-2 bg-[#1E1E2E] rounded-full overflow-hidden">
<div class="h-full bg-gradient-to-r from-indigo-600 to-indigo-400" style="width: 35%"></div>
</div>
</div>
</div>
<div class="mt-4 pt-4 border-t border-white/5 text-xs text-gray-500">
Macros adjust automatically based on your TDEE and meal timing
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Privacy Section (Updated) -->
<section class="py-20 px-4 bg-[#1E1E2E]/50 node-pattern">
<div class="max-w-7xl mx-auto">
<div class="text-center mb-16">
<h2 class="text-3xl sm:text-4xl font-bold mb-4">Your Data, Your Control</h2>
<p class="text-gray-400 max-w-2xl mx-auto">
Pierre respects your privacy. Your fitness data stays secure and under your control.
</p>
</div>
<div class="grid md:grid-cols-3 gap-6">
<div class="bg-[#0F0F1A]/80 backdrop-blur-sm rounded-xl p-6 border border-white/10 text-center">
<div class="icon-container w-14 h-14 bg-emerald-500/20 mx-auto mb-4">
<svg class="w-7 h-7 text-emerald-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/>
</svg>
</div>
<h3 class="font-semibold mb-2">Encrypted & Secure</h3>
<p class="text-gray-400 text-sm">Your data is encrypted end-to-end and never shared with third parties.</p>
</div>
<div class="bg-[#0F0F1A]/80 backdrop-blur-sm rounded-xl p-6 border border-white/10 text-center">
<div class="icon-container w-14 h-14 bg-violet-600/20 mx-auto mb-4">
<svg class="w-7 h-7 text-violet-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"/>
</svg>
</div>
<h3 class="font-semibold mb-2">Code on GitHub</h3>
<p class="text-gray-400 text-sm">Review the source code, run it yourself, or contribute to development.</p>
</div>
<div class="bg-[#0F0F1A]/80 backdrop-blur-sm rounded-xl p-6 border border-white/10 text-center">
<div class="icon-container w-14 h-14 bg-cyan-500/20 mx-auto mb-4">
<svg class="w-7 h-7 text-cyan-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/>
</svg>
</div>
<h3 class="font-semibold mb-2">You're in Control</h3>
<p class="text-gray-400 text-sm">Connect and disconnect your devices anytime. Delete your data whenever you want.</p>
</div>
</div>
</div>
</section>
<!-- Section Divider -->
<div class="section-divider max-w-4xl mx-auto"></div>
<!-- For Developers Section (B2B) -->
<section id="developers" class="py-20 px-4 bg-[#1E1E2E]/30">
<div class="max-w-7xl mx-auto">
<div class="text-center mb-12">
<div class="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-violet-600/20 border border-violet-500/30 text-violet-400 text-sm font-medium mb-4">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"/>
</svg>
For Developers
</div>
<h2 class="text-3xl sm:text-4xl font-bold mb-4">Build with Pierre</h2>
<p class="text-gray-400 max-w-2xl mx-auto">
Integrate fitness intelligence into your applications using industry-standard protocols.
</p>
</div>
<div class="grid md:grid-cols-2 gap-8">
<!-- MCP Protocol -->
<div class="bg-[#0F0F1A] rounded-xl p-8 border border-violet-500/20">
<div class="flex items-center gap-4 mb-6">
<div class="icon-container w-12 h-12 bg-violet-600/20">
<svg class="w-6 h-6 text-violet-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
</svg>
</div>
<div>
<h3 class="text-xl font-semibold">MCP Protocol</h3>
<p class="text-gray-500 text-sm">Model Context Protocol</p>
</div>
</div>
<p class="text-gray-400 mb-6">
Connect Pierre to Claude, ChatGPT, or any MCP-compatible AI assistant. Your AI gains access to 34 fitness tools.
</p>
<div class="code-block rounded-lg p-4 text-sm overflow-x-auto">
<code class="text-gray-300">
<span class="text-violet-400">"mcpServers"</span>: {<br>
<span class="text-emerald-400">"pierre"</span>: {<br>
<span class="text-amber-400">"url"</span>: <span class="text-cyan-400">"https://api.pierre.fitness/mcp"</span><br>
}<br>
}
</code>
</div>
</div>
<!-- A2A Protocol -->
<div class="bg-[#0F0F1A] rounded-xl p-8 border border-cyan-500/20">
<div class="flex items-center gap-4 mb-6">
<div class="icon-container w-12 h-12 bg-cyan-500/20">
<svg class="w-6 h-6 text-cyan-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4"/>
</svg>
</div>
<div>
<h3 class="text-xl font-semibold">A2A Protocol</h3>
<p class="text-gray-500 text-sm">Agent-to-Agent Communication</p>
</div>
</div>
<p class="text-gray-400 mb-6">
Enable your AI agents to communicate with Pierre using Google's A2A protocol for seamless multi-agent workflows.
</p>
<div class="code-block rounded-lg p-4 text-sm overflow-x-auto">
<code class="text-gray-300">
<span class="text-cyan-400">GET</span> <span class="text-gray-500">/.well-known/agent.json</span><br>
<span class="text-cyan-400">POST</span> <span class="text-gray-500">/a2a/tasks</span><br>
<span class="text-cyan-400">WS</span> <span class="text-gray-500">/a2a/stream</span>
</code>
</div>
</div>
</div>
<div class="text-center mt-8">
<a href="https://github.com/Async-IO/pierre_mcp_server" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-2 px-6 py-3 rounded-lg border border-white/20 hover:bg-white/5 transition-colors font-medium">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"/>
</svg>
View on GitHub
</a>
</div>
</div>
</section>
<!-- Early Access Section -->
<section id="early-access" class="py-20 px-4">
<div class="max-w-3xl mx-auto text-center">
<div class="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-violet-600/20 border border-violet-500/30 text-violet-400 text-sm font-medium mb-6">
<span class="relative flex h-2 w-2">
<span class="pulse-ring absolute inline-flex h-full w-full rounded-full bg-violet-400 opacity-75"></span>
<span class="relative inline-flex rounded-full h-2 w-2 bg-violet-500"></span>
</span>
Coming Soon
</div>
<h2 class="text-3xl sm:text-4xl font-bold mb-4">Meet Your Coaching Team</h2>
<p class="text-gray-300 max-w-2xl mx-auto mb-8">
Pierre is launching soon with expert AI coaches ready to guide your training, nutrition, recovery, and mobility. Be the first to get access and help shape the future of AI fitness coaching.
</p>
<!-- Signup Form -->
<form id="early-access-form" class="flex flex-col sm:flex-row gap-3 max-w-md mx-auto mb-4">
<input
type="email"
name="email"
id="bd-email"
placeholder="you@example.com"
required
class="flex-1 px-4 py-3 rounded-lg bg-[#0F0F1A] border border-white/20 text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-violet-500 focus:border-transparent transition-all"
/>
<button
type="submit"
id="submit-btn"
class="gradient-pierre px-6 py-3 rounded-lg font-semibold hover:opacity-90 transition-opacity inline-flex items-center justify-center gap-2 whitespace-nowrap"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
</svg>
<span id="btn-text">Join Waitlist</span>
</button>
</form>
<p id="form-message" class="text-sm mb-2 h-6"></p>
<p class="text-gray-500 text-sm">No spam, ever. Unsubscribe anytime.</p>
<!-- Benefits -->
<div class="mt-12 grid sm:grid-cols-3 gap-6 text-left">
<div class="bg-[#1E1E2E] rounded-lg p-5 border border-white/5">
<div class="icon-container w-10 h-10 bg-emerald-500/20 mb-3">
<svg class="w-5 h-5 text-emerald-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
</div>
<h3 class="font-semibold mb-1">Early Access</h3>
<p class="text-gray-400 text-sm">Be among the first to try Pierre before public launch.</p>
</div>
<div class="bg-[#1E1E2E] rounded-lg p-5 border border-white/5">
<div class="icon-container w-10 h-10 bg-violet-600/20 mb-3">
<svg class="w-5 h-5 text-violet-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"/>
</svg>
</div>
<h3 class="font-semibold mb-1">Shape the Product</h3>
<p class="text-gray-400 text-sm">Your feedback will directly influence features and direction.</p>
</div>
<div class="bg-[#1E1E2E] rounded-lg p-5 border border-white/5">
<div class="icon-container w-10 h-10 bg-amber-500/20 mb-3">
<svg class="w-5 h-5 text-amber-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/>
</svg>
</div>
<h3 class="font-semibold mb-1">Exclusive Updates</h3>
<p class="text-gray-400 text-sm">Get development updates and behind-the-scenes insights.</p>
</div>
</div>
</div>
</section>
<!-- Footer (Simplified) -->
<footer class="py-12 px-4 border-t border-white/10">
<div class="max-w-7xl mx-auto">
<div class="flex flex-col md:flex-row items-center justify-between gap-6">
<div class="flex items-center gap-3">
<img src="/pierre-logo.svg" alt="Pierre" class="h-10 w-10">
<span class="text-xl font-semibold">Pierre</span>
</div>
<div class="flex items-center gap-6">
<a href="https://github.com/Async-IO/pierre_mcp_server" target="_blank" rel="noopener noreferrer" class="flex items-center gap-2 text-gray-400 hover:text-white transition-colors">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"/>
</svg>
<span>GitHub</span>
</a>
<a href="https://github.com/Async-IO/pierre_mcp_server/discussions" target="_blank" rel="noopener noreferrer" class="text-gray-400 hover:text-white transition-colors">
Discussions
</a>
</div>
<div class="text-gray-500 text-sm">
© 2025 Pierre Fitness Intelligence
</div>
</div>
</div>
</footer>
<!-- Scripts -->
<script is:inline>
// Mobile Menu Toggle
(function() {
const menuBtn = document.getElementById('mobile-menu-btn');
const mobileMenu = document.getElementById('mobile-menu');
const hamburgerIcon = document.getElementById('hamburger-icon');
const closeIcon = document.getElementById('close-icon');
if (menuBtn && mobileMenu) {
menuBtn.addEventListener('click', function() {
const isOpen = !mobileMenu.classList.contains('hidden');
mobileMenu.classList.toggle('hidden');
hamburgerIcon.classList.toggle('hidden');
closeIcon.classList.toggle('hidden');
menuBtn.setAttribute('aria-expanded', !isOpen);
});
// Close menu when clicking a link
mobileMenu.querySelectorAll('a').forEach(link => {
link.addEventListener('click', () => {
mobileMenu.classList.add('hidden');
hamburgerIcon.classList.remove('hidden');
closeIcon.classList.add('hidden');
menuBtn.setAttribute('aria-expanded', 'false');
});
});
}
})();
// Smooth scroll
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
});
// Early Access Form
(function() {
const form = document.getElementById('early-access-form');
const emailInput = document.getElementById('bd-email');
const submitBtn = document.getElementById('submit-btn');
const btnText = document.getElementById('btn-text');
const message = document.getElementById('form-message');
if (form) {
form.addEventListener('submit', async function(e) {
e.preventDefault();
const email = emailInput.value.trim();
if (!email) return;
submitBtn.disabled = true;
btnText.textContent = 'Joining...';
message.textContent = '';
message.className = 'text-sm mb-2 h-6';
try {
const formData = new FormData();
formData.append('email', email);
formData.append('embed', '1');
await fetch('https://buttondown.com/api/emails/embed-subscribe/pierrefitness', {
method: 'POST',
body: formData,
mode: 'no-cors'
});
message.textContent = '✓ You\'re on the list! Check your email to confirm.';
message.className = 'text-sm mb-2 h-6 text-emerald-400';
emailInput.value = '';
btnText.textContent = 'Joined!';
setTimeout(() => {
btnText.textContent = 'Join Waitlist';
submitBtn.disabled = false;
}, 3000);
} catch (error) {
message.textContent = 'Something went wrong. Please try again.';
message.className = 'text-sm mb-2 h-6 text-red-400';
btnText.textContent = 'Join Waitlist';
submitBtn.disabled = false;
}
});
}
})();
// Announcement Banner
(function() {
const BANNER_KEY = 'pierre_banner_dismissed';
const banner = document.getElementById('announcement-banner');
const nav = document.getElementById('main-nav');
const hero = document.getElementById('hero-section');
const dismissBtn = document.getElementById('banner-dismiss');
const styles = getComputedStyle(document.documentElement);
function getCssVar(name, fallback) {
const value = styles.getPropertyValue(name).trim();
return value || fallback;
}
function hideBanner() {
if (banner) banner.style.display = 'none';
if (nav) nav.style.top = '0';
if (hero) hero.style.paddingTop = getCssVar('--hero-padding-without-banner', '8rem');
localStorage.setItem(BANNER_KEY, 'true');
}
function showBanner() {
if (banner) banner.style.display = 'block';
if (nav) nav.style.top = getCssVar('--banner-height', '2.5rem');
if (hero) hero.style.paddingTop = getCssVar('--hero-padding-with-banner', '11rem');
}
if (localStorage.getItem(BANNER_KEY) === 'true') {
hideBanner();
} else {
showBanner();
}
if (dismissBtn) {
dismissBtn.addEventListener('click', hideBanner);
}
})();
// Stats animation on scroll
(function() {
const statsContainer = document.getElementById('stats-container');
if (!statsContainer) return;
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.querySelectorAll('.stat-glow').forEach((stat, index) => {
stat.style.animationDelay = `${index * 0.15}s`;
stat.classList.add('stat-animate');
});
observer.unobserve(entry.target);
}
});
}, { threshold: 0.3 });
observer.observe(statsContainer);
})();
// Example Report Modal
(function() {
const card = document.getElementById('example-report-card');
const modal = document.getElementById('report-modal');
const backdrop = document.getElementById('modal-backdrop');
const closeBtn = document.getElementById('close-modal');
const modalCta = document.getElementById('modal-cta');
let animationRan = false;
function openModal() {
modal.classList.remove('hidden');
document.body.style.overflow = 'hidden';
// Animate entrance
setTimeout(() => {
modal.querySelector('.modal-content').style.transform = 'scale(1)';
modal.querySelector('.modal-content').style.opacity = '1';
}, 10);
// Run animations only once
if (!animationRan) {
animationRan = true;
setTimeout(runAnimations, 300);
}
}
function closeModal() {
modal.classList.add('hidden');
document.body.style.overflow = '';
}
function runAnimations() {
// Animate counters
document.querySelectorAll('.counter').forEach(counter => {
const target = parseInt(counter.dataset.target);
const duration = 1500;
const step = target / (duration / 16);
let current = 0;
const updateCounter = () => {
current += step;
if (current < target) {
counter.textContent = Math.floor(current).toLocaleString();
requestAnimationFrame(updateCounter);
} else {
counter.textContent = target.toLocaleString();
}
};
updateCounter();
});
// Animate sport progress bars
document.querySelectorAll('.sport-bar').forEach((bar, index) => {
const percent = bar.dataset.percent;
const progress = bar.querySelector('.sport-progress');
setTimeout(() => {
progress.style.transition = 'width 1s ease-out';
progress.style.width = percent + '%';
}, index * 100);
});
// Animate year bars
document.querySelectorAll('.year-fill').forEach((fill, index) => {
const height = fill.dataset.height;
setTimeout(() => {
fill.style.transition = 'height 0.8s ease-out';
fill.style.height = height;
}, 800 + index * 150);
});
}
if (card) {
card.addEventListener('click', openModal);
}
if (closeBtn) {
closeBtn.addEventListener('click', closeModal);
}
if (backdrop) {
backdrop.addEventListener('click', closeModal);
}
if (modalCta) {
modalCta.addEventListener('click', closeModal);
}
// Close on Escape key
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && !modal.classList.contains('hidden')) {
closeModal();
}
});
})();
// Tools Modal (34 Fitness Insights)
(function() {
const toolsCard = document.getElementById('tools-stat-card');
const toolsModal = document.getElementById('tools-modal');
const toolsBackdrop = document.getElementById('tools-modal-backdrop');
const toolsCloseBtn = document.getElementById('close-tools-modal');
const toolsModalCta = document.getElementById('tools-modal-cta');
function openToolsModal() {
toolsModal.classList.remove('hidden');
document.body.style.overflow = 'hidden';
// Animate entrance
setTimeout(() => {
const content = toolsModal.querySelector('.tools-modal-content');
if (content) {
content.style.transform = 'scale(1)';
content.style.opacity = '1';
}
}, 10);
}
function closeToolsModal() {
toolsModal.classList.add('hidden');
document.body.style.overflow = '';
}
if (toolsCard) {
toolsCard.addEventListener('click', openToolsModal);
}
if (toolsCloseBtn) {
toolsCloseBtn.addEventListener('click', closeToolsModal);
}
if (toolsBackdrop) {
toolsBackdrop.addEventListener('click', closeToolsModal);
}
if (toolsModalCta) {
toolsModalCta.addEventListener('click', closeToolsModal);
}
// Close on Escape key
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && toolsModal && !toolsModal.classList.contains('hidden')) {
closeToolsModal();
}
});
})();
// Pillar Modals (Training, Nutrition, Recovery)
(function() {
// Helper function to create modal handlers
function setupPillarModal(cardId, modalId, backdropId, closeBtnId, ctaId) {
const card = document.getElementById(cardId);
const modal = document.getElementById(modalId);
const backdrop = document.getElementById(backdropId);
const closeBtn = document.getElementById(closeBtnId);
const cta = document.getElementById(ctaId);
if (!modal) return;
function openModal() {
modal.classList.remove('hidden');
document.body.style.overflow = 'hidden';
// Animate entrance
setTimeout(() => {
const content = modal.querySelector('.pillar-modal-content');
if (content) {
content.style.transform = 'scale(1)';
content.style.opacity = '1';
}
}, 10);
}
function closeModal() {
modal.classList.add('hidden');
document.body.style.overflow = '';
}
if (card) card.addEventListener('click', openModal);
if (closeBtn) closeBtn.addEventListener('click', closeModal);
if (backdrop) backdrop.addEventListener('click', closeModal);
if (cta) cta.addEventListener('click', closeModal);
// Close on Escape key
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && !modal.classList.contains('hidden')) {
closeModal();
}
});
}
// Setup each pillar modal
setupPillarModal('training-pillar-card', 'training-modal', 'training-modal-backdrop', 'close-training-modal', 'training-modal-cta');
setupPillarModal('nutrition-pillar-card', 'nutrition-modal', 'nutrition-modal-backdrop', 'close-nutrition-modal', 'nutrition-modal-cta');
setupPillarModal('recovery-pillar-card', 'recovery-modal', 'recovery-modal-backdrop', 'close-recovery-modal', 'recovery-modal-cta');
})();
// Tool Example Tooltip (shows what Pierre tells you)
(function() {
// Create tooltip element
const tooltip = document.createElement('div');
tooltip.id = 'tool-example-tooltip';
tooltip.className = 'fixed z-[110] max-w-sm bg-[#1a1a2e] border border-violet-500/30 rounded-xl shadow-2xl shadow-violet-500/20 p-4 hidden';
tooltip.innerHTML = `
<div class="flex items-start gap-3">
<div class="flex-shrink-0 w-8 h-8 rounded-lg gradient-pierre flex items-center justify-center">
<svg class="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"/>
</svg>
</div>
<div>
<div class="text-xs text-violet-400 font-medium mb-1">Pierre says:</div>
<div id="tooltip-text" class="text-sm text-gray-300 leading-relaxed"></div>
</div>
</div>
<div class="absolute -top-2 left-6 w-4 h-4 bg-[#1a1a2e] border-l border-t border-violet-500/30 transform rotate-45"></div>
`;
document.body.appendChild(tooltip);
const tooltipText = document.getElementById('tooltip-text');
let activeCard = null;
// Close tooltip when clicking outside
document.addEventListener('click', (e) => {
if (!tooltip.contains(e.target) && !e.target.closest('.tool-card')) {
tooltip.classList.add('hidden');
if (activeCard) {
activeCard.classList.remove('ring-2', 'ring-violet-500/50');
activeCard = null;
}
}
});
// Handle tool card clicks
document.querySelectorAll('.tool-card').forEach(card => {
card.addEventListener('click', (e) => {
e.stopPropagation();
const example = card.dataset.example;
if (!example) return;
// Remove highlight from previous card
if (activeCard && activeCard !== card) {
activeCard.classList.remove('ring-2', 'ring-violet-500/50');
}
// Toggle tooltip for same card
if (activeCard === card && !tooltip.classList.contains('hidden')) {
tooltip.classList.add('hidden');
card.classList.remove('ring-2', 'ring-violet-500/50');
activeCard = null;
return;
}
// Show tooltip
tooltipText.textContent = example;
activeCard = card;
card.classList.add('ring-2', 'ring-violet-500/50');
// Position tooltip below the card (fixed positioning uses viewport coords)
const rect = card.getBoundingClientRect();
tooltip.classList.remove('hidden');
// Get tooltip dimensions
const tooltipRect = tooltip.getBoundingClientRect();
// Calculate position - try below first, then above if no room
let top = rect.bottom + 8;
let left = rect.left;
// If tooltip would go below viewport, position above the card
if (top + tooltipRect.height > window.innerHeight - 20) {
top = rect.top - tooltipRect.height - 8;
}
// Keep tooltip within horizontal viewport bounds
if (left + tooltipRect.width > window.innerWidth - 20) {
left = window.innerWidth - tooltipRect.width - 20;
}
if (left < 20) left = 20;
tooltip.style.top = top + 'px';
tooltip.style.left = left + 'px';
});
});
// Close on Escape
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
tooltip.classList.add('hidden');
if (activeCard) {
activeCard.classList.remove('ring-2', 'ring-violet-500/50');
activeCard = null;
}
}
});
})();
</script>
</body>
</html>