diff --git a/dotcom-rendering/src/components/ArticleHeadline.tsx b/dotcom-rendering/src/components/ArticleHeadline.tsx
index 72d9fe5b720..88ff86f6230 100644
--- a/dotcom-rendering/src/components/ArticleHeadline.tsx
+++ b/dotcom-rendering/src/components/ArticleHeadline.tsx
@@ -152,6 +152,16 @@ const labsFont = css`
}
`;
+const labsGalleryFont = css`
+ ${textSansBold34};
+ line-height: 2.1875rem;
+ ${from.desktop} {
+ ${textSansBold34};
+ font-size: 50px;
+ line-height: 3.125rem;
+ }
+`;
+
const jumboLabsFont = css`
${textSansBold34};
font-size: 3.125rem;
@@ -859,7 +869,7 @@ export const ArticleHeadline = ({
{
const isLiveBlog = format.design === ArticleDesign.LiveBlog;
const isInteractive = format.design === ArticleDesign.Interactive;
+ const isGallery = format.design === ArticleDesign.Gallery;
const { ophanComponentName, ophanComponentLink } = getOphanComponents({
branding,
@@ -235,6 +241,7 @@ export const Branding = ({ branding, format }: Props) => {
{
}
};
-const labsBylineStyles = css`
- ${textSansItalic17};
- line-height: 1.4;
-`;
+const labsBylineStyles = (design: ArticleDesign) => {
+ const textStyle =
+ design === ArticleDesign.Gallery
+ ? textEgyptianItalic17
+ : textSansItalic17;
+ return css`
+ ${textStyle};
+ line-height: 1.4;
+ `;
+};
type Props = {
byline?: string;
@@ -96,7 +103,8 @@ export const Contributor = ({ byline, tags, format, source }: Props) => (
}
css={[
bylineStyles(format),
- format.theme === ArticleSpecial.Labs && labsBylineStyles,
+ format.theme === ArticleSpecial.Labs &&
+ labsBylineStyles(format.design),
format.design === ArticleDesign.LiveBlog &&
standfirstColourBelowDesktop,
]}
diff --git a/dotcom-rendering/src/components/SeriesSectionLink.tsx b/dotcom-rendering/src/components/SeriesSectionLink.tsx
index c45fb8c6792..4ffed2d618f 100644
--- a/dotcom-rendering/src/components/SeriesSectionLink.tsx
+++ b/dotcom-rendering/src/components/SeriesSectionLink.tsx
@@ -8,6 +8,7 @@ import {
space,
textSans17,
textSans20,
+ textSansBold17,
textSansBold20,
until,
} from '@guardian/source/foundations';
@@ -101,43 +102,60 @@ const invertedStyle = (design: ArticleDesign) => {
};
const fontStyles = (format: ArticleFormat) => {
- if (format.design === ArticleDesign.Gallery) {
- return css`
- ${headlineBold17}
- ${from.desktop} {
- ${headlineBold20}
- line-height: 36px;
- }
- line-height: 36px;
- `;
- }
- switch (format.theme) {
- case ArticleSpecial.Labs:
- switch (format.display) {
- case ArticleDisplay.Immersive:
+ switch (format.design) {
+ case ArticleDesign.Gallery:
+ switch (format.theme) {
+ case ArticleSpecial.Labs:
return css`
- ${textSansBold20};
- line-height: 23px;
- ${from.leftCol} {
- line-height: 20px;
+ ${textSansBold17};
+ line-height: 36px;
+ ${from.desktop} {
+ ${textSansBold20};
+ /* Overrides the line-height from the font preset */
+ line-height: 36px;
}
`;
default:
return css`
- ${textSans20};
- line-height: 23px;
- ${from.leftCol} {
- line-height: 20px;
+ ${headlineBold17}
+ line-height: 36px;
+
+ ${from.desktop} {
+ ${headlineBold20}
+ /* Overrides the line-height from the font preset */
+ line-height: 36px;
}
`;
}
default:
- return css`
- ${headlineBold17}
- ${from.wide} {
- ${headlineBold20}
- }
- `;
+ switch (format.theme) {
+ case ArticleSpecial.Labs:
+ switch (format.display) {
+ case ArticleDisplay.Immersive:
+ return css`
+ ${textSansBold20};
+ line-height: 23px;
+ ${from.leftCol} {
+ line-height: 20px;
+ }
+ `;
+ default:
+ return css`
+ ${textSans20};
+ line-height: 23px;
+ ${from.leftCol} {
+ line-height: 20px;
+ }
+ `;
+ }
+ default:
+ return css`
+ ${headlineBold17}
+ ${from.wide} {
+ ${headlineBold20}
+ }
+ `;
+ }
}
};
diff --git a/dotcom-rendering/src/components/Standfirst.tsx b/dotcom-rendering/src/components/Standfirst.tsx
index 53b59a5092e..916d8eee27b 100644
--- a/dotcom-rendering/src/components/Standfirst.tsx
+++ b/dotcom-rendering/src/components/Standfirst.tsx
@@ -12,6 +12,7 @@ import {
textSans17,
textSans20,
textSans24,
+ textSansBold15,
} from '@guardian/source/foundations';
import sanitise from 'sanitize-html';
import { grid } from '../../src/grid';
@@ -83,6 +84,11 @@ const decideFont = ({ display, design, theme }: ArticleFormat) => {
const isLabs = theme === ArticleSpecial.Labs;
switch (design) {
case ArticleDesign.Gallery:
+ if (isLabs) {
+ return css`
+ ${textSansBold15};
+ `;
+ }
return css`
${headlineBold17}
`;
diff --git a/dotcom-rendering/src/layouts/GalleryLayout.tsx b/dotcom-rendering/src/layouts/GalleryLayout.tsx
index bcb9e35095a..3079fa02fa3 100644
--- a/dotcom-rendering/src/layouts/GalleryLayout.tsx
+++ b/dotcom-rendering/src/layouts/GalleryLayout.tsx
@@ -19,6 +19,7 @@ import { DesktopAdSlot, MobileAdSlot } from '../components/GalleryAdSlots';
import { GalleryImage } from '../components/GalleryImage';
import { HeaderAdSlot } from '../components/HeaderAdSlot';
import { Island } from '../components/Island';
+import { LabsHeader } from '../components/LabsHeader';
import { MainMediaGallery } from '../components/MainMediaGallery';
import { Masthead } from '../components/Masthead/Masthead';
import { Section } from '../components/Section';
@@ -51,12 +52,6 @@ interface AppProps extends Props {
renderingTarget: 'Apps';
}
-const border = css({
- borderWidth: 1,
- borderStyle: 'solid',
- color: '#ccc',
-});
-
const headerStyles = css`
${grid.container}
background-color: ${themePalette('--article-inner-background')};
@@ -140,6 +135,23 @@ const galleryBorder = css`
export const GalleryLayout = (props: WebProps | AppProps) => {
const { gallery, renderingTarget } = props;
+
+ const {
+ config: {
+ abTests,
+ idUrl,
+ mmaUrl,
+ discussionApiUrl,
+ idApiUrl,
+ shortUrlId,
+ isPreview,
+ isSensitive,
+ section,
+ switches,
+ },
+ editionId,
+ } = gallery.frontendData;
+
const frontendData = gallery.frontendData;
const isWeb = renderingTarget === 'Web';
@@ -176,23 +188,21 @@ export const GalleryLayout = (props: WebProps | AppProps) => {
padSides={false}
shouldCenter={false}
>
-
+
)}
{
/>
)}
+
+ {format.theme === ArticleSpecial.Labs && (
+
+
+
+ )}
+
- Labs header
{
frontendData.webPublicationSecondaryDateDisplay
}
isCommentable={frontendData.isCommentable}
- discussionApiUrl={
- frontendData.config.discussionApiUrl
- }
- shortUrlId={frontendData.config.shortUrlId}
+ discussionApiUrl={discussionApiUrl}
+ shortUrlId={shortUrlId}
/>
) : null}
{isApps ? (
@@ -281,10 +304,8 @@ export const GalleryLayout = (props: WebProps | AppProps) => {
frontendData.webPublicationSecondaryDateDisplay
}
isCommentable={frontendData.isCommentable}
- discussionApiUrl={
- frontendData.config.discussionApiUrl
- }
- shortUrlId={frontendData.config.shortUrlId}
+ discussionApiUrl={discussionApiUrl}
+ shortUrlId={shortUrlId}
/>
) : null}
@@ -396,23 +417,21 @@ export const GalleryLayout = (props: WebProps | AppProps) => {
contributionsServiceUrl={
contributionsServiceUrl
}
- idApiUrl={frontendData.config.idApiUrl}
+ idApiUrl={idApiUrl}
isMinuteArticle={
frontendData.pageType.isMinuteArticle
}
isPaidContent={
frontendData.pageType.isPaidContent
}
- isPreview={!!frontendData.config.isPreview}
- isSensitive={frontendData.config.isSensitive}
+ isPreview={!!isPreview}
+ isSensitive={isSensitive}
pageId={frontendData.pageId}
- sectionId={frontendData.config.section}
+ sectionId={section}
shouldHideReaderRevenue={
frontendData.shouldHideReaderRevenue
}
- remoteBannerSwitch={
- !!frontendData.config.switches.remoteBanner
- }
+ remoteBannerSwitch={!!switches.remoteBanner}
tags={frontendData.tags}
/>
diff --git a/dotcom-rendering/src/paletteDeclarations.ts b/dotcom-rendering/src/paletteDeclarations.ts
index 90e0161f076..d88d438bf94 100644
--- a/dotcom-rendering/src/paletteDeclarations.ts
+++ b/dotcom-rendering/src/paletteDeclarations.ts
@@ -2040,7 +2040,7 @@ const brandingLinkDark: PaletteFunction = ({ design, theme }) => {
case Pillar.Lifestyle:
return pillarPalette(theme, 500);
case ArticleSpecial.Labs:
- return sourcePalette.specialReport[500];
+ return sourcePalette.neutral[73];
case ArticleSpecial.SpecialReport:
return sourcePalette.specialReport[500];
case ArticleSpecial.SpecialReportAlt:
@@ -2672,7 +2672,12 @@ const captionTextLight: PaletteFunction = ({ design, theme }) => {
return sourcePalette.neutral[7];
}
case ArticleSpecial.Labs:
- return sourcePalette.neutral[20];
+ switch (design) {
+ case ArticleDesign.Gallery:
+ return sourcePalette.neutral[86];
+ default:
+ return sourcePalette.neutral[20];
+ }
default:
switch (design) {
case ArticleDesign.PhotoEssay:
@@ -3640,7 +3645,6 @@ const shareButtonLiveBlogMobileMetaLight: PaletteFunction = ({
const shareButtonHoverLight: PaletteFunction = ({ design, theme }) => {
switch (design) {
- case ArticleDesign.Gallery:
case ArticleDesign.Audio:
case ArticleDesign.Video:
case ArticleDesign.Picture:
@@ -3650,6 +3654,8 @@ const shareButtonHoverLight: PaletteFunction = ({ design, theme }) => {
default:
return sourcePalette.neutral[7];
}
+ case ArticleDesign.Gallery:
+ return sourcePalette.neutral[7];
default:
return sourcePalette.neutral[100];
}
@@ -3849,6 +3855,9 @@ const liveBlockBorderBottomDark: PaletteFunction = () =>
const subMetaLabelTextLight: PaletteFunction = ({ theme, design }) => {
switch (theme) {
case ArticleSpecial.Labs:
+ if (design === ArticleDesign.Gallery) {
+ return sourcePalette.neutral[60];
+ }
return sourcePalette.neutral[7];
case ArticleSpecial.SpecialReport:
return sourcePalette.specialReport[300];
@@ -3865,9 +3874,8 @@ const subMetaLabelTextLight: PaletteFunction = ({ theme, design }) => {
case ArticleDesign.Picture:
case ArticleDesign.Video:
case ArticleDesign.Audio:
- return sourcePalette.neutral[60];
case ArticleDesign.Gallery:
- return sourcePalette.neutral[73];
+ return sourcePalette.neutral[60];
default:
return sourcePalette.neutral[46];
}
@@ -3912,13 +3920,15 @@ const subMetaBackgroundLight: PaletteFunction = ({
case ArticleDesign.Picture:
case ArticleDesign.Video:
case ArticleDesign.Audio:
- case ArticleDesign.Gallery:
switch (theme) {
case ArticleSpecial.Labs:
return sourcePalette.neutral[86];
default:
return sourcePalette.neutral[7];
}
+ case ArticleDesign.Gallery:
+ return sourcePalette.neutral[7];
+
default:
switch (theme) {
case ArticleSpecial.SpecialReport:
@@ -3970,7 +3980,12 @@ const subMetaBackgroundDark: PaletteFunction = ({ design, theme }) => {
const subMetaTextLight: PaletteFunction = ({ design, theme }) => {
switch (theme) {
case ArticleSpecial.Labs:
- return sourcePalette.neutral[7];
+ switch (design) {
+ case ArticleDesign.Gallery:
+ return sourcePalette.neutral[86];
+ default:
+ return sourcePalette.neutral[7];
+ }
case ArticleSpecial.SpecialReport:
return sourcePalette.specialReport[100];
default:
@@ -4046,7 +4061,12 @@ const subMetaTextHoverLight: PaletteFunction = ({ design, theme }) => {
case ArticleDesign.Picture:
switch (theme) {
case ArticleSpecial.Labs:
- return sourcePalette.neutral[100];
+ switch (design) {
+ case ArticleDesign.Gallery:
+ return sourcePalette.neutral[7];
+ default:
+ return sourcePalette.neutral[100];
+ }
default:
return sourcePalette.neutral[7];
}