feat: dark mode across all blocks

This commit is contained in:
Jeffrey 2026-02-20 11:17:18 +01:00
parent 097615569b
commit 576ecf1e97
22 changed files with 397 additions and 259 deletions

View File

@ -14,12 +14,24 @@ export const FDAlternateHeroBlockComponent: React.FC<Props> = ({
imageCaption, imageCaption,
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 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-gray-light' : 'bg-white'
const titleClass = isDark ? 'text-fd-yellow' : 'text-fd-navy' const bgClass =
const bodyClass = isDark ? 'text-white' : 'text-fd-navy' isDark
? 'bg-fd-navy'
: sectionBackground === 'gray'
? 'bg-fd-gray-light dark:bg-fd-navy'
: 'bg-white dark:bg-fd-navy'
const titleClass = isDark
? 'text-fd-yellow'
: 'text-fd-navy dark:text-fd-yellow'
const bodyClass = isDark
? 'text-white'
: 'text-fd-navy dark:text-white'
return ( return (
<section className={`w-full pt-16 md:pt-20 lg:pt-[99px] ${bgClass}`}> <section className={`w-full pt-16 md:pt-20 lg:pt-[99px] ${bgClass}`}>
@ -49,7 +61,7 @@ export const FDAlternateHeroBlockComponent: React.FC<Props> = ({
)} )}
</div> </div>
{/* FIX: Full-width image using FDImage with fill, replacing raw <img> */} {/* Full-width image — no border radius, bleeds edge to edge */}
{hasImage && ( {hasImage && (
<div className="w-full"> <div className="w-full">
<div className="relative w-full" style={{ maxHeight: '620px', height: '45vw', minHeight: '220px' }}> <div className="relative w-full" style={{ maxHeight: '620px', height: '45vw', minHeight: '220px' }}>

View File

@ -1,42 +1,44 @@
// @ts-nocheck
import React from 'react' import React from 'react'
import type { FDCtaBannerBlock as FDCtaBannerBlockProps } from '@/payload-types' import type { FDCtaBannerBlock as FDCtaBannerBlockProps } from '@/payload-types'
const bgMap: Record<string, { section: string; heading: string; sub: string; primaryBtn: string; secondaryBtn: string }> = { const bgMap: Record<string, {
section: string; heading: string; sub: string
primaryBtn: string; secondaryBtn: string
}> = {
yellow: { yellow: {
section: 'bg-fd-yellow', section: 'bg-fd-yellow',
heading: 'text-fd-navy', heading: 'text-fd-navy',
sub: 'text-fd-navy/70', sub: 'text-fd-navy/70',
primaryBtn: 'bg-fd-navy hover:bg-fd-navy/90 text-white', primaryBtn: 'bg-fd-navy hover:bg-fd-navy/90 text-white',
secondaryBtn: 'border-2 border-fd-navy text-fd-navy hover:bg-fd-navy/10', secondaryBtn: 'border-2 border-fd-navy text-fd-navy hover:bg-fd-navy/10',
}, },
navy: { navy: {
section: 'bg-fd-navy', section: 'bg-fd-navy',
heading: 'text-fd-yellow', heading: 'text-fd-yellow',
sub: 'text-white/70', sub: 'text-white/70',
primaryBtn: 'bg-fd-yellow hover:bg-fd-yellow/90 text-fd-navy', primaryBtn: 'bg-fd-yellow hover:bg-fd-yellow/90 text-fd-navy',
secondaryBtn: 'border-2 border-white text-white hover:bg-white/10', secondaryBtn: 'border-2 border-white text-white hover:bg-white/10',
}, },
gray: { gray: {
section: 'bg-[#e5e5e5]', section: 'bg-fd-gray-light dark:bg-fd-navy',
heading: 'text-fd-navy', heading: 'text-fd-navy dark:text-fd-yellow',
sub: 'text-fd-navy/70', sub: 'text-fd-navy/70 dark:text-white/70',
primaryBtn: 'bg-fd-navy hover:bg-fd-navy/90 text-white', primaryBtn: 'bg-fd-navy hover:bg-fd-navy/90 text-white dark:bg-fd-yellow dark:hover:bg-fd-yellow/90 dark:text-fd-navy',
secondaryBtn: 'border-2 border-fd-navy text-fd-navy hover:bg-fd-navy/10', secondaryBtn: 'border-2 border-fd-navy text-fd-navy hover:bg-fd-navy/10 dark:border-white dark:text-white dark:hover:bg-white/10',
}, },
white: { white: {
section: 'bg-white', section: 'bg-white dark:bg-fd-navy',
heading: 'text-fd-navy', heading: 'text-fd-navy dark:text-fd-yellow',
sub: 'text-fd-navy/70', sub: 'text-fd-navy/70 dark:text-white/70',
primaryBtn: 'bg-fd-navy hover:bg-fd-navy/90 text-white', primaryBtn: 'bg-fd-navy hover:bg-fd-navy/90 text-white dark:bg-fd-yellow dark:hover:bg-fd-yellow/90 dark:text-fd-navy',
secondaryBtn: 'border-2 border-fd-navy text-fd-navy hover:bg-fd-navy/10', secondaryBtn: 'border-2 border-fd-navy text-fd-navy hover:bg-fd-navy/10 dark:border-white dark:text-white dark:hover:bg-white/10',
}, },
} }
const sizeMap: Record<string, { py: string; heading: string; sub: string }> = { const sizeMap: Record<string, { py: string; heading: string; sub: string }> = {
small: { py: 'py-10 md:py-14', heading: 'text-2xl md:text-3xl lg:text-4xl', sub: 'text-base md:text-lg' }, small: { py: 'py-10 md:py-14', heading: 'text-fd-h2', sub: 'text-fd-body' },
medium: { py: 'py-14 md:py-20 lg:py-[80px]', heading: 'text-3xl md:text-4xl lg:text-5xl', sub: 'text-lg md:text-xl' }, medium: { py: 'py-14 md:py-20 lg:py-[80px]', heading: 'text-fd-h1', sub: 'text-fd-body-lg' },
large: { py: 'py-16 md:py-24 lg:py-[99px]', heading: 'text-4xl md:text-5xl lg:text-[64px]', sub: 'text-xl md:text-2xl' }, large: { py: 'py-16 md:py-24 lg:py-[99px]', heading: 'text-fd-display', sub: 'text-fd-body-lg' },
} }
export const FDCtaBannerBlockComponent: React.FC<FDCtaBannerBlockProps> = ({ export const FDCtaBannerBlockComponent: React.FC<FDCtaBannerBlockProps> = ({
@ -50,8 +52,8 @@ export const FDCtaBannerBlockComponent: React.FC<FDCtaBannerBlockProps> = ({
alignment = 'center', alignment = 'center',
size = 'medium', size = 'medium',
}) => { }) => {
const theme = bgMap[sectionBackground] || bgMap.yellow const theme = bgMap[sectionBackground ?? 'yellow'] || bgMap.yellow
const sizing = sizeMap[size] || sizeMap.medium const sizing = sizeMap[size ?? 'medium'] || sizeMap.medium
const isCenter = alignment === 'center' const isCenter = alignment === 'center'
return ( return (
@ -75,7 +77,7 @@ export const FDCtaBannerBlockComponent: React.FC<FDCtaBannerBlockProps> = ({
{ctaText && ( {ctaText && (
<a <a
href={ctaLink || '#'} href={ctaLink || '#'}
className={`inline-flex items-center justify-center px-8 py-3 rounded-full font-joey-bold text-lg transition-colors ${theme.primaryBtn}`} className={`inline-flex items-center justify-center px-8 py-3 rounded-full font-joey-bold text-fd-btn transition-colors ${theme.primaryBtn}`}
> >
{ctaText} {ctaText}
</a> </a>
@ -83,7 +85,7 @@ export const FDCtaBannerBlockComponent: React.FC<FDCtaBannerBlockProps> = ({
{secondaryCtaText && secondaryCtaLink && ( {secondaryCtaText && secondaryCtaLink && (
<a <a
href={secondaryCtaLink} href={secondaryCtaLink}
className={`inline-flex items-center justify-center px-8 py-3 rounded-full font-joey-bold text-lg transition-colors ${theme.secondaryBtn}`} className={`inline-flex items-center justify-center px-8 py-3 rounded-full font-joey-bold text-fd-btn transition-colors ${theme.secondaryBtn}`}
> >
{secondaryCtaText} {secondaryCtaText}
</a> </a>

View File

@ -16,26 +16,32 @@ export const FDCtaSideImageBlockComponent: React.FC<FDCtaSideImageBlockProps> =
const isDark = theme === 'dark' const isDark = theme === 'dark'
const hasImage = !!image const hasImage = !!image
// Light theme adapts to OS dark preference → becomes navy bg
const sectionBg = isDark
? 'bg-fd-navy'
: 'bg-white dark:bg-fd-navy'
const headingClass = isDark
? 'text-fd-yellow'
: 'text-fd-navy dark:text-fd-yellow'
const bodyClass = isDark
? 'text-white'
: 'text-fd-navy dark:text-white'
const textContent = ( const textContent = (
<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-fd-h1 leading-tight ${headingClass}`}>
className={`w-full font-joey-heavy text-fd-h1 leading-tight ${
isDark ? 'text-fd-yellow' : 'text-fd-navy'
}`}
>
{heading} {heading}
</h2> </h2>
<p <p className={`w-full font-joey text-fd-body-lg leading-relaxed ${bodyClass}`}>
className={`w-full font-joey text-fd-body-lg leading-relaxed ${
isDark ? 'text-white' : 'text-fd-navy'
}`}
>
{body} {body}
</p> </p>
</div> </div>
{ctaText && ( {ctaText && (
// onDark — either explicit dark theme, or dark: mode makes it navy anyway
<FDButton href={ctaLink || '#'} variant="primary" onDark={isDark}> <FDButton href={ctaLink || '#'} variant="primary" onDark={isDark}>
{ctaText} {ctaText}
</FDButton> </FDButton>
@ -56,19 +62,12 @@ export const FDCtaSideImageBlockComponent: React.FC<FDCtaSideImageBlockProps> =
) : null ) : null
return ( return (
// FIX: added md:py-20 so tablet gets correct spacing <section className={`w-full py-16 md:py-20 lg:py-[99px] ${sectionBg}`}>
<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' ? (
<> <>{imageContent}{textContent}</>
{imageContent}
{textContent}
</>
) : ( ) : (
<> <>{textContent}{imageContent}</>
{textContent}
{imageContent}
</>
)} )}
</div> </div>
</section> </section>

View File

@ -10,16 +10,29 @@ export const FDFaqBlockComponent: React.FC<FDFaqBlockProps> = ({
}) => { }) => {
const [openIndex, setOpenIndex] = useState<number | null>(null) const [openIndex, setOpenIndex] = useState<number | null>(null)
// dark theme = always navy. gray/white adapt via dark: OS preference
const bgClass = const bgClass =
theme === 'dark' theme === 'dark'
? 'bg-fd-navy' ? 'bg-fd-navy'
: theme === 'gray' : theme === 'gray'
? 'bg-fd-gray-light' ? 'bg-fd-gray-light dark:bg-fd-navy'
: 'bg-white' : 'bg-white dark:bg-fd-navy'
const headingColor = theme === 'dark' ? 'text-fd-yellow' : 'text-fd-navy'
const textColor = theme === 'dark' ? 'text-white' : 'text-fd-navy' const headingColor = theme === 'dark'
const borderColor = theme === 'dark' ? 'border-white/20' : 'border-fd-navy/10' ? 'text-fd-yellow'
const proseColor = theme === 'dark' ? 'text-white/80' : 'text-fd-navy/80' : 'text-fd-navy dark:text-fd-yellow'
const textColor = theme === 'dark'
? 'text-white'
: 'text-fd-navy dark:text-white'
const borderColor = theme === 'dark'
? 'border-white/20'
: 'border-fd-navy/10 dark:border-white/20'
const proseColor = theme === 'dark'
? 'text-white/80'
: 'text-fd-navy/80 dark:text-white/80'
return ( return (
<section className={`w-full py-16 md:py-20 lg:py-[130px] ${bgClass}`}> <section className={`w-full py-16 md:py-20 lg:py-[130px] ${bgClass}`}>

View File

@ -11,21 +11,36 @@ export const FDFeatureAnnouncementBlockComponent: React.FC<FDFeatureAnnouncement
}) => { }) => {
const isDark = theme === 'dark' const isDark = theme === 'dark'
const bgClass = isDark ? 'bg-fd-navy' : theme === 'gray' ? 'bg-fd-gray' : 'bg-white' // Light themes pick up dark: variants from OS preference
const headingColor = isDark ? 'text-fd-yellow' : 'text-fd-navy' const bgClass =
const bodyColor = isDark ? 'text-white' : 'text-fd-navy' isDark
? 'bg-fd-navy'
: theme === 'gray'
? 'bg-fd-gray-light dark:bg-fd-navy'
: 'bg-white dark:bg-fd-navy'
const headingColor = isDark
? 'text-fd-yellow'
: 'text-fd-navy dark:text-fd-yellow'
const bodyColor = isDark
? 'text-white'
: 'text-fd-navy dark:text-white'
// In dark mode the section is always navy, so onDark=true for the button
const onDark = isDark || true // once dark: kicks in bg is navy anyway
return ( return (
<section className={`w-full py-20 md:py-28 lg:py-[173px] ${bgClass}`}> <section className={`w-full py-20 md:py-28 lg:py-[173px] ${bgClass}`}>
<div className="max-w-[1200px] mx-auto px-6 md:px-8 flex flex-col items-center gap-8"> <div className="max-w-[1200px] mx-auto px-6 md:px-8 flex flex-col items-center gap-8">
<h2 <h2
className={`w-full max-w-[696px] font-joey-bold text-3xl md:text-4xl lg:text-[54px] text-center leading-tight lg:leading-[64.8px] ${headingColor}`} className={`w-full max-w-[696px] font-joey-bold text-fd-h1 text-center leading-tight ${headingColor}`}
> >
{heading} {heading}
</h2> </h2>
<p <p
className={`w-full max-w-[1112px] font-joey text-xl md:text-2xl lg:text-4xl text-center leading-relaxed lg:leading-[44px] ${bodyColor}`} className={`w-full max-w-[1112px] font-joey text-xl md:text-2xl lg:text-4xl text-center leading-relaxed ${bodyColor}`}
> >
{body} {body}
</p> </p>

View File

@ -3,31 +3,38 @@ import type { FDHeaderTextImageBlock as FDHeaderTextImageBlockProps, Media } fro
import { FDImage } from '@/components/FDImage' import { FDImage } from '@/components/FDImage'
const bgMap: Record<string, string> = { const bgMap: Record<string, string> = {
white: 'bg-white', white: 'bg-white dark:bg-fd-navy',
gray: 'bg-fd-gray-light', gray: 'bg-fd-gray-light dark:bg-fd-navy',
navy: 'bg-fd-navy', navy: 'bg-fd-navy',
} }
const textMap: Record<string, string> = { // Heading: navy→yellow in dark, white stays white
navy: 'text-fd-navy', const headingMap: Record<string, string> = {
navy: 'text-fd-navy dark:text-fd-yellow',
white: 'text-white',
}
// Body: navy→white in dark, white stays white
const bodyMap: Record<string, string> = {
navy: 'text-fd-navy dark:text-white',
white: 'text-white', white: 'text-white',
} }
const overlayMap: Record<string, string> = { const overlayMap: Record<string, string> = {
none: '', none: '',
navyLight: 'bg-fd-navy/20', navyLight: 'bg-fd-navy/20',
navyMedium: 'bg-fd-navy/40', navyMedium: 'bg-fd-navy/40',
yellowLight: 'bg-fd-yellow/20', yellowLight: 'bg-fd-yellow/20',
yellowMedium: 'bg-fd-yellow/40', yellowMedium:'bg-fd-yellow/40',
sepia: 'bg-[#8B7D3C]/30', sepia: 'bg-[#8B7D3C]/30',
blackLight: 'bg-black/20', blackLight: 'bg-black/20',
blackMedium: 'bg-black/40', blackMedium: 'bg-black/40',
} }
const roundedMap: Record<string, string> = { const roundedMap: Record<string, string> = {
none: '', none: '',
medium: 'rounded-[24px]', medium: 'rounded-[24px]',
large: 'rounded-[40px]', large: 'rounded-[40px]',
} }
export const FDHeaderTextImageBlockComponent: React.FC<FDHeaderTextImageBlockProps> = ({ export const FDHeaderTextImageBlockComponent: React.FC<FDHeaderTextImageBlockProps> = ({
@ -40,23 +47,24 @@ export const FDHeaderTextImageBlockComponent: React.FC<FDHeaderTextImageBlockPro
sectionBackground = 'white', sectionBackground = 'white',
textColor = 'navy', textColor = 'navy',
}) => { }) => {
const bg = bgMap[sectionBackground || 'white'] const bg = bgMap[sectionBackground || 'white']
const txt = textMap[textColor || 'navy'] const headClr = headingMap[textColor || 'navy']
const bodyClr = bodyMap[textColor || 'navy']
const overlay = overlayMap[imageOverlay || 'none'] const overlay = overlayMap[imageOverlay || 'none']
const rounded = roundedMap[imageRounded || 'large'] const rounded = roundedMap[imageRounded || 'large']
const align = textAlign === 'center' ? 'text-center' : 'text-left' const align = textAlign === 'center' ? 'text-center' : 'text-left'
const media = image as Media const media = image as Media
return ( return (
<section className={`w-full py-12 md:py-16 lg:py-20 ${bg}`}> <section className={`w-full py-16 md:py-20 lg:py-[99px] ${bg}`}>
<div className="max-w-[1200px] mx-auto px-6 md:px-8 flex flex-col gap-8 md:gap-10"> <div className="max-w-[1200px] mx-auto px-6 md:px-8 flex flex-col gap-8 md:gap-10">
{(heading || body) && ( {(heading || body) && (
<div className={`flex flex-col gap-4 md:gap-6 ${align} ${textAlign === 'center' ? 'max-w-[900px] mx-auto' : ''}`}> <div className={`flex flex-col gap-4 md:gap-6 ${align} ${textAlign === 'center' ? 'max-w-[900px] mx-auto' : ''}`}>
{heading && ( {heading && (
<h2 className={`font-joey-heavy text-fd-h1 ${txt}`}>{heading}</h2> <h2 className={`font-joey-heavy text-fd-h1 ${headClr}`}>{heading}</h2>
)} )}
{body && ( {body && (
<p className={`font-joey text-fd-body ${txt} opacity-80`}>{body}</p> <p className={`font-joey text-fd-body-lg ${bodyClr} opacity-80`}>{body}</p>
)} )}
</div> </div>
)} )}

View File

@ -3,22 +3,28 @@ import type { FDIconBarBlock as FDIconBarBlockProps, Media } from '@/payload-typ
import { FDImage } from '@/components/FDImage' import { FDImage } from '@/components/FDImage'
const bgMap: Record<string, string> = { const bgMap: Record<string, string> = {
white: 'bg-white', white: 'bg-white dark:bg-fd-navy',
gray: 'bg-fd-gray-light', gray: 'bg-fd-gray-light dark:bg-fd-navy',
navy: 'bg-fd-navy', navy: 'bg-fd-navy',
yellow: 'bg-fd-yellow', yellow: 'bg-fd-yellow',
} }
const textColorMap: Record<string, string> = { const headingMap: Record<string, string> = {
navy: 'text-fd-navy', navy: 'text-fd-navy dark:text-fd-yellow',
white: 'text-white', white: 'text-white',
} }
const labelMap: Record<string, string> = {
navy: 'text-fd-navy dark:text-white',
white: 'text-white',
}
// Icon circle bg — navy circles become yellow-tinted in dark when on a now-navy section
const iconBgMap: Record<string, string> = { const iconBgMap: Record<string, string> = {
navy: 'bg-fd-navy', navy: 'bg-fd-navy dark:bg-white/10',
yellow: 'bg-fd-yellow', yellow: 'bg-fd-yellow',
gray: 'bg-[#e5e5e5]', gray: 'bg-fd-gray-light dark:bg-white/10',
none: '', none: '',
} }
export const FDIconBarBlockComponent: React.FC<FDIconBarBlockProps> = ({ export const FDIconBarBlockComponent: React.FC<FDIconBarBlockProps> = ({
@ -28,16 +34,17 @@ export const FDIconBarBlockComponent: React.FC<FDIconBarBlockProps> = ({
sectionBackground = 'gray', sectionBackground = 'gray',
textColor = 'navy', textColor = 'navy',
}) => { }) => {
const bg = bgMap[sectionBackground || 'gray'] const bg = bgMap[sectionBackground || 'gray']
const txtColor = textColorMap[textColor || 'navy'] const headClr = headingMap[textColor || 'navy']
const iconBg = iconBgMap[iconStyle || 'navy'] const labelClr = labelMap[textColor || 'navy']
const iconBg = iconBgMap[iconStyle || 'navy']
const hasCircle = iconStyle !== 'none' const hasCircle = iconStyle !== 'none'
return ( return (
<section className={`w-full py-12 md:py-16 lg:py-20 ${bg}`}> <section className={`w-full py-16 md:py-20 lg:py-[99px] ${bg}`}>
<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-fd-h1 mb-10 md:mb-14 ${txtColor}`}> <h2 className={`font-joey-heavy text-fd-h1 mb-10 md:mb-14 ${headClr}`}>
{heading} {heading}
</h2> </h2>
)} )}
@ -61,7 +68,7 @@ export const FDIconBarBlockComponent: React.FC<FDIconBarBlockProps> = ({
/> />
)} )}
</div> </div>
<span className={`font-joey-bold text-fd-body text-center ${txtColor}`}> <span className={`font-joey-bold text-fd-body text-center ${labelClr}`}>
{item.label} {item.label}
</span> </span>
</div> </div>

View File

@ -12,18 +12,24 @@ export const FDLocationsGridBlockComponent: React.FC<Props> = ({
}) => { }) => {
const bgClass = const bgClass =
sectionBackground === 'navy' ? 'bg-fd-navy' : sectionBackground === 'navy' ? 'bg-fd-navy' :
sectionBackground === 'gray' ? 'bg-fd-surface-alt' : 'bg-white' sectionBackground === 'gray' ? 'bg-fd-gray-light dark:bg-fd-navy' :
'bg-white dark:bg-fd-navy'
const titleClass = sectionBackground === 'navy' ? 'text-fd-yellow' : 'text-fd-navy' const titleClass = sectionBackground === 'navy'
const bodyClass = sectionBackground === 'navy' ? 'text-white' : 'text-fd-navy' ? 'text-fd-yellow'
: 'text-fd-navy dark:text-fd-yellow'
const bodyClass = sectionBackground === 'navy'
? 'text-white'
: 'text-fd-navy dark:text-white'
const hoverBgClass = const hoverBgClass =
hoverColor === 'yellow' ? 'bg-fd-yellow' : hoverColor === 'yellow' ? 'bg-fd-yellow' :
hoverColor === 'mint' ? 'bg-fd-mint' : 'bg-fd-navy' hoverColor === 'mint' ? 'bg-fd-mint' : 'bg-fd-navy'
const hoverTextClass = const hoverTextClass =
hoverColor === 'yellow' ? 'text-fd-navy' : hoverColor === 'yellow' ? 'text-fd-navy' :
hoverColor === 'mint' ? 'text-fd-navy' : 'text-white' hoverColor === 'mint' ? 'text-fd-navy' : 'text-white'
return ( return (
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${bgClass}`}> <section className={`w-full py-16 md:py-20 lg:py-[99px] ${bgClass}`}>
@ -51,8 +57,8 @@ export const FDLocationsGridBlockComponent: React.FC<Props> = ({
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6"> <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6">
{(cards ?? []).map((card, i) => { {(cards ?? []).map((card, i) => {
const media = card.image as Media | undefined const media = card.image as Media | undefined
const isLink = Boolean(card.link) const isLink = Boolean(card.link)
const className = `group relative overflow-hidden rounded-[30px] md:rounded-[50px] aspect-[4/3] block ${isLink ? 'cursor-pointer' : ''}` const className = `group relative overflow-hidden rounded-[30px] md:rounded-[50px] aspect-[4/3] block ${isLink ? 'cursor-pointer' : ''}`
const inner = ( const inner = (

View File

@ -8,22 +8,23 @@ export const FDPartnersLogosBlockComponent: React.FC<FDPartnersLogosBlockProps>
sectionBackground = 'gray', sectionBackground = 'gray',
}) => { }) => {
const bgClass = const bgClass =
sectionBackground === 'navy' sectionBackground === 'navy' ? 'bg-fd-navy' :
? 'bg-fd-navy' sectionBackground === 'gray' ? 'bg-fd-gray-light dark:bg-fd-navy' :
: sectionBackground === 'gray' 'bg-white dark:bg-fd-navy'
? 'bg-fd-surface-alt'
: 'bg-white'
const titleClass = sectionBackground === 'navy' ? 'text-fd-yellow' : 'text-fd-navy' const titleClass = sectionBackground === 'navy'
? 'text-fd-yellow'
: 'text-fd-navy dark:text-fd-yellow'
// In dark mode, monochrome logos invert to be visible on navy bg
const imgFilter = const imgFilter =
displayMode === 'monochrome' displayMode === 'monochrome'
? 'grayscale opacity-40 hover:grayscale-0 hover:opacity-100 transition-all duration-500' ? 'grayscale opacity-40 hover:grayscale-0 hover:opacity-100 dark:invert dark:opacity-50 dark:hover:opacity-100 transition-all duration-500'
: 'hover:opacity-80 transition-opacity duration-300' : 'hover:opacity-80 transition-opacity duration-300'
return ( return (
<section className={`fd-section ${bgClass}`}> <section className={`w-full py-16 md:py-20 lg:py-[99px] ${bgClass}`}>
<div className="fd-container"> <div className="max-w-[1200px] mx-auto px-6 md:px-8">
{heading && ( {heading && (
<h2 className={`font-joey-medium text-fd-h2 text-center mb-10 md:mb-14 ${titleClass}`}> <h2 className={`font-joey-medium text-fd-h2 text-center mb-10 md:mb-14 ${titleClass}`}>
{heading} {heading}

View File

@ -3,14 +3,14 @@ import type { FDPricingCardBlock as FDPricingCardBlockProps } from '@/payload-ty
import { FDButton } from '@/components/FDButton' import { FDButton } from '@/components/FDButton'
const sectionBgMap: Record<string, string> = { const sectionBgMap: Record<string, string> = {
white: 'bg-white', white: 'bg-white dark:bg-fd-navy',
navy: 'bg-fd-navy', navy: 'bg-fd-navy',
gray: 'bg-fd-gray-light', gray: 'bg-fd-gray-light dark:bg-fd-navy',
yellow: 'bg-fd-yellow', yellow: 'bg-fd-yellow',
} }
const titleColorMap: Record<string, string> = { const titleColorMap: Record<string, string> = {
navy: 'text-fd-navy', navy: 'text-fd-navy dark:text-fd-yellow',
white: 'text-white', white: 'text-white',
yellow: 'text-fd-yellow', yellow: 'text-fd-yellow',
} }
@ -19,11 +19,41 @@ const cardStyleMap: Record<string, {
bg: string; border: string; title: string bg: string; border: string; title: string
subtitle: string; body: string; bullet: string; isDark: boolean subtitle: string; body: string; bullet: string; isDark: boolean
}> = { }> = {
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: {
navy: { bg: 'bg-fd-navy', border: '', title: 'text-fd-yellow', subtitle: 'text-white', body: 'text-white/80', bullet: 'text-white', isDark: true }, bg: 'bg-white dark:bg-white/10',
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 }, border: 'border-[2px] border-gray-200 dark:border-white/20',
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 }, title: 'text-fd-navy dark:text-fd-yellow',
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 }, subtitle: 'text-fd-navy dark:text-white',
body: 'text-fd-navy/80 dark:text-white/80',
bullet: 'text-fd-navy dark:text-white',
isDark: false,
},
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-fd-gray-light dark:bg-white/10',
border: '',
title: 'text-fd-navy dark:text-white',
subtitle: 'text-fd-navy dark:text-white',
body: 'text-fd-navy/80 dark:text-white/80',
bullet: 'text-fd-navy dark:text-white',
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 dark:bg-white/10 shadow-lg dark:shadow-none',
border: '',
title: 'text-fd-navy dark:text-fd-yellow',
subtitle: 'text-fd-navy dark:text-white',
body: 'text-fd-navy/80 dark:text-white/80',
bullet: 'text-fd-navy dark:text-white',
isDark: false,
},
} }
const buttonVariantMap: Record<string, { variant: 'primary' | 'outline' }> = { const buttonVariantMap: Record<string, { variant: 'primary' | 'outline' }> = {
@ -47,13 +77,13 @@ export const FDPricingCardBlockComponent: React.FC<FDPricingCardBlockProps> = ({
sectionBackground = 'white', sectionBackground = 'white',
titleColor = 'navy', titleColor = 'navy',
}) => { }) => {
const sectionBg = sectionBgMap[sectionBackground || 'white'] const sectionBg = sectionBgMap[sectionBackground || 'white']
const sectionTitleColor = titleColorMap[titleColor || 'navy'] const sectionTitleColor = titleColorMap[titleColor || 'navy']
const style = cardStyleMap[cardStyle || 'outlined'] const style = cardStyleMap[cardStyle || 'outlined']
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]
const outlineOnDark = style.isDark const outlineOnDark = style.isDark
return ( return (
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${sectionBg}`}> <section className={`w-full py-16 md:py-20 lg:py-[99px] ${sectionBg}`}>
@ -63,7 +93,6 @@ export const FDPricingCardBlockComponent: React.FC<FDPricingCardBlockProps> = ({
{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

View File

@ -14,10 +14,9 @@ export const FDServicesGridBlockComponent: React.FC<FDServicesGridBlockProps> =
columns = '4', columns = '4',
}) => { }) => {
return ( return (
// FIX: lg:py-24 → lg:py-[99px] (standard section padding) <section className="relative w-full bg-white dark:bg-fd-navy py-16 md:py-20 lg:py-[99px]">
<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 dark:text-fd-yellow mb-8 lg:mb-12">
{heading} {heading}
</h2> </h2>
@ -27,7 +26,7 @@ export const FDServicesGridBlockComponent: React.FC<FDServicesGridBlockProps> =
const content = ( const content = (
<div className="flex flex-col gap-4 md:gap-6 lg:gap-[30px]"> <div className="flex flex-col gap-4 md:gap-6 lg:gap-[30px]">
<h3 className="font-joey-bold text-fd-navy text-fd-h2"> <h3 className="font-joey-bold text-fd-navy dark:text-white text-fd-h2">
{service.title} {service.title}
</h3> </h3>
@ -41,7 +40,7 @@ export const FDServicesGridBlockComponent: React.FC<FDServicesGridBlockProps> =
/> />
)} )}
<p className="font-joey text-fd-navy text-fd-body"> <p className="font-joey text-fd-navy dark:text-white/80 text-fd-body">
{service.description} {service.description}
</p> </p>
</div> </div>

View File

@ -9,10 +9,10 @@ const heightMap: Record<string, string> = {
} }
const bgMap: Record<string, string> = { const bgMap: Record<string, string> = {
white: 'bg-white', white: 'bg-white dark:bg-fd-navy',
navy: 'bg-fd-navy', navy: 'bg-fd-navy',
gray: 'bg-fd-gray-light', gray: 'bg-fd-gray-light dark:bg-fd-navy',
yellow: 'bg-fd-yellow', yellow: 'bg-fd-yellow',
transparent: 'bg-transparent', transparent: 'bg-transparent',
} }

View File

@ -22,17 +22,24 @@ export const FDStatisticsBlockComponent: React.FC<Props> = ({
const bgClass = const bgClass =
sectionBackground === 'navy' ? 'bg-fd-navy' : sectionBackground === 'navy' ? 'bg-fd-navy' :
sectionBackground === 'gray' ? 'bg-fd-surface-alt' : 'bg-white' sectionBackground === 'gray' ? 'bg-fd-gray-light dark:bg-fd-navy' :
'bg-white dark:bg-fd-navy'
const titleClass = sectionBackground === 'navy' ? 'text-fd-yellow' : 'text-fd-navy' const titleClass = sectionBackground === 'navy'
const labelClass = sectionBackground === 'navy' ? 'text-white' : 'text-fd-navy' ? 'text-fd-yellow'
: 'text-fd-navy dark:text-fd-yellow'
const labelClass = sectionBackground === 'navy'
? 'text-white'
: 'text-fd-navy dark:text-white'
const getNumberClass = () => { const getNumberClass = () => {
if (numberColor === 'gradient') return 'bg-gradient-to-r from-fd-yellow to-fd-mint bg-clip-text text-transparent' if (numberColor === 'gradient') return 'bg-gradient-to-r from-fd-yellow to-fd-mint bg-clip-text text-transparent'
if (numberColor === 'yellow') return 'text-fd-yellow' if (numberColor === 'yellow') return 'text-fd-yellow'
if (numberColor === 'mint') return 'text-fd-mint' if (numberColor === 'mint') return 'text-fd-mint'
if (numberColor === 'white') return 'text-white' if (numberColor === 'white') return 'text-white'
return 'text-fd-navy' // navy number adapts in dark mode
return 'text-fd-navy dark:text-white'
} }
return ( return (
@ -52,7 +59,6 @@ export const FDStatisticsBlockComponent: React.FC<Props> = ({
}`} }`}
style={{ transitionDelay: `${i * 120}ms` }} style={{ transitionDelay: `${i * 120}ms` }}
> >
{/* Intentionally oversized for visual impact — not mapped to fd-* token */}
<span className={`font-joey-heavy text-5xl md:text-7xl lg:text-[96px] leading-none ${getNumberClass()}`}> <span className={`font-joey-heavy text-5xl md:text-7xl lg:text-[96px] leading-none ${getNumberClass()}`}>
{stat.number} {stat.number}
</span> </span>

View File

@ -2,10 +2,10 @@ import React from 'react'
import type { FDTagsBlock as FDTagsBlockProps } from '@/payload-types' import type { FDTagsBlock as FDTagsBlockProps } from '@/payload-types'
const tagStyleMap: Record<string, { bg: string; text: string; border: string }> = { const tagStyleMap: Record<string, { bg: string; text: string; border: string }> = {
navy: { bg: 'bg-fd-navy', text: 'text-fd-yellow', border: '' }, navy: { bg: 'bg-fd-navy', text: 'text-fd-yellow', border: '' },
yellow: { bg: 'bg-fd-yellow', text: 'text-fd-navy', border: '' }, yellow: { bg: 'bg-fd-yellow', text: 'text-fd-navy', border: '' },
outlined: { bg: 'bg-transparent', text: 'text-fd-navy', border: 'border-2 border-fd-navy' }, outlined: { bg: 'bg-transparent', text: 'text-fd-navy dark:text-white', border: 'border-2 border-fd-navy dark:border-white' },
gray: { bg: 'bg-fd-surface-alt', text: 'text-fd-navy', border: '' }, gray: { bg: 'bg-fd-gray-light dark:bg-white/10', text: 'text-fd-navy dark:text-white', border: '' },
} }
const tagSizeMap: Record<string, string> = { const tagSizeMap: Record<string, string> = {
@ -15,15 +15,15 @@ const tagSizeMap: Record<string, string> = {
} }
const sectionBgMap: Record<string, string> = { const sectionBgMap: Record<string, string> = {
white: 'bg-white', white: 'bg-white dark:bg-fd-navy',
navy: 'bg-fd-navy', navy: 'bg-fd-navy',
gray: 'bg-fd-gray-light', gray: 'bg-fd-gray-light dark:bg-fd-navy',
} }
const headingColorMap: Record<string, string> = { const headingColorMap: Record<string, string> = {
white: 'text-fd-navy', white: 'text-fd-navy dark:text-fd-yellow',
navy: 'text-fd-yellow', navy: 'text-fd-yellow',
gray: 'text-fd-navy', gray: 'text-fd-navy dark:text-fd-yellow',
} }
export const FDTagsBlockComponent: React.FC<FDTagsBlockProps> = ({ export const FDTagsBlockComponent: React.FC<FDTagsBlockProps> = ({
@ -34,14 +34,14 @@ export const FDTagsBlockComponent: React.FC<FDTagsBlockProps> = ({
alignment = 'left', alignment = 'left',
sectionBackground = 'white', sectionBackground = 'white',
}) => { }) => {
const style = tagStyleMap[tagStyle ?? 'navy'] || tagStyleMap.navy const style = tagStyleMap[tagStyle ?? 'navy'] || tagStyleMap.navy
const size = tagSizeMap[tagSize ?? 'large'] || tagSizeMap.large const size = tagSizeMap[tagSize ?? 'large'] || tagSizeMap.large
const sectionBg = sectionBgMap[sectionBackground || 'white'] const sectionBg = sectionBgMap[sectionBackground || 'white']
const headingColor = headingColorMap[sectionBackground || 'white'] const headingColor = headingColorMap[sectionBackground || 'white']
const justify = alignment === 'center' ? 'justify-center' : 'justify-start' const justify = alignment === 'center' ? 'justify-center' : 'justify-start'
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">
{heading && ( {heading && (
<h2 <h2

View File

@ -3,15 +3,33 @@ 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 dark:bg-fd-navy',
gray: 'bg-fd-gray-light', gray: 'bg-fd-gray-light dark:bg-fd-navy',
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: {
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' }, bg: 'bg-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' }, name: 'text-fd-yellow',
role: 'text-white/70',
bio: 'text-white/60',
icon: 'text-white/40 hover:text-fd-yellow',
},
white: {
bg: 'bg-white dark:bg-white/10',
name: 'text-fd-navy dark:text-white',
role: 'text-fd-navy/60 dark:text-white/60',
bio: 'text-fd-navy/60 dark:text-white/60',
icon: 'text-fd-navy/40 hover:text-fd-navy dark:text-white/40 dark:hover:text-white',
},
gray: {
bg: 'bg-fd-gray-light dark:bg-white/10',
name: 'text-fd-navy dark:text-white',
role: 'text-fd-navy/60 dark:text-white/60',
bio: 'text-fd-navy/60 dark:text-white/60',
icon: 'text-fd-navy/40 hover:text-fd-navy dark:text-white/40 dark:hover:text-white',
},
} }
const colsMap: Record<string, string> = { const colsMap: Record<string, string> = {
@ -28,42 +46,38 @@ export const FDTeamBlockComponent: React.FC<FDTeamBlockProps> = ({
cardStyle = 'navy', cardStyle = 'navy',
sectionBackground = 'white', sectionBackground = 'white',
}) => { }) => {
const sectionBg = sectionBgMap[sectionBackground ?? 'white'] || sectionBgMap.white const sectionBg = sectionBgMap[sectionBackground ?? 'white'] || sectionBgMap.white
const card = cardMap[cardStyle ?? 'navy'] || cardMap.navy const card = cardMap[cardStyle ?? 'navy'] || cardMap.navy
const gridCols = colsMap[columns ?? '3'] || colsMap['3'] const gridCols = colsMap[columns ?? '3'] || colsMap['3']
const isNavySection = sectionBackground === 'navy' const isNavySection = sectionBackground === 'navy'
return ( return (
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${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">
{/* Header */}
{(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-fd-h1 ${isNavySection ? 'text-fd-yellow' : 'text-fd-navy'}`}> <h2 className={`font-joey-heavy text-fd-h1 ${isNavySection ? 'text-fd-yellow' : 'text-fd-navy dark:text-fd-yellow'}`}>
{heading} {heading}
</h2> </h2>
)} )}
{subheading && ( {subheading && (
<p className={`font-joey text-fd-body-lg ${isNavySection ? 'text-white/70' : 'text-fd-navy/60'}`}> <p className={`font-joey text-fd-body-lg ${isNavySection ? 'text-white/70' : 'text-fd-navy/60 dark:text-white/70'}`}>
{subheading} {subheading}
</p> </p>
)} )}
</div> </div>
)} )}
{/* 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 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 */}
<div className="aspect-[4/3] w-full overflow-hidden"> <div className="aspect-[4/3] w-full overflow-hidden">
{hasPhoto ? ( {hasPhoto ? (
<FDImage <FDImage
@ -74,7 +88,7 @@ export const FDTeamBlockComponent: React.FC<FDTeamBlockProps> = ({
fallbackAlt={member.name} fallbackAlt={member.name}
/> />
) : ( ) : (
<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 dark:bg-white/5'}`}>
<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" />
<path d="M10 72c0-16.6 13.4-30 30-30s30 13.4 30 30H10z" /> <path d="M10 72c0-16.6 13.4-30 30-30s30 13.4 30 30H10z" />
@ -83,7 +97,6 @@ export const FDTeamBlockComponent: React.FC<FDTeamBlockProps> = ({
)} )}
</div> </div>
{/* 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-fd-h3 ${card.name}`}>{member.name}</p> <p className={`font-joey-bold text-fd-h3 ${card.name}`}>{member.name}</p>
<p className={`font-joey text-fd-small ${card.role}`}>{member.role}</p> <p className={`font-joey text-fd-small ${card.role}`}>{member.role}</p>
@ -94,28 +107,17 @@ export const FDTeamBlockComponent: React.FC<FDTeamBlockProps> = ({
</p> </p>
)} )}
{/* Links */}
{(member.email || member.linkedin) && ( {(member.email || member.linkedin) && (
<div className="flex items-center gap-4 mt-4"> <div className="flex items-center gap-4 mt-4">
{member.email && ( {member.email && (
<a <a href={`mailto:${member.email}`} aria-label={`E-post till ${member.name}`} className={`transition-colors ${card.icon}`}>
href={`mailto:${member.email}`}
aria-label={`E-post till ${member.name}`}
className={`transition-colors ${card.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>
</a> </a>
)} )}
{member.linkedin && ( {member.linkedin && (
<a <a href={member.linkedin} target="_blank" rel="noopener noreferrer" aria-label={`LinkedIn för ${member.name}`} className={`transition-colors ${card.icon}`}>
href={member.linkedin}
target="_blank"
rel="noopener noreferrer"
aria-label={`LinkedIn för ${member.name}`}
className={`transition-colors ${card.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>

View File

@ -3,20 +3,22 @@ import type { FDTechPropertiesBlock as FDTechPropertiesBlockProps } from '@/payl
const bgMap: Record<string, string> = { const bgMap: Record<string, string> = {
navy: 'bg-fd-navy', navy: 'bg-fd-navy',
white: 'bg-white', white: 'bg-white dark:bg-fd-navy',
gray: 'bg-fd-gray-light', gray: 'bg-fd-gray-light dark:bg-fd-navy',
yellow: 'bg-fd-yellow', yellow: 'bg-fd-yellow',
} }
// Category label (small text above value)
const catColorMap: Record<string, string> = { const catColorMap: Record<string, string> = {
white: 'text-white', white: 'text-white',
navy: 'text-fd-navy', navy: 'text-fd-navy dark:text-white/70',
} }
// Value (large number/text)
const valColorMap: Record<string, string> = { const valColorMap: Record<string, string> = {
yellow: 'text-fd-yellow', yellow: 'text-fd-yellow',
white: 'text-white', white: 'text-white',
navy: 'text-fd-navy', navy: 'text-fd-navy dark:text-fd-yellow',
} }
export const FDTechPropertiesBlockComponent: React.FC<FDTechPropertiesBlockProps> = ({ export const FDTechPropertiesBlockComponent: React.FC<FDTechPropertiesBlockProps> = ({
@ -25,15 +27,15 @@ export const FDTechPropertiesBlockComponent: React.FC<FDTechPropertiesBlockProps
categoryColor = 'white', categoryColor = 'white',
valueColor = 'yellow', valueColor = 'yellow',
}) => { }) => {
const bg = bgMap[sectionBackground || 'navy'] const bg = bgMap[sectionBackground || 'navy']
const catColor = catColorMap[categoryColor || 'white'] const catColor = catColorMap[categoryColor || 'white']
const valColor = valColorMap[valueColor || 'yellow'] const valColor = valColorMap[valueColor || 'yellow']
const count = properties?.length || 1 const count = properties?.length || 1
const gridCols = const gridCols =
count <= 2 ? 'grid-cols-2' : count === 3 ? 'grid-cols-3' : 'grid-cols-2 md:grid-cols-4' count <= 2 ? 'grid-cols-2' : count === 3 ? 'grid-cols-3' : 'grid-cols-2 md:grid-cols-4'
return ( return (
<section className={`w-full py-12 md:py-16 lg:py-20 ${bg}`}> <section className={`w-full py-16 md:py-20 lg:py-[99px] ${bg}`}>
<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 ${gridCols} gap-8 md:gap-12`}> <div className={`grid ${gridCols} gap-8 md:gap-12`}>
{properties?.map((prop, index) => ( {properties?.map((prop, index) => (

View File

@ -2,13 +2,36 @@ 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, {
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' }, section: string; card: string
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' }, quote: string; meta: string; name: string; accent: string
navy: { section: 'bg-fd-navy', card: 'bg-white/10', quote: 'text-white', meta: 'text-white/60', name: 'text-white', company: 'text-white/50' }, }> = {
gray: {
section: 'bg-fd-gray-light dark:bg-fd-navy',
card: 'bg-white dark:bg-white/10',
quote: 'text-fd-navy dark:text-white',
meta: 'text-fd-navy/60 dark:text-white/60',
name: 'text-fd-navy dark:text-white',
accent: 'text-fd-navy dark:text-fd-yellow',
},
white: {
section: 'bg-white dark:bg-fd-navy',
card: 'bg-fd-gray-light dark:bg-white/10',
quote: 'text-fd-navy dark:text-white',
meta: 'text-fd-navy/60 dark:text-white/60',
name: 'text-fd-navy dark:text-white',
accent: 'text-fd-navy dark:text-fd-yellow',
},
navy: {
section: 'bg-fd-navy',
card: 'bg-white/10',
quote: 'text-white',
meta: 'text-white/60',
name: 'text-white',
accent: 'text-fd-yellow',
},
} }
/** Avatar helper — uses FDImage with media object correctly */
const Avatar: React.FC<{ media: Media | undefined; name: string; size: number }> = ({ media, name, size }) => { const Avatar: React.FC<{ media: Media | undefined; name: string; size: number }> = ({ media, name, size }) => {
if (!media?.url) return null if (!media?.url) return null
return ( return (
@ -33,26 +56,24 @@ export const FDTestimonialBlockComponent: React.FC<FDTestimonialBlockProps> = ({
layout = 'grid', layout = 'grid',
sectionBackground = 'gray', sectionBackground = 'gray',
}) => { }) => {
const theme = bgMap[sectionBackground ?? 'gray'] || 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-fd-h1 mb-10 md:mb-14 ${isNavy ? 'text-fd-yellow' : 'text-fd-navy'}`}> <h2 className={`font-joey-heavy text-fd-h1 mb-10 md:mb-14 ${theme.accent}`}>
{heading} {heading}
</h2> </h2>
)} )}
{isFeatured && testimonials && testimonials.length > 0 ? ( {isFeatured && testimonials && testimonials.length > 0 ? (
// ── Featured layout: first testimonial large, rest below ──────
<div className="flex flex-col gap-6"> <div className="flex flex-col gap-6">
{/* First testimonial — large */} {/* First testimonial — large */}
{(() => { {(() => {
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-8 md:px-16 py-10 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`}>
@ -72,7 +93,6 @@ export const FDTestimonialBlockComponent: React.FC<FDTestimonialBlockProps> = ({
) )
})()} })()}
{/* Remaining testimonials — smaller grid */}
{testimonials.length > 1 && ( {testimonials.length > 1 && (
<div className="grid grid-cols-1 md:grid-cols-2 gap-6"> <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{testimonials.slice(1).map((t, i) => { {testimonials.slice(1).map((t, i) => {
@ -98,14 +118,12 @@ export const FDTestimonialBlockComponent: React.FC<FDTestimonialBlockProps> = ({
)} )}
</div> </div>
) : ( ) : (
// ── Grid layout ───────────────────────────────────────────────
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{testimonials?.map((t, i) => { {testimonials?.map((t, i) => {
const avatar = t.avatar as Media | undefined const avatar = t.avatar as Media | undefined
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 */} <span className={`font-joey-heavy text-5xl leading-none ${theme.accent} opacity-30`}>
<span className={`font-joey-heavy text-5xl leading-none ${isNavy ? 'text-fd-yellow' : 'text-fd-navy'} opacity-30`}>
&ldquo; &ldquo;
</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}`}>

View File

@ -3,9 +3,9 @@ import type { FDTextBlock as FDTextBlockProps } from '@/payload-types'
import RichText from '@/components/RichText' import RichText from '@/components/RichText'
const bgMap: Record<string, string> = { const bgMap: Record<string, string> = {
white: 'bg-white', white: 'bg-white dark:bg-fd-navy',
navy: 'bg-fd-navy', navy: 'bg-fd-navy',
gray: 'bg-fd-gray-light', gray: 'bg-fd-gray-light dark:bg-fd-navy',
yellow: 'bg-fd-yellow', yellow: 'bg-fd-yellow',
} }
@ -22,10 +22,15 @@ const maxWidthMap: Record<string, string> = {
full: '', full: '',
} }
// Navy text color = adapts to dark mode. White/yellow = always explicit.
const textColorMap: Record<string, { h1: string; h2: string; body: string }> = { const textColorMap: Record<string, { h1: string; h2: string; body: string }> = {
navy: { h1: 'text-fd-navy', h2: 'text-fd-navy', body: 'text-fd-navy' }, navy: {
white: { h1: 'text-white', h2: 'text-white', body: 'text-white/90' }, h1: 'text-fd-navy dark:text-fd-yellow',
yellow: { h1: 'text-fd-yellow', h2: 'text-fd-yellow', body: 'text-fd-yellow/90' }, h2: 'text-fd-navy dark:text-fd-yellow',
body: 'text-fd-navy dark:text-white',
},
white: { h1: 'text-white', h2: 'text-white', body: 'text-white/90' },
yellow: { h1: 'text-fd-yellow', h2: 'text-fd-yellow', body: 'text-fd-yellow/90' },
} }
export const FDTextBlockComponent: React.FC<FDTextBlockProps> = ({ export const FDTextBlockComponent: React.FC<FDTextBlockProps> = ({
@ -37,9 +42,9 @@ export const FDTextBlockComponent: React.FC<FDTextBlockProps> = ({
sectionBackground = 'white', sectionBackground = 'white',
maxWidth = 'wide', maxWidth = 'wide',
}) => { }) => {
const bg = bgMap[sectionBackground || 'white'] const bg = bgMap[sectionBackground || 'white']
const align = alignMap[alignment || 'left'] const align = alignMap[alignment || 'left']
const width = maxWidthMap[maxWidth || 'wide'] const width = maxWidthMap[maxWidth || 'wide']
const colors = textColorMap[textColor || 'navy'] const colors = textColorMap[textColor || 'navy']
const containerAlign = const containerAlign =
alignment === 'center' ? 'mx-auto' : alignment === 'right' ? 'ml-auto' : '' alignment === 'center' ? 'mx-auto' : alignment === 'right' ? 'ml-auto' : ''
@ -47,7 +52,7 @@ export const FDTextBlockComponent: React.FC<FDTextBlockProps> = ({
if (!heading && !subheading && !body) return null if (!heading && !subheading && !body) return null
return ( return (
<section className={`w-full py-12 md:py-16 lg:py-20 ${bg}`}> <section className={`w-full py-16 md:py-20 lg:py-[99px] ${bg}`}>
<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={`${width} ${containerAlign} ${align} flex flex-col gap-4 md:gap-6`}> <div className={`${width} ${containerAlign} ${align} flex flex-col gap-4 md:gap-6`}>
{heading && ( {heading && (

View File

@ -3,13 +3,18 @@ import type { FDUspChecklistBlock as FDUspChecklistBlockProps, Media } from '@/p
import { FDImage } from '@/components/FDImage' import { FDImage } from '@/components/FDImage'
const bgMap: Record<string, string> = { const bgMap: Record<string, string> = {
white: 'bg-white', white: 'bg-white dark:bg-fd-navy',
gray: 'bg-fd-gray-light', gray: 'bg-fd-gray-light dark:bg-fd-navy',
navy: 'bg-fd-navy', navy: 'bg-fd-navy',
} }
const textMap: Record<string, string> = { const headingMap: Record<string, string> = {
navy: 'text-fd-navy', navy: 'text-fd-navy dark:text-fd-yellow',
white: 'text-white',
}
const bodyMap: Record<string, string> = {
navy: 'text-fd-navy dark:text-white',
white: 'text-white', white: 'text-white',
} }
@ -38,19 +43,20 @@ export const FDUspChecklistBlockComponent: React.FC<FDUspChecklistBlockProps> =
sectionBackground = 'white', sectionBackground = 'white',
textColor = 'navy', textColor = 'navy',
}) => { }) => {
const bg = bgMap[sectionBackground || 'white'] const bg = bgMap[sectionBackground || 'white']
const txt = textMap[textColor || 'navy'] const headClr = headingMap[textColor || 'navy']
const media = image as Media | undefined const bodyClr = bodyMap[textColor || 'navy']
const media = image as Media | undefined
const hasImage = Boolean(media?.url) const hasImage = Boolean(media?.url)
const textContent = ( const textContent = (
<div className="flex-1 flex flex-col gap-6 md:gap-8"> <div className="flex-1 flex flex-col gap-6 md:gap-8">
<h2 className={`font-joey-heavy text-fd-h1 ${txt}`}>{heading}</h2> <h2 className={`font-joey-heavy text-fd-h1 ${headClr}`}>{heading}</h2>
<div className="flex flex-col gap-5 md:gap-6"> <div className="flex flex-col gap-5 md:gap-6">
{items?.map((item, index) => ( {items?.map((item, index) => (
<div key={index} className="flex items-start gap-4"> <div key={index} className="flex items-start gap-4">
<CheckIcon color={checkColor || 'navy'} /> <CheckIcon color={checkColor || 'navy'} />
<span className={`font-joey text-fd-body-lg pt-1 ${txt}`}>{item.text}</span> <span className={`font-joey text-fd-body-lg pt-1 ${bodyClr}`}>{item.text}</span>
</div> </div>
))} ))}
</div> </div>
@ -70,7 +76,7 @@ export const FDUspChecklistBlockComponent: React.FC<FDUspChecklistBlockProps> =
) : null ) : null
return ( return (
<section className={`w-full py-12 md:py-16 lg:py-20 ${bg}`}> <section className={`w-full py-16 md:py-20 lg:py-[99px] ${bg}`}>
<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' ? <>{imageContent}{textContent}</> : <>{textContent}{imageContent}</>} {imagePosition === 'left' ? <>{imageContent}{textContent}</> : <>{textContent}{imageContent}</>}
</div> </div>

View File

@ -3,18 +3,30 @@ import type { FDUspTableBlock as FDUspTableBlockProps } from '@/payload-types'
import RichText from '@/components/RichText' import RichText from '@/components/RichText'
const bgMap: Record<string, string> = { const bgMap: Record<string, string> = {
white: 'bg-white', white: 'bg-white dark:bg-fd-navy',
gray: 'bg-fd-gray-light', gray: 'bg-fd-gray-light dark:bg-fd-navy',
navy: 'bg-fd-navy', navy: 'bg-fd-navy',
} }
const textMap: Record<string, string> = { // Heading: navy bg → yellow in dark
navy: 'text-fd-navy', const headingMap: Record<string, string> = {
navy: 'text-fd-navy dark:text-fd-yellow',
white: 'text-white', white: 'text-white',
} }
// Body / row titles: navy bg → white in dark
const textMap: Record<string, string> = {
navy: 'text-fd-navy dark:text-white',
white: 'text-white',
}
const proseMap: Record<string, string> = {
navy: 'text-fd-navy/80 dark:text-white/80',
white: 'text-white/80',
}
const borderMap: Record<string, string> = { const borderMap: Record<string, string> = {
navy: 'border-fd-navy/10', navy: 'border-fd-navy/10 dark:border-white/20',
white: 'border-white/20', white: 'border-white/20',
} }
@ -41,16 +53,17 @@ export const FDUspTableBlockComponent: React.FC<FDUspTableBlockProps> = ({
sectionBackground = 'white', sectionBackground = 'white',
textColor = 'navy', textColor = 'navy',
}) => { }) => {
const bg = bgMap[sectionBackground || 'white'] const bg = bgMap[sectionBackground || 'white']
const txt = textMap[textColor || 'navy'] const headClr = headingMap[textColor || 'navy']
const border = borderMap[textColor || 'navy'] const txt = textMap[textColor || 'navy']
const proseOpacity = textColor === 'white' ? 'opacity-80' : 'opacity-80' const prose = proseMap[textColor || 'navy']
const border = borderMap[textColor || 'navy']
return ( return (
<section className={`w-full py-12 md:py-16 lg:py-20 ${bg}`}> <section className={`w-full py-16 md:py-20 lg:py-[99px] ${bg}`}>
<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-fd-h1 mb-10 md:mb-14 ${txt}`}>{heading}</h2> <h2 className={`font-joey-heavy text-fd-h1 mb-10 md:mb-14 ${headClr}`}>{heading}</h2>
)} )}
<div className="flex flex-col"> <div className="flex flex-col">
{rows?.map((row, index) => ( {rows?.map((row, index) => (
@ -64,7 +77,7 @@ export const FDUspTableBlockComponent: React.FC<FDUspTableBlockProps> = ({
<CheckIcon color={checkColor || 'navy'} /> <CheckIcon color={checkColor || 'navy'} />
<span className={`font-joey-bold text-fd-h3 ${txt}`}>{row.title}</span> <span className={`font-joey-bold text-fd-h3 ${txt}`}>{row.title}</span>
</div> </div>
<div className={`font-joey text-fd-body fd-prose ${txt} ${proseOpacity} md:pl-0 pl-14`}> <div className={`font-joey text-fd-body fd-prose ${prose} md:pl-0 pl-14`}>
<RichText data={(row.description) as any} /> <RichText data={(row.description) as any} />
</div> </div>
</div> </div>

View File

@ -4,22 +4,22 @@ import { FDButton } from '@/components/FDButton'
import { FDImage } from '@/components/FDImage' 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-fd-gray-light', heading: 'text-fd-navy', body: 'text-fd-navy/80', isDark: false }, gray: { bg: 'bg-fd-gray-light dark:bg-white/10', heading: 'text-fd-navy dark:text-white', body: 'text-fd-navy/80 dark:text-white/80', isDark: false },
white: { bg: 'bg-white shadow-xl', heading: 'text-fd-navy', body: 'text-fd-navy/80', isDark: false }, white: { bg: 'bg-white dark:bg-white/10 shadow-xl dark:shadow-none', heading: 'text-fd-navy dark:text-white', body: 'text-fd-navy/80 dark:text-white/80', isDark: false },
} }
const sectionBgMap: Record<string, string> = { const sectionBgMap: Record<string, string> = {
white: 'bg-white', white: 'bg-white dark:bg-fd-navy',
gray: 'bg-fd-gray-light', gray: 'bg-fd-gray-light dark:bg-fd-navy',
navy: 'bg-fd-navy', navy: 'bg-fd-navy',
} }
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' },
white: { variant: 'primary' }, white: { variant: 'primary' },
} }
export const FDWideCardBlockComponent: React.FC<FDWideCardBlockProps> = ({ export const FDWideCardBlockComponent: React.FC<FDWideCardBlockProps> = ({
@ -32,11 +32,11 @@ export const FDWideCardBlockComponent: React.FC<FDWideCardBlockProps> = ({
buttonColor = 'yellow', buttonColor = 'yellow',
sectionBackground = 'white', sectionBackground = 'white',
}) => { }) => {
const card = cardBgMap[cardBackground || 'navy'] const card = cardBgMap[cardBackground || 'navy']
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 hasImage = media && typeof media === 'object' && media.url const hasImage = media && typeof media === 'object' && media.url
return ( return (
<section className={`w-full py-16 md:py-20 lg:py-[99px] ${sectionBg}`}> <section className={`w-full py-16 md:py-20 lg:py-[99px] ${sectionBg}`}>
@ -53,18 +53,13 @@ export const FDWideCardBlockComponent: React.FC<FDWideCardBlockProps> = ({
)} )}
{ctaText && ( {ctaText && (
<div> <div>
<FDButton <FDButton href={ctaLink || '#'} variant={variant} onDark={card.isDark}>
href={ctaLink || '#'}
variant={variant}
onDark={card.isDark}
>
{ctaText} {ctaText}
</FDButton> </FDButton>
</div> </div>
)} )}
</div> </div>
{/* FIX: replaced raw <img> with FDImage */}
{hasImage && ( {hasImage && (
<div className="relative flex-1 min-h-[250px] lg:min-h-0"> <div className="relative flex-1 min-h-[250px] lg:min-h-0">
<FDImage <FDImage

File diff suppressed because one or more lines are too long