Skip to content

Commit 69cf666

Browse files
Programcodeclaude
andauthored
Landing page: less text, a phone-first hero, three fewer sections (#250)
On a phone the first screen now holds Ollie, the H1, one line, the Start trial button and three checked chips. The hero copy is the first sentence of the old subheadline; the announcement, second button and plan boxes are gone, and the product preview shows from lg up. What's new, Active Grounding and Use cases are removed: they repeated the feature list. Features are icon tiles, How it works and Pricing carry one short line per item, the short answer folds to three lines on phones, and the guide links become chip rows that scroll sideways on phones. Every link, anchor, heading level and JSON-LD source string stays. Unused keys leave all three catalogs; hu and es get the same shorter copy. At 390 px the English page goes from about 15,250 px to 5,120 px. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent fea1ab9 commit 69cf666

16 files changed

Lines changed: 209 additions & 695 deletions

‎src/components/landing/DeepDive.tsx‎

Lines changed: 0 additions & 80 deletions
This file was deleted.

‎src/components/landing/FAQ.tsx‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,17 @@ const FAQ = () => {
1919
];
2020

2121
return (
22-
<section id="faq" aria-labelledby="faq-title" className="bg-secondary/5 py-24">
22+
<section id="faq" aria-labelledby="faq-title" className="bg-secondary/5 py-12 md:py-20">
2323
<div className="section-container max-w-3xl">
24-
<Reveal className="mb-12 text-center">
25-
<h2 id="faq-title" className="section-heading mb-4">{t('faq.title')}</h2>
26-
<p className="text-muted-foreground">{t('faq.subtitle')}</p>
24+
<Reveal className="mb-6 text-center md:mb-10">
25+
<h2 id="faq-title" className="section-heading">{t('faq.title')}</h2>
2726
</Reveal>
2827

2928
{/* Native disclosure: closed answers stay in the HTML, so crawlers and find-in-page see them. */}
3029
<Reveal delay={0.05}>
3130
{faqs.map((faq) => (
3231
<details key={faq.question} className="group border-b">
33-
<summary className="flex cursor-pointer list-none items-center justify-between gap-4 rounded-sm py-4 text-left text-lg font-medium transition-colors duration-150 hover:text-primary focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring [&::-webkit-details-marker]:hidden">
32+
<summary className="flex cursor-pointer list-none items-center justify-between gap-4 rounded-sm py-4 text-left font-bold md:text-lg transition-colors duration-150 hover:text-primary focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring [&::-webkit-details-marker]:hidden">
3433
{faq.question}
3534
<ChevronDown aria-hidden="true" className="h-4 w-4 shrink-0 transition-transform duration-150 ease-out-strong group-open:rotate-180" />
3635
</summary>

‎src/components/landing/Features.tsx‎

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,35 @@ const Features = () => {
3232
];
3333

3434
return (
35-
<section id="features" className="relative py-24">
35+
<section id="features" className="relative py-12 md:py-20">
3636
<div className="absolute inset-0 pointer-events-none">
3737
{/* Positioned with top, not a translate, so nothing can override it. */}
3838
<div className="orb orb-primary left-0 top-[calc(50%-12rem)] h-96 w-96 opacity-40" />
3939
<div className="orb orb-accent bottom-0 right-0 h-80 w-80 opacity-40" />
4040
</div>
4141

4242
<div className="section-container relative z-10">
43-
<Reveal className="mb-12 text-center">
43+
<Reveal className="mb-8 text-center md:mb-12">
4444
<h2 className="section-heading">{t('features.title')}</h2>
4545
</Reveal>
4646

47-
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
47+
{/* Phones get icon tiles, two across; the one-line description joins from sm up. */}
48+
<div className="grid grid-cols-2 gap-3 sm:gap-4 md:grid-cols-3 lg:grid-cols-4">
4849
{features.map((feature, index) => (
49-
<Reveal key={feature.title} delay={index * 0.04}>
50-
<div className="feature-card h-full">
51-
<div className="mb-4 flex h-12 w-12 items-center justify-center rounded-md bg-brand-tint shadow-[0_3px_0_var(--do-primary-tint-border)]">
52-
<feature.icon aria-hidden="true" className="h-6 w-6 text-primary" />
50+
<Reveal
51+
key={feature.title}
52+
delay={index * 0.03}
53+
// An odd last tile takes the whole row while the grid is two across.
54+
className={index === features.length - 1 && features.length % 2 ? "h-full max-md:col-span-2" : "h-full"}
55+
>
56+
<div className="feature-card flex h-full flex-col gap-3 p-4 sm:p-5">
57+
<div className="flex h-10 w-10 items-center justify-center rounded-md bg-brand-tint shadow-[0_3px_0_var(--do-primary-tint-border)]">
58+
<feature.icon aria-hidden="true" className="h-5 w-5 text-primary" />
59+
</div>
60+
<div>
61+
<h3 className="font-display text-base font-[600] leading-snug text-heading sm:text-lg">{feature.title}</h3>
62+
<p className="mt-1 hidden text-sm text-muted-foreground sm:block">{feature.description}</p>
5363
</div>
54-
<h3 className="mb-2 font-display text-xl font-[600] text-heading">{feature.title}</h3>
55-
<p className="text-sm leading-relaxed text-muted-foreground">{feature.description}</p>
5664
</div>
5765
</Reveal>
5866
))}

‎src/components/landing/FinalCTA.tsx‎

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useTranslation } from "react-i18next";
22
import { Reveal } from "./Reveal";
3-
import { ArrowRight, Sparkles } from "lucide-react";
3+
import { ArrowRight } from "lucide-react";
44
import { Link } from "react-router-dom";
55
import { useRoutePrefetch } from "@/hooks/use-route-prefetch";
66

@@ -9,7 +9,7 @@ const FinalCTA = () => {
99
const appPrefetch = useRoutePrefetch("/app");
1010

1111
return (
12-
<section className="relative overflow-hidden py-24">
12+
<section className="relative overflow-hidden py-14 md:py-24">
1313
<div className="absolute inset-0 bg-linear-to-br from-primary/10 via-secondary/10 to-[rgb(255_196_20/0.14)]" />
1414
<div className="absolute inset-0 animated-grid opacity-45" />
1515

@@ -18,19 +18,10 @@ const FinalCTA = () => {
1818

1919
<div className="section-container relative z-10">
2020
<Reveal className="mx-auto max-w-3xl text-center">
21-
<div className="mb-6 inline-flex items-center gap-2 rounded-full border-2 border-brand-tint-border bg-brand-tint px-4 py-2 text-sm font-bold text-foreground">
22-
<Sparkles aria-hidden="true" className="h-4 w-4 text-primary" />
23-
{t('finalCta.freeTrialAvailable')}
24-
</div>
25-
2621
<h2 className="section-heading">{t('finalCta.title')}</h2>
2722

28-
<p className="mt-6 text-lg text-muted-foreground md:text-xl">
29-
{t('finalCta.subtitle')}
30-
</p>
31-
32-
<div className="mt-10 inline-flex">
33-
<Link to="/app" {...appPrefetch} className="btn-primary-gradient inline-flex items-center gap-3 px-10 py-5 text-lg">
23+
<div className="mt-8 flex justify-center">
24+
<Link to="/app" {...appPrefetch} className="btn-primary-gradient inline-flex w-full items-center justify-center gap-3 px-10 py-4 text-lg sm:w-auto md:py-5">
3425
<span className="relative z-10">{t('finalCta.cta')}</span>
3526
<ArrowRight aria-hidden="true" className="relative z-10 h-5 w-5" />
3627
</Link>

‎src/components/landing/GuideHub.tsx‎

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,19 @@ const GROUPS = [
1717
] as const;
1818

1919
const TOOLS = GROUPS.find((group) => group.id === "tools")!;
20-
const linkClass = "inline-flex text-muted-foreground underline-offset-4 hover:text-primary hover:underline pointer-coarse:min-h-11 pointer-coarse:items-center";
20+
const chipClass = "inline-flex shrink-0 items-center whitespace-nowrap rounded-full border-2 border-border bg-card px-3.5 py-1.5 text-sm font-semibold text-foreground transition-colors hover:border-brand-tint-border hover:text-primary pointer-coarse:min-h-11";
21+
/** One sideways-scrolling row of chips per group on phones; the chips wrap from md up. */
22+
const chipRowClass = "-mx-4 flex gap-2 overflow-x-auto px-4 pb-1 sm:-mx-6 sm:px-6 md:mx-0 md:flex-wrap md:overflow-visible md:px-0";
23+
24+
const HubHeading = () => {
25+
const { t } = useTranslation();
26+
return (
27+
<Reveal className="mb-8 text-center md:mb-10">
28+
<h2 id="guide-hub-title" className="section-heading">{t('guideHub.title')}</h2>
29+
<p className="mx-auto mt-4 hidden max-w-2xl text-lg text-muted-foreground md:block">{t('guideHub.subtitle')}</p>
30+
</Reveal>
31+
);
32+
};
2133

2234
/**
2335
* /hu and /es: the guides are in English, so only the free tools show, at their
@@ -26,27 +38,24 @@ const linkClass = "inline-flex text-muted-foreground underline-offset-4 hover:te
2638
const TranslatedToolsHub = ({ language }: { language: "hu" | "es" }) => {
2739
const { t } = useTranslation();
2840
return (
29-
<section aria-labelledby="guide-hub-title" className="py-24">
41+
<section aria-labelledby="guide-hub-title" className="py-12 md:py-20">
3042
<div className="section-container">
31-
<Reveal className="mb-12 text-center">
32-
<h2 id="guide-hub-title" className="section-heading mb-4">{t('guideHub.title')}</h2>
33-
<p className="mx-auto max-w-2xl text-lg text-muted-foreground">{t('guideHub.subtitle')}</p>
34-
</Reveal>
43+
<HubHeading />
3544

36-
<Reveal delay={0.05} className="mx-auto max-w-md">
45+
<Reveal delay={0.05} className="mx-auto max-w-2xl">
3746
<nav aria-labelledby="guide-hub-tools">
38-
<h3 id="guide-hub-tools" className="mb-3 font-semibold">{t('guideHub.tools')}</h3>
39-
<ul className="space-y-2">
47+
<h3 id="guide-hub-tools" className="mb-3 font-display text-lg font-[600] text-heading">{t('guideHub.tools')}</h3>
48+
<ul className={chipRowClass}>
4049
{TOOLS.paths.map((path) => (
41-
<li key={path}>
42-
<Link to={localizedPath(path, language)} className={linkClass}>{t(`guideHub.links.${path.slice(1)}`)}</Link>
50+
<li key={path} className="shrink-0">
51+
<Link to={localizedPath(path, language)} className={chipClass}>{t(`guideHub.links.${path.slice(1)}`)}</Link>
4352
</li>
4453
))}
4554
</ul>
4655
</nav>
4756
{/* The English home page lists every guide; a plain link loads it from the server. */}
48-
<p className="mt-6">
49-
<a href="/#guide-hub-title" hrefLang="en" className={linkClass}>{t('guideHub.englishGuides')}</a>
57+
<p className="mt-5">
58+
<a href="/#guide-hub-title" hrefLang="en" className="inline-flex items-center font-semibold text-primary underline-offset-4 hover:underline pointer-coarse:min-h-11">{t('guideHub.englishGuides')}</a>
5059
</p>
5160
</Reveal>
5261
</div>
@@ -60,22 +69,19 @@ const GuideHub = () => {
6069
if (language !== "en") return <TranslatedToolsHub language={language} />;
6170

6271
return (
63-
<section aria-labelledby="guide-hub-title" className="py-24">
72+
<section aria-labelledby="guide-hub-title" className="py-12 md:py-20">
6473
<div className="section-container">
65-
<Reveal className="mb-12 text-center">
66-
<h2 id="guide-hub-title" className="section-heading mb-4">{t('guideHub.title')}</h2>
67-
<p className="mx-auto max-w-2xl text-lg text-muted-foreground">{t('guideHub.subtitle')}</p>
68-
</Reveal>
74+
<HubHeading />
6975

70-
<Reveal delay={0.05} className="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-5">
76+
<Reveal delay={0.05} className="grid grid-cols-1 gap-6 md:grid-cols-2 md:gap-8 lg:grid-cols-3">
7177
{GROUPS.map((group) => (
7278
<nav key={group.id} aria-labelledby={`guide-hub-${group.id}`}>
73-
<h3 id={`guide-hub-${group.id}`} className="mb-3 font-semibold">{t(`guideHub.${group.id}`)}</h3>
74-
<ul className="space-y-2">
79+
<h3 id={`guide-hub-${group.id}`} className="mb-3 font-display text-lg font-[600] text-heading">{t(`guideHub.${group.id}`)}</h3>
80+
<ul className={chipRowClass}>
7581
{group.paths.map((path) => (
76-
<li key={path}>
82+
<li key={path} className="shrink-0">
7783
{/* Static pages, not app routes: a plain link loads each from the server. */}
78-
<a href={path} className={linkClass}>
84+
<a href={path} className={chipClass}>
7985
{t(`guideHub.links.${path.slice(1)}`)}
8086
</a>
8187
</li>

0 commit comments

Comments
 (0)