Skip to content
Merged
Show file tree
Hide file tree
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
80 changes: 0 additions & 80 deletions src/components/landing/DeepDive.tsx

This file was deleted.

9 changes: 4 additions & 5 deletions src/components/landing/FAQ.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,17 @@ const FAQ = () => {
];

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

{/* Native disclosure: closed answers stay in the HTML, so crawlers and find-in-page see them. */}
<Reveal delay={0.05}>
{faqs.map((faq) => (
<details key={faq.question} className="group border-b">
<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">
<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">
{faq.question}
<ChevronDown aria-hidden="true" className="h-4 w-4 shrink-0 transition-transform duration-150 ease-out-strong group-open:rotate-180" />
</summary>
Expand Down
26 changes: 17 additions & 9 deletions src/components/landing/Features.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,35 @@ const Features = () => {
];

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

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

<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
{/* Phones get icon tiles, two across; the one-line description joins from sm up. */}
<div className="grid grid-cols-2 gap-3 sm:gap-4 md:grid-cols-3 lg:grid-cols-4">
{features.map((feature, index) => (
<Reveal key={feature.title} delay={index * 0.04}>
<div className="feature-card h-full">
<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)]">
<feature.icon aria-hidden="true" className="h-6 w-6 text-primary" />
<Reveal
key={feature.title}
delay={index * 0.03}
// An odd last tile takes the whole row while the grid is two across.
className={index === features.length - 1 && features.length % 2 ? "h-full max-md:col-span-2" : "h-full"}
>
<div className="feature-card flex h-full flex-col gap-3 p-4 sm:p-5">
<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)]">
<feature.icon aria-hidden="true" className="h-5 w-5 text-primary" />
</div>
<div>
<h3 className="font-display text-base font-[600] leading-snug text-heading sm:text-lg">{feature.title}</h3>
<p className="mt-1 hidden text-sm text-muted-foreground sm:block">{feature.description}</p>
</div>
<h3 className="mb-2 font-display text-xl font-[600] text-heading">{feature.title}</h3>
<p className="text-sm leading-relaxed text-muted-foreground">{feature.description}</p>
</div>
</Reveal>
))}
Expand Down
17 changes: 4 additions & 13 deletions src/components/landing/FinalCTA.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useTranslation } from "react-i18next";
import { Reveal } from "./Reveal";
import { ArrowRight, Sparkles } from "lucide-react";
import { ArrowRight } from "lucide-react";
import { Link } from "react-router-dom";
import { useRoutePrefetch } from "@/hooks/use-route-prefetch";

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

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

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

<div className="section-container relative z-10">
<Reveal className="mx-auto max-w-3xl text-center">
<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">
<Sparkles aria-hidden="true" className="h-4 w-4 text-primary" />
{t('finalCta.freeTrialAvailable')}
</div>

<h2 className="section-heading">{t('finalCta.title')}</h2>

<p className="mt-6 text-lg text-muted-foreground md:text-xl">
{t('finalCta.subtitle')}
</p>

<div className="mt-10 inline-flex">
<Link to="/app" {...appPrefetch} className="btn-primary-gradient inline-flex items-center gap-3 px-10 py-5 text-lg">
<div className="mt-8 flex justify-center">
<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">
<span className="relative z-10">{t('finalCta.cta')}</span>
<ArrowRight aria-hidden="true" className="relative z-10 h-5 w-5" />
</Link>
Expand Down
52 changes: 29 additions & 23 deletions src/components/landing/GuideHub.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,19 @@ const GROUPS = [
] as const;

const TOOLS = GROUPS.find((group) => group.id === "tools")!;
const linkClass = "inline-flex text-muted-foreground underline-offset-4 hover:text-primary hover:underline pointer-coarse:min-h-11 pointer-coarse:items-center";
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";
/** One sideways-scrolling row of chips per group on phones; the chips wrap from md up. */
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";

const HubHeading = () => {
const { t } = useTranslation();
return (
<Reveal className="mb-8 text-center md:mb-10">
<h2 id="guide-hub-title" className="section-heading">{t('guideHub.title')}</h2>
<p className="mx-auto mt-4 hidden max-w-2xl text-lg text-muted-foreground md:block">{t('guideHub.subtitle')}</p>
</Reveal>
);
};

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

<Reveal delay={0.05} className="mx-auto max-w-md">
<Reveal delay={0.05} className="mx-auto max-w-2xl">
<nav aria-labelledby="guide-hub-tools">
<h3 id="guide-hub-tools" className="mb-3 font-semibold">{t('guideHub.tools')}</h3>
<ul className="space-y-2">
<h3 id="guide-hub-tools" className="mb-3 font-display text-lg font-[600] text-heading">{t('guideHub.tools')}</h3>
<ul className={chipRowClass}>
{TOOLS.paths.map((path) => (
<li key={path}>
<Link to={localizedPath(path, language)} className={linkClass}>{t(`guideHub.links.${path.slice(1)}`)}</Link>
<li key={path} className="shrink-0">
<Link to={localizedPath(path, language)} className={chipClass}>{t(`guideHub.links.${path.slice(1)}`)}</Link>
</li>
))}
</ul>
</nav>
{/* The English home page lists every guide; a plain link loads it from the server. */}
<p className="mt-6">
<a href="/#guide-hub-title" hrefLang="en" className={linkClass}>{t('guideHub.englishGuides')}</a>
<p className="mt-5">
<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>
</p>
</Reveal>
</div>
Expand All @@ -60,22 +69,19 @@ const GuideHub = () => {
if (language !== "en") return <TranslatedToolsHub language={language} />;

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

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