88 textSansBold28 ,
99 visuallyHidden ,
1010} from '@guardian/source/foundations' ;
11+ import { getContrast } from '../lib/colour' ;
1112import { palette } from '../palette' ;
1213
1314const containerCss = css `
@@ -44,7 +45,7 @@ const labelCss = css`
4445 ${ textSansBold14 } ;
4546 grid- area: label;
4647 justify- self: center;
47- color : ${ palette ( '--football-match-stat-name ' ) } ;
48+ color : ${ palette ( '--football-match-stat-text ' ) } ;
4849 ${ from . desktop } {
4950 ${ textSansBold15 } ;
5051 }
@@ -62,6 +63,10 @@ const largeNumberCss = css`
6263 }
6364` ;
6465
66+ const numberFixContrastCss = css `
67+ color : ${ palette ( '--football-match-stat-text' ) } ;
68+ ` ;
69+
6570const awayStatCss = css `
6671 grid- area: away- stat;
6772 justify- self: end;
@@ -80,6 +85,10 @@ const barCss = css`
8085 bor der- radius: 8px;
8186` ;
8287
88+ const barFixContrastCss = css `
89+ bor der: 1px solid ${ palette ( '--football-match-stat-text' ) } ;
90+ ` ;
91+
8392type MatchStatistic = {
8493 teamName : string ;
8594 teamColour : string ;
@@ -109,12 +118,32 @@ export const FootballMatchStat = ({
109118 const homePercentage = ( home . value / ( home . value + away . value ) ) * 100 ;
110119 const awayPercentage = ( away . value / ( home . value + away . value ) ) * 100 ;
111120
121+ const minimumContrast = 3.1 ; // https://www.w3.org/TR/WCAG21/#contrast-minimum
122+
123+ const backgroundColour = '#f6f6f6' ; // TODO: fetch from palette
124+
125+ const homeNeedsContrast =
126+ getContrast ( home . teamColour , backgroundColour ) < minimumContrast ;
127+ const awayNeedsContrast =
128+ getContrast ( away . teamColour , backgroundColour ) < minimumContrast ;
129+
130+ /**
131+ * If either team colour lacks sufficient contrast we adjust both numbers
132+ * so we don't appear to be favouring one team over the other. For the chart
133+ * we keep the team colour and apply a contrasting border colour.
134+ */
135+ const numbersNeedContrast = homeNeedsContrast || awayNeedsContrast ;
136+
112137 return (
113138 < div css = { containerCss } >
114139 < div css = { [ headerCss , raiseLabelOnDesktop && raiseLabelCss ] } >
115140 < span css = { labelCss } > { label } </ span >
116141 < span
117- css = { [ numberCss , largeNumbersOnDesktop && largeNumberCss ] }
142+ css = { [
143+ numberCss ,
144+ largeNumbersOnDesktop && largeNumberCss ,
145+ numbersNeedContrast && numberFixContrastCss ,
146+ ] }
118147 style = { { '--match-stat-team-colour' : home . teamColour } }
119148 >
120149 < span
@@ -131,6 +160,7 @@ export const FootballMatchStat = ({
131160 numberCss ,
132161 awayStatCss ,
133162 largeNumbersOnDesktop && largeNumberCss ,
163+ numbersNeedContrast && numberFixContrastCss ,
134164 ] }
135165 style = { { '--match-stat-team-colour' : away . teamColour } }
136166 >
@@ -146,14 +176,14 @@ export const FootballMatchStat = ({
146176 </ div >
147177 < div aria-hidden = "true" css = { chartCss } >
148178 < div
149- css = { barCss }
179+ css = { [ barCss , homeNeedsContrast && barFixContrastCss ] }
150180 style = { {
151181 '--match-stat-percentage' : `${ homePercentage } %` ,
152182 '--match-stat-team-colour' : home . teamColour ,
153183 } }
154184 > </ div >
155185 < div
156- css = { barCss }
186+ css = { [ barCss , awayNeedsContrast && barFixContrastCss ] }
157187 style = { {
158188 '--match-stat-percentage' : `${ awayPercentage } %` ,
159189 '--match-stat-team-colour' : away . teamColour ,
0 commit comments