Skip to content

Conversation

@romaricpascal
Copy link
Member

First step towards having the brand colours in GOV.UK Frontend. This PR adds them in a private variable, with a corresponding function to access them and starts using them where we were previously creating ad-hoc tints of $govuk-brand-colour.

Thoughts

Given white has no variant, it is left out from the $_govuk-brand-colours map listing the brand colours to keep the data structure of the map consistent for all colours. Instead its value is returned by an @if in the _govuk-brand-colours function.

As we haven't designed how brand colours are applied to components yet, the $_govuk-brand-colours map and _govuk-brand-colour function are kept private. We'll need to discuss the final visibility, but I'm not sure $_govuk-brand-colours should be public, to avoid temptation to expand the list of colours specified by the brand.

@github-actions
Copy link

github-actions bot commented Oct 3, 2025

Other changes to npm package

diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/_index.scss b/packages/govuk-frontend/dist/govuk/components/service-navigation/_index.scss
index 93f3f109c..ea74d5fff 100644
--- a/packages/govuk-frontend/dist/govuk/components/service-navigation/_index.scss
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/_index.scss
@@ -18,7 +18,7 @@
     @include _govuk-rebrand(
       "background-color",
       $from: $govuk-service-navigation-background,
-      $to: $_govuk-rebrand-template-background-colour
+      $to: _govuk-brand-colour("blue", "tint-95")
     );
   }
 
diff --git a/packages/govuk-frontend/dist/govuk/helpers/_colour.scss b/packages/govuk-frontend/dist/govuk/helpers/_colour.scss
index e044d3910..5f99e4747 100644
--- a/packages/govuk-frontend/dist/govuk/helpers/_colour.scss
+++ b/packages/govuk-frontend/dist/govuk/helpers/_colour.scss
@@ -27,9 +27,11 @@
     "removed in the next major version.");
   }
 
+  // Sass parses unquoted colours as colours, so we need to turn them into
+  // strings before looking them up in the colour palette
+  // https://sass-lang.com/documentation/values/strings#unquoted
   @if type-of($colour) == "color" {
-    // stylelint-disable-next-line scss/function-quote-no-quoted-strings-inside
-    $colour: quote("#{$colour}");
+    $colour: "#{$colour}";
   }
 
   @if not map-has-key($govuk-colours, $colour) {
@@ -39,6 +41,42 @@
   @return map-get($govuk-colours, $colour);
 }
 
+/// Get brand colour
+///
+/// @param {String | Colour} $colour - Name of brand colour from the palette
+///   (`$govuk-colour`)
+/// @param {String } $variant - Name of the colour variant from the palette
+/// @return {Colour} Representation of the variant of the brand colour
+///
+/// @throw if `$variant` is not a variant from the colour
+/// @access private
+@function _govuk-brand-colour($colour, $variant: null) {
+  // Sass parses unquoted colours as colours, so we need to turn them into
+  // strings before looking them up in the colour palette
+  // https://sass-lang.com/documentation/values/strings#unquoted
+  @if type-of($colour) == "color" {
+    $colour: "#{$colour}";
+  }
+
+  @if $colour == "white" {
+    @return #fff;
+  }
+
+  $colour-variants: map-get($govuk-brand-colours, $colour);
+
+  @if not $colour-variants {
+    @error "Unknown colour `#{$colour}` (available colours: #{map-keys($govuk-brand-colours)}, white)";
+  }
+
+  $result: map-get($colour-variants, $variant);
+
+  @if not $result {
+    @error "Unknown variant `#{$variant}` for colour `#{$colour}` (available variants: #{map-keys($colour-variants)})";
+  }
+
+  @return $result;
+}
+
 /// Get the colour for a government organisation
 ///
 /// @param {String} $organisation - Organisation name, lowercase, hyphenated
diff --git a/packages/govuk-frontend/dist/govuk/settings/_colours-applied.scss b/packages/govuk-frontend/dist/govuk/settings/_colours-applied.scss
index 75ecbe4b4..9d1eb6adf 100644
--- a/packages/govuk-frontend/dist/govuk/settings/_colours-applied.scss
+++ b/packages/govuk-frontend/dist/govuk/settings/_colours-applied.scss
@@ -184,12 +184,12 @@ $govuk-link-active-colour: govuk-colour("black") !default;
 ///
 /// @type Colour
 /// @access private
-$_govuk-rebrand-template-background-colour: govuk-tint($govuk-brand-colour, 95%);
+$_govuk-rebrand-template-background-colour: _govuk-brand-colour("blue", "tint-95");
 
 /// Border colour for areas on a light-blue background
 ///
 /// @type Colour
 /// @access private
-$_govuk-rebrand-border-colour-on-blue-tint-95: govuk-tint($govuk-brand-colour, 50%);
+$_govuk-rebrand-border-colour-on-blue-tint-95: _govuk-brand-colour("blue", "tint-50");
 
 /*# sourceMappingURL=_colours-applied.scss.map */
diff --git a/packages/govuk-frontend/dist/govuk/settings/_colours-palette.scss b/packages/govuk-frontend/dist/govuk/settings/_colours-palette.scss
index 3714f88eb..bb0273eed 100644
--- a/packages/govuk-frontend/dist/govuk/settings/_colours-palette.scss
+++ b/packages/govuk-frontend/dist/govuk/settings/_colours-palette.scss
@@ -34,4 +34,94 @@ $govuk-colours: (
   "turquoise": #28a197
 ) !default;
 
+/// Colour palette
+///
+/// @type Map
+///
+/// @prop $colour.$variant - Representation for the given $variant of $colour, where $colour is the
+///   friendly name for the colour, and $variant the friendly name for the variant
+///   (e.g. `"red": ("primary": #ff0000)`)
+/// @access private
+
+$govuk-brand-colours: (
+  "blue": (
+    "primary": #1d70b8,
+    "tint-25": #5694ca,
+    "tint-50": #8eb8dc,
+    "tint-80": #d2e2f1,
+    "tint-95": #f4f8fb,
+    "shade-50": #0f385c
+  ),
+  "green": (
+    "primary": #11875a,
+    "tint-25": #4da583,
+    "tint-50": #88c3ad,
+    "tint-80": #cfe7de,
+    "tint-95": #f3f9f7,
+    "shade-50": #09442d
+  ),
+  "teal": (
+    "primary": #158187,
+    "tint-25": #50a1a5,
+    "tint-50": #8ac0c3,
+    "tint-80": #d0e6e7,
+    "tint-95": #f3f9f9,
+    "shade-50": #0b4144,
+    "accent": #00ffe0
+  ),
+  "purple": (
+    "primary": #54319f,
+    "tint-25": #7f65b7,
+    "tint-50": #aa98cf,
+    "tint-80": #ddd6ec,
+    "tint-95": #f6f5fa,
+    "shade-50": #2a1950
+  ),
+  "magenta": (
+    "primary": #ca357c,
+    "tint-25": #d7689d,
+    "tint-50": #e59abe,
+    "tint-80": #f4d7e5,
+    "tint-95": #fcf5f8,
+    "shade-50": #651b3e
+  ),
+  "red": (
+    "primary": #ca3535,
+    "tint-25": #d76868,
+    "tint-50": #e59a9a,
+    "tint-80": #f4d7d7,
+    "tint-95": #fcf5f5,
+    "shade-50": #651b1b
+  ),
+  "orange": (
+    "primary": #f47738,
+    "tint-25": #f7996a,
+    "tint-50": #fabb9c,
+    "tint-80": #fde4d7,
+    "tint-95": #fef8f5,
+    "shade-50": #7a3c1c
+  ),
+  "yellow": (
+    "primary": #ffdd00,
+    "tint-25": #ffe640,
+    "tint-50": #ffee80,
+    "tint-80": #fff8cc,
+    "tint-95": #fffdf2,
+    "shade-50": #806f00
+  ),
+  "brown": (
+    "primary": #99704a,
+    "tint-25": #b39477,
+    "tint-50": #ccb8a5,
+    "tint-95": #faf8f6
+  ),
+  "black": (
+    "primary": #0b0c0c,
+    "tint-25": #484949,
+    "tint-50": #858686,
+    "tint-80": #cecece,
+    "tint-95": #f3f3f3
+  )
+) !default;
+
 /*# sourceMappingURL=_colours-palette.scss.map */

Action run for 101867f

@github-actions
Copy link

github-actions bot commented Oct 3, 2025

📋 Stats

No changes to any distributed file sizes!


Action run for 101867f

@romaricpascal romaricpascal marked this pull request as draft October 3, 2025 13:46
Copy link
Member Author

@romaricpascal romaricpascal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll leave the PR as spike for a little bit the time to explore that govuk-colour-variant idea in that last comment as an alternative way to access the brand colours and applied colours.

"background-color",
$from: $govuk-service-navigation-background,
$to: $_govuk-rebrand-template-background-colour
$to: _govuk-brand-colour("blue", "tint-95")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note Now we can access the brand colours, we can avoid re-using the colour of the template background for the Service Navigation.

Comment on lines +61 to +63
@if $colour == "white" {
@return #fff;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note Unless we have a long list of colours that don't fit the <name> -> <variant> structure, I think it's best to handle exceptions in the _govuk-brand-colour function.

If the list starts to grow, we could store them in $_govuk-brand-colours and test for @if type-of $colour-variants == "color" after accessing the value for the colour name.

"tint-80": #cecece,
"tint-95": #f3f3f3
)
) !default;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note While the variable is private, this !default enable us to test the _govuk-brand-colour function easily. This is because of the @import "../settings/colours-palette"; at the top of helpers/_colours.scss.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative could be to pass the map of colours to the _govuk-brand-colour function as a last argument: _govuk-brand-colour($colour, $variant, $colours), similarly to how breakpoint functions receive breakpoints.

If we rename the function govuk-colour-variant, we may use the concept for applied colours potentially, for example doing:

.govuk-link:hover {
	color: govuk-colour-variant(link, hover, $govuk-applied-colours)
}

:focus {
	govuk-colour-variant(focus, text, $govuk-applied-colours)
}

That looks like a separate piece of work though, and doesn't change the situation with testing: either through parameters or !default users need to pass a map of colours.

@romaricpascal romaricpascal changed the title Add private variable and functions to access brand colours [SPIKE-ISH] Add private variable and functions for brand colours Oct 3, 2025
@romaricpascal romaricpascal changed the title [SPIKE-ISH] Add private variable and functions for brand colours [SPIKE-ISH] Add private variable and function for brand colours Oct 3, 2025
// Sass parses unquoted colours as colours, so we need to turn them into
// strings before looking them up in the colour palette
// https://sass-lang.com/documentation/values/strings#unquoted
@if type-of($colour) == "color" {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note Maybe better as:

Suggested change
@if type-of($colour) == "color" {
@if type-of($colour) != "string" {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants