diff --git a/dotcom-rendering/index.d.ts b/dotcom-rendering/index.d.ts
index 1a1c58d2719..b066dd816ef 100644
--- a/dotcom-rendering/index.d.ts
+++ b/dotcom-rendering/index.d.ts
@@ -551,3 +551,10 @@ declare namespace JSX {
'data-link-name'?: string;
}
}
+
+declare namespace React {
+ interface CSSProperties {
+ // Allow custom properties to be passed to the style prop
+ [key: `--${string}`]: string | undefined;
+ }
+}
diff --git a/dotcom-rendering/src/components/Card/components/CardWrapper.tsx b/dotcom-rendering/src/components/Card/components/CardWrapper.tsx
index b46714fa96f..d07bf4d4441 100644
--- a/dotcom-rendering/src/components/Card/components/CardWrapper.tsx
+++ b/dotcom-rendering/src/components/Card/components/CardWrapper.tsx
@@ -5,6 +5,7 @@ import { from, neutral } from '@guardian/source-foundations';
import { decidePalette } from '../../../lib/decidePalette';
import type { DCRContainerPalette } from '../../../types/front';
import type { Palette } from '../../../types/palette';
+import { ContainerOverrides } from '../../ContainerOverrides';
import { FormatBoundary } from '../../FormatBoundary';
type Props = {
@@ -182,14 +183,20 @@ export const CardWrapper = ({
const palette = decidePalette(format, containerPalette);
return (
-
- {children}
-
+
+ {children}
+
+
);
};
diff --git a/dotcom-rendering/src/components/CardHeadline.stories.tsx b/dotcom-rendering/src/components/CardHeadline.stories.tsx
index 1e328d91eb1..c835faf5084 100644
--- a/dotcom-rendering/src/components/CardHeadline.stories.tsx
+++ b/dotcom-rendering/src/components/CardHeadline.stories.tsx
@@ -1,14 +1,16 @@
+import type { ArticleFormat } from '@guardian/libs';
import {
ArticleDesign,
ArticleDisplay,
ArticleSpecial,
Pillar,
} from '@guardian/libs';
-import { breakpoints, specialReport } from '@guardian/source-foundations';
+import { breakpoints, palette } from '@guardian/source-foundations';
import type { StoryObj } from '@storybook/react';
import { splitTheme } from '../../.storybook/decorators/splitThemeDecorator';
import type { DCRContainerPalette } from '../types/front';
import { CardHeadline } from './CardHeadline';
+import { ContainerOverrides } from './ContainerOverrides';
import { Section } from './Section';
export default {
@@ -39,6 +41,11 @@ export const Article = () => (
);
Article.storyName = 'Article';
+const specialReport = {
+ display: ArticleDisplay.Standard,
+ design: ArticleDesign.Analysis,
+ theme: ArticleSpecial.SpecialReport,
+} satisfies ArticleFormat;
export const Analysis = () => (
<>
{smallHeadlineSizes.map((size) => (
@@ -110,16 +117,14 @@ export const Analysis = () => (
fullWidth={true}
showTopBorder={false}
showSideBorders={false}
- backgroundColour={specialReport[300]}
+ backgroundColour={palette.specialReport[300]}
>
-
+
+
+
>
);
@@ -305,26 +310,35 @@ export const OpinionKicker = () => (
);
OpinionKicker.storyName = 'With an opinion kicker';
-export const SpecialReport = () => (
+export const SpecialReport: StoryObj = ({
+ format,
+}: {
+ format: ArticleFormat;
+}) => (
);
SpecialReport.storyName = 'With theme SpecialReport';
+SpecialReport.args = {
+ format: {
+ display: ArticleDisplay.Standard,
+ design: ArticleDesign.Standard,
+ theme: ArticleSpecial.SpecialReport,
+ },
+};
export const Busy = () => (
@@ -342,105 +356,70 @@ export const Busy = () => (
);
Busy.storyName = 'Lifestyle opinion';
-export const Byline = () => (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
+export const Byline: StoryObj = ({ format }: { format: ArticleFormat }) => (
+
- >
+
+
);
Byline.storyName = 'With byline';
+Byline.decorators = [
+ splitTheme([
+ {
+ display: ArticleDisplay.Standard,
+ design: ArticleDesign.Feature,
+ theme: ArticleSpecial.Labs,
+ },
+ {
+ display: ArticleDisplay.Standard,
+ design: ArticleDesign.Feature,
+ theme: Pillar.News,
+ },
+ {
+ display: ArticleDisplay.Standard,
+ design: ArticleDesign.Feature,
+ theme: Pillar.Sport,
+ },
+ {
+ display: ArticleDisplay.Standard,
+ design: ArticleDesign.Feature,
+ theme: Pillar.Culture,
+ },
+ {
+ display: ArticleDisplay.Standard,
+ design: ArticleDesign.Feature,
+ theme: Pillar.Lifestyle,
+ },
+ {
+ display: ArticleDisplay.Standard,
+ design: ArticleDesign.Feature,
+ theme: Pillar.Opinion,
+ },
+ {
+ display: ArticleDisplay.Standard,
+ design: ArticleDesign.Feature,
+ theme: ArticleSpecial.SpecialReport,
+ },
+ ]),
+];
const containerPalettes = [
'EventPalette',
@@ -469,17 +448,23 @@ export const WithContainerOverrides: StoryObj = ({
showSideBorders={false}
containerPalette={containerPalette}
>
-
+ containerPalette={containerPalette}
+ isDynamo={false}
+ >
+
+
))}
>
diff --git a/dotcom-rendering/src/components/CardHeadline.tsx b/dotcom-rendering/src/components/CardHeadline.tsx
index 25b706d0d38..d26d6706dde 100644
--- a/dotcom-rendering/src/components/CardHeadline.tsx
+++ b/dotcom-rendering/src/components/CardHeadline.tsx
@@ -14,6 +14,7 @@ import { Link, SvgExternal } from '@guardian/source-react-components';
import React from 'react';
import { decidePalette } from '../lib/decidePalette';
import { getZIndex } from '../lib/getZIndex';
+import { palette as schemedPalette } from '../palette';
import type { DCRContainerPalette } from '../types/front';
import type { Palette } from '../types/palette';
import { Byline } from './Byline';
@@ -287,9 +288,7 @@ export const CardHeadline = ({
{showQuotes && }
diff --git a/dotcom-rendering/src/components/ContainerOverrides.tsx b/dotcom-rendering/src/components/ContainerOverrides.tsx
new file mode 100644
index 00000000000..db59eace65e
--- /dev/null
+++ b/dotcom-rendering/src/components/ContainerOverrides.tsx
@@ -0,0 +1,49 @@
+import { css } from '@emotion/react';
+import { decideContainerOverrides } from '../lib/decideContainerOverrides';
+import { decidePalette } from '../lib/decidePalette';
+import type { palette } from '../palette';
+import type { DCRContainerPalette } from '../types/front';
+
+type Props = {
+ children: React.ReactNode;
+ format: ArticleFormat;
+ isDynamo: boolean;
+ containerPalette?: DCRContainerPalette;
+};
+
+/** @see https://developer.mozilla.org/en-US/docs/Web/CSS/display-box#contents */
+const displayContents = css`
+ display: contents;
+`;
+
+type ColourName = Parameters[0];
+
+/**
+ * Add CSS custom property overrides for palette colours in a given container
+ */
+export const ContainerOverrides = ({
+ containerPalette,
+ isDynamo,
+ children,
+ format,
+}: Props) => {
+ const { text } = containerPalette
+ ? decideContainerOverrides(containerPalette)
+ : { text: undefined };
+
+ const paletteOverrides = {
+ '--headline-colour': isDynamo
+ ? text?.dynamoHeadline ?? decidePalette(format).text.dynamoHeadline
+ : text?.cardHeadline ?? decidePalette(format).text.cardHeadline,
+ } satisfies Partial>;
+
+ return (
+
+ {children}
+
+ );
+};