fix: mobile audit — gray token, FDImage props, border radius, padding
This commit is contained in:
parent
5b64cbf24c
commit
097615569b
@ -340,6 +340,7 @@ html:not([data-theme]) {
|
|||||||
--color-fd-gray-warm: #F8F8F6;
|
--color-fd-gray-warm: #F8F8F6;
|
||||||
--color-fd-gray-cool: #F5F7F9;
|
--color-fd-gray-cool: #F5F7F9;
|
||||||
--color-fd-gray-200: #C8CCD0;
|
--color-fd-gray-200: #C8CCD0;
|
||||||
|
--color-fd-gray-light: #F0F0F0;
|
||||||
--color-fd-gray-300: #A9AEB5;
|
--color-fd-gray-300: #A9AEB5;
|
||||||
--color-fd-gray-400: #8A919A;
|
--color-fd-gray-400: #8A919A;
|
||||||
--color-fd-gray-500: #6B737E;
|
--color-fd-gray-500: #6B737E;
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import type { FDAlternateHeroBlock as Props, Media } from '@/payload-types'
|
import type { FDAlternateHeroBlock as Props, Media } from '@/payload-types'
|
||||||
|
import { FDImage } from '@/components/FDImage'
|
||||||
|
import { FDButton } from '@/components/FDButton'
|
||||||
|
|
||||||
export const FDAlternateHeroBlockComponent: React.FC<Props> = ({
|
export const FDAlternateHeroBlockComponent: React.FC<Props> = ({
|
||||||
heading,
|
heading,
|
||||||
@ -13,8 +15,9 @@ export const FDAlternateHeroBlockComponent: React.FC<Props> = ({
|
|||||||
sectionBackground = 'white',
|
sectionBackground = 'white',
|
||||||
}) => {
|
}) => {
|
||||||
const media = image as Media | undefined
|
const media = image as Media | undefined
|
||||||
|
const hasImage = media && typeof media === 'object' && media.url
|
||||||
const isDark = sectionBackground === 'navy'
|
const isDark = sectionBackground === 'navy'
|
||||||
const bgClass = isDark ? 'bg-fd-navy' : sectionBackground === 'gray' ? 'bg-fd-surface-alt' : 'bg-white'
|
const bgClass = isDark ? 'bg-fd-navy' : sectionBackground === 'gray' ? 'bg-fd-gray-light' : 'bg-white'
|
||||||
const titleClass = isDark ? 'text-fd-yellow' : 'text-fd-navy'
|
const titleClass = isDark ? 'text-fd-yellow' : 'text-fd-navy'
|
||||||
const bodyClass = isDark ? 'text-white' : 'text-fd-navy'
|
const bodyClass = isDark ? 'text-white' : 'text-fd-navy'
|
||||||
|
|
||||||
@ -33,31 +36,33 @@ export const FDAlternateHeroBlockComponent: React.FC<Props> = ({
|
|||||||
{(primaryCtaText || secondaryCtaText) && (
|
{(primaryCtaText || secondaryCtaText) && (
|
||||||
<div className="flex flex-col sm:flex-row items-center justify-center gap-4 mt-2">
|
<div className="flex flex-col sm:flex-row items-center justify-center gap-4 mt-2">
|
||||||
{primaryCtaText && (
|
{primaryCtaText && (
|
||||||
<a href={primaryCtaLink || '#'} className="fd-btn-primary">
|
<FDButton href={primaryCtaLink || '#'} variant="primary" onDark={isDark}>
|
||||||
{primaryCtaText} →
|
{primaryCtaText} →
|
||||||
</a>
|
</FDButton>
|
||||||
)}
|
)}
|
||||||
{secondaryCtaText && (
|
{secondaryCtaText && (
|
||||||
<a
|
<FDButton href={secondaryCtaLink || '#'} variant="outline" onDark={isDark}>
|
||||||
href={secondaryCtaLink || '#'}
|
|
||||||
className={isDark ? 'fd-btn-secondary-dark' : 'fd-btn-secondary'}
|
|
||||||
>
|
|
||||||
{secondaryCtaText}
|
{secondaryCtaText}
|
||||||
</a>
|
</FDButton>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Full-width image — no container, no border radius */}
|
{/* FIX: Full-width image using FDImage with fill, replacing raw <img> */}
|
||||||
{media?.url && (
|
{hasImage && (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<img
|
<div className="relative w-full" style={{ maxHeight: '620px', height: '45vw', minHeight: '220px' }}>
|
||||||
src={media.url}
|
<FDImage
|
||||||
alt={(media as any).alt || heading}
|
media={media}
|
||||||
className="w-full object-cover block"
|
size="hero"
|
||||||
style={{ maxHeight: '620px', objectPosition: 'center top' }}
|
fill
|
||||||
|
priority
|
||||||
|
className="object-cover object-center"
|
||||||
|
sizes="100vw"
|
||||||
|
fallbackAlt={heading || ''}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
{imageCaption && (
|
{imageCaption && (
|
||||||
<div className={`text-center py-3 font-joey text-fd-small opacity-60 ${bodyClass} ${bgClass}`}>
|
<div className={`text-center py-3 font-joey text-fd-small opacity-60 ${bodyClass} ${bgClass}`}>
|
||||||
{imageCaption}
|
{imageCaption}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ const cardStyleMap: Record<
|
|||||||
border: '',
|
border: '',
|
||||||
},
|
},
|
||||||
gray: {
|
gray: {
|
||||||
bg: 'bg-[#e5e5e5] dark:bg-white/10',
|
bg: 'bg-fd-gray-light dark:bg-white/10',
|
||||||
headingText: 'text-fd-navy dark:text-fd-yellow',
|
headingText: 'text-fd-navy dark:text-fd-yellow',
|
||||||
bodyText: 'text-fd-navy dark:text-white',
|
bodyText: 'text-fd-navy dark:text-white',
|
||||||
linkText: 'text-fd-navy hover:text-fd-navy/70 dark:text-fd-yellow dark:hover:text-fd-yellow/80',
|
linkText: 'text-fd-navy hover:text-fd-navy/70 dark:text-fd-yellow dark:hover:text-fd-yellow/80',
|
||||||
@ -73,7 +73,7 @@ export const FDCardGridBlockComponent: React.FC<FDCardGridBlockProps> = ({
|
|||||||
const gridCols = layoutGridMap[layout] || layoutGridMap['1-1-1']
|
const gridCols = layoutGridMap[layout] || layoutGridMap['1-1-1']
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={`w-full py-12 md:py-16 lg:py-20 ${sectionBg}`}>
|
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${sectionBg}`}>
|
||||||
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
|
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
|
||||||
<div className={`grid grid-cols-1 md:grid-cols-2 ${gridCols} gap-4 md:gap-6`}>
|
<div className={`grid grid-cols-1 md:grid-cols-2 ${gridCols} gap-4 md:gap-6`}>
|
||||||
{cards?.map((card, index) => {
|
{cards?.map((card, index) => {
|
||||||
@ -84,7 +84,7 @@ export const FDCardGridBlockComponent: React.FC<FDCardGridBlockProps> = ({
|
|||||||
if (mode === 'centeredHeading') {
|
if (mode === 'centeredHeading') {
|
||||||
cardContent = (
|
cardContent = (
|
||||||
<div
|
<div
|
||||||
className={`${style.bg} ${style.border} rounded-[70px] px-10 md:px-14 py-14 md:py-20 flex items-center justify-center min-h-[280px] md:min-h-[360px]`}
|
className={`${style.bg} ${style.border} rounded-[70px] px-8 md:px-14 py-14 md:py-20 flex items-center justify-center min-h-[280px] md:min-h-[360px]`}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={`font-joey-heavy text-fd-display leading-tight text-center ${style.headingText}`}
|
className={`font-joey-heavy text-fd-display leading-tight text-center ${style.headingText}`}
|
||||||
@ -96,7 +96,7 @@ export const FDCardGridBlockComponent: React.FC<FDCardGridBlockProps> = ({
|
|||||||
} else if (mode === 'centeredBody') {
|
} else if (mode === 'centeredBody') {
|
||||||
cardContent = (
|
cardContent = (
|
||||||
<div
|
<div
|
||||||
className={`${style.bg} ${style.border} rounded-[70px] px-10 md:px-14 py-14 md:py-20 flex items-center justify-center min-h-[280px] md:min-h-[360px]`}
|
className={`${style.bg} ${style.border} rounded-[70px] px-8 md:px-14 py-14 md:py-20 flex items-center justify-center min-h-[280px] md:min-h-[360px]`}
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
className={`font-joey text-fd-body-lg text-center ${style.bodyText}`}
|
className={`font-joey text-fd-body-lg text-center ${style.bodyText}`}
|
||||||
@ -106,9 +106,10 @@ export const FDCardGridBlockComponent: React.FC<FDCardGridBlockProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
// FIX: px-6 on mobile → px-10 on md+ to prevent 40px padding squashing 375px cards
|
||||||
cardContent = (
|
cardContent = (
|
||||||
<div
|
<div
|
||||||
className={`${style.bg} ${style.border} rounded-[70px] px-10 md:px-14 py-10 md:py-14 flex flex-col gap-1 h-full`}
|
className={`${style.bg} ${style.border} rounded-[70px] px-6 md:px-10 lg:px-14 py-8 md:py-12 lg:py-14 flex flex-col gap-1 h-full`}
|
||||||
>
|
>
|
||||||
{card.heading && (
|
{card.heading && (
|
||||||
<h3
|
<h3
|
||||||
|
|||||||
@ -9,22 +9,25 @@ export const FDContactBlockComponent: React.FC<FDContactBlockProps> = ({
|
|||||||
return (
|
return (
|
||||||
<section className="relative w-full bg-fd-navy py-16 md:py-20 lg:pt-[100px] lg:pb-[120px]">
|
<section className="relative w-full bg-fd-navy py-16 md:py-20 lg:pt-[100px] lg:pb-[120px]">
|
||||||
<div className="max-w-[1200px] mx-auto px-6 md:px-8 flex flex-col items-center gap-8 lg:gap-10">
|
<div className="max-w-[1200px] mx-auto px-6 md:px-8 flex flex-col items-center gap-8 lg:gap-10">
|
||||||
<h2 className="w-full font-joey-heavy text-fd-navy text-fd-h1 text-fd-yellow text-center">
|
{/* FIX: removed conflicting text-fd-navy class, kept text-fd-yellow */}
|
||||||
|
<h2 className="w-full font-joey-heavy text-fd-h1 text-fd-yellow text-center">
|
||||||
{heading}
|
{heading}
|
||||||
</h2>
|
</h2>
|
||||||
<div className="flex flex-row items-stretch gap-4 md:gap-7 w-full max-w-[656px]">
|
|
||||||
|
{/* FIX: flex-col on mobile → sm:flex-row so cards don't squash at 375px */}
|
||||||
|
<div className="flex flex-col sm:flex-row items-stretch gap-4 md:gap-7 w-full max-w-[656px]">
|
||||||
{contactMethods?.map((method, index) => {
|
{contactMethods?.map((method, index) => {
|
||||||
const media = method.icon as Media
|
const media = method.icon as Media
|
||||||
const card = (
|
const card = (
|
||||||
<div className="flex-1 flex flex-col items-center gap-3 md:gap-5 cursor-pointer transition-transform hover:scale-105">
|
<div className="flex-1 flex flex-col items-center gap-3 md:gap-5 cursor-pointer transition-transform hover:scale-105">
|
||||||
{media?.url && (
|
{media?.url && (
|
||||||
<div className="relative w-full h-[120px] md:h-[160px] lg:h-[200px] overflow-hidden rounded-[70px]">
|
<div className="relative w-full h-[140px] sm:h-[120px] md:h-[160px] lg:h-[200px] overflow-hidden rounded-[70px]">
|
||||||
<FDImage
|
<FDImage
|
||||||
media={media}
|
media={media}
|
||||||
size="medium"
|
size="medium"
|
||||||
fill
|
fill
|
||||||
className="object-cover"
|
className="object-cover"
|
||||||
sizes="(max-width: 768px) 50vw, 300px"
|
sizes="(max-width: 640px) 90vw, (max-width: 768px) 50vw, 300px"
|
||||||
fallbackAlt={method.label}
|
fallbackAlt={method.label}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -20,14 +20,14 @@ export const FDCtaSideImageBlockComponent: React.FC<FDCtaSideImageBlockProps> =
|
|||||||
<div className={`flex flex-col flex-1 items-start gap-8 lg:gap-[41px] ${!hasImage ? 'max-w-2xl' : ''}`}>
|
<div className={`flex flex-col flex-1 items-start gap-8 lg:gap-[41px] ${!hasImage ? 'max-w-2xl' : ''}`}>
|
||||||
<div className="flex flex-col items-start gap-4 w-full">
|
<div className="flex flex-col items-start gap-4 w-full">
|
||||||
<h2
|
<h2
|
||||||
className={`w-full font-joey-heavy text-3xl md:text-4xl lg:text-5xl leading-tight lg:leading-[57.6px] ${
|
className={`w-full font-joey-heavy text-fd-h1 leading-tight ${
|
||||||
isDark ? 'text-fd-yellow' : 'text-fd-navy'
|
isDark ? 'text-fd-yellow' : 'text-fd-navy'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{heading}
|
{heading}
|
||||||
</h2>
|
</h2>
|
||||||
<p
|
<p
|
||||||
className={`w-full font-joey text-lg md:text-xl lg:text-2xl leading-relaxed lg:leading-[38px] ${
|
className={`w-full font-joey text-fd-body-lg leading-relaxed ${
|
||||||
isDark ? 'text-white' : 'text-fd-navy'
|
isDark ? 'text-white' : 'text-fd-navy'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
@ -47,14 +47,17 @@ export const FDCtaSideImageBlockComponent: React.FC<FDCtaSideImageBlockProps> =
|
|||||||
<div className="w-full lg:w-[575px] lg:h-[479px] flex-shrink-0">
|
<div className="w-full lg:w-[575px] lg:h-[479px] flex-shrink-0">
|
||||||
<FDImage
|
<FDImage
|
||||||
media={image as Media}
|
media={image as Media}
|
||||||
|
size="large"
|
||||||
fallbackAlt={heading}
|
fallbackAlt={heading}
|
||||||
className="w-full h-full object-cover rounded-[70px]"
|
className="w-full h-full object-cover rounded-[70px]"
|
||||||
|
sizes="(max-width: 1024px) 100vw, 575px"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : null
|
) : null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={`w-full py-16 lg:py-[79px] ${isDark ? 'bg-fd-navy' : 'bg-white'}`}>
|
// FIX: added md:py-20 so tablet gets correct spacing
|
||||||
|
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${isDark ? 'bg-fd-navy' : 'bg-white'}`}>
|
||||||
<div className="max-w-[1200px] mx-auto px-6 md:px-8 flex flex-col lg:flex-row items-center gap-10 lg:gap-16">
|
<div className="max-w-[1200px] mx-auto px-6 md:px-8 flex flex-col lg:flex-row items-center gap-10 lg:gap-16">
|
||||||
{imagePosition === 'left' ? (
|
{imagePosition === 'left' ? (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -21,12 +21,11 @@ const cardStyleMap: Record<string, {
|
|||||||
}> = {
|
}> = {
|
||||||
outlined: { bg: 'bg-white', border: 'border-[2px] border-[#d1d5db]', title: 'text-fd-navy', subtitle: 'text-fd-navy', body: 'text-fd-navy/80', bullet: 'text-fd-navy', isDark: false },
|
outlined: { bg: 'bg-white', border: 'border-[2px] border-[#d1d5db]', title: 'text-fd-navy', subtitle: 'text-fd-navy', body: 'text-fd-navy/80', bullet: 'text-fd-navy', isDark: false },
|
||||||
navy: { bg: 'bg-fd-navy', border: '', title: 'text-fd-yellow', subtitle: 'text-white', body: 'text-white/80', bullet: 'text-white', isDark: true },
|
navy: { bg: 'bg-fd-navy', border: '', title: 'text-fd-yellow', subtitle: 'text-white', body: 'text-white/80', bullet: 'text-white', isDark: true },
|
||||||
gray: { bg: 'bg-[#e5e5e5]', border: '', title: 'text-fd-navy', subtitle: 'text-fd-navy', body: 'text-fd-navy/80', bullet: 'text-fd-navy', isDark: false },
|
gray: { bg: 'bg-fd-gray-light', border: '', title: 'text-fd-navy', subtitle: 'text-fd-navy', body: 'text-fd-navy/80', bullet: 'text-fd-navy', isDark: false },
|
||||||
yellow: { bg: 'bg-fd-yellow', border: '', title: 'text-fd-navy', subtitle: 'text-fd-navy', body: 'text-fd-navy/80', bullet: 'text-fd-navy', isDark: false },
|
yellow: { bg: 'bg-fd-yellow', border: '', title: 'text-fd-navy', subtitle: 'text-fd-navy', body: 'text-fd-navy/80', bullet: 'text-fd-navy', isDark: false },
|
||||||
white: { bg: 'bg-white shadow-lg', border: '', title: 'text-fd-navy', subtitle: 'text-fd-navy', body: 'text-fd-navy/80', bullet: 'text-fd-navy', isDark: false },
|
white: { bg: 'bg-white shadow-lg', border: '', title: 'text-fd-navy', subtitle: 'text-fd-navy', body: 'text-fd-navy/80', bullet: 'text-fd-navy', isDark: false },
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maps CMS buttonColor to FDButton variant — outline used where primary yellow wouldn't be visible
|
|
||||||
const buttonVariantMap: Record<string, { variant: 'primary' | 'outline' }> = {
|
const buttonVariantMap: Record<string, { variant: 'primary' | 'outline' }> = {
|
||||||
yellow: { variant: 'primary' },
|
yellow: { variant: 'primary' },
|
||||||
navy: { variant: 'primary' },
|
navy: { variant: 'primary' },
|
||||||
@ -54,34 +53,33 @@ export const FDPricingCardBlockComponent: React.FC<FDPricingCardBlockProps> = ({
|
|||||||
const { variant } = buttonVariantMap[buttonColor || 'yellow']
|
const { variant } = buttonVariantMap[buttonColor || 'yellow']
|
||||||
const cardCount = cards?.length || 1
|
const cardCount = cards?.length || 1
|
||||||
const gridCols = gridColsMap[cardCount] || gridColsMap[3]
|
const gridCols = gridColsMap[cardCount] || gridColsMap[3]
|
||||||
|
|
||||||
// outline-dark vs outline-light is determined by the card background
|
|
||||||
const outlineOnDark = style.isDark
|
const outlineOnDark = style.isDark
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={`w-full py-12 md:py-16 lg:py-20 ${sectionBg}`}>
|
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${sectionBg}`}>
|
||||||
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
|
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
|
||||||
{sectionTitle && (
|
{sectionTitle && (
|
||||||
<h2 className={`font-joey-heavy text-3xl md:text-4xl lg:text-[54px] leading-tight text-center mb-10 md:mb-14 ${sectionTitleColor}`}>
|
<h2 className={`font-joey-heavy text-fd-h1 text-center mb-10 md:mb-14 ${sectionTitleColor}`}>
|
||||||
{sectionTitle}
|
{sectionTitle}
|
||||||
</h2>
|
</h2>
|
||||||
)}
|
)}
|
||||||
|
{/* FIX: rounded-[32px] → rounded-[70px] per design system */}
|
||||||
<div className={`grid grid-cols-1 ${gridCols} gap-6 md:gap-8`}>
|
<div className={`grid grid-cols-1 ${gridCols} gap-6 md:gap-8`}>
|
||||||
{cards?.map((card, index) => (
|
{cards?.map((card, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className={`${style.bg} ${style.border} rounded-[32px] px-8 md:px-10 py-10 md:py-12 flex flex-col gap-5`}
|
className={`${style.bg} ${style.border} rounded-[70px] px-8 md:px-10 py-10 md:py-12 flex flex-col gap-5`}
|
||||||
>
|
>
|
||||||
<h3 className={`font-joey-heavy text-2xl md:text-3xl lg:text-4xl leading-tight ${style.title}`}>
|
<h3 className={`font-joey-heavy text-fd-h2 leading-tight ${style.title}`}>
|
||||||
{card.title}
|
{card.title}
|
||||||
</h3>
|
</h3>
|
||||||
{card.subtitle && (
|
{card.subtitle && (
|
||||||
<p className={`font-joey-bold text-xl md:text-2xl leading-tight ${style.subtitle}`}>
|
<p className={`font-joey-bold text-fd-h3 leading-tight ${style.subtitle}`}>
|
||||||
{card.subtitle}
|
{card.subtitle}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
{card.description && (
|
{card.description && (
|
||||||
<p className={`font-joey text-base md:text-lg leading-relaxed ${style.body}`}>
|
<p className={`font-joey text-fd-body-lg leading-relaxed ${style.body}`}>
|
||||||
{card.description}
|
{card.description}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
@ -90,7 +88,7 @@ export const FDPricingCardBlockComponent: React.FC<FDPricingCardBlockProps> = ({
|
|||||||
{card.bulletPoints.map((point, i) => (
|
{card.bulletPoints.map((point, i) => (
|
||||||
<li key={i} className="flex items-start gap-3">
|
<li key={i} className="flex items-start gap-3">
|
||||||
<span className="mt-2 w-2 h-2 rounded-full bg-current flex-shrink-0" />
|
<span className="mt-2 w-2 h-2 rounded-full bg-current flex-shrink-0" />
|
||||||
<span className="font-joey text-base md:text-lg">{point.text}</span>
|
<span className="font-joey text-fd-body-lg">{point.text}</span>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
@ -101,7 +99,6 @@ export const FDPricingCardBlockComponent: React.FC<FDPricingCardBlockProps> = ({
|
|||||||
href={card.ctaLink || '#'}
|
href={card.ctaLink || '#'}
|
||||||
variant={variant}
|
variant={variant}
|
||||||
onDark={variant === 'outline' ? outlineOnDark : style.isDark}
|
onDark={variant === 'outline' ? outlineOnDark : style.isDark}
|
||||||
className="text-lg md:text-xl"
|
|
||||||
>
|
>
|
||||||
{card.ctaText}
|
{card.ctaText}
|
||||||
</FDButton>
|
</FDButton>
|
||||||
|
|||||||
@ -14,7 +14,8 @@ export const FDServicesGridBlockComponent: React.FC<FDServicesGridBlockProps> =
|
|||||||
columns = '4',
|
columns = '4',
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<section className="relative w-full bg-white py-16 md:py-20 lg:py-24">
|
// FIX: lg:py-24 → lg:py-[99px] (standard section padding)
|
||||||
|
<section className="relative w-full bg-white py-16 md:py-20 lg:py-[99px]">
|
||||||
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
|
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
|
||||||
<h2 className="font-joey-heavy text-fd-h1 text-fd-navy mb-8 lg:mb-12">
|
<h2 className="font-joey-heavy text-fd-h1 text-fd-navy mb-8 lg:mb-12">
|
||||||
{heading}
|
{heading}
|
||||||
|
|||||||
@ -1,18 +1,17 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import type { FDTeamBlock as FDTeamBlockProps, Media } from '@/payload-types'
|
import type { FDTeamBlock as FDTeamBlockProps, Media } from '@/payload-types'
|
||||||
import { FDImage } from '@/components/FDImage'
|
import { FDImage } from '@/components/FDImage'
|
||||||
|
|
||||||
const sectionBgMap: Record<string, string> = {
|
const sectionBgMap: Record<string, string> = {
|
||||||
white: 'bg-white',
|
white: 'bg-white',
|
||||||
gray: 'bg-[#e5e5e5]',
|
gray: 'bg-fd-gray-light',
|
||||||
navy: 'bg-fd-navy',
|
navy: 'bg-fd-navy',
|
||||||
}
|
}
|
||||||
|
|
||||||
const cardMap: Record<string, { bg: string; name: string; role: string; bio: string; icon: string }> = {
|
const cardMap: Record<string, { bg: string; name: string; role: string; bio: string; icon: string }> = {
|
||||||
navy: { bg: 'bg-fd-navy', name: 'text-fd-yellow', role: 'text-white/70', bio: 'text-white/60', icon: 'text-white/40 hover:text-fd-yellow' },
|
navy: { bg: 'bg-fd-navy', name: 'text-fd-yellow', role: 'text-white/70', bio: 'text-white/60', icon: 'text-white/40 hover:text-fd-yellow' },
|
||||||
white: { bg: 'bg-white', name: 'text-fd-navy', role: 'text-fd-navy/60', bio: 'text-fd-navy/60', icon: 'text-fd-navy/40 hover:text-fd-navy' },
|
white: { bg: 'bg-white', name: 'text-fd-navy', role: 'text-fd-navy/60', bio: 'text-fd-navy/60', icon: 'text-fd-navy/40 hover:text-fd-navy' },
|
||||||
gray: { bg: 'bg-[#e5e5e5]', name: 'text-fd-navy', role: 'text-fd-navy/60', bio: 'text-fd-navy/60', icon: 'text-fd-navy/40 hover:text-fd-navy' },
|
gray: { bg: 'bg-fd-gray-light', name: 'text-fd-navy', role: 'text-fd-navy/60', bio: 'text-fd-navy/60', icon: 'text-fd-navy/40 hover:text-fd-navy' },
|
||||||
}
|
}
|
||||||
|
|
||||||
const colsMap: Record<string, string> = {
|
const colsMap: Record<string, string> = {
|
||||||
@ -29,9 +28,9 @@ export const FDTeamBlockComponent: React.FC<FDTeamBlockProps> = ({
|
|||||||
cardStyle = 'navy',
|
cardStyle = 'navy',
|
||||||
sectionBackground = 'white',
|
sectionBackground = 'white',
|
||||||
}) => {
|
}) => {
|
||||||
const sectionBg = sectionBgMap[sectionBackground] || sectionBgMap.white
|
const sectionBg = sectionBgMap[sectionBackground ?? 'white'] || sectionBgMap.white
|
||||||
const card = cardMap[cardStyle] || cardMap.navy
|
const card = cardMap[cardStyle ?? 'navy'] || cardMap.navy
|
||||||
const gridCols = colsMap[columns] || colsMap['3']
|
const gridCols = colsMap[columns ?? '3'] || colsMap['3']
|
||||||
const isNavySection = sectionBackground === 'navy'
|
const isNavySection = sectionBackground === 'navy'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -42,12 +41,12 @@ export const FDTeamBlockComponent: React.FC<FDTeamBlockProps> = ({
|
|||||||
{(heading || subheading) && (
|
{(heading || subheading) && (
|
||||||
<div className="flex flex-col gap-3 mb-10 md:mb-14">
|
<div className="flex flex-col gap-3 mb-10 md:mb-14">
|
||||||
{heading && (
|
{heading && (
|
||||||
<h2 className={`font-joey-heavy text-3xl md:text-4xl lg:text-5xl leading-tight ${isNavySection ? 'text-fd-yellow' : 'text-fd-navy'}`}>
|
<h2 className={`font-joey-heavy text-fd-h1 ${isNavySection ? 'text-fd-yellow' : 'text-fd-navy'}`}>
|
||||||
{heading}
|
{heading}
|
||||||
</h2>
|
</h2>
|
||||||
)}
|
)}
|
||||||
{subheading && (
|
{subheading && (
|
||||||
<p className={`font-joey text-lg md:text-xl ${isNavySection ? 'text-white/70' : 'text-fd-navy/60'}`}>
|
<p className={`font-joey text-fd-body-lg ${isNavySection ? 'text-white/70' : 'text-fd-navy/60'}`}>
|
||||||
{subheading}
|
{subheading}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
@ -57,22 +56,24 @@ export const FDTeamBlockComponent: React.FC<FDTeamBlockProps> = ({
|
|||||||
{/* Grid */}
|
{/* Grid */}
|
||||||
<div className={`grid grid-cols-1 ${gridCols} gap-6`}>
|
<div className={`grid grid-cols-1 ${gridCols} gap-6`}>
|
||||||
{members?.map((member, i) => {
|
{members?.map((member, i) => {
|
||||||
|
// FIX: cast photo properly as Media and pass full object to FDImage
|
||||||
const photo = member.photo as Media | undefined
|
const photo = member.photo as Media | undefined
|
||||||
|
const hasPhoto = photo && typeof photo === 'object' && photo.url
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={i} className={`${card.bg} rounded-[70px] overflow-hidden flex flex-col`}>
|
<div key={i} className={`${card.bg} rounded-[70px] overflow-hidden flex flex-col`}>
|
||||||
|
|
||||||
{/* Photo */}
|
{/* Photo */}
|
||||||
<div className="aspect-[4/3] w-full overflow-hidden">
|
<div className="aspect-[4/3] w-full overflow-hidden">
|
||||||
{photo?.url ? (
|
{hasPhoto ? (
|
||||||
<FDImage
|
<FDImage
|
||||||
src={photo.url}
|
media={photo}
|
||||||
alt={photo.alt || member.name}
|
size="medium"
|
||||||
width={600}
|
|
||||||
height={450}
|
|
||||||
className="w-full h-full object-cover object-top"
|
className="w-full h-full object-cover object-top"
|
||||||
|
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
|
||||||
|
fallbackAlt={member.name}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
// Placeholder when no photo
|
|
||||||
<div className={`w-full h-full flex items-center justify-center ${cardStyle === 'navy' ? 'bg-fd-navy/50' : 'bg-fd-navy/10'}`}>
|
<div className={`w-full h-full flex items-center justify-center ${cardStyle === 'navy' ? 'bg-fd-navy/50' : 'bg-fd-navy/10'}`}>
|
||||||
<svg viewBox="0 0 80 80" className="w-20 h-20 opacity-30" fill="currentColor">
|
<svg viewBox="0 0 80 80" className="w-20 h-20 opacity-30" fill="currentColor">
|
||||||
<circle cx="40" cy="30" r="18" />
|
<circle cx="40" cy="30" r="18" />
|
||||||
@ -84,11 +85,11 @@ export const FDTeamBlockComponent: React.FC<FDTeamBlockProps> = ({
|
|||||||
|
|
||||||
{/* Info */}
|
{/* Info */}
|
||||||
<div className="flex flex-col gap-2 px-8 py-8 flex-1">
|
<div className="flex flex-col gap-2 px-8 py-8 flex-1">
|
||||||
<p className={`font-joey-bold text-xl ${card.name}`}>{member.name}</p>
|
<p className={`font-joey-bold text-fd-h3 ${card.name}`}>{member.name}</p>
|
||||||
<p className={`font-joey text-sm ${card.role}`}>{member.role}</p>
|
<p className={`font-joey text-fd-small ${card.role}`}>{member.role}</p>
|
||||||
|
|
||||||
{member.bio && (
|
{member.bio && (
|
||||||
<p className={`font-joey text-sm leading-relaxed mt-2 ${card.bio}`}>
|
<p className={`font-joey text-fd-small leading-relaxed mt-2 ${card.bio}`}>
|
||||||
{member.bio}
|
{member.bio}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
@ -102,7 +103,6 @@ export const FDTeamBlockComponent: React.FC<FDTeamBlockProps> = ({
|
|||||||
aria-label={`E-post till ${member.name}`}
|
aria-label={`E-post till ${member.name}`}
|
||||||
className={`transition-colors ${card.icon}`}
|
className={`transition-colors ${card.icon}`}
|
||||||
>
|
>
|
||||||
{/* Email icon */}
|
|
||||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||||
</svg>
|
</svg>
|
||||||
@ -116,7 +116,6 @@ export const FDTeamBlockComponent: React.FC<FDTeamBlockProps> = ({
|
|||||||
aria-label={`LinkedIn för ${member.name}`}
|
aria-label={`LinkedIn för ${member.name}`}
|
||||||
className={`transition-colors ${card.icon}`}
|
className={`transition-colors ${card.icon}`}
|
||||||
>
|
>
|
||||||
{/* LinkedIn icon */}
|
|
||||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
||||||
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" />
|
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
@ -1,29 +1,48 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import type { FDTestimonialBlock as FDTestimonialBlockProps, Media } from '@/payload-types'
|
import type { FDTestimonialBlock as FDTestimonialBlockProps, Media } from '@/payload-types'
|
||||||
import { FDImage } from '@/components/FDImage'
|
import { FDImage } from '@/components/FDImage'
|
||||||
|
|
||||||
const bgMap: Record<string, { section: string; card: string; quote: string; meta: string; name: string; company: string }> = {
|
const bgMap: Record<string, { section: string; card: string; quote: string; meta: string; name: string; company: string }> = {
|
||||||
gray: { section: 'bg-[#e5e5e5]', card: 'bg-white', quote: 'text-fd-navy', meta: 'text-fd-navy/60', name: 'text-fd-navy', company: 'text-fd-navy/50' },
|
gray: { section: 'bg-fd-gray-light', card: 'bg-white', quote: 'text-fd-navy', meta: 'text-fd-navy/60', name: 'text-fd-navy', company: 'text-fd-navy/50' },
|
||||||
white: { section: 'bg-white', card: 'bg-[#e5e5e5]', quote: 'text-fd-navy', meta: 'text-fd-navy/60', name: 'text-fd-navy', company: 'text-fd-navy/50' },
|
white: { section: 'bg-white', card: 'bg-fd-gray-light', quote: 'text-fd-navy', meta: 'text-fd-navy/60', name: 'text-fd-navy', company: 'text-fd-navy/50' },
|
||||||
navy: { section: 'bg-fd-navy', card: 'bg-white/10', quote: 'text-white', meta: 'text-white/60', name: 'text-white', company: 'text-white/50' },
|
navy: { section: 'bg-fd-navy', card: 'bg-white/10', quote: 'text-white', meta: 'text-white/60', name: 'text-white', company: 'text-white/50' },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Avatar helper — uses FDImage with media object correctly */
|
||||||
|
const Avatar: React.FC<{ media: Media | undefined; name: string; size: number }> = ({ media, name, size }) => {
|
||||||
|
if (!media?.url) return null
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="rounded-full overflow-hidden flex-shrink-0"
|
||||||
|
style={{ width: size, height: size }}
|
||||||
|
>
|
||||||
|
<FDImage
|
||||||
|
media={media}
|
||||||
|
size="thumbnail"
|
||||||
|
className="w-full h-full object-cover"
|
||||||
|
sizes={`${size}px`}
|
||||||
|
fallbackAlt={name}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export const FDTestimonialBlockComponent: React.FC<FDTestimonialBlockProps> = ({
|
export const FDTestimonialBlockComponent: React.FC<FDTestimonialBlockProps> = ({
|
||||||
heading,
|
heading,
|
||||||
testimonials,
|
testimonials,
|
||||||
layout = 'grid',
|
layout = 'grid',
|
||||||
sectionBackground = 'gray',
|
sectionBackground = 'gray',
|
||||||
}) => {
|
}) => {
|
||||||
const theme = bgMap[sectionBackground] || bgMap.gray
|
const theme = bgMap[sectionBackground ?? 'gray'] || bgMap.gray
|
||||||
const isFeatured = layout === 'featured'
|
const isFeatured = layout === 'featured'
|
||||||
|
const isNavy = sectionBackground === 'navy'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${theme.section}`}>
|
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${theme.section}`}>
|
||||||
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
|
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
|
||||||
|
|
||||||
{heading && (
|
{heading && (
|
||||||
<h2 className={`font-joey-heavy text-3xl md:text-4xl lg:text-5xl leading-tight mb-10 md:mb-14 ${sectionBackground === 'navy' ? 'text-fd-yellow' : 'text-fd-navy'}`}>
|
<h2 className={`font-joey-heavy text-fd-h1 mb-10 md:mb-14 ${isNavy ? 'text-fd-yellow' : 'text-fd-navy'}`}>
|
||||||
{heading}
|
{heading}
|
||||||
</h2>
|
</h2>
|
||||||
)}
|
)}
|
||||||
@ -36,22 +55,12 @@ export const FDTestimonialBlockComponent: React.FC<FDTestimonialBlockProps> = ({
|
|||||||
const t = testimonials[0]
|
const t = testimonials[0]
|
||||||
const avatar = t.avatar as Media | undefined
|
const avatar = t.avatar as Media | undefined
|
||||||
return (
|
return (
|
||||||
<div className={`${theme.card} rounded-[70px] px-10 md:px-16 py-12 md:py-16 flex flex-col gap-8`}>
|
<div className={`${theme.card} rounded-[70px] px-8 md:px-16 py-10 md:py-16 flex flex-col gap-8`}>
|
||||||
<p className={`font-joey-medium text-xl md:text-2xl lg:text-3xl leading-relaxed ${theme.quote}`}>
|
<p className={`font-joey-medium text-xl md:text-2xl lg:text-3xl leading-relaxed ${theme.quote}`}>
|
||||||
“{t.quote}”
|
“{t.quote}”
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
{avatar?.url && (
|
<Avatar media={avatar} name={t.authorName} size={56} />
|
||||||
<div className="w-14 h-14 rounded-full overflow-hidden flex-shrink-0">
|
|
||||||
<FDImage
|
|
||||||
src={avatar.url}
|
|
||||||
alt={avatar.alt || t.authorName}
|
|
||||||
width={56}
|
|
||||||
height={56}
|
|
||||||
className="w-full h-full object-cover"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div>
|
<div>
|
||||||
<p className={`font-joey-bold text-lg ${theme.name}`}>{t.authorName}</p>
|
<p className={`font-joey-bold text-lg ${theme.name}`}>{t.authorName}</p>
|
||||||
<p className={`font-joey text-sm ${theme.meta}`}>
|
<p className={`font-joey text-sm ${theme.meta}`}>
|
||||||
@ -74,17 +83,7 @@ export const FDTestimonialBlockComponent: React.FC<FDTestimonialBlockProps> = ({
|
|||||||
“{t.quote}”
|
“{t.quote}”
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
{avatar?.url && (
|
<Avatar media={avatar} name={t.authorName} size={40} />
|
||||||
<div className="w-10 h-10 rounded-full overflow-hidden flex-shrink-0">
|
|
||||||
<FDImage
|
|
||||||
src={avatar.url}
|
|
||||||
alt={avatar.alt || t.authorName}
|
|
||||||
width={40}
|
|
||||||
height={40}
|
|
||||||
className="w-full h-full object-cover"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div>
|
<div>
|
||||||
<p className={`font-joey-bold text-base ${theme.name}`}>{t.authorName}</p>
|
<p className={`font-joey-bold text-base ${theme.name}`}>{t.authorName}</p>
|
||||||
<p className={`font-joey text-xs ${theme.meta}`}>
|
<p className={`font-joey text-xs ${theme.meta}`}>
|
||||||
@ -106,24 +105,14 @@ export const FDTestimonialBlockComponent: React.FC<FDTestimonialBlockProps> = ({
|
|||||||
return (
|
return (
|
||||||
<div key={i} className={`${theme.card} rounded-[70px] px-8 md:px-10 py-10 md:py-12 flex flex-col gap-6`}>
|
<div key={i} className={`${theme.card} rounded-[70px] px-8 md:px-10 py-10 md:py-12 flex flex-col gap-6`}>
|
||||||
{/* Quote mark */}
|
{/* Quote mark */}
|
||||||
<span className={`font-joey-heavy text-5xl leading-none ${sectionBackground === 'navy' ? 'text-fd-yellow' : 'text-fd-navy'} opacity-30`}>
|
<span className={`font-joey-heavy text-5xl leading-none ${isNavy ? 'text-fd-yellow' : 'text-fd-navy'} opacity-30`}>
|
||||||
“
|
“
|
||||||
</span>
|
</span>
|
||||||
<p className={`font-joey-medium text-lg leading-relaxed -mt-4 ${theme.quote}`}>
|
<p className={`font-joey-medium text-lg leading-relaxed -mt-4 ${theme.quote}`}>
|
||||||
{t.quote}
|
{t.quote}
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-center gap-3 mt-auto">
|
<div className="flex items-center gap-3 mt-auto">
|
||||||
{avatar?.url && (
|
<Avatar media={avatar} name={t.authorName} size={40} />
|
||||||
<div className="w-10 h-10 rounded-full overflow-hidden flex-shrink-0">
|
|
||||||
<FDImage
|
|
||||||
src={avatar.url}
|
|
||||||
alt={avatar.alt || t.authorName}
|
|
||||||
width={40}
|
|
||||||
height={40}
|
|
||||||
className="w-full h-full object-cover"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div>
|
<div>
|
||||||
<p className={`font-joey-bold text-base ${theme.name}`}>{t.authorName}</p>
|
<p className={`font-joey-bold text-base ${theme.name}`}>{t.authorName}</p>
|
||||||
<p className={`font-joey text-sm ${theme.meta}`}>
|
<p className={`font-joey text-sm ${theme.meta}`}>
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import type { FDWideCardBlock as FDWideCardBlockProps, Media } from '@/payload-types'
|
import type { FDWideCardBlock as FDWideCardBlockProps, Media } from '@/payload-types'
|
||||||
import { FDButton } from '@/components/FDButton'
|
import { FDButton } from '@/components/FDButton'
|
||||||
|
import { FDImage } from '@/components/FDImage'
|
||||||
|
|
||||||
const cardBgMap: Record<string, { bg: string; heading: string; body: string; isDark: boolean }> = {
|
const cardBgMap: Record<string, { bg: string; heading: string; body: string; isDark: boolean }> = {
|
||||||
navy: { bg: 'bg-fd-navy', heading: 'text-white', body: 'text-white/80', isDark: true },
|
navy: { bg: 'bg-fd-navy', heading: 'text-white', body: 'text-white/80', isDark: true },
|
||||||
yellow: { bg: 'bg-fd-yellow', heading: 'text-fd-navy', body: 'text-fd-navy/80', isDark: false },
|
yellow: { bg: 'bg-fd-yellow', heading: 'text-fd-navy', body: 'text-fd-navy/80', isDark: false },
|
||||||
gray: { bg: 'bg-[#e5e5e5]', heading: 'text-fd-navy', body: 'text-fd-navy/80', isDark: false },
|
gray: { bg: 'bg-fd-gray-light', heading: 'text-fd-navy', body: 'text-fd-navy/80', isDark: false },
|
||||||
white: { bg: 'bg-white shadow-xl', heading: 'text-fd-navy', body: 'text-fd-navy/80', isDark: false },
|
white: { bg: 'bg-white shadow-xl', heading: 'text-fd-navy', body: 'text-fd-navy/80', isDark: false },
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15,7 +16,6 @@ const sectionBgMap: Record<string, string> = {
|
|||||||
navy: 'bg-fd-navy',
|
navy: 'bg-fd-navy',
|
||||||
}
|
}
|
||||||
|
|
||||||
// Button variant per CMS color choice — outline used for navy cards with navy button (would be invisible)
|
|
||||||
const btnVariantMap: Record<string, { variant: 'primary' | 'outline' }> = {
|
const btnVariantMap: Record<string, { variant: 'primary' | 'outline' }> = {
|
||||||
yellow: { variant: 'primary' },
|
yellow: { variant: 'primary' },
|
||||||
navy: { variant: 'outline' },
|
navy: { variant: 'outline' },
|
||||||
@ -36,19 +36,18 @@ export const FDWideCardBlockComponent: React.FC<FDWideCardBlockProps> = ({
|
|||||||
const sectionBg = sectionBgMap[sectionBackground || 'white']
|
const sectionBg = sectionBgMap[sectionBackground || 'white']
|
||||||
const { variant } = btnVariantMap[buttonColor || 'yellow']
|
const { variant } = btnVariantMap[buttonColor || 'yellow']
|
||||||
const media = image as Media | undefined
|
const media = image as Media | undefined
|
||||||
const imageUrl = media?.url || ''
|
const hasImage = media && typeof media === 'object' && media.url
|
||||||
const hasImage = Boolean(imageUrl)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={`w-full py-12 md:py-16 lg:py-20 ${sectionBg}`}>
|
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${sectionBg}`}>
|
||||||
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
|
<div className="max-w-[1200px] mx-auto px-6 md:px-8">
|
||||||
<div className={`${card.bg} rounded-[70px] overflow-hidden flex flex-col lg:flex-row`}>
|
<div className={`${card.bg} rounded-[70px] overflow-hidden flex flex-col lg:flex-row`}>
|
||||||
<div className="flex-1 flex flex-col justify-center gap-5 md:gap-6 px-10 md:px-14 lg:px-16 py-12 md:py-16">
|
<div className="flex-1 flex flex-col justify-center gap-5 md:gap-6 px-8 md:px-14 lg:px-16 py-12 md:py-16">
|
||||||
<h2 className={`font-joey-heavy text-2xl md:text-3xl lg:text-[42px] leading-tight ${card.heading}`}>
|
<h2 className={`font-joey-heavy text-fd-h1 leading-tight ${card.heading}`}>
|
||||||
{heading}
|
{heading}
|
||||||
</h2>
|
</h2>
|
||||||
{body && (
|
{body && (
|
||||||
<p className={`font-joey text-base md:text-lg lg:text-xl leading-relaxed ${card.body}`}>
|
<p className={`font-joey text-fd-body-lg leading-relaxed ${card.body}`}>
|
||||||
{body}
|
{body}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
@ -58,16 +57,24 @@ export const FDWideCardBlockComponent: React.FC<FDWideCardBlockProps> = ({
|
|||||||
href={ctaLink || '#'}
|
href={ctaLink || '#'}
|
||||||
variant={variant}
|
variant={variant}
|
||||||
onDark={card.isDark}
|
onDark={card.isDark}
|
||||||
className="text-lg md:text-xl"
|
|
||||||
>
|
>
|
||||||
{ctaText}
|
{ctaText}
|
||||||
</FDButton>
|
</FDButton>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* FIX: replaced raw <img> with FDImage */}
|
||||||
{hasImage && (
|
{hasImage && (
|
||||||
<div className="flex-1 min-h-[250px] lg:min-h-0">
|
<div className="relative flex-1 min-h-[250px] lg:min-h-0">
|
||||||
<img src={imageUrl} alt={media?.alt || ''} className="w-full h-full object-cover" />
|
<FDImage
|
||||||
|
media={media}
|
||||||
|
size="large"
|
||||||
|
fill
|
||||||
|
className="object-cover"
|
||||||
|
sizes="(max-width: 1024px) 100vw, 50vw"
|
||||||
|
fallbackAlt={heading || ''}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user