.button+.button]:-ml-2 z-20 ml-auto flex min-w-9 shrink grow items-center justify-end gap-x-4 lg:gap-x-6 xl:grow-0',
+ '@4xl:[&>.button+.button]:-ml-2 z-20 ml-auto flex min-w-9 shrink grow @7xl:grow-0 items-center justify-end @4xl:gap-x-6 gap-x-4',
style
)}
>
diff --git a/packages/gitbook/src/components/Header/headerLinks.module.css b/packages/gitbook/src/components/Header/headerLinks.module.css
index 2a5736b43e..8384648e3b 100644
--- a/packages/gitbook/src/components/Header/headerLinks.module.css
+++ b/packages/gitbook/src/components/Header/headerLinks.module.css
@@ -1,4 +1,4 @@
-@media (max-width: 1279px) {
+@container header (width < 1280px) {
.containerHeaderlinks {
container-type: inline-size;
container-name: headerlinks;
diff --git a/packages/gitbook/src/components/PageAside/PageAside.tsx b/packages/gitbook/src/components/PageAside/PageAside.tsx
index 6b14991f94..5bf96aeaf4 100644
--- a/packages/gitbook/src/components/PageAside/PageAside.tsx
+++ b/packages/gitbook/src/components/PageAside/PageAside.tsx
@@ -37,24 +37,32 @@ export function PageAside(props: {
'group/aside',
'order-last',
'hidden',
+ 'max-w-0',
'pt-8',
'pb-4',
+ 'opacity-0',
'xl:flex',
- 'xl:max-3xl:chat-open:hidden',
- 'xl:max-3xl:chat-open:opacity-0',
- 'max-w-56',
- // Animate the width of the aside when the chat is open
- 'xl:max-3xl:*:chat-open:w-56',
+ 'overflow-hidden',
+
+ 'xl:max-w-56',
+ 'xl:opacity-11',
+ 'xl:ml-12',
+
+ 'xl:max-3xl:chat-open:hidden',
'xl:max-3xl:chat-open:max-w-0',
+ 'xl:max-3xl:chat-open:opacity-0',
'xl:max-3xl:chat-open:ml-0',
- 'motion-safe:xl:transition-[width,max-width,margin,opacity,display] motion-safe:xl:duration-300',
- 'motion-safe:transition-discrete',
+ 'hydrated:starting:ml-0',
+ 'hydrated:starting:max-w-0',
+ 'hydrated:starting:opacity-0',
+
+ 'transition-[margin,max-width,opacity,display] duration-300',
+ 'transition-discrete',
'basis-56',
- 'xl:ml-12',
'grow-0',
'shrink-0',
'break-anywhere', // To prevent long words in headings from breaking the layout
@@ -93,6 +101,7 @@ export function PageAside(props: {
(
variantClasses.header,
sizeClasses,
// Additional custom styles
- 'has-[input:focus]:-translate-y-px h-9 grow cursor-pointer px-2.5 has-[input:focus]:bg-tint-base has-[input:focus]:depth-subtle:shadow-lg has-[input:focus]:depth-subtle:shadow-primary-subtle has-[input:focus-visible]:ring-2 has-[input:focus-visible]:ring-primary-hover md:cursor-text',
+ 'has-[input:focus]:-translate-y-px h-9 grow @2xl:cursor-text cursor-pointer px-2.5 has-[input:focus]:bg-tint-base has-[input:focus]:depth-subtle:shadow-lg has-[input:focus]:depth-subtle:shadow-primary-subtle has-[input:focus-visible]:ring-2 has-[input:focus-visible]:ring-primary-hover',
'theme-bold:border-header-link/3 has-[input:focus-visible]:theme-bold:border-header-link/5 has-[input:focus-visible]:theme-bold:bg-header-link/3 has-[input:focus-visible]:theme-bold:ring-header-link/5',
'theme-bold:before:absolute theme-bold:before:inset-0 theme-bold:before:bg-header-background/7 theme-bold:before:backdrop-blur-xl ', // Special overlay to make the transparent colors of theme-bold visible.
- 'relative z-30 max-w-none shrink grow justify-start max-md:absolute max-md:right-0',
- isOpen ? 'max-md:w-56' : 'max-md:w-[38px]'
+ '@max-2xl:absolute relative @max-2xl:right-0 z-30 max-w-none shrink grow justify-start',
+ isOpen ? '@max-2xl:w-56' : '@max-2xl:w-[38px]'
)}
>
{value && isOpen ? (
@@ -111,7 +111,7 @@ export const SearchInput = React.forwardRef
(
data-testid="search-input"
className={tcls(
'peer z-10 min-w-0 grow bg-transparent py-0.5 text-tint-strong theme-bold:text-header-link outline-hidden transition-[width] duration-300 contain-paint placeholder:text-tint theme-bold:placeholder:text-current theme-bold:placeholder:opacity-7',
- isOpen ? '' : 'max-md:opacity-0'
+ isOpen ? '' : '@max-2xl:opacity-0'
)}
role="combobox"
autoComplete="off"
diff --git a/packages/gitbook/src/components/SpaceLayout/SpaceLayout.tsx b/packages/gitbook/src/components/SpaceLayout/SpaceLayout.tsx
index 48f0d66f0d..aa963284da 100644
--- a/packages/gitbook/src/components/SpaceLayout/SpaceLayout.tsx
+++ b/packages/gitbook/src/components/SpaceLayout/SpaceLayout.tsx
@@ -129,7 +129,8 @@ export function SpaceLayout(props: SpaceLayoutProps) {
'lg:flex-row',
'lg:justify-center',
CONTAINER_STYLE,
- 'site-width-wide:max-w-full',
+ 'site-width-wide:max-w-screen-4xl',
+ 'hydrated:transition-[max-width] duration-300',
// Ensure the footer is display below the viewport even if the content is not enough
withFooter && [
diff --git a/packages/gitbook/src/components/primitives/KeyboardShortcut.tsx b/packages/gitbook/src/components/primitives/KeyboardShortcut.tsx
index 891fc5efd9..49705139ac 100644
--- a/packages/gitbook/src/components/primitives/KeyboardShortcut.tsx
+++ b/packages/gitbook/src/components/primitives/KeyboardShortcut.tsx
@@ -28,7 +28,7 @@ export function KeyboardShortcut(props: { keys: string[]; className?: ClassValue
className={tcls(
'shortcut hidden justify-end gap-0.5 whitespace-nowrap text-tint text-xs [font-feature-settings:"calt","case"] contrast-more:text-tint-strong md:flex',
operatingSystem
- ? 'motion-safe:animate-fade-in motion-reduce:opacity-100'
+ ? 'motion-safe:animate-fade-in motion-reduce:opacity-11'
: 'opacity-0'
)}
>
diff --git a/packages/gitbook/src/components/primitives/NavigationLoader.tsx b/packages/gitbook/src/components/primitives/NavigationLoader.tsx
index 1ce47ad164..76c63f880f 100644
--- a/packages/gitbook/src/components/primitives/NavigationLoader.tsx
+++ b/packages/gitbook/src/components/primitives/NavigationLoader.tsx
@@ -1,9 +1,31 @@
'use client';
import { tcls } from '@/lib/tailwind';
+import { usePathname } from 'next/navigation';
+import { useEffect, useLayoutEffect } from 'react';
import { useIsNavigating } from '../hooks';
export const NavigationLoader = () => {
const isNavigating = useIsNavigating();
+ const pathname = usePathname();
+
+ // Mark client hydration so initial paint doesn't animate.
+ useEffect(() => {
+ document.documentElement.classList.add('hydrated');
+ }, []);
+
+ // On route changes, add a transient class for the first paint of the new page.
+ useLayoutEffect(() => {
+ void pathname;
+ const root = document.documentElement;
+ root.classList.add('route-change');
+ const raf1 = requestAnimationFrame(() => {
+ const raf2 = requestAnimationFrame(() => {
+ root.classList.remove('route-change');
+ });
+ return () => cancelAnimationFrame(raf2);
+ });
+ return () => cancelAnimationFrame(raf1);
+ }, [pathname]);
return (
&:first-of-type'); // optional for group-based variants