This commit is contained in:
2026-07-10 21:52:36 +02:00
parent bb528d6ef9
commit 671c1a1559
28 changed files with 6396 additions and 5561 deletions

View File

@@ -42,8 +42,9 @@ const TOOLS = [
{ icon: Youtube, name: 'YouTube', description: 'Open YouTube video', href: '/tools/youtube-qr-code', color: 'text-red-600', bg: 'bg-red-50' },
{ icon: MessageCircle, name: 'WhatsApp', description: 'Send WhatsApp message', href: '/tools/whatsapp-qr-code', color: 'text-green-600', bg: 'bg-green-50' },
{ icon: Music, name: 'TikTok', description: 'Open TikTok profile', href: '/tools/tiktok-qr-code', color: 'text-slate-900', bg: 'bg-slate-100' },
{ icon: MapPin, name: 'Location', description: 'Share GPS coordinates', href: '/tools/location-qr-code', color: 'text-emerald-500', bg: 'bg-emerald-50' },
{ icon: Phone, name: 'Call', description: 'Start a phone call', href: '/tools/phone-qr-code', color: 'text-teal-500', bg: 'bg-teal-50' },
{ icon: MapPin, name: 'Location', description: 'Share GPS coordinates', href: '/tools/geolocation-qr-code', color: 'text-emerald-500', bg: 'bg-emerald-50' },
{ icon: Phone, name: 'Call', description: 'Start a phone call', href: '/tools/call-qr-code-generator', color: 'text-teal-500', bg: 'bg-teal-50' },
{ icon: Star, name: 'Google Review', description: 'Collect more reviews', href: '/tools/google-review-qr-code', color: 'text-yellow-500', bg: 'bg-yellow-50' },
{ icon: Barcode, name: 'Barcode', description: 'Free online barcode generator', href: '/tools/barcode-generator', color: 'text-amber-600', bg: 'bg-amber-50' },
];

View File

@@ -1,47 +1,47 @@
'use client';
'use client';
import React from 'react';
import Link from 'next/link';
import { Hero } from '@/components/marketing/Hero';
import AIComingSoonBanner from '@/components/marketing/AIComingSoonBanner';
import { StatsStrip } from '@/components/marketing/StatsStrip';
import { TemplateCards } from '@/components/marketing/TemplateCards';
import { InstantGenerator } from '@/components/marketing/InstantGenerator';
import { StaticVsDynamic } from '@/components/marketing/StaticVsDynamic';
import { Features } from '@/components/marketing/Features';
import { Pricing } from '@/components/marketing/Pricing';
import { FAQ } from '@/components/marketing/FAQ';
import { Button } from '@/components/ui/Button';
import { ReprintCalculatorTeaser } from '@/components/marketing/ReprintCalculatorTeaser';
import { ScrollToTop } from '@/components/ui/ScrollToTop';
import { FreeToolsGrid } from '@/components/marketing/FreeToolsGrid';
import { TestimonialsCarousel } from '@/components/marketing/TestimonialsCarousel';
import { testimonials } from '@/lib/testimonial-data';
import AIComingSoonBanner from '@/components/marketing/AIComingSoonBanner';
import { StatsStrip } from '@/components/marketing/StatsStrip';
import { TemplateCards } from '@/components/marketing/TemplateCards';
import { InstantGenerator } from '@/components/marketing/InstantGenerator';
import { StaticVsDynamic } from '@/components/marketing/StaticVsDynamic';
import { Features } from '@/components/marketing/Features';
import { Pricing } from '@/components/marketing/Pricing';
import { FAQ } from '@/components/marketing/FAQ';
import { Button } from '@/components/ui/Button';
import { ReprintCalculatorTeaser } from '@/components/marketing/ReprintCalculatorTeaser';
import { ScrollToTop } from '@/components/ui/ScrollToTop';
import { FreeToolsGrid } from '@/components/marketing/FreeToolsGrid';
import { TestimonialsCarousel } from '@/components/marketing/TestimonialsCarousel';
import { testimonials } from '@/lib/testimonial-data';
import en from '@/i18n/en.json';
import { allUseCases } from '@/lib/growth-pages';
export default function HomePageClient() {
// Always use English for marketing pages
const t = en;
const industries = [
'Restaurant Chain',
'Tech Startup',
'Real Estate',
'Event Agency',
'Retail Store',
'Healthcare',
];
return (
<>
<Hero t={t} />
{/* Main Interaction: Generator */}
<InstantGenerator t={t} />
<AIComingSoonBanner />
import { publishedUseCases } from '@/lib/growth-pages';
export default function HomePageClient() {
// Always use English for marketing pages
const t = en;
const industries = [
'Restaurant Chain',
'Tech Startup',
'Real Estate',
'Event Agency',
'Retail Store',
'Healthcare',
];
return (
<>
<Hero t={t} />
{/* Main Interaction: Generator */}
<InstantGenerator t={t} />
<AIComingSoonBanner />
{/* Free Tools Grid */}
<FreeToolsGrid />
@@ -133,7 +133,7 @@ export default function HomePageClient() {
</p>
</div>
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
{allUseCases.slice(0, 8).map((item) => (
{publishedUseCases.slice(0, 8).map((item) => (
<Link
key={item.href}
href={item.href}
@@ -157,22 +157,22 @@ export default function HomePageClient() {
</section>
{/* Testimonials Carousel */}
<TestimonialsCarousel testimonials={testimonials} />
<React.Fragment>
<StaticVsDynamic t={t} />
<ReprintCalculatorTeaser />
<Features t={t} />
</React.Fragment>
{/* Pricing Section */}
<Pricing t={t} />
{/* FAQ Section */}
<FAQ t={t} />
{/* Scroll to Top Button */}
<ScrollToTop />
</>
);
}
<TestimonialsCarousel testimonials={testimonials} />
<React.Fragment>
<StaticVsDynamic t={t} />
<ReprintCalculatorTeaser />
<Features t={t} />
</React.Fragment>
{/* Pricing Section */}
<Pricing t={t} />
{/* FAQ Section */}
<FAQ t={t} />
{/* Scroll to Top Button */}
<ScrollToTop />
</>
);
}

View File

@@ -0,0 +1,300 @@
'use client';
import React, { useState, useEffect } from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { Button } from '@/components/ui/Button';
import { Footer } from '@/components/ui/Footer';
import de from '@/i18n/de.json';
import { ChevronDown, Wifi, Contact, MessageCircle, Link2, Type, Mail, MessageSquare, Phone, Calendar, MapPin, Facebook, Instagram, Twitter, Youtube, Music, Bitcoin, CreditCard, Video, Users, Star, Barcode as BarcodeIcon } from 'lucide-react';
import { cn } from '@/lib/utils';
import { AnimatePresence, motion } from 'framer-motion';
import Image from 'next/image';
export default function MarketingLayout({
children,
}: {
children: React.ReactNode;
}) {
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const [scrolled, setScrolled] = useState(false);
const [toolsOpen, setToolsOpen] = useState(false);
const [mobileToolsOpen, setMobileToolsOpen] = useState(false);
const pathname = usePathname();
useEffect(() => {
const handleScroll = () => {
setScrolled(window.scrollY > 20);
};
// Check immediately on mount
handleScroll();
window.addEventListener('scroll', handleScroll, { passive: true });
return () => window.removeEventListener('scroll', handleScroll);
}, []);
// Close simple menus when path changes
useEffect(() => {
setMobileMenuOpen(false);
setToolsOpen(false);
}, [pathname]);
// Always German for this layout
const t = de;
const tools = [
{ name: 'URL / Link', description: 'Link to any website', href: '/tools/url-qr-code', icon: Link2, color: 'text-blue-500', bgColor: 'bg-blue-50' },
{ name: 'Text', description: 'Plain text message', href: '/tools/text-qr-code', icon: Type, color: 'text-slate-500', bgColor: 'bg-slate-50' },
{ name: 'WiFi', description: 'Share WiFi credentials', href: '/tools/wifi-qr-code', icon: Wifi, color: 'text-indigo-500', bgColor: 'bg-indigo-50' },
{ name: 'VCard', description: 'Digital business card', href: '/tools/vcard-qr-code', icon: Contact, color: 'text-pink-500', bgColor: 'bg-pink-50' },
{ name: 'WhatsApp', description: 'Start a chat', href: '/tools/whatsapp-qr-code', icon: MessageCircle, color: 'text-green-500', bgColor: 'bg-green-50' },
{ name: 'Email', description: 'Compose an email', href: '/tools/email-qr-code', icon: Mail, color: 'text-amber-500', bgColor: 'bg-amber-50' },
{ name: 'SMS', description: 'Send a text message', href: '/tools/sms-qr-code', icon: MessageSquare, color: 'text-cyan-500', bgColor: 'bg-cyan-50' },
{ name: 'Call', description: 'Anruf starten', href: '/tools/call-qr-code-generator', icon: Phone, color: 'text-violet-500', bgColor: 'bg-violet-50' },
{ name: 'Event', description: 'Add calendar event', href: '/tools/event-qr-code', icon: Calendar, color: 'text-red-500', bgColor: 'bg-red-50' },
{ name: 'Location', description: 'Share a place', href: '/tools/geolocation-qr-code', icon: MapPin, color: 'text-emerald-500', bgColor: 'bg-emerald-50' },
{ name: 'Facebook', description: 'Facebook profile/page', href: '/tools/facebook-qr-code', icon: Facebook, color: 'text-blue-600', bgColor: 'bg-blue-50' },
{ name: 'Instagram', description: 'Instagram profile', href: '/tools/instagram-qr-code', icon: Instagram, color: 'text-pink-600', bgColor: 'bg-pink-50' },
{ name: 'Twitter / X', description: 'Twitter profile', href: '/tools/twitter-qr-code', icon: Twitter, color: 'text-sky-500', bgColor: 'bg-sky-50' },
{ name: 'YouTube', description: 'YouTube video/channel', href: '/tools/youtube-qr-code', icon: Youtube, color: 'text-red-600', bgColor: 'bg-red-50' },
{ name: 'TikTok', description: 'TikTok profile', href: '/tools/tiktok-qr-code', icon: Music, color: 'text-slate-800', bgColor: 'bg-slate-100' },
{ name: 'Crypto', description: 'Share wallet address', href: '/tools/crypto-qr-code', icon: Bitcoin, color: 'text-orange-500', bgColor: 'bg-orange-50' },
{ name: 'PayPal', description: 'Receive payments', href: '/tools/paypal-qr-code', icon: CreditCard, color: 'text-blue-700', bgColor: 'bg-blue-50' },
{ name: 'Zoom', description: 'Join Zoom meeting', href: '/tools/zoom-qr-code', icon: Video, color: 'text-sky-500', bgColor: 'bg-sky-50' },
{ name: 'Teams', description: 'Join Teams meeting', href: '/tools/teams-qr-code', icon: Users, color: 'text-violet-500', bgColor: 'bg-violet-50' },
{ name: 'Google Bewertungen', description: 'Mehr Bewertungen sammeln', href: '/tools/google-review-qr-code', icon: Star, color: 'text-yellow-500', bgColor: 'bg-yellow-50' },
{ name: 'Barcode', description: 'Barcode erstellen', href: '/tools/barcode-generator', icon: BarcodeIcon, color: 'text-slate-800', bgColor: 'bg-slate-100' },
];
return (
<div className="min-h-screen bg-white">
{/* Server-rendered navigation links for SEO (crawlers) - Placed first for priority */}
<div className="sr-only" aria-hidden="false">
<nav aria-label="Seitenübersicht">
<ul>
<li><a href="/qr-code-erstellen">Startseite</a></li>
<li><a href="/de/preise">Preise</a></li>
<li><a href="/de/qr-codes-fuer-fitnessstudios">QR-Codes für Fitnessstudios</a></li>
<li><a href="/de/qr-codes-fuer-events">QR-Codes für Events</a></li>
<li><a href="/de/qr-codes-fuer-immobilienschilder">QR-Codes für Immobilienschilder</a></li>
<li><a href="/blog">Blog</a></li>
<li><a href="/faq">FAQ</a></li>
<li><a href="/login">Anmelden</a></li>
<li><a href="/signup">Registrieren</a></li>
{/* Tools */}
<li><a href="/tools/url-qr-code">URL QR Code</a></li>
<li><a href="/tools/text-qr-code">Text QR Code</a></li>
<li><a href="/tools/wifi-qr-code">WLAN QR Code</a></li>
<li><a href="/tools/vcard-qr-code">vCard QR Code</a></li>
<li><a href="/tools/whatsapp-qr-code">WhatsApp QR Code</a></li>
<li><a href="/tools/email-qr-code">Email QR Code</a></li>
<li><a href="/tools/sms-qr-code">SMS QR Code</a></li>
<li><a href="/tools/call-qr-code-generator">Call / Anruf QR Code</a></li>
<li><a href="/tools/event-qr-code">Event QR Code</a></li>
<li><a href="/tools/geolocation-qr-code">Standort QR Code</a></li>
<li><a href="/tools/facebook-qr-code">Facebook QR Code</a></li>
<li><a href="/tools/instagram-qr-code">Instagram QR Code</a></li>
<li><a href="/tools/twitter-qr-code">Twitter QR Code</a></li>
<li><a href="/tools/youtube-qr-code">YouTube QR Code</a></li>
<li><a href="/tools/tiktok-qr-code">TikTok QR Code</a></li>
<li><a href="/tools/crypto-qr-code">Crypto QR Code</a></li>
<li><a href="/tools/paypal-qr-code">PayPal QR Code</a></li>
<li><a href="/tools/zoom-qr-code">Zoom QR Code</a></li>
<li><a href="/tools/teams-qr-code">Teams QR Code</a></li>
<li><a href="/tools/google-review-qr-code">Google Bewertungen QR Code</a></li>
<li><a href="/tools/barcode-generator">Barcode Generator</a></li>
</ul>
</nav>
</div>
{/* Header */}
<header
className="fixed top-0 left-0 right-0 z-50 bg-white/80 backdrop-blur-md border-b border-slate-200 shadow-sm"
>
<nav className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl h-20 flex items-center justify-between">
{/* Logo */}
<Link href="/qr-code-erstellen" className="flex items-center space-x-3 group">
<div className="relative w-16 h-16 overflow-hidden rounded-full shadow-indigo-200 shadow-lg group-hover:scale-105 transition-transform duration-200">
<Image
src="/logo.svg"
alt="QR Master"
fill
sizes="64px"
className="object-cover"
priority
/>
</div>
<span className="text-xl font-bold text-slate-900 tracking-tight group-hover:text-indigo-600 transition-colors">QR Master</span>
</Link>
{/* Desktop Navigation */}
<div className="hidden md:flex items-center space-x-1">
{/* Tools Dropdown */}
<div
className="relative group px-3 py-2"
onMouseEnter={() => setToolsOpen(true)}
onMouseLeave={() => setToolsOpen(false)}
>
<button className="flex items-center space-x-1 text-sm font-medium text-slate-600 group-hover:text-slate-900 transition-colors">
<span>{t.nav.tools}</span>
<ChevronDown className={cn("w-4 h-4 transition-transform duration-200", toolsOpen && "rotate-180")} />
</button>
<AnimatePresence>
{toolsOpen && (
<motion.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 10 }}
transition={{ duration: 0.15 }}
className="absolute left-1/2 -translate-x-1/2 top-full mt-2 w-[750px] bg-white rounded-2xl shadow-lg border border-slate-100 p-4 overflow-hidden"
>
<div className="grid grid-cols-3 gap-1">
{tools.map((tool) => (
<Link
key={tool.name}
href={tool.href}
className="flex items-center space-x-3 p-2.5 rounded-xl transition-colors hover:bg-slate-50"
>
<div className={cn("p-2 rounded-lg shrink-0", tool.bgColor, tool.color)}>
<tool.icon className="w-4 h-4" />
</div>
<div>
<div className="text-sm font-semibold text-slate-900">{tool.name}</div>
<p className="text-xs text-slate-500 leading-snug">{tool.description}</p>
</div>
</Link>
))}
</div>
<div className="mt-3 pt-3 border-t border-slate-100 -mx-4 -mb-4 px-4 py-3 text-center bg-slate-50/50">
<p className="text-xs text-slate-500 font-medium">{t.nav.all_free}</p>
</div>
</motion.div>
)}
</AnimatePresence>
</div>
<Link href="/#features" className="px-3 py-2 text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">
{t.nav.features}
</Link>
<Link href="/de/preise" className="px-3 py-2 text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">
{t.nav.pricing}
</Link>
<Link href="/blog" className="px-3 py-2 text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">
{t.nav.blog}
</Link>
<Link href="/#faq" className="px-3 py-2 text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">
{t.nav.faq}
</Link>
</div>
<div className="hidden md:flex items-center space-x-4">
<Link href="/login" className="text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors">
{t.nav.login}
</Link>
<Link href="/signup">
<Button className={cn(
"font-semibold shadow-lg shadow-indigo-500/20 transition-all hover:scale-105",
scrolled ? "bg-blue-600 text-white hover:bg-blue-700" : "bg-blue-600 text-white hover:bg-blue-700"
)}>
{t.nav.cta || "Get Started Free"}
</Button>
</Link>
</div>
{/* Mobile Menu Button - Always dark */}
<button
className="md:hidden p-2 text-slate-900"
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
aria-label="Toggle menu"
>
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
{mobileMenuOpen ? (
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
) : (
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
)}
</svg>
</button>
</nav>
{/* Mobile Menu */}
<AnimatePresence>
{mobileMenuOpen && (
<motion.div
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: 'auto' }}
exit={{ opacity: 0, height: 0 }}
className="md:hidden bg-white border-b border-slate-100 overflow-hidden"
>
<div className="container mx-auto px-4 py-6 space-y-2">
{/* Free Tools Accordion */}
<button
onClick={() => setMobileToolsOpen(!mobileToolsOpen)}
className="flex items-center justify-between w-full px-4 py-3 rounded-xl hover:bg-slate-50 text-slate-700 font-semibold"
>
<span>{t.nav.tools}</span>
<ChevronDown className={cn("w-5 h-5 transition-transform", mobileToolsOpen && "rotate-180")} />
</button>
<AnimatePresence>
{mobileToolsOpen && (
<motion.div
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: 'auto' }}
exit={{ opacity: 0, height: 0 }}
className="overflow-hidden"
>
<div className="max-h-[50vh] overflow-y-auto pl-4 space-y-1 border-l-2 border-slate-100 ml-4">
{tools.map((tool) => (
<Link
key={tool.name}
href={tool.href}
className="flex items-center gap-3 px-4 py-2.5 rounded-lg hover:bg-slate-50 text-slate-600 text-sm"
onClick={() => { setMobileMenuOpen(false); setMobileToolsOpen(false); }}
>
<tool.icon className={cn("w-4 h-4", tool.color)} />
{tool.name}
</Link>
))}
</div>
</motion.div>
)}
</AnimatePresence>
<div className="h-px bg-slate-100 my-2"></div>
<Link href="/#features" className="block px-4 py-3 text-slate-700 font-medium rounded-xl hover:bg-slate-50" onClick={() => setMobileMenuOpen(false)}>{t.nav.features}</Link>
<Link href="/de/preise" className="block px-4 py-3 text-slate-700 font-medium rounded-xl hover:bg-slate-50" onClick={() => setMobileMenuOpen(false)}>{t.nav.pricing}</Link>
<Link href="/blog" className="block px-4 py-3 text-slate-700 font-medium rounded-xl hover:bg-slate-50" onClick={() => setMobileMenuOpen(false)}>{t.nav.blog}</Link>
<Link href="/#faq" className="block px-4 py-3 text-slate-700 font-medium rounded-xl hover:bg-slate-50" onClick={() => setMobileMenuOpen(false)}>{t.nav.faq}</Link>
<div className="grid grid-cols-2 gap-4 pt-4">
<Link href="/login" onClick={() => setMobileMenuOpen(false)}>
<Button variant="outline" className="w-full justify-center">{t.nav.login}</Button>
</Link>
<Link href="/signup" onClick={() => setMobileMenuOpen(false)}>
<Button className="w-full justify-center bg-indigo-600 hover:bg-indigo-700">{t.nav.cta}</Button>
</Link>
</div>
</div>
</motion.div>
)}
</AnimatePresence>
</header>
{/* Main Content */}
<main className="pt-20">
{children}
</main>
{/* Footer */}
<Footer t={t} />
</div >
);
}

View File

@@ -38,6 +38,40 @@ type LinkCard = {
description: string;
};
export type UseCaseTemplateLabels = {
badge: string;
subBenefits: { title: string; body: string }[];
nowLabel: string;
setupPreviewLabel: string;
comparisonLeftTitle: string;
comparisonRightTitle: string;
guidelinesEyebrow: string;
relatedResourcesTitle: string;
faqTitle?: string;
nextStepEyebrow: string;
ctaBannerTitle: string;
};
const defaultLabels: UseCaseTemplateLabels = {
badge: "Use Case",
subBenefits: [
{ title: "Print Stability", body: "Keep printed tables & flyers clean and permanent" },
{ title: "Instant Redirection", body: "Update links instantly without reprinting codes" },
{ title: "Attribution Flows", body: "Built-in campaign tracking and flow analysis" },
{ title: "Mobile Optimized", body: "Designed to load fast on mobile data connections" },
],
nowLabel: "now",
setupPreviewLabel: "Setup Preview",
comparisonLeftTitle: "Static QR",
comparisonRightTitle: "Dynamic QR",
guidelinesEyebrow: "Standard Guidelines",
relatedResourcesTitle: "Related resources",
nextStepEyebrow: "Next step",
ctaBannerTitle: "Start with a QR setup that keeps your print permanent.",
};
const subBenefitIcons = [ShieldCheck, RefreshCw, BarChart3, Zap];
type UseCasePageTemplateProps = {
title: string;
description: string;
@@ -78,16 +112,19 @@ type UseCasePageTemplateProps = {
authoritySignals?: string[];
directAnswer?: string;
schemaData?: Record<string, unknown>[];
labels?: UseCaseTemplateLabels;
};
export function buildUseCaseMetadata({
title,
description,
canonicalPath,
dePath,
}: {
title: string;
description: string;
canonicalPath: string;
dePath?: string;
}): Metadata {
const canonical = `https://www.qrmaster.net${canonicalPath}`;
@@ -101,6 +138,7 @@ export function buildUseCaseMetadata({
languages: {
"x-default": canonical,
en: canonical,
...(dePath ? { de: `https://www.qrmaster.net${dePath}` } : {}),
},
},
openGraph: {
@@ -395,6 +433,7 @@ export function UseCasePageTemplate({
authoritySignals = [],
directAnswer,
schemaData = [],
labels = defaultLabels,
}: UseCasePageTemplateProps) {
return (
<>
@@ -419,7 +458,7 @@ export function UseCasePageTemplate({
<div className="grid gap-16 lg:grid-cols-[1.15fr_0.85fr] lg:items-center">
<div className="space-y-8">
<div className="inline-flex items-center rounded-md border border-slate-200 bg-slate-50 px-3 py-1 text-xs font-semibold tracking-wider text-slate-500 uppercase shadow-sm">
<span>Use Case</span>
<span>{labels.badge}</span>
</div>
<div className="space-y-5">
@@ -433,12 +472,7 @@ export function UseCasePageTemplate({
{/* Sub-benefits (Styled as authentic, clean Framer-style Apple Notification banners) */}
<div className="grid gap-4 sm:grid-cols-2">
{[
{ title: "Print Stability", body: "Keep printed tables & flyers clean and permanent", icon: ShieldCheck },
{ title: "Instant Redirection", body: "Update links instantly without reprinting codes", icon: RefreshCw },
{ title: "Attribution Flows", body: "Built-in campaign tracking and flow analysis", icon: BarChart3 },
{ title: "Mobile Optimized", body: "Designed to load fast on mobile data connections", icon: Zap },
].map((item) => (
{labels.subBenefits.map((benefit, idx) => ({ ...benefit, icon: subBenefitIcons[idx % subBenefitIcons.length] })).map((item) => (
<div
key={item.title}
className="flex items-center gap-3.5 rounded-[1.25rem] bg-[#f4f4f5]/90 border border-slate-200/30 p-3.5 shadow-[0_8px_24px_rgba(0,0,0,0.02)] backdrop-blur-md transition-all duration-200 hover:scale-[1.01] hover:bg-[#f4f4f5]"
@@ -449,7 +483,7 @@ export function UseCasePageTemplate({
<div className="flex-1 min-w-0">
<div className="flex items-baseline justify-between">
<span className="text-[13px] font-semibold text-slate-900 truncate">{item.title}</span>
<span className="text-[10px] text-slate-400 font-medium shrink-0 ml-2">now</span>
<span className="text-[10px] text-slate-400 font-medium shrink-0 ml-2">{labels.nowLabel}</span>
</div>
<p className="text-[12px] text-slate-500 leading-snug mt-0.5">{item.body}</p>
</div>
@@ -502,7 +536,7 @@ export function UseCasePageTemplate({
<span className="w-2 h-2 rounded-full bg-rose-400/80" />
<span className="w-2 h-2 rounded-full bg-amber-400/80" />
<span className="w-2 h-2 rounded-full bg-emerald-400/80" />
<span className="text-[9px] text-slate-400 font-semibold ml-4 tracking-wide uppercase">Setup Preview</span>
<span className="text-[9px] text-slate-400 font-semibold ml-4 tracking-wide uppercase">{labels.setupPreviewLabel}</span>
</div>
{/* Visual Container */}
<div className="relative aspect-[4/3] overflow-hidden rounded-xl bg-slate-50/50">
@@ -536,8 +570,8 @@ export function UseCasePageTemplate({
whatIsIt={answer}
whenToUse={whenToUse}
comparison={{
leftTitle: "Static QR",
rightTitle: "Dynamic QR",
leftTitle: labels.comparisonLeftTitle,
rightTitle: labels.comparisonRightTitle,
items: comparisonItems,
}}
howTo={{
@@ -613,7 +647,7 @@ export function UseCasePageTemplate({
<div className="flex items-center justify-between gap-4 border-b border-slate-100 pb-5">
<div>
<div className="text-xs font-semibold uppercase tracking-wider text-slate-450">
Standard Guidelines
{labels.guidelinesEyebrow}
</div>
<h2 className="mt-2 text-2xl font-bold text-slate-900 sm:text-3xl -tracking-[0.02em]">
{checklistTitle}
@@ -645,7 +679,7 @@ export function UseCasePageTemplate({
<div className="flex h-10 w-10 items-center justify-center rounded-lg bg-slate-50 border border-slate-100 text-slate-550">
<Link2 className="h-5 w-5" />
</div>
<h2 className="text-2xl font-bold text-slate-900 sm:text-3xl -tracking-[0.02em]">Related resources</h2>
<h2 className="text-2xl font-bold text-slate-900 sm:text-3xl -tracking-[0.02em]">{labels.relatedResourcesTitle}</h2>
</div>
<div className="mt-6 space-y-4">
@@ -676,7 +710,7 @@ export function UseCasePageTemplate({
{/* FAQs */}
<div className="container mx-auto max-w-5xl px-4 pb-12 sm:px-6 lg:px-8">
<FAQSection items={faq} title={`${title} FAQ`} />
<FAQSection items={faq} title={labels.faqTitle ?? `${title} FAQ`} />
</div>
{/* Bottom CTA Banner (Flat light-gray card, no gradients) */}
@@ -686,10 +720,10 @@ export function UseCasePageTemplate({
<div className="relative z-10 flex flex-col gap-8 lg:flex-row lg:items-center lg:justify-between">
<div className="max-w-2xl space-y-3">
<div className="text-xs font-semibold uppercase tracking-wider text-slate-450">
Next step
{labels.nextStepEyebrow}
</div>
<h2 className="text-3xl font-bold tracking-tight sm:text-4xl -tracking-[0.02em] leading-tight text-slate-950">
Start with a QR setup that keeps your print permanent.
{labels.ctaBannerTitle}
</h2>
<p className="text-base leading-relaxed text-slate-500">
{description}

View File

@@ -1,7 +1,7 @@
import Link from 'next/link';
import en from '@/i18n/en.json';
import { Instagram, Twitter, Linkedin, Facebook } from 'lucide-react';
import { allUseCases } from '@/lib/growth-pages';
import { publishedUseCases } from '@/lib/growth-pages';
import { industryPages } from '@/lib/industry-pages';
interface FooterProps {
@@ -93,7 +93,7 @@ export function Footer({ variant = 'marketing', t }: FooterProps) {
<div>
<h3 className={`font-semibold mb-4 ${isDashboard ? 'text-gray-900' : ''}`}>Use Cases</h3>
<ul className={`space-y-2 ${isDashboard ? 'text-gray-500' : 'text-gray-400'}`}>
{allUseCases.map((uc) => (
{publishedUseCases.map((uc) => (
<li key={uc.slug}>
<Link href={uc.href} className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>
{uc.title}