diff --git a/mu-plugins/blocks/global-header-footer/postcss/header/menu.pcss b/mu-plugins/blocks/global-header-footer/postcss/header/menu.pcss
index 70e5d6cae..e534733ea 100644
--- a/mu-plugins/blocks/global-header-footer/postcss/header/menu.pcss
+++ b/mu-plugins/blocks/global-header-footer/postcss/header/menu.pcss
@@ -341,4 +341,9 @@
left: 0;
right: 0;
}
+
+ /* Hide the global header when other menus are open. */
+ html.has-modal-open:not(.has-global-modal-open) .global-header {
+ display: none;
+ }
}
diff --git a/mu-plugins/blocks/local-navigation-bar/images/brush-stroke-mask.svg b/mu-plugins/blocks/local-navigation-bar/images/brush-stroke-mask.svg
new file mode 100644
index 000000000..272553a64
--- /dev/null
+++ b/mu-plugins/blocks/local-navigation-bar/images/brush-stroke-mask.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/mu-plugins/blocks/local-navigation-bar/index.php b/mu-plugins/blocks/local-navigation-bar/index.php
new file mode 100644
index 000000000..804188aa2
--- /dev/null
+++ b/mu-plugins/blocks/local-navigation-bar/index.php
@@ -0,0 +1,93 @@
+ __NAMESPACE__ . '\render',
+ )
+ );
+
+ // Add the Brush Stroke block style.
+ register_block_style(
+ 'wporg/local-navigation-bar',
+ array(
+ 'name' => 'brush-stroke',
+ 'label' => __( 'Brush Stroke', 'wporg' ),
+ )
+ );
+}
+
+/**
+ * Render the block content.
+ *
+ * @param array $attributes Block attributes.
+ * @param string $content Block default content.
+ * @param WP_Block $block Block instance.
+ *
+ * @return string Returns the block markup.
+ */
+function render( $attributes, $content, $block ) {
+ $wrapper_attributes = get_block_wrapper_attributes();
+
+ return sprintf(
+ '
%2$s
',
+ $wrapper_attributes,
+ $content
+ );
+}
+
+/**
+ * Inject the default block values. In the editor, these are read from block.json.
+ * See https://github.com/WordPress/gutenberg/issues/50229.
+ *
+ * @param array $block The parsed block data.
+ *
+ * @return array
+ */
+function update_block_attributes( $block ) {
+ if ( ! empty( $block['blockName'] ) && 'wporg/local-navigation-bar' === $block['blockName'] ) {
+ // Always override alignment.
+ $block['attrs']['align'] = 'full';
+
+ // Set layout values if they don't exist.
+ $default_layout = array(
+ 'type' => 'flex',
+ 'flexWrap' => 'wrap',
+ 'justifyContent' => 'space-between',
+ );
+ if ( ! empty( $block['attrs']['layout'] ) ) {
+ $block['attrs']['layout'] = array_merge( $default_layout, $block['attrs']['layout'] );
+ } else {
+ $block['attrs']['layout'] = $default_layout;
+ }
+
+ // Set position if it doesn't exist (functionally this will always be
+ // sticky, unless different positions are added).
+ if ( empty( $block['attrs']['style']['position'] ) ) {
+ $block['attrs']['style']['position'] = array(
+ 'type' => 'sticky',
+ );
+ }
+ }
+
+ return $block;
+}
diff --git a/mu-plugins/blocks/local-navigation-bar/postcss/editor-style.pcss b/mu-plugins/blocks/local-navigation-bar/postcss/editor-style.pcss
new file mode 100644
index 000000000..dc6533362
--- /dev/null
+++ b/mu-plugins/blocks/local-navigation-bar/postcss/editor-style.pcss
@@ -0,0 +1,3 @@
+.wp-block-wporg-local-navigation-bar .block-editor-inner-blocks {
+ width: 100%;
+}
diff --git a/mu-plugins/blocks/local-navigation-bar/postcss/style.pcss b/mu-plugins/blocks/local-navigation-bar/postcss/style.pcss
new file mode 100644
index 000000000..cc8597e22
--- /dev/null
+++ b/mu-plugins/blocks/local-navigation-bar/postcss/style.pcss
@@ -0,0 +1,68 @@
+:where(.wp-block-wporg-local-navigation-bar) {
+ background-color: var(--wp--preset--color--blueberry-1);
+ color: var(--wp--preset--color--white);
+
+ padding-right: var(--wp--preset--spacing--edge-space);
+ padding-left: var(--wp--preset--spacing--edge-space);
+ padding-top: 16px;
+ padding-bottom: 16px;
+
+ top: var(--wp-global-header-offset, 0);
+}
+
+.wp-block-wporg-local-navigation-bar {
+ & > *:nth-child(3) {
+ flex-basis: 100%;
+ }
+
+ /* Reset the sticky position on small screens. */
+ @media (max-width: 889px) {
+ position: static !important;
+ }
+
+ &.is-style-brush-stroke {
+ position: sticky;
+ padding-bottom: 0 !important; /* Override element style */
+
+ &::before {
+ content: "";
+ min-height: var(--wp--custom--brush-stroke--spacing--height, 16px);
+ position: absolute;
+ top: 100%;
+ left: 0;
+ right: 0;
+ width: auto;
+ mask-image: url(../images/brush-stroke-mask.svg);
+ mask-repeat: no-repeat;
+ mask-size: cover;
+ mask-position: bottom right;
+ background-color: inherit;
+ }
+ }
+
+ /* Make sure breadcrumbs inherit the set text color */
+ & .wp-block-wporg-site-breadcrumbs {
+ & a {
+ color: inherit;
+ }
+ }
+
+ & .wp-block-navigation .wp-block-navigation__submenu-container {
+ top: calc(100% + 10px) !important;
+ left: auto !important;
+ right: 0 !important;
+
+ & .wp-block-navigation-item {
+ display: block;
+ }
+
+ & .wp-block-navigation__submenu-icon {
+ display: none;
+ }
+
+ & .wp-block-navigation__submenu-container {
+ border: none;
+ margin-left: 8px;
+ }
+ }
+}
diff --git a/mu-plugins/blocks/local-navigation-bar/src/block.json b/mu-plugins/blocks/local-navigation-bar/src/block.json
new file mode 100644
index 000000000..6d38aa89b
--- /dev/null
+++ b/mu-plugins/blocks/local-navigation-bar/src/block.json
@@ -0,0 +1,87 @@
+{
+ "$schema": "https://schemas.wp.org/trunk/block.json",
+ "apiVersion": 2,
+ "name": "wporg/local-navigation-bar",
+ "title": "Local Navigation Bar",
+ "icon": "ellipsis",
+ "category": "layout",
+ "description": "A special block to handle the local navigation on pages in a section.",
+ "textdomain": "wporg",
+ "attributes": {
+ "align": {
+ "type": "string",
+ "default": "full"
+ },
+ "backgroundColor": {
+ "type": "string",
+ "default": "blueberry-1"
+ },
+ "layout": {
+ "type": "object",
+ "default": {
+ "type": "flex",
+ "flexWrap": "nowrap",
+ "justifyContent": "space-between"
+ }
+ },
+ "style": {
+ "type": "object",
+ "default": {
+ "spacing": {
+ "padding": {
+ "right": "var:preset|spacing|60",
+ "left": "var:preset|spacing|60",
+ "top": "16px",
+ "bottom": "16px"
+ }
+ },
+ "position": {
+ "type": "sticky"
+ }
+ }
+ },
+ "textColor": {
+ "type": "string",
+ "default": "white"
+ }
+ },
+ "supports": {
+ "align": true,
+ "color": {
+ "text": true,
+ "background": true,
+ "link": true
+ },
+ "position": {
+ "sticky": true
+ },
+ "spacing": {
+ "margin": true,
+ "padding": true,
+ "__experimentalDefaultControls": {
+ "margin": true,
+ "padding": true
+ }
+ },
+ "typography": {
+ "fontSize": true,
+ "lineHeight": true
+ },
+ "__experimentalBorder": {
+ "color": true,
+ "radius": true,
+ "style": true,
+ "width": true,
+ "__experimentalDefaultControls": {
+ "color": true,
+ "radius": true,
+ "style": true,
+ "width": true
+ }
+ },
+ "__experimentalLayout": true
+ },
+ "editorScript": "file:./index.js",
+ "editorStyle": "file:./editor-style.css",
+ "style": "file:./style.css"
+}
diff --git a/mu-plugins/blocks/local-navigation-bar/src/index.js b/mu-plugins/blocks/local-navigation-bar/src/index.js
new file mode 100644
index 000000000..a3817ebb9
--- /dev/null
+++ b/mu-plugins/blocks/local-navigation-bar/src/index.js
@@ -0,0 +1,39 @@
+/**
+ * WordPress dependencies
+ */
+import { registerBlockType } from '@wordpress/blocks';
+import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
+
+/**
+ * Internal dependencies
+ */
+import metadata from './block.json';
+
+function Edit() {
+ return (
+
+
+
+ );
+}
+
+registerBlockType( metadata.name, {
+ edit: Edit,
+ save: () => {
+ return ;
+ },
+} );
diff --git a/mu-plugins/loader.php b/mu-plugins/loader.php
index f8ecc5df3..720da1aa9 100644
--- a/mu-plugins/loader.php
+++ b/mu-plugins/loader.php
@@ -1,5 +1,7 @@