From edaba14ed198de0bc67b4f1a3b629092f841e2c4 Mon Sep 17 00:00:00 2001
From: Tim Down <158919+timdown@users.noreply.github.com>
Date: Tue, 28 May 2024 12:40:05 +0100
Subject: [PATCH] Merge pull request #18420 from overleaf/td-bs5-nav
Bootstrap 5: Navigation
GitOrigin-RevId: d22683d78c8b3bc3f41bbd276c36f47d480e24ff
---
services/web/app/views/_mixins/navbar.pug | 23 ++
services/web/app/views/layout-marketing.pug | 9 +-
.../layout/navbar-marketing-bootstrap-5.pug | 179 ++++++++++++++
.../components/bootstrap-5/dropdown-menu.tsx | 7 +-
.../components/types/dropdown-menu-props.ts | 4 +
.../bootstrap-5/abstracts/all.scss | 2 +-
.../abstracts/variable-overrides.scss | 36 ++-
.../bootstrap-5/base/bootstrap.scss | 3 +
.../bootstrap-5/components/all.scss | 2 +
.../bootstrap-5/components/button.scss | 1 -
.../bootstrap-5/components/dropdown-menu.scss | 32 ++-
.../bootstrap-5/components/nav.scss | 56 +++++
.../bootstrap-5/components/navbar.scss | 220 ++++++++++++++++++
.../bootstrap-5/foundations/elevation.scss | 4 +-
14 files changed, 555 insertions(+), 23 deletions(-)
create mode 100644 services/web/app/views/_mixins/navbar.pug
create mode 100644 services/web/app/views/layout/navbar-marketing-bootstrap-5.pug
create mode 100644 services/web/frontend/stylesheets/bootstrap-5/components/nav.scss
create mode 100644 services/web/frontend/stylesheets/bootstrap-5/components/navbar.scss
diff --git a/services/web/app/views/_mixins/navbar.pug b/services/web/app/views/_mixins/navbar.pug
new file mode 100644
index 0000000000..bd72cf2939
--- /dev/null
+++ b/services/web/app/views/_mixins/navbar.pug
@@ -0,0 +1,23 @@
+mixin nav-item
+ li(role="none")&attributes(attributes)
+ block
+
+mixin nav-link
+ a(role="menuitem")&attributes(attributes)
+ block
+
+mixin dropdown-menu
+ ul(role="menu").dropdown-menu&attributes(attributes)
+ block
+
+mixin dropdown-menu-item
+ li(role="none")
+ block
+
+mixin dropdown-menu-link-item
+ +dropdown-menu-item
+ a(role="menuitem", tabindex="-1").dropdown-item&attributes(attributes)
+ block
+
+mixin dropdown-menu-divider
+ li(role="separator").dropdown-divider.d-none.d-lg-block
diff --git a/services/web/app/views/layout-marketing.pug b/services/web/app/views/layout-marketing.pug
index a5c7ae5b76..528fabaa82 100644
--- a/services/web/app/views/layout-marketing.pug
+++ b/services/web/app/views/layout-marketing.pug
@@ -7,12 +7,15 @@ block entrypointVar
- entrypoint = 'marketing'
block body
- if (typeof(suppressNavbar) == "undefined")
- include layout/navbar-marketing
+ if (typeof suppressNavbar === "undefined")
+ if bootstrapVersion === 5
+ include layout/navbar-marketing-bootstrap-5
+ else
+ include layout/navbar-marketing
block content
- if (typeof(suppressFooter) == "undefined")
+ if (typeof suppressFooter === "undefined")
if showThinFooter
include layout/footer-marketing
else
diff --git a/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug b/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug
new file mode 100644
index 0000000000..3bacbd65eb
--- /dev/null
+++ b/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug
@@ -0,0 +1,179 @@
+include ../_mixins/navbar
+
+nav.navbar.navbar-default.navbar-main.navbar-expand-lg
+ .container-fluid.navbar-container
+ .navbar-header
+ if settings.nav.custom_logo
+ a(href='/', aria-label=settings.appName, style='background-image:url("'+settings.nav.custom_logo+'")').navbar-brand
+ else if (nav.title)
+ a(href='/', aria-label=settings.appName).navbar-title #{nav.title}
+ else
+ a(href='/', aria-label=settings.appName).navbar-brand
+
+ - var enableUpgradeButton = projectDashboardReact && usersBestSubscription && usersBestSubscription.type === 'free'
+ if (enableUpgradeButton)
+ a.btn.btn-primary.me-2.d-md-none(
+ href="/user/subscription/plans"
+ event-tracking="upgrade-button-click"
+ event-tracking-mb="true"
+ event-tracking-label="upgrade"
+ event-tracking-trigger="click"
+ event-segmentation='{"source": "dashboard-top", "project-dashboard-react": "enabled", "is-dashboard-sidebar-hidden": "true", "is-screen-width-less-than-768px": "true"}'
+ ) #{translate("upgrade")}
+
+ - var canDisplayAdminMenu = hasAdminAccess()
+ - var canDisplayAdminRedirect = canRedirectToAdminDomain()
+ - var canDisplaySplitTestMenu = hasFeature('saas') && (canDisplayAdminMenu || (getSessionUser() && getSessionUser().staffAccess && (getSessionUser().staffAccess.splitTestMetrics || getSessionUser().staffAccess.splitTestManagement)))
+ - var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu
+
+ if (typeof suppressNavbarRight === "undefined")
+ button.navbar-toggler.collapsed(
+ type="button",
+ data-bs-toggle="collapse",
+ data-bs-target="#navbar-main-collapse"
+ aria-controls="navbar-main-collapse"
+ aria-expanded="false"
+ aria-label="Toggle " + translate('navigation')
+ )
+ i.fa.fa-bars(aria-hidden="true")
+
+ .navbar-collapse.collapse#navbar-main-collapse
+ ul.nav.navbar-nav.navbar-right.ms-auto(role="menubar")
+ if (canDisplayAdminMenu || canDisplayAdminRedirect || canDisplaySplitTestMenu)
+ +nav-item.dropdown.subdued
+ button.dropdown-toggle(
+ aria-haspopup="true",
+ aria-expanded="false",
+ data-bs-toggle="dropdown"
+ )
+ | Admin
+ span.caret
+ +dropdown-menu.dropdown-menu-end
+ if canDisplayAdminMenu
+ +dropdown-menu-link-item()(href="/admin") Manage Site
+ +dropdown-menu-link-item()(href="/admin/user") Manage Users
+ +dropdown-menu-link-item()(href="/admin/project") Project URL Lookup
+ if canDisplayAdminRedirect
+ +dropdown-menu-link-item()(settings.adminUrl) Switch to Admin
+ if canDisplaySplitTestMenu
+ +dropdown-menu-link-item()(href="/admin/split-test") Manage Feature Flags
+ if canDisplaySurveyMenu
+ +dropdown-menu-link-item()(href="/admin/survey") Manage Surveys
+
+ // loop over header_extras
+ each item in nav.header_extras
+ -
+ if ((item.only_when_logged_in && getSessionUser())
+ || (item.only_when_logged_out && (!getSessionUser()))
+ || (!item.only_when_logged_out && !item.only_when_logged_in && !item.only_content_pages)
+ || (item.only_content_pages && (typeof suppressNavContentLinks === "undefined" || !suppressNavContentLinks))
+ ){
+ var showNavItem = true
+ } else {
+ var showNavItem = false
+ }
+
+ if showNavItem
+ if item.dropdown
+ +nav-item.dropdown(class=item.class)
+ button.dropdown-toggle(
+ aria-haspopup="true",
+ aria-expanded="false",
+ data-bs-toggle="dropdown"
+ )
+ | !{translate(item.text)}
+ span.caret
+ +dropdown-menu.dropdown-menu-end
+ each child in item.dropdown
+ if child.divider
+ +dropdown-menu-divider
+ else if child.isContactUs
+ +dropdown-menu-link-item()(data-ol-open-contact-form-modal="contact-us" href)
+ span(event-tracking="menu-clicked-contact" event-tracking-mb="true" event-tracking-trigger="click")
+ | #{translate("contact_us")}
+ else
+ if child.url
+ +dropdown-menu-link-item()(
+ class=child.class,
+ event-tracking=child.event
+ event-tracking-mb="true"
+ event-tracking-trigger="click"
+ event-segmentation=child.eventSegmentation
+ ) !{translate(child.text)}
+ else
+ +dropdown-menu-item !{translate(child.text)}
+ else
+ +nav-item(class=item.class)
+ if item.url
+ +nav-link(
+ href=item.url,
+ class=item.class,
+ event-tracking=item.event
+ event-tracking-mb="true"
+ event-tracking-trigger="click"
+ ) !{translate(item.text)}
+ else
+ | !{translate(item.text)}
+
+ // logged out
+ if !getSessionUser()
+ // register link
+ if hasFeature('registration-page')
+ +nav-item.primary
+ +nav-link(
+ href="/register"
+ event-tracking="menu-clicked-register"
+ event-tracking-action="clicked"
+ event-tracking-trigger="click"
+ event-tracking-mb="true"
+ event-segmentation={ page: currentUrl }
+ ) #{translate('sign_up')}
+
+ // login link
+ +nav-item
+ +nav-link(
+ href="/login"
+ event-tracking="menu-clicked-login"
+ event-tracking-action="clicked"
+ event-tracking-trigger="click"
+ event-tracking-mb="true"
+ event-segmentation={ page: currentUrl }
+ ) #{translate('log_in')}
+
+ // projects link and account menu
+ if getSessionUser()
+ +nav-item
+ +nav-link(href="/project") #{translate('Projects')}
+ +nav-item.dropdown
+ button.dropdown-toggle(
+ aria-haspopup="true",
+ aria-expanded="false",
+ data-bs-toggle="dropdown"
+ )
+ | #{translate('Account')}
+ span.caret
+ +dropdown-menu.dropdown-menu-end
+ +dropdown-menu-item
+ div.disabled.dropdown-item #{getSessionUser().email}
+ +dropdown-menu-divider
+ +dropdown-menu-link-item()(href="/user/settings") #{translate('Account Settings')}
+ if nav.showSubscriptionLink
+ +dropdown-menu-link-item()(href="/user/subscription") #{translate('subscription')}
+ +dropdown-menu-divider
+ +dropdown-menu-item
+ //-
+ The button is outside the form but still belongs to it via the form attribute. The reason to do
+ this is that if the button is inside the form, screen readers will not count it in the total
+ number of menu items.
+ button.btn-link.text-left.dropdown-menu-button.dropdown-item(
+ role="menuitem",
+ tabindex="-1"
+ form="logOutForm"
+ )
+ | #{translate('log_out')}
+ form(
+ method="POST",
+ action="/logout",
+ id="logOutForm"
+ )
+ input(name='_csrf', type='hidden', value=csrfToken)
diff --git a/services/web/frontend/js/features/ui/components/bootstrap-5/dropdown-menu.tsx b/services/web/frontend/js/features/ui/components/bootstrap-5/dropdown-menu.tsx
index 9202eb3492..6973ee37c9 100644
--- a/services/web/frontend/js/features/ui/components/bootstrap-5/dropdown-menu.tsx
+++ b/services/web/frontend/js/features/ui/components/bootstrap-5/dropdown-menu.tsx
@@ -11,6 +11,7 @@ import type {
DropdownItemProps,
DropdownToggleProps,
DropdownMenuProps,
+ DropdownDividerProps,
} from '@/features/ui/components/types/dropdown-menu-props'
import MaterialIcon from '@/shared/components/material-icon'
@@ -62,9 +63,9 @@ export function DropdownToggle({ ...props }: DropdownToggleProps) {
}
export function DropdownMenu({ as = 'ul', ...props }: DropdownMenuProps) {
- return
+ return
}
-export function DropdownDivider() {
- return
+export function DropdownDivider({ as = 'li' }: DropdownDividerProps) {
+ return
}
diff --git a/services/web/frontend/js/features/ui/components/types/dropdown-menu-props.ts b/services/web/frontend/js/features/ui/components/types/dropdown-menu-props.ts
index 9084ea15d2..22b20fbce5 100644
--- a/services/web/frontend/js/features/ui/components/types/dropdown-menu-props.ts
+++ b/services/web/frontend/js/features/ui/components/types/dropdown-menu-props.ts
@@ -45,3 +45,7 @@ export type DropdownMenuProps = PropsWithChildren<{
disabled?: boolean
show?: boolean
}>
+
+export type DropdownDividerProps = PropsWithChildren<{
+ as?: ElementType
+}>
diff --git a/services/web/frontend/stylesheets/bootstrap-5/abstracts/all.scss b/services/web/frontend/stylesheets/bootstrap-5/abstracts/all.scss
index f22cfa6898..f4cc66b99f 100644
--- a/services/web/frontend/stylesheets/bootstrap-5/abstracts/all.scss
+++ b/services/web/frontend/stylesheets/bootstrap-5/abstracts/all.scss
@@ -1,3 +1,3 @@
@import 'mixins';
-@import 'variable-overrides';
@import 'variables';
+@import 'variable-overrides';
diff --git a/services/web/frontend/stylesheets/bootstrap-5/abstracts/variable-overrides.scss b/services/web/frontend/stylesheets/bootstrap-5/abstracts/variable-overrides.scss
index a258087c26..eaddc23b43 100644
--- a/services/web/frontend/stylesheets/bootstrap-5/abstracts/variable-overrides.scss
+++ b/services/web/frontend/stylesheets/bootstrap-5/abstracts/variable-overrides.scss
@@ -130,7 +130,6 @@ $form-validation-states: (
),
);
// Close buttons
-// Close button
$btn-close-color: $content-primary;
$btn-close-opacity: 1;
$btn-close-width: 10px;
@@ -145,6 +144,14 @@ $danger: $bg-danger-01;
$light: $bg-light-tertiary;
$dark: $neutral-90;
+// Body colors
+$body-color: $content-primary;
+$body-bg: $bg-light-primary;
+$body-secondary-color: $content-secondary;
+$body-secondary-bg: $bg-light-secondary;
+$body-tertiary-color: $content-disabled;
+$body-tertiary-bg: $bg-light-tertiary;
+
// Badges
$badge-font-size: var(--font-size-01);
$badge-font-weight: var(--bs-body-font-weight);
@@ -183,3 +190,30 @@ $box-shadow-lg: shadow-lg();
$modal-header-padding: $spacing-05 $spacing-06;
$modal-header-padding-x: $spacing-08;
$modal-header-padding-y: $spacing-08;
+
+// Nav toggler
+$navbar-toggler-font-size: 30px;
+$navbar-toggler-padding-x: var(--spacing-05);
+$navbar-toggler-padding-y: var(--spacing-02);
+$navbar-toggler-border-radius: var(--border-radius-base);
+
+// Spacing scale used by Bootstrap utilities
+$spacer: $spacing-06;
+$spacers: (
+ 0: 0,
+ 1: $spacing-02,
+ 2: $spacing-04,
+ 3: $spacing-06,
+ 4: $spacing-08,
+ 5: $spacing-11,
+);
+
+// Dropdowns
+$dropdown-link-disabled-color: var(--content-disabled);
+$dropdown-spacer: var(--spacing-01);
+$dropdown-border-width: 0;
+$dropdown-border-radius: var(--border-radius-base);
+$dropdown-padding-x: var(--spacing-02);
+$dropdown-padding-y: var(--spacing-02);
+$dropdown-item-padding-x: var(--spacing-04);
+$dropdown-item-padding-y: var(--spacing-05);
diff --git a/services/web/frontend/stylesheets/bootstrap-5/base/bootstrap.scss b/services/web/frontend/stylesheets/bootstrap-5/base/bootstrap.scss
index dd6379ca14..155a1b4a56 100644
--- a/services/web/frontend/stylesheets/bootstrap-5/base/bootstrap.scss
+++ b/services/web/frontend/stylesheets/bootstrap-5/base/bootstrap.scss
@@ -22,6 +22,7 @@
// Layout & components
@import 'bootstrap-5/scss/root';
@import 'bootstrap-5/scss/reboot';
+@import 'bootstrap-5/scss/transitions';
@import 'bootstrap-5/scss/type';
@import 'bootstrap-5/scss/images';
@import 'bootstrap-5/scss/containers';
@@ -35,6 +36,8 @@
@import 'bootstrap-5/scss/spinners';
@import 'bootstrap-5/scss/card';
@import 'bootstrap-5/scss/close';
+@import 'bootstrap-5/scss/nav';
+@import 'bootstrap-5/scss/navbar';
// Helpers
@import 'bootstrap-5/scss/helpers';
diff --git a/services/web/frontend/stylesheets/bootstrap-5/components/all.scss b/services/web/frontend/stylesheets/bootstrap-5/components/all.scss
index 5040eb55d7..77d938d5e9 100644
--- a/services/web/frontend/stylesheets/bootstrap-5/components/all.scss
+++ b/services/web/frontend/stylesheets/bootstrap-5/components/all.scss
@@ -9,3 +9,5 @@
@import 'input-suggestions';
@import 'modal';
@import 'footer';
+@import 'nav';
+@import 'navbar';
diff --git a/services/web/frontend/stylesheets/bootstrap-5/components/button.scss b/services/web/frontend/stylesheets/bootstrap-5/components/button.scss
index bc43b96dfa..66d153bdda 100644
--- a/services/web/frontend/stylesheets/bootstrap-5/components/button.scss
+++ b/services/web/frontend/stylesheets/bootstrap-5/components/button.scss
@@ -96,7 +96,6 @@
color: var(--link-ui);
font-weight: normal;
cursor: pointer;
- border-radius: 0;
text-decoration: underline;
font-size: inherit;
vertical-align: inherit;
diff --git a/services/web/frontend/stylesheets/bootstrap-5/components/dropdown-menu.scss b/services/web/frontend/stylesheets/bootstrap-5/components/dropdown-menu.scss
index bcdd3a5580..cdd93837e6 100644
--- a/services/web/frontend/stylesheets/bootstrap-5/components/dropdown-menu.scss
+++ b/services/web/frontend/stylesheets/bootstrap-5/components/dropdown-menu.scss
@@ -3,30 +3,30 @@
}
.dropdown-menu {
- @include shadow-sm;
+ @include shadow-md;
- border: none;
- border-radius: var(--border-radius-base);
- padding: var(--spacing-02);
- transform: none;
width: 240px;
}
.dropdown-item {
@include body-sm;
- border-radius: var(--border-radius-base);
- color: var(--neutral-90);
+ --bs-dropdown-item-border-radius: var(--border-radius-base);
display: grid;
grid-auto-flow: column;
justify-content: start;
+ align-content: center;
min-height: 44px; // a minimum height of 44px to be accessible for touch screens
- padding: var(--spacing-05) var(--spacing-04);
position: relative;
&:active {
background-color: var(--bg-accent-03);
- color: inherit;
+ }
+
+ &,
+ &:active,
+ &:visited {
+ color: var(--neutral-90);
}
&:hover:not(.active),
@@ -49,12 +49,20 @@
background-color: var(--bg-accent-03);
color: var(--green-70);
}
+
+ &.btn-link {
+ text-decoration: none;
+
+ &:hover,
+ &:focus {
+ color: inherit;
+ }
+ }
}
.dropdown-divider {
- border-radius: 1px;
- background-color: var(--border-divider);
- margin: 2px 6px;
+ border-top-color: var(--border-divider);
+ margin: var(--spacing-01) var(--spacing-03);
}
.dropdown-item-description {
diff --git a/services/web/frontend/stylesheets/bootstrap-5/components/nav.scss b/services/web/frontend/stylesheets/bootstrap-5/components/nav.scss
new file mode 100644
index 0000000000..40bcfce6e4
--- /dev/null
+++ b/services/web/frontend/stylesheets/bootstrap-5/components/nav.scss
@@ -0,0 +1,56 @@
+@import 'bootstrap-5/scss/functions';
+
+:root {
+ // Basics
+ --navbar-item-spacing-horizontal: var(--spacing-06);
+
+ --navbar-bg: var(--bg-dark-primary);
+ --navbar-border: transparent;
+
+ --navbar-padding-h: var(--spacing-05);
+ --navbar-padding: 0 var(--navbar-padding-h);
+
+ --navbar-brand-width: 130px;
+ --navbar-brand-image-url: url(../../../../public/img/ol-brand/overleaf-white.svg);
+
+ // Title, when used instead of a logo
+ --navbar-title-font-size: var(--font-size-05);
+ --navbar-title-color: var(--neutral-20);
+ --navbar-title-color-hover: var(--neutral-40);
+
+ // Button-like top-level items
+ --navbar-btn-font-size: #{$font-size-base};
+ --navbar-btn-border-radius: #{$border-radius-full};
+ --navbar-btn-border-width: #{$spacing-01};
+ --navbar-btn-font-weight: #{$font-weight-base};
+ --navbar-btn-padding-v: #{$spacing-02};
+ --navbar-btn-padding-h: #{$spacing-06};
+ --navbar-btn-line-height: #{$line-height-base};
+
+ // Properties of "subdued" items
+ --navbar-subdued-padding: calc(
+ var(--navbar-btn-padding-v) + var(--navbar-btn-border-width)
+ )
+ calc(var(--navbar-btn-padding-h) + 1px);
+ --navbar-subdued-color: var(--white);
+ --navbar-subdued-hover-bg: var(--white);
+ --navbar-subdued-hover-color: var(--green-50);
+
+ // Links
+ --navbar-link-color: var(--white);
+ --navbar-link-border-color: var(--navbar-link-color);
+
+ --navbar-link-hover-color: var(--white);
+ --navbar-link-hover-bg: var(--green-50);
+ --navbar-link-hover-border-color: var(--navbar-link-hover-bg);
+
+ // Toggler
+ --navbar-toggler-expanded-color: var(--navbar-link-color);
+ --navbar-toggler-expanded-bg: var(--blue-60);
+
+ // Mobile view
+ --navbar-hamburger-submenu-bg: var(--bg-dark-secondary);
+ --navbar-hamburger-submenu-item-color: var(--navbar-link-color);
+ --navbar-hamburger-submenu-item-hover-color: var(--navbar-link-color);
+ --navbar-hamburger-submenu-item-hover-bg: var(--navbar-link-hover-bg);
+}
diff --git a/services/web/frontend/stylesheets/bootstrap-5/components/navbar.scss b/services/web/frontend/stylesheets/bootstrap-5/components/navbar.scss
new file mode 100644
index 0000000000..196b7df7b6
--- /dev/null
+++ b/services/web/frontend/stylesheets/bootstrap-5/components/navbar.scss
@@ -0,0 +1,220 @@
+// Default navbar
+.navbar-default {
+ background-color: var(--navbar-bg);
+ border-color: var(--navbar-border);
+ padding: var(--navbar-padding);
+ position: absolute;
+ top: 0;
+ width: 100%;
+ height: $header-height;
+
+ .navbar-container {
+ padding-left: 0;
+ padding-right: 0;
+ }
+
+ .navbar-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ flex: 1;
+ }
+
+ .navbar-brand {
+ width: var(--navbar-brand-width);
+ height: $header-height;
+ padding: 0;
+ background: var(--navbar-brand-image-url) no-repeat left center;
+ background-size: contain;
+ }
+
+ .navbar-title {
+ display: inline-block;
+ font-size: var(--navbar-title-font-size);
+ color: var(--navbar-title-color);
+ text-decoration: none;
+
+ &:hover,
+ &:active,
+ &:focus {
+ color: var(--navbar-title-color-hover);
+ }
+ }
+
+ .navbar-nav {
+ > li {
+ display: inline-flex;
+
+ > a,
+ > .dropdown-toggle {
+ display: block;
+ color: var(--navbar-link-color);
+ background-color: transparent;
+ padding: var(--navbar-btn-padding-v) var(--navbar-btn-padding-h);
+ margin-left: var(--navbar-item-spacing-horizontal);
+ border: var(--navbar-btn-border-width) solid
+ var(--navbar-link-border-color);
+ border-radius: var(--navbar-btn-border-radius);
+ font-size: var(--navbar-btn-font-size);
+ font-weight: var(--navbar-btn-font-weight);
+ line-height: var(--navbar-btn-line-height);
+ text-decoration: none;
+
+ &.show,
+ &:hover,
+ &:focus {
+ color: var(--navbar-link-hover-color);
+ background-color: var(--navbar-link-hover-bg);
+ border-color: var(--navbar-link-hover-border-color);
+ }
+ }
+
+ &.subdued > a,
+ &.subdued > .dropdown-toggle {
+ border: 0;
+ color: var(--navbar-subdued-color);
+ padding: var(--navbar-subdued-padding);
+ margin-left: 0;
+
+ &.show,
+ &:hover,
+ &:focus {
+ color: var(--navbar-subdued-hover-color);
+ background-color: var(--navbar-subdued-hover-bg);
+ }
+ }
+ }
+ }
+
+ .navbar-toggler {
+ color: var(--navbar-link-color);
+ border-radius: var(--border-radius-base);
+ border-width: 0;
+ transition: 0.2s ease-out;
+
+ &:not(.collapsed) {
+ color: var(--navbar-toggler-expanded-color);
+ background-color: var(--navbar-toggler-expanded-bg);
+ transition: 0.2s ease-in;
+ }
+ }
+
+ .navbar-collapse,
+ .navbar-form {
+ border-color: var(--navbar-border);
+ }
+}
+
+@include media-breakpoint-only(lg) {
+ :root {
+ --navbar-btn-padding-h: #{$spacing-04};
+ }
+}
+
+// Different (stacked) layout for smaller screens
+@include media-breakpoint-down(lg) {
+ .navbar-default .navbar-collapse {
+ &.show {
+ min-height: calc(100vh - $header-height);
+ }
+
+ background-color: var(--navbar-bg);
+ margin: 0 calc(-1 * var(--navbar-padding-h));
+ z-index: 1;
+
+ .navbar-nav {
+ > li {
+ display: block;
+
+ > a,
+ > .dropdown-toggle {
+ margin: 0;
+ padding: var(--spacing-05) var(--navbar-padding-h);
+ width: 100%;
+ text-align: left;
+ border-radius: 0;
+ border-width: 0;
+ }
+
+ // Dropdowns get custom display when collapsed
+ .dropdown-menu.show {
+ --bs-dropdown-spacer: 0;
+ box-shadow: none;
+
+ background-color: var(--navbar-hamburger-submenu-bg);
+ width: auto;
+
+ .dropdown-item {
+ padding: var(--spacing-02) var(--spacing-06) var(--spacing-02)
+ var(--spacing-08);
+
+ &:not(.disabled) {
+ color: var(--navbar-hamburger-submenu-item-color);
+
+ &:hover,
+ &:focus {
+ color: var(--navbar-hamburger-submenu-item-hover-color);
+ background-color: var(--navbar-hamburger-submenu-item-hover-bg);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// Accessibility
+.skip-to-content {
+ color: var(--navbar-link-color);
+ background-color: var(--navbar-link-bg);
+ border: var(--spacing-01) solid transparent;
+ border-radius: var(--navbar-btn-border-radius);
+ font-size: var(--navbar-btn-font-size);
+ font-weight: var(--navbar-btn-font-weight);
+ left: calc(var(--navbar-brand-width) + var(--spacing-09));
+ line-height: var(--navbar-btn-line-height);
+ padding: var(--navbar-btn-padding-v) var(--navbar-btn-padding-h);
+ position: absolute;
+ top: -200px;
+ z-index: 1;
+
+ &:focus {
+ background-color: var(--navbar-link-hover-bg);
+ border: var(--spacing-01) solid var(--navbar-link-hover-color);
+ color: var(--white);
+ text-decoration: none;
+ top: calc(($header-height - 36px) / 2); // 36px is the height of the link
+ }
+}
+
+.website-redesign-navbar {
+ --navbar-title-color: var(--content-primary);
+ --navbar-title-color-hover: var(--content-secondary);
+
+ --navbar-brand-image-url: url(../../../../public/img/ol-brand/overleaf-black.svg);
+
+ --navbar-subdued-color: var(--content-primary);
+ --navbar-subdued-hover-bg: var(--bg-dark-primary);
+ --navbar-subdued-hover-color: var(--content-primary-dark);
+
+ --navbar-bg: var(--bg-light-primary);
+
+ // Navbar links
+ --navbar-link-color: var(--content-primary);
+ --navbar-link-border-color: var(--border-primary);
+
+ --navbar-link-hover-color: var(--navbar-link-color);
+ --navbar-link-hover-bg: var(--bg-light-tertiary);
+ --navbar-link-hover-border-color: var(--navbar-link-border-color);
+
+ // Toggler
+ --navbar-toggler-expanded-color: var(--white);
+ --navbar-toggler-expanded-bg: var(--bg-dark-primary);
+
+ // Mobile view
+ --navbar-hamburger-submenu-bg: var(--bg-light-secondary);
+ --navbar-hamburger-submenu-item-color: var(--navbar-link-color);
+ --navbar-hamburger-submenu-item-hover-color: var(--white);
+ --navbar-hamburger-submenu-item-hover-bg: var(--bg-dark-primary);
+}
diff --git a/services/web/frontend/stylesheets/bootstrap-5/foundations/elevation.scss b/services/web/frontend/stylesheets/bootstrap-5/foundations/elevation.scss
index 78cec48f0f..f75e99a21c 100644
--- a/services/web/frontend/stylesheets/bootstrap-5/foundations/elevation.scss
+++ b/services/web/frontend/stylesheets/bootstrap-5/foundations/elevation.scss
@@ -13,6 +13,6 @@
// Modals, drawers
@mixin shadow-lg {
box-shadow:
- 0px 8px 16px 0px rgb(30 37 48 / 12%),
- 0px 4px 6px 0px rgb(30 37 48 / 12%);
+ 0 8px 16px 0 rgb(30 37 48 / 12%),
+ 0 4px 6px 0 rgb(30 37 48 / 12%);
}