Coach — Hero Landing
An energetic dark hero section for a personal fitness coach, built with a bold uppercase headline, an action-photo panel and a glowing electric-lime call to action. Animated counters tally clients coached, years of experience and average success rate, while a horizontal program strip lets visitors flip between strength, hiit and mobility tracks. Scroll reveals, magnetic buttons and a lightweight toast make the whole page feel alive without any framework.
MCP
Code
:root {
--bg: #0f1115;
--surface: #171a21;
--surface-2: #1f232c;
--lime: #c2f542;
--lime-d: #a3d62f;
--orange: #ff6b35;
--ink: #f2f4f0;
--muted: #9aa0a6;
--line: rgba(255, 255, 255, 0.1);
--line-2: rgba(255, 255, 255, 0.18);
--white: #fff;
--r-sm: 8px;
--r-md: 14px;
--r-lg: 20px;
}
* {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
font-family: "Inter", system-ui, -apple-system, sans-serif;
background: var(--bg);
color: var(--ink);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow-x: hidden;
background-image:
radial-gradient(60% 50% at 80% -5%, rgba(194, 245, 66, 0.12), transparent 60%),
radial-gradient(50% 40% at -5% 20%, rgba(255, 107, 53, 0.1), transparent 60%);
background-repeat: no-repeat;
}
:focus-visible {
outline: 3px solid var(--lime);
outline-offset: 3px;
border-radius: var(--r-sm);
}
/* ---------- Topbar ---------- */
.topbar {
display: flex;
align-items: center;
gap: 24px;
max-width: 1160px;
margin: 0 auto;
padding: 22px 32px;
}
.brand {
display: flex;
align-items: center;
gap: 12px;
text-decoration: none;
color: var(--ink);
margin-right: auto;
}
.brand-mark {
display: grid;
place-items: center;
width: 38px;
height: 38px;
border-radius: var(--r-sm);
background: var(--lime);
color: #10130a;
font-weight: 800;
letter-spacing: 0.5px;
box-shadow: 0 0 22px rgba(194, 245, 66, 0.45);
}
.brand-name {
font-weight: 800;
letter-spacing: 0.5px;
text-transform: uppercase;
font-size: 15px;
}
.brand-name span {
color: var(--lime);
}
.nav {
display: flex;
gap: 26px;
}
.nav a {
color: var(--muted);
text-decoration: none;
font-weight: 500;
font-size: 14px;
transition: color 0.2s ease;
}
.nav a:hover {
color: var(--ink);
}
/* ---------- Buttons ---------- */
.btn {
font-family: inherit;
font-weight: 700;
font-size: 15px;
border: 0;
cursor: pointer;
border-radius: var(--r-md);
padding: 14px 22px;
display: inline-flex;
align-items: center;
gap: 10px;
transition: transform 0.18s ease, box-shadow 0.25s ease,
background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.btn-lime {
background: var(--lime);
color: #10130a;
box-shadow: 0 0 0 rgba(194, 245, 66, 0);
}
.btn-lime:hover {
background: var(--lime-d);
box-shadow: 0 12px 34px rgba(194, 245, 66, 0.4),
0 0 22px rgba(194, 245, 66, 0.35);
}
.btn-lime:active {
transform: translateY(1px) scale(0.99);
}
.btn-outline {
background: transparent;
color: var(--ink);
border: 1px solid var(--line-2);
}
.btn-outline:hover {
border-color: var(--lime);
color: var(--lime);
}
.btn-ghost {
background: var(--surface);
color: var(--ink);
border: 1px solid var(--line);
padding: 10px 18px;
font-size: 14px;
}
.btn-ghost:hover {
border-color: var(--line-2);
transform: translateY(-1px);
}
.btn-arrow {
transition: transform 0.2s ease;
}
.btn-lime:hover .btn-arrow {
transform: translateX(4px);
}
.play {
font-size: 11px;
color: var(--lime);
}
/* ---------- Hero ---------- */
.hero {
max-width: 1160px;
margin: 30px auto 0;
padding: 24px 32px 70px;
display: grid;
grid-template-columns: 1.05fr 0.95fr;
gap: 56px;
align-items: center;
}
.eyebrow {
display: inline-flex;
align-items: center;
gap: 10px;
text-transform: uppercase;
letter-spacing: 2px;
font-size: 12px;
font-weight: 700;
color: var(--lime);
margin: 0 0 22px;
}
.pulse {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--lime);
box-shadow: 0 0 0 0 rgba(194, 245, 66, 0.6);
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 rgba(194, 245, 66, 0.55);
}
70% {
box-shadow: 0 0 0 12px rgba(194, 245, 66, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(194, 245, 66, 0);
}
}
.headline {
font-size: clamp(40px, 6vw, 72px);
line-height: 0.98;
font-weight: 800;
letter-spacing: -1.5px;
text-transform: uppercase;
margin: 0 0 22px;
}
.headline-accent {
color: var(--lime);
text-shadow: 0 0 34px rgba(194, 245, 66, 0.35);
}
.lede {
color: var(--muted);
font-size: 17px;
max-width: 46ch;
margin: 0 0 30px;
}
.cta-row {
display: flex;
gap: 14px;
flex-wrap: wrap;
margin-bottom: 30px;
}
.trust {
list-style: none;
display: flex;
flex-wrap: wrap;
gap: 10px 22px;
padding: 0;
margin: 0;
}
.trust li {
color: var(--muted);
font-size: 13.5px;
font-weight: 500;
display: flex;
align-items: center;
gap: 8px;
}
.trust li::before {
content: "";
width: 16px;
height: 16px;
border-radius: 50%;
background: radial-gradient(circle at 30% 30%, var(--lime), var(--lime-d));
flex: none;
}
/* ---------- Hero media ---------- */
.hero-media {
position: relative;
transform-style: preserve-3d;
transition: transform 0.15s ease-out;
}
.photo {
position: relative;
height: 460px;
border-radius: var(--r-lg);
overflow: hidden;
border: 1px solid var(--line);
background:
linear-gradient(180deg, rgba(15, 17, 21, 0.05), rgba(15, 17, 21, 0.7)),
url("https://images.unsplash.com/photo-1534438327276-14e5300c3a48?q=80&w=1200&auto=format&fit=crop")
center / cover no-repeat,
linear-gradient(150deg, var(--orange), var(--lime));
box-shadow: 0 40px 80px rgba(0, 0, 0, 0.5);
}
.photo-shine {
position: absolute;
inset: 0;
background: linear-gradient(
120deg,
transparent 30%,
rgba(255, 255, 255, 0.14) 48%,
transparent 62%
);
transform: translateX(-120%);
animation: shine 5.5s ease-in-out infinite;
}
@keyframes shine {
0%,
60% {
transform: translateX(-120%);
}
85%,
100% {
transform: translateX(120%);
}
}
.badge-float {
position: absolute;
top: 22px;
left: -18px;
background: var(--surface-2);
border: 1px solid var(--line-2);
border-radius: var(--r-md);
padding: 12px 16px;
display: flex;
flex-direction: column;
transform: translateZ(50px);
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
}
.badge-big {
font-weight: 800;
font-size: 22px;
display: flex;
align-items: center;
gap: 4px;
}
.badge-star {
color: var(--lime);
font-size: 16px;
}
.badge-sub {
color: var(--muted);
font-size: 12px;
font-weight: 500;
}
.intake-pill {
position: absolute;
bottom: 20px;
right: -14px;
background: var(--surface);
border: 1px solid var(--line-2);
border-radius: 999px;
padding: 10px 16px;
font-size: 13px;
color: var(--muted);
display: flex;
align-items: center;
gap: 9px;
transform: translateZ(60px);
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
}
.intake-pill strong {
color: var(--orange);
}
.intake-pill .dot {
width: 9px;
height: 9px;
border-radius: 50%;
background: var(--orange);
box-shadow: 0 0 10px var(--orange);
animation: blink 1.6s infinite;
}
@keyframes blink {
50% {
opacity: 0.35;
}
}
/* ---------- Stats ---------- */
.stats {
max-width: 1160px;
margin: 0 auto;
padding: 34px 32px;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 18px;
border-top: 1px solid var(--line);
border-bottom: 1px solid var(--line);
}
.stat {
background: var(--surface);
border: 1px solid var(--line);
border-radius: var(--r-md);
padding: 24px 22px;
transition: transform 0.2s ease, border-color 0.2s ease;
}
.stat:hover {
transform: translateY(-4px);
border-color: var(--line-2);
}
.stat-num {
display: block;
font-size: clamp(30px, 4vw, 44px);
font-weight: 800;
letter-spacing: -1px;
color: var(--lime);
line-height: 1;
}
.stat-label {
display: block;
margin-top: 8px;
color: var(--muted);
font-size: 13.5px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.5px;
}
/* ---------- Programs ---------- */
.programs {
max-width: 1160px;
margin: 0 auto;
padding: 56px 32px 80px;
}
.programs-head {
margin-bottom: 26px;
}
.section-title {
font-size: clamp(26px, 4vw, 38px);
font-weight: 800;
text-transform: uppercase;
letter-spacing: -0.5px;
margin: 0 0 8px;
}
.section-sub {
color: var(--muted);
margin: 0;
font-size: 15.5px;
}
.program-strip {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
}
.program {
font-family: inherit;
text-align: left;
cursor: pointer;
background: var(--surface);
border: 1px solid var(--line);
border-radius: var(--r-md);
padding: 22px 20px;
color: var(--ink);
display: flex;
flex-direction: column;
gap: 8px;
position: relative;
overflow: hidden;
transition: transform 0.2s ease, border-color 0.2s ease,
background 0.2s ease;
}
.program::before {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(160deg, rgba(194, 245, 66, 0.14), transparent 55%);
opacity: 0;
transition: opacity 0.25s ease;
}
.program:hover {
transform: translateY(-4px);
border-color: var(--line-2);
}
.program.is-active {
border-color: var(--lime);
background: var(--surface-2);
box-shadow: 0 0 0 1px var(--lime), 0 16px 40px rgba(194, 245, 66, 0.14);
}
.program.is-active::before {
opacity: 1;
}
.program-tag {
font-size: 12px;
font-weight: 700;
color: var(--muted);
letter-spacing: 1px;
}
.program.is-active .program-tag {
color: var(--lime);
}
.program-name {
font-size: 19px;
font-weight: 800;
text-transform: uppercase;
letter-spacing: -0.3px;
position: relative;
}
.program-meta {
font-size: 13px;
color: var(--muted);
position: relative;
}
/* ---------- Reveal ---------- */
.reveal {
opacity: 0;
transform: translateY(24px);
transition: opacity 0.6s ease, transform 0.6s ease;
}
.reveal.in {
opacity: 1;
transform: none;
}
/* ---------- Toast ---------- */
.toast {
position: fixed;
left: 50%;
bottom: 28px;
transform: translate(-50%, 140%);
background: var(--lime);
color: #10130a;
font-weight: 700;
padding: 13px 22px;
border-radius: 999px;
box-shadow: 0 16px 40px rgba(0, 0, 0, 0.4),
0 0 24px rgba(194, 245, 66, 0.4);
transition: transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1);
z-index: 60;
max-width: 90vw;
}
.toast.show {
transform: translate(-50%, 0);
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation: none !important;
transition: none !important;
}
.reveal {
opacity: 1;
transform: none;
}
}
/* ---------- Responsive ---------- */
@media (max-width: 900px) {
.hero {
grid-template-columns: 1fr;
gap: 40px;
}
.stats {
grid-template-columns: repeat(2, 1fr);
}
.program-strip {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 520px) {
.topbar {
padding: 16px 18px;
gap: 14px;
}
.nav {
display: none;
}
.hero {
padding: 12px 18px 50px;
}
.headline {
letter-spacing: -0.5px;
}
.cta-row {
flex-direction: column;
align-items: stretch;
}
.cta-row .btn {
justify-content: center;
}
.photo {
height: 340px;
}
.badge-float {
left: 10px;
}
.intake-pill {
right: 10px;
}
.stats {
grid-template-columns: 1fr;
padding: 24px 18px;
}
.program-strip {
grid-template-columns: 1fr;
}
.programs {
padding: 40px 18px 60px;
}
}(function () {
"use strict";
/* ---------- Toast helper ---------- */
var toastEl = document.getElementById("toast");
var toastTimer;
function toast(msg) {
if (!toastEl) return;
toastEl.textContent = msg;
toastEl.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("show");
}, 2600);
}
/* ---------- Reveal on scroll + animated counters ---------- */
var reduceMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)"
).matches;
function animateCount(el) {
var target = parseFloat(el.getAttribute("data-count")) || 0;
var suffix = el.getAttribute("data-suffix") || "";
if (reduceMotion) {
el.textContent = formatNum(target) + suffix;
return;
}
var start = performance.now();
var dur = 1400;
function tick(now) {
var p = Math.min((now - start) / dur, 1);
var eased = 1 - Math.pow(1 - p, 3); // easeOutCubic
el.textContent = formatNum(Math.round(target * eased)) + suffix;
if (p < 1) requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
}
function formatNum(n) {
return n.toLocaleString("en-US");
}
if ("IntersectionObserver" in window) {
var io = new IntersectionObserver(
function (entries) {
entries.forEach(function (entry) {
if (!entry.isIntersecting) return;
entry.target.classList.add("in");
var num = entry.target.querySelector("[data-count]");
if (num && !num.dataset.done) {
num.dataset.done = "1";
animateCount(num);
}
io.unobserve(entry.target);
});
},
{ threshold: 0.25 }
);
document.querySelectorAll(".reveal").forEach(function (el) {
io.observe(el);
});
} else {
document.querySelectorAll(".reveal").forEach(function (el) {
el.classList.add("in");
});
document.querySelectorAll("[data-count]").forEach(animateCount);
}
/* ---------- Parallax tilt on hero photo ---------- */
var tilt = document.querySelector("[data-tilt]");
if (tilt && !reduceMotion && window.matchMedia("(pointer:fine)").matches) {
tilt.addEventListener("mousemove", function (e) {
var r = tilt.getBoundingClientRect();
var px = (e.clientX - r.left) / r.width - 0.5;
var py = (e.clientY - r.top) / r.height - 0.5;
tilt.style.transform =
"perspective(900px) rotateY(" +
px * 8 +
"deg) rotateX(" +
-py * 8 +
"deg)";
});
tilt.addEventListener("mouseleave", function () {
tilt.style.transform = "";
});
}
/* ---------- Magnetic CTA ---------- */
var mag = document.querySelector(".magnetic");
if (mag && !reduceMotion && window.matchMedia("(pointer:fine)").matches) {
mag.addEventListener("mousemove", function (e) {
var r = mag.getBoundingClientRect();
var x = e.clientX - r.left - r.width / 2;
var y = e.clientY - r.top - r.height / 2;
mag.style.transform =
"translate(" + x * 0.18 + "px," + y * 0.22 + "px)";
});
mag.addEventListener("mouseleave", function () {
mag.style.transform = "";
});
}
/* ---------- Program strip toggle ---------- */
var programs = Array.prototype.slice.call(
document.querySelectorAll(".program")
);
var eyebrowText = document.querySelector("[data-eyebrow]");
var taglineText = document.querySelector("[data-tagline]");
function selectProgram(btn) {
programs.forEach(function (p) {
var active = p === btn;
p.classList.toggle("is-active", active);
p.setAttribute("aria-selected", active ? "true" : "false");
});
var eb = btn.getAttribute("data-eyebrow-text");
var tg = btn.getAttribute("data-tagline-text");
if (eyebrowText && eb) eyebrowText.textContent = eb;
if (taglineText && tg) taglineText.textContent = tg;
var name = btn.querySelector(".program-name");
toast("Track selected — " + (name ? name.textContent : "program"));
}
programs.forEach(function (btn, i) {
btn.addEventListener("click", function () {
selectProgram(btn);
});
// Arrow-key roving for the tablist
btn.addEventListener("keydown", function (e) {
var next = null;
if (e.key === "ArrowRight" || e.key === "ArrowDown") {
next = programs[(i + 1) % programs.length];
} else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
next = programs[(i - 1 + programs.length) % programs.length];
}
if (next) {
e.preventDefault();
next.focus();
selectProgram(next);
}
});
});
/* ---------- CTA actions ---------- */
var messages = {
hero: "Transformation booked — check your inbox for the intake form.",
nav: "Your discovery call is on hold. We'll confirm within 24h.",
watch: "Loading the method breakdown…",
};
document.querySelectorAll("[data-cta]").forEach(function (el) {
el.addEventListener("click", function () {
var key = el.getAttribute("data-cta");
toast(messages[key] || "Thanks — talk soon!");
});
});
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Mara Voss — Performance Coach</title>
<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;800&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<header class="topbar">
<a class="brand" href="#" aria-label="Mara Voss home">
<span class="brand-mark" aria-hidden="true">MV</span>
<span class="brand-name">Mara<span>Voss</span></span>
</a>
<nav class="nav" aria-label="Primary">
<a href="#programs">Programs</a>
<a href="#stats">Results</a>
<a href="#coach">Method</a>
</nav>
<button class="btn btn-ghost nav-cta" type="button" data-cta="nav">
Book a call
</button>
</header>
<main>
<section class="hero" id="top">
<div class="hero-copy reveal">
<p class="eyebrow" id="hero-eyebrow">
<span class="pulse" aria-hidden="true"></span>
<span data-eyebrow>Elite strength coaching</span>
</p>
<h1 class="headline">
Build the body<br />
you've been<br />
<span class="headline-accent">putting off.</span>
</h1>
<p class="lede" data-tagline>
Data-driven 1:1 coaching that fits your life — not the other way
around. No fads, no guilt. Just relentless, measurable progress.
</p>
<div class="cta-row">
<button class="btn btn-lime magnetic" type="button" data-cta="hero">
Start your transformation
<span class="btn-arrow" aria-hidden="true">→</span>
</button>
<button class="btn btn-outline" type="button" data-cta="watch">
<span class="play" aria-hidden="true">▶</span>
Watch the method
</button>
</div>
<ul class="trust" aria-label="What is included">
<li>Custom weekly plan</li>
<li>Form check reviews</li>
<li>Nutrition guardrails</li>
</ul>
</div>
<div class="hero-media reveal" data-tilt>
<div class="photo" role="img" aria-label="Coach Mara Voss mid-training session">
<div class="photo-shine" aria-hidden="true"></div>
</div>
<div class="badge-float">
<span class="badge-big">4.9<span class="badge-star">★</span></span>
<span class="badge-sub">312 verified reviews</span>
</div>
<div class="intake-pill">
<span class="dot" aria-hidden="true"></span>
Next intake — <strong>3 spots left</strong>
</div>
</div>
</section>
<section class="stats" id="stats" aria-label="Coaching results">
<div class="stat reveal">
<span class="stat-num" data-count="1240" data-suffix="+">0</span>
<span class="stat-label">Clients coached</span>
</div>
<div class="stat reveal">
<span class="stat-num" data-count="11" data-suffix="">0</span>
<span class="stat-label">Years in the game</span>
</div>
<div class="stat reveal">
<span class="stat-num" data-count="94" data-suffix="%">0</span>
<span class="stat-label">Hit their goal</span>
</div>
<div class="stat reveal">
<span class="stat-num" data-count="18" data-suffix="k">0</span>
<span class="stat-label">Sessions logged</span>
</div>
</section>
<section class="programs" id="programs" aria-label="Training programs">
<div class="programs-head reveal">
<h2 class="section-title">Pick your track</h2>
<p class="section-sub">
Every program is a starting point — I tune it to you within week one.
</p>
</div>
<div class="program-strip" role="tablist" aria-label="Program tracks">
<button
class="program is-active"
role="tab"
aria-selected="true"
type="button"
data-eyebrow-text="Elite strength coaching"
data-tagline-text="Data-driven 1:1 coaching that fits your life — not the other way around. No fads, no guilt. Just relentless, measurable progress."
>
<span class="program-tag">01</span>
<span class="program-name">Raw Strength</span>
<span class="program-meta">12 weeks · 4 days / wk</span>
</button>
<button
class="program"
role="tab"
aria-selected="false"
type="button"
data-eyebrow-text="High-intensity conditioning"
data-tagline-text="Short, brutal, effective. HIIT blocks engineered to torch fat and spike your engine in 35 minutes flat — anywhere, minimal kit."
>
<span class="program-tag">02</span>
<span class="program-name">Engine HIIT</span>
<span class="program-meta">8 weeks · 5 days / wk</span>
</button>
<button
class="program"
role="tab"
aria-selected="false"
type="button"
data-eyebrow-text="Mobility & longevity"
data-tagline-text="Move pain-free for the next 40 years. A joint-first program that rebuilds mobility, control and resilience without wrecking your knees."
>
<span class="program-tag">03</span>
<span class="program-name">Bulletproof</span>
<span class="program-meta">10 weeks · 3 days / wk</span>
</button>
<button
class="program"
role="tab"
aria-selected="false"
type="button"
data-eyebrow-text="Physique transformation"
data-tagline-text="Recomp done right. A calculated cut-and-build cycle with weekly check-ins so the mirror and the scale finally agree with each other."
>
<span class="program-tag">04</span>
<span class="program-name">Recomp Pro</span>
<span class="program-meta">16 weeks · 4 days / wk</span>
</button>
</div>
</section>
</main>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>A high-impact hero landing for a fictional performance coach, Mara Voss. The layout splits into a copy column with an uppercase display headline, a supporting sub-line and dual CTAs, plus an action-photo panel that tilts subtly toward the pointer. A floating badge and a live “next intake” pill keep the offer feeling urgent and human.
Below the fold sits a stat band whose numbers count up when they scroll into view — clients coached, years in the game and average client success rate — followed by a program strip. Each program chip is a real toggle: activating one swaps the headline eyebrow, updates the featured tagline and glows lime to show it is selected, all announced politely for screen readers.
Interactions are pure vanilla JS: an IntersectionObserver drives the reveal-on-scroll and counter animations, a pointer-move handler powers the parallax photo tilt, the CTA fires a toast confirming the transformation booking, and every control is keyboard reachable with a visible focus ring.