Typography: - Raise all fd-* token minimums in globals.css for larger mobile text (fd-h1: 28→40px, fd-h2: 22→32px, fd-h3: 18→22px, body-lg: 15→18px, body: 14→16px) - Strip all text-[x] sm:text-fd-* overrides from 25 block components — tokens now handle full range, no block-level hacks - Change RichText enableGutter default to false — fixes rich text indenting in FAQ, TextBlock, posts, and form confirmations Layout fixes (mobile): - FDContactBlock: 3-column grid on all screen sizes - FDHeroBlock: full-width buttons on mobile - FDServicesGridBlock: px-3 padding on description text under images - FDWideCardBlock: image now padded inside card, object-contain, no longer bleeds edge-to-edge - FDCtaSideImageBlock: consistent mobile order (heading → image → body → button) regardless of imagePosition setting; extra mt-4 between body and button on mobile - FDTestimonialBlock: quote text sizes migrated to fd-h3/fd-body-lg tokens
100 lines
3.7 KiB
TypeScript
100 lines
3.7 KiB
TypeScript
import React from 'react'
|
|
import type { FDCtaSideImageBlock as FDCtaSideImageBlockProps } from '@/payload-types'
|
|
import type { Media } from '@/payload-types'
|
|
import { FDImage } from '@/components/FDImage'
|
|
import { FDButton } from '@/components/FDButton'
|
|
|
|
/* Priority #5: Responsive radius */
|
|
const imageRadius = 'rounded-[32px] md:rounded-[50px] lg:rounded-[70px]'
|
|
|
|
/* Color overlay — same map as FDHeaderTextImageBlock */
|
|
const overlayMap: Record<string, string> = {
|
|
none: '',
|
|
navyLight: 'bg-fd-navy/20',
|
|
navyMedium: 'bg-fd-navy/40',
|
|
yellowLight: 'bg-fd-yellow/20',
|
|
yellowMedium:'bg-fd-yellow/40',
|
|
sepia: 'bg-[#8B7D3C]/30',
|
|
blackLight: 'bg-black/20',
|
|
blackMedium: 'bg-black/40',
|
|
}
|
|
|
|
export const FDCtaSideImageBlockComponent: React.FC<FDCtaSideImageBlockProps> = ({
|
|
heading,
|
|
body,
|
|
ctaText,
|
|
ctaLink = '#',
|
|
image,
|
|
imageOverlay = 'none',
|
|
imagePosition = 'right',
|
|
theme = 'dark',
|
|
anchorId,
|
|
}) => {
|
|
const isDark = theme === 'dark'
|
|
const hasImage = !!image
|
|
const overlay = overlayMap[(imageOverlay as string) || 'none'] || ''
|
|
|
|
// 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'
|
|
|
|
// Mobile order is always: heading → image → body → button
|
|
// Desktop order respects imagePosition (left/right)
|
|
// We achieve this by splitting heading from body+button and using CSS order
|
|
|
|
const desktopTextOrder = imagePosition === 'left' ? 'min-[820px]:order-2' : 'min-[820px]:order-1'
|
|
const desktopImageOrder = imagePosition === 'left' ? 'min-[820px]:order-1' : 'min-[820px]:order-2'
|
|
|
|
return (
|
|
<section id={anchorId || undefined} className={`w-full py-16 md:py-20 lg:py-[99px] ${sectionBg}`}>
|
|
<div className="max-w-[1200px] mx-auto px-6 md:px-8 flex flex-col min-[820px]:flex-row min-[820px]:items-center gap-6 min-[820px]:gap-16">
|
|
|
|
{/* Heading — always first on mobile */}
|
|
<h2 className={`w-full font-joey-heavy text-fd-h1 leading-tight order-1 min-[820px]:hidden ${headingClass}`}>
|
|
{heading}
|
|
</h2>
|
|
|
|
{/* Image — always second on mobile, position-aware on desktop */}
|
|
{hasImage && (
|
|
<div className={`relative w-full min-[820px]:w-[45%] lg:w-[575px] lg:h-[479px] flex-shrink-0 overflow-hidden order-2 ${desktopImageOrder} ${imageRadius}`}>
|
|
<FDImage
|
|
media={image as Media}
|
|
size="large"
|
|
fallbackAlt={heading}
|
|
className="w-full h-full object-cover"
|
|
sizes="(max-width: 1024px) 100vw, 575px"
|
|
/>
|
|
{overlay && <div className={`absolute inset-0 ${overlay}`} />}
|
|
</div>
|
|
)}
|
|
|
|
{/* Text block — heading hidden on mobile (shown above), body+button always third */}
|
|
<div className={`flex flex-col flex-1 items-start gap-4 min-[820px]:gap-[41px] order-3 ${desktopTextOrder} ${!hasImage ? 'max-w-2xl' : ''}`}>
|
|
{/* Heading shown only on desktop inside the text column */}
|
|
<h2 className={`hidden min-[820px]:block w-full font-joey-heavy text-fd-h1 leading-tight ${headingClass}`}>
|
|
{heading}
|
|
</h2>
|
|
<p className={`w-full font-joey text-fd-body-lg leading-relaxed ${bodyClass}`}>
|
|
{body}
|
|
</p>
|
|
{ctaText && (
|
|
<FDButton href={ctaLink || '#'} variant="primary" onDark={isDark} className="w-full sm:w-auto justify-center mt-4 min-[820px]:mt-0">
|
|
{ctaText}
|
|
</FDButton>
|
|
)}
|
|
</div>
|
|
|
|
</div>
|
|
</section>
|
|
)
|
|
}
|