Promote HomePage V3 to production, redesign layout and refine FuneralFinder
Homepage: add "Why Use FA" text+image section and "Three Ways" feature cards, reorder sections (logos carousel above discover), apply warm-grey alternating backgrounds from Figma, unify all section headings to display3 serif, increase section padding, fix heading hierarchy for SEO, and left-align testimonials. FuneralFinder V3: responsive CTA (medium on mobile), shorten button to "Search", bump reassurance text to caption variant, tighten location pin-to-text gap. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -561,7 +561,7 @@ export const FuneralFinderV3 = React.forwardRef<HTMLDivElement, FuneralFinderV3P
|
||||
placeholder="Enter suburb or postcode"
|
||||
inputRef={locationInputRef}
|
||||
startAdornment={
|
||||
<InputAdornment position="start" sx={{ ml: 0.5 }}>
|
||||
<InputAdornment position="start" sx={{ ml: 0.25, mr: -0.5 }}>
|
||||
<LocationOnOutlinedIcon
|
||||
sx={{
|
||||
fontSize: 20,
|
||||
@@ -577,6 +577,7 @@ export const FuneralFinderV3 = React.forwardRef<HTMLDivElement, FuneralFinderV3P
|
||||
...fieldBaseSx,
|
||||
'& .MuiOutlinedInput-input': {
|
||||
...fieldInputStyles,
|
||||
pl: 0.75,
|
||||
'&::placeholder': {
|
||||
color: 'var(--fa-color-text-disabled)',
|
||||
opacity: 1,
|
||||
@@ -617,12 +618,12 @@ export const FuneralFinderV3 = React.forwardRef<HTMLDivElement, FuneralFinderV3P
|
||||
loading={loading}
|
||||
endIcon={!loading ? <ArrowForwardIcon /> : undefined}
|
||||
onClick={handleSubmit}
|
||||
sx={{ minHeight: 52 }}
|
||||
sx={{ minHeight: { xs: 40, sm: 52 }, fontSize: { xs: '0.875rem', sm: undefined } }}
|
||||
>
|
||||
Search Local Providers
|
||||
Search
|
||||
</Button>
|
||||
<Typography
|
||||
variant="captionSm"
|
||||
variant="caption"
|
||||
color="text.secondary"
|
||||
sx={{ textAlign: 'center', display: 'block', mt: 1.5 }}
|
||||
>
|
||||
|
||||
@@ -380,16 +380,109 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
||||
)}
|
||||
|
||||
{/* ═══════════════════════════════════════════════════════════════════
|
||||
Section 2c: Discover — Map + Featured Providers (V2)
|
||||
Section 2b: Partner Logos Carousel
|
||||
═══════════════════════════════════════════════════════════════════ */}
|
||||
{partnerLogos.length > 0 && (
|
||||
<Box
|
||||
component="section"
|
||||
aria-labelledby="partners-heading"
|
||||
sx={{
|
||||
bgcolor: 'var(--fa-color-surface-default)',
|
||||
borderBottom: '1px solid #ebe0d4',
|
||||
pt: { xs: 22, md: 28 },
|
||||
pb: { xs: 10, md: 14 },
|
||||
}}
|
||||
>
|
||||
<Container maxWidth="lg">
|
||||
<Typography
|
||||
variant="overline"
|
||||
component="h2"
|
||||
id="partners-heading"
|
||||
sx={{
|
||||
textAlign: 'center',
|
||||
color: 'var(--fa-color-brand-600)',
|
||||
mb: { xs: 6, md: 10 },
|
||||
}}
|
||||
>
|
||||
{partnerTrustLine}
|
||||
</Typography>
|
||||
</Container>
|
||||
|
||||
{/* Carousel track */}
|
||||
<Box
|
||||
role="presentation"
|
||||
sx={{
|
||||
overflow: 'hidden',
|
||||
position: 'relative',
|
||||
'&::before, &::after': {
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
width: 80,
|
||||
zIndex: 1,
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
'&::before': {
|
||||
left: 0,
|
||||
background: 'linear-gradient(to right, #fff, transparent)',
|
||||
},
|
||||
'&::after': {
|
||||
right: 0,
|
||||
background: 'linear-gradient(to left, #fff, transparent)',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
aria-label="Partner funeral directors"
|
||||
sx={{
|
||||
display: 'flex',
|
||||
gap: { xs: 8, md: 12 },
|
||||
alignItems: 'center',
|
||||
width: 'max-content',
|
||||
animation: 'logoScroll 35s linear infinite',
|
||||
'@keyframes logoScroll': {
|
||||
'0%': { transform: 'translateX(0)' },
|
||||
'100%': { transform: 'translateX(-50%)' },
|
||||
},
|
||||
'&:hover': { animationPlayState: 'paused' },
|
||||
'@media (prefers-reduced-motion: reduce)': { animation: 'none' },
|
||||
}}
|
||||
>
|
||||
{[...partnerLogos, ...partnerLogos].map((logo, i) => (
|
||||
<Box
|
||||
key={`${logo.alt}-${i}`}
|
||||
component="img"
|
||||
src={logo.src}
|
||||
alt={i < partnerLogos.length ? logo.alt : ''}
|
||||
aria-hidden={i >= partnerLogos.length ? true : undefined}
|
||||
sx={{
|
||||
height: { xs: 46, md: 55 },
|
||||
maxWidth: { xs: 140, md: 184 },
|
||||
width: 'auto',
|
||||
objectFit: 'contain',
|
||||
filter: 'grayscale(100%) brightness(1.2)',
|
||||
opacity: 0.4,
|
||||
flexShrink: 0,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* ═══════════════════════════════════════════════════════════════════
|
||||
Section 2c: Discover — Map + Featured Providers
|
||||
═══════════════════════════════════════════════════════════════════ */}
|
||||
{featuredProviders.length > 0 && (
|
||||
<Box
|
||||
component="section"
|
||||
aria-labelledby="discover-heading"
|
||||
sx={{
|
||||
bgcolor: 'var(--fa-color-surface-subtle)',
|
||||
pt: { xs: 22, md: 28 },
|
||||
pb: { xs: 8, md: 12 },
|
||||
bgcolor: '#fdfbf9',
|
||||
pt: { xs: 10, md: 14 },
|
||||
pb: { xs: 10, md: 14 },
|
||||
}}
|
||||
>
|
||||
<Container maxWidth="lg">
|
||||
@@ -486,93 +579,208 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
||||
)}
|
||||
|
||||
{/* ═══════════════════════════════════════════════════════════════════
|
||||
Section 3: Partner Logos Carousel
|
||||
Section 3b: Why Use FA — Text + Image
|
||||
═══════════════════════════════════════════════════════════════════ */}
|
||||
{partnerLogos.length > 0 && (
|
||||
<Box
|
||||
component="section"
|
||||
aria-label="Trusted partners"
|
||||
aria-labelledby="why-fa-heading"
|
||||
sx={{
|
||||
bgcolor: 'var(--fa-color-surface-cool)',
|
||||
pt: { xs: 10, md: 13 },
|
||||
pb: { xs: 8, md: 10 },
|
||||
bgcolor: 'var(--fa-color-surface-default)',
|
||||
borderTop: '1px solid #f3efea',
|
||||
borderBottom: '1px solid #f3efea',
|
||||
py: { xs: 10, md: 14 },
|
||||
}}
|
||||
>
|
||||
<Container maxWidth="lg">
|
||||
<Typography
|
||||
variant="body1"
|
||||
color="text.secondary"
|
||||
sx={{ textAlign: 'center', mb: { xs: 4, md: 6 } }}
|
||||
>
|
||||
{partnerTrustLine}
|
||||
</Typography>
|
||||
</Container>
|
||||
|
||||
{/* Carousel track */}
|
||||
<Box
|
||||
role="presentation"
|
||||
sx={{
|
||||
overflow: 'hidden',
|
||||
position: 'relative',
|
||||
'&::before, &::after': {
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
width: 80,
|
||||
zIndex: 1,
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
'&::before': {
|
||||
left: 0,
|
||||
background:
|
||||
'linear-gradient(to right, var(--fa-color-surface-cool), transparent)',
|
||||
},
|
||||
'&::after': {
|
||||
right: 0,
|
||||
background:
|
||||
'linear-gradient(to left, var(--fa-color-surface-cool), transparent)',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
aria-label="Partner funeral directors"
|
||||
sx={{
|
||||
display: 'flex',
|
||||
gap: { xs: 8, md: 12 },
|
||||
display: 'grid',
|
||||
gridTemplateColumns: { xs: '1fr', md: '1fr 1fr' },
|
||||
gap: { xs: 4, md: 8 },
|
||||
alignItems: 'center',
|
||||
width: 'max-content',
|
||||
animation: 'logoScroll 35s linear infinite',
|
||||
'@keyframes logoScroll': {
|
||||
'0%': { transform: 'translateX(0)' },
|
||||
'100%': { transform: 'translateX(-50%)' },
|
||||
},
|
||||
'&:hover': { animationPlayState: 'paused' },
|
||||
'@media (prefers-reduced-motion: reduce)': { animation: 'none' },
|
||||
}}
|
||||
>
|
||||
{[...partnerLogos, ...partnerLogos].map((logo, i) => (
|
||||
{/* Text */}
|
||||
<Box>
|
||||
<Typography
|
||||
variant="overline"
|
||||
component="div"
|
||||
sx={{ color: 'var(--fa-color-brand-600)', mb: 1.5 }}
|
||||
>
|
||||
Why Use Funeral Arranger
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="display3"
|
||||
component="h2"
|
||||
id="why-fa-heading"
|
||||
sx={{ mb: 2.5, color: 'text.primary' }}
|
||||
>
|
||||
Making an impossible time a little easier
|
||||
</Typography>
|
||||
<Typography variant="body1" color="text.secondary">
|
||||
Funeral planning doesn’t have to be overwhelming. Whether a loved one has
|
||||
just passed, is imminent, or you’re pre-planning the future for yourself.
|
||||
Compare transparent pricing from local funeral directors. Explore the service
|
||||
options, coffins and more to personalise a funeral plan in clear, easy steps.
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
{/* Image */}
|
||||
<Box
|
||||
key={`${logo.alt}-${i}`}
|
||||
component="img"
|
||||
src={logo.src}
|
||||
alt={i < partnerLogos.length ? logo.alt : ''}
|
||||
aria-hidden={i >= partnerLogos.length ? true : undefined}
|
||||
sx={{
|
||||
height: { xs: 46, md: 55 },
|
||||
maxWidth: { xs: 140, md: 184 },
|
||||
width: 'auto',
|
||||
objectFit: 'contain',
|
||||
filter: 'grayscale(100%) brightness(1.2)',
|
||||
opacity: 0.4,
|
||||
flexShrink: 0,
|
||||
borderRadius: 'var(--fa-border-radius-lg, 12px)',
|
||||
overflow: 'hidden',
|
||||
'& img': {
|
||||
width: '100%',
|
||||
height: 'auto',
|
||||
display: 'block',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src="/brandassets/images/Homepage/people.png"
|
||||
alt="Family planning together with care and confidence"
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</Container>
|
||||
</Box>
|
||||
|
||||
{/* ═══════════════════════════════════════════════════════════════════
|
||||
Section 3c: What You Can Do Here — Three Feature Cards
|
||||
═══════════════════════════════════════════════════════════════════ */}
|
||||
<Box
|
||||
component="section"
|
||||
aria-labelledby="what-you-can-do-heading"
|
||||
sx={{
|
||||
bgcolor: '#f8f5f1',
|
||||
py: { xs: 10, md: 14 },
|
||||
}}
|
||||
>
|
||||
<Container maxWidth="lg">
|
||||
<Box sx={{ textAlign: 'center', mb: { xs: 5, md: 8 } }}>
|
||||
<Typography
|
||||
variant="overline"
|
||||
component="div"
|
||||
sx={{ color: 'var(--fa-color-brand-600)', mb: 1.5 }}
|
||||
>
|
||||
What You Can Do Here
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="display3"
|
||||
component="h2"
|
||||
id="what-you-can-do-heading"
|
||||
sx={{ color: 'text.primary' }}
|
||||
>
|
||||
Three ways we can help you today
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: { xs: '1fr', md: 'repeat(3, 1fr)' },
|
||||
gap: { xs: 3, md: 4 },
|
||||
}}
|
||||
>
|
||||
{/* Card 1: Compare pricing */}
|
||||
<Box
|
||||
sx={{
|
||||
bgcolor: 'var(--fa-color-surface-default)',
|
||||
borderRadius: 'var(--fa-card-border-radius-default, 8px)',
|
||||
boxShadow: 'var(--fa-shadow-md)',
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
height: 200,
|
||||
background:
|
||||
'linear-gradient(135deg, var(--fa-color-brand-100) 0%, var(--fa-color-brand-200) 100%)',
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
<Box sx={{ p: 3, flex: 1, display: 'flex', flexDirection: 'column' }}>
|
||||
<Typography variant="h5" component="h3" sx={{ mb: 1.5, color: 'text.primary' }}>
|
||||
Compare pricing
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 3, flex: 1 }}>
|
||||
See verified, itemised prices from multiple funeral directors in your area
|
||||
side by side.
|
||||
</Typography>
|
||||
<Button variant="outlined" size="medium" fullWidth>
|
||||
Compare prices in my area
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{/* Card 2: Find a funeral director */}
|
||||
<Box
|
||||
sx={{
|
||||
bgcolor: 'var(--fa-color-surface-default)',
|
||||
borderRadius: 'var(--fa-card-border-radius-default, 8px)',
|
||||
boxShadow: 'var(--fa-shadow-md)',
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
height: 200,
|
||||
background:
|
||||
'linear-gradient(135deg, var(--fa-color-sage-100, #E8EDEF) 0%, var(--fa-color-sage-200, #D0D8DD) 100%)',
|
||||
}}
|
||||
/>
|
||||
<Box sx={{ p: 3, flex: 1, display: 'flex', flexDirection: 'column' }}>
|
||||
<Typography variant="h5" component="h3" sx={{ mb: 1.5, color: 'text.primary' }}>
|
||||
Find a funeral director
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 3, flex: 1 }}>
|
||||
Browse rated, reviewed directors near you with profiles, photos, and contact
|
||||
details.
|
||||
</Typography>
|
||||
<Button variant="outlined" size="medium" fullWidth>
|
||||
Search near me
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{/* Card 3: Arrange a funeral */}
|
||||
<Box
|
||||
sx={{
|
||||
bgcolor: 'var(--fa-color-surface-default)',
|
||||
borderRadius: 'var(--fa-card-border-radius-default, 8px)',
|
||||
boxShadow: 'var(--fa-shadow-md)',
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
height: 200,
|
||||
background:
|
||||
'linear-gradient(135deg, var(--fa-color-neutral-100) 0%, var(--fa-color-neutral-200) 100%)',
|
||||
}}
|
||||
/>
|
||||
<Box sx={{ p: 3, flex: 1, display: 'flex', flexDirection: 'column' }}>
|
||||
<Typography variant="h5" component="h3" sx={{ mb: 1.5, color: 'text.primary' }}>
|
||||
Arrange a funeral
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 3, flex: 1 }}>
|
||||
Build a fully customised quote — choose coffin, flowers, transport,
|
||||
venue, and more.
|
||||
</Typography>
|
||||
<Button variant="outlined" size="medium" fullWidth>
|
||||
Start building your quote
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
</Container>
|
||||
</Box>
|
||||
|
||||
{/* ═══════════════════════════════════════════════════════════════════
|
||||
Section 4: Why Use Funeral Arranger (Features)
|
||||
@@ -583,7 +791,7 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
||||
aria-labelledby="features-heading"
|
||||
sx={{
|
||||
bgcolor: 'var(--fa-color-surface-default)',
|
||||
py: { xs: 8, md: 12 },
|
||||
py: { xs: 10, md: 14 },
|
||||
}}
|
||||
>
|
||||
<Container maxWidth="lg">
|
||||
@@ -648,8 +856,8 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
||||
component="section"
|
||||
aria-labelledby="reviews-heading"
|
||||
sx={{
|
||||
py: { xs: 8, md: 12 },
|
||||
bgcolor: 'var(--fa-color-surface-subtle)',
|
||||
py: { xs: 10, md: 14 },
|
||||
bgcolor: '#f8f5f1',
|
||||
}}
|
||||
>
|
||||
<Container maxWidth="md">
|
||||
@@ -683,26 +891,29 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Editorial testimonials — alternating alignment with dividers */}
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
|
||||
{/* Editorial testimonials — left-aligned with dividers */}
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: 0,
|
||||
maxWidth: 560,
|
||||
mx: 'auto',
|
||||
}}
|
||||
>
|
||||
{testimonials.map((t, i) => {
|
||||
const isRight = i % 2 === 1;
|
||||
return (
|
||||
<React.Fragment key={`${t.name}-${i}`}>
|
||||
{i > 0 && <Divider sx={{ my: 4 }} />}
|
||||
<Box
|
||||
sx={{
|
||||
textAlign: isRight ? 'right' : 'left',
|
||||
maxWidth: '85%',
|
||||
ml: isRight ? 'auto' : 0,
|
||||
mr: isRight ? 0 : 'auto',
|
||||
textAlign: 'left',
|
||||
}}
|
||||
>
|
||||
<FormatQuoteIcon
|
||||
sx={{
|
||||
fontSize: 32,
|
||||
color: 'var(--fa-color-brand-300)',
|
||||
transform: isRight ? 'scaleX(-1)' : 'none',
|
||||
mb: 1,
|
||||
}}
|
||||
/>
|
||||
@@ -750,7 +961,7 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
||||
sx={{
|
||||
background:
|
||||
'linear-gradient(180deg, var(--fa-color-brand-100, #F5EDE4) 0%, var(--fa-color-surface-warm, #FEF9F5) 100%)',
|
||||
py: { xs: 8, md: 10 },
|
||||
py: { xs: 10, md: 14 },
|
||||
}}
|
||||
>
|
||||
<Container maxWidth="md" sx={{ textAlign: 'center' }}>
|
||||
@@ -777,17 +988,17 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
||||
aria-labelledby="faq-heading"
|
||||
sx={{
|
||||
bgcolor: 'var(--fa-color-surface-default)',
|
||||
py: { xs: 8, md: 12 },
|
||||
py: { xs: 10, md: 14 },
|
||||
}}
|
||||
>
|
||||
<Container maxWidth="lg">
|
||||
<Typography
|
||||
variant="h2"
|
||||
variant="display3"
|
||||
component="h2"
|
||||
id="faq-heading"
|
||||
sx={{ textAlign: 'center', mb: { xs: 5, md: 8 }, color: 'text.primary' }}
|
||||
>
|
||||
FAQ
|
||||
Frequently Asked Questions
|
||||
</Typography>
|
||||
|
||||
<Box sx={{ maxWidth: 700, mx: 'auto' }}>
|
||||
@@ -823,6 +1034,11 @@ export const HomePage = React.forwardRef<HTMLDivElement, HomePageProps>(
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
))}
|
||||
<Box sx={{ textAlign: 'center', mt: 4 }}>
|
||||
<Button variant="text" size="medium">
|
||||
See more
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Container>
|
||||
</Box>
|
||||
|
||||
@@ -240,7 +240,7 @@ const partnerLogos: PartnerLogo[] = [
|
||||
// ─── Meta ────────────────────────────────────────────────────────────────────
|
||||
|
||||
const meta: Meta<typeof HomePage> = {
|
||||
title: 'Archive/HomePage V3',
|
||||
title: 'Pages/HomePage',
|
||||
component: HomePage,
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
@@ -258,7 +258,7 @@ export const Default: Story = {
|
||||
navigation: nav,
|
||||
footer,
|
||||
heroImageUrl: '/brandassets/images/heroes/hero-3.png',
|
||||
heroHeading: 'Compare funeral directors pricing near you and arrange with confidence',
|
||||
heroHeading: 'Compare funeral director pricing near you and arrange with confidence',
|
||||
heroSubheading: 'Transparent pricing \u00B7 No hidden fees \u00B7 Arrange 24/7',
|
||||
stats: trustStats,
|
||||
featuredProviders,
|
||||
@@ -269,7 +269,7 @@ export const Default: Story = {
|
||||
}),
|
||||
onSelectFeaturedProvider: (id) => console.log('Featured provider:', id),
|
||||
partnerLogos,
|
||||
partnerTrustLine: 'Trusted by hundreds of verified funeral directors across Australia',
|
||||
partnerTrustLine: 'Verified funeral directors on Funeral Arranger',
|
||||
features,
|
||||
googleRating: 4.9,
|
||||
googleReviewCount: 2340,
|
||||
|
||||
Reference in New Issue
Block a user