Skip to content

Commit e2fa043

Browse files
mostlyerrorclaude
andcommitted
Add dedicated FAQ page and refine homepage layout
- New /faq page with masonry card grid, structured data, and dark-variant accordion - Consolidate homepage sections: merge "ready signals" + process into single dark panel - Move FAQ from homepage inline to a compact preview with link to full page - Add FAQ to nav, footer, sitemap, and smoke test routes - Bump base font size to 18px site-wide - Remove ownership FAQ item that didn't fit business model - Expand FAQ content with pricing, first-call, and industries questions Co-Authored-By: Claude Opus 4.6 <[email protected]>
1 parent 41167f6 commit e2fa043

10 files changed

Lines changed: 292 additions & 114 deletions

File tree

app/(main)/faq/page.tsx

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { Metadata } from 'next'
2+
import HeroSimple from '@/components/HeroSimple'
3+
import CTA from '@/components/CTA'
4+
import FAQMasonryGrid from '@/components/FAQMasonryGrid'
5+
import { JsonLd } from '@/components/JsonLd'
6+
import { MESSAGING } from '@/lib/messaging.constants'
7+
8+
export const metadata: Metadata = {
9+
title: 'FAQ | Good Robot Co.',
10+
description: 'Common questions about working with Good Robot Co. — pricing, process, timelines, AI, lead generation, and what to expect from a growth partnership.',
11+
openGraph: {
12+
title: 'FAQ | Good Robot Co.',
13+
description: 'Common questions about working with Good Robot Co. — pricing, process, timelines, AI, lead generation, and what to expect from a growth partnership.',
14+
url: 'https://goodrobotco.com/faq',
15+
type: 'website',
16+
images: [
17+
{
18+
url: '/og-image.png',
19+
width: 1200,
20+
height: 630,
21+
},
22+
],
23+
},
24+
}
25+
26+
export default function FAQPage() {
27+
const faqSchema = {
28+
'@context': 'https://schema.org',
29+
'@type': 'FAQPage',
30+
mainEntity: MESSAGING.faqItems.map((item) => ({
31+
'@type': 'Question',
32+
name: item.question,
33+
acceptedAnswer: {
34+
'@type': 'Answer',
35+
text: item.answer,
36+
},
37+
})),
38+
}
39+
40+
return (
41+
<>
42+
<JsonLd data={faqSchema} />
43+
44+
<HeroSimple
45+
label="FAQ"
46+
title="Questions, answered."
47+
subtitle="Everything you'd want to know before we start working together."
48+
/>
49+
50+
<section className="py-16 md:py-24 bg-cream">
51+
<div className="max-w-6xl mx-auto px-6 md:px-12">
52+
<FAQMasonryGrid items={MESSAGING.faqItems} />
53+
</div>
54+
</section>
55+
56+
<CTA
57+
headline="Still have questions?"
58+
subheadline="Book a free 20-minute call. I'll give you straight answers — no pitch, no pressure."
59+
/>
60+
</>
61+
)
62+
}

app/(main)/page.tsx

Lines changed: 90 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import Image from 'next/image'
44
import Link from 'next/link'
55
import { useEffect, useRef, useState } from 'react'
6-
import { JsonLd } from '@/components/JsonLd'
76
import { MESSAGING } from '@/lib/messaging.constants'
87
import { Reveal, useInView } from '@/components/Reveal'
98
import ContactForm from '@/components/ContactForm'
@@ -126,22 +125,8 @@ function AnimatedCounter({ end, suffix = '', prefix = '', duration = 2000, tickR
126125

127126
export default function Home() {
128127

129-
const faqSchema = {
130-
'@context': 'https://schema.org',
131-
'@type': 'FAQPage',
132-
mainEntity: MESSAGING.faqItems.slice(0, 4).map((item) => ({
133-
'@type': 'Question',
134-
name: item.question,
135-
acceptedAnswer: {
136-
'@type': 'Answer',
137-
text: item.answer,
138-
},
139-
})),
140-
}
141-
142128
return (
143129
<>
144-
<JsonLd data={faqSchema} />
145130
<div className="bg-cream min-h-screen">
146131

147132
{/* ══════════════════════════════════════
@@ -556,108 +541,87 @@ export default function Home() {
556541
</section>
557542

558543
{/* ══════════════════════════════════════
559-
9. PROCESS
544+
9. READY + PROCESS
560545
══════════════════════════════════════ */}
561-
<section className="py-20 md:py-28 bg-cream">
562-
<div className="max-w-4xl mx-auto px-6 md:px-12">
563-
<Reveal>
564-
<span className="text-xs font-bold tracking-[0.3em] uppercase text-coral block mb-4">How it works</span>
565-
<h2 className="text-3xl font-display font-bold text-charcoal mb-3">
566-
How this usually goes.
567-
</h2>
568-
<p className="text-charcoal-light mb-12">(Refreshingly uncomplicated.)</p>
569-
</Reveal>
570-
571-
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-5">
572-
{[
573-
{ n: '1', title: 'Strategy Session', desc: "20 min. You tell me what's holding your business back. I'll tell you if I can help.", color: 'bg-coral' },
574-
{ n: '2', title: 'Growth Audit', desc: 'I dig into your lead flow, sales process, and operations. You get a clear action plan.', color: 'bg-sage' },
575-
{ n: '3', title: 'Build & Launch', desc: 'I build the systems. Regular updates, no jargon. You see results fast.', color: 'bg-mustard' },
576-
{ n: '4', title: 'Grow Together', desc: "I don't disappear after launch. Continuous optimization and a partner invested in your growth.", color: 'bg-lavender' },
577-
].map((s, i) => (
578-
<Reveal key={s.n} delay={i * 0.08}>
579-
<div className={`${s.color} text-cream p-6 rounded-2xl text-center`}>
580-
<span className="text-4xl font-display font-black text-cream/20 block mb-2">{s.n}</span>
581-
<h3 className="font-bold text-lg mb-1">{s.title}</h3>
582-
<p className="text-cream/70 text-sm">{s.desc}</p>
583-
</div>
584-
</Reveal>
585-
))}
586-
</div>
546+
<section className="py-24 md:py-32 bg-charcoal text-cream relative overflow-hidden">
547+
<div className="absolute inset-0 pointer-events-none">
548+
<div className="absolute top-[30%] left-[5%] w-[400px] h-[400px] bg-sage/5 rounded-full blur-[150px]" />
549+
<div className="absolute bottom-[10%] right-[10%] w-[350px] h-[350px] bg-coral/5 rounded-full blur-[120px]" />
587550
</div>
588-
</section>
589551

590-
{/* ══════════════════════════════════════
591-
10. WHEN TO INVEST
592-
══════════════════════════════════════ */}
593-
<section className="py-24 md:py-32 bg-white">
594-
<div className="max-w-5xl mx-auto px-6 md:px-12">
552+
<div className="max-w-6xl mx-auto px-6 md:px-12 relative z-10">
595553
<Reveal>
596-
<span className="text-xs font-bold tracking-[0.3em] uppercase text-coral block mb-4">Not sure where to start?</span>
597-
<h2 className="text-3xl md:text-4xl font-display font-bold text-charcoal mb-14 text-center">
598-
When to invest in growth.
554+
<span className="text-xs font-bold tracking-[0.3em] uppercase text-coral block mb-4">Ready to grow?</span>
555+
<h2 className="text-3xl md:text-4xl font-display font-black text-cream mb-16">
556+
See yourself here? Here&apos;s how we fix it.
599557
</h2>
600558
</Reveal>
601559

602-
<div className="grid md:grid-cols-2 gap-6">
603-
{MESSAGING.investMatrix.map((category, i) => {
604-
const colorMap: Record<string, { gradient: string; text: string; check: string }> = {
605-
sage: { gradient: 'from-sage/10 to-sage/5', text: 'text-sage', check: 'text-sage' },
606-
sky: { gradient: 'from-sky/10 to-sky/5', text: 'text-sky', check: 'text-sky' },
607-
mustard: { gradient: 'from-mustard/10 to-mustard/5', text: 'text-mustard', check: 'text-mustard' },
608-
coral: { gradient: 'from-coral/10 to-coral/5', text: 'text-coral', check: 'text-coral' },
609-
}
610-
const colors = colorMap[category.color] || colorMap.sage
611-
return (
612-
<Reveal key={category.title} delay={i * 0.08}>
613-
<div className={`bg-gradient-to-br ${colors.gradient} p-8 rounded-2xl`}>
614-
<h3 className={`text-xl font-display font-bold mb-5 ${colors.text}`}>{category.title}</h3>
615-
<ul className="space-y-3">
616-
{category.items.map((item, j) => (
617-
<li key={j} className="flex items-start gap-3 text-charcoal-light text-sm">
618-
<span className={`${colors.check} mt-0.5 flex-shrink-0`}>&#x2713;</span>
619-
<span>{item}</span>
620-
</li>
621-
))}
622-
</ul>
623-
</div>
624-
</Reveal>
625-
)
626-
})}
627-
</div>
628-
629-
<Reveal delay={0.3}>
630-
<div className="text-center mt-12">
631-
<p className="text-charcoal-light mb-5">Not sure which approach fits your situation?</p>
632-
<Link href="#contact" className="inline-flex items-center gap-3 px-8 py-4 bg-coral text-white font-bold text-lg rounded-full shadow-xl shadow-coral/25 hover:-translate-y-1 hover:shadow-2xl transition-all duration-300">
633-
Let&apos;s Find Your Growth Lever &rarr;
634-
</Link>
635-
</div>
636-
</Reveal>
637-
</div>
638-
</section>
639-
640-
{/* ══════════════════════════════════════
641-
11. FAQ
642-
══════════════════════════════════════ */}
643-
<section className="py-24 md:py-32 bg-cream">
644-
<div className="max-w-4xl mx-auto px-6 md:px-12">
645-
<Reveal>
646-
<span className="text-xs font-bold tracking-[0.3em] uppercase text-coral block mb-4">Common questions</span>
647-
<h2 className="text-3xl md:text-4xl font-display font-bold text-charcoal mb-4 text-center">
648-
What most people want to know.
649-
</h2>
650-
<p className="text-charcoal-light text-center mb-14">Before we start working together.</p>
651-
</Reveal>
560+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-12">
561+
{/* Left column — readiness signals */}
562+
<Reveal>
563+
<div className="h-full">
564+
<div className="flex items-center gap-2.5 mb-8">
565+
<div className="w-2.5 h-2.5 rounded-full bg-coral animate-pulse" />
566+
<span className="text-sm font-bold text-cream/50 uppercase tracking-wider">You&apos;re ready if&hellip;</span>
567+
</div>
568+
<div className="space-y-4">
569+
{[
570+
{ title: 'Lead Gen', signal: 'You have no system to find your ideal customer — relying on word-of-mouth while competitors show up everywhere', dot: 'bg-sage', border: 'border-sage/20' },
571+
{ title: 'Sales Automation', signal: 'Leads go cold because follow-up takes too long and your team is doing data entry instead of selling', dot: 'bg-sky', border: 'border-sky/20' },
572+
{ title: 'Customer Retention', signal: 'You\'re chasing new customers but neglecting the ones who already trust you — sparse reviews, no re-engagement', dot: 'bg-mustard', border: 'border-mustard/20' },
573+
{ title: 'Operational Efficiency', signal: 'Your team spends hours on repetitive tasks that break when key people are out', dot: 'bg-coral', border: 'border-coral/20' },
574+
].map((item, i) => (
575+
<Reveal key={i} delay={i * 0.06}>
576+
<div className={`border-l-2 ${item.border} pl-5 py-3`}>
577+
<div className="flex items-center gap-2 mb-1.5">
578+
<div className={`w-2 h-2 rounded-full ${item.dot}`} />
579+
<span className="text-xs font-bold uppercase tracking-wider text-cream/40">{item.title}</span>
580+
</div>
581+
<p className="text-cream/70 text-[15px] leading-relaxed">{item.signal}</p>
582+
</div>
583+
</Reveal>
584+
))}
585+
</div>
586+
</div>
587+
</Reveal>
652588

653-
<Reveal delay={0.1}>
654-
<FAQAccordion items={MESSAGING.faqItems} />
655-
</Reveal>
589+
{/* Right column — process steps */}
590+
<Reveal delay={0.15}>
591+
<div className="h-full">
592+
<div className="flex items-center gap-2.5 mb-8">
593+
<div className="w-2.5 h-2.5 rounded-full bg-sage" />
594+
<span className="text-sm font-bold text-cream/50 uppercase tracking-wider">How this usually goes</span>
595+
</div>
596+
<div className="space-y-3">
597+
{[
598+
{ n: '01', title: 'Strategy Session', desc: "20 min. You tell me what's holding your business back. I'll tell you if I can help.", accent: 'text-coral' },
599+
{ n: '02', title: 'Growth Audit', desc: 'I dig into your lead flow, sales process, and operations. You get a clear action plan.', accent: 'text-sage' },
600+
{ n: '03', title: 'Build & Launch', desc: 'I build the systems. Regular updates, no jargon. You see results fast.', accent: 'text-mustard' },
601+
{ n: '04', title: 'Grow Together', desc: "I don't disappear after launch. Continuous optimization and a partner invested in your growth.", accent: 'text-lavender' },
602+
].map((s, i) => (
603+
<Reveal key={s.n} delay={0.15 + i * 0.06}>
604+
<div className="bg-white/5 border border-white/10 rounded-xl p-5 hover:bg-white/[0.08] transition-colors duration-300">
605+
<div className="flex items-start gap-4">
606+
<span className={`text-2xl font-display font-black ${s.accent} opacity-40 leading-none mt-0.5`}>{s.n}</span>
607+
<div>
608+
<h3 className="font-bold text-cream mb-1">{s.title}</h3>
609+
<p className="text-cream/50 text-sm leading-relaxed">{s.desc}</p>
610+
</div>
611+
</div>
612+
</div>
613+
</Reveal>
614+
))}
615+
</div>
616+
<p className="text-cream/25 text-sm mt-5 italic">(Refreshingly uncomplicated.)</p>
617+
</div>
618+
</Reveal>
619+
</div>
656620
</div>
657621
</section>
658622

659623
{/* ══════════════════════════════════════
660-
12. CTA + CONTACT
624+
10. CTA + CONTACT + FAQ
661625
══════════════════════════════════════ */}
662626
<section id="contact" className="py-28 md:py-40 bg-charcoal relative overflow-hidden">
663627
<div className="absolute inset-0 pointer-events-none">
@@ -724,6 +688,27 @@ export default function Home() {
724688
</div>
725689
</Reveal>
726690
</div>
691+
692+
<Reveal delay={0.3}>
693+
<div className="mt-20 pt-16 border-t border-white/10">
694+
<h3 className="text-2xl font-display font-bold text-cream mb-8 text-center">Before you decide&hellip;</h3>
695+
<div className="max-w-3xl mx-auto">
696+
<FAQAccordion
697+
items={[
698+
MESSAGING.faqItems[5], // "How quickly can I expect to see results?"
699+
MESSAGING.faqItems[2], // "Can AI actually help my business grow?"
700+
MESSAGING.faqItems[3], // "What does 'Growth Partnership' actually mean?"
701+
]}
702+
variant="dark"
703+
/>
704+
<p className="text-center mt-6">
705+
<Link href="/faq" className="text-cream/40 text-sm hover:text-cream transition-colors underline underline-offset-4 decoration-cream/20 hover:decoration-cream/50">
706+
More questions &rarr;
707+
</Link>
708+
</p>
709+
</div>
710+
</div>
711+
</Reveal>
727712
</div>
728713
</section>
729714

app/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export default function RootLayout({
5656
}) {
5757
return (
5858
<html lang="en" className={`${dmSans.variable} ${fraunces.variable}`}>
59-
<body className="bg-cream text-charcoal text-[17px] leading-relaxed overflow-x-hidden font-body">
59+
<body className="bg-cream text-charcoal text-[18px] leading-relaxed overflow-x-hidden font-body">
6060
{children}
6161
<Analytics />
6262
<SpeedInsights />

app/sitemap.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
3535
changeFrequency: 'monthly',
3636
priority: 0.9,
3737
},
38+
{
39+
url: `${SEO.baseUrl}/faq`,
40+
lastModified: new Date(),
41+
changeFrequency: 'monthly',
42+
priority: 0.6,
43+
},
3844
{
3945
url: `${SEO.baseUrl}/blog`,
4046
lastModified: new Date(),

components/FAQAccordion.tsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,43 @@ export interface FAQItem {
77
answer: string
88
}
99

10-
function FAQAccordionItem({ question, answer, isOpen, onToggle }: {
11-
question: string; answer: string; isOpen: boolean; onToggle: () => void
10+
function FAQAccordionItem({ question, answer, isOpen, onToggle, variant = 'light' }: {
11+
question: string; answer: string; isOpen: boolean; onToggle: () => void; variant?: 'light' | 'dark'
1212
}) {
13+
const isDark = variant === 'dark'
14+
1315
return (
14-
<div className={`bg-white border rounded-2xl overflow-hidden transition-all duration-300 ${isOpen ? 'border-coral shadow-lg' : 'border-charcoal/10 hover:border-charcoal/20'}`}>
16+
<div className={`rounded-2xl overflow-hidden transition-all duration-300 border ${
17+
isDark
18+
? isOpen ? 'bg-white/10 border-coral shadow-lg' : 'bg-white/5 border-white/10 hover:border-white/20'
19+
: isOpen ? 'bg-white border-coral shadow-lg' : 'bg-white border-charcoal/10 hover:border-charcoal/20'
20+
}`}>
1521
<button
1622
onClick={onToggle}
17-
className="w-full text-left p-6 flex items-center justify-between gap-4 hover:bg-cream/50 transition-colors duration-200 cursor-pointer"
23+
className={`w-full text-left p-6 flex items-center justify-between gap-4 transition-colors duration-200 cursor-pointer ${
24+
isDark ? 'hover:bg-white/5' : 'hover:bg-cream/50'
25+
}`}
1826
aria-expanded={isOpen}
1927
type="button"
2028
>
21-
<span className="font-semibold text-lg text-charcoal">{question}</span>
29+
<span className={`font-semibold text-lg ${isDark ? 'text-cream' : 'text-charcoal'}`}>{question}</span>
2230
<svg
2331
className={`w-6 h-6 flex-shrink-0 text-coral transition-transform duration-300 ${isOpen ? 'rotate-180' : ''}`}
2432
fill="none" stroke="currentColor" viewBox="0 0 24 24"
2533
>
2634
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
2735
</svg>
2836
</button>
29-
<div className={`px-6 text-charcoal-light leading-relaxed transition-all duration-300 overflow-hidden ${isOpen ? 'pb-6 max-h-96 opacity-100' : 'max-h-0 opacity-0'}`}>
37+
<div className={`px-6 leading-relaxed transition-all duration-300 overflow-hidden ${
38+
isDark ? 'text-cream/70' : 'text-charcoal-light'
39+
} ${isOpen ? 'pb-6 max-h-96 opacity-100' : 'max-h-0 opacity-0'}`}>
3040
{answer}
3141
</div>
3242
</div>
3343
)
3444
}
3545

36-
export default function FAQAccordion({ items }: { items: readonly FAQItem[] }) {
46+
export default function FAQAccordion({ items, variant = 'light' }: { items: readonly FAQItem[]; variant?: 'light' | 'dark' }) {
3747
const [openIndex, setOpenIndex] = useState<number | null>(null)
3848

3949
return (
@@ -45,6 +55,7 @@ export default function FAQAccordion({ items }: { items: readonly FAQItem[] }) {
4555
answer={faq.answer}
4656
isOpen={openIndex === i}
4757
onToggle={() => setOpenIndex(openIndex === i ? null : i)}
58+
variant={variant}
4859
/>
4960
))}
5061
</div>

0 commit comments

Comments
 (0)