Strip template feel from features + simplify CTA section
Features: remove Card containers and circular icon backgrounds. Clean icon (brand colour) + heading + description in open grid. Feels authentic, not template-generated. CTA: remove warm bg, use default surface with subtle divider above. Heading in display3, understated placement between testimonials and FAQ. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,8 +12,8 @@ import StarBorderIcon from '@mui/icons-material/StarBorder';
|
|||||||
import type { SxProps, Theme } from '@mui/material/styles';
|
import type { SxProps, Theme } from '@mui/material/styles';
|
||||||
import { Typography } from '../../atoms/Typography';
|
import { Typography } from '../../atoms/Typography';
|
||||||
import { Button } from '../../atoms/Button';
|
import { Button } from '../../atoms/Button';
|
||||||
import { Card } from '../../atoms/Card';
|
|
||||||
import { ProviderCardCompact } from '../../molecules/ProviderCardCompact';
|
import { ProviderCardCompact } from '../../molecules/ProviderCardCompact';
|
||||||
|
import { Divider } from '../../atoms/Divider';
|
||||||
import { FuneralFinderV3, type FuneralFinderV3SearchParams } from '../../organisms/FuneralFinder';
|
import { FuneralFinderV3, type FuneralFinderV3SearchParams } from '../../organisms/FuneralFinder';
|
||||||
|
|
||||||
// ─── Types ───────────────────────────────────────────────────────────────────
|
// ─── Types ───────────────────────────────────────────────────────────────────
|
||||||
@@ -102,6 +102,10 @@ export interface HomePageProps {
|
|||||||
|
|
||||||
/** Feature cards for "Why Use FA" */
|
/** Feature cards for "Why Use FA" */
|
||||||
features?: FeatureCard[];
|
features?: FeatureCard[];
|
||||||
|
/** Features section heading */
|
||||||
|
featuresHeading?: string;
|
||||||
|
/** Features section body text */
|
||||||
|
featuresBody?: string;
|
||||||
|
|
||||||
/** Aggregate Google rating */
|
/** Aggregate Google rating */
|
||||||
googleRating?: number;
|
googleRating?: number;
|
||||||
@@ -178,6 +182,8 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
|||||||
discoverMapSlot,
|
discoverMapSlot,
|
||||||
onSelectFeaturedProvider,
|
onSelectFeaturedProvider,
|
||||||
features = [],
|
features = [],
|
||||||
|
featuresHeading = 'How it works',
|
||||||
|
featuresBody = 'Search local funeral directors, compare transparent pricing, and personalise a plan — all in your own time. No pressure, no hidden costs.',
|
||||||
googleRating,
|
googleRating,
|
||||||
googleReviewCount,
|
googleReviewCount,
|
||||||
testimonials = [],
|
testimonials = [],
|
||||||
@@ -404,15 +410,15 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
|||||||
display: 'grid',
|
display: 'grid',
|
||||||
gridTemplateColumns: { xs: '1fr', md: '1fr 1fr' },
|
gridTemplateColumns: { xs: '1fr', md: '1fr 1fr' },
|
||||||
gap: 3,
|
gap: 3,
|
||||||
alignItems: 'start',
|
alignItems: 'stretch',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Map placeholder */}
|
{/* Map placeholder — stretches to match card stack */}
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
minHeight: { xs: 240, md: 400 },
|
minHeight: { xs: 240, md: 0 },
|
||||||
bgcolor: 'var(--fa-color-surface-cool)',
|
bgcolor: 'var(--fa-color-surface-cool)',
|
||||||
border: '1px solid',
|
border: '1px solid',
|
||||||
borderColor: 'divider',
|
borderColor: 'divider',
|
||||||
@@ -447,6 +453,13 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
|||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
{/* CTA */}
|
||||||
|
<Box sx={{ textAlign: 'center', mt: 4 }}>
|
||||||
|
<Button variant="text" size="medium" onClick={onCtaClick}>
|
||||||
|
Start exploring →
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
</Container>
|
</Container>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
@@ -556,28 +569,19 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
|||||||
<Container maxWidth="lg">
|
<Container maxWidth="lg">
|
||||||
<Box sx={{ textAlign: 'center', mb: { xs: 4, md: 6 } }}>
|
<Box sx={{ textAlign: 'center', mb: { xs: 4, md: 6 } }}>
|
||||||
<Typography
|
<Typography
|
||||||
variant="overline"
|
variant="display3"
|
||||||
sx={{ color: 'var(--fa-color-text-brand)', mb: 1.5, display: 'block' }}
|
|
||||||
>
|
|
||||||
Why use Funeral Arranger
|
|
||||||
</Typography>
|
|
||||||
<Typography
|
|
||||||
variant="h2"
|
|
||||||
component="h2"
|
component="h2"
|
||||||
id="features-heading"
|
id="features-heading"
|
||||||
sx={{ mb: 2, color: 'text.primary' }}
|
sx={{ mb: 2, color: 'text.primary' }}
|
||||||
>
|
>
|
||||||
Making an impossible time a little easier
|
{featuresHeading}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography
|
<Typography
|
||||||
variant="body2"
|
variant="body1"
|
||||||
color="text.secondary"
|
color="text.secondary"
|
||||||
sx={{ maxWidth: 560, mx: 'auto' }}
|
sx={{ maxWidth: 560, mx: 'auto' }}
|
||||||
>
|
>
|
||||||
Funeral planning doesn't have to be overwhelming. Whether a loved one has
|
{featuresBody}
|
||||||
just passed, is imminent, or you're pre-planning for the future. Compare
|
|
||||||
transparent pricing from local funeral directors. Explore the service options,
|
|
||||||
coffins and more to personalise a funeral plan in clear, easy steps.
|
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
@@ -589,41 +593,27 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
|||||||
sm: 'repeat(2, 1fr)',
|
sm: 'repeat(2, 1fr)',
|
||||||
md: 'repeat(4, 1fr)',
|
md: 'repeat(4, 1fr)',
|
||||||
},
|
},
|
||||||
gap: { xs: 3, md: 3 },
|
gap: { xs: 4, md: 5 },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{features.map((feature) => (
|
{features.map((feature) => (
|
||||||
<Card key={feature.heading} variant="outlined" padding="compact">
|
<Box key={feature.heading} sx={{ textAlign: 'center' }}>
|
||||||
<Box sx={{ textAlign: 'center' }}>
|
<Box
|
||||||
<Box
|
sx={{
|
||||||
sx={{
|
mb: 2,
|
||||||
mb: 1.5,
|
color: 'primary.main',
|
||||||
mx: 'auto',
|
'& svg': { fontSize: 32 },
|
||||||
width: 56,
|
}}
|
||||||
height: 56,
|
>
|
||||||
borderRadius: '50%',
|
{feature.icon}
|
||||||
bgcolor: 'var(--fa-color-brand-50)',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
color: 'primary.main',
|
|
||||||
'& svg': { fontSize: 28 },
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{feature.icon}
|
|
||||||
</Box>
|
|
||||||
<Typography
|
|
||||||
variant="h5"
|
|
||||||
component="h3"
|
|
||||||
sx={{ mb: 1, color: 'text.primary' }}
|
|
||||||
>
|
|
||||||
{feature.heading}
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
{feature.description}
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Card>
|
<Typography variant="h6" component="h3" sx={{ mb: 1, color: 'text.primary' }}>
|
||||||
|
{feature.heading}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" color="text.secondary">
|
||||||
|
{feature.description}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
</Container>
|
</Container>
|
||||||
@@ -639,17 +629,17 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
|||||||
aria-labelledby="reviews-heading"
|
aria-labelledby="reviews-heading"
|
||||||
sx={{
|
sx={{
|
||||||
py: { xs: 6, md: 10 },
|
py: { xs: 6, md: 10 },
|
||||||
bgcolor: 'var(--fa-color-surface-warm)',
|
bgcolor: 'var(--fa-color-surface-subtle)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Container maxWidth="md">
|
<Container maxWidth="md">
|
||||||
<Typography
|
<Typography
|
||||||
variant="h2"
|
variant="display3"
|
||||||
component="h2"
|
component="h2"
|
||||||
id="reviews-heading"
|
id="reviews-heading"
|
||||||
sx={{ textAlign: 'center', mb: 1, color: 'text.primary' }}
|
sx={{ textAlign: 'center', mb: 1, color: 'text.primary' }}
|
||||||
>
|
>
|
||||||
Testimonials
|
What families are saying
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
{googleRating != null && (
|
{googleRating != null && (
|
||||||
@@ -673,55 +663,57 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
|||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Editorial testimonials — alternating alignment */}
|
{/* Editorial testimonials — alternating alignment with dividers */}
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
|
||||||
{testimonials.map((t, i) => {
|
{testimonials.map((t, i) => {
|
||||||
const isRight = i % 2 === 1;
|
const isRight = i % 2 === 1;
|
||||||
return (
|
return (
|
||||||
<Box
|
<React.Fragment key={`${t.name}-${i}`}>
|
||||||
key={`${t.name}-${i}`}
|
{i > 0 && <Divider sx={{ my: 4 }} />}
|
||||||
sx={{
|
|
||||||
textAlign: isRight ? 'right' : 'left',
|
|
||||||
maxWidth: '85%',
|
|
||||||
ml: isRight ? 'auto' : 0,
|
|
||||||
mr: isRight ? 0 : 'auto',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<FormatQuoteIcon
|
|
||||||
sx={{
|
|
||||||
fontSize: 32,
|
|
||||||
color: 'var(--fa-color-brand-300)',
|
|
||||||
transform: isRight ? 'scaleX(-1)' : 'none',
|
|
||||||
mb: 1,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Typography
|
|
||||||
variant="h5"
|
|
||||||
component="blockquote"
|
|
||||||
sx={{ mb: 2, fontWeight: 400 }}
|
|
||||||
>
|
|
||||||
{t.quote}
|
|
||||||
</Typography>
|
|
||||||
<Typography
|
|
||||||
variant="label"
|
|
||||||
component="cite"
|
|
||||||
sx={{ fontStyle: 'normal', display: 'block', mb: 0.5 }}
|
|
||||||
>
|
|
||||||
{t.name}
|
|
||||||
</Typography>
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: 'inline-flex',
|
textAlign: isRight ? 'right' : 'left',
|
||||||
alignItems: 'center',
|
maxWidth: '85%',
|
||||||
gap: 1,
|
ml: isRight ? 'auto' : 0,
|
||||||
|
mr: isRight ? 0 : 'auto',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<StarRating rating={t.rating} size={12} />
|
<FormatQuoteIcon
|
||||||
<Typography variant="caption" color="text.secondary">
|
sx={{
|
||||||
· {t.timeAgo}
|
fontSize: 32,
|
||||||
|
color: 'var(--fa-color-brand-300)',
|
||||||
|
transform: isRight ? 'scaleX(-1)' : 'none',
|
||||||
|
mb: 1,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Typography
|
||||||
|
variant="h5"
|
||||||
|
component="blockquote"
|
||||||
|
sx={{ mb: 2, fontWeight: 400 }}
|
||||||
|
>
|
||||||
|
{t.quote}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<Typography
|
||||||
|
variant="label"
|
||||||
|
component="cite"
|
||||||
|
sx={{ fontStyle: 'normal', display: 'block', mb: 0.5 }}
|
||||||
|
>
|
||||||
|
{t.name}
|
||||||
|
</Typography>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'inline-flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<StarRating rating={t.rating} size={12} />
|
||||||
|
<Typography variant="caption" color="text.secondary">
|
||||||
|
· {t.timeAgo}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Box>
|
</Box>
|
||||||
@@ -736,16 +728,16 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
|||||||
component="section"
|
component="section"
|
||||||
aria-labelledby="cta-heading"
|
aria-labelledby="cta-heading"
|
||||||
sx={{
|
sx={{
|
||||||
bgcolor: 'var(--fa-color-surface-warm)',
|
py: { xs: 6, md: 8 },
|
||||||
py: { xs: 6, md: 10 },
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Container maxWidth="lg" sx={{ textAlign: 'center' }}>
|
<Container maxWidth="sm" sx={{ textAlign: 'center' }}>
|
||||||
|
<Divider sx={{ mb: { xs: 5, md: 6 } }} />
|
||||||
<Typography
|
<Typography
|
||||||
variant="displaySm"
|
variant="display3"
|
||||||
component="h2"
|
component="h2"
|
||||||
id="cta-heading"
|
id="cta-heading"
|
||||||
sx={{ mb: 3, color: 'text.primary', maxWidth: 500, mx: 'auto' }}
|
sx={{ mb: 3, color: 'text.primary' }}
|
||||||
>
|
>
|
||||||
{ctaHeading}
|
{ctaHeading}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|||||||
Reference in New Issue
Block a user