search console SEO ableitungen
This commit is contained in:
@@ -1,427 +1,427 @@
|
||||
import type { FAQItem } from "@/lib/types";
|
||||
import type { Metadata } from "next";
|
||||
|
||||
import Link from "next/link";
|
||||
import {
|
||||
ArrowRight,
|
||||
CheckCircle2,
|
||||
Compass,
|
||||
Link2,
|
||||
Radar,
|
||||
Sparkles,
|
||||
} from "lucide-react";
|
||||
|
||||
import Breadcrumbs, { BreadcrumbItem } from "@/components/Breadcrumbs";
|
||||
import SeoJsonLd from "@/components/SeoJsonLd";
|
||||
import { FAQSection } from "@/components/aeo/FAQSection";
|
||||
import {
|
||||
MarketingPageTracker,
|
||||
TrackedCtaLink,
|
||||
} from "@/components/marketing/MarketingAnalytics";
|
||||
import { AnswerFirstBlock } from "@/components/marketing/AnswerFirstBlock";
|
||||
import { Button } from "@/components/ui/Button";
|
||||
import { Card } from "@/components/ui/Card";
|
||||
import { breadcrumbSchema, faqPageSchema } from "@/lib/schema";
|
||||
|
||||
type LinkCard = {
|
||||
href: string;
|
||||
title: string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
type UseCasePageTemplateProps = {
|
||||
title: string;
|
||||
description: string;
|
||||
eyebrow: string;
|
||||
intro: string;
|
||||
pageType: "commercial" | "use_case";
|
||||
cluster: string;
|
||||
useCase?: string;
|
||||
breadcrumbs: BreadcrumbItem[];
|
||||
answer: string;
|
||||
whenToUse: string[];
|
||||
comparisonItems: {
|
||||
label: string;
|
||||
value: boolean;
|
||||
text?: string;
|
||||
}[];
|
||||
howToSteps: string[];
|
||||
primaryCta: {
|
||||
href: string;
|
||||
label: string;
|
||||
};
|
||||
secondaryCta: {
|
||||
href: string;
|
||||
label: string;
|
||||
};
|
||||
workflowTitle: string;
|
||||
workflowIntro: string;
|
||||
workflowCards: {
|
||||
title: string;
|
||||
description: string;
|
||||
}[];
|
||||
checklistTitle: string;
|
||||
checklist: string[];
|
||||
supportLinks: LinkCard[];
|
||||
faq: FAQItem[];
|
||||
schemaData?: Record<string, unknown>[];
|
||||
};
|
||||
|
||||
export function buildUseCaseMetadata({
|
||||
title,
|
||||
description,
|
||||
canonicalPath,
|
||||
}: {
|
||||
title: string;
|
||||
description: string;
|
||||
canonicalPath: string;
|
||||
}): Metadata {
|
||||
const canonical = `https://www.qrmaster.net${canonicalPath}`;
|
||||
|
||||
return {
|
||||
title: {
|
||||
absolute: `${title} | QR Master`,
|
||||
},
|
||||
description,
|
||||
alternates: {
|
||||
canonical,
|
||||
languages: {
|
||||
"x-default": canonical,
|
||||
en: canonical,
|
||||
},
|
||||
},
|
||||
openGraph: {
|
||||
title: `${title} | QR Master`,
|
||||
description,
|
||||
url: canonical,
|
||||
type: "website",
|
||||
images: ["/og-image.png"],
|
||||
},
|
||||
twitter: {
|
||||
title: `${title} | QR Master`,
|
||||
description,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function UseCasePageTemplate({
|
||||
title,
|
||||
description,
|
||||
eyebrow,
|
||||
intro,
|
||||
pageType,
|
||||
cluster,
|
||||
useCase,
|
||||
breadcrumbs,
|
||||
answer,
|
||||
whenToUse,
|
||||
comparisonItems,
|
||||
howToSteps,
|
||||
primaryCta,
|
||||
secondaryCta,
|
||||
workflowTitle,
|
||||
workflowIntro,
|
||||
workflowCards,
|
||||
checklistTitle,
|
||||
checklist,
|
||||
supportLinks,
|
||||
faq,
|
||||
schemaData = [],
|
||||
}: UseCasePageTemplateProps) {
|
||||
return (
|
||||
<>
|
||||
<SeoJsonLd
|
||||
data={[...schemaData, breadcrumbSchema(breadcrumbs), faqPageSchema(faq)]}
|
||||
/>
|
||||
<MarketingPageTracker
|
||||
pageType={pageType}
|
||||
cluster={cluster}
|
||||
useCase={useCase}
|
||||
/>
|
||||
|
||||
<div className="min-h-screen bg-white">
|
||||
<section className="relative overflow-hidden bg-gradient-to-br from-slate-950 via-blue-950 to-cyan-900 text-white">
|
||||
<div className="absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(125,211,252,0.22),transparent_38%),radial-gradient(circle_at_bottom_right,rgba(255,255,255,0.08),transparent_30%)]" />
|
||||
<div className="relative container mx-auto max-w-7xl px-4 py-20 sm:px-6 lg:px-8">
|
||||
<Breadcrumbs
|
||||
items={breadcrumbs}
|
||||
className="[&_a]:text-blue-100/80 [&_a:hover]:text-white [&_span]:text-blue-100/80 [&_[aria-current=page]]:text-white"
|
||||
/>
|
||||
|
||||
<div className="grid gap-12 lg:grid-cols-[minmax(0,1.2fr)_minmax(320px,0.8fr)] lg:items-center">
|
||||
<div className="space-y-8">
|
||||
<div className="inline-flex items-center gap-2 rounded-full border border-white/15 bg-white/10 px-4 py-2 text-sm font-semibold text-cyan-100 shadow-lg shadow-cyan-950/30 backdrop-blur">
|
||||
<Sparkles className="h-4 w-4" />
|
||||
<span>{eyebrow}</span>
|
||||
</div>
|
||||
|
||||
<div className="space-y-5">
|
||||
<h1 className="max-w-4xl text-4xl font-bold tracking-tight text-white md:text-5xl lg:text-6xl">
|
||||
{title}
|
||||
</h1>
|
||||
<p className="max-w-3xl text-lg leading-8 text-blue-50/88 md:text-xl">
|
||||
{intro}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-3 text-sm text-blue-50/80 sm:grid-cols-2">
|
||||
{[
|
||||
"Built for QR workflows where the printed surface should stay stable.",
|
||||
"Focused on operational clarity, not inflated ROI claims.",
|
||||
"Connected to a commercial parent and sibling workflows.",
|
||||
"Designed to fit QR Master's existing marketing theme.",
|
||||
].map((line) => (
|
||||
<div
|
||||
key={line}
|
||||
className="flex items-start gap-3 rounded-2xl border border-white/10 bg-white/5 px-4 py-3 backdrop-blur-sm"
|
||||
>
|
||||
<CheckCircle2 className="mt-0.5 h-4 w-4 shrink-0 text-cyan-300" />
|
||||
<span>{line}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-4 sm:flex-row">
|
||||
<TrackedCtaLink
|
||||
href={primaryCta.href}
|
||||
ctaLabel={primaryCta.label}
|
||||
ctaLocation="hero_primary"
|
||||
pageType={pageType}
|
||||
cluster={cluster}
|
||||
useCase={useCase}
|
||||
>
|
||||
<Button
|
||||
size="lg"
|
||||
className="w-full bg-white px-8 py-4 text-base font-semibold text-slate-950 hover:bg-slate-100 sm:w-auto"
|
||||
>
|
||||
{primaryCta.label}
|
||||
</Button>
|
||||
</TrackedCtaLink>
|
||||
|
||||
<TrackedCtaLink
|
||||
href={secondaryCta.href}
|
||||
ctaLabel={secondaryCta.label}
|
||||
ctaLocation="hero_secondary"
|
||||
pageType={pageType}
|
||||
cluster={cluster}
|
||||
useCase={useCase}
|
||||
>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="lg"
|
||||
className="w-full border-white/30 bg-white/5 px-8 py-4 text-base text-white hover:bg-white/10 sm:w-auto"
|
||||
>
|
||||
{secondaryCta.label}
|
||||
</Button>
|
||||
</TrackedCtaLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Card className="border-white/10 bg-white/10 p-8 text-white shadow-2xl shadow-slate-950/30 backdrop-blur">
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center justify-between border-b border-white/10 pb-4">
|
||||
<div>
|
||||
<div className="text-xs uppercase tracking-[0.24em] text-cyan-200/70">
|
||||
Workflow snapshot
|
||||
</div>
|
||||
<div className="mt-2 text-2xl font-semibold text-white">
|
||||
What matters here
|
||||
</div>
|
||||
</div>
|
||||
<Compass className="h-9 w-9 text-cyan-300" />
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
{workflowCards.map((card, index) => (
|
||||
<div
|
||||
key={card.title}
|
||||
className="rounded-2xl border border-white/10 bg-slate-950/30 p-4"
|
||||
>
|
||||
<div className="mb-2 flex items-center gap-3">
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-cyan-400/15 text-sm font-semibold text-cyan-200">
|
||||
{index + 1}
|
||||
</div>
|
||||
<div className="text-lg font-semibold text-white">
|
||||
{card.title}
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm leading-6 text-blue-50/80">
|
||||
{card.description}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="container mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8">
|
||||
<AnswerFirstBlock
|
||||
whatIsIt={answer}
|
||||
whenToUse={whenToUse}
|
||||
comparison={{
|
||||
leftTitle: "Static",
|
||||
rightTitle: "Better fit here",
|
||||
items: comparisonItems,
|
||||
}}
|
||||
howTo={{
|
||||
steps: howToSteps,
|
||||
}}
|
||||
className="mt-0"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<section className="bg-slate-50 py-16">
|
||||
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<div className="mb-10 max-w-3xl">
|
||||
<h2 className="text-3xl font-bold tracking-tight text-slate-900">
|
||||
{workflowTitle}
|
||||
</h2>
|
||||
<p className="mt-4 text-lg leading-8 text-slate-600">
|
||||
{workflowIntro}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-6 lg:grid-cols-3">
|
||||
{workflowCards.map((card) => (
|
||||
<Card
|
||||
key={card.title}
|
||||
className="rounded-3xl border-slate-200/80 bg-white p-7 shadow-sm"
|
||||
>
|
||||
<div className="mb-5 flex h-12 w-12 items-center justify-center rounded-2xl bg-blue-50 text-blue-700">
|
||||
<Radar className="h-6 w-6" />
|
||||
</div>
|
||||
<h3 className="text-xl font-semibold text-slate-900">
|
||||
{card.title}
|
||||
</h3>
|
||||
<p className="mt-3 text-base leading-7 text-slate-600">
|
||||
{card.description}
|
||||
</p>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="py-16">
|
||||
<div className="container mx-auto grid max-w-7xl gap-8 px-4 sm:px-6 lg:grid-cols-[minmax(0,0.95fr)_minmax(280px,0.8fr)] lg:px-8">
|
||||
<Card className="rounded-3xl border-slate-200 bg-white p-8 shadow-sm">
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<div className="text-sm font-semibold uppercase tracking-[0.22em] text-blue-700">
|
||||
Checklist
|
||||
</div>
|
||||
<h2 className="mt-3 text-3xl font-bold text-slate-900">
|
||||
{checklistTitle}
|
||||
</h2>
|
||||
</div>
|
||||
<CheckCircle2 className="h-8 w-8 text-blue-700" />
|
||||
</div>
|
||||
|
||||
<ul className="mt-8 space-y-4">
|
||||
{checklist.map((item) => (
|
||||
<li
|
||||
key={item}
|
||||
className="flex items-start gap-3 text-slate-700"
|
||||
>
|
||||
<CheckCircle2 className="mt-1 h-5 w-5 shrink-0 text-green-600" />
|
||||
<span className="leading-7">{item}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Card>
|
||||
|
||||
<Card className="rounded-3xl border-slate-200 bg-slate-950 p-8 text-white shadow-xl shadow-slate-200">
|
||||
<div className="flex items-center gap-3">
|
||||
<Link2 className="h-5 w-5 text-cyan-300" />
|
||||
<h2 className="text-2xl font-bold">Related links</h2>
|
||||
</div>
|
||||
<div className="mt-6 space-y-4">
|
||||
{supportLinks.map((link) => (
|
||||
<Link
|
||||
key={link.href}
|
||||
href={link.href}
|
||||
className="group block rounded-2xl border border-white/10 bg-white/5 p-4 transition-colors hover:bg-white/10"
|
||||
>
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<div className="text-lg font-semibold text-white">
|
||||
{link.title}
|
||||
</div>
|
||||
<div className="mt-2 text-sm leading-6 text-blue-50/78">
|
||||
{link.description}
|
||||
</div>
|
||||
</div>
|
||||
<ArrowRight className="mt-1 h-4 w-4 shrink-0 text-cyan-300 transition-transform group-hover:translate-x-1" />
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="container mx-auto max-w-5xl px-4 pb-6 sm:px-6 lg:px-8">
|
||||
<FAQSection items={faq} title={`${title} FAQ`} />
|
||||
</div>
|
||||
|
||||
<section className="pb-20 pt-6">
|
||||
<div className="container mx-auto max-w-5xl px-4 sm:px-6 lg:px-8">
|
||||
<div className="rounded-[2rem] bg-gradient-to-r from-blue-700 via-indigo-700 to-slate-900 px-8 py-10 text-white shadow-2xl shadow-blue-100">
|
||||
<div className="flex flex-col gap-8 lg:flex-row lg:items-end lg:justify-between">
|
||||
<div className="max-w-2xl">
|
||||
<div className="text-sm font-semibold uppercase tracking-[0.22em] text-blue-100/80">
|
||||
Next step
|
||||
</div>
|
||||
<h2 className="mt-3 text-3xl font-bold tracking-tight">
|
||||
Use a QR workflow that stays useful after the print run starts.
|
||||
</h2>
|
||||
<p className="mt-4 text-lg leading-8 text-blue-50/84">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-4 sm:flex-row">
|
||||
<TrackedCtaLink
|
||||
href={primaryCta.href}
|
||||
ctaLabel={primaryCta.label}
|
||||
ctaLocation="footer_primary"
|
||||
pageType={pageType}
|
||||
cluster={cluster}
|
||||
useCase={useCase}
|
||||
>
|
||||
<Button
|
||||
size="lg"
|
||||
className="w-full bg-white px-7 text-slate-950 hover:bg-slate-100 sm:w-auto"
|
||||
>
|
||||
{primaryCta.label}
|
||||
</Button>
|
||||
</TrackedCtaLink>
|
||||
|
||||
<TrackedCtaLink
|
||||
href={secondaryCta.href}
|
||||
ctaLabel={secondaryCta.label}
|
||||
ctaLocation="footer_secondary"
|
||||
pageType={pageType}
|
||||
cluster={cluster}
|
||||
useCase={useCase}
|
||||
>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="lg"
|
||||
className="w-full border-white/30 bg-white/5 text-white hover:bg-white/10 sm:w-auto"
|
||||
>
|
||||
{secondaryCta.label}
|
||||
</Button>
|
||||
</TrackedCtaLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
import type { FAQItem } from "@/lib/types";
|
||||
import type { Metadata } from "next";
|
||||
|
||||
import Link from "next/link";
|
||||
import {
|
||||
ArrowRight,
|
||||
CheckCircle2,
|
||||
Compass,
|
||||
Link2,
|
||||
Radar,
|
||||
Sparkles,
|
||||
} from "lucide-react";
|
||||
|
||||
import Breadcrumbs, { BreadcrumbItem } from "@/components/Breadcrumbs";
|
||||
import SeoJsonLd from "@/components/SeoJsonLd";
|
||||
import { FAQSection } from "@/components/aeo/FAQSection";
|
||||
import {
|
||||
MarketingPageTracker,
|
||||
TrackedCtaLink,
|
||||
} from "@/components/marketing/MarketingAnalytics";
|
||||
import { AnswerFirstBlock } from "@/components/marketing/AnswerFirstBlock";
|
||||
import { Button } from "@/components/ui/Button";
|
||||
import { Card } from "@/components/ui/Card";
|
||||
import { breadcrumbSchema, faqPageSchema } from "@/lib/schema";
|
||||
|
||||
type LinkCard = {
|
||||
href: string;
|
||||
title: string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
type UseCasePageTemplateProps = {
|
||||
title: string;
|
||||
description: string;
|
||||
eyebrow: string;
|
||||
intro: string;
|
||||
pageType: "commercial" | "use_case";
|
||||
cluster: string;
|
||||
useCase?: string;
|
||||
breadcrumbs: BreadcrumbItem[];
|
||||
answer: string;
|
||||
whenToUse: string[];
|
||||
comparisonItems: {
|
||||
label: string;
|
||||
value: boolean;
|
||||
text?: string;
|
||||
}[];
|
||||
howToSteps: string[];
|
||||
primaryCta: {
|
||||
href: string;
|
||||
label: string;
|
||||
};
|
||||
secondaryCta: {
|
||||
href: string;
|
||||
label: string;
|
||||
};
|
||||
workflowTitle: string;
|
||||
workflowIntro: string;
|
||||
workflowCards: {
|
||||
title: string;
|
||||
description: string;
|
||||
}[];
|
||||
checklistTitle: string;
|
||||
checklist: string[];
|
||||
supportLinks: LinkCard[];
|
||||
faq: FAQItem[];
|
||||
schemaData?: Record<string, unknown>[];
|
||||
};
|
||||
|
||||
export function buildUseCaseMetadata({
|
||||
title,
|
||||
description,
|
||||
canonicalPath,
|
||||
}: {
|
||||
title: string;
|
||||
description: string;
|
||||
canonicalPath: string;
|
||||
}): Metadata {
|
||||
const canonical = `https://www.qrmaster.net${canonicalPath}`;
|
||||
|
||||
return {
|
||||
title: {
|
||||
absolute: `${title} | QR Master`,
|
||||
},
|
||||
description,
|
||||
alternates: {
|
||||
canonical,
|
||||
languages: {
|
||||
"x-default": canonical,
|
||||
en: canonical,
|
||||
},
|
||||
},
|
||||
openGraph: {
|
||||
title: `${title} | QR Master`,
|
||||
description,
|
||||
url: canonical,
|
||||
type: "website",
|
||||
images: ["/og-image.png"],
|
||||
},
|
||||
twitter: {
|
||||
title: `${title} | QR Master`,
|
||||
description,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function UseCasePageTemplate({
|
||||
title,
|
||||
description,
|
||||
eyebrow,
|
||||
intro,
|
||||
pageType,
|
||||
cluster,
|
||||
useCase,
|
||||
breadcrumbs,
|
||||
answer,
|
||||
whenToUse,
|
||||
comparisonItems,
|
||||
howToSteps,
|
||||
primaryCta,
|
||||
secondaryCta,
|
||||
workflowTitle,
|
||||
workflowIntro,
|
||||
workflowCards,
|
||||
checklistTitle,
|
||||
checklist,
|
||||
supportLinks,
|
||||
faq,
|
||||
schemaData = [],
|
||||
}: UseCasePageTemplateProps) {
|
||||
return (
|
||||
<>
|
||||
<SeoJsonLd
|
||||
data={[...schemaData, breadcrumbSchema(breadcrumbs), faqPageSchema(faq)]}
|
||||
/>
|
||||
<MarketingPageTracker
|
||||
pageType={pageType}
|
||||
cluster={cluster}
|
||||
useCase={useCase}
|
||||
/>
|
||||
|
||||
<div className="min-h-screen bg-white">
|
||||
<section className="relative overflow-hidden bg-gradient-to-br from-slate-950 via-blue-950 to-cyan-900 text-white">
|
||||
<div className="absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(125,211,252,0.22),transparent_38%),radial-gradient(circle_at_bottom_right,rgba(255,255,255,0.08),transparent_30%)]" />
|
||||
<div className="relative container mx-auto max-w-7xl px-4 py-20 sm:px-6 lg:px-8">
|
||||
<Breadcrumbs
|
||||
items={breadcrumbs}
|
||||
className="[&_a]:text-blue-100/80 [&_a:hover]:text-white [&_span]:text-blue-100/80 [&_[aria-current=page]]:text-white"
|
||||
/>
|
||||
|
||||
<div className="grid gap-12 lg:grid-cols-[minmax(0,1.2fr)_minmax(320px,0.8fr)] lg:items-center">
|
||||
<div className="space-y-8">
|
||||
<div className="inline-flex items-center gap-2 rounded-full border border-white/15 bg-white/10 px-4 py-2 text-sm font-semibold text-cyan-100 shadow-lg shadow-cyan-950/30 backdrop-blur">
|
||||
<Sparkles className="h-4 w-4" />
|
||||
<span>{eyebrow}</span>
|
||||
</div>
|
||||
|
||||
<div className="space-y-5">
|
||||
<h1 className="max-w-4xl text-4xl font-bold tracking-tight text-white md:text-5xl lg:text-6xl">
|
||||
{title}
|
||||
</h1>
|
||||
<p className="max-w-3xl text-lg leading-8 text-blue-50/88 md:text-xl">
|
||||
{intro}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-3 text-sm text-blue-50/80 sm:grid-cols-2">
|
||||
{[
|
||||
"Built for QR workflows where the printed surface should stay stable.",
|
||||
"Focused on operational clarity, not inflated ROI claims.",
|
||||
"Connected to a commercial parent and sibling workflows.",
|
||||
"Designed to fit QR Master's existing marketing theme.",
|
||||
].map((line) => (
|
||||
<div
|
||||
key={line}
|
||||
className="flex items-start gap-3 rounded-2xl border border-white/10 bg-white/5 px-4 py-3 backdrop-blur-sm"
|
||||
>
|
||||
<CheckCircle2 className="mt-0.5 h-4 w-4 shrink-0 text-cyan-300" />
|
||||
<span>{line}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-4 sm:flex-row">
|
||||
<TrackedCtaLink
|
||||
href={primaryCta.href}
|
||||
ctaLabel={primaryCta.label}
|
||||
ctaLocation="hero_primary"
|
||||
pageType={pageType}
|
||||
cluster={cluster}
|
||||
useCase={useCase}
|
||||
>
|
||||
<Button
|
||||
size="lg"
|
||||
className="w-full bg-white px-8 py-4 text-base font-semibold text-slate-950 hover:bg-slate-100 sm:w-auto"
|
||||
>
|
||||
{primaryCta.label}
|
||||
</Button>
|
||||
</TrackedCtaLink>
|
||||
|
||||
<TrackedCtaLink
|
||||
href={secondaryCta.href}
|
||||
ctaLabel={secondaryCta.label}
|
||||
ctaLocation="hero_secondary"
|
||||
pageType={pageType}
|
||||
cluster={cluster}
|
||||
useCase={useCase}
|
||||
>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="lg"
|
||||
className="w-full border-white/30 bg-white/5 px-8 py-4 text-base text-white hover:bg-white/10 sm:w-auto"
|
||||
>
|
||||
{secondaryCta.label}
|
||||
</Button>
|
||||
</TrackedCtaLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Card className="border-white/10 bg-white/10 p-8 text-white shadow-2xl shadow-slate-950/30 backdrop-blur">
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center justify-between border-b border-white/10 pb-4">
|
||||
<div>
|
||||
<div className="text-xs uppercase tracking-[0.24em] text-cyan-200/70">
|
||||
Workflow snapshot
|
||||
</div>
|
||||
<div className="mt-2 text-2xl font-semibold text-white">
|
||||
What matters here
|
||||
</div>
|
||||
</div>
|
||||
<Compass className="h-9 w-9 text-cyan-300" />
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
{workflowCards.map((card, index) => (
|
||||
<div
|
||||
key={card.title}
|
||||
className="rounded-2xl border border-white/10 bg-slate-950/30 p-4"
|
||||
>
|
||||
<div className="mb-2 flex items-center gap-3">
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-cyan-400/15 text-sm font-semibold text-cyan-200">
|
||||
{index + 1}
|
||||
</div>
|
||||
<div className="text-lg font-semibold text-white">
|
||||
{card.title}
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm leading-6 text-blue-50/80">
|
||||
{card.description}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="container mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8">
|
||||
<AnswerFirstBlock
|
||||
whatIsIt={answer}
|
||||
whenToUse={whenToUse}
|
||||
comparison={{
|
||||
leftTitle: "Static",
|
||||
rightTitle: "Better fit here",
|
||||
items: comparisonItems,
|
||||
}}
|
||||
howTo={{
|
||||
steps: howToSteps,
|
||||
}}
|
||||
className="mt-0"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<section className="bg-slate-50 py-16">
|
||||
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<div className="mb-10 max-w-3xl">
|
||||
<h2 className="text-3xl font-bold tracking-tight text-slate-900">
|
||||
{workflowTitle}
|
||||
</h2>
|
||||
<p className="mt-4 text-lg leading-8 text-slate-600">
|
||||
{workflowIntro}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-6 lg:grid-cols-3">
|
||||
{workflowCards.map((card) => (
|
||||
<Card
|
||||
key={card.title}
|
||||
className="rounded-3xl border-slate-200/80 bg-white p-7 shadow-sm"
|
||||
>
|
||||
<div className="mb-5 flex h-12 w-12 items-center justify-center rounded-2xl bg-blue-50 text-blue-700">
|
||||
<Radar className="h-6 w-6" />
|
||||
</div>
|
||||
<h3 className="text-xl font-semibold text-slate-900">
|
||||
{card.title}
|
||||
</h3>
|
||||
<p className="mt-3 text-base leading-7 text-slate-600">
|
||||
{card.description}
|
||||
</p>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="py-16">
|
||||
<div className="container mx-auto grid max-w-7xl gap-8 px-4 sm:px-6 lg:grid-cols-[minmax(0,0.95fr)_minmax(280px,0.8fr)] lg:px-8">
|
||||
<Card className="rounded-3xl border-slate-200 bg-white p-8 shadow-sm">
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<div className="text-sm font-semibold uppercase tracking-[0.22em] text-blue-700">
|
||||
Checklist
|
||||
</div>
|
||||
<h2 className="mt-3 text-3xl font-bold text-slate-900">
|
||||
{checklistTitle}
|
||||
</h2>
|
||||
</div>
|
||||
<CheckCircle2 className="h-8 w-8 text-blue-700" />
|
||||
</div>
|
||||
|
||||
<ul className="mt-8 space-y-4">
|
||||
{checklist.map((item) => (
|
||||
<li
|
||||
key={item}
|
||||
className="flex items-start gap-3 text-slate-700"
|
||||
>
|
||||
<CheckCircle2 className="mt-1 h-5 w-5 shrink-0 text-green-600" />
|
||||
<span className="leading-7">{item}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Card>
|
||||
|
||||
<Card className="rounded-3xl border-slate-200 bg-slate-950 p-8 text-white shadow-xl shadow-slate-200">
|
||||
<div className="flex items-center gap-3">
|
||||
<Link2 className="h-5 w-5 text-cyan-300" />
|
||||
<h2 className="text-2xl font-bold">Related links</h2>
|
||||
</div>
|
||||
<div className="mt-6 space-y-4">
|
||||
{supportLinks.map((link) => (
|
||||
<Link
|
||||
key={link.href}
|
||||
href={link.href}
|
||||
className="group block rounded-2xl border border-white/10 bg-white/5 p-4 transition-colors hover:bg-white/10"
|
||||
>
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<div className="text-lg font-semibold text-white">
|
||||
{link.title}
|
||||
</div>
|
||||
<div className="mt-2 text-sm leading-6 text-blue-50/78">
|
||||
{link.description}
|
||||
</div>
|
||||
</div>
|
||||
<ArrowRight className="mt-1 h-4 w-4 shrink-0 text-cyan-300 transition-transform group-hover:translate-x-1" />
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="container mx-auto max-w-5xl px-4 pb-6 sm:px-6 lg:px-8">
|
||||
<FAQSection items={faq} title={`${title} FAQ`} />
|
||||
</div>
|
||||
|
||||
<section className="pb-20 pt-6">
|
||||
<div className="container mx-auto max-w-5xl px-4 sm:px-6 lg:px-8">
|
||||
<div className="rounded-[2rem] bg-gradient-to-r from-blue-700 via-indigo-700 to-slate-900 px-8 py-10 text-white shadow-2xl shadow-blue-100">
|
||||
<div className="flex flex-col gap-8 lg:flex-row lg:items-end lg:justify-between">
|
||||
<div className="max-w-2xl">
|
||||
<div className="text-sm font-semibold uppercase tracking-[0.22em] text-blue-100/80">
|
||||
Next step
|
||||
</div>
|
||||
<h2 className="mt-3 text-3xl font-bold tracking-tight">
|
||||
Use a QR workflow that stays useful after the print run starts.
|
||||
</h2>
|
||||
<p className="mt-4 text-lg leading-8 text-blue-50/84">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-4 sm:flex-row">
|
||||
<TrackedCtaLink
|
||||
href={primaryCta.href}
|
||||
ctaLabel={primaryCta.label}
|
||||
ctaLocation="footer_primary"
|
||||
pageType={pageType}
|
||||
cluster={cluster}
|
||||
useCase={useCase}
|
||||
>
|
||||
<Button
|
||||
size="lg"
|
||||
className="w-full bg-white px-7 text-slate-950 hover:bg-slate-100 sm:w-auto"
|
||||
>
|
||||
{primaryCta.label}
|
||||
</Button>
|
||||
</TrackedCtaLink>
|
||||
|
||||
<TrackedCtaLink
|
||||
href={secondaryCta.href}
|
||||
ctaLabel={secondaryCta.label}
|
||||
ctaLocation="footer_secondary"
|
||||
pageType={pageType}
|
||||
cluster={cluster}
|
||||
useCase={useCase}
|
||||
>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="lg"
|
||||
className="w-full border-white/30 bg-white/5 text-white hover:bg-white/10 sm:w-auto"
|
||||
>
|
||||
{secondaryCta.label}
|
||||
</Button>
|
||||
</TrackedCtaLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user