diff --git a/dotcom-rendering/src/components/ArticleBody.tsx b/dotcom-rendering/src/components/ArticleBody.tsx
index 68d530f071d..d6f9b463a05 100644
--- a/dotcom-rendering/src/components/ArticleBody.tsx
+++ b/dotcom-rendering/src/components/ArticleBody.tsx
@@ -55,6 +55,7 @@ type Props = {
shouldHideAds: boolean;
serverTime?: number;
idApiUrl?: string;
+ isOldInteractive?: boolean;
};
const globalOlStyles = () => css`
@@ -145,6 +146,7 @@ export const ArticleBody = ({
shouldHideAds,
serverTime,
idApiUrl,
+ isOldInteractive = false,
}: Props) => {
const isInteractiveContent =
format.design === ArticleDesign.Interactive ||
@@ -266,6 +268,7 @@ export const ArticleBody = ({
contributionsServiceUrl={contributionsServiceUrl}
shouldHideAds={shouldHideAds}
idApiUrl={idApiUrl}
+ isOldInteractive={isOldInteractive}
/>
{hasObserverPublicationTag && }
diff --git a/dotcom-rendering/src/components/Figure.tsx b/dotcom-rendering/src/components/Figure.tsx
index 83a444ac608..04d2d1da1ea 100644
--- a/dotcom-rendering/src/components/Figure.tsx
+++ b/dotcom-rendering/src/components/Figure.tsx
@@ -1,12 +1,5 @@
import { css } from '@emotion/react';
-import {
- breakpoints,
- from,
- palette as sourcePalette,
- space,
- until,
-} from '@guardian/source/foundations';
-import type { LayoutType } from '../layouts/lib/articleArrangements';
+import { from, space, until } from '@guardian/source/foundations';
import { ArticleDesign, type ArticleFormat } from '../lib/articleFormat';
import { transparentColour } from '../lib/transparentColour';
import { palette } from '../palette';
@@ -110,47 +103,7 @@ const roleCss = {
margin-top: ${space[3]}px;
margin-bottom: ${space[3]}px;
- ${until.tablet} {
- margin-left: -20px;
- margin-right: -20px;
- }
- ${until.mobileLandscape} {
- margin-left: -10px;
- margin-right: -10px;
- }
- ${from.tablet} {
- --scrollbar-width-fallback: 15px;
- --half-scrollbar-width-fallback: 7.5px;
-
- width: calc(
- 100vw - var(--scrollbar-width, var(--scrollbar-width-fallback))
- );
- max-width: calc(
- 100vw - var(--scrollbar-width, var(--scrollbar-width-fallback))
- );
-
- --grid-container-max-width: 740px;
- --grid-container-left-margin: calc(
- ((-100vw + (var(--grid-container-max-width) - 42px)) / 2) +
- var(
- --half-scrollbar-width,
- var(--half-scrollbar-width-fallback)
- )
- );
-
- margin-left: var(--grid-container-left-margin);
- }
- ${from.desktop} {
- --grid-container-max-width: ${breakpoints.desktop}px;
- }
- ${from.leftCol} {
- --grid-container-max-width: ${breakpoints.leftCol}px;
- --grid-left-col-width: 140px;
- }
- ${from.wide} {
- --grid-container-max-width: ${breakpoints.wide}px;
- --grid-left-col-width: 219px;
- }
+ grid-column: 1 / -1;
`,
showcase: css`
diff --git a/dotcom-rendering/src/components/MostViewedRightWithAd.island.tsx b/dotcom-rendering/src/components/MostViewedRightWithAd.island.tsx
index f2d7c2de9ed..71b490c4249 100644
--- a/dotcom-rendering/src/components/MostViewedRightWithAd.island.tsx
+++ b/dotcom-rendering/src/components/MostViewedRightWithAd.island.tsx
@@ -68,13 +68,13 @@ export const MostViewedRightWithAd = ({
/>
) : null}
- {!isPaidContent && !shouldHideMostViewed ? (
+ {!isPaidContent && !shouldHideMostViewed && (
- ) : null}
+ )}
{isApps && }
diff --git a/dotcom-rendering/src/components/SlotBodyEnd.island.tsx b/dotcom-rendering/src/components/SlotBodyEnd.island.tsx
index 115b9326d88..85f13d085ff 100644
--- a/dotcom-rendering/src/components/SlotBodyEnd.island.tsx
+++ b/dotcom-rendering/src/components/SlotBodyEnd.island.tsx
@@ -13,6 +13,7 @@ import type {
} from '@guardian/support-dotcom-components/dist/dotcom/types';
import type { EpicProps } from '@guardian/support-dotcom-components/dist/shared/types';
import { useEffect, useState } from 'react';
+import { grid } from '../grid';
import { getArticleCounts } from '../lib/articleCount';
import {
BrazeBannersSystemPlacementId,
@@ -56,6 +57,10 @@ type Props = {
const slotStyles = css`
color: ${palette.neutral[7]};
+ ${grid.container};
+ & > *:first-child {
+ ${grid.column.centre};
+ }
`;
const buildReaderRevenueEpicConfig = (
diff --git a/dotcom-rendering/src/components/SubMeta.tsx b/dotcom-rendering/src/components/SubMeta.tsx
index 7be376741d0..18f9eb90aaa 100644
--- a/dotcom-rendering/src/components/SubMeta.tsx
+++ b/dotcom-rendering/src/components/SubMeta.tsx
@@ -14,6 +14,7 @@ import { grid } from '../grid';
import { ArticleDesign, type ArticleFormat } from '../lib/articleFormat';
import type { BaseLinkType } from '../model/extract-nav';
import { palette } from '../palette';
+import { palette as themePalette } from '../palette';
import { Island } from './Island';
import { ShareButton } from './ShareButton.island';
@@ -130,6 +131,7 @@ type Props = {
webUrl: string;
webTitle: string;
showBottomSocialButtons: boolean;
+ isDeprecatedInteractiveLayout?: boolean;
};
const syndicationButtonOverrides = css`
@@ -205,6 +207,7 @@ export const SubMeta = ({
webUrl,
webTitle,
showBottomSocialButtons,
+ isDeprecatedInteractiveLayout = false,
}: Props) => {
const createLinks = () => {
const links: BaseLinkType[] = [];
@@ -229,14 +232,29 @@ export const SubMeta = ({
* {
+ ${grid.column.centre}
+ }
+ `
+ : undefined,
]}
>
+
{format.design === ArticleDesign.Gallery && (
diff --git a/dotcom-rendering/src/layouts/DecideLayout.tsx b/dotcom-rendering/src/layouts/DecideLayout.tsx
index eb0399542fa..3394500a6cc 100644
--- a/dotcom-rendering/src/layouts/DecideLayout.tsx
+++ b/dotcom-rendering/src/layouts/DecideLayout.tsx
@@ -14,7 +14,6 @@ import { HostedArticleLayout } from './HostedArticleLayout';
import { HostedGalleryLayout } from './HostedGalleryLayout';
import { HostedVideoLayout } from './HostedVideoLayout';
import { ImmersiveLayout } from './ImmersiveLayout';
-import { InteractiveLayout } from './InteractiveLayout';
import { LiveLayout } from './LiveLayout';
import { NewsletterSignupLayout } from './NewsletterSignupLayout';
import { PictureLayout } from './PictureLayout';
@@ -137,14 +136,12 @@ const DecideLayoutApps = ({ article, renderingTarget }: AppProps) => {
switch (article.design) {
case ArticleDesign.Interactive:
return (
-
);
-
case ArticleDesign.FullPageInteractive: {
return (
{
switch (article.design) {
case ArticleDesign.Interactive:
return (
-
);
case ArticleDesign.FullPageInteractive: {
diff --git a/dotcom-rendering/src/layouts/FullPageInteractiveLayout.tsx b/dotcom-rendering/src/layouts/FullPageInteractiveLayout.tsx
index 0bb9c91a48c..c7697bcd7f5 100644
--- a/dotcom-rendering/src/layouts/FullPageInteractiveLayout.tsx
+++ b/dotcom-rendering/src/layouts/FullPageInteractiveLayout.tsx
@@ -28,7 +28,7 @@ import type { ArticleDeprecated } from '../types/article';
import type { Switches } from '../types/config';
import type { FEElement } from '../types/content';
import type { RenderingTarget } from '../types/renderingTarget';
-import { temporaryBodyCopyColourOverride } from './InteractiveLayout';
+import { temporaryBodyCopyColourOverride } from './interactives/InteractiveArticleGridDeprecated';
import { interactiveGlobalStyles } from './lib/interactiveLegacyStyling';
import { BannerWrapper, Stuck } from './lib/stickiness';
diff --git a/dotcom-rendering/src/layouts/InteractiveLayout.tsx b/dotcom-rendering/src/layouts/InteractiveLayout.tsx
deleted file mode 100644
index 80e2f30611e..00000000000
--- a/dotcom-rendering/src/layouts/InteractiveLayout.tsx
+++ /dev/null
@@ -1,840 +0,0 @@
-import { css, Global } from '@emotion/react';
-import {
- from,
- palette as sourcePalette,
- space,
- until,
-} from '@guardian/source/foundations';
-import { Hide } from '@guardian/source/react-components';
-import { StraightLines } from '@guardian/source-development-kitchen/react-components';
-import type React from 'react';
-import { AdSlot, MobileStickyContainer } from '../components/AdSlot.web';
-import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer';
-import { AppsFooter } from '../components/AppsFooter.island';
-import { ArticleBody } from '../components/ArticleBody';
-import { ArticleContainer } from '../components/ArticleContainer';
-import { ArticleHeadline } from '../components/ArticleHeadline';
-import { ArticleMetaApps } from '../components/ArticleMeta.apps';
-import { ArticleMeta } from '../components/ArticleMeta.web';
-import { ArticleTitle } from '../components/ArticleTitle';
-import { Border } from '../components/Border';
-import { Carousel } from '../components/Carousel.island';
-import { DecideLines } from '../components/DecideLines';
-import { DirectoryPageNavIsland } from '../components/DirectoryPageNavIsland';
-import { DiscussionLayout } from '../components/DiscussionLayout';
-import { Footer } from '../components/Footer';
-import { GridItem } from '../components/GridItem';
-import { HeaderAdSlot } from '../components/HeaderAdSlot';
-import { InteractivesDisableArticleSwipe } from '../components/InteractivesDisableArticleSwipe.island';
-import { InteractivesNativePlatformWrapper } from '../components/InteractivesNativePlatformWrapper.island';
-import { InteractivesScrollbarWidth } from '../components/InteractivesScrollbarWidth.island';
-import { Island } from '../components/Island';
-import { LabsHeader } from '../components/LabsHeader';
-import { MainMedia } from '../components/MainMedia';
-import { Masthead } from '../components/Masthead/Masthead';
-import { MostViewedFooterData } from '../components/MostViewedFooterData.island';
-import { MostViewedFooterLayout } from '../components/MostViewedFooterLayout';
-import { OnwardsUpper } from '../components/OnwardsUpper.island';
-import { Section } from '../components/Section';
-import { SlotBodyEnd } from '../components/SlotBodyEnd.island';
-import { Standfirst } from '../components/Standfirst';
-import { StickyBottomBanner } from '../components/StickyBottomBanner.island';
-import { SubMeta } from '../components/SubMeta';
-import { SubNav } from '../components/SubNav.island';
-import { type ArticleFormat, ArticleSpecial } from '../lib/articleFormat';
-import { canRenderAds } from '../lib/canRenderAds';
-import { getContributionsServiceUrl } from '../lib/contributions';
-import { decideStoryPackageTrails } from '../lib/decideTrail';
-import type { NavType } from '../model/extract-nav';
-import { palette as themePalette } from '../palette';
-import type { ArticleDeprecated } from '../types/article';
-import type { RoleType } from '../types/content';
-import type { RenderingTarget } from '../types/renderingTarget';
-import {
- interactiveGlobalStyles,
- interactiveLegacyClasses,
-} from './lib/interactiveLegacyStyling';
-import { BannerWrapper, Stuck } from './lib/stickiness';
-
-const InteractiveGrid = ({ children }: { children: React.ReactNode }) => (
-
- {children}
-
-);
-
-const maxWidth = css`
- ${from.desktop} {
- max-width: 620px;
- }
-`;
-
-const stretchLines = css`
- ${until.phablet} {
- margin-left: -20px;
- margin-right: -20px;
- }
- ${until.mobileLandscape} {
- margin-left: -10px;
- margin-right: -10px;
- }
-`;
-
-export const temporaryBodyCopyColourOverride = css`
- .content__main-column--interactive p {
- /* stylelint-disable-next-line declaration-no-important */
- color: ${themePalette('--article-text')} !important;
- }
-`;
-
-interface CommonProps {
- article: ArticleDeprecated;
- format: ArticleFormat;
- renderingTarget: RenderingTarget;
- serverTime?: number;
-}
-
-interface WebProps extends CommonProps {
- NAV: NavType;
- renderingTarget: 'Web';
-}
-
-interface AppsProps extends CommonProps {
- renderingTarget: 'Apps';
-}
-
-export const InteractiveLayout = (props: WebProps | AppsProps) => {
- const { article, format, renderingTarget, serverTime } = props;
- const {
- config: { isPaidContent, host, hasSurveyAd },
- editionId,
- } = article;
-
- const isApps = renderingTarget === 'Apps';
- const isWeb = renderingTarget === 'Web';
-
- const showComments = article.isCommentable && !isPaidContent;
-
- const { branding } = article.commercialProperties[article.editionId];
-
- const contributionsServiceUrl = getContributionsServiceUrl(article);
-
- const renderAds = canRenderAds(article);
-
- const includesFullWidthElement = article.blocks.some((block) =>
- block.elements.some((element) => {
- const role =
- 'role' in element
- ? (element.role as RoleType | 'fullWidth' | undefined)
- : undefined;
- return role === 'fullWidth';
- }),
- );
-
- return (
- <>
- {includesFullWidthElement && (
-
-
-
- )}
- {isApps && (
- <>
-
-
-
-
-
-
-
- >
- )}
- {article.isLegacyInteractive && (
-
- )}
- {isWeb && (
- <>
-
- {renderAds && (
-
-
-
-
-
- )}
-
-
tag.id)}
- sectionId={article.config.section}
- contentType={article.contentType}
- />
-
-
- {format.theme === ArticleSpecial.Labs && (
-
-
-
- )}
-
- {renderAds && hasSurveyAd && (
-
- )}
- >
- )}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {format.theme === ArticleSpecial.Labs ? (
- <>>
- ) : (
-
- )}
-
-
-
-
-
-
-
-
-
-
-
-
- {isApps ? (
- <>
-
-
-
-
-
-
- >
- ) : (
-
- )}
-
-
- {article.affiliateLinksDisclaimerRequired && (
-
-
-
- )}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {isWeb && renderAds && (
-
- )}
-
- {article.storyPackage && (
-
- )}
-
-
-
-
-
- {showComments && (
-
- )}
-
- {!isPaidContent && (
-
- )}
-
- {isWeb && renderAds && (
-
- )}
-
-
- {isWeb && props.NAV.subNavSections && (
-
- )}
-
- {isWeb && (
- <>
-
-
-
-
-
-
-
- {renderAds && (
-
- )}
- >
- )}
- {isApps && (
-
- )}
- >
- );
-};
diff --git a/dotcom-rendering/src/layouts/StandardLayout.tsx b/dotcom-rendering/src/layouts/StandardLayout.tsx
index cd5abdf5f3d..8bc45908ffb 100644
--- a/dotcom-rendering/src/layouts/StandardLayout.tsx
+++ b/dotcom-rendering/src/layouts/StandardLayout.tsx
@@ -33,6 +33,7 @@ import type { NavType } from '../model/extract-nav';
import { palette as themePalette } from '../palette';
import type { ArticleDeprecated } from '../types/article';
import type { RenderingTarget } from '../types/renderingTarget';
+import { InteractiveArticleGridDeprecated } from './interactives/InteractiveArticleGridDeprecated';
import { BannerWrapper, Stuck } from './lib/stickiness';
import { StandardLayoutArticleGrid } from './StandardLayoutArticleGrid';
@@ -43,12 +44,12 @@ interface Props {
serverTime?: number;
}
-interface WebProps extends Props {
+export interface WebProps extends Props {
NAV: NavType;
renderingTarget: 'Web';
}
-interface AppProps extends Props {
+export interface AppProps extends Props {
renderingTarget: 'Apps';
}
@@ -84,6 +85,12 @@ export const StandardLayout = (props: WebProps | AppProps) => {
const isCricketMatchReport =
format.design === ArticleDesign.MatchReport && !!cricketMatchHeaderUrl;
+ const interactiveLayoutSwitchoverDate = new Date('2024-06-01T00:00:00Z');
+ const publicationDate = new Date(article.webPublicationDate);
+ const isLegacyInteractive =
+ publicationDate < interactiveLayoutSwitchoverDate &&
+ format.design === ArticleDesign.Interactive;
+
const showComments = article.isCommentable && !isPaidContent;
const contributionsServiceUrl = getContributionsServiceUrl(article);
@@ -176,11 +183,15 @@ export const StandardLayout = (props: WebProps | AppProps) => {
{/* This element is used to replace the article with the scorecard when the scorecard tab is clicked */}
-
+ {isLegacyInteractive ? (
+
+ ) : (
+
+ )}
{isWeb && renderAds && !isLabs && (
diff --git a/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx b/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx
index 2a2c70ede75..7139f798546 100644
--- a/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx
+++ b/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx
@@ -2,7 +2,6 @@ import { css } from '@emotion/react';
import { log } from '@guardian/libs';
import { from, space, until } from '@guardian/source/foundations';
import { Hide } from '@guardian/source/react-components';
-import { StraightLines } from '@guardian/source-development-kitchen/react-components';
import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer';
import { AppsEpic } from '../components/AppsEpic.island';
import { ArticleBody } from '../components/ArticleBody';
@@ -132,58 +131,23 @@ export const StandardLayoutArticleGrid = ({
format.design === ArticleDesign.Video ||
format.design === ArticleDesign.Audio;
const isShowcase = format.display === ArticleDisplay.Showcase;
- const isImmersive = format.display === ArticleDisplay.Immersive;
- const isFeature = format.design === ArticleDesign.Feature;
+ const isInteractive = format.design === ArticleDesign.Interactive;
- const isFootballMatchReport =
- format.design === ArticleDesign.MatchReport && !!footballMatchStatsUrl;
-
- const mainMedia = article.mainMediaElements[0];
- const captionText = decideMainMediaCaption(mainMedia);
- const mainMediaUrl: string | undefined =
- mainMedia?._type ===
- 'model.dotcomrendering.pageElements.ImageBlockElement'
- ? mainMedia.media.allImages[0]?.url
- : undefined;
- const mainMediaAspectRatio =
- mainMedia?._type ===
- 'model.dotcomrendering.pageElements.ImageBlockElement'
- ? mainMedia.media.allImages[0]?.fields.aspectRatio
+ const footballMatchUrl =
+ article.matchType === 'FootballMatchType'
+ ? article.matchUrl
: undefined;
- const mainMediaOrientation =
- mainMediaUrl != null ? getImageOrientation(mainMediaUrl) : 'landscape';
-
- const layoutType = getLayoutType({
- isImmersive,
- isFeature,
- orientation: mainMediaOrientation,
- isMedia,
- isShowcase,
- });
- const contentLayoutName = `${ArticleDisplay[format.display]}Layout`;
-
- const isImmersivePortrait =
- layoutType === 'immersivePortraitDefault' ||
- layoutType === 'immersivePortraitFeature';
- const isImmersiveLandscape =
- layoutType === 'immersiveLandscapeDefault' ||
- layoutType === 'immersiveLandscapeFeature';
- const centreRuleColumn = (() => {
- switch (layoutType) {
- case 'immersivePortraitDefault':
- case 'immersivePortraitFeature':
- case 'immersiveLandscapeDefault':
- return 4;
- default:
- return 3;
- }
- })();
+ const isFootballMatchReport =
+ format.design === ArticleDesign.MatchReport && !!footballMatchStatsUrl;
- const ageWarning = getAgeWarning(
- article.tags,
- article.webPublicationDateDeprecated,
- );
+ const layoutType: LayoutType = isMedia
+ ? 'media'
+ : isShowcase
+ ? 'showcase'
+ : isInteractive
+ ? 'interactive'
+ : 'standard';
return (
- {isImmersive && (
-
-
-
-
-
- )}
- {format.display !== ArticleDisplay.Immersive &&
- format.design !== ArticleDesign.Audio &&
- layoutType !== 'immersivePortraitDefault' && (
-
- {isWeb &&
- format.theme === ArticleSpecial.Labs &&
- format.design !== ArticleDesign.Video ? (
-
- ) : (
-
- )}
-
- )}
+ {format.design !== ArticleDesign.Audio && (
+
+ {isWeb &&
+ format.theme === ArticleSpecial.Labs &&
+ format.design !== ArticleDesign.Video ? (
+
+ ) : (
+
+ )}
+
+ )}
{isApps ? (
<>
@@ -576,14 +515,6 @@ export const StandardLayoutArticleGrid = ({
/>
)}
-
diff --git a/dotcom-rendering/src/layouts/interactives/InteractiveArticleGridDeprecated.tsx b/dotcom-rendering/src/layouts/interactives/InteractiveArticleGridDeprecated.tsx
new file mode 100644
index 00000000000..31e12e72702
--- /dev/null
+++ b/dotcom-rendering/src/layouts/interactives/InteractiveArticleGridDeprecated.tsx
@@ -0,0 +1,382 @@
+import { css } from '@emotion/react';
+import { from, until } from '@guardian/source/foundations';
+import { Hide } from '@guardian/source/react-components';
+import { ArticleBody } from '../../components/ArticleBody';
+import { ArticleContainer } from '../../components/ArticleContainer';
+import { ArticleHeadline } from '../../components/ArticleHeadline';
+import { ArticleMetaApps } from '../../components/ArticleMeta.apps';
+import { ArticleMeta } from '../../components/ArticleMeta.web';
+import { ArticleTitle } from '../../components/ArticleTitle';
+import { Border } from '../../components/Border';
+import { DecideLines } from '../../components/DecideLines';
+import { GridItem } from '../../components/GridItem';
+import { MainMedia } from '../../components/MainMedia';
+import { Section } from '../../components/Section';
+import { Standfirst } from '../../components/Standfirst';
+import { type ArticleFormat, ArticleSpecial } from '../../lib/articleFormat';
+import { getContributionsServiceUrl } from '../../lib/contributions';
+import type { NavType } from '../../model/extract-nav';
+import { palette as themePalette } from '../../palette';
+import type { ArticleDeprecated } from '../../types/article';
+import type { RenderingTarget } from '../../types/renderingTarget';
+import { interactiveLegacyClasses } from '../lib/interactiveLegacyStyling';
+
+const InteractiveGrid = ({ children }: { children: React.ReactNode }) => (
+
+ {children}
+
+);
+
+const maxWidth = css`
+ ${from.desktop} {
+ max-width: 620px;
+ }
+`;
+
+const stretchLines = css`
+ ${until.phablet} {
+ margin-left: -20px;
+ margin-right: -20px;
+ }
+ ${until.mobileLandscape} {
+ margin-left: -10px;
+ margin-right: -10px;
+ }
+`;
+
+interface Props {
+ article: ArticleDeprecated;
+ format: ArticleFormat;
+ renderingTarget: RenderingTarget;
+ serverTime?: number;
+}
+
+interface WebProps extends Props {
+ NAV: NavType;
+ renderingTarget: 'Web';
+}
+
+interface AppProps extends Props {
+ renderingTarget: 'Apps';
+}
+
+export const temporaryBodyCopyColourOverride = css`
+ .content__main-column--interactive p {
+ /* stylelint-disable-next-line declaration-no-important */
+ color: ${themePalette('--article-text')} !important;
+ }
+`;
+
+export const InteractiveArticleGridDeprecated = (
+ props: WebProps | AppProps,
+) => {
+ const { article, format, renderingTarget } = props;
+ const {
+ config: { host },
+ } = article;
+ const isApps = renderingTarget === 'Apps';
+
+ const contributionsServiceUrl = getContributionsServiceUrl(article);
+
+ const { branding } = article.commercialProperties[article.editionId];
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ {format.theme === ArticleSpecial.Labs ? (
+ <>>
+ ) : (
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+ {isApps ? (
+ <>
+
+
+
+
+
+
+ >
+ ) : (
+
+ )}
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/dotcom-rendering/src/layouts/lib/articleArrangements.ts b/dotcom-rendering/src/layouts/lib/articleArrangements.ts
index e7fee10daec..222a2f44806 100644
--- a/dotcom-rendering/src/layouts/lib/articleArrangements.ts
+++ b/dotcom-rendering/src/layouts/lib/articleArrangements.ts
@@ -2,14 +2,7 @@ import { css, type SerializedStyles } from '@emotion/react';
import { from, until } from '@guardian/source/foundations';
import { grid } from '../../grid';
-export type LayoutType =
- | 'standard'
- | 'showcase'
- | 'media'
- | 'immersiveLandscapeDefault'
- | 'immersiveLandscapeFeature'
- | 'immersivePortraitDefault'
- | 'immersivePortraitFeature';
+export type LayoutType = 'standard' | 'showcase' | 'media' | 'interactive';
export type Area =
| 'title'
@@ -158,171 +151,35 @@ const mediaCss: LayoutCssMap = {
},
};
-const immersivePortraitDefaultCss: LayoutCssMap = {
+const interactiveCss: LayoutCssMap = {
title: {
- mobile: 'grid-row: 1;',
tablet: 'grid-row: 1;',
- desktop: `grid-row: 1; ${grid.between('centre-column-start', 8)};`,
- leftCol: `grid-row: 1; ${grid.between('left-column-start', 9)};`,
+ leftCol: `grid-row: 1; ${grid.column.left}`,
},
headline: {
- mobile: 'grid-row: 2;',
tablet: 'grid-row: 2;',
- desktop: `grid-row: 2; ${grid.between('centre-column-start', 8)};`,
- leftCol: `grid-row: 2; ${grid.between('left-column-start', 9)};`,
- wide: `grid-row: 2; ${grid.between('left-column-start', 10)};`,
- },
- media: {
- mobile: 'grid-row: 3;',
- tablet: 'grid-row: 3;',
- desktop: `grid-row: 1 / span 4; ${grid.between(8, 'right-column-end')};`,
- leftCol: `grid-row: 1 / span 3; ${grid.between(9, 'right-column-end')};`,
- wide: `grid-row: 1 / span 3; ${grid.between(10, 'right-column-end')};`,
+ leftCol: 'grid-row: 1;',
},
standfirst: {
- mobile: 'grid-row: 4;',
- tablet: 'grid-row: 4;',
- desktop: `grid-row: 3; ${grid.between('centre-column-start', 7)};`,
- leftCol: `grid-row: 3; ${grid.between('centre-column-start', 8)};`,
- wide: `grid-row: 3; ${grid.between('centre-column-start', 9)};`,
- },
- caption: {
- mobile: 'grid-row: 5;',
- tablet: 'grid-row: 5;',
- desktop: `grid-row: 5;`,
- },
- meta: {
- mobile: 'grid-row: 6;',
- tablet: 'grid-row: 6;',
- desktop: `grid-row: 4; ${grid.between('centre-column-start', 8)};`,
- leftCol: `grid-row: 3 / span 2; ${grid.column.left};`,
- },
- body: {
- mobile: 'grid-row: 7;',
- leftCol: 'grid-row: 4;',
- },
- 'right-column': {
- desktop: `grid-row: 5 / span 2; ${grid.column.right};`,
- leftCol: `grid-row: 4; ${grid.column.right};`,
- },
-};
-
-const immersivePortraitFeatureCss: LayoutCssMap = {
- title: {
- mobile: 'grid-row: 2;',
- tablet: 'grid-row: 2;',
- desktop: `grid-row: 1; ${grid.between('centre-column-start', 8)};`,
- leftCol: `grid-row: 1; ${grid.between('left-column-start', 9)};`,
- },
- headline: {
- mobile: 'grid-row: 3;',
tablet: 'grid-row: 3;',
- desktop: `grid-row: 2; ${grid.between('centre-column-start', 8)};`,
- leftCol: `grid-row: 2; ${grid.between('left-column-start', 9)};`,
- wide: `grid-row: 2; ${grid.between('left-column-start', 10)};`,
+ leftCol: 'grid-row: 2;',
},
media: {
- mobile: 'grid-row: 1;',
- tablet: 'grid-row: 1;',
- desktop: `grid-row: 1 / span 4; ${grid.between(8, 'right-column-end')};`,
- leftCol: `grid-row: 1 / span 3; ${grid.between(9, 'right-column-end')};`,
- wide: `grid-row: 1 / span 3; ${grid.between(10, 'right-column-end')};`,
- },
- standfirst: {
- mobile: 'grid-row: 4;',
tablet: 'grid-row: 4;',
- desktop: `grid-row: 3; ${grid.between('centre-column-start', 7)};`,
- leftCol: `grid-row: 3; ${grid.between('centre-column-start', 8)};`,
- wide: `grid-row: 3; ${grid.between('centre-column-start', 9)};`,
- },
- caption: {
- mobile: 'grid-row: 5;',
- tablet: 'grid-row: 5;',
- desktop: `grid-row: 5;`,
+ leftCol: 'grid-row: 3;',
},
meta: {
- mobile: 'grid-row: 6;',
- tablet: 'grid-row: 6;',
- desktop: `grid-row: 4; ${grid.between('centre-column-start', 8)};`,
+ tablet: 'grid-row: 5;',
leftCol: `grid-row: 3 / span 2; ${grid.column.left};`,
},
body: {
- mobile: 'grid-row: 7;',
+ mobile: `${grid.column.all};`,
+ tablet: `grid-row: 6; ${grid.column.all};`,
leftCol: 'grid-row: 4;',
},
'right-column': {
- desktop: `grid-row: 5 / span 2; ${grid.column.right};`,
- leftCol: `grid-row: 4; ${grid.column.right};`,
- },
-};
-
-const immersiveLandscapeDefaultCss: LayoutCssMap = {
- title: {
- mobile: 'grid-row: 1;',
- tablet: 'grid-row: 1;',
- desktop: 'grid-row: 2;',
- },
- headline: {
- mobile: 'grid-row: 2;',
- tablet: 'grid-row: 2;',
- desktop: 'grid-row: 3 / span 2;',
- wide: `${grid.between('centre-column-start', 14)};`,
- },
- media: {
- mobile: 'grid-row: 3;',
- tablet: 'grid-row: 3;',
- desktop: `grid-row: 1 / span 3; ${grid.between('centre-column-start', 'right-column-end')};`,
- leftCol: `grid-row: 1 / span 3; ${grid.between('left-column-start', 'right-column-end')};`,
- },
- standfirst: {
- mobile: 'grid-row: 4;',
- tablet: 'grid-row: 4;',
- desktop: 'grid-row: 5;',
- },
- caption: {
- desktop: 'grid-row: 6;',
- },
- meta: {
- mobile: 'grid-row: 5;',
- tablet: 'grid-row: 5;',
- desktop: `grid-row: 7;`,
- leftCol: `grid-row: 5 / span 2; ${grid.column.left};`,
- },
- body: {
- leftCol: 'grid-row: 6;',
- },
- 'right-column': {
- desktop: `grid-row: 6 / span 3; ${grid.column.right};`,
- },
-};
-
-const immersiveLandscapeFeatureCss: LayoutCssMap = {
- title: {
- desktop: 'grid-row: 2;',
- },
- headline: {
- desktop: 'grid-row: 3 / span 2;',
- },
- media: {
- mobile: `${grid.column.all}`,
- desktop: `grid-row: 1 / span 3; ${grid.between('centre-column-start', 'right-column-end')};`,
- leftCol: `grid-row: 1 / span 3; ${grid.between('left-column-start', 'right-column-end')};`,
- },
- standfirst: {
- desktop: 'grid-row: 5;',
- },
- caption: {
- desktop: 'grid-row: 6;',
- },
- meta: {
- desktop: `grid-row: 7;`,
- leftCol: `grid-row: 5 / span 2; ${grid.column.left};`,
- },
- body: {
- leftCol: 'grid-row: 6;',
- },
- 'right-column': {
- desktop: `grid-row: 6 / span 3; ${grid.column.right};`,
+ desktop: `grid-row: 1 / span 6; ${grid.column.right};`,
+ leftCol: `grid-row: 1 / span 4; ${grid.column.right};`,
},
};
@@ -330,10 +187,7 @@ const layoutCssMaps: Record = {
standard: standardCss,
showcase: showcaseCss,
media: mediaCss,
- immersiveLandscapeDefault: immersiveLandscapeDefaultCss,
- immersiveLandscapeFeature: immersiveLandscapeFeatureCss,
- immersivePortraitDefault: immersivePortraitDefaultCss,
- immersivePortraitFeature: immersivePortraitFeatureCss,
+ interactive: interactiveCss,
};
/**
diff --git a/dotcom-rendering/src/lib/ArticleRenderer.tsx b/dotcom-rendering/src/lib/ArticleRenderer.tsx
index d04336cef97..e9fcc5e01bf 100644
--- a/dotcom-rendering/src/lib/ArticleRenderer.tsx
+++ b/dotcom-rendering/src/lib/ArticleRenderer.tsx
@@ -3,6 +3,7 @@ import { Fragment } from 'react';
import { useConfig } from '../components/ConfigContext';
import { FeastContextualNudge } from '../components/FeastContextualNudge.island';
import { Island } from '../components/Island';
+import { grid } from '../grid';
import { interactiveLegacyClasses } from '../layouts/lib/interactiveLegacyStyling';
import type { Switches } from '../types/config';
import type { FEElement, RecipeBlockElement } from '../types/content';
@@ -66,6 +67,7 @@ type Props = {
contributionsServiceUrl: string;
shouldHideAds: boolean;
idApiUrl?: string;
+ isOldInteractive?: boolean;
};
export const ArticleRenderer = ({
@@ -89,6 +91,7 @@ export const ArticleRenderer = ({
contributionsServiceUrl,
shouldHideAds,
idApiUrl,
+ isOldInteractive = false,
}: Props) => {
const isSectionedMiniProfilesArticle =
elements.filter(
@@ -223,6 +226,13 @@ export const ArticleRenderer = ({
// ^^ Until we decide where to do the "isomorphism split" in this this code is not safe here.
// But should be soon.
+ const interactiveLayoutCSS = css`
+ ${grid.container}
+ > * {
+ ${grid.column.centre}
+ }
+ `;
+
return (
{renderingTarget === 'Apps'
? augmentedElements
diff --git a/dotcom-rendering/src/lib/adStyles.ts b/dotcom-rendering/src/lib/adStyles.ts
index 3b286d63b36..9dad558304a 100644
--- a/dotcom-rendering/src/lib/adStyles.ts
+++ b/dotcom-rendering/src/lib/adStyles.ts
@@ -126,6 +126,8 @@ const spacefinderAdSlotContainerStyles = css`
text-align: center;
display: flex;
justify-content: center;
+ /* TODO: Revisit ads positioning/sizing nicely in interactive body grid */
+ width: 100%;
max-width: 620px;
margin-left: 0;