diff --git a/dictionary-octopus.txt b/dictionary-octopus.txt
index cdcca35cbf..a94359012f 100644
--- a/dictionary-octopus.txt
+++ b/dictionary-octopus.txt
@@ -337,7 +337,6 @@ netstandard
newcert
newguid
NEWID
-newnav
Newtonsoft
nfsadmin
nlog
diff --git a/src/components/Header.astro b/src/components/Header.astro
deleted file mode 100644
index 834d8fc676..0000000000
--- a/src/components/Header.astro
+++ /dev/null
@@ -1,81 +0,0 @@
----
-import { accelerator } from '@lib/accelerator';
-import type { Frontmatter } from 'astro-accelerator-utils/types/Frontmatter';
-import { Lang } from '@util/Languages';
-import { SITE } from '@config';
-import Search from '../themes/octopus/components/Search.astro';
-import MobileMenu from './MobileMenu.astro';
-import OctopusLogo from './icons/OctopusLogo.astro';
-import ThemeSwitcher from './ThemeSwitcher.astro';
-import TopNav from './TopNav.astro';
-
-const stats = new accelerator.statistics('components/Header.astro');
-stats.start();
-
-// Properties
-type Props = {
- lang: string;
- frontmatter: Frontmatter;
- headings: { depth: number; slug: string; text: string }[];
- showSearch: boolean;
-};
-const { lang, showSearch } = Astro.props satisfies Props;
-
-// Language
-const _ = Lang(lang);
-
-stats.stop();
----
-
-
-
-
-
-
-
-
diff --git a/src/components/MobileMenu.astro b/src/components/MobileMenu.astro
deleted file mode 100644
index b01e906f37..0000000000
--- a/src/components/MobileMenu.astro
+++ /dev/null
@@ -1,26 +0,0 @@
----
-// Drawer body is populated client-side by nav-mobile.js cloning #site-nav.
-import ThemeSwitcher from './ThemeSwitcher.astro';
----
-
-
diff --git a/src/components/ThemeSwitcher.astro b/src/components/ThemeSwitcher.astro
deleted file mode 100644
index 8967e152f5..0000000000
--- a/src/components/ThemeSwitcher.astro
+++ /dev/null
@@ -1,44 +0,0 @@
----
-import SunIcon from './icons/SunIcon.astro';
-import MoonIcon from './icons/MoonIcon.astro';
-
-type Props = {
- /** Unique per instance - the label needs its own `for` target. */
- id: string;
-};
-
-const { id } = Astro.props satisfies Props;
----
-
-
-
-
-
-
-
diff --git a/src/components/TopNav.astro b/src/components/TopNav.astro
index 6b0e6b55d4..cdbc0cb022 100644
--- a/src/components/TopNav.astro
+++ b/src/components/TopNav.astro
@@ -170,6 +170,10 @@ const sectionItems: MenuItem[] = links.map(({ label, href }) => ({
);
box-sizing: border-box;
+ position: fixed;
+ inset-block-start: 0;
+ inset-inline: 0;
+ z-index: 11;
display: grid;
grid-template-columns:
minmax(max-content, var(--top-nav-content-start))
diff --git a/src/components/icons/MoonIcon.astro b/src/components/icons/MoonIcon.astro
deleted file mode 100644
index 45d26fef9d..0000000000
--- a/src/components/icons/MoonIcon.astro
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/components/icons/OctopusLogo.astro b/src/components/icons/OctopusLogo.astro
deleted file mode 100644
index c31fb459e1..0000000000
--- a/src/components/icons/OctopusLogo.astro
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
\ No newline at end of file
diff --git a/src/components/icons/SunIcon.astro b/src/components/icons/SunIcon.astro
deleted file mode 100644
index 612cbda578..0000000000
--- a/src/components/icons/SunIcon.astro
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/layouts/Api.astro b/src/layouts/Api.astro
index a62b77d0e8..5b09cd7d7b 100644
--- a/src/layouts/Api.astro
+++ b/src/layouts/Api.astro
@@ -17,7 +17,7 @@ import Taxonomy from '@components/Taxonomy.astro';
import ApiNavigation from '../components/ApiNavigation.astro';
import ArticleHeader from '../components/ArticleHeader.astro';
import Feedback from '../components/Feedback.astro';
-import Header from '../components/Header.astro';
+import TopNav from '../components/TopNav.astro';
import Plausible from 'src/components/Plausible.astro';
import Footer from 'src/components/Footer.astro';
import DocsSearch from '../components/DocsSearch.astro';
@@ -72,12 +72,7 @@ const lastUpdated = frontmatter.modDate ?? frontmatter.pubDate ?? null;
/>
-
+
diff --git a/src/layouts/Default.astro b/src/layouts/Default.astro
index 9f0fd7b565..d6f591caf0 100644
--- a/src/layouts/Default.astro
+++ b/src/layouts/Default.astro
@@ -17,7 +17,7 @@ import Taxonomy from '@components/Taxonomy.astro';
import ArticleHeader from '../components/ArticleHeader.astro';
import ArticleNav from '../components/ArticleNav.astro';
import Feedback from '../components/Feedback.astro';
-import Header from '../components/Header.astro';
+import TopNav from '../components/TopNav.astro';
import EditOnGithub from '../components/EditOnGithub.astro';
import CopyAsMarkdown from '../components/CopyAsMarkdown.astro';
import MarkdownLinks from '../components/MarkdownLinks.astro';
@@ -70,12 +70,7 @@ const lastUpdated = frontmatter.modDate ?? frontmatter.pubDate ?? null;
/>
-
+
diff --git a/src/scripts/main.js b/src/scripts/main.js
index 90584d1510..3fa6d85c28 100644
--- a/src/scripts/main.js
+++ b/src/scripts/main.js
@@ -4,8 +4,6 @@ import {
addListImageIntersectionObserver,
} from './modules/animation.js';
import { addResizedEvent } from './modules/resizing.js';
-import { addStickyNavigation } from './modules/nav-sticky.js';
-import { mobileNav } from './modules/nav-mobile.js';
import { markdownLinkMenus } from './modules/markdown-links.js';
import { setClickableBlocks } from './modules/click-blocks.js';
import { setExternalLinkAttributes } from './modules/external-links.js';
@@ -14,17 +12,11 @@ import { enableSharing } from './modules/share.js';
import { highlightCurrentHeading } from './modules/toc.js';
import { enhanceTooltips } from './modules/tooltips';
-const resizedEventName = addResizedEvent();
+addResizedEvent();
enhanceTooltips();
setClickableBlocks();
setExternalLinkAttributes();
-addStickyNavigation(
- '.site-header',
- '#site-nav',
- '#site-nav > ul',
- resizedEventName
-);
addIntersectionObserver('.anim-show-parent img, .anim-show-parent .card');
addListImageIntersectionObserver('.card img');
monitorInputType();
diff --git a/src/scripts/modules/nav-mobile.js b/src/scripts/modules/nav-mobile.js
deleted file mode 100644
index 075a521410..0000000000
--- a/src/scripts/modules/nav-mobile.js
+++ /dev/null
@@ -1,100 +0,0 @@
-// @ts-check
-import { qs, qsa } from './query.js';
-import { removeScroll, resetScroll } from './scrollbar.js';
-
-class MobileNav {
- constructor() {
- this.mobileMenuWrapper = qs('[data-mobile-menu-wrapper]');
- this.hamburgerIcon = qs('[data-hamburger-icon]');
- this.mobileMenu = qs('[data-mobile-menu]');
- this.mobileMenuList = qs('[data-mobile-menu-list]');
-
- this.populateMobileMenu();
- this.menuItems = qsa('[data-mobile-menu-list] li');
-
- // Initially hide the menu
- this.mobileMenu.style.visibility = 'hidden';
-
- this.addListeners();
- }
-
- populateMobileMenu() {
- // Idempotent on hot-reload.
- if (this.mobileMenuList.children.length > 0) return;
-
- const sourceList = document.querySelector('#site-nav .site-nav__list');
- if (!sourceList) {
- console.warn(
- '[nav-mobile] #site-nav not found; mobile drawer will be empty'
- );
- return;
- }
-
- for (const child of sourceList.children) {
- this.mobileMenuList.appendChild(child.cloneNode(true));
- }
- }
-
- toggleMobileMenu() {
- const isOpen = this.mobileMenuWrapper.classList.contains('is-active');
- if (isOpen) {
- this.closeMobileMenu();
- } else {
- this.openMobileMenu();
- }
- }
-
- openMobileMenu() {
- this.mobileMenu.style.visibility = 'visible';
- this.mobileMenuWrapper.classList.add('is-active');
- this.hamburgerIcon.setAttribute('aria-expanded', 'true');
-
- removeScroll();
- }
-
- closeMobileMenu() {
- this.mobileMenuWrapper.classList.remove('is-active');
- this.hamburgerIcon.setAttribute('aria-expanded', 'false');
-
- // Wait for the transition to complete before hiding the menu
- setTimeout(() => {
- this.mobileMenu.style.visibility = 'hidden';
- }, 500);
-
- resetScroll();
- }
-
- handleDropdownKeyboardNavigation(e) {
- if (!this.mobileMenuWrapper.classList.contains('is-active')) return;
- if (e.key === 'Escape') {
- this.closeMobileMenu();
- }
-
- if (e.key === 'Tab') {
- const firstElement = this.hamburgerIcon;
- const lastElement = this.menuItems[this.menuItems.length - 1].firstChild;
-
- if (e.shiftKey && document.activeElement === firstElement) {
- e.preventDefault();
- lastElement?.focus();
- } else if (!e.shiftKey && document.activeElement === lastElement) {
- e.preventDefault();
- firstElement.focus();
- }
- }
- }
-
- addListeners() {
- this.hamburgerIcon.addEventListener('click', (e) => {
- e.preventDefault();
- this.toggleMobileMenu();
- });
-
- document.addEventListener('keydown', (e) =>
- this.handleDropdownKeyboardNavigation(e)
- );
- }
-}
-
-const mobileNav = new MobileNav();
-export { mobileNav };
diff --git a/src/scripts/modules/nav-sticky.js b/src/scripts/modules/nav-sticky.js
deleted file mode 100644
index 564266faed..0000000000
--- a/src/scripts/modules/nav-sticky.js
+++ /dev/null
@@ -1,89 +0,0 @@
-// @ts-check
-
-import { qs } from './query.js';
-
-/**
- * Makes an existing navigation element sticky
- *
- * Example: If the existing navigation is not as tall as the content, the
- * navigation will stick to the top, allowing the user to see it as
- * they scroll through the article
- *
- * @param {string} headerSelector
- * @param {string} navigationSelector
- * @param {string} navigationListSelector
- * @param {string} resizedEventName
- */
-function addStickyNavigation(
- headerSelector,
- navigationSelector,
- navigationListSelector,
- resizedEventName
-) {
- function setNavigationMode() {
- const header = qs(headerSelector);
- const navigation = qs(navigationSelector);
- const navigationList = qs(navigationListSelector);
-
- const buffer = 50;
- const className = 'sticky';
-
- const dimensions = {
- browserHeight: window.innerHeight,
- browserWidth: window.innerWidth,
- headerHeight: header.clientHeight,
- navigationHeight: navigationList.clientHeight,
- };
-
- // Only enable sticky mode if the menu will fit vertically
- // && where the browser is more than 860px wide
- if (
- dimensions.navigationHeight <
- dimensions.browserHeight -
- Math.max(dimensions.headerHeight, site_features.stickyNav.top) -
- buffer &&
- dimensions.browserWidth > 860
- ) {
- // Navigation: Sticky Mode
-
- navigation.classList.add(className);
- const top = site_features.stickyNav.top ?? 220;
- navigation.style.top = top + 'px';
- } else {
- // Navigation: Fixed Mode
-
- navigation.classList.remove(className);
- }
- }
-
- function hideNavigation() {
- const navigation = qs(navigationSelector);
-
- // Stop hiding the nav tree once the new nav's drawer is ready
- if (document.documentElement.dataset.navDrawer === 'ready') {
- navigation.style.display = '';
- return;
- }
-
- if (window.innerWidth <= 1130) {
- navigation.style.display = 'none';
- } else {
- navigation.style.display = 'block';
- }
- }
-
- setNavigationMode();
- hideNavigation();
-
- document.addEventListener(resizedEventName, function (e) {
- if (e.detail && e.detail.change && e.detail.change.height != 0) {
- setNavigationMode();
- }
-
- if (e.detail.change.width != 0) {
- hideNavigation();
- }
- });
-}
-
-export { addStickyNavigation };
diff --git a/src/scripts/theme-switcher.ts b/src/scripts/theme-switcher.ts
index 20dbecb2f6..27aecfddae 100644
--- a/src/scripts/theme-switcher.ts
+++ b/src/scripts/theme-switcher.ts
@@ -13,8 +13,6 @@ import {
// Matches --duration-default in vars.css.
const TRANSITION_MS = 300;
-const CHECKBOX_SELECTOR = '[data-theme-toggle-checkbox]';
-
const BUTTON_SELECTOR = '[data-theme-toggle-button]';
const BUTTON_ICON_SELECTOR = '.btn__icon';
@@ -26,10 +24,6 @@ const BUTTON_ICON_CLASSES: Record = {
const root = document.documentElement;
const darkQuery = window.matchMedia(COLOR_SCHEME_QUERY);
-function checkboxes() {
- return document.querySelectorAll(CHECKBOX_SELECTOR);
-}
-
function buttons() {
return document.querySelectorAll(BUTTON_SELECTOR);
}
@@ -67,10 +61,6 @@ function currentTheme(): Theme {
}
function syncControls(theme: Theme) {
- checkboxes().forEach((box) => {
- box.checked = theme === 'dark';
- });
-
buttons().forEach((button) => {
const icon = button.querySelector(BUTTON_ICON_SELECTOR);
icon?.classList.remove(
@@ -117,25 +107,6 @@ function bind() {
// control rather than re-deriving it, so all switchers agree from paint one.
syncControls(currentTheme());
- checkboxes().forEach((box) => {
- if (box.dataset.themeBound) return;
- box.dataset.themeBound = 'true';
-
- // Covers mouse, touch, label clicks and Space.
- box.addEventListener('change', () =>
- setTheme(box.checked ? 'dark' : 'light')
- );
-
- // A checkbox ignores Enter. The switch role treats it as an optional
- // second activation key, and this control supported it before. Routed
- // through click() so the change handler stays the only writer of state.
- box.addEventListener('keydown', (event) => {
- if (event.key !== 'Enter') return;
- event.preventDefault();
- box.click();
- });
- });
-
buttons().forEach((button) => {
if (button.dataset.themeBound) return;
button.dataset.themeBound = 'true';
diff --git a/src/scripts/top-nav-drawer.ts b/src/scripts/top-nav-drawer.ts
index 64ce26ac30..1d04134e19 100644
--- a/src/scripts/top-nav-drawer.ts
+++ b/src/scripts/top-nav-drawer.ts
@@ -74,8 +74,6 @@ function placeNav(isCompact: boolean) {
if (siteNav.parentElement !== navSlot) {
navSlot.append(siteNav);
}
- // Undo nav-sticky.js hiding the tree
- siteNav.style.display = '';
} else if (siteNav.parentElement !== navHome) {
navHome.insertBefore(siteNav, navHomeNextSibling);
}
diff --git a/src/styles/main.css b/src/styles/main.css
index 659e2d3e81..8e1ee10ab6 100644
--- a/src/styles/main.css
+++ b/src/styles/main.css
@@ -715,176 +715,6 @@ nav.skip-links a:focus {
width: auto;
}
-/* Site Header */
-
-.octo-header-bkg {
- box-shadow: 0 5px 30px rgba(0, 0, 0, 0.2);
- background-color: var(--header-bg);
- min-height: var(--header-height);
- position: fixed;
- width: 100%;
- top: 0;
- /* z-index due to conflict with octo-title-bkg */
- z-index: 11;
- background-color: var(--color-base-primary);
- transition: background-color var(--duration-default) ease-in-out;
-
- @media (prefers-reduced-motion: reduce) {
- transition: none;
- }
-}
-
-.octo-header {
- margin-inline: var(--page-inline-margin);
- font-size: var(--fontSizeBase);
- z-index: 10;
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 1rem 0;
-}
-
-@media (max-width: 1130px) {
- .octo-header {
- gap: 0.5rem;
- }
-}
-
-.octo-header .logo {
- max-height: 45px;
-}
-
-.octo-header__logo {
- height: 50px;
- width: auto;
-}
-
-.octo-header > a.navigation-icon {
- display: none;
- text-align: end;
- stroke: var(--header-link-alt);
- width: 40px;
- height: 40px;
-}
-
-@media (max-width: 1130px) {
- .octo-header {
- grid-template-columns: auto 40px;
- }
-
- .octo-header > nav,
- .octo-header > a.button--primary {
- display: none;
- }
-
- .octo-header > a.navigation-icon {
- display: inline-block;
- }
-}
-
-.octo-header__wrapper--left {
- display: flex;
- align-items: center;
- flex-wrap: nowrap;
- column-gap: 0.5rem;
-}
-
-/* Hide badge due to not enough space */
-@media (max-width: 360px) {
- .octo-header__wrapper--left .badge {
- display: none;
- }
-}
-
-/* Badge */
-.badge {
- display: flex;
- justify-content: center;
- align-items: center;
- padding: 0.5rem 0.75rem;
- gap: 0.75rem;
- border-radius: 0.5rem;
- font-size: var(--fontSizeMedium);
- font-weight: var(--fontWeight600);
- line-height: 138%;
- transition-property: background-color, color;
- transition-timing-function: ease-in-out;
- transition-duration: var(--duration-default);
-
- @media (prefers-reduced-motion: reduce) {
- transition-property: none;
- }
-}
-
-.badge--brand {
- color: var(--badge-color);
- background-color: var(--badge-background);
-}
-
-/* Theme switcher */
-
-.theme-switcher {
- position: relative;
- display: inline-block;
- width: 11.1875rem;
- height: 2.5rem;
- margin-inline-start: 1rem;
-}
-
-/* Hide theme switcher in header on mobile */
-@media screen and (max-width: 1130px) {
- .octo-header .octo-header__wrapper--left > .theme-switcher {
- display: none;
- }
-}
-
-.site-nav__mobile > .theme-switcher {
- display: block;
- margin: 1rem auto;
-}
-
-.theme-switcher input {
- opacity: 0;
- width: 0;
- height: 0;
- position: absolute;
-}
-
-.theme-switcher__label {
- display: flex;
- align-items: center;
- justify-content: space-around;
- color: var(--white);
- cursor: pointer;
- width: 100%;
- height: 100%;
- background-color: var(--header-bg);
- border: 0.0625rem solid var(--theme-switcher-border);
- border-radius: 1.75rem;
- position: relative;
- transition: background-color var(--duration-default) ease-in-out;
-}
-
-.switch-slider {
- --toggle-sides-offset: 0.375rem;
- position: absolute;
- width: calc((100% - var(--toggle-sides-offset)) / 2);
- height: calc(100% - var(--toggle-sides-offset));
- left: calc(var(--toggle-sides-offset) / 2);
- background-color: var(--blue-500);
- border-radius: 3.375rem;
- transition: transform var(--duration-default) ease-in-out;
-}
-
-.theme-switcher__icon {
- font-size: var(--fontSizeMedium);
- font-weight: var(--fontWeight700);
- display: flex;
- align-items: center;
- gap: 0.25rem;
- z-index: 2;
-}
-
.theme-switcher__moon_icon {
background-color: var(--colorIconPrimary);
mask: url('../assets/icons/moon.svg') center / contain no-repeat;
@@ -895,40 +725,6 @@ nav.skip-links a:focus {
mask: url('../assets/icons/sun.svg') center / contain no-repeat;
}
-html[data-theme='dark'] .theme-switcher .switch-slider {
- transform: translateX(100%);
-}
-
-html[data-theme='dark'] .theme-switcher__icon--light {
- color: #7c98b4;
-}
-
-html[data-theme='dark'] .theme-switcher__icon--light svg path {
- fill: #7c98b4;
-}
-
-html[data-theme='light'] .theme-switcher__icon--dark {
- color: #557999;
-}
-
-html[data-theme='light'] .theme-switcher__icon--dark svg path {
- fill: #557999;
-}
-
-/* The input is visually hidden but still the focusable control, so the ring
- has to be drawn on the label. */
-.theme-switcher input:focus-visible + .theme-switcher__label {
- outline: 0.125rem solid var(--octo-blue);
- outline-offset: 0.125rem;
-}
-
-.theme-switcher input:disabled + .theme-switcher__label {
- opacity: 0.5;
- cursor: not-allowed;
-}
-
-/* */
-
.docs-home {
text-align: center;
margin-block-start: 5vh;
@@ -1425,81 +1221,6 @@ html[data-theme='dark'] img.card__icon {
}
}
-.mobile-menu {
- display: none;
-}
-
-@media (max-width: 1130px) {
- .mobile-menu {
- display: flex;
- justify-content: center;
- align-items: center;
- width: var(--navbar-icon-size);
- height: var(--navbar-icon-size);
- }
-}
-.site-nav__mobile {
- position: absolute;
- width: 100%;
- right: -100%;
- transition: right 500ms ease-in-out;
- margin: 0;
- top: 5.125rem;
-}
-
-.mobile-menu.is-active .site-nav__mobile {
- right: 0;
-}
-
-/* Burger menu */
-.hamburger {
- position: relative;
-}
-
-.hamburger:hover {
- cursor: pointer;
-}
-
-.hamburger .line {
- width: var(--hamburger-line-width);
- height: var(--hamburger-line-height);
- background-color: var(--hamburger-lines-color);
- display: block;
- margin: var(--hamburger-line-margin) auto;
- transition-property: opacity, transform;
- transition-duration: 500ms;
- border-radius: 0.1rem;
-}
-.hamburger .circle {
- display: block;
- width: var(--navbar-icon-size);
- height: var(--navbar-icon-size);
- border: solid #76a1c2;
- border-radius: 50%;
- border-width: 0;
- background-color: transparent;
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- opacity: 0;
- transition-property: opacity, border-width;
- transition-duration: 500ms;
-}
-.mobile-menu.is-active .hamburger .line:nth-child(1) {
- transform: translateY(var(--hamburger-translate-y)) rotate(45deg);
-}
-.mobile-menu.is-active .hamburger .line:nth-child(2) {
- opacity: 0;
-}
-.mobile-menu.is-active .hamburger .line:nth-child(3) {
- transform: translateY(calc(-1 * var(--hamburger-translate-y))) rotate(-45deg);
-}
-.mobile-menu.is-active .hamburger .circle {
- opacity: 1;
- border-width: 0.0625rem;
-}
-
/* Main content group */
/* The footer gets its own row so the nav can span both. The design runs the
@@ -2185,14 +1906,6 @@ a[data-youtube] {
}
}
-@media screen and (max-width: 1130px) {
- .octo-header .site-search-results,
- .octo-header .site-search__overlay,
- .octo-header .site-search.is-active {
- display: none;
- }
-}
-
.site-search {
height: var(--search-height);
border-radius: var(--search-border-radius);
@@ -2432,27 +2145,6 @@ html:has(.site-search__wrapper.is-active) {
display: none;
}
-@media (max-width: 1130px) {
- .site-header .site-search__wrapper {
- max-width: fit-content;
- order: -1;
- }
-
- .site-header .site-search {
- display: none;
- }
-
- .site-header .site-search__mobile {
- display: flex;
- width: var(--navbar-icon-size);
- height: var(--navbar-icon-size);
- border-radius: calc(var(--navbar-icon-size) / 2);
- justify-content: center;
- align-items: center;
- border: var(--search-border);
- }
-}
-
.site-search .show-more {
display: inline-block;
font-size: var(--fontSizeMedium);
@@ -2936,10 +2628,6 @@ a.button.button--primary:active {
box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.35) inset;
}
-.octo-header a.button {
- width: 120px;
-}
-
/* Tooltip. Put the label in data-tooltip; the host positions the bubble above
itself, so it needs room there and a stacking context of its own. */
[data-tooltip] {
@@ -3074,26 +2762,6 @@ a.button.button--primary:active {
}
/* TopNav component */
-.new-top-nav {
- display: none;
-}
-
-html[data-nav='new'] {
- --header-height: 68px;
-}
-
-html[data-nav='new'] .new-top-nav {
- display: block;
- position: fixed;
- width: 100%;
- top: 0;
- z-index: 11;
-}
-
-html[data-nav='new'] .site-header {
- display: none;
-}
-
.top-nav__bars-icon,
.top-nav__close-icon {
background-color: var(--colorIconPrimary);
@@ -3105,13 +2773,11 @@ html[data-nav='new'] .site-header {
}
@media (max-width: 1130px) {
- html[data-nav='new'][data-nav-drawer='ready'] .content-group .site-nav {
+ html[data-nav-drawer='ready'] .content-group .site-nav {
display: none;
}
- html[data-nav='new'][data-nav-drawer='ready']
- .skip-links
- a[href='#site-nav'] {
+ html[data-nav-drawer='ready'] .skip-links a[href='#site-nav'] {
display: none;
}
}
diff --git a/src/styles/vars.css b/src/styles/vars.css
index e566ac3607..c56e23d592 100644
--- a/src/styles/vars.css
+++ b/src/styles/vars.css
@@ -163,23 +163,8 @@
--search-placeholder-color: #173b56;
--search-remove-icon-color: #355670;
--search-overlay: rgba(12, 26, 36, 0.3);
- --navbar-icon-size: 3rem;
-
- /* Hamburger menu */
- --hamburger-line-width: 1.5rem;
- --hamburger-line-height: 0.2rem;
- --hamburger-line-margin: 0.2rem;
- --hamburger-translate-y: calc(
- var(--hamburger-line-height) + var(--hamburger-line-margin)
- );
- --hamburger-lines-color: var(--colorIconPrimary);
- /* Theme Switcher */
- --theme-switcher-border: var(--colorBorderPrimary);
-
- /* Badge */
- --badge-background: rgba(162, 209, 244, 0.2);
- --badge-color: #0d80d8;
+ --hamburger-lines-color: var(--colorIconPrimary);
/* Card */
--card-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.15);
@@ -193,9 +178,7 @@
--octo-blue-lighter: #2f95e3ff;
--octo-blue-lightest: #1fc0ffff;
- --header-bg: var(--colorBackgroundPrimaryDefault);
--header-link-color: var(--octo-blue);
- --header-link-alt: var(--blue-gray-darker);
--content-bg: var(--white);
@@ -211,7 +194,7 @@
--block-gap: 2rem;
--header-pin: 0;
- --header-height: 82px;
+ --header-height: 68px;
--scroll-pad: 140px;
--box-shadow: 4px 0px 8px rgba(0, 0, 0, 0.25);
@@ -304,12 +287,9 @@ html[data-theme='dark'] {
/* TODO: --blue-grey is hand-themed for .card__description, which is
secondary text, so --color-text-secondary already covers it. */
--blue-grey: #dae2e9ff;
- --header-link-alt: var(--color-text);
--grey-light: var(--navy-700);
--octopus-logo-text-color: var(--white);
--search-overlay: rgba(12, 26, 36, 0.8);
- --badge-background: rgba(31, 192, 255, 0.1);
- --badge-color: var(--octo-blue-lightest);
/* Tiles sit one step above the page so hover has somewhere lighter to go */
--icon-tile-background-hover: var(--colorBackgroundTertiary);
diff --git a/tests/profile-menu.spec.ts b/tests/profile-menu.spec.ts
index e5612c743f..8c377fb616 100644
--- a/tests/profile-menu.spec.ts
+++ b/tests/profile-menu.spec.ts
@@ -1,6 +1,6 @@
import { test, expect, type Page } from '@playwright/test';
-const docsPage = '/docs/?newnav';
+const docsPage = '/docs/';
// Match the full width avatar menu; the inline one used when the page narrows is tested in
// topnav-responsive.spec.ts
diff --git a/tests/theme.spec.ts b/tests/theme.spec.ts
index 92a30c2e87..273a78caf6 100644
--- a/tests/theme.spec.ts
+++ b/tests/theme.spec.ts
@@ -3,10 +3,9 @@ import { test, expect, type Page } from '@playwright/test';
const home = '/docs/';
const otherPage = '/docs/getting-started/';
-const headerInput = '#theme-switcher';
-const headerLabel = 'label[for="theme-switcher"]';
-const mobileInput = '#theme-switcher-mobile';
-const slider = '#theme-switcher ~ .theme-switcher__label .switch-slider';
+const toggle = '.top-nav__trailing [data-theme-toggle-button]';
+const toggleIcon = `${toggle} .btn__icon`;
+const drawerToggleIcon = '.top-nav__drawer-theme .btn__icon';
// Auto-retrying so a slow style/attribute write can never make these flaky.
function expectTheme(page: Page, value: string) {
@@ -20,8 +19,10 @@ function expectPreference(page: Page, value: string) {
);
}
-function sliderTransform(page: Page) {
- return page.locator(slider).evaluate((el) => getComputedStyle(el).transform);
+function expectToggleOffers(page: Page, theme: string) {
+ return expect(page.locator(toggleIcon)).toHaveClass(
+ new RegExp(`theme-switcher__${theme === 'dark' ? 'moon' : 'sun'}_icon`)
+ );
}
test.describe('theme', () => {
@@ -33,21 +34,21 @@ test.describe('theme', () => {
await expectTheme(page, 'dark');
await expectPreference(page, 'system');
- await expect(page.locator(headerInput)).toBeChecked();
+ await expectToggleOffers(page, 'light');
});
test('an explicit choice wins and survives navigation', async ({
page,
}) => {
await page.goto(home);
- await page.locator(headerLabel).click();
+ await page.locator(toggle).click();
await expectTheme(page, 'light');
await expectPreference(page, 'light');
await page.goto(otherPage);
await expectTheme(page, 'light');
- await expect(page.locator(headerInput)).not.toBeChecked();
+ await expectToggleOffers(page, 'dark');
});
test('falls back to the OS when storage throws', async ({ page }) => {
@@ -63,7 +64,7 @@ test.describe('theme', () => {
await expectTheme(page, 'dark');
// Still usable for the life of the page, just not persisted.
- await page.locator(headerLabel).click();
+ await page.locator(toggle).click();
await expectTheme(page, 'light');
});
});
@@ -75,38 +76,20 @@ test.describe('theme', () => {
await page.goto(home);
await expectTheme(page, 'light');
- await expect(page.locator(headerInput)).not.toBeChecked();
+ await expectToggleOffers(page, 'dark');
});
- test('both switchers stay in sync', async ({ page }) => {
+ test('every switcher on the page stays in sync', async ({ page }) => {
await page.goto(home);
- await page.locator(headerLabel).click();
+ await page.locator(toggle).click();
await expectTheme(page, 'dark');
- await expect(page.locator(headerInput)).toBeChecked();
- await expect(page.locator(mobileInput)).toBeChecked();
-
- await page.locator(headerLabel).click();
- await expectTheme(page, 'light');
- await expect(page.locator(mobileInput)).not.toBeChecked();
+ await expectToggleOffers(page, 'light');
+ // The drawer's toggle is the one used when the page narrows.
+ await expect(page.locator(drawerToggleIcon)).toHaveClass(
+ /theme-switcher__sun_icon/
+ );
});
-
- // Space is the native checkbox key; Enter is optional for role="switch"
- // but the control supported it before, so both have to keep working.
- for (const key of ['Space', 'Enter']) {
- test(`is operable with ${key}`, async ({ page }) => {
- await page.goto(home);
- await page.locator(headerInput).focus();
-
- await page.keyboard.press(key);
- await expectTheme(page, 'dark');
- await expect(page.locator(headerInput)).toBeChecked();
-
- await page.keyboard.press(key);
- await expectTheme(page, 'light');
- await expect(page.locator(headerInput)).not.toBeChecked();
- });
- }
});
// The design token stylesheets define their custom properties only under
@@ -124,24 +107,4 @@ test.describe('theme', () => {
await expectTheme(page, 'light');
});
});
-
- // Regression guard: the knob used to be driven by a JS-applied class, so it
- // painted on the light side and slid across after hydration. Driving it from
- // data-theme means the attribute alone decides the position.
- test('the knob position is driven by data-theme, not by script', async ({
- page,
- }) => {
- await page.goto(home);
-
- // Polled because the slider transitions between the two positions.
- await page.evaluate(() =>
- document.documentElement.setAttribute('data-theme', 'dark')
- );
- await expect.poll(() => sliderTransform(page)).not.toBe('none');
-
- await page.evaluate(() =>
- document.documentElement.setAttribute('data-theme', 'light')
- );
- await expect.poll(() => sliderTransform(page)).toBe('none');
- });
});
diff --git a/tests/topnav-responsive.spec.ts b/tests/topnav-responsive.spec.ts
index 353d434eb4..1d087f4e3f 100644
--- a/tests/topnav-responsive.spec.ts
+++ b/tests/topnav-responsive.spec.ts
@@ -1,7 +1,7 @@
import { test, expect, type Page } from '@playwright/test';
-const docsPage = '/docs/?newnav';
-const sectionPage = '/docs/getting-started/?newnav';
+const docsPage = '/docs/';
+const sectionPage = '/docs/getting-started/';
const nav = '.top-nav';
const inlineLinks = `${nav} .top-nav__links`;
diff --git a/tests/topnav-signedin.spec.ts b/tests/topnav-signedin.spec.ts
index 22c9ed2263..88c9422b04 100644
--- a/tests/topnav-signedin.spec.ts
+++ b/tests/topnav-signedin.spec.ts
@@ -1,6 +1,6 @@
import { test, expect, type Page } from '@playwright/test';
-const docsPage = '/docs/?newnav';
+const docsPage = '/docs/';
const nav = '.top-nav';
const trailing = `${nav} .top-nav__trailing`;