)}
)}
{/* Main body content */}
-
+
diff --git a/components/Storyblok/SbMegaMenu/SbMegaMenu.styles.ts b/components/Storyblok/SbMegaMenu/SbMegaMenu.styles.ts
index 6fda39601..c522e3528 100644
--- a/components/Storyblok/SbMegaMenu/SbMegaMenu.styles.ts
+++ b/components/Storyblok/SbMegaMenu/SbMegaMenu.styles.ts
@@ -60,6 +60,6 @@ export const cardRoot = (backgroundColor: DarkBgColorType = 'digital-red') => cn
export const cardImageWrapper = 'hidden lg:block overflow-hidden';
export const cardImage = 'group-hocus-within:scale-105 transition-transform';
export const cardContent = 'rs-px-2 rs-pt-2 rs-pb-3 group-hover:bg-black-true/40 group-focus-within:bg-black-true/40 transition-colors';
-export const cardHeading = 'rs-mb-1 type-3 lg:type-2';
-export const headingLink = 'stretched-link no-underline text-white hocus:text-white hocus:underline';
-export const cardCtaTextIcon = 'group-hocus-within:translate-x-02em';
+export const cardHeading = 'group-hocus-within:underline rs-mb-1 type-3 lg:type-2';
+
+export const cta = 'rs-mt-1 stretched-link hocus:no-underline';
diff --git a/components/Storyblok/SbMegaMenu/SbMegaMenuCard.tsx b/components/Storyblok/SbMegaMenu/SbMegaMenuCard.tsx
index b0e6beb55..2a69bf891 100644
--- a/components/Storyblok/SbMegaMenu/SbMegaMenuCard.tsx
+++ b/components/Storyblok/SbMegaMenu/SbMegaMenuCard.tsx
@@ -1,7 +1,7 @@
import { type SbBlokData, storyblokEditable } from '@storyblok/react/rsc';
import { AspectRatioImage } from '@/components/Image';
-import { SbLink } from '@/components/Storyblok/partials/SbLink';
-import { Heading, Paragraph } from '@/components/Typography';
+import { CtaLink } from '@/components/Cta';
+import { Heading } from '@/components/Typography';
import { type SbImageType, type SbLinkType } from '@/components/Storyblok/Storyblok.types';
import { type DarkBgColorType } from '@/utilities/datasource';
import * as styles from './SbMegaMenu.styles';
@@ -31,7 +31,6 @@ export const SbMegaMenuCard = ({ blok }: SbMegaMenuCardProps) => {
{
)}
{headline && (
-
-
- {headline}
-
+
+ {headline}
)}
{ctaText && (
-
{ctaText}
-
+
)}
diff --git a/components/Storyblok/SbQuoteCard.tsx b/components/Storyblok/SbQuoteCard.tsx
index ca2e1f4db..ba4df52b3 100644
--- a/components/Storyblok/SbQuoteCard.tsx
+++ b/components/Storyblok/SbQuoteCard.tsx
@@ -29,7 +29,7 @@ export const SbQuoteCard = ({ blok }: SbQuoteCardProps) => {
const {
quoteText,
quoteSource,
- image: { filename, alt, focus} = {},
+ image: { filename, focus } = {},
showImage,
visibleHorizontal = 'center',
visibleVertical = 'top',
@@ -69,7 +69,6 @@ export const SbQuoteCard = ({ blok }: SbQuoteCardProps) => {
quoteText={QuoteText}
quoteSource={QuoteSource}
filename={displayImage ? filename : ''}
- alt={displayImage ? alt : ''}
focus={displayImage ? focus : ''}
visibleHorizontal={displayImage ? visibleHorizontal : undefined}
visibleVertical={displayImage ? visibleVertical : undefined}
diff --git a/components/Storyblok/SbStoryImage.tsx b/components/Storyblok/SbStoryImage.tsx
index a19d19047..dac083f73 100644
--- a/components/Storyblok/SbStoryImage.tsx
+++ b/components/Storyblok/SbStoryImage.tsx
@@ -1,6 +1,6 @@
import { storyblokEditable, type SbBlokData } from '@storyblok/react/rsc';
import { type StoryblokRichtext } from 'storyblok-rich-text-react-renderer';
-import { StoryImage, type VisibleVerticalType } from '@/components/Image';
+import { StoryImage, type VisibleVerticalType, ImageAspectRatioType } from '@/components/Image';
import { StoryImageWidthType } from '@/components/Media';
import { RichText } from '@/components/RichText';
import { type TextAlignType } from '@/components/Typography';
@@ -12,6 +12,7 @@ type SbStoryImageProps = {
blok: SbBlokData & {
image: SbImageType;
alt?: string;
+ aspectRatio?: ImageAspectRatioType | 'free';
imageWidth?: StoryImageWidthType;
visibleVertical?: VisibleVerticalType;
caption?: StoryblokRichtext;
@@ -25,7 +26,8 @@ type SbStoryImageProps = {
export const SbStoryImage = ({
blok: {
- image: { filename, alt } = {},
+ image: { filename, alt, focus } = {},
+ aspectRatio,
caption,
captionAlign,
isCard,
@@ -37,6 +39,12 @@ export const SbStoryImage = ({
},
blok,
}: SbStoryImageProps) => {
+ /**
+ * If user chooses the "Edge to edge" option (su-w-full), use the 10x3 aspect ratio for cropping
+ * Previously we didn't crop the image, but use a container height of 30vw to simulate the 10x3 ratio
+ * Cropping the image is better because the user can now set an image focus and it reduces the image size
+ */
+ const effectiveAspectRatio = imageWidth === 'su-w-full' ? '10x3' : aspectRatio || 'free';
const Caption = hasRichText(caption)
? {
superheadline,
headline,
link,
- image: { filename, alt, focus } = {},
+ image: { filename, focus } = {},
showImage,
visibleHorizontal = 'center',
visibleVertical = 'center',
@@ -41,7 +41,6 @@ export const SbTileCard = ({ blok }: SbTileCardProps) => {
headline={headline}
link={link}
filename={showImage ? filename : ''}
- alt={showImage ? alt : ''}
focus={showImage ? focus : ''}
visibleHorizontal={showImage ? visibleHorizontal : undefined}
visibleVertical={showImage ? visibleVertical : undefined}
diff --git a/components/Storyblok/partials/PageLayout.tsx b/components/Storyblok/partials/PageLayout.tsx
index 2aa621c61..bea6265b5 100644
--- a/components/Storyblok/partials/PageLayout.tsx
+++ b/components/Storyblok/partials/PageLayout.tsx
@@ -47,7 +47,7 @@ export const PageLayout = ({
oodCampaignHeader={oodCampaignHeader}
slug={slug}
/>
-
+
{children}
diff --git a/components/TileCard/TileCard.styles.ts b/components/TileCard/TileCard.styles.ts
index de8692664..09e518009 100644
--- a/components/TileCard/TileCard.styles.ts
+++ b/components/TileCard/TileCard.styles.ts
@@ -2,12 +2,10 @@ import { cnb } from 'cnbuilder';
export const superhead = 'text-09em mb-16 md:max-lg:text-[.8em]';
-export const heading = 'fluid-type-2 md:max-lg:text-25';
-
-export const link = 'group stretched-link font-semibold';
+export const link = 'group stretched-link font-semibold no-underline';
export const linkText = (hasDarkText: boolean) => cnb(
- 'lg:leading-tight group-hocus:underline',
+ 'lg:leading-tight group-hocus:underline fluid-type-2 md:max-lg:text-25',
hasDarkText ? 'group-hocus:text-digital-red' : 'group-hocus:text-white',
);
diff --git a/components/TileCard/TileCard.tsx b/components/TileCard/TileCard.tsx
index 6ebbadfc1..82ec228b8 100644
--- a/components/TileCard/TileCard.tsx
+++ b/components/TileCard/TileCard.tsx
@@ -22,46 +22,42 @@ const TileCardContent = ({
superheadline,
headline,
link,
- headingLevel = 'h3',
+ headingLevel,
}: TileCardContentProps) => {
const isExternalLink = link?.linktype !== 'story';
return (
<>
{superheadline && (
-
{superheadline}
-
+
)}
-
-
-
- {headline}
-
-
-
+
+
+ {headline}
+
+
>
);
};
@@ -73,7 +69,6 @@ export const TileCard = ({
headline,
link,
filename,
- alt,
focus,
visibleHorizontal,
visibleVertical,
@@ -96,7 +91,6 @@ export const TileCard = ({
hasLink
bgColor={a11yBgColor}
filename={filename}
- alt={alt}
focus={focus}
visibleHorizontal={visibleHorizontal}
visibleVertical={visibleVertical}
diff --git a/styles/tables.css b/styles/tables.css
index c2c5e9e9f..92e9b910c 100644
--- a/styles/tables.css
+++ b/styles/tables.css
@@ -1,6 +1,6 @@
/* Table styles for Giving */
table:not(.life-income-gifts) tr {
- @apply even:bg-fog-light;
+ @apply even:bg-fog-light odd:bg-white;
}
/* Wrapper styles that adds the horizontal scroll if the table is wider than the viewport */
diff --git a/utilities/getImageSources.ts b/utilities/getImageSources.ts
index 792a4c50d..f2ea13b5c 100644
--- a/utilities/getImageSources.ts
+++ b/utilities/getImageSources.ts
@@ -1,4 +1,5 @@
import { getProcessedImage } from './getProcessedImage';
+import { getSbImageSize } from './getSbImageSize';
type ResponsiveBreakpointType = {
cropWidth: number;
@@ -11,34 +12,26 @@ type ImageSourceType = {
};
// Default breakpoints for generating responsive images
-const defaultResponsiveBreakpoints: ResponsiveBreakpointType[] = [
+const srcsetBreakpoints: ResponsiveBreakpointType[] = [
{ cropWidth: 2000, minWidth: 1500 },
{ cropWidth: 1500, minWidth: 1200 },
{ cropWidth: 1200, minWidth: 992 },
- { cropWidth: 1000, minWidth: 768 },
- { cropWidth: 800, minWidth: 461 },
- { cropWidth: 460, minWidth: 0 }, // Mobile/smallest size
+ { cropWidth: 1000, minWidth: 576 },
+ { cropWidth: 600, minWidth: 0 }, // Mobile/smallest size
];
/**
* Generates responsive image sources for use with picture element
*
* @param filename - The image filename from Storyblok
- * @param originalWidth - Original width of the image
- * @param originalHeight - Original height of the image
- * @param customBreakpoints - Optional custom breakpoints to override defaults
* @returns Array of image sources with srcSet and media queries
*/
-export const getImageSources = (
- filename: string,
- originalWidth: number,
- customBreakpoints?: ResponsiveBreakpointType[],
-): ImageSourceType[] => {
+export const getImageSources = ( filename: string ): ImageSourceType[] => {
const sources: ImageSourceType[] = [];
- const breakpoints = customBreakpoints || defaultResponsiveBreakpoints;
+ const { width: originalWidth } = getSbImageSize(filename);
// If the original image width is < 2000px, find out what breakpoint range it falls into
- const largestBp = breakpoints.find(bp => originalWidth >= bp.minWidth && originalWidth < bp.cropWidth);
+ const largestBp = srcsetBreakpoints.find(bp => originalWidth >= bp.minWidth && originalWidth < bp.cropWidth);
// If we found an appropriate breakpoint, insert the original image at that breakpoint
// For example, if the original image is 1100px, it will be used for the min-width: 992px breakpoint
@@ -50,9 +43,9 @@ export const getImageSources = (
}
// Add all smaller sizes that are relevant
- breakpoints
+ srcsetBreakpoints
// First pass: always include the mobile size, and keep all the breakpoints with minWidth < the original image width
- .filter(bp => bp.cropWidth < originalWidth || bp.cropWidth === 460)
+ .filter(bp => bp.cropWidth < originalWidth || bp.cropWidth === 600)
// If the original image is wider than 2000px (no largestBp assigned), keep all the breakpoints from the first pass
// Otherwise, keep only the breakpoints that are smaller than the largestBp
.filter(bp => !largestBp || bp.minWidth < largestBp.minWidth)