>
diff --git a/src/theme/BlogPostItem/Container/styles.module.css b/src/theme/BlogPostItem/Container/styles.module.css
deleted file mode 100644
index e23c978d..00000000
--- a/src/theme/BlogPostItem/Container/styles.module.css
+++ /dev/null
@@ -1,34 +0,0 @@
-:root {
- --border-color: hsla(240, 6%, 90%, 0.7);
-}
-
-html[data-theme='dark'] {
- --border-color: #262626;
-}
-
-.article {
- position: relative;
- @apply px-4 pt-4 pb-3 lg:px-6;
- /* border: 1px solid var(--border-color); */
-}
-
-.cover {
- position: absolute;
- z-index: 1;
- left: 0;
- right: 0;
- top: 0;
- height: 224px;
-}
-
-.coverMask {
- border-radius: var(--ifm-pagination-nav-border-radius);
-
- background-size: cover;
- background-position: center;
- background-repeat: no-repeat;
- height: 100%;
- width: 100%;
- -webkit-mask-image: linear-gradient(180deg, #fff -17.19%, #00000000 92.43%);
- mask-image: linear-gradient(180deg, #fff -17.19%, #00000000 92.43%);
-}
diff --git a/src/theme/BlogPostPage/index.tsx b/src/theme/BlogPostPage/index.tsx
index 229b51da..63ed76a1 100644
--- a/src/theme/BlogPostPage/index.tsx
+++ b/src/theme/BlogPostPage/index.tsx
@@ -10,7 +10,7 @@ import type { Props } from '@theme/BlogPostPage'
import BlogPostPageMetadata from '@theme/BlogPostPage/Metadata'
import BlogPostPaginator from '@theme/BlogPostPaginator'
import TOC from '@theme/TOC'
-import React, { type ReactNode } from 'react'
+import { type ReactNode } from 'react'
function BlogPostPageContent({
sidebar,
diff --git a/src/theme/Navbar/ColorModeToggle/index.tsx b/src/theme/Navbar/ColorModeToggle/index.tsx
new file mode 100644
index 00000000..b0d40077
--- /dev/null
+++ b/src/theme/Navbar/ColorModeToggle/index.tsx
@@ -0,0 +1,28 @@
+import React from 'react';
+import {useColorMode, useThemeConfig} from '@docusaurus/theme-common';
+import ColorModeToggle from '@theme/ColorModeToggle';
+import type {Props} from '@theme/Navbar/ColorModeToggle';
+import styles from './styles.module.css';
+
+export default function NavbarColorModeToggle({
+ className,
+}: Props): JSX.Element | null {
+ const navbarStyle = useThemeConfig().navbar.style;
+ const disabled = useThemeConfig().colorMode.disableSwitch;
+ const {colorMode, setColorMode} = useColorMode();
+
+ if (disabled) {
+ return null;
+ }
+
+ return (
+
+ );
+}
diff --git a/src/theme/Navbar/ColorModeToggle/styles.module.css b/src/theme/Navbar/ColorModeToggle/styles.module.css
new file mode 100644
index 00000000..7bd077a6
--- /dev/null
+++ b/src/theme/Navbar/ColorModeToggle/styles.module.css
@@ -0,0 +1,3 @@
+.darkNavbarColorModeToggle:hover {
+ background: var(--ifm-color-gray-800);
+}
diff --git a/src/theme/Navbar/Content/index.tsx b/src/theme/Navbar/Content/index.tsx
new file mode 100644
index 00000000..f8bf21e1
--- /dev/null
+++ b/src/theme/Navbar/Content/index.tsx
@@ -0,0 +1,90 @@
+import React, {type ReactNode} from 'react';
+import {useThemeConfig, ErrorCauseBoundary} from '@docusaurus/theme-common';
+import {
+ splitNavbarItems,
+ useNavbarMobileSidebar,
+} from '@docusaurus/theme-common/internal';
+import NavbarItem, {type Props as NavbarItemConfig} from '@theme/NavbarItem';
+import NavbarColorModeToggle from '@theme/Navbar/ColorModeToggle';
+import SearchBar from '@theme/SearchBar';
+import NavbarMobileSidebarToggle from '@theme/Navbar/MobileSidebar/Toggle';
+import NavbarLogo from '@theme/Navbar/Logo';
+import NavbarSearch from '@theme/Navbar/Search';
+
+import styles from './styles.module.css';
+
+function useNavbarItems() {
+ // TODO temporary casting until ThemeConfig type is improved
+ return useThemeConfig().navbar.items as NavbarItemConfig[];
+}
+
+function NavbarItems({items}: {items: NavbarItemConfig[]}): JSX.Element {
+ return (
+ <>
+ {items.map((item, i) => (
+
+ new Error(
+ `A theme navbar item failed to render.
+Please double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:
+${JSON.stringify(item, null, 2)}`,
+ {cause: error},
+ )
+ }>
+
+
+ ))}
+ >
+ );
+}
+
+function NavbarContentLayout({
+ left,
+ right,
+}: {
+ left: ReactNode;
+ right: ReactNode;
+}) {
+ return (
+
+
{left}
+
{right}
+
+ );
+}
+
+export default function NavbarContent(): JSX.Element {
+ const mobileSidebar = useNavbarMobileSidebar();
+
+ const items = useNavbarItems();
+ const [leftItems, rightItems] = splitNavbarItems(items);
+
+ const searchBarItem = items.find((item) => item.type === 'search');
+
+ return (
+
+ {!mobileSidebar.disabled && }
+
+
+ >
+ }
+ right={
+ // TODO stop hardcoding items?
+ // Ask the user to add the respective navbar items => more flexible
+ <>
+
+
+ {!searchBarItem && (
+
+
+
+ )}
+ >
+ }
+ />
+ );
+}
diff --git a/src/theme/Navbar/Content/styles.module.css b/src/theme/Navbar/Content/styles.module.css
new file mode 100644
index 00000000..4c9471e1
--- /dev/null
+++ b/src/theme/Navbar/Content/styles.module.css
@@ -0,0 +1,8 @@
+/*
+Hide color mode toggle in small viewports
+ */
+@media (max-width: 996px) {
+ .colorModeToggle {
+ display: none;
+ }
+}
diff --git a/src/theme/Navbar/Layout/index.tsx b/src/theme/Navbar/Layout/index.tsx
new file mode 100644
index 00000000..14abe9c3
--- /dev/null
+++ b/src/theme/Navbar/Layout/index.tsx
@@ -0,0 +1,51 @@
+import { translate } from '@docusaurus/Translate'
+import { useThemeConfig } from '@docusaurus/theme-common'
+import { useHideableNavbar, useNavbarMobileSidebar } from '@docusaurus/theme-common/internal'
+import type { Props } from '@theme/Navbar/Layout'
+import NavbarMobileSidebar from '@theme/Navbar/MobileSidebar'
+import clsx from 'clsx'
+import { type ComponentProps } from 'react'
+import { useLocation } from 'react-router-dom'
+
+import styles from './styles.module.css'
+
+function NavbarBackdrop(props: ComponentProps<'div'>) {
+ return
+}
+
+export default function NavbarLayout({ children }: Props): JSX.Element {
+ const {
+ navbar: { hideOnScroll, style },
+ } = useThemeConfig()
+ const mobileSidebar = useNavbarMobileSidebar()
+ const { navbarRef, isNavbarVisible } = useHideableNavbar(hideOnScroll)
+
+ const location = useLocation()
+ const isHomePage = location.pathname === '/'
+
+ return (
+
+ )
+}
diff --git a/src/theme/Navbar/Layout/styles.module.css b/src/theme/Navbar/Layout/styles.module.css
new file mode 100644
index 00000000..e72891a4
--- /dev/null
+++ b/src/theme/Navbar/Layout/styles.module.css
@@ -0,0 +1,7 @@
+.navbarHideable {
+ transition: transform var(--ifm-transition-fast) ease;
+}
+
+.navbarHidden {
+ transform: translate3d(0, calc(-100% - 2px), 0);
+}
diff --git a/src/theme/Navbar/Logo/index.tsx b/src/theme/Navbar/Logo/index.tsx
new file mode 100644
index 00000000..db71564b
--- /dev/null
+++ b/src/theme/Navbar/Logo/index.tsx
@@ -0,0 +1,12 @@
+import React from 'react';
+import Logo from '@theme/Logo';
+
+export default function NavbarLogo(): JSX.Element {
+ return (
+
+ );
+}
diff --git a/src/theme/Navbar/MobileSidebar/Header/index.tsx b/src/theme/Navbar/MobileSidebar/Header/index.tsx
new file mode 100644
index 00000000..d1f1659b
--- /dev/null
+++ b/src/theme/Navbar/MobileSidebar/Header/index.tsx
@@ -0,0 +1,33 @@
+import React from 'react';
+import {useNavbarMobileSidebar} from '@docusaurus/theme-common/internal';
+import {translate} from '@docusaurus/Translate';
+import NavbarColorModeToggle from '@theme/Navbar/ColorModeToggle';
+import IconClose from '@theme/Icon/Close';
+import NavbarLogo from '@theme/Navbar/Logo';
+
+function CloseButton() {
+ const mobileSidebar = useNavbarMobileSidebar();
+ return (
+
+ );
+}
+
+export default function NavbarMobileSidebarHeader(): JSX.Element {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/src/theme/Navbar/MobileSidebar/Layout/index.tsx b/src/theme/Navbar/MobileSidebar/Layout/index.tsx
index dd1880ef..ac41cc39 100644
--- a/src/theme/Navbar/MobileSidebar/Layout/index.tsx
+++ b/src/theme/Navbar/MobileSidebar/Layout/index.tsx
@@ -2,7 +2,6 @@ import { useNavbarSecondaryMenu } from '@docusaurus/theme-common/internal'
import UserCard from '@site/src/components/UserCard'
import { cn } from '@site/src/lib/utils'
import type { Props } from '@theme/Navbar/MobileSidebar/Layout'
-import React from 'react'
export default function NavbarMobileSidebarLayout({ header, primaryMenu, secondaryMenu }: Props): JSX.Element {
const { shown: secondaryMenuShown } = useNavbarSecondaryMenu()
diff --git a/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx b/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx
new file mode 100644
index 00000000..db30be49
--- /dev/null
+++ b/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx
@@ -0,0 +1,31 @@
+import React from 'react';
+import {useThemeConfig} from '@docusaurus/theme-common';
+import {useNavbarMobileSidebar} from '@docusaurus/theme-common/internal';
+import NavbarItem, {type Props as NavbarItemConfig} from '@theme/NavbarItem';
+
+function useNavbarItems() {
+ // TODO temporary casting until ThemeConfig type is improved
+ return useThemeConfig().navbar.items as NavbarItemConfig[];
+}
+
+// The primary menu displays the navbar items
+export default function NavbarMobilePrimaryMenu(): JSX.Element {
+ const mobileSidebar = useNavbarMobileSidebar();
+
+ // TODO how can the order be defined for mobile?
+ // Should we allow providing a different list of items?
+ const items = useNavbarItems();
+
+ return (
+