alphagov / govuk-frontend

GOV.UK Frontend contains the code you need to start building a user interface for government platforms and services.
https://frontend.design-system.service.gov.uk/
MIT License
1.17k stars 320 forks source link

Service navigation component #5206

Closed querkmachine closed 1 month ago

querkmachine commented 1 month ago

This PR supersedes #4950. This PR should be considered the working branch for the navigation work.

I opted to make a new PR as we've decided to remove or refactor many aspects of the previous PR. However, we may still integrate those aspects at a later date, so having the previous PR exist as-is as a point of reference and comparison is still useful.

Changes from the previous PR

github-actions[bot] commented 1 month ago

:clipboard: Stats

File sizes

File Size
dist/govuk-frontend-development.min.css 118.4 KiB
dist/govuk-frontend-development.min.js 43.63 KiB
packages/govuk-frontend/dist/govuk/all.bundle.js 90.19 KiB
packages/govuk-frontend/dist/govuk/all.bundle.mjs 84.69 KiB
packages/govuk-frontend/dist/govuk/all.mjs 1.05 KiB
packages/govuk-frontend/dist/govuk/govuk-frontend-component.mjs 359 B
packages/govuk-frontend/dist/govuk/govuk-frontend.min.css 118.39 KiB
packages/govuk-frontend/dist/govuk/govuk-frontend.min.js 43.62 KiB
packages/govuk-frontend/dist/govuk/i18n.mjs 5.55 KiB
packages/govuk-frontend/dist/govuk/init.mjs 4.97 KiB

Modules

File Size (bundled) Size (minified)
all.mjs 81.8 KiB 41.48 KiB
accordion.mjs 23.5 KiB 12.39 KiB
button.mjs 5.98 KiB 2.69 KiB
character-count.mjs 22.4 KiB 9.92 KiB
checkboxes.mjs 5.83 KiB 2.83 KiB
error-summary.mjs 7.89 KiB 3.46 KiB
exit-this-page.mjs 17.1 KiB 9.26 KiB
header.mjs 4.46 KiB 2.6 KiB
notification-banner.mjs 6.26 KiB 2.62 KiB
password-input.mjs 15.15 KiB 7.25 KiB
radios.mjs 4.83 KiB 2.38 KiB
service-navigation.mjs 4.46 KiB 2.69 KiB
skip-link.mjs 4.39 KiB 2.18 KiB
tabs.mjs 10.05 KiB 6.06 KiB

View stats and visualisations on the review app


Action run for 414298be46ba5836c7644f36755dfda268ef417b

github-actions[bot] commented 1 month ago

JavaScript changes to npm package

diff --git a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
index bc47ebb0c..33b78bfdd 100644
--- a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
+++ b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
@@ -899,6 +899,45 @@ class Radios extends GOVUKFrontendComponent {
     }
 }
 Radios.moduleName = "govuk-radios";
+class ServiceNavigation extends GOVUKFrontendComponent {
+    constructor(e) {
+        if (super(), this.$module = void 0, this.$menuButton = void 0, this.$menu = void 0, this.menuIsOpen = !1, this.mql = null, !e) throw new ElementError({
+            componentName: "Service Navigation",
+            element: e,
+            identifier: "Root element (`$module`)"
+        });
+        this.$module = e;
+        const t = e.querySelector(".govuk-js-service-navigation-toggle");
+        if (!t) return this;
+        const n = t.getAttribute("aria-controls");
+        if (!n) throw new ElementError({
+            componentName: "Service Navigation",
+            identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
+        });
+        const i = document.getElementById(n);
+        if (!i) throw new ElementError({
+            componentName: "Service Navigation",
+            element: i,
+            identifier: `Navigation (\`<ul id="${n}">\`)`
+        });
+        this.$menu = i, this.$menuButton = t, this.setupResponsiveChecks(), this.$menuButton.addEventListener("click", (() => this.handleMenuButtonClick()))
+    }
+    setupResponsiveChecks() {
+        const e = getBreakpoint("tablet");
+        if (!e.value) throw new ElementError({
+            componentName: "Service Navigation",
+            identifier: `CSS custom property (\`${e.property}\`) on pseudo-class \`:root\``
+        });
+        this.mql = window.matchMedia(`(min-width: ${e.value})`), "addEventListener" in this.mql ? this.mql.addEventListener("change", (() => this.checkMode())) : this.mql.addListener((() => this.checkMode())), this.checkMode()
+    }
+    checkMode() {
+        this.mql && this.$menu && this.$menuButton && (this.mql.matches ? (this.$menu.removeAttribute("hidden"), this.$menuButton.setAttribute("hidden", "")) : (this.$menuButton.removeAttribute("hidden"), this.$menuButton.setAttribute("aria-expanded", this.menuIsOpen.toString()), this.menuIsOpen ? this.$menu.removeAttribute("hidden") : this.$menu.setAttribute("hidden", "")))
+    }
+    handleMenuButtonClick() {
+        this.menuIsOpen = !this.menuIsOpen, this.checkMode()
+    }
+}
+ServiceNavigation.moduleName = "govuk-service-navigation";
 class SkipLink extends GOVUKFrontendComponent {
     constructor(e) {
         var t;
@@ -1095,6 +1134,7 @@ function initAll(e) {
             [NotificationBanner, e.notificationBanner],
             [PasswordInput, e.passwordInput],
             [Radios],
+            [ServiceNavigation],
             [SkipLink],
             [Tabs]
         ],
@@ -1126,6 +1166,7 @@ export {
     NotificationBanner,
     PasswordInput,
     Radios,
+    ServiceNavigation,
     SkipLink,
     Tabs,
     createAll,

Action run for 414298be46ba5836c7644f36755dfda268ef417b

github-actions[bot] commented 1 month ago

Stylesheets changes to npm package

diff --git a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.css b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.css
index 3e1eaeb38..bf4e7565a 100644
--- a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.css
+++ b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.css
@@ -3687,6 +3687,14 @@ only screen and (min-resolution:2dppx) {
     clear: both
 }

+.govuk-header--full-width-border {
+    border-bottom-color: #1d70b8
+}
+
+.govuk-header--full-width-border .govuk-header__container {
+    border-bottom-color: transparent
+}
+
 .govuk-header__logotype {
     display: inline-block;
     position: relative;
@@ -5117,6 +5125,311 @@ screen and (forced-colors:active) {
     border-color: #0b0c0c
 }

+.govuk-service-navigation {
+    border-bottom: 1px solid #b1b4b6;
+    background-color: #f3f2f1
+}
+
+.govuk-service-navigation__container {
+    display: flex;
+    flex-direction: column;
+    align-items: start
+}
+
+@media (min-width:40.0625em) {
+    .govuk-service-navigation__container {
+        flex-direction: row;
+        flex-wrap: wrap
+    }
+}
+
+.govuk-service-navigation__item,
+.govuk-service-navigation__service-name {
+    position: relative;
+    margin: 10px 0;
+    border: 0 solid #1a65a6
+}
+
+@media (min-width:40.0625em) {
+
+    .govuk-service-navigation__item,
+    .govuk-service-navigation__service-name {
+        margin-top: 0;
+        margin-bottom: 0;
+        padding: 20px 0
+    }
+
+    .govuk-service-navigation__item:not(:last-child),
+    .govuk-service-navigation__service-name:not(:last-child) {
+        margin-right: 20px
+    }
+}
+
+@media (min-width:40.0625em) and (min-width:40.0625em) {
+
+    .govuk-service-navigation__item:not(:last-child),
+    .govuk-service-navigation__service-name:not(:last-child) {
+        margin-right: 30px
+    }
+}
+
+@media (max-width:40.0525em) {
+    .govuk-service-navigation__item--active {
+        margin-left: -15px;
+        padding-left: 10px;
+        border-left-width: 5px
+    }
+}
+
+@media (min-width:40.0625em) {
+    .govuk-service-navigation__item--active {
+        padding-bottom: 15px;
+        border-bottom-width: 5px
+    }
+}
+
+.govuk-service-navigation__link {
+    font-family: GDS Transport, arial, sans-serif;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+    text-decoration: underline;
+    text-decoration-thickness: max(1px, .0625rem);
+    text-underline-offset: .1578em
+}
+
+@media print {
+    .govuk-service-navigation__link {
+        font-family: sans-serif
+    }
+}
+
+.govuk-service-navigation__link:hover {
+    text-decoration-thickness: max(3px, .1875rem, .12em);
+    -webkit-text-decoration-skip-ink: none;
+    text-decoration-skip-ink: none;
+    -webkit-text-decoration-skip: none;
+    text-decoration-skip: none
+}
+
+.govuk-service-navigation__link:focus {
+    outline: 3px solid transparent;
+    background-color: #fd0;
+    box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
+    text-decoration: none;
+    -webkit-box-decoration-break: clone;
+    box-decoration-break: clone
+}
+
+.govuk-service-navigation__link:not(:hover):not(:active) {
+    text-decoration: none
+}
+
+.govuk-service-navigation__link:link,
+.govuk-service-navigation__link:visited {
+    color: #1d70b8
+}
+
+.govuk-service-navigation__link:hover {
+    color: #003078
+}
+
+.govuk-service-navigation__link:active,
+.govuk-service-navigation__link:focus {
+    color: #0b0c0c
+}
+
+.govuk-service-navigation__link:not(:hover):not(:focus) {
+    color: #1a65a6
+}
+
+.govuk-service-navigation__service-name {
+    font-family: GDS Transport, arial, sans-serif;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+    font-weight: 700;
+    font-size: 1rem;
+    line-height: 1.25
+}
+
+@media print {
+    .govuk-service-navigation__service-name {
+        font-family: sans-serif
+    }
+}
+
+@media (min-width:40.0625em) {
+    .govuk-service-navigation__service-name {
+        font-size: 1.1875rem;
+        line-height: 1.3157894737
+    }
+}
+
+@media print {
+    .govuk-service-navigation__service-name {
+        font-size: 14pt;
+        line-height: 1.15
+    }
+}
+
+.govuk-service-navigation__service-name .govuk-service-navigation__link:link,
+.govuk-service-navigation__service-name .govuk-service-navigation__link:visited {
+    color: #0b0c0c
+}
+
+@media print {
+
+    .govuk-service-navigation__service-name .govuk-service-navigation__link:link,
+    .govuk-service-navigation__service-name .govuk-service-navigation__link:visited {
+        color: #000
+    }
+}
+
+.govuk-service-navigation__service-name .govuk-service-navigation__link:hover {
+    color: rgba(11, 12, 12, .99)
+}
+
+.govuk-service-navigation__service-name .govuk-service-navigation__link:active,
+.govuk-service-navigation__service-name .govuk-service-navigation__link:focus {
+    color: #0b0c0c
+}
+
+@media print {
+
+    .govuk-service-navigation__service-name .govuk-service-navigation__link:active,
+    .govuk-service-navigation__service-name .govuk-service-navigation__link:focus {
+        color: #000
+    }
+}
+
+.govuk-service-navigation__toggle {
+    font-family: GDS Transport, arial, sans-serif;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+    font-weight: 700;
+    font-size: 1rem;
+    line-height: 1.25;
+    display: inline-flex;
+    margin: 0 0 10px;
+    padding: 0;
+    border: 0;
+    color: #1a65a6;
+    background: none;
+    word-break: break-all;
+    cursor: pointer;
+    align-items: center
+}
+
+@media print {
+    .govuk-service-navigation__toggle {
+        font-family: sans-serif
+    }
+}
+
+@media (min-width:40.0625em) {
+    .govuk-service-navigation__toggle {
+        font-size: 1.1875rem;
+        line-height: 1.3157894737
+    }
+}
+
+@media print {
+    .govuk-service-navigation__toggle {
+        font-size: 14pt;
+        line-height: 1.15
+    }
+}
+
+.govuk-service-navigation__toggle:focus {
+    outline: 3px solid transparent;
+    color: #0b0c0c;
+    background-color: #fd0;
+    box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
+    text-decoration: none;
+    -webkit-box-decoration-break: clone;
+    box-decoration-break: clone
+}
+
+.govuk-service-navigation__toggle:after {
+    display: inline-block;
+    width: 0;
+    height: 0;
+    -webkit-clip-path: polygon(0 0, 50% 100%, 100% 0);
+    clip-path: polygon(0 0, 50% 100%, 100% 0);
+    border-color: transparent;
+    border-style: solid;
+    border-width: 8.66px 5px 0;
+    border-top-color: inherit;
+    content: "";
+    margin-left: 5px
+}
+
+.govuk-service-navigation__toggle[aria-expanded=true]:after {
+    display: inline-block;
+    width: 0;
+    height: 0;
+    -webkit-clip-path: polygon(50% 0, 0 100%, 100% 100%);
+    clip-path: polygon(50% 0, 0 100%, 100% 100%);
+    border-color: transparent;
+    border-style: solid;
+    border-width: 0 5px 8.66px;
+    border-bottom-color: inherit
+}
+
+.govuk-service-navigation__toggle[hidden] {
+    display: none
+}
+
+.govuk-service-navigation__list {
+    font-family: GDS Transport, arial, sans-serif;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+    font-weight: 400;
+    font-size: 1rem;
+    line-height: 1.25;
+    margin: 0 0 15px;
+    padding: 0;
+    list-style: none
+}
+
+@media print {
+    .govuk-service-navigation__list {
+        font-family: sans-serif
+    }
+}
+
+@media (min-width:40.0625em) {
+    .govuk-service-navigation__list {
+        font-size: 1.1875rem;
+        line-height: 1.3157894737
+    }
+}
+
+@media print {
+    .govuk-service-navigation__list {
+        font-size: 14pt;
+        line-height: 1.15
+    }
+}
+
+@media (min-width:40.0625em) {
+    .govuk-service-navigation__list {
+        display: flex;
+        flex-wrap: wrap;
+        margin-bottom: 0
+    }
+}
+
+@media (min-width:40.0625em) and (-ms-high-contrast:none),
+screen and (min-width:40.0625em) and (-ms-high-contrast:active) {
+    .govuk-service-navigation__list {
+        display: block
+    }
+}
+
+.govuk-service-navigation__active-fallback {
+    font-weight: inherit
+}
+
 .govuk-skip-link {
     font-family: GDS Transport, arial, sans-serif;
     -webkit-font-smoothing: antialiased;

Action run for 414298be46ba5836c7644f36755dfda268ef417b

github-actions[bot] commented 1 month ago

Rendered HTML changes to npm package

diff --git a/packages/govuk-frontend/dist/govuk/components/header/template-with-full-width-border.html b/packages/govuk-frontend/dist/govuk/components/header/template-with-full-width-border.html
new file mode 100644
index 000000000..b90fbeb52
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/header/template-with-full-width-border.html
@@ -0,0 +1,24 @@
+<header class="govuk-header govuk-header--full-width-border" data-module="govuk-header">
+  <div class="govuk-header__container govuk-width-container">
+    <div class="govuk-header__logo">
+      <a href="/" class="govuk-header__link govuk-header__link--homepage">
+        <svg
+          focusable="false"
+          role="img"
+          class="govuk-header__logotype"
+          xmlns="http://www.w3.org/2000/svg"
+          viewBox="0 0 148 30"
+          height="30"
+          width="148"
+          aria-label="GOV.UK"
+        >
+          <title>GOV.UK</title>
+          <path d="M22.6 10.4c-1 .4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s-.1 2-1 2.4m-5.9 6.7c-.9.4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s-.1 2-1 2.4m10.8-3.7c-1 .4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s0 2-1 2.4m3.3 4.8c-1 .4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s-.1 2-1 2.4M17 4.7l2.3 1.2V2.5l-2.3.7-.2-.2.9-3h-3.4l.9 3-.2.2c-.1.1-2.3-.7-2.3-.7v3.4L15 4.7c.1.1.1.2.2.2l-1.3 4c-.1.2-.1.4-.1.6 0 1.1.8 2 1.9 2.2h.7c1-.2 1.9-1.1 1.9-2.1 0-.2 0-.4-.1-.6l-1.3-4c-.1-.2 0-.2.1-.3m-7.6 5.7c.9.4 2-.1 2.4-1 .4-.9-.1-2-1-2.4-.9-.4-2 .1-2.4 1s0 2 1 2.4m-5 3c.9.4 2-.1 2.4-1 .4-.9-.1-2-1-2.4-.9-.4-2 .1-2.4 1s.1 2 1 2.4m-3.2 4.8c.9.4 2-.1 2.4-1 .4-.9-.1-2-1-2.4-.9-.4-2 .1-2.4 1s0 2 1 2.4m14.8 11c4.4 0 8.6.3 12.3.8 1.1-4.5 2.4-7 3.7-8.8l-2.5-.9c.2 1.3.3 1.9 0 2.7-.4-.4-.8-1.1-1.1-2.3l-1.2 4c.7-.5 1.3-.8 2-.9-1.1 2.5-2.6 3.1-3.5 3-1.1-.2-1.7-1.2-1.5-2.1.3-1.2 1.5-1.5 2.1-.1 1.1-2.3-.8-3-2-2.3 1.9-1.9 2.1-3.5.6-5.6-2.1 1.6-2.1 3.2-1.2 5.5-1.2-1.4-3.2-.6-2.5 1.6.9-1.4 2.1-.5 1.9.8-.2 1.1-1.7 2.1-3.5 1.9-2.7-.2-2.9-2.1-2.9-3.6.7-.1 1.9.5 2.9 1.9l.4-4.3c-1.1 1.1-2.1 1.4-3.2 1.4.4-1.2 2.1-3 2.1-3h-5.4s1.7 1.9 2.1 3c-1.1 0-2.1-.2-3.2-1.4l.4 4.3c1-1.4 2.2-2 2.9-1.9-.1 1.5-.2 3.4-2.9 3.6-1.9.2-3.4-.8-3.5-1.9-.2-1.3 1-2.2 1.9-.8.7-2.3-1.2-3-2.5-1.6.9-2.2.9-3.9-1.2-5.5-1.5 2-1.3 3.7.6 5.6-1.2-.7-3.1 0-2 2.3.6-1.4 1.8-1.1 2.1.1.2.9-.3 1.9-1.5 2.1-.9.2-2.4-.5-3.5-3 .6 0 1.2.3 2 .9l-1.2-4c-.3 1.1-.7 1.9-1.1 2.3-.3-.8-.2-1.4 0-2.7l-2.9.9C1.3 23 2.6 25.5 3.7 30c3.7-.5 7.9-.8 12.3-.8m28.3-11.6c0 .9.1 1.7.3 2.5.2.8.6 1.5 1 2.2.5.6 1 1.1 1.7 1.5.7.4 1.5.6 2.5.6.9 0 1.7-.1 2.3-.4s1.1-.7 1.5-1.1c.4-.4.6-.9.8-1.5.1-.5.2-1 .2-1.5v-.2h-5.3v-3.2h9.4V28H55v-2.5c-.3.4-.6.8-1 1.1-.4.3-.8.6-1.3.9-.5.2-1 .4-1.6.6s-1.2.2-1.8.2c-1.5 0-2.9-.3-4-.8-1.2-.6-2.2-1.3-3-2.3-.8-1-1.4-2.1-1.8-3.4-.3-1.4-.5-2.8-.5-4.3s.2-2.9.7-4.2c.5-1.3 1.1-2.4 2-3.4.9-1 1.9-1.7 3.1-2.3 1.2-.6 2.6-.8 4.1-.8 1 0 1.9.1 2.8.3.9.2 1.7.6 2.4 1s1.4.9 1.9 1.5c.6.6 1 1.3 1.4 2l-3.7 2.1c-.2-.4-.5-.9-.8-1.2-.3-.4-.6-.7-1-1-.4-.3-.8-.5-1.3-.7-.5-.2-1.1-.2-1.7-.2-1 0-1.8.2-2.5.6-.7.4-1.3.9-1.7 1.5-.5.6-.8 1.4-1 2.2-.3.8-.4 1.9-.4 2.7zM71.5 6.8c1.5 0 2.9.3 4.2.8 1.2.6 2.3 1.3 3.1 2.3.9 1 1.5 2.1 2 3.4s.7 2.7.7 4.2-.2 2.9-.7 4.2c-.4 1.3-1.1 2.4-2 3.4-.9 1-1.9 1.7-3.1 2.3-1.2.6-2.6.8-4.2.8s-2.9-.3-4.2-.8c-1.2-.6-2.3-1.3-3.1-2.3-.9-1-1.5-2.1-2-3.4-.4-1.3-.7-2.7-.7-4.2s.2-2.9.7-4.2c.4-1.3 1.1-2.4 2-3.4.9-1 1.9-1.7 3.1-2.3 1.2-.5 2.6-.8 4.2-.8zm0 17.6c.9 0 1.7-.2 2.4-.5s1.3-.8 1.7-1.4c.5-.6.8-1.3 1.1-2.2.2-.8.4-1.7.4-2.7v-.1c0-1-.1-1.9-.4-2.7-.2-.8-.6-1.6-1.1-2.2-.5-.6-1.1-1.1-1.7-1.4-.7-.3-1.5-.5-2.4-.5s-1.7.2-2.4.5-1.3.8-1.7 1.4c-.5.6-.8 1.3-1.1 2.2-.2.8-.4 1.7-.4 2.7v.1c0 1 .1 1.9.4 2.7.2.8.6 1.6 1.1 2.2.5.6 1.1 1.1 1.7 1.4.6.3 1.4.5 2.4.5zM88.9 28 83 7h4.7l4 15.7h.1l4-15.7h4.7l-5.9 21h-5.7zm28.8-3.6c.6 0 1.2-.1 1.7-.3.5-.2 1-.4 1.4-.8.4-.4.7-.8.9-1.4.2-.6.3-1.2.3-2v-13h4.1v13.6c0 1.2-.2 2.2-.6 3.1s-1 1.7-1.8 2.4c-.7.7-1.6 1.2-2.7 1.5-1 .4-2.2.5-3.4.5-1.2 0-2.4-.2-3.4-.5-1-.4-1.9-.9-2.7-1.5-.8-.7-1.3-1.5-1.8-2.4-.4-.9-.6-2-.6-3.1V6.9h4.2v13c0 .8.1 1.4.3 2 .2.6.5 1 .9 1.4.4.4.8.6 1.4.8.6.2 1.1.3 1.8.3zm13-17.4h4.2v9.1l7.4-9.1h5.2l-7.2 8.4L148 28h-4.9l-5.5-9.4-2.7 3V28h-4.2V7zm-27.6 16.1c-1.5 0-2.7 1.2-2.7 2.7s1.2 2.7 2.7 2.7 2.7-1.2 2.7-2.7-1.2-2.7-2.7-2.7z"></path>
+        </svg>
+        <span class="govuk-header__product-name">
+          Product Name
+        </span>
+      </a>
+    </div>
+  </div>
+</header>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-default.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-default.html
new file mode 100644
index 000000000..faefef37c
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-default.html
@@ -0,0 +1,57 @@
+
+  <div class="govuk-service-navigation"
+data-module="govuk-service-navigation"
+>
+      <div class="govuk-width-container">
+
+    <div class="govuk-service-navigation__container">
+      
+
+      
+        <nav aria-label="Menu" class="govuk-service-navigation__wrapper">
+          <button type="button" class="govuk-service-navigation__toggle govuk-js-service-navigation-toggle" aria-controls="navigation" hidden>
+            Menu
+          </button>
+
+          <ul class="govuk-service-navigation__list" id="navigation" >
+
+            
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/1">
+                                    
+Navigation item 1
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/2">
+                                    
+Navigation item 2
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/3">
+                                    
+Navigation item 3
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/4">
+                                    
+Navigation item 4
+                  </a>
+              </li>
+
+            </ul>
+        </nav>
+    </div>
+
+    </div>
+
+  </div>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-html-navigation-items.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-html-navigation-items.html
new file mode 100644
index 000000000..3e8fe3809
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-html-navigation-items.html
@@ -0,0 +1,49 @@
+
+  <div class="govuk-service-navigation"
+data-module="govuk-service-navigation"
+>
+      <div class="govuk-width-container">
+
+    <div class="govuk-service-navigation__container">
+      
+
+      
+        <nav aria-label="Menu" class="govuk-service-navigation__wrapper">
+          <button type="button" class="govuk-service-navigation__toggle govuk-js-service-navigation-toggle" aria-controls="navigation" hidden>
+            Menu
+          </button>
+
+          <ul class="govuk-service-navigation__list" id="navigation" >
+
+            
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/1">
+                                    
+<em>Navigation item 1</em>
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/2">
+                                    
+<em>Navigation item 2</em>
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/3">
+                                    
+<em>Navigation item 3</em>
+                  </a>
+              </li>
+
+            </ul>
+        </nav>
+    </div>
+
+    </div>
+
+  </div>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-large-navigation.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-large-navigation.html
new file mode 100644
index 000000000..ad9417df1
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-large-navigation.html
@@ -0,0 +1,153 @@
+
+  <div class="govuk-service-navigation"
+data-module="govuk-service-navigation"
+>
+      <div class="govuk-width-container">
+
+    <div class="govuk-service-navigation__container">
+      
+
+      
+        <nav aria-label="Menu" class="govuk-service-navigation__wrapper">
+          <button type="button" class="govuk-service-navigation__toggle govuk-js-service-navigation-toggle" aria-controls="navigation" hidden>
+            Menu
+          </button>
+
+          <ul class="govuk-service-navigation__list" id="navigation" >
+
+            
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/benefits">
+                                    
+Benefits
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/births-deaths-marriages">
+                                    
+Births, deaths, marriages and care
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/business">
+                                    
+Business and self-employed
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/childcare-parenting">
+                                    
+Childcare and parenting
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/citizenship">
+                                    
+Citizenship and living in the UK
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/justice">
+                                    
+Crime, justice and the law
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/disabilities">
+                                    
+Disabled people
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/driving">
+                                    
+Driving and transport
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/education">
+                                    
+Education and learning
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/employing-people">
+                                    
+Employing people
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/environment-countryside">
+                                    
+Environment and countryside
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/housing-local-services">
+                                    
+Housing and local services
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/tax">
+                                    
+Money and tax
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/abroad">
+                                    
+Passports, travel and living abroad
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/visas-immigration">
+                                    
+Visas and immigration
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/browse/working">
+                                    
+Working, jobs and pensions
+                  </a>
+              </li>
+
+            </ul>
+        </nav>
+    </div>
+
+    </div>
+
+  </div>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-long-service-name.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-long-service-name.html
new file mode 100644
index 000000000..3fb470853
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-long-service-name.html
@@ -0,0 +1,20 @@
+
+  <section aria-label="Service information" class="govuk-service-navigation"
+data-module="govuk-service-navigation"
+>
+      <div class="govuk-width-container">
+
+    <div class="govuk-service-navigation__container">
+      
+        <span class="govuk-service-navigation__service-name">
+            <a href="#/" class="govuk-service-navigation__link">
+              Apply to receive a rare holofoil Charizard Pokémon card from the King
+            </a>
+        </span>
+
+      
+    </div>
+
+    </div>
+
+  </section>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-navigation-with-a-current-item.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-navigation-with-a-current-item.html
new file mode 100644
index 000000000..68234154f
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-navigation-with-a-current-item.html
@@ -0,0 +1,58 @@
+
+  <div class="govuk-service-navigation"
+data-module="govuk-service-navigation"
+>
+      <div class="govuk-width-container">
+
+    <div class="govuk-service-navigation__container">
+      
+
+      
+        <nav aria-label="Menu" class="govuk-service-navigation__wrapper">
+          <button type="button" class="govuk-service-navigation__toggle govuk-js-service-navigation-toggle" aria-controls="navigation" hidden>
+            Menu
+          </button>
+
+          <ul class="govuk-service-navigation__list" id="navigation" >
+
+            
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/1">
+                                    
+Navigation item 1
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item govuk-service-navigation__item--active">
+                  <a class="govuk-service-navigation__link" href="#/2" aria-current="page">
+                                    
+                  <strong class="govuk-service-navigation__active-fallback">Navigation item 2</strong>
+
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/3">
+                                    
+Navigation item 3
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/4">
+                                    
+Navigation item 4
+                  </a>
+              </li>
+
+            </ul>
+        </nav>
+    </div>
+
+    </div>
+
+  </div>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-navigation-with-an-active-item.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-navigation-with-an-active-item.html
new file mode 100644
index 000000000..21595e457
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-navigation-with-an-active-item.html
@@ -0,0 +1,58 @@
+
+  <div class="govuk-service-navigation"
+data-module="govuk-service-navigation"
+>
+      <div class="govuk-width-container">
+
+    <div class="govuk-service-navigation__container">
+      
+
+      
+        <nav aria-label="Menu" class="govuk-service-navigation__wrapper">
+          <button type="button" class="govuk-service-navigation__toggle govuk-js-service-navigation-toggle" aria-controls="navigation" hidden>
+            Menu
+          </button>
+
+          <ul class="govuk-service-navigation__list" id="navigation" >
+
+            
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/1">
+                                    
+Navigation item 1
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item govuk-service-navigation__item--active">
+                  <a class="govuk-service-navigation__link" href="#/2" aria-current="true">
+                                    
+                  <strong class="govuk-service-navigation__active-fallback">Navigation item 2</strong>
+
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/3">
+                                    
+Navigation item 3
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/4">
+                                    
+Navigation item 4
+                  </a>
+              </li>
+
+            </ul>
+        </nav>
+    </div>
+
+    </div>
+
+  </div>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-non-link-navigation-items.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-non-link-navigation-items.html
new file mode 100644
index 000000000..fe4b49ca7
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-non-link-navigation-items.html
@@ -0,0 +1,49 @@
+
+  <div class="govuk-service-navigation"
+data-module="govuk-service-navigation"
+>
+      <div class="govuk-width-container">
+
+    <div class="govuk-service-navigation__container">
+      
+
+      
+        <nav aria-label="Menu" class="govuk-service-navigation__wrapper">
+          <button type="button" class="govuk-service-navigation__toggle govuk-js-service-navigation-toggle" aria-controls="navigation" hidden>
+            Menu
+          </button>
+
+          <ul class="govuk-service-navigation__list" id="navigation" >
+
+            
+              
+              <li class="govuk-service-navigation__item">
+                  <span class="govuk-service-navigation__text">
+                                    
+Navigation item 1
+                  </span>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <span class="govuk-service-navigation__text">
+                                    
+<em>Navigation item 2</em>
+                  </span>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <span class="govuk-service-navigation__text">
+                                    
+Navigation item 3
+                  </span>
+              </li>
+
+            </ul>
+        </nav>
+    </div>
+
+    </div>
+
+  </div>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-link.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-link.html
new file mode 100644
index 000000000..a722c3f06
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-link.html
@@ -0,0 +1,20 @@
+
+  <section aria-label="Service information" class="govuk-service-navigation"
+data-module="govuk-service-navigation"
+>
+      <div class="govuk-width-container">
+
+    <div class="govuk-service-navigation__container">
+      
+        <span class="govuk-service-navigation__service-name">
+            <a href="#/" class="govuk-service-navigation__link">
+              Service name
+            </a>
+        </span>
+
+      
+    </div>
+
+    </div>
+
+  </section>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name-and-navigation.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name-and-navigation.html
new file mode 100644
index 000000000..b344d5451
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name-and-navigation.html
@@ -0,0 +1,63 @@
+
+  <section aria-label="Service information" class="govuk-service-navigation"
+data-module="govuk-service-navigation"
+>
+      <div class="govuk-width-container">
+
+    <div class="govuk-service-navigation__container">
+      
+        <span class="govuk-service-navigation__service-name">
+            <a href="#/" class="govuk-service-navigation__link">
+              Apply for a juggling license
+            </a>
+        </span>
+
+      
+        <nav aria-label="Menu" class="govuk-service-navigation__wrapper">
+          <button type="button" class="govuk-service-navigation__toggle govuk-js-service-navigation-toggle" aria-controls="navigation" hidden>
+            Menu
+          </button>
+
+          <ul class="govuk-service-navigation__list" id="navigation" >
+
+            
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/1">
+                                    
+Navigation item 1
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item govuk-service-navigation__item--active">
+                  <a class="govuk-service-navigation__link" href="#/2" aria-current="true">
+                                    
+                  <strong class="govuk-service-navigation__active-fallback">Navigation item 2</strong>
+
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/3">
+                                    
+Navigation item 3
+                  </a>
+              </li>
+
+              
+              <li class="govuk-service-navigation__item">
+                  <a class="govuk-service-navigation__link" href="#/4">
+                                    
+Navigation item 4
+                  </a>
+              </li>
+
+            </ul>
+        </nav>
+    </div>
+
+    </div>
+
+  </section>
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name.html b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name.html
new file mode 100644
index 000000000..b0bdcf282
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name.html
@@ -0,0 +1,18 @@
+
+  <section aria-label="Service information" class="govuk-service-navigation"
+data-module="govuk-service-navigation"
+>
+      <div class="govuk-width-container">
+
+    <div class="govuk-service-navigation__container">
+      
+        <span class="govuk-service-navigation__service-name">
+            <span class="govuk-service-navigation__text">Service name</span>
+        </span>
+
+      
+    </div>
+
+    </div>
+
+  </section>

Action run for 414298be46ba5836c7644f36755dfda268ef417b

github-actions[bot] commented 1 month ago

Other changes to npm package

diff --git a/packages/govuk-frontend/dist/govuk/all.bundle.js b/packages/govuk-frontend/dist/govuk/all.bundle.js
index 1bccdae71..ac0dcb3a3 100644
--- a/packages/govuk-frontend/dist/govuk/all.bundle.js
+++ b/packages/govuk-frontend/dist/govuk/all.bundle.js
@@ -1994,6 +1994,94 @@
   }
   Radios.moduleName = 'govuk-radios';

+  /**
+   * Service Navigation component
+   *
+   * @preserve
+   */
+  class ServiceNavigation extends GOVUKFrontendComponent {
+    /**
+     * @param {Element | null} $module - HTML element to use for header
+     */
+    constructor($module) {
+      super();
+      this.$module = void 0;
+      this.$menuButton = void 0;
+      this.$menu = void 0;
+      this.menuIsOpen = false;
+      this.mql = null;
+      if (!$module) {
+        throw new ElementError({
+          componentName: 'Service Navigation',
+          element: $module,
+          identifier: 'Root element (`$module`)'
+        });
+      }
+      this.$module = $module;
+      const $menuButton = $module.querySelector('.govuk-js-service-navigation-toggle');
+      if (!$menuButton) {
+        return this;
+      }
+      const menuId = $menuButton.getAttribute('aria-controls');
+      if (!menuId) {
+        throw new ElementError({
+          componentName: 'Service Navigation',
+          identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
+        });
+      }
+      const $menu = document.getElementById(menuId);
+      if (!$menu) {
+        throw new ElementError({
+          componentName: 'Service Navigation',
+          element: $menu,
+          identifier: `Navigation (\`<ul id="${menuId}">\`)`
+        });
+      }
+      this.$menu = $menu;
+      this.$menuButton = $menuButton;
+      this.setupResponsiveChecks();
+      this.$menuButton.addEventListener('click', () => this.handleMenuButtonClick());
+    }
+    setupResponsiveChecks() {
+      const breakpoint = getBreakpoint('tablet');
+      if (!breakpoint.value) {
+        throw new ElementError({
+          componentName: 'Service Navigation',
+          identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
+        });
+      }
+      this.mql = window.matchMedia(`(min-width: ${breakpoint.value})`);
+      if ('addEventListener' in this.mql) {
+        this.mql.addEventListener('change', () => this.checkMode());
+      } else {
+        this.mql.addListener(() => this.checkMode());
+      }
+      this.checkMode();
+    }
+    checkMode() {
+      if (!this.mql || !this.$menu || !this.$menuButton) {
+        return;
+      }
+      if (this.mql.matches) {
+        this.$menu.removeAttribute('hidden');
+        this.$menuButton.setAttribute('hidden', '');
+      } else {
+        this.$menuButton.removeAttribute('hidden');
+        this.$menuButton.setAttribute('aria-expanded', this.menuIsOpen.toString());
+        if (this.menuIsOpen) {
+          this.$menu.removeAttribute('hidden');
+        } else {
+          this.$menu.setAttribute('hidden', '');
+        }
+      }
+    }
+    handleMenuButtonClick() {
+      this.menuIsOpen = !this.menuIsOpen;
+      this.checkMode();
+    }
+  }
+  ServiceNavigation.moduleName = 'govuk-service-navigation';
+
   /**
    * Skip link component
    *
@@ -2355,7 +2443,7 @@
       console.log(new SupportError());
       return;
     }
-    const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [Header], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [SkipLink], [Tabs]];
+    const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [Header], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [ServiceNavigation], [SkipLink], [Tabs]];
     const $scope = (_config$scope = config.scope) != null ? _config$scope : document;
     components.forEach(([Component, config]) => {
       createAll(Component, config, $scope);
@@ -2433,6 +2521,7 @@
   exports.NotificationBanner = NotificationBanner;
   exports.PasswordInput = PasswordInput;
   exports.Radios = Radios;
+  exports.ServiceNavigation = ServiceNavigation;
   exports.SkipLink = SkipLink;
   exports.Tabs = Tabs;
   exports.createAll = createAll;
diff --git a/packages/govuk-frontend/dist/govuk/all.bundle.mjs b/packages/govuk-frontend/dist/govuk/all.bundle.mjs
index bec0c33e5..3137f499e 100644
--- a/packages/govuk-frontend/dist/govuk/all.bundle.mjs
+++ b/packages/govuk-frontend/dist/govuk/all.bundle.mjs
@@ -1988,6 +1988,94 @@ class Radios extends GOVUKFrontendComponent {
 }
 Radios.moduleName = 'govuk-radios';

+/**
+ * Service Navigation component
+ *
+ * @preserve
+ */
+class ServiceNavigation extends GOVUKFrontendComponent {
+  /**
+   * @param {Element | null} $module - HTML element to use for header
+   */
+  constructor($module) {
+    super();
+    this.$module = void 0;
+    this.$menuButton = void 0;
+    this.$menu = void 0;
+    this.menuIsOpen = false;
+    this.mql = null;
+    if (!$module) {
+      throw new ElementError({
+        componentName: 'Service Navigation',
+        element: $module,
+        identifier: 'Root element (`$module`)'
+      });
+    }
+    this.$module = $module;
+    const $menuButton = $module.querySelector('.govuk-js-service-navigation-toggle');
+    if (!$menuButton) {
+      return this;
+    }
+    const menuId = $menuButton.getAttribute('aria-controls');
+    if (!menuId) {
+      throw new ElementError({
+        componentName: 'Service Navigation',
+        identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
+      });
+    }
+    const $menu = document.getElementById(menuId);
+    if (!$menu) {
+      throw new ElementError({
+        componentName: 'Service Navigation',
+        element: $menu,
+        identifier: `Navigation (\`<ul id="${menuId}">\`)`
+      });
+    }
+    this.$menu = $menu;
+    this.$menuButton = $menuButton;
+    this.setupResponsiveChecks();
+    this.$menuButton.addEventListener('click', () => this.handleMenuButtonClick());
+  }
+  setupResponsiveChecks() {
+    const breakpoint = getBreakpoint('tablet');
+    if (!breakpoint.value) {
+      throw new ElementError({
+        componentName: 'Service Navigation',
+        identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
+      });
+    }
+    this.mql = window.matchMedia(`(min-width: ${breakpoint.value})`);
+    if ('addEventListener' in this.mql) {
+      this.mql.addEventListener('change', () => this.checkMode());
+    } else {
+      this.mql.addListener(() => this.checkMode());
+    }
+    this.checkMode();
+  }
+  checkMode() {
+    if (!this.mql || !this.$menu || !this.$menuButton) {
+      return;
+    }
+    if (this.mql.matches) {
+      this.$menu.removeAttribute('hidden');
+      this.$menuButton.setAttribute('hidden', '');
+    } else {
+      this.$menuButton.removeAttribute('hidden');
+      this.$menuButton.setAttribute('aria-expanded', this.menuIsOpen.toString());
+      if (this.menuIsOpen) {
+        this.$menu.removeAttribute('hidden');
+      } else {
+        this.$menu.setAttribute('hidden', '');
+      }
+    }
+  }
+  handleMenuButtonClick() {
+    this.menuIsOpen = !this.menuIsOpen;
+    this.checkMode();
+  }
+}
+ServiceNavigation.moduleName = 'govuk-service-navigation';
+
 /**
  * Skip link component
  *
@@ -2349,7 +2437,7 @@ function initAll(config) {
     console.log(new SupportError());
     return;
   }
-  const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [Header], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [SkipLink], [Tabs]];
+  const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [Header], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [ServiceNavigation], [SkipLink], [Tabs]];
   const $scope = (_config$scope = config.scope) != null ? _config$scope : document;
   components.forEach(([Component, config]) => {
     createAll(Component, config, $scope);
@@ -2417,5 +2505,5 @@ function createAll(Component, config, $scope = document) {
  * @typedef {keyof Config} ConfigKey
  */

-export { Accordion, Button, CharacterCount, Checkboxes, ErrorSummary, ExitThisPage, Header, NotificationBanner, PasswordInput, Radios, SkipLink, Tabs, createAll, initAll, version };
+export { Accordion, Button, CharacterCount, Checkboxes, ErrorSummary, ExitThisPage, Header, NotificationBanner, PasswordInput, Radios, ServiceNavigation, SkipLink, Tabs, createAll, initAll, version };
 //# sourceMappingURL=all.bundle.mjs.map
diff --git a/packages/govuk-frontend/dist/govuk/all.mjs b/packages/govuk-frontend/dist/govuk/all.mjs
index e395113b0..8634e964f 100644
--- a/packages/govuk-frontend/dist/govuk/all.mjs
+++ b/packages/govuk-frontend/dist/govuk/all.mjs
@@ -9,6 +9,7 @@ export { Header } from './components/header/header.mjs';
 export { NotificationBanner } from './components/notification-banner/notification-banner.mjs';
 export { PasswordInput } from './components/password-input/password-input.mjs';
 export { Radios } from './components/radios/radios.mjs';
+export { ServiceNavigation } from './components/service-navigation/service-navigation.mjs';
 export { SkipLink } from './components/skip-link/skip-link.mjs';
 export { Tabs } from './components/tabs/tabs.mjs';
 export { createAll, initAll } from './init.mjs';
diff --git a/packages/govuk-frontend/dist/govuk/components/_index.scss b/packages/govuk-frontend/dist/govuk/components/_index.scss
index c0c34dca3..e909f8f64 100644
--- a/packages/govuk-frontend/dist/govuk/components/_index.scss
+++ b/packages/govuk-frontend/dist/govuk/components/_index.scss
@@ -27,6 +27,7 @@
 @import "phase-banner/index";
 @import "radios/index";
 @import "select/index";
+@import "service-navigation/index";
 @import "skip-link/index";
 @import "summary-list/index";
 @import "table/index";
diff --git a/packages/govuk-frontend/dist/govuk/components/header/_index.scss b/packages/govuk-frontend/dist/govuk/components/header/_index.scss
index 858595250..b91aa7d85 100644
--- a/packages/govuk-frontend/dist/govuk/components/header/_index.scss
+++ b/packages/govuk-frontend/dist/govuk/components/header/_index.scss
@@ -38,6 +38,14 @@
     border-bottom: $govuk-header-border-width solid $govuk-header-border-color;
   }

+  .govuk-header--full-width-border {
+    border-bottom-color: $govuk-header-border-color;
+
+    .govuk-header__container {
+      border-bottom-color: transparent;
+    }
+  }
+
   .govuk-header__logotype {
     display: inline-block;
     position: relative;
diff --git a/packages/govuk-frontend/dist/govuk/components/header/fixtures.json b/packages/govuk-frontend/dist/govuk/components/header/fixtures.json
index 56770525e..24c2c7733 100644
--- a/packages/govuk-frontend/dist/govuk/components/header/fixtures.json
+++ b/packages/govuk-frontend/dist/govuk/components/header/fixtures.json
@@ -323,6 +323,18 @@
             "screenshot": false,
             "html": "<header class=\"govuk-header\" data-module=\"govuk-header\">\n  <div class=\"govuk-header__container govuk-header__container--full-width\">\n    <div class=\"govuk-header__logo\">\n      <a href=\"/\" class=\"govuk-header__link govuk-header__link--homepage\">\n        <svg\n          focusable=\"false\"\n          role=\"img\"\n          class=\"govuk-header__logotype\"\n          xmlns=\"http://www.w3.org/2000/svg\"\n          viewBox=\"0 0 148 30\"\n          height=\"30\"\n          width=\"148\"\n          aria-label=\"GOV.UK\"\n        >\n          <title>GOV.UK</title>\n          <path d=\"M22.6 10.4c-1 .4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s-.1 2-1 2.4m-5.9 6.7c-.9.4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s-.1 2-1 2.4m10.8-3.7c-1 .4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s0 2-1 2.4m3.3 4.8c-1 .4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s-.1 2-1 2.4M17 4.7l2.3 1.2V2.5l-2.3.7-.2-.2.9-3h-3.4l.9 3-.2.2c-.1.1-2.3-.7-2.3-.7v3.4L15 4.7c.1.1.1.2.2.2l-1.3 4c-.1.2-.1.4-.1.6 0 1.1.8 2 1.9 2.2h.7c1-.2 1.9-1.1 1.9-2.1 0-.2 0-.4-.1-.6l-1.3-4c-.1-.2 0-.2.1-.3m-7.6 5.7c.9.4 2-.1 2.4-1 .4-.9-.1-2-1-2.4-.9-.4-2 .1-2.4 1s0 2 1 2.4m-5 3c.9.4 2-.1 2.4-1 .4-.9-.1-2-1-2.4-.9-.4-2 .1-2.4 1s.1 2 1 2.4m-3.2 4.8c.9.4 2-.1 2.4-1 .4-.9-.1-2-1-2.4-.9-.4-2 .1-2.4 1s0 2 1 2.4m14.8 11c4.4 0 8.6.3 12.3.8 1.1-4.5 2.4-7 3.7-8.8l-2.5-.9c.2 1.3.3 1.9 0 2.7-.4-.4-.8-1.1-1.1-2.3l-1.2 4c.7-.5 1.3-.8 2-.9-1.1 2.5-2.6 3.1-3.5 3-1.1-.2-1.7-1.2-1.5-2.1.3-1.2 1.5-1.5 2.1-.1 1.1-2.3-.8-3-2-2.3 1.9-1.9 2.1-3.5.6-5.6-2.1 1.6-2.1 3.2-1.2 5.5-1.2-1.4-3.2-.6-2.5 1.6.9-1.4 2.1-.5 1.9.8-.2 1.1-1.7 2.1-3.5 1.9-2.7-.2-2.9-2.1-2.9-3.6.7-.1 1.9.5 2.9 1.9l.4-4.3c-1.1 1.1-2.1 1.4-3.2 1.4.4-1.2 2.1-3 2.1-3h-5.4s1.7 1.9 2.1 3c-1.1 0-2.1-.2-3.2-1.4l.4 4.3c1-1.4 2.2-2 2.9-1.9-.1 1.5-.2 3.4-2.9 3.6-1.9.2-3.4-.8-3.5-1.9-.2-1.3 1-2.2 1.9-.8.7-2.3-1.2-3-2.5-1.6.9-2.2.9-3.9-1.2-5.5-1.5 2-1.3 3.7.6 5.6-1.2-.7-3.1 0-2 2.3.6-1.4 1.8-1.1 2.1.1.2.9-.3 1.9-1.5 2.1-.9.2-2.4-.5-3.5-3 .6 0 1.2.3 2 .9l-1.2-4c-.3 1.1-.7 1.9-1.1 2.3-.3-.8-.2-1.4 0-2.7l-2.9.9C1.3 23 2.6 25.5 3.7 30c3.7-.5 7.9-.8 12.3-.8m28.3-11.6c0 .9.1 1.7.3 2.5.2.8.6 1.5 1 2.2.5.6 1 1.1 1.7 1.5.7.4 1.5.6 2.5.6.9 0 1.7-.1 2.3-.4s1.1-.7 1.5-1.1c.4-.4.6-.9.8-1.5.1-.5.2-1 .2-1.5v-.2h-5.3v-3.2h9.4V28H55v-2.5c-.3.4-.6.8-1 1.1-.4.3-.8.6-1.3.9-.5.2-1 .4-1.6.6s-1.2.2-1.8.2c-1.5 0-2.9-.3-4-.8-1.2-.6-2.2-1.3-3-2.3-.8-1-1.4-2.1-1.8-3.4-.3-1.4-.5-2.8-.5-4.3s.2-2.9.7-4.2c.5-1.3 1.1-2.4 2-3.4.9-1 1.9-1.7 3.1-2.3 1.2-.6 2.6-.8 4.1-.8 1 0 1.9.1 2.8.3.9.2 1.7.6 2.4 1s1.4.9 1.9 1.5c.6.6 1 1.3 1.4 2l-3.7 2.1c-.2-.4-.5-.9-.8-1.2-.3-.4-.6-.7-1-1-.4-.3-.8-.5-1.3-.7-.5-.2-1.1-.2-1.7-.2-1 0-1.8.2-2.5.6-.7.4-1.3.9-1.7 1.5-.5.6-.8 1.4-1 2.2-.3.8-.4 1.9-.4 2.7zM71.5 6.8c1.5 0 2.9.3 4.2.8 1.2.6 2.3 1.3 3.1 2.3.9 1 1.5 2.1 2 3.4s.7 2.7.7 4.2-.2 2.9-.7 4.2c-.4 1.3-1.1 2.4-2 3.4-.9 1-1.9 1.7-3.1 2.3-1.2.6-2.6.8-4.2.8s-2.9-.3-4.2-.8c-1.2-.6-2.3-1.3-3.1-2.3-.9-1-1.5-2.1-2-3.4-.4-1.3-.7-2.7-.7-4.2s.2-2.9.7-4.2c.4-1.3 1.1-2.4 2-3.4.9-1 1.9-1.7 3.1-2.3 1.2-.5 2.6-.8 4.2-.8zm0 17.6c.9 0 1.7-.2 2.4-.5s1.3-.8 1.7-1.4c.5-.6.8-1.3 1.1-2.2.2-.8.4-1.7.4-2.7v-.1c0-1-.1-1.9-.4-2.7-.2-.8-.6-1.6-1.1-2.2-.5-.6-1.1-1.1-1.7-1.4-.7-.3-1.5-.5-2.4-.5s-1.7.2-2.4.5-1.3.8-1.7 1.4c-.5.6-.8 1.3-1.1 2.2-.2.8-.4 1.7-.4 2.7v.1c0 1 .1 1.9.4 2.7.2.8.6 1.6 1.1 2.2.5.6 1.1 1.1 1.7 1.4.6.3 1.4.5 2.4.5zM88.9 28 83 7h4.7l4 15.7h.1l4-15.7h4.7l-5.9 21h-5.7zm28.8-3.6c.6 0 1.2-.1 1.7-.3.5-.2 1-.4 1.4-.8.4-.4.7-.8.9-1.4.2-.6.3-1.2.3-2v-13h4.1v13.6c0 1.2-.2 2.2-.6 3.1s-1 1.7-1.8 2.4c-.7.7-1.6 1.2-2.7 1.5-1 .4-2.2.5-3.4.5-1.2 0-2.4-.2-3.4-.5-1-.4-1.9-.9-2.7-1.5-.8-.7-1.3-1.5-1.8-2.4-.4-.9-.6-2-.6-3.1V6.9h4.2v13c0 .8.1 1.4.3 2 .2.6.5 1 .9 1.4.4.4.8.6 1.4.8.6.2 1.1.3 1.8.3zm13-17.4h4.2v9.1l7.4-9.1h5.2l-7.2 8.4L148 28h-4.9l-5.5-9.4-2.7 3V28h-4.2V7zm-27.6 16.1c-1.5 0-2.7 1.2-2.7 2.7s1.2 2.7 2.7 2.7 2.7-1.2 2.7-2.7-1.2-2.7-2.7-2.7z\"></path>\n        </svg>\n        <span class=\"govuk-header__product-name\">\n          Product Name\n        </span>\n      </a>\n    </div>\n    <div class=\"govuk-header__content\">\n      <nav aria-label=\"Menu\" class=\"govuk-header__navigation govuk-header__navigation--end\">\n        <button type=\"button\" class=\"govuk-header__menu-button govuk-js-header-toggle\" aria-controls=\"navigation\" hidden>\n          Menu\n        </button>\n\n        <ul id=\"navigation\" class=\"govuk-header__navigation-list\">\n          <li class=\"govuk-header__navigation-item govuk-header__navigation-item--active\">\n            <a class=\"govuk-header__link\" href=\"#1\">\n              Navigation item 1\n            </a>\n          </li>\n          <li class=\"govuk-header__navigation-item\">\n            <a class=\"govuk-header__link\" href=\"#2\">\n              Navigation item 2\n            </a>\n          </li>\n          <li class=\"govuk-header__navigation-item\">\n            <a class=\"govuk-header__link\" href=\"#3\">\n              Navigation item 3\n            </a>\n          </li>\n        </ul>\n      </nav>\n    </div>\n  </div>\n</header>"
         },
+        {
+            "name": "with full width border",
+            "options": {
+                "classes": "govuk-header--full-width-border",
+                "productName": "Product Name"
+            },
+            "hidden": false,
+            "description": "Makes the header's bottom border full width without affecting the header's content.",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<header class=\"govuk-header govuk-header--full-width-border\" data-module=\"govuk-header\">\n  <div class=\"govuk-header__container govuk-width-container\">\n    <div class=\"govuk-header__logo\">\n      <a href=\"/\" class=\"govuk-header__link govuk-header__link--homepage\">\n        <svg\n          focusable=\"false\"\n          role=\"img\"\n          class=\"govuk-header__logotype\"\n          xmlns=\"http://www.w3.org/2000/svg\"\n          viewBox=\"0 0 148 30\"\n          height=\"30\"\n          width=\"148\"\n          aria-label=\"GOV.UK\"\n        >\n          <title>GOV.UK</title>\n          <path d=\"M22.6 10.4c-1 .4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s-.1 2-1 2.4m-5.9 6.7c-.9.4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s-.1 2-1 2.4m10.8-3.7c-1 .4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s0 2-1 2.4m3.3 4.8c-1 .4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s-.1 2-1 2.4M17 4.7l2.3 1.2V2.5l-2.3.7-.2-.2.9-3h-3.4l.9 3-.2.2c-.1.1-2.3-.7-2.3-.7v3.4L15 4.7c.1.1.1.2.2.2l-1.3 4c-.1.2-.1.4-.1.6 0 1.1.8 2 1.9 2.2h.7c1-.2 1.9-1.1 1.9-2.1 0-.2 0-.4-.1-.6l-1.3-4c-.1-.2 0-.2.1-.3m-7.6 5.7c.9.4 2-.1 2.4-1 .4-.9-.1-2-1-2.4-.9-.4-2 .1-2.4 1s0 2 1 2.4m-5 3c.9.4 2-.1 2.4-1 .4-.9-.1-2-1-2.4-.9-.4-2 .1-2.4 1s.1 2 1 2.4m-3.2 4.8c.9.4 2-.1 2.4-1 .4-.9-.1-2-1-2.4-.9-.4-2 .1-2.4 1s0 2 1 2.4m14.8 11c4.4 0 8.6.3 12.3.8 1.1-4.5 2.4-7 3.7-8.8l-2.5-.9c.2 1.3.3 1.9 0 2.7-.4-.4-.8-1.1-1.1-2.3l-1.2 4c.7-.5 1.3-.8 2-.9-1.1 2.5-2.6 3.1-3.5 3-1.1-.2-1.7-1.2-1.5-2.1.3-1.2 1.5-1.5 2.1-.1 1.1-2.3-.8-3-2-2.3 1.9-1.9 2.1-3.5.6-5.6-2.1 1.6-2.1 3.2-1.2 5.5-1.2-1.4-3.2-.6-2.5 1.6.9-1.4 2.1-.5 1.9.8-.2 1.1-1.7 2.1-3.5 1.9-2.7-.2-2.9-2.1-2.9-3.6.7-.1 1.9.5 2.9 1.9l.4-4.3c-1.1 1.1-2.1 1.4-3.2 1.4.4-1.2 2.1-3 2.1-3h-5.4s1.7 1.9 2.1 3c-1.1 0-2.1-.2-3.2-1.4l.4 4.3c1-1.4 2.2-2 2.9-1.9-.1 1.5-.2 3.4-2.9 3.6-1.9.2-3.4-.8-3.5-1.9-.2-1.3 1-2.2 1.9-.8.7-2.3-1.2-3-2.5-1.6.9-2.2.9-3.9-1.2-5.5-1.5 2-1.3 3.7.6 5.6-1.2-.7-3.1 0-2 2.3.6-1.4 1.8-1.1 2.1.1.2.9-.3 1.9-1.5 2.1-.9.2-2.4-.5-3.5-3 .6 0 1.2.3 2 .9l-1.2-4c-.3 1.1-.7 1.9-1.1 2.3-.3-.8-.2-1.4 0-2.7l-2.9.9C1.3 23 2.6 25.5 3.7 30c3.7-.5 7.9-.8 12.3-.8m28.3-11.6c0 .9.1 1.7.3 2.5.2.8.6 1.5 1 2.2.5.6 1 1.1 1.7 1.5.7.4 1.5.6 2.5.6.9 0 1.7-.1 2.3-.4s1.1-.7 1.5-1.1c.4-.4.6-.9.8-1.5.1-.5.2-1 .2-1.5v-.2h-5.3v-3.2h9.4V28H55v-2.5c-.3.4-.6.8-1 1.1-.4.3-.8.6-1.3.9-.5.2-1 .4-1.6.6s-1.2.2-1.8.2c-1.5 0-2.9-.3-4-.8-1.2-.6-2.2-1.3-3-2.3-.8-1-1.4-2.1-1.8-3.4-.3-1.4-.5-2.8-.5-4.3s.2-2.9.7-4.2c.5-1.3 1.1-2.4 2-3.4.9-1 1.9-1.7 3.1-2.3 1.2-.6 2.6-.8 4.1-.8 1 0 1.9.1 2.8.3.9.2 1.7.6 2.4 1s1.4.9 1.9 1.5c.6.6 1 1.3 1.4 2l-3.7 2.1c-.2-.4-.5-.9-.8-1.2-.3-.4-.6-.7-1-1-.4-.3-.8-.5-1.3-.7-.5-.2-1.1-.2-1.7-.2-1 0-1.8.2-2.5.6-.7.4-1.3.9-1.7 1.5-.5.6-.8 1.4-1 2.2-.3.8-.4 1.9-.4 2.7zM71.5 6.8c1.5 0 2.9.3 4.2.8 1.2.6 2.3 1.3 3.1 2.3.9 1 1.5 2.1 2 3.4s.7 2.7.7 4.2-.2 2.9-.7 4.2c-.4 1.3-1.1 2.4-2 3.4-.9 1-1.9 1.7-3.1 2.3-1.2.6-2.6.8-4.2.8s-2.9-.3-4.2-.8c-1.2-.6-2.3-1.3-3.1-2.3-.9-1-1.5-2.1-2-3.4-.4-1.3-.7-2.7-.7-4.2s.2-2.9.7-4.2c.4-1.3 1.1-2.4 2-3.4.9-1 1.9-1.7 3.1-2.3 1.2-.5 2.6-.8 4.2-.8zm0 17.6c.9 0 1.7-.2 2.4-.5s1.3-.8 1.7-1.4c.5-.6.8-1.3 1.1-2.2.2-.8.4-1.7.4-2.7v-.1c0-1-.1-1.9-.4-2.7-.2-.8-.6-1.6-1.1-2.2-.5-.6-1.1-1.1-1.7-1.4-.7-.3-1.5-.5-2.4-.5s-1.7.2-2.4.5-1.3.8-1.7 1.4c-.5.6-.8 1.3-1.1 2.2-.2.8-.4 1.7-.4 2.7v.1c0 1 .1 1.9.4 2.7.2.8.6 1.6 1.1 2.2.5.6 1.1 1.1 1.7 1.4.6.3 1.4.5 2.4.5zM88.9 28 83 7h4.7l4 15.7h.1l4-15.7h4.7l-5.9 21h-5.7zm28.8-3.6c.6 0 1.2-.1 1.7-.3.5-.2 1-.4 1.4-.8.4-.4.7-.8.9-1.4.2-.6.3-1.2.3-2v-13h4.1v13.6c0 1.2-.2 2.2-.6 3.1s-1 1.7-1.8 2.4c-.7.7-1.6 1.2-2.7 1.5-1 .4-2.2.5-3.4.5-1.2 0-2.4-.2-3.4-.5-1-.4-1.9-.9-2.7-1.5-.8-.7-1.3-1.5-1.8-2.4-.4-.9-.6-2-.6-3.1V6.9h4.2v13c0 .8.1 1.4.3 2 .2.6.5 1 .9 1.4.4.4.8.6 1.4.8.6.2 1.1.3 1.8.3zm13-17.4h4.2v9.1l7.4-9.1h5.2l-7.2 8.4L148 28h-4.9l-5.5-9.4-2.7 3V28h-4.2V7zm-27.6 16.1c-1.5 0-2.7 1.2-2.7 2.7s1.2 2.7 2.7 2.7 2.7-1.2 2.7-2.7-1.2-2.7-2.7-2.7z\"></path>\n        </svg>\n        <span class=\"govuk-header__product-name\">\n          Product Name\n        </span>\n      </a>\n    </div>\n  </div>\n</header>"
+        },
         {
             "name": "navigation item with html",
             "options": {
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/README.md b/packages/govuk-frontend/dist/govuk/components/service-navigation/README.md
new file mode 100644
index 000000000..87e7f1f08
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/README.md
@@ -0,0 +1,15 @@
+# Service navigation
+
+## Installation
+
+See the [main README quick start guide](https://github.com/alphagov/govuk-frontend#quick-start) for how to install this component.
+
+## Guidance and Examples
+
+Find out when to use the Service navigation component in your service in the [GOV.UK Design System](https://design-system.service.gov.uk/components/service-navigation).
+
+## Component options
+
+Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
+
+See [options table](https://design-system.service.gov.uk/components/service-navigation/#options-service-navigation-example) for details.
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/_index.scss b/packages/govuk-frontend/dist/govuk/components/service-navigation/_index.scss
new file mode 100644
index 000000000..0eb5a7ed3
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/_index.scss
@@ -0,0 +1,162 @@
+@include govuk-exports("govuk/component/service-navigation") {
+  $govuk-service-navigation-active-link-border-width: govuk-spacing(1);
+  $govuk-service-navigation-background: $govuk-canvas-background-colour;
+  $govuk-service-navigation-border-colour: $govuk-border-colour;
+
+  // We make the link colour a little darker than normal here so that it has
+  // better perceptual contrast with the navigation background.
+  $govuk-service-navigation-link-colour: govuk-shade($govuk-link-colour, 10%);
+
+  .govuk-service-navigation {
+    border-bottom: 1px solid $govuk-service-navigation-border-colour;
+    background-color: $govuk-service-navigation-background;
+  }
+
+  .govuk-service-navigation__container {
+    display: flex;
+    flex-direction: column;
+    align-items: start;
+
+    @include govuk-media-query($from: tablet) {
+      flex-direction: row;
+      flex-wrap: wrap;
+    }
+  }
+
+  // These styles are shared between nav items and the service name, they
+  // ensure that both of them remain vertically aligned with one another
+  .govuk-service-navigation__item,
+  .govuk-service-navigation__service-name {
+    position: relative;
+    margin: govuk-spacing(2) 0;
+    border: 0 solid $govuk-service-navigation-link-colour;
+
+    @include govuk-media-query($from: tablet) {
+      margin-top: 0;
+      margin-bottom: 0;
+      padding: govuk-spacing(4) 0;
+
+      &:not(:last-child) {
+        @include govuk-responsive-margin(6, $direction: right);
+      }
+    }
+  }
+
+  .govuk-service-navigation__item--active {
+    @include govuk-media-query($until: tablet) {
+      // Negative offset the left margin so we can place a current page indicator
+      // to the left without misaligning the list item text.
+      margin-left: ((govuk-spacing(2) + $govuk-service-navigation-active-link-border-width) * -1);
+      padding-left: govuk-spacing(2);
+      border-left-width: $govuk-service-navigation-active-link-border-width;
+    }
+
+    @include govuk-media-query($from: tablet) {
+      padding-bottom: govuk-spacing(4) - $govuk-service-navigation-active-link-border-width;
+      border-bottom-width: $govuk-service-navigation-active-link-border-width;
+    }
+  }
+
+  .govuk-service-navigation__link {
+    @include govuk-link-common;
+    @include govuk-link-style-no-underline;
+    @include govuk-link-style-no-visited-state;
+
+    &:not(:hover):not(:focus) {
+      // We set the colour here as we don't want to override the hover or
+      // focus colours
+      color: $govuk-service-navigation-link-colour;
+    }
+  }
+
+  //
+  // Service name specific code
+  //
+
+  .govuk-service-navigation__service-name {
+    @include govuk-font($size: 19, $weight: bold);
+  }
+
+  // Annoyingly this requires a compound selector in order to overcome the
+  // specificity of the other link colour override we're doing
+  .govuk-service-navigation__service-name .govuk-service-navigation__link {
+    @include govuk-link-style-text;
+  }
+
+  //
+  // Navigation list specific code
+  //
+
+  .govuk-service-navigation__toggle {
+    @include govuk-font($size: 19, $weight: bold);
+    display: inline-flex;
+    margin: 0 0 govuk-spacing(2);
+    padding: 0;
+    border: 0;
+    color: $govuk-service-navigation-link-colour;
+    background: none;
+    word-break: break-all;
+    cursor: pointer;
+    align-items: center;
+
+    &:focus {
+      @include govuk-focused-text;
+    }
+
+    &::after {
+      @include govuk-shape-arrow($direction: down, $base: 10px, $display: inline-block);
+      content: "";
+      margin-left: govuk-spacing(1);
+    }
+
+    &[aria-expanded="true"]::after {
+      @include govuk-shape-arrow($direction: up, $base: 10px, $display: inline-block);
+    }
+
+    // Ensure the button stays hidden if the hidden attribute is present
+    &[hidden] {
+      display: none;
+    }
+  }
+
+  .govuk-service-navigation__list {
+    @include govuk-font($size: 19);
+    margin: 0;
+    margin-bottom: govuk-spacing(3);
+    padding: 0;
+    list-style: none;
+
+    // Make the navigation list a flexbox. Doing so resolves a couple of
+    // accessibility problems caused by the list items being inline-blocks:
+    // - Removes the extra whitespace from between each list item that screen
+    //   readers would pointlessly announce.
+    // - Fixes an NVDA issue in Firefox and Chrome <= 124 where it would read
+    //   all of the links as a run-on sentence.
+    @include govuk-media-query($from: tablet) {
+      display: flex;
+      flex-wrap: wrap;
+      margin-bottom: 0;
+
+      // However... IE11 totally trips over flexbox and doesn't wrap anything,
+      // making all of the items into a single, horizontally scrolling row,
+      // which is no good. This CSS hack removes the flexbox definition for
+      // IE 10 & 11, reverting it to the flawed, but OK, non-flexbox version.
+      //
+      // CSS hack taken from https://stackoverflow.com/questions/11173106/apply-style-only-on-ie#answer-36448860
+      // which also includes an explanation of why this works
+      @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
+        display: block;
+      }
+    }
+  }
+
+  // This is a <strong> element that is used as a fallback mechanism for
+  // visually indicating the current page in scenarios where CSS isn't
+  // available. We don't actually want it to be bold normally, so set it to
+  // inherit the parent font-weight.
+  .govuk-service-navigation__active-fallback {
+    font-weight: inherit;
+  }
+}
+
+/*# sourceMappingURL=_index.scss.map */
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/_service-navigation.scss b/packages/govuk-frontend/dist/govuk/components/service-navigation/_service-navigation.scss
new file mode 100644
index 000000000..8003c1e24
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/_service-navigation.scss
@@ -0,0 +1,4 @@
+@import "../../base";
+@import "./index";
+
+/*# sourceMappingURL=_service-navigation.scss.map */
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/fixtures.json b/packages/govuk-frontend/dist/govuk/components/service-navigation/fixtures.json
new file mode 100644
index 000000000..83e41071c
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/fixtures.json
@@ -0,0 +1,464 @@
+{
+    "component": "service-navigation",
+    "fixtures": [
+        {
+            "name": "default",
+            "options": {
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    },
+                    {
+                        "href": "#/2",
+                        "text": "Navigation item 2"
+                    },
+                    {
+                        "href": "#/3",
+                        "text": "Navigation item 3"
+                    },
+                    {
+                        "href": "#/4",
+                        "text": "Navigation item 4"
+                    }
+                ]
+            },
+            "hidden": false,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden>\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \nNavigation item 2\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+        },
+        {
+            "name": "with navigation with a current item",
+            "options": {
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    },
+                    {
+                        "href": "#/2",
+                        "text": "Navigation item 2",
+                        "current": true
+                    },
+                    {
+                        "href": "#/3",
+                        "text": "Navigation item 3"
+                    },
+                    {
+                        "href": "#/4",
+                        "text": "Navigation item 4"
+                    }
+                ]
+            },
+            "hidden": false,
+            "description": "The current item indicates that the user is present on that exact page. It looks the same as an active item, but marks this item as the one the user is currently viewing in ARIA.",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden>\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\" aria-current=\"page\">\n                                    \n                  <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 2</strong>\n\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+        },
+        {
+            "name": "with navigation with an active item",
+            "options": {
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    },
+                    {
+                        "href": "#/2",
+                        "text": "Navigation item 2",
+                        "active": true
+                    },
+                    {
+                        "href": "#/3",
+                        "text": "Navigation item 3"
+                    },
+                    {
+                        "href": "#/4",
+                        "text": "Navigation item 4"
+                    }
+                ]
+            },
+            "hidden": false,
+            "description": "The active item indicates that the user is within that section, but not on the exact page being linked. It looks the same as a current item, but marks this item as an ancestor to the one the user is viewing in ARIA (e.g. a parent section).",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden>\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\" aria-current=\"true\">\n                                    \n                  <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 2</strong>\n\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+        },
+        {
+            "name": "with large navigation",
+            "options": {
+                "navigation": [
+                    {
+                        "href": "#/browse/benefits",
+                        "text": "Benefits"
+                    },
+                    {
+                        "href": "#/browse/births-deaths-marriages",
+                        "text": "Births, deaths, marriages and care"
+                    },
+                    {
+                        "href": "#/browse/business",
+                        "text": "Business and self-employed"
+                    },
+                    {
+                        "href": "#/browse/childcare-parenting",
+                        "text": "Childcare and parenting"
+                    },
+                    {
+                        "href": "#/browse/citizenship",
+                        "text": "Citizenship and living in the UK"
+                    },
+                    {
+                        "href": "#/browse/justice",
+                        "text": "Crime, justice and the law"
+                    },
+                    {
+                        "href": "#/browse/disabilities",
+                        "text": "Disabled people"
+                    },
+                    {
+                        "href": "#/browse/driving",
+                        "text": "Driving and transport"
+                    },
+                    {
+                        "href": "#/browse/education",
+                        "text": "Education and learning"
+                    },
+                    {
+                        "href": "#/browse/employing-people",
+                        "text": "Employing people"
+                    },
+                    {
+                        "href": "#/browse/environment-countryside",
+                        "text": "Environment and countryside"
+                    },
+                    {
+                        "href": "#/browse/housing-local-services",
+                        "text": "Housing and local services"
+                    },
+                    {
+                        "href": "#/browse/tax",
+                        "text": "Money and tax"
+                    },
+                    {
+                        "href": "#/browse/abroad",
+                        "text": "Passports, travel and living abroad"
+                    },
+                    {
+                        "href": "#/browse/visas-immigration",
+                        "text": "Visas and immigration"
+                    },
+                    {
+                        "href": "#/browse/working",
+                        "text": "Working, jobs and pensions"
+                    }
+                ]
+            },
+            "hidden": false,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden>\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/benefits\">\n                                    \nBenefits\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/births-deaths-marriages\">\n                                    \nBirths, deaths, marriages and care\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/business\">\n                                    \nBusiness and self-employed\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/childcare-parenting\">\n                                    \nChildcare and parenting\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/citizenship\">\n                                    \nCitizenship and living in the UK\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/justice\">\n                                    \nCrime, justice and the law\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/disabilities\">\n                                    \nDisabled people\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/driving\">\n                                    \nDriving and transport\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/education\">\n                                    \nEducation and learning\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/employing-people\">\n                                    \nEmploying people\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/environment-countryside\">\n                                    \nEnvironment and countryside\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/housing-local-services\">\n                                    \nHousing and local services\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/tax\">\n                                    \nMoney and tax\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/abroad\">\n                                    \nPassports, travel and living abroad\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/visas-immigration\">\n                                    \nVisas and immigration\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/browse/working\">\n                                    \nWorking, jobs and pensions\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+        },
+        {
+            "name": "with HTML navigation items",
+            "options": {
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "html": "<em>Navigation item 1</em>"
+                    },
+                    {
+                        "href": "#/2",
+                        "html": "<em>Navigation item 2</em>"
+                    },
+                    {
+                        "href": "#/3",
+                        "html": "<em>Navigation item 3</em>"
+                    }
+                ]
+            },
+            "hidden": false,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden>\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \n<em>Navigation item 1</em>\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n                                    \n<em>Navigation item 2</em>\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \n<em>Navigation item 3</em>\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+        },
+        {
+            "name": "with non-link navigation items",
+            "options": {
+                "navigation": [
+                    {
+                        "text": "Navigation item 1"
+                    },
+                    {
+                        "html": "<em>Navigation item 2</em>"
+                    },
+                    {
+                        "text": "Navigation item 3"
+                    }
+                ]
+            },
+            "hidden": false,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden>\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <span class=\"govuk-service-navigation__text\">\n                                    \nNavigation item 1\n                  </span>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <span class=\"govuk-service-navigation__text\">\n                                    \n<em>Navigation item 2</em>\n                  </span>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <span class=\"govuk-service-navigation__text\">\n                                    \nNavigation item 3\n                  </span>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+        },
+        {
+            "name": "with service name",
+            "options": {
+                "serviceName": "Service name"
+            },
+            "hidden": false,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <span class=\"govuk-service-navigation__text\">Service name</span>\n        </span>\n\n      \n    </div>\n\n    </div>\n\n  </section>"
+        },
+        {
+            "name": "with service link",
+            "options": {
+                "serviceName": "Service name",
+                "serviceUrl": "#/"
+            },
+            "hidden": false,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Service name\n            </a>\n        </span>\n\n      \n    </div>\n\n    </div>\n\n  </section>"
+        },
+        {
+            "name": "with long service name",
+            "options": {
+                "serviceName": "Apply to receive a rare holofoil Charizard Pokémon card from the King",
+                "serviceUrl": "#/"
+            },
+            "hidden": false,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply to receive a rare holofoil Charizard Pokémon card from the King\n            </a>\n        </span>\n\n      \n    </div>\n\n    </div>\n\n  </section>"
+        },
+        {
+            "name": "with service name and navigation",
+            "options": {
+                "serviceName": "Apply for a juggling license",
+                "serviceUrl": "#/",
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    },
+                    {
+                        "href": "#/2",
+                        "text": "Navigation item 2",
+                        "active": true
+                    },
+                    {
+                        "href": "#/3",
+                        "text": "Navigation item 3"
+                    },
+                    {
+                        "href": "#/4",
+                        "text": "Navigation item 4"
+                    }
+                ]
+            },
+            "hidden": false,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <a href=\"#/\" class=\"govuk-service-navigation__link\">\n              Apply for a juggling license\n            </a>\n        </span>\n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden>\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/2\" aria-current=\"true\">\n                                    \n                  <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 2</strong>\n\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n                                    \nNavigation item 3\n                  </a>\n              </li>\n\n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n                                    \nNavigation item 4\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </section>"
+        },
+        {
+            "name": "with no options set",
+            "options": {},
+            "hidden": true,
+            "description": "If no serviceName or navigation is set, don't render anything.",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n    </div>\n\n    </div>\n\n  </div>"
+        },
+        {
+            "name": "attributes",
+            "options": {
+                "serviceName": "Service name",
+                "attributes": {
+                    "data-foo": "bar",
+                    "data-pika": "chu"
+                }
+            },
+            "hidden": true,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\" data-foo=\"bar\" data-pika=\"chu\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <span class=\"govuk-service-navigation__text\">Service name</span>\n        </span>\n\n      \n    </div>\n\n    </div>\n\n  </section>"
+        },
+        {
+            "name": "classes",
+            "options": {
+                "serviceName": "Service name",
+                "classes": "app-my-curious-custom-class"
+            },
+            "hidden": true,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation app-my-curious-custom-class\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <span class=\"govuk-service-navigation__text\">Service name</span>\n        </span>\n\n      \n    </div>\n\n    </div>\n\n  </section>"
+        },
+        {
+            "name": "with custom aria-label",
+            "options": {
+                "serviceName": "Service name",
+                "ariaLabel": "Service name and nav"
+            },
+            "hidden": true,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<section aria-label=\"Service name and nav\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n        <span class=\"govuk-service-navigation__service-name\">\n            <span class=\"govuk-service-navigation__text\">Service name</span>\n        </span>\n\n      \n    </div>\n\n    </div>\n\n  </section>"
+        },
+        {
+            "name": "with custom navigation toggle text",
+            "options": {
+                "menuButtonText": "Enter the NavZone",
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    }
+                ]
+            },
+            "hidden": true,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Enter the NavZone\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden>\n            Enter the NavZone\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+        },
+        {
+            "name": "with custom navigation toggle label",
+            "options": {
+                "menuButtonLabel": "Enter the NavZone",
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    }
+                ]
+            },
+            "hidden": true,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" aria-label=\"Enter the NavZone\" hidden>\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+        },
+        {
+            "name": "with identical navigation toggle text and label",
+            "options": {
+                "menuButtonText": "Enter the NavZone",
+                "menuButtonLabel": "Enter the NavZone",
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    }
+                ]
+            },
+            "hidden": true,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Enter the NavZone\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden>\n            Enter the NavZone\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+        },
+        {
+            "name": "with custom navigation label",
+            "options": {
+                "navigationLabel": "Main navigation",
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    }
+                ]
+            },
+            "hidden": true,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Main navigation\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden>\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+        },
+        {
+            "name": "with custom navigation toggle text and navigation label",
+            "options": {
+                "menuButtonText": "Enter the NavZone",
+                "navigationLabel": "The NavZone",
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    }
+                ]
+            },
+            "hidden": true,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"The NavZone\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden>\n            Enter the NavZone\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+        },
+        {
+            "name": "with custom navigation classes",
+            "options": {
+                "navigationClasses": "app-my-neat-navigation-class",
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    }
+                ]
+            },
+            "hidden": true,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper app-my-neat-navigation-class\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden>\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+        },
+        {
+            "name": "with custom navigation ID",
+            "options": {
+                "navigationId": "main-nav",
+                "navigation": [
+                    {
+                        "href": "#/1",
+                        "text": "Navigation item 1"
+                    }
+                ]
+            },
+            "hidden": true,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"main-nav\" hidden>\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"main-nav\" >\n\n            \n              \n              <li class=\"govuk-service-navigation__item\">\n                  <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n                                    \nNavigation item 1\n                  </a>\n              </li>\n\n            </ul>\n        </nav>\n    </div>\n\n    </div>\n\n  </div>"
+        },
+        {
+            "name": "with slotted content",
+            "options": {
+                "slots": {
+                    "start": "<div>[start]</div>",
+                    "end": "<div>[end]</div>",
+                    "navigationStart": "<li>[navigation start]</li>",
+                    "navigationEnd": "<li>[navigation end]</li>"
+                }
+            },
+            "hidden": true,
+            "description": "",
+            "previewLayoutModifiers": [],
+            "screenshot": false,
+            "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n      <div class=\"govuk-width-container\">\n\n    <div>[start]</div><div class=\"govuk-service-navigation__container\">\n      \n\n      \n        <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n          <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden>\n            Menu\n          </button>\n\n          <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n            <li>[navigation start]</li>\n            <li>[navigation end]</li></ul>\n        </nav>\n    </div>\n\n    <div>[end]</div></div>\n\n  </section>"
+        }
+    ],
+    "previewLayout": "full-width"
+}
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/macro-options.json b/packages/govuk-frontend/dist/govuk/components/service-navigation/macro-options.json
new file mode 100644
index 000000000..272dd94d8
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/macro-options.json
@@ -0,0 +1,138 @@
+[
+    {
+        "name": "classes",
+        "type": "string",
+        "required": false,
+        "description": "Classes to add to the service navigation container."
+    },
+    {
+        "name": "attributes",
+        "type": "object",
+        "required": false,
+        "description": "HTML attributes (for example, data attributes) to add to the service navigation container."
+    },
+    {
+        "name": "ariaLabel",
+        "type": "string",
+        "required": false,
+        "description": "The text for the `aria-label` which labels the service navigation container when a service name is included. Defaults to `\"Service information\"`."
+    },
+    {
+        "name": "menuButtonText",
+        "type": "string",
+        "required": false,
+        "description": "The text of the mobile navigation menu toggle."
+    },
+    {
+        "name": "menuButtonLabel",
+        "type": "string",
+        "required": false,
+        "description": "The screen reader label for the mobile navigation menu toggle. Defaults to the same value as `menuButtonText` if not specified."
+    },
+    {
+        "name": "navigationLabel",
+        "type": "string",
+        "required": false,
+        "description": "The screen reader label for the mobile navigation menu. Defaults to the same value as `menuButtonText` if not specified."
+    },
+    {
+        "name": "navigationId",
+        "type": "string",
+        "required": false,
+        "description": "The ID used to associate the mobile navigation toggle with the navigation menu. Defaults to `navigation`."
+    },
+    {
+        "name": "navigationClasses",
+        "type": "string",
+        "required": false,
+        "description": "Classes to add to the navigation menu container."
+    },
+    {
+        "name": "serviceName",
+        "type": "string",
+        "required": false,
+        "description": "The name of your service."
+    },
+    {
+        "name": "serviceUrl",
+        "type": "string",
+        "required": false,
+        "description": "The homepage of your service."
+    },
+    {
+        "name": "navigation",
+        "type": "array",
+        "required": true,
+        "description": "Used to add navigation to the service header.",
+        "params": [
+            {
+                "name": "current",
+                "type": "boolean",
+                "required": false,
+                "description": "If `true`, indicates that the user is currently on this page. This takes precedence over `active`."
+            },
+            {
+                "name": "active",
+                "type": "boolean",
+                "required": false,
+                "description": "If `true`, indicates that the user is within this group of pages in the navigation hierarchy."
+            },
+            {
+                "name": "html",
+                "type": "string",
+                "required": true,
+                "description": "HTML for the navigation item. If `html` is provided, the `text` option will be ignored."
+            },
+            {
+                "name": "text",
+                "type": "string",
+                "required": true,
+                "description": "Text for the navigation item. If `html` is provided, the `text` option will be ignored."
+            },
+            {
+                "name": "href",
+                "type": "string",
+                "required": false,
+                "description": "URL of the navigation item anchor."
+            },
+            {
+                "name": "attributes",
+                "type": "object",
+                "required": false,
+                "description": "HTML attributes (for example data attributes) to add to the navigation item anchor."
+            }
+        ]
+    },
+    {
+        "name": "slots",
+        "type": "object",
+        "required": false,
+        "description": "Specified points for injecting custom HTML into the service header.",
+        "params": [
+            {
+                "name": "start",
+                "type": "string",
+                "required": false,
+                "description": "HTML injected at the start of the service header container."
+            },
+            {
+                "name": "end",
+                "type": "string",
+                "required": false,
+                "description": "HTML injected at the end of the service header container."
+            },
+            {
+                "name": "navigationStart",
+                "type": "string",
+                "required": false,
+                "description": "HTML injected before the first list item in the navigation list. Requires `navigation` to be set."
+            },
+            {
+                "name": "navigationEnd",
+                "type": "string",
+                "required": false,
+                "description": "HTML injected after the last list item in the navigation list. Requires `navigation` to be set."
+            }
+        ]
+    }
+]
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js b/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js
new file mode 100644
index 000000000..fa3c4c6cc
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js
@@ -0,0 +1,183 @@
+(function (global, factory) {
+  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+  typeof define === 'function' && define.amd ? define(['exports'], factory) :
+  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.GOVUKFrontend = {}));
+})(this, (function (exports) { 'use strict';
+
+  function getBreakpoint(name) {
+    const property = `--govuk-frontend-breakpoint-${name}`;
+    const value = window.getComputedStyle(document.documentElement).getPropertyValue(property);
+    return {
+      property,
+      value: value || undefined
+    };
+  }
+  function isSupported($scope = document.body) {
+    if (!$scope) {
+      return false;
+    }
+    return $scope.classList.contains('govuk-frontend-supported');
+  }
+
+  /**
+   * Schema for component config
+   *
+   * @typedef {object} Schema
+   * @property {{ [field: string]: SchemaProperty | undefined }} properties - Schema properties
+   * @property {SchemaCondition[]} [anyOf] - List of schema conditions
+   */
+
+  /**
+   * Schema property for component config
+   *
+   * @typedef {object} SchemaProperty
+   * @property {'string' | 'boolean' | 'number' | 'object'} type - Property type
+   */
+
+  /**
+   * Schema condition for component config
+   *
+   * @typedef {object} SchemaCondition
+   * @property {string[]} required - List of required config fields
+   * @property {string} errorMessage - Error message when required config fields not provided
+   */
+
+  class GOVUKFrontendError extends Error {
+    constructor(...args) {
+      super(...args);
+      this.name = 'GOVUKFrontendError';
+    }
+  }
+  class SupportError extends GOVUKFrontendError {
+    /**
+     * Checks if GOV.UK Frontend is supported on this page
+     *
+     * @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support
+     */
+    constructor($scope = document.body) {
+      const supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class="govuk-frontend-supported">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';
+      super($scope ? supportMessage : 'GOV.UK Frontend initialised without `<script type="module">`');
+      this.name = 'SupportError';
+    }
+  }
+  class ElementError extends GOVUKFrontendError {
+    constructor(messageOrOptions) {
+      let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';
+      if (typeof messageOrOptions === 'object') {
+        const {
+          componentName,
+          identifier,
+          element,
+          expectedType
+        } = messageOrOptions;
+        message = `${componentName}: ${identifier}`;
+        message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';
+      }
+      super(message);
+      this.name = 'ElementError';
+    }
+  }
+
+  class GOVUKFrontendComponent {
+    constructor() {
+      this.checkSupport();
+    }
+    checkSupport() {
+      if (!isSupported()) {
+        throw new SupportError();
+      }
+    }
+  }
+
+  /**
+   * Service Navigation component
+   *
+   * @preserve
+   */
+  class ServiceNavigation extends GOVUKFrontendComponent {
+    /**
+     * @param {Element | null} $module - HTML element to use for header
+     */
+    constructor($module) {
+      super();
+      this.$module = void 0;
+      this.$menuButton = void 0;
+      this.$menu = void 0;
+      this.menuIsOpen = false;
+      this.mql = null;
+      if (!$module) {
+        throw new ElementError({
+          componentName: 'Service Navigation',
+          element: $module,
+          identifier: 'Root element (`$module`)'
+        });
+      }
+      this.$module = $module;
+      const $menuButton = $module.querySelector('.govuk-js-service-navigation-toggle');
+      if (!$menuButton) {
+        return this;
+      }
+      const menuId = $menuButton.getAttribute('aria-controls');
+      if (!menuId) {
+        throw new ElementError({
+          componentName: 'Service Navigation',
+          identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
+        });
+      }
+      const $menu = document.getElementById(menuId);
+      if (!$menu) {
+        throw new ElementError({
+          componentName: 'Service Navigation',
+          element: $menu,
+          identifier: `Navigation (\`<ul id="${menuId}">\`)`
+        });
+      }
+      this.$menu = $menu;
+      this.$menuButton = $menuButton;
+      this.setupResponsiveChecks();
+      this.$menuButton.addEventListener('click', () => this.handleMenuButtonClick());
+    }
+    setupResponsiveChecks() {
+      const breakpoint = getBreakpoint('tablet');
+      if (!breakpoint.value) {
+        throw new ElementError({
+          componentName: 'Service Navigation',
+          identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
+        });
+      }
+      this.mql = window.matchMedia(`(min-width: ${breakpoint.value})`);
+      if ('addEventListener' in this.mql) {
+        this.mql.addEventListener('change', () => this.checkMode());
+      } else {
+        this.mql.addListener(() => this.checkMode());
+      }
+      this.checkMode();
+    }
+    checkMode() {
+      if (!this.mql || !this.$menu || !this.$menuButton) {
+        return;
+      }
+      if (this.mql.matches) {
+        this.$menu.removeAttribute('hidden');
+        this.$menuButton.setAttribute('hidden', '');
+      } else {
+        this.$menuButton.removeAttribute('hidden');
+        this.$menuButton.setAttribute('aria-expanded', this.menuIsOpen.toString());
+        if (this.menuIsOpen) {
+          this.$menu.removeAttribute('hidden');
+        } else {
+          this.$menu.setAttribute('hidden', '');
+        }
+      }
+    }
+    handleMenuButtonClick() {
+      this.menuIsOpen = !this.menuIsOpen;
+      this.checkMode();
+    }
+  }
+  ServiceNavigation.moduleName = 'govuk-service-navigation';
+
+  exports.ServiceNavigation = ServiceNavigation;
+
+}));
+//# sourceMappingURL=service-navigation.bundle.js.map
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs b/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs
new file mode 100644
index 000000000..1ef6c6d0c
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs
@@ -0,0 +1,175 @@
+function getBreakpoint(name) {
+  const property = `--govuk-frontend-breakpoint-${name}`;
+  const value = window.getComputedStyle(document.documentElement).getPropertyValue(property);
+  return {
+    property,
+    value: value || undefined
+  };
+}
+function isSupported($scope = document.body) {
+  if (!$scope) {
+    return false;
+  }
+  return $scope.classList.contains('govuk-frontend-supported');
+}
+
+/**
+ * Schema for component config
+ *
+ * @typedef {object} Schema
+ * @property {{ [field: string]: SchemaProperty | undefined }} properties - Schema properties
+ * @property {SchemaCondition[]} [anyOf] - List of schema conditions
+ */
+
+/**
+ * Schema property for component config
+ *
+ * @typedef {object} SchemaProperty
+ * @property {'string' | 'boolean' | 'number' | 'object'} type - Property type
+ */
+
+/**
+ * Schema condition for component config
+ *
+ * @typedef {object} SchemaCondition
+ * @property {string[]} required - List of required config fields
+ * @property {string} errorMessage - Error message when required config fields not provided
+ */
+
+class GOVUKFrontendError extends Error {
+  constructor(...args) {
+    super(...args);
+    this.name = 'GOVUKFrontendError';
+  }
+}
+class SupportError extends GOVUKFrontendError {
+  /**
+   * Checks if GOV.UK Frontend is supported on this page
+   *
+   * @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support
+   */
+  constructor($scope = document.body) {
+    const supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class="govuk-frontend-supported">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';
+    super($scope ? supportMessage : 'GOV.UK Frontend initialised without `<script type="module">`');
+    this.name = 'SupportError';
+  }
+}
+class ElementError extends GOVUKFrontendError {
+  constructor(messageOrOptions) {
+    let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';
+    if (typeof messageOrOptions === 'object') {
+      const {
+        componentName,
+        identifier,
+        element,
+        expectedType
+      } = messageOrOptions;
+      message = `${componentName}: ${identifier}`;
+      message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';
+    }
+    super(message);
+    this.name = 'ElementError';
+  }
+}
+
+class GOVUKFrontendComponent {
+  constructor() {
+    this.checkSupport();
+  }
+  checkSupport() {
+    if (!isSupported()) {
+      throw new SupportError();
+    }
+  }
+}
+
+/**
+ * Service Navigation component
+ *
+ * @preserve
+ */
+class ServiceNavigation extends GOVUKFrontendComponent {
+  /**
+   * @param {Element | null} $module - HTML element to use for header
+   */
+  constructor($module) {
+    super();
+    this.$module = void 0;
+    this.$menuButton = void 0;
+    this.$menu = void 0;
+    this.menuIsOpen = false;
+    this.mql = null;
+    if (!$module) {
+      throw new ElementError({
+        componentName: 'Service Navigation',
+        element: $module,
+        identifier: 'Root element (`$module`)'
+      });
+    }
+    this.$module = $module;
+    const $menuButton = $module.querySelector('.govuk-js-service-navigation-toggle');
+    if (!$menuButton) {
+      return this;
+    }
+    const menuId = $menuButton.getAttribute('aria-controls');
+    if (!menuId) {
+      throw new ElementError({
+        componentName: 'Service Navigation',
+        identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
+      });
+    }
+    const $menu = document.getElementById(menuId);
+    if (!$menu) {
+      throw new ElementError({
+        componentName: 'Service Navigation',
+        element: $menu,
+        identifier: `Navigation (\`<ul id="${menuId}">\`)`
+      });
+    }
+    this.$menu = $menu;
+    this.$menuButton = $menuButton;
+    this.setupResponsiveChecks();
+    this.$menuButton.addEventListener('click', () => this.handleMenuButtonClick());
+  }
+  setupResponsiveChecks() {
+    const breakpoint = getBreakpoint('tablet');
+    if (!breakpoint.value) {
+      throw new ElementError({
+        componentName: 'Service Navigation',
+        identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
+      });
+    }
+    this.mql = window.matchMedia(`(min-width: ${breakpoint.value})`);
+    if ('addEventListener' in this.mql) {
+      this.mql.addEventListener('change', () => this.checkMode());
+    } else {
+      this.mql.addListener(() => this.checkMode());
+    }
+    this.checkMode();
+  }
+  checkMode() {
+    if (!this.mql || !this.$menu || !this.$menuButton) {
+      return;
+    }
+    if (this.mql.matches) {
+      this.$menu.removeAttribute('hidden');
+      this.$menuButton.setAttribute('hidden', '');
+    } else {
+      this.$menuButton.removeAttribute('hidden');
+      this.$menuButton.setAttribute('aria-expanded', this.menuIsOpen.toString());
+      if (this.menuIsOpen) {
+        this.$menu.removeAttribute('hidden');
+      } else {
+        this.$menu.setAttribute('hidden', '');
+      }
+    }
+  }
+  handleMenuButtonClick() {
+    this.menuIsOpen = !this.menuIsOpen;
+    this.checkMode();
+  }
+}
+ServiceNavigation.moduleName = 'govuk-service-navigation';
+
+export { ServiceNavigation };
+//# sourceMappingURL=service-navigation.bundle.mjs.map
diff --git a/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.mjs b/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.mjs
new file mode 100644
index 000000000..e3006114b
--- /dev/null
+++ b/packages/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.mjs
@@ -0,0 +1,94 @@
+import { getBreakpoint } from '../../common/index.mjs';
+import { ElementError } from '../../errors/index.mjs';
+import { GOVUKFrontendComponent } from '../../govuk-frontend-component.mjs';
+
+/**
+ * Service Navigation component
+ *
+ * @preserve
+ */
+class ServiceNavigation extends GOVUKFrontendComponent {
+  /**
+   * @param {Element | null} $module - HTML element to use for header
+   */
+  constructor($module) {
+    super();
+    this.$module = void 0;
+    this.$menuButton = void 0;
+    this.$menu = void 0;
+    this.menuIsOpen = false;
+    this.mql = null;
+    if (!$module) {
+      throw new ElementError({
+        componentName: 'Service Navigation',
+        element: $module,
+        identifier: 'Root element (`$module`)'
+      });
+    }
+    this.$module = $module;
+    const $menuButton = $module.querySelector('.govuk-js-service-navigation-toggle');
+    if (!$menuButton) {
+      return this;
+    }
+    const menuId = $menuButton.getAttribute('aria-controls');
+    if (!menuId) {
+      throw new ElementError({
+        componentName: 'Service Navigation',
+        identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
+      });
+    }
+    const $menu = document.getElementById(menuId);
+    if (!$menu) {
+      throw new ElementError({
+        componentName: 'Service Navigation',
+        element: $menu,
+        identifier: `Navigation (\`<ul id="${menuId}">\`)`
+      });
+    }
+    this.$menu = $menu;
+    this.$menuButton = $menuButton;
+    this.setupResponsiveChecks();
+    this.$menuButton.addEventListener('click', () => this.handleMenuButtonClick());
+  }
+  setupResponsiveChecks() {
+    const breakpoint = getBreakpoint('tablet');
+    if (!breakpoint.value) {
+      throw new ElementError({
+        componentName: 'Service Navigation',
+        identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
+      });
+    }
+    this.mql = window.matchMedia(`(min-width: ${breakpoint.value})`);
+    if ('addEventListener' in this.mql) {
+      this.mql.addEventListener('change', () => this.checkMode());
+    } else {
+      this.mql.addListener(() => this.checkMode());
+    }
+    this.checkMode();
+  }
+  checkMode() {
+    if (!this.mql || !this.$menu || !this.$menuButton) {
+      return;
+    }
+    if (this.mql.matches) {
+      this.$menu.removeAttribute('hidden');
+      this.$menuButton.setAttribute('hidden', '');
+    } else {
+      this.$menuButton.removeAttribute('hidden');
+      this.$menuButton.setAttribute('aria-expanded', this.menuIsOpen.toString());
+      if (this.menuIsOpen) {
+        this.$menu.removeAttribute('hidden');
+      } else {
+        this.$menu.setAttribute('hidden', '');
+      }
+    }
+  }
+  handleMenuButtonClick() {
+    this.menuIsOpen = !this.menuIsOpen;
+    this.checkMode();
+  }
+}
+ServiceNavigation.moduleName = 'govuk-service-navigation';
+
+export { ServiceNavigation };
+//# sourceMappingURL=service-navigation.mjs.map
diff --git a/packages/govuk-frontend/dist/govuk/init.mjs b/packages/govuk-frontend/dist/govuk/init.mjs
index f985eaffb..2b98947c3 100644
--- a/packages/govuk-frontend/dist/govuk/init.mjs
+++ b/packages/govuk-frontend/dist/govuk/init.mjs
@@ -9,6 +9,7 @@ import { Header } from './components/header/header.mjs';
 import { NotificationBanner } from './components/notification-banner/notification-banner.mjs';
 import { PasswordInput } from './components/password-input/password-input.mjs';
 import { Radios } from './components/radios/radios.mjs';
+import { ServiceNavigation } from './components/service-navigation/service-navigation.mjs';
 import { SkipLink } from './components/skip-link/skip-link.mjs';
 import { Tabs } from './components/tabs/tabs.mjs';
 import { SupportError } from './errors/index.mjs';
@@ -28,7 +29,7 @@ function initAll(config) {
     console.log(new SupportError());
     return;
   }
-  const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [Header], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [SkipLink], [Tabs]];
+  const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [Header], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [ServiceNavigation], [SkipLink], [Tabs]];
   const $scope = (_config$scope = config.scope) != null ? _config$scope : document;
   components.forEach(([Component, config]) => {
     createAll(Component, config, $scope);

Action run for 414298be46ba5836c7644f36755dfda268ef417b

querkmachine commented 1 month ago

@owenatgov Which parts cannot be translated? I can't see anything hardcoded at a glance.

owenatgov commented 1 month ago

@querkmachine Ah whoops you're right! Sorry, habitual reviewing.

querkmachine commented 1 month ago

@owenatgov Yeah, that one is a lot trickier as the wrapping is a result of flex-wrap, which in turn happens (or doesn't happen) depending on the length of the service name and navigation items. It's not a case of being able to tweak styles for a specific breakpoint.