Full Source Code
HTML + CSS + JavaScript. The most technically advanced free project on Coodeverse. Animated SVG circular progress bars using stroke-dashoffset, IntersectionObserver scroll-triggered animation, CSS custom properties for instant retheming, Bebas Neue display typography, dark radial gradient hero, and fully responsive layout. Study the JS tab carefully — IntersectionObserver and SVG animation are essential skills for mid-to-senior frontend roles.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>PEAK • Your Ultimate Fitness App</title>
<link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Inter:wght@400;600;700;900&display=swap" rel="stylesheet">
<style>
:root {
--bg: #0d0d0d;
--text: #ffffff;
--accent: #ff2a6d;
--green: #00ff9d;
--purple: #9d4edd;
--card: #1a1a1a;
}
* { margin:0; padding:0; box-sizing:border-box; }
body { font-family: 'Inter', sans-serif; background: var(--bg); color: var(--text); overflow-x: hidden; }
.hero {
height: 100vh; display: flex; align-items: center; justify-content: space-between;
padding: 0 8%; background: radial-gradient(circle at 20% 80%, #1a0d33 0%, var(--bg) 70%);
position: relative; overflow: hidden;
}
.hero-content { max-width: 600px; z-index: 10; }
h1 {
font-family: 'Bebas Neue', sans-serif; font-size: 8.5rem; line-height: 0.9; letter-spacing: -4px;
background: linear-gradient(90deg, #fff, var(--accent));
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
.tagline { font-size: 1.8rem; margin: 1.5rem 0 2.5rem; opacity: 0.9; }
.btn {
padding: 20px 50px; background: var(--accent); color: #000; border: none; border-radius: 50px;
font-size: 1.4rem; font-weight: 900; cursor: pointer;
box-shadow: 0 20px 50px rgba(255,42,109,0.4); transition: all 0.4s;
}
.btn:hover { transform: translateY(-10px); box-shadow: 0 30px 80px rgba(255,42,109,0.6); }
.stats {
position: absolute; right: 8%; top: 50%; transform: translateY(-50%);
display: flex; flex-direction: column; gap: 3rem;
}
.circle { width: 220px; height: 220px; position: relative; }
svg { transform: rotate(-90deg); width: 100%; height: 100%; }
.circle-bg { fill: none; stroke: rgba(255,255,255,0.1); stroke-width: 18; }
.circle-fg {
fill: none; stroke-width: 18; stroke-linecap: round;
stroke-dasharray: 628; stroke-dashoffset: 628; transition: stroke-dashoffset 2.2s ease;
}
.circle-fg.animate { stroke-dashoffset: var(--offset); }
.circle-1 .circle-fg { stroke: var(--accent); }
.circle-2 .circle-fg { stroke: var(--green); }
.circle-3 .circle-fg { stroke: var(--purple); }
.circle-value {
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
text-align: center; font-family: 'Bebas Neue';
}
.value { font-size: 3.5rem; font-weight: 400; line-height: 1; }
.label { font-size: 1.1rem; opacity: 0.8; margin-top: 0.5rem; letter-spacing: 2px; }
.features {
padding: 150px 8%; background: var(--card);
display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 4rem; text-align: center;
}
.feature h3 {
font-size: 2rem; margin: 1.5rem 0 1rem;
background: linear-gradient(90deg, var(--accent), var(--green));
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
.cta {
padding: 150px 8%; text-align: center;
background: linear-gradient(135deg, #1a0d33, var(--bg));
}
.cta h2 { font-family: 'Bebas Neue'; font-size: 6rem; margin-bottom: 2rem; }
@media (max-width: 1024px) {
.hero { flex-direction: column; text-align: center; padding: 10% 5%; height: auto; min-height: 100vh; }
h1 { font-size: 6.5rem; }
.stats { position: static; transform: none; margin-top: 4rem; flex-direction: row; justify-content: center; }
.circle { width: 180px; height: 180px; }
}
@media (max-width: 768px) {
h1 { font-size: 5rem; }
.tagline { font-size: 1.4rem; }
.stats { flex-wrap: wrap; gap: 2rem; }
.circle { width: 150px; height: 150px; }
.value { font-size: 2.8rem; }
}
</style>
</head>
<body>
<section class="hero">
<div class="hero-content">
<h1>GET<br>PEAK<br>PERFORMANCE</h1>
<p class="tagline">Train smarter. Track everything. Become unstoppable.</p>
<button class="btn">Download Free</button>
</div>
<div class="stats">
<div class="circle circle-1">
<svg viewBox="0 0 220 220">
<circle class="circle-bg" cx="110" cy="110" r="100"/>
<circle class="circle-fg" cx="110" cy="110" r="100" data-percent="87"/>
</svg>
<div class="circle-value">
<div class="value">87<span style="font-size:1.8rem;">%</span></div>
<div class="label">WORKOUTS</div>
</div>
</div>
<div class="circle circle-2">
<svg viewBox="0 0 220 220">
<circle class="circle-bg" cx="110" cy="110" r="100"/>
<circle class="circle-fg" cx="110" cy="110" r="100" data-percent="94"/>
</svg>
<div class="circle-value">
<div class="value">94<span style="font-size:1.8rem;">k</span></div>
<div class="label">CALORIES</div>
</div>
</div>
<div class="circle circle-3">
<svg viewBox="0 0 220 220">
<circle class="circle-bg" cx="110" cy="110" r="100"/>
<circle class="circle-fg" cx="110" cy="110" r="100" data-percent="42"/>
</svg>
<div class="circle-value">
<div class="value">42</div>
<div class="label">DAY STREAK</div>
</div>
</div>
</div>
</section>
<section class="features">
<div class="feature">
<h3>AI Workouts</h3>
<p>Personalized plans that adapt to your progress, schedule, and goals.</p>
</div>
<div class="feature">
<h3>Real-Time Tracking</h3>
<p>Apple Watch, Garmin, Whoop — everything syncs instantly.</p>
</div>
<div class="feature">
<h3>Community Challenges</h3>
<p>Compete with friends, earn badges, stay motivated.</p>
</div>
</section>
<section class="cta">
<h2>JOIN 2M+ ATHLETES</h2>
<button class="btn">Start Your Journey</button>
</section>
<script>
// Animate circles on page load
window.addEventListener('load', () => {
document.querySelectorAll('.circle-fg').forEach(circle => {
const percent = circle.dataset.percent;
const offset = 628 - (628 * percent / 100);
setTimeout(() => {
circle.style.setProperty('--offset', offset);
circle.classList.add('animate');
}, 600);
});
});
// Re-animate when hero scrolls into view
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.querySelectorAll('.circle-fg').forEach(circle => {
const percent = circle.dataset.percent || 80;
const offset = 628 - (628 * percent / 100);
circle.style.setProperty('--offset', offset);
circle.classList.add('animate');
});
}
});
}, { threshold: 0.7 });
observer.observe(document.querySelector('.hero'));
</script>
</body>
</html>