Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 20 additions & 13 deletions vite-project/src/components/layout/Landing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
<div className="inline-flex items-center space-x-2 bg-white rounded-full px-4 py-1.5 shadow-sm border border-emerald-100 mb-6">
<span className="flex h-2 w-2 rounded-full bg-emerald-500"></span>
<span className="text-sm font-semibold text-emerald-800 tracking-wide uppercase">
Free forever for the basics
Made for runners by a runner
</span>
</div>
<h1 className="text-4xl lg:text-6xl font-extrabold text-slate-900 tracking-tight leading-[1.1] mb-6">
Expand All @@ -100,7 +100,7 @@
icon={ArrowRight}
onClick={() => navigate("/calculator")}
>
Get Started Free
Get Started
</Button>
<Button variant="secondary" size="lg" onClick={scrollToFeatures}>
See How It Works
Expand All @@ -121,29 +121,36 @@

{/* Visual / Dashboard Mockup */}
<div className="relative mx-auto w-full max-w-lg lg:max-w-none">
<div className="relative rounded-2xl bg-white shadow-2xl border border-slate-200 overflow-hidden">
<div
className="relative rounded-2xl bg-white shadow-2xl border border-slate-200 overflow-hidden cursor-pointer hover:shadow-emerald-200 hover:border-emerald-300 transition-all duration-200 group"
onClick={() => navigate("/race")}

Check warning on line 126 in vite-project/src/components/layout/Landing.tsx

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

vite-project/src/components/layout/Landing.tsx#L126

Returning a void expression from an arrow function shorthand is forbidden. Please add braces to the arrow function.
onKeyDown={(e) => (e.key === "Enter" || e.key === " ") && navigate("/race")}

Check warning on line 127 in vite-project/src/components/layout/Landing.tsx

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

vite-project/src/components/layout/Landing.tsx#L127

Returning a void expression from an arrow function shorthand is forbidden. Please add braces to the arrow function.
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onKeyDown triggers navigation on Space but doesn’t call preventDefault(), so Space can also scroll the page while the element is focused. Also, Space activation is expected for role="button" rather than role="link" (links generally activate on Enter). Align the role/keyboard interaction and prevent the default Space behavior when handling it.

Suggested change
onKeyDown={(e) => (e.key === "Enter" || e.key === " ") && navigate("/race")}
onKeyDown={(e) => e.key === "Enter" && navigate("/race")}

Copilot uses AI. Check for mistakes.
role="link"
Comment on lines +124 to +128
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This clickable card is implemented as a

with role="link" and custom keyboard handling. For better accessibility/semantics (and to get correct keyboard behavior + SEO for free), consider using a real <Link to="/race"> (or an <a href>), rather than a generic div with ARIA role.

Copilot uses AI. Check for mistakes.
tabIndex={0}
aria-label="Browse race courses"
>
<div className="bg-slate-50 px-4 py-3 border-b border-slate-200 flex items-center space-x-2">
<div className="w-3 h-3 rounded-full bg-red-400"></div>
<div className="w-3 h-3 rounded-full bg-yellow-400"></div>
<div className="w-3 h-3 rounded-full bg-green-400"></div>
<div className="ml-4 text-xs text-slate-400 font-mono">
trainpace.com/dashboard
<div className="ml-4 text-xs text-slate-400 font-mono group-hover:text-emerald-600 transition-colors">
trainpace.com/race
</div>
</div>
<div className="p-6 grid gap-6">
{/* Mock UI Elements */}
{/* Mock UI Elements - Race page preview */}
<div className="flex items-center justify-between border-b border-slate-100 pb-4">
<div>
<div className="text-sm text-slate-500 font-medium uppercase">
Next Long Run
Race Courses
</div>
<div className="text-2xl font-bold text-slate-900">
18 Miles{" "}
<span className="text-emerald-600">@ 8:45/mi</span>
Boston Marathon{" "}
<span className="text-orange-500">Rolling Hills</span>
</div>
</div>
<div className="h-10 w-10 bg-emerald-100 rounded-full flex items-center justify-center text-emerald-600">
<Activity size={20} />
<Map size={20} />
</div>
</div>

Expand Down Expand Up @@ -261,8 +268,8 @@
solution: "Personalized gel timing and carb calculations.",
},
{
problem: "Coaches are expensive ($150+/mo).",
solution: "TrainPace is 100% free, forever.",
problem: "I want to know what pace I should be going per km.",
solution: "Get your exact per-km pace zones from any recent race time.",
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy consistency: this problem statement uses “per km” while the solution right below uses “per-km”. Consider standardizing the phrasing (either both “per km” or both “per-km”) to avoid inconsistent UI copy.

Suggested change
solution: "Get your exact per-km pace zones from any recent race time.",
solution: "Get your exact per km pace zones from any recent race time.",

Copilot uses AI. Check for mistakes.
},
];

Expand Down Expand Up @@ -814,7 +821,7 @@
className="bg-white text-emerald-700 font-bold py-4 px-8 rounded-full hover:bg-emerald-50 transition shadow-xl"
onClick={() => navigate("/calculator")}
>
Get Started Free
Get Started
</button>
<button
className="bg-emerald-700 text-white font-semibold py-4 px-8 rounded-full hover:bg-emerald-800 transition border border-emerald-500"
Expand Down
Loading