From 667399e5fb9d369d005966ee4c5b19ff528fa64b Mon Sep 17 00:00:00 2001 From: Frederick O'Brien Date: Thu, 27 Aug 2026 12:00:40 +0100 Subject: [PATCH 1/6] Delete legacy immersive layout and styling --- .../playwright/tests/commercial.e2e.spec.ts | 2 +- .../src/components/ArticleHeadline.tsx | 134 +-- .../src/components/ArticleTitle.tsx | 18 +- .../src/components/SeriesSectionLink.tsx | 4 +- dotcom-rendering/src/layouts/DecideLayout.tsx | 28 +- .../src/layouts/ImmersiveLayout.tsx | 1033 ----------------- .../src/layouts/StandardLayoutArticleGrid.tsx | 18 +- 7 files changed, 27 insertions(+), 1210 deletions(-) delete mode 100644 dotcom-rendering/src/layouts/ImmersiveLayout.tsx diff --git a/dotcom-rendering/playwright/tests/commercial.e2e.spec.ts b/dotcom-rendering/playwright/tests/commercial.e2e.spec.ts index 61c96351056..db823202659 100644 --- a/dotcom-rendering/playwright/tests/commercial.e2e.spec.ts +++ b/dotcom-rendering/playwright/tests/commercial.e2e.spec.ts @@ -19,7 +19,7 @@ test.describe('Commercial E2E tests', () => { 'merchandising', ]; - const totalSlotsExpected = 15; // All slots, even if unfilled ie. `display: none` + const totalSlotsExpected = 16; // All slots, even if unfilled ie. `display: none` const inlineSlots = totalSlotsExpected - fixedSlots.length; // We are excluding survey slot as they can be switched off diff --git a/dotcom-rendering/src/components/ArticleHeadline.tsx b/dotcom-rendering/src/components/ArticleHeadline.tsx index 67e3cc50970..490a4a72b89 100644 --- a/dotcom-rendering/src/components/ArticleHeadline.tsx +++ b/dotcom-rendering/src/components/ArticleHeadline.tsx @@ -28,7 +28,6 @@ import { ArticleSpecial, Pillar, } from '../lib/articleFormat'; -import { getZIndex } from '../lib/getZIndex'; import { palette as themePalette } from '../palette'; import type { StarRating as Rating } from '../types/content'; import type { TagType } from '../types/tag'; @@ -216,56 +215,6 @@ const invertedStyles = css` box-decoration-break: clone; `; -const legacyInvertedStyles = css` - white-space: pre-wrap; - padding-right: ${space[1]}px; - padding-bottom: ${space[1]}px; - box-shadow: -6px 0 0 ${themePalette('--headline-background')}; - /* Box decoration is required to push the box shadow out on Firefox */ - box-decoration-break: clone; -`; - -const legacyImmersiveStyles = css` - min-height: 112px; - padding-bottom: ${space[6]}px; - padding-left: ${space[1]}px; - - ${from.mobileLandscape} { - padding-left: ${space[3]}px; - } - - ${from.tablet} { - padding-left: ${space[1]}px; - } - - margin-right: ${space[5]}px; -`; - -const legacyImmersiveWrapper = css` - margin-left: 6px; - - ${from.tablet} { - margin-left: 16px; - } - - ${from.leftCol} { - margin-left: 25px; - } - - flex-grow: 1; - z-index: ${getZIndex('articleHeadline')}; - - ${until.mobileLandscape} { - margin-right: 40px; - } -`; - -const legacyInvertedText = css` - white-space: pre-wrap; - padding-bottom: ${space[1]}px; - padding-right: ${space[1]}px; -`; - const darkBackground = css` background-color: ${themePalette('--headline-background')}; `; @@ -307,20 +256,7 @@ const gridHeadlineTextBelowDesktop = css` } `; -const immersiveHeadlineStyles = ( - layoutType: LayoutType | undefined, - isLegacyImmersive: boolean, -) => { - if (isLegacyImmersive) { - return [ - legacyImmersiveWrapper, - darkBackground, - css` - color: ${themePalette('--headline-colour')}; - `, - ]; - } - +const immersiveHeadlineStyles = (layoutType: LayoutType | undefined) => { if (layoutType === 'immersiveLandscapeDefault') { return [invertedText, darkBackground]; } @@ -350,29 +286,13 @@ const zIndex = css` z-index: 1; `; -const ageWarningMargins = ( - format: ArticleFormat, - isLegacyImmersive: boolean, -) => { - if (format.design === ArticleDesign.Gallery) { +const ageWarningMargins = (format: ArticleFormat) => { + if ( + format.design === ArticleDesign.Gallery || + format.display === ArticleDisplay.Immersive + ) { return ''; } - if (format.display === ArticleDisplay.Immersive) { - return isLegacyImmersive - ? css` - margin-left: 0; - margin-bottom: 0; - - ${from.tablet} { - margin-left: 10px; - } - - ${from.leftCol} { - margin-left: 20px; - } - ` - : ''; - } return css` margin-top: 12px; margin-left: -10px; @@ -395,14 +315,12 @@ const WithAgeWarning = ({ format, children, snapToInverted = false, - isLegacyImmersive = false, }: { tags: TagType[]; webPublicationDateDeprecated: string; format: ArticleFormat; children: React.ReactNode; snapToInverted?: boolean; - isLegacyImmersive?: boolean; }) => { const age = getAgeWarning(tags, webPublicationDateDeprecated); @@ -411,14 +329,8 @@ const WithAgeWarning = ({ <>
{ const isInverted = layoutType === 'immersiveLandscapeDefault'; - const isLegacyImmersive = layoutType == null; switch (format.display) { case ArticleDisplay.Immersive: { switch (format.design) { @@ -550,18 +461,9 @@ export const ArticleHeadline = ({ format.theme === ArticleSpecial.Labs ? labsFont : headlineFont(format), - isLegacyImmersive - ? [ - legacyInvertedText, - css` - color: ${themePalette( - '--headline-colour', - )}; - `, - ] - : isInverted - ? [invertedText, darkBackground] - : gridHeadlineText, + isInverted + ? [invertedText, darkBackground] + : gridHeadlineText, ]} > {headlineString} @@ -588,26 +490,14 @@ export const ArticleHeadline = ({ } format={format} snapToInverted={isInverted} - isLegacyImmersive={isLegacyImmersive} > -

+

diff --git a/dotcom-rendering/src/components/ArticleTitle.tsx b/dotcom-rendering/src/components/ArticleTitle.tsx index 7786b099158..464d51a85c5 100644 --- a/dotcom-rendering/src/components/ArticleTitle.tsx +++ b/dotcom-rendering/src/components/ArticleTitle.tsx @@ -29,7 +29,7 @@ const sectionStyles = css` } `; -const immersiveGridMargins = css` +const immersiveMargins = css` max-width: 500px; min-width: 200px; margin-bottom: 0; @@ -39,18 +39,6 @@ const immersiveGridMargins = css` } `; -const legacyImmersiveMargins = css` - max-width: 400px; - min-width: 200px; - margin-bottom: 4px; - ${from.tablet} { - margin-left: 16px; - } - ${from.leftCol} { - margin-left: 25px; - } -`; - const galleryStyles = css` ${grid.column.all} @@ -84,9 +72,7 @@ export const ArticleTitle = ({
diff --git a/dotcom-rendering/src/components/SeriesSectionLink.tsx b/dotcom-rendering/src/components/SeriesSectionLink.tsx index 5b077df0093..2b593d57a47 100644 --- a/dotcom-rendering/src/components/SeriesSectionLink.tsx +++ b/dotcom-rendering/src/components/SeriesSectionLink.tsx @@ -359,8 +359,7 @@ export const SeriesSectionLink = ({ return (
{ ); } default: { - return article.theme === ArticleSpecial.Labs && - article.design === ArticleDesign.Standard ? ( + return ( - ) : ( - ); } } @@ -242,8 +229,7 @@ const DecideLayoutWeb = ({ article, NAV, renderingTarget }: WebProps) => { ); } default: { - return article.theme === ArticleSpecial.Labs && - article.design === ArticleDesign.Standard ? ( + return ( { renderingTarget={renderingTarget} serverTime={serverTime} /> - ) : ( - ); } } diff --git a/dotcom-rendering/src/layouts/ImmersiveLayout.tsx b/dotcom-rendering/src/layouts/ImmersiveLayout.tsx deleted file mode 100644 index 2816aba60b5..00000000000 --- a/dotcom-rendering/src/layouts/ImmersiveLayout.tsx +++ /dev/null @@ -1,1033 +0,0 @@ -import { css } from '@emotion/react'; -import { - from, - palette as sourcePalette, - space, - until, -} from '@guardian/source/foundations'; -import { StraightLines } from '@guardian/source-development-kitchen/react-components'; -import { AdPortals } from '../components/AdPortals.island'; -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 { Caption } from '../components/Caption'; -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 { GuardianLabsLines } from '../components/GuardianLabsLines'; -import { HeadlineByline } from '../components/HeadlineByline'; -import { Hide } from '../components/Hide'; -import { Island } from '../components/Island'; -import { LabsHeader } from '../components/LabsHeader'; -import { ListenToArticle } from '../components/ListenToArticle.island'; -import { MainMedia } from '../components/MainMedia'; -import { Masthead } from '../components/Masthead/Masthead'; -import { minHeaderHeightPx } from '../components/Masthead/Titlepiece/constants'; -import { MostViewedFooterData } from '../components/MostViewedFooterData.island'; -import { MostViewedFooterLayout } from '../components/MostViewedFooterLayout'; -import { OnwardsUpper } from '../components/OnwardsUpper.island'; -import { RightColumn } from '../components/RightColumn'; -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 { - ArticleDesign, - type ArticleFormat, - ArticleSpecial, -} from '../lib/articleFormat'; -import { canRenderAds } from '../lib/canRenderAds'; -import { getContributionsServiceUrl } from '../lib/contributions'; -import { decideMainMediaCaption } from '../lib/decide-caption'; -import { decideStoryPackageTrails } from '../lib/decideTrail'; -import { getZIndex } from '../lib/getZIndex'; -import { LABS_HEADER_HEIGHT } from '../lib/labs-constants'; -import { parse } from '../lib/slot-machine-flags'; -import type { NavType } from '../model/extract-nav'; -import { palette as themePalette } from '../palette'; -import type { ArticleDeprecated } from '../types/article'; -import { BannerWrapper, Stuck } from './lib/stickiness'; - -const ImmersiveGrid = ({ children }: { children: React.ReactNode }) => ( -
- {children} -
-); - -const maxWidth = css` - ${from.desktop} { - max-width: 620px; - } -`; - -const linesMargin = css` - ${from.leftCol} { - margin-top: ${space[5]}px; - } -`; - -const stretchLines = css` - ${until.phablet} { - margin-left: -20px; - margin-right: -20px; - } - ${until.mobileLandscape} { - margin-left: -10px; - margin-right: -10px; - } -`; - -interface CommonProps { - article: ArticleDeprecated; - format: ArticleFormat; - serverTime?: number; -} - -interface WebProps extends CommonProps { - NAV: NavType; - renderingTarget: 'Web'; -} - -interface AppProps extends CommonProps { - renderingTarget: 'Apps'; -} - -const Box = ({ children }: { children: React.ReactNode }) => ( -
- {children} -
-); - -export const ImmersiveLayout = (props: WebProps | AppProps) => { - const { article, format, renderingTarget, serverTime } = props; - - const { - config: { isPaidContent, host, hasSurveyAd }, - editionId, - } = article; - const isWeb = renderingTarget === 'Web'; - const isApps = renderingTarget === 'Apps'; - - const showBodyEndSlot = - isWeb && - (parse(article.slotMachineFlags ?? '').showBodyEnd || - article.config.switches.slotBodyEnd); - - // TODO: - // 1) Read 'forceEpic' value from URL parameter and use it to force the slot to render - // 2) Otherwise, ensure slot only renders if `article.config.shouldHideReaderRevenue` equals false. - - const showComments = article.isCommentable && !isPaidContent; - - const mainMedia = article.mainMediaElements[0]; - - const captionText = decideMainMediaCaption(mainMedia); - - const HEADLINE_OFFSET = mainMedia ? 120 : 0; - - const { branding } = article.commercialProperties[article.editionId]; - - const contributionsServiceUrl = getContributionsServiceUrl(article); - - const isLabs = format.theme === ArticleSpecial.Labs; - - /** - We need change the height values depending on whether the labs header is there or not to keep - the headlines appearing at a consistent height between labs and non labs immersive articles. - */ - - const labsHeaderHeight = LABS_HEADER_HEIGHT; - const combinedHeight = (minHeaderHeightPx + labsHeaderHeight).toString(); - - const navAndLabsHeaderHeight = isLabs - ? `${combinedHeight}px` - : `${minHeaderHeightPx}px`; - - const hasMainMediaStyles = css` - height: calc(80vh - ${navAndLabsHeaderHeight}); - /** - 80vh is normally enough but don't let the content shrink vertically too - much just in case - */ - min-height: calc(25rem - ${navAndLabsHeaderHeight}); - ${from.desktop} { - height: calc(100vh - ${navAndLabsHeaderHeight}); - min-height: calc(31.25rem - ${navAndLabsHeaderHeight}); - } - ${from.wide} { - min-height: calc(50rem - ${navAndLabsHeaderHeight}); - } - `; - const LeftColCaption = () => ( -
- -
- ); - - const renderAds = canRenderAds(article); - - return ( - <> - {isWeb && ( - tag.id)} - sectionId={article.config.section} - contentType={article.contentType} - /> - )} - - - - {format.theme === ArticleSpecial.Labs && ( - -
- -
-
- )} - -
-
- -
- {mainMedia && ( - <> -
-
} - > - -
- -
- -
-
-
- - )} -
- - {isWeb && renderAds && hasSurveyAd && ( - - )} - -
- {isApps && renderAds && ( - - - - )} -
- - {/* Above leftCol, the Caption is controlled by Section ^^ */} - - - - - - - {format.design === ArticleDesign.PhotoEssay ? ( - <> - ) : ( - - )} - - - <> - {!mainMedia && ( -
- -
- )} - -
- - <> - {!mainMedia && ( -
- -
- )} - -
- - - - - {!!article.byline && ( - - )} - {article.affiliateLinksDisclaimerRequired && ( - - - - )} - {/* Only show Listen to Article button on App landscape views */} - {isApps && ( - -
- - - -
-
- )} -
- - {format.design === ArticleDesign.PhotoEssay && - !isLabs ? ( - <> - ) : ( -
-
- {format.theme === - ArticleSpecial.Labs ? ( - - ) : ( - - )} -
-
- )} -
- {isApps ? ( - <> - - - - - - - - ) : ( - <> - - - )} - {article.affiliateLinksDisclaimerRequired && ( - - - - )} -
-
- - - - {showBodyEndSlot && ( - - - - )} - - - - - -
- - <> - {mainMedia && isWeb && renderAds && ( -
- { - - } -
- )} - -
-
-
-
-
- {!isLabs && isWeb && renderAds && ( -
- -
- )} - - {article.storyPackage && ( -
- - - -
- )} - - - - - - {showComments && ( -
- -
- )} - {!isPaidContent && ( -
- - - - - -
- )} - {!isLabs && isWeb && renderAds && ( -
- -
- )} -
- - {isWeb && props.NAV.subNavSections && ( -
- - - -
- )} - - {isWeb && ( - <> -
-
-
- - - - - - - {renderAds && ( - - )} - - )} - {isApps && ( -
- - - -
- )} - - ); -}; diff --git a/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx b/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx index 1dd6909df4c..843cb579ca7 100644 --- a/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx +++ b/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx @@ -237,12 +237,15 @@ export const StandardLayoutArticleGrid = ({ `, grid.container, grid.outerRules(), - isLabs && - isImmersive && + isImmersive && css` - &::before, - &::after { - z-index: ${getZIndex('immersiveGridOuterRules')}; + ${from.desktop} { + &::before, + &::after { + z-index: ${getZIndex( + 'immersiveGridOuterRules', + )}; + } } `, !isLabs && @@ -263,11 +266,6 @@ export const StandardLayoutArticleGrid = ({ grid-template-rows: auto auto ${ageWarning != null ? '130px' : '90px'} auto auto auto auto auto; - ${grid.centreRule( - layoutType === 'immersiveLandscapeFeature' - ? 3 - : 4, - )} } `, (isImmersivePortrait || isImmersiveLandscape) && From b8b45a9cadaa0074da036ba4840da931a026351c Mon Sep 17 00:00:00 2001 From: Frederick O'Brien Date: Fri, 28 Aug 2026 17:05:10 +0100 Subject: [PATCH 2/6] Put rollout behind 0% A/B test --- ab-testing/config/abTests.ts | 11 + ab-testing/config/types.ts | 3 +- .../src/components/ArticleHeadline.tsx | 134 ++- .../src/components/ArticleTitle.tsx | 18 +- .../src/components/SeriesSectionLink.tsx | 4 +- dotcom-rendering/src/layouts/DecideLayout.tsx | 32 +- .../src/layouts/ImmersiveLayout.tsx | 1033 +++++++++++++++++ .../src/layouts/StandardLayoutArticleGrid.tsx | 10 +- 8 files changed, 1220 insertions(+), 25 deletions(-) create mode 100644 dotcom-rendering/src/layouts/ImmersiveLayout.tsx diff --git a/ab-testing/config/abTests.ts b/ab-testing/config/abTests.ts index 3afc5da2228..0f3781e5c78 100644 --- a/ab-testing/config/abTests.ts +++ b/ab-testing/config/abTests.ts @@ -223,6 +223,17 @@ const ABTests: ABTest[] = [ groups: ["control", "variant"], shouldForceMetricsCollection: true, }, + { + name: "articles-and-publishing-revamped-immersive-layout", + description: "New grid-based immersive layout for all articles", + owners: ["articles.and.publishing@guardian.co.uk "], + status: "ON", + expirationDate: "2027-08-31", + type: "server", + audienceSize: 0 / 100, + groups: ["enable"], + shouldForceMetricsCollection: false, + }, ]; const activeABtests = ABTests.filter((test) => test.status === "ON"); diff --git a/ab-testing/config/types.ts b/ab-testing/config/types.ts index be7d8b3d4d8..f64107a4156 100644 --- a/ab-testing/config/types.ts +++ b/ab-testing/config/types.ts @@ -15,7 +15,8 @@ type Team = | "feast" | "martech" | "identity-and-trust" - | "puzzles"; + | "puzzles" + | "articles-and-publishing"; type TestName = `${Team}-${string}`; diff --git a/dotcom-rendering/src/components/ArticleHeadline.tsx b/dotcom-rendering/src/components/ArticleHeadline.tsx index 490a4a72b89..67e3cc50970 100644 --- a/dotcom-rendering/src/components/ArticleHeadline.tsx +++ b/dotcom-rendering/src/components/ArticleHeadline.tsx @@ -28,6 +28,7 @@ import { ArticleSpecial, Pillar, } from '../lib/articleFormat'; +import { getZIndex } from '../lib/getZIndex'; import { palette as themePalette } from '../palette'; import type { StarRating as Rating } from '../types/content'; import type { TagType } from '../types/tag'; @@ -215,6 +216,56 @@ const invertedStyles = css` box-decoration-break: clone; `; +const legacyInvertedStyles = css` + white-space: pre-wrap; + padding-right: ${space[1]}px; + padding-bottom: ${space[1]}px; + box-shadow: -6px 0 0 ${themePalette('--headline-background')}; + /* Box decoration is required to push the box shadow out on Firefox */ + box-decoration-break: clone; +`; + +const legacyImmersiveStyles = css` + min-height: 112px; + padding-bottom: ${space[6]}px; + padding-left: ${space[1]}px; + + ${from.mobileLandscape} { + padding-left: ${space[3]}px; + } + + ${from.tablet} { + padding-left: ${space[1]}px; + } + + margin-right: ${space[5]}px; +`; + +const legacyImmersiveWrapper = css` + margin-left: 6px; + + ${from.tablet} { + margin-left: 16px; + } + + ${from.leftCol} { + margin-left: 25px; + } + + flex-grow: 1; + z-index: ${getZIndex('articleHeadline')}; + + ${until.mobileLandscape} { + margin-right: 40px; + } +`; + +const legacyInvertedText = css` + white-space: pre-wrap; + padding-bottom: ${space[1]}px; + padding-right: ${space[1]}px; +`; + const darkBackground = css` background-color: ${themePalette('--headline-background')}; `; @@ -256,7 +307,20 @@ const gridHeadlineTextBelowDesktop = css` } `; -const immersiveHeadlineStyles = (layoutType: LayoutType | undefined) => { +const immersiveHeadlineStyles = ( + layoutType: LayoutType | undefined, + isLegacyImmersive: boolean, +) => { + if (isLegacyImmersive) { + return [ + legacyImmersiveWrapper, + darkBackground, + css` + color: ${themePalette('--headline-colour')}; + `, + ]; + } + if (layoutType === 'immersiveLandscapeDefault') { return [invertedText, darkBackground]; } @@ -286,13 +350,29 @@ const zIndex = css` z-index: 1; `; -const ageWarningMargins = (format: ArticleFormat) => { - if ( - format.design === ArticleDesign.Gallery || - format.display === ArticleDisplay.Immersive - ) { +const ageWarningMargins = ( + format: ArticleFormat, + isLegacyImmersive: boolean, +) => { + if (format.design === ArticleDesign.Gallery) { return ''; } + if (format.display === ArticleDisplay.Immersive) { + return isLegacyImmersive + ? css` + margin-left: 0; + margin-bottom: 0; + + ${from.tablet} { + margin-left: 10px; + } + + ${from.leftCol} { + margin-left: 20px; + } + ` + : ''; + } return css` margin-top: 12px; margin-left: -10px; @@ -315,12 +395,14 @@ const WithAgeWarning = ({ format, children, snapToInverted = false, + isLegacyImmersive = false, }: { tags: TagType[]; webPublicationDateDeprecated: string; format: ArticleFormat; children: React.ReactNode; snapToInverted?: boolean; + isLegacyImmersive?: boolean; }) => { const age = getAgeWarning(tags, webPublicationDateDeprecated); @@ -329,8 +411,14 @@ const WithAgeWarning = ({ <>
{ const isInverted = layoutType === 'immersiveLandscapeDefault'; + const isLegacyImmersive = layoutType == null; switch (format.display) { case ArticleDisplay.Immersive: { switch (format.design) { @@ -461,9 +550,18 @@ export const ArticleHeadline = ({ format.theme === ArticleSpecial.Labs ? labsFont : headlineFont(format), - isInverted - ? [invertedText, darkBackground] - : gridHeadlineText, + isLegacyImmersive + ? [ + legacyInvertedText, + css` + color: ${themePalette( + '--headline-colour', + )}; + `, + ] + : isInverted + ? [invertedText, darkBackground] + : gridHeadlineText, ]} > {headlineString} @@ -490,14 +588,26 @@ export const ArticleHeadline = ({ } format={format} snapToInverted={isInverted} + isLegacyImmersive={isLegacyImmersive} > -

+

diff --git a/dotcom-rendering/src/components/ArticleTitle.tsx b/dotcom-rendering/src/components/ArticleTitle.tsx index 464d51a85c5..7786b099158 100644 --- a/dotcom-rendering/src/components/ArticleTitle.tsx +++ b/dotcom-rendering/src/components/ArticleTitle.tsx @@ -29,7 +29,7 @@ const sectionStyles = css` } `; -const immersiveMargins = css` +const immersiveGridMargins = css` max-width: 500px; min-width: 200px; margin-bottom: 0; @@ -39,6 +39,18 @@ const immersiveMargins = css` } `; +const legacyImmersiveMargins = css` + max-width: 400px; + min-width: 200px; + margin-bottom: 4px; + ${from.tablet} { + margin-left: 16px; + } + ${from.leftCol} { + margin-left: 25px; + } +`; + const galleryStyles = css` ${grid.column.all} @@ -72,7 +84,9 @@ export const ArticleTitle = ({
diff --git a/dotcom-rendering/src/components/SeriesSectionLink.tsx b/dotcom-rendering/src/components/SeriesSectionLink.tsx index 2b593d57a47..5b077df0093 100644 --- a/dotcom-rendering/src/components/SeriesSectionLink.tsx +++ b/dotcom-rendering/src/components/SeriesSectionLink.tsx @@ -359,7 +359,8 @@ export const SeriesSectionLink = ({ return (
+ article.frontendData.config.serverSideABTests[ + REVAMPED_IMMERSIVE_LAYOUT_AB_TEST + ] === 'enable'; + const DecideLayoutApps = ({ article, renderingTarget }: AppProps) => { const format = { design: article.design, @@ -53,13 +66,20 @@ const DecideLayoutApps = ({ article, renderingTarget }: AppProps) => { ); } default: { - return ( + return isInRevampedImmersiveLayoutTest(article) ? ( + ) : ( + ); } } @@ -229,7 +249,7 @@ const DecideLayoutWeb = ({ article, NAV, renderingTarget }: WebProps) => { ); } default: { - return ( + return isInRevampedImmersiveLayoutTest(article) ? ( { renderingTarget={renderingTarget} serverTime={serverTime} /> + ) : ( + ); } } diff --git a/dotcom-rendering/src/layouts/ImmersiveLayout.tsx b/dotcom-rendering/src/layouts/ImmersiveLayout.tsx new file mode 100644 index 00000000000..2816aba60b5 --- /dev/null +++ b/dotcom-rendering/src/layouts/ImmersiveLayout.tsx @@ -0,0 +1,1033 @@ +import { css } from '@emotion/react'; +import { + from, + palette as sourcePalette, + space, + until, +} from '@guardian/source/foundations'; +import { StraightLines } from '@guardian/source-development-kitchen/react-components'; +import { AdPortals } from '../components/AdPortals.island'; +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 { Caption } from '../components/Caption'; +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 { GuardianLabsLines } from '../components/GuardianLabsLines'; +import { HeadlineByline } from '../components/HeadlineByline'; +import { Hide } from '../components/Hide'; +import { Island } from '../components/Island'; +import { LabsHeader } from '../components/LabsHeader'; +import { ListenToArticle } from '../components/ListenToArticle.island'; +import { MainMedia } from '../components/MainMedia'; +import { Masthead } from '../components/Masthead/Masthead'; +import { minHeaderHeightPx } from '../components/Masthead/Titlepiece/constants'; +import { MostViewedFooterData } from '../components/MostViewedFooterData.island'; +import { MostViewedFooterLayout } from '../components/MostViewedFooterLayout'; +import { OnwardsUpper } from '../components/OnwardsUpper.island'; +import { RightColumn } from '../components/RightColumn'; +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 { + ArticleDesign, + type ArticleFormat, + ArticleSpecial, +} from '../lib/articleFormat'; +import { canRenderAds } from '../lib/canRenderAds'; +import { getContributionsServiceUrl } from '../lib/contributions'; +import { decideMainMediaCaption } from '../lib/decide-caption'; +import { decideStoryPackageTrails } from '../lib/decideTrail'; +import { getZIndex } from '../lib/getZIndex'; +import { LABS_HEADER_HEIGHT } from '../lib/labs-constants'; +import { parse } from '../lib/slot-machine-flags'; +import type { NavType } from '../model/extract-nav'; +import { palette as themePalette } from '../palette'; +import type { ArticleDeprecated } from '../types/article'; +import { BannerWrapper, Stuck } from './lib/stickiness'; + +const ImmersiveGrid = ({ children }: { children: React.ReactNode }) => ( +
+ {children} +
+); + +const maxWidth = css` + ${from.desktop} { + max-width: 620px; + } +`; + +const linesMargin = css` + ${from.leftCol} { + margin-top: ${space[5]}px; + } +`; + +const stretchLines = css` + ${until.phablet} { + margin-left: -20px; + margin-right: -20px; + } + ${until.mobileLandscape} { + margin-left: -10px; + margin-right: -10px; + } +`; + +interface CommonProps { + article: ArticleDeprecated; + format: ArticleFormat; + serverTime?: number; +} + +interface WebProps extends CommonProps { + NAV: NavType; + renderingTarget: 'Web'; +} + +interface AppProps extends CommonProps { + renderingTarget: 'Apps'; +} + +const Box = ({ children }: { children: React.ReactNode }) => ( +
+ {children} +
+); + +export const ImmersiveLayout = (props: WebProps | AppProps) => { + const { article, format, renderingTarget, serverTime } = props; + + const { + config: { isPaidContent, host, hasSurveyAd }, + editionId, + } = article; + const isWeb = renderingTarget === 'Web'; + const isApps = renderingTarget === 'Apps'; + + const showBodyEndSlot = + isWeb && + (parse(article.slotMachineFlags ?? '').showBodyEnd || + article.config.switches.slotBodyEnd); + + // TODO: + // 1) Read 'forceEpic' value from URL parameter and use it to force the slot to render + // 2) Otherwise, ensure slot only renders if `article.config.shouldHideReaderRevenue` equals false. + + const showComments = article.isCommentable && !isPaidContent; + + const mainMedia = article.mainMediaElements[0]; + + const captionText = decideMainMediaCaption(mainMedia); + + const HEADLINE_OFFSET = mainMedia ? 120 : 0; + + const { branding } = article.commercialProperties[article.editionId]; + + const contributionsServiceUrl = getContributionsServiceUrl(article); + + const isLabs = format.theme === ArticleSpecial.Labs; + + /** + We need change the height values depending on whether the labs header is there or not to keep + the headlines appearing at a consistent height between labs and non labs immersive articles. + */ + + const labsHeaderHeight = LABS_HEADER_HEIGHT; + const combinedHeight = (minHeaderHeightPx + labsHeaderHeight).toString(); + + const navAndLabsHeaderHeight = isLabs + ? `${combinedHeight}px` + : `${minHeaderHeightPx}px`; + + const hasMainMediaStyles = css` + height: calc(80vh - ${navAndLabsHeaderHeight}); + /** + 80vh is normally enough but don't let the content shrink vertically too + much just in case + */ + min-height: calc(25rem - ${navAndLabsHeaderHeight}); + ${from.desktop} { + height: calc(100vh - ${navAndLabsHeaderHeight}); + min-height: calc(31.25rem - ${navAndLabsHeaderHeight}); + } + ${from.wide} { + min-height: calc(50rem - ${navAndLabsHeaderHeight}); + } + `; + const LeftColCaption = () => ( +
+ +
+ ); + + const renderAds = canRenderAds(article); + + return ( + <> + {isWeb && ( + tag.id)} + sectionId={article.config.section} + contentType={article.contentType} + /> + )} + + + + {format.theme === ArticleSpecial.Labs && ( + +
+ +
+
+ )} + +
+
+ +
+ {mainMedia && ( + <> +
+
} + > + +
+ +
+ +
+
+
+ + )} +
+ + {isWeb && renderAds && hasSurveyAd && ( + + )} + +
+ {isApps && renderAds && ( + + + + )} +
+ + {/* Above leftCol, the Caption is controlled by Section ^^ */} + + + + + + + {format.design === ArticleDesign.PhotoEssay ? ( + <> + ) : ( + + )} + + + <> + {!mainMedia && ( +
+ +
+ )} + +
+ + <> + {!mainMedia && ( +
+ +
+ )} + +
+ + + + + {!!article.byline && ( + + )} + {article.affiliateLinksDisclaimerRequired && ( + + + + )} + {/* Only show Listen to Article button on App landscape views */} + {isApps && ( + +
+ + + +
+
+ )} +
+ + {format.design === ArticleDesign.PhotoEssay && + !isLabs ? ( + <> + ) : ( +
+
+ {format.theme === + ArticleSpecial.Labs ? ( + + ) : ( + + )} +
+
+ )} +
+ {isApps ? ( + <> + + + + + + + + ) : ( + <> + + + )} + {article.affiliateLinksDisclaimerRequired && ( + + + + )} +
+
+ + + + {showBodyEndSlot && ( + + + + )} + + + + + +
+ + <> + {mainMedia && isWeb && renderAds && ( +
+ { + + } +
+ )} + +
+
+
+
+
+ {!isLabs && isWeb && renderAds && ( +
+ +
+ )} + + {article.storyPackage && ( +
+ + + +
+ )} + + + + + + {showComments && ( +
+ +
+ )} + {!isPaidContent && ( +
+ + + + + +
+ )} + {!isLabs && isWeb && renderAds && ( +
+ +
+ )} +
+ + {isWeb && props.NAV.subNavSections && ( +
+ + + +
+ )} + + {isWeb && ( + <> +
+
+
+ + + + + + + {renderAds && ( + + )} + + )} + {isApps && ( +
+ + + +
+ )} + + ); +}; diff --git a/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx b/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx index 843cb579ca7..37544d83395 100644 --- a/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx +++ b/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx @@ -239,13 +239,9 @@ export const StandardLayoutArticleGrid = ({ grid.outerRules(), isImmersive && css` - ${from.desktop} { - &::before, - &::after { - z-index: ${getZIndex( - 'immersiveGridOuterRules', - )}; - } + &::before, + &::after { + z-index: ${getZIndex('immersiveGridOuterRules')}; } `, !isLabs && From d607db2f36088d6ddcd264003e5819576a181646 Mon Sep 17 00:00:00 2001 From: Frederick O'Brien Date: Tue, 1 Sep 2026 10:39:08 +0100 Subject: [PATCH 3/6] Change expected ad slots count back --- dotcom-rendering/playwright/tests/commercial.e2e.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotcom-rendering/playwright/tests/commercial.e2e.spec.ts b/dotcom-rendering/playwright/tests/commercial.e2e.spec.ts index db823202659..61c96351056 100644 --- a/dotcom-rendering/playwright/tests/commercial.e2e.spec.ts +++ b/dotcom-rendering/playwright/tests/commercial.e2e.spec.ts @@ -19,7 +19,7 @@ test.describe('Commercial E2E tests', () => { 'merchandising', ]; - const totalSlotsExpected = 16; // All slots, even if unfilled ie. `display: none` + const totalSlotsExpected = 15; // All slots, even if unfilled ie. `display: none` const inlineSlots = totalSlotsExpected - fixedSlots.length; // We are excluding survey slot as they can be switched off From edb5a0cc3cad2c06807a8ee57b4c1257f00aef9c Mon Sep 17 00:00:00 2001 From: Frederick O'Brien Date: Tue, 1 Sep 2026 12:02:02 +0100 Subject: [PATCH 4/6] Send Labs pieces to new format regardless --- dotcom-rendering/src/layouts/DecideLayout.tsx | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/dotcom-rendering/src/layouts/DecideLayout.tsx b/dotcom-rendering/src/layouts/DecideLayout.tsx index 1d3093b20af..ae47531e140 100644 --- a/dotcom-rendering/src/layouts/DecideLayout.tsx +++ b/dotcom-rendering/src/layouts/DecideLayout.tsx @@ -1,4 +1,8 @@ -import { ArticleDesign, ArticleDisplay } from '../lib/articleFormat'; +import { + ArticleDesign, + ArticleDisplay, + ArticleSpecial, +} from '../lib/articleFormat'; import type { NavType } from '../model/extract-nav'; import type { Article } from '../types/article'; import type { RenderingTarget } from '../types/renderingTarget'; @@ -66,7 +70,9 @@ const DecideLayoutApps = ({ article, renderingTarget }: AppProps) => { ); } default: { - return isInRevampedImmersiveLayoutTest(article) ? ( + return isInRevampedImmersiveLayoutTest(article) || + (article.theme === ArticleSpecial.Labs && + article.design === ArticleDesign.Standard) ? ( { ); } default: { - return isInRevampedImmersiveLayoutTest(article) ? ( + return isInRevampedImmersiveLayoutTest(article) || + (article.theme === ArticleSpecial.Labs && + article.design === ArticleDesign.Standard) ? ( Date: Tue, 1 Sep 2026 12:21:04 +0100 Subject: [PATCH 5/6] Adjust z index to prevent central rule overlapping body --- dotcom-rendering/src/lib/getZIndex.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dotcom-rendering/src/lib/getZIndex.ts b/dotcom-rendering/src/lib/getZIndex.ts index 2b92726f8da..22fa2676144 100644 --- a/dotcom-rendering/src/lib/getZIndex.ts +++ b/dotcom-rendering/src/lib/getZIndex.ts @@ -82,14 +82,14 @@ const indices = [ // Sticky table of contents element 'tableOfContents', - // Article headline (should be above main media) - 'articleHeadline', - 'immersiveBlackBox', - // Body 'bodyArea', 'rightColumnArea', + // Article headline (should be above main media) + 'articleHeadline', + 'immersiveBlackBox', + // Media overlay 'mediaOverlay', From fc904a26d324147c1fe5b305baae145b7c56c096 Mon Sep 17 00:00:00 2001 From: Frederick O'Brien Date: Tue, 1 Sep 2026 20:24:53 +0100 Subject: [PATCH 6/6] Strip away immersive feature forks --- .../src/components/ArticleHeadline.tsx | 4 +- dotcom-rendering/src/components/Figure.tsx | 50 +-------- .../src/components/SeriesSectionLink.tsx | 6 +- .../src/layouts/StandardLayoutArticleGrid.tsx | 44 ++------ .../src/layouts/lib/articleArrangements.ts | 104 ++---------------- dotcom-rendering/src/lib/renderElement.tsx | 1 - 6 files changed, 25 insertions(+), 184 deletions(-) diff --git a/dotcom-rendering/src/components/ArticleHeadline.tsx b/dotcom-rendering/src/components/ArticleHeadline.tsx index 67e3cc50970..ba48d62bac3 100644 --- a/dotcom-rendering/src/components/ArticleHeadline.tsx +++ b/dotcom-rendering/src/components/ArticleHeadline.tsx @@ -321,7 +321,7 @@ const immersiveHeadlineStyles = ( ]; } - if (layoutType === 'immersiveLandscapeDefault') { + if (layoutType === 'immersiveLandscape') { return [invertedText, darkBackground]; } @@ -523,7 +523,7 @@ export const ArticleHeadline = ({ isMatch, starRating, }: Props) => { - const isInverted = layoutType === 'immersiveLandscapeDefault'; + const isInverted = layoutType === 'immersiveLandscape'; const isLegacyImmersive = layoutType == null; switch (format.display) { case ArticleDisplay.Immersive: { diff --git a/dotcom-rendering/src/components/Figure.tsx b/dotcom-rendering/src/components/Figure.tsx index 83a444ac608..ccb113fb4b1 100644 --- a/dotcom-rendering/src/components/Figure.tsx +++ b/dotcom-rendering/src/components/Figure.tsx @@ -1,15 +1,6 @@ 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 { breakpoints, from, space, until } from '@guardian/source/foundations'; import { ArticleDesign, type ArticleFormat } from '../lib/articleFormat'; -import { transparentColour } from '../lib/transparentColour'; -import { palette } from '../palette'; import type { FEElement, RoleType } from '../types/content'; type Props = { @@ -21,35 +12,8 @@ type Props = { className?: string; type?: FEElement['_type']; isTimeline?: boolean; - articleArrangement?: LayoutType; }; -const overlayMaskGradientStyles = (angle: string) => css` - mask-image: linear-gradient( - ${angle}, - rgb(0, 0, 0) 0%, - rgba(0, 0, 0, 0.9619) 12.5%, - rgba(0, 0, 0, 0.8536) 25%, - rgba(0, 0, 0, 0.6913) 37.5%, - rgba(0, 0, 0, 0.5) 50%, - rgba(0, 0, 0, 0.3087) 62.5%, - rgba(0, 0, 0, 0.1464) 75%, - rgba(0, 0, 0, 0.0381) 87.5%, - transparent 100% - ); -`; - -const blurStyles = css` - position: absolute; - inset: 0; - background-color: ${palette('--article-background')}; - backdrop-filter: blur(12px) brightness(0.5); - @supports not (backdrop-filter: blur(12px)) { - background-color: ${transparentColour(sourcePalette.neutral[10], 0.7)}; - } - ${overlayMaskGradientStyles('0deg')}; -`; - const roleCss = { inline: css` margin-top: ${space[3]}px; @@ -299,7 +263,6 @@ export const Figure = ({ className = '', type, isTimeline = false, - articleArrangement = 'standard', }: Props) => { if (isMainMedia && !isTimeline) { // Don't add in-body styles for main media elements @@ -310,17 +273,6 @@ export const Figure = ({ return (
{children} - {articleArrangement === 'immersiveLandscapeFeature' && ( -
- )}
); } diff --git a/dotcom-rendering/src/components/SeriesSectionLink.tsx b/dotcom-rendering/src/components/SeriesSectionLink.tsx index 5b077df0093..0443b19417b 100644 --- a/dotcom-rendering/src/components/SeriesSectionLink.tsx +++ b/dotcom-rendering/src/components/SeriesSectionLink.tsx @@ -408,10 +408,8 @@ export const SeriesSectionLink = ({ ); } if ( - layoutType === 'immersivePortraitDefault' || - layoutType === 'immersivePortraitFeature' || - layoutType === 'immersiveLandscapeDefault' || - layoutType === 'immersiveLandscapeFeature' + layoutType === 'immersivePortrait' || + layoutType === 'immersiveLandscape' ) { return ( <> diff --git a/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx b/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx index 37544d83395..04411be9fd0 100644 --- a/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx +++ b/dotcom-rendering/src/layouts/StandardLayoutArticleGrid.tsx @@ -207,23 +207,6 @@ export const StandardLayoutArticleGrid = ({ }); 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 ageWarning = getAgeWarning( article.tags, article.webPublicationDateDeprecated, @@ -247,16 +230,16 @@ export const StandardLayoutArticleGrid = ({ !isLabs && css` ${from.leftCol} { - ${grid.centreRule(centreRuleColumn)} + ${grid.centreRule(isImmersive ? 4 : 3)} } `, - isImmersivePortrait && + layoutType === 'immersivePortrait' && css` ${from.desktop} { grid-template-rows: 0.25fr 1fr auto; } `, - isImmersiveLandscape && + layoutType === 'immersiveLandscape' && css` ${from.desktop} { grid-template-rows: auto auto ${ageWarning != null @@ -264,7 +247,7 @@ export const StandardLayoutArticleGrid = ({ : '90px'} auto auto auto auto auto; } `, - (isImmersivePortrait || isImmersiveLandscape) && + isImmersive && css` ${until.desktop} { /* Anchor the title consistently while wrapped text extends the media below it. */ @@ -286,14 +269,12 @@ export const StandardLayoutArticleGrid = ({ align-self: start; ${mainMediaAspectRatio != null && `aspect-ratio: ${mainMediaAspectRatio.replace(':', ' / ')};`} - ${isImmersiveLandscape && + ${layoutType === 'immersiveLandscape' && `margin-left: -20px; margin-right: -20px;`} } - ${(isImmersivePortrait || - isImmersiveLandscape) && - immersiveMediaBelowDesktop( + ${immersiveMediaBelowDesktop( headlineBackground, isMainMediaImage, )} @@ -341,7 +322,7 @@ export const StandardLayoutArticleGrid = ({ padding-bottom: ${space[2]}px; } `, - isImmersivePortrait && + layoutType === 'immersivePortrait' && css` align-self: end; margin-bottom: 0; @@ -377,8 +358,7 @@ export const StandardLayoutArticleGrid = ({ padding-bottom: ${space[8]}px; } `, - (layoutType === 'immersivePortraitDefault' || - layoutType === 'immersivePortraitFeature') && + layoutType === 'immersivePortrait' && css` ${from.desktop} { border-bottom: 1px solid @@ -387,7 +367,7 @@ export const StandardLayoutArticleGrid = ({ ${themePalette('--article-border')}; } `, - isImmersiveLandscape && + layoutType === 'immersiveLandscape' && css` ${from.desktop} { padding-bottom: ${space[8]}px; @@ -417,7 +397,7 @@ export const StandardLayoutArticleGrid = ({ padding-top: ${space[2]}px; } `, - isImmersiveLandscape && + layoutType === 'immersiveLandscape' && css` ${from.desktop} { padding-bottom: ${space[8]}px; @@ -464,7 +444,7 @@ export const StandardLayoutArticleGrid = ({ padding-top: ${space[3]}px; } `, - layoutType === 'immersivePortraitDefault' + layoutType === 'immersivePortrait' ? css` ${from.leftCol} { margin-right: -10px; @@ -475,7 +455,7 @@ export const StandardLayoutArticleGrid = ({ > {format.display !== ArticleDisplay.Immersive && format.design !== ArticleDesign.Audio && - layoutType !== 'immersivePortraitDefault' && ( + layoutType !== 'immersivePortrait' && (
{isWeb && format.theme === ArticleSpecial.Labs && diff --git a/dotcom-rendering/src/layouts/lib/articleArrangements.ts b/dotcom-rendering/src/layouts/lib/articleArrangements.ts index 25481511bb6..da0a4b45226 100644 --- a/dotcom-rendering/src/layouts/lib/articleArrangements.ts +++ b/dotcom-rendering/src/layouts/lib/articleArrangements.ts @@ -6,10 +6,8 @@ export type LayoutType = | 'standard' | 'showcase' | 'media' - | 'immersiveLandscapeDefault' - | 'immersiveLandscapeFeature' - | 'immersivePortraitDefault' - | 'immersivePortraitFeature'; + | 'immersiveLandscape' + | 'immersivePortrait'; export type Area = | 'title' @@ -165,7 +163,7 @@ const mediaCss: LayoutCssMap = { }, }; -const immersivePortraitDefaultCss: LayoutCssMap = { +const immersivePortraitCss: LayoutCssMap = { title: { belowDesktop: `${grid.column.all} grid-row: 2;`, desktop: `grid-row: 1; ${grid.between('centre-column-start', 8)};`, @@ -208,50 +206,7 @@ const immersivePortraitDefaultCss: LayoutCssMap = { }, }; -const immersivePortraitFeatureCss: LayoutCssMap = { - title: { - belowDesktop: `${grid.column.all} grid-row: 2;`, - desktop: `grid-row: 1; ${grid.between('centre-column-start', 8)};`, - leftCol: `grid-row: 1; ${grid.between('left-column-start', 9)};`, - }, - headline: { - belowDesktop: `${grid.column.all} 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)};`, - }, - media: { - belowDesktop: `${grid.column.all} grid-row: 1 / span 2;`, - 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: { - belowDesktop: '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: { - belowDesktop: 'grid-row: 5;', - desktop: `grid-row: 5;`, - }, - meta: { - belowDesktop: 'grid-row: 6;', - desktop: `grid-row: 4; ${grid.between('centre-column-start', 8)};`, - leftCol: `grid-row: 3 / span 2; ${grid.column.left};`, - }, - body: { - belowDesktop: '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 immersiveLandscapeDefaultCss: LayoutCssMap = { +const immersiveLandscapeCss: LayoutCssMap = { title: { belowDesktop: `${grid.column.all} grid-row: 2; align-self: end;`, desktop: 'grid-row: 2;', @@ -288,50 +243,12 @@ const immersiveLandscapeDefaultCss: LayoutCssMap = { }, }; -const immersiveLandscapeFeatureCss: LayoutCssMap = { - title: { - belowDesktop: `${grid.column.all} grid-row: 2; align-self: end;`, - desktop: 'grid-row: 2;', - }, - headline: { - belowDesktop: `${grid.column.all} grid-row: 3;`, - desktop: 'grid-row: 3 / span 2;', - }, - media: { - belowDesktop: `${grid.column.all} grid-row: 1 / span 2;`, - 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: { - belowDesktop: 'grid-row: 4;', - desktop: 'grid-row: 5;', - }, - caption: { - belowDesktop: 'grid-row: 5;', - desktop: 'grid-row: 6;', - }, - meta: { - belowDesktop: 'grid-row: 6;', - desktop: `grid-row: 7;`, - leftCol: `grid-row: 5 / span 2; ${grid.column.left};`, - }, - body: { - belowDesktop: 'grid-row: 7;', - leftCol: 'grid-row: 6;', - }, - 'right-column': { - desktop: `grid-row: 6 / span 3; ${grid.column.right};`, - }, -}; - const layoutCssMaps: Record = { standard: standardCss, showcase: showcaseCss, media: mediaCss, - immersiveLandscapeDefault: immersiveLandscapeDefaultCss, - immersiveLandscapeFeature: immersiveLandscapeFeatureCss, - immersivePortraitDefault: immersivePortraitDefaultCss, - immersivePortraitFeature: immersivePortraitFeatureCss, + immersiveLandscape: immersiveLandscapeCss, + immersivePortrait: immersivePortraitCss, }; /** @@ -380,7 +297,6 @@ export const gridItemCss = ( */ export const getLayoutType = ({ isImmersive, - isFeature, orientation, isMedia, isShowcase, @@ -393,14 +309,10 @@ export const getLayoutType = ({ }): LayoutType => { if (isImmersive) { if (orientation === 'portrait') { - return isFeature - ? 'immersivePortraitFeature' - : 'immersivePortraitDefault'; + return 'immersivePortrait'; } // Square images are treated the same as landscape for immersive layouts. - return isFeature - ? 'immersiveLandscapeFeature' - : 'immersiveLandscapeDefault'; + return 'immersiveLandscape'; } if (isMedia) return 'media'; if (isShowcase) return 'showcase'; diff --git a/dotcom-rendering/src/lib/renderElement.tsx b/dotcom-rendering/src/lib/renderElement.tsx index 70cecbba728..68bb7b4f231 100644 --- a/dotcom-rendering/src/lib/renderElement.tsx +++ b/dotcom-rendering/src/lib/renderElement.tsx @@ -1104,7 +1104,6 @@ export const RenderArticleElement = ({ type={element._type} format={format} isTimeline={isTimeline} - articleArrangement={articleArrangement} > {el}