From 4f5aed4f5007c058ac093fa2e5ecf485a1abafdc Mon Sep 17 00:00:00 2001 From: James Mockett <1166188+jamesmockett@users.noreply.github.com> Date: Fri, 23 Jan 2026 14:36:16 +0000 Subject: [PATCH 1/4] Use fixed colours for match info figures --- dotcom-rendering/src/components/FootballMatchStat.tsx | 8 ++------ dotcom-rendering/src/components/Lineups.tsx | 8 +++----- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/dotcom-rendering/src/components/FootballMatchStat.tsx b/dotcom-rendering/src/components/FootballMatchStat.tsx index 30c6147fd0c..7c7c0d9b60d 100644 --- a/dotcom-rendering/src/components/FootballMatchStat.tsx +++ b/dotcom-rendering/src/components/FootballMatchStat.tsx @@ -68,7 +68,7 @@ const labelCss = css` const numberCss = css` ${textSansBold20}; grid-area: home-stat; - color: var(--match-stat-team-colour); + color: var(--football-match-stat-text); `; const largeNumberCss = css` @@ -136,10 +136,7 @@ export const FootballMatchStat = ({ ]} > {label} - + player.substitute === isSubstitute) .map((player) => (
  • - - {player.shirtNumber} - + {player.shirtNumber} {player.name.charAt(0).toUpperCase()}. {player.name} @@ -184,11 +182,11 @@ const awayStyles = css` } `; -const shirtNumber = (color: string) => css` +const shirtNumber = css` display: inline-block; width: ${space[5]}px; ${textSansBold14} - color: ${color}; + color: ${palette('--football-match-stat-text')}; `; const listItem = css` From e5b46f6e7260c1488573f5b1795a6e06415cadc8 Mon Sep 17 00:00:00 2001 From: James Mockett <1166188+jamesmockett@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:02:33 +0000 Subject: [PATCH 2/4] Add team colour examples to match stat stories --- .../fixtures/manual/footballTeams.ts | 90 +++++++++++++++++++ .../FootballMatchGoalAttempts.stories.tsx | 61 ++++++++++++- .../components/FootballMatchStat.stories.tsx | 40 +++++++++ 3 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 dotcom-rendering/fixtures/manual/footballTeams.ts diff --git a/dotcom-rendering/fixtures/manual/footballTeams.ts b/dotcom-rendering/fixtures/manual/footballTeams.ts new file mode 100644 index 00000000000..4d628a839e9 --- /dev/null +++ b/dotcom-rendering/fixtures/manual/footballTeams.ts @@ -0,0 +1,90 @@ +export const footballTeams = [ + { + home: { name: 'Wolves', colour: '#faa01b' }, + away: { name: 'Man Utd', colour: '#b00101' }, + }, + { + home: { name: 'Fulham', colour: '#ffffff' }, + away: { name: 'C Palace', colour: '#af1f17' }, + }, + { + home: { name: 'Brighton', colour: '#2a449a' }, + away: { name: 'West Ham', colour: '#7c1e42' }, + }, + { + home: { name: 'Leeds', colour: '#f5f5f5' }, + away: { name: 'Liverpool', colour: '#ce070c' }, + }, + { + home: { name: 'AFC Bournemouth', colour: '#c80000' }, + away: { name: 'Chelsea', colour: '#005ca4' }, + }, + { + home: { name: 'Everton', colour: '#00349a' }, + away: { name: 'Nottm Forest', colour: '#db1812' }, + }, + { + home: { name: 'Man City', colour: '#5cbfeb' }, + away: { name: 'Sunderland', colour: '#d51022' }, + }, + { + home: { name: 'Newcastle', colour: '#383838' }, + away: { name: 'Burnley', colour: '#570e30' }, + }, + { + home: { name: 'Spurs', colour: '#ffffff' }, + away: { name: 'Brentford', colour: '#c4040f' }, + }, + { + home: { name: 'Aston Villa', colour: '#720e44' }, + away: { name: 'Arsenal', colour: '#c40007' }, + }, + { + home: { name: 'Birmingham', colour: '#01009a' }, + away: { name: 'Norwich', colour: '#ffe400' }, + }, + { + home: { name: 'Derby', colour: '#ffffff' }, + away: { name: 'Watford', colour: '#fef502' }, + }, + { + home: { name: 'Leicester', colour: '#4b2cd3' }, + away: { name: 'Stoke', colour: '#cc0617' }, + }, + { + home: { name: 'Oxford Utd', colour: '#fec726' }, + away: { name: 'Middlesbrough', colour: '#e70101' }, + }, + { + home: { name: 'Portsmouth', colour: '#0077ac' }, + away: { name: 'Millwall', colour: '#1a2791' }, + }, + { + home: { name: 'QPR', colour: '#1f539f' }, + away: { name: 'Hull', colour: '#f2b100' }, + }, + { + home: { name: 'Bristol City', colour: '#c70c23' }, + away: { name: 'Swansea', colour: '#ffffff' }, + }, + { + home: { name: 'Charlton', colour: '#d4222b' }, + away: { name: 'Southampton', colour: '#d71921' }, + }, + { + home: { name: 'Coventry', colour: '#b1d0ff' }, + away: { name: 'West Brom', colour: '#00246a' }, + }, + { + home: { name: 'Celtic', colour: '#559861' }, + away: { name: 'Dundee', colour: '#000033' }, + }, + { + home: { name: 'Falkirk', colour: '#002341' }, + away: { name: 'Motherwell', colour: '#f0c650' }, + }, + { + home: { name: 'Dundee Utd', colour: '#ff6c00' }, + away: { name: 'Rangers', colour: '#195091' }, + }, +]; diff --git a/dotcom-rendering/src/components/FootballMatchGoalAttempts.stories.tsx b/dotcom-rendering/src/components/FootballMatchGoalAttempts.stories.tsx index e61282b7c1c..42cfc161ed6 100644 --- a/dotcom-rendering/src/components/FootballMatchGoalAttempts.stories.tsx +++ b/dotcom-rendering/src/components/FootballMatchGoalAttempts.stories.tsx @@ -1,18 +1,41 @@ +import { css } from '@emotion/react'; +import { space } from '@guardian/source/foundations'; import type { Meta, StoryObj } from '@storybook/react-webpack5'; -import { FootballMatchGoalAttempts as FootballMatchGoalAttemptsComponent } from './FootballMatchStat'; +import { splitTheme } from '../../.storybook/decorators/splitThemeDecorator'; +import { footballTeams } from '../../fixtures/manual/footballTeams'; +import { ArticleDesign, ArticleDisplay, Pillar } from '../lib/articleFormat'; +import { FootballMatchGoalAttempts } from './FootballMatchStat'; const meta = { title: 'Components/Football Match Goal Attempts', - component: FootballMatchGoalAttemptsComponent, + component: FootballMatchGoalAttempts, + decorators: [ + (Story) => ( +
    + +
    + ), + splitTheme([ + { + design: ArticleDesign.Standard, + display: ArticleDisplay.Standard, + theme: Pillar.News, + }, + ]), + ], parameters: { layout: 'padded', }, -} satisfies Meta; +} satisfies Meta; export default meta; type Story = StoryObj; -export const FootballMatchGoalAttempts = { +export const Default = { args: { homeTeam: { name: 'Manchester United', @@ -32,3 +55,33 @@ export const FootballMatchGoalAttempts = { }, }, } satisfies Story; + +export const TeamColours = { + render: (args) => ( +
    + {footballTeams.map((match, index) => ( + + ))} +
    + ), + args: { + ...Default.args, + }, +} satisfies Story; diff --git a/dotcom-rendering/src/components/FootballMatchStat.stories.tsx b/dotcom-rendering/src/components/FootballMatchStat.stories.tsx index 9f8e8d50378..98b6d63c238 100644 --- a/dotcom-rendering/src/components/FootballMatchStat.stories.tsx +++ b/dotcom-rendering/src/components/FootballMatchStat.stories.tsx @@ -1,6 +1,9 @@ import { css } from '@emotion/react'; import { space } from '@guardian/source/foundations'; import type { Meta, StoryObj } from '@storybook/react-webpack5'; +import { splitTheme } from '../../.storybook/decorators/splitThemeDecorator'; +import { footballTeams } from '../../fixtures/manual/footballTeams'; +import { ArticleDesign, ArticleDisplay, Pillar } from '../lib/articleFormat'; import { palette } from '../palette'; import { FootballMatchStat } from './FootballMatchStat'; @@ -20,6 +23,13 @@ const meta = { ), + splitTheme([ + { + design: ArticleDesign.Standard, + display: ArticleDisplay.Standard, + theme: Pillar.News, + }, + ]), ], parameters: { viewport: { @@ -70,3 +80,33 @@ export const CompactLayout = { layout: 'compact', }, } satisfies Story; + +export const TeamColours = { + render: (args) => ( +
    + {footballTeams.map((match, index) => ( + + ))} +
    + ), + args: { + ...ShownAsPercentage.args, + }, +} satisfies Story; From 49be50f02ac394990eda429137b26cbf63633949 Mon Sep 17 00:00:00 2001 From: James Mockett <1166188+jamesmockett@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:03:55 +0000 Subject: [PATCH 3/4] Adjust on target text for background colour --- .../src/components/FootballMatchStat.tsx | 42 ++++++------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/dotcom-rendering/src/components/FootballMatchStat.tsx b/dotcom-rendering/src/components/FootballMatchStat.tsx index 7c7c0d9b60d..c95b9f320d4 100644 --- a/dotcom-rendering/src/components/FootballMatchStat.tsx +++ b/dotcom-rendering/src/components/FootballMatchStat.tsx @@ -11,6 +11,7 @@ import { textSansBold28, visuallyHidden, } from '@guardian/source/foundations'; +import { isLight } from '../lib/isLight'; import { transparentColour } from '../lib/transparentColour'; import { palette } from '../palette'; @@ -22,6 +23,7 @@ const containerCss = css` 'home-stat label away-stat' 'graph graph graph'; padding: 5px 10px 10px; + color: ${palette('--football-match-stat-text')}; border: 1px solid ${palette('--football-match-stat-border')}; border-radius: 6px; &::before { @@ -59,7 +61,6 @@ const labelCss = css` ${textSansBold14}; grid-area: label; justify-self: center; - color: ${palette('--football-match-stat-text')}; ${from.desktop} { ${textSansBold15}; } @@ -68,7 +69,6 @@ const labelCss = css` const numberCss = css` ${textSansBold20}; grid-area: home-stat; - color: var(--football-match-stat-text); `; const largeNumberCss = css` @@ -189,12 +189,12 @@ const goalAttemptsLayoutCss = css` } `; -const offTargetCss = css` +const offTargetCss = (colour: string) => css` ${textSans14}; grid-area: home-attempts; margin-top: 5px; padding: ${space[1]}px 0 0 6px; - background-color: var(--off-target-colour); + background-color: ${transparentColour(colour, 0.1)}; border-radius: 4px; ${from.desktop} { ${textSans15}; @@ -208,10 +208,12 @@ const offTargetAwayCss = css` padding-right: 6px; `; -const onTargetCss = css` +const onTargetCss = (colour: string) => css` padding: ${space[1]}px 0 0 6px; - color: ${sourcePalette.neutral[100]}; - background-color: var(--on-target-colour); + color: ${isLight(colour) + ? sourcePalette.neutral[7] + : sourcePalette.neutral[100]}; + background-color: ${colour}; border-radius: 4px; width: 80%; min-height: 62px; @@ -264,19 +266,10 @@ export const FootballMatchGoalAttempts = ({ > {homeTeam.name} -
    +
    Off target {homeValues.offTarget} -
    +
    On target {homeValues.onTarget}
    @@ -288,19 +281,10 @@ export const FootballMatchGoalAttempts = ({ > {awayTeam.name} -
    +
    Off target {awayValues.offTarget} -
    +
    On target {awayValues.onTarget}
    From 79d70f2d31252b2a5f4eb4a7fa9fa49bd38b8f71 Mon Sep 17 00:00:00 2001 From: James Mockett <1166188+jamesmockett@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:24:57 +0000 Subject: [PATCH 4/4] Add borders to stat charts to ensure visibility --- dotcom-rendering/src/components/FootballMatchStat.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dotcom-rendering/src/components/FootballMatchStat.tsx b/dotcom-rendering/src/components/FootballMatchStat.tsx index c95b9f320d4..848ee3123ef 100644 --- a/dotcom-rendering/src/components/FootballMatchStat.tsx +++ b/dotcom-rendering/src/components/FootballMatchStat.tsx @@ -93,6 +93,7 @@ const barCss = css` height: ${space[2]}px; width: var(--match-stat-percentage); background-color: var(--match-stat-team-colour); + border: 1px solid ${palette('--football-match-stat-border')}; border-radius: 8px; `; @@ -195,6 +196,7 @@ const offTargetCss = (colour: string) => css` margin-top: 5px; padding: ${space[1]}px 0 0 6px; background-color: ${transparentColour(colour, 0.1)}; + border: 1px solid ${palette('--football-match-stat-border')}; border-radius: 4px; ${from.desktop} { ${textSans15}; @@ -214,6 +216,8 @@ const onTargetCss = (colour: string) => css` ? sourcePalette.neutral[7] : sourcePalette.neutral[100]}; background-color: ${colour}; + border-top: 1px solid ${palette('--football-match-stat-border')}; + border-left: 1px solid ${palette('--football-match-stat-border')}; border-radius: 4px; width: 80%; min-height: 62px; @@ -227,6 +231,8 @@ const onTargetAwayCss = css` padding-left: 0; padding-right: 6px; justify-self: start; + border-left: none; + border-right: 1px solid ${palette('--football-match-stat-border')}; `; const attemptCountCss = css`