diff --git a/docs/app/page.tsx b/docs/app/page.tsx index 3d35bb81be..a87007d0cc 100644 --- a/docs/app/page.tsx +++ b/docs/app/page.tsx @@ -16,47 +16,49 @@ export default async function HomePage() { {/* Left side — Hero title */}
- {/* 3D Logo */} + {/* 3D Logo: WebPs are rendered from the original SVGs at 2x their + display size with the grain baked in, so they're `unoptimized` to + keep next/image from resampling the grain away. */}
{/* Dark mode logos */}
{/* Light mode logos */}
diff --git a/docs/assets/GeistPixel-Square.woff2 b/docs/assets/GeistPixel-Square.woff2 new file mode 100644 index 0000000000..02cd121c51 Binary files /dev/null and b/docs/assets/GeistPixel-Square.woff2 differ diff --git a/docs/components/landing/hero-readme.tsx b/docs/components/landing/hero-readme.tsx index 883029f79e..7f7fc6ee2d 100644 --- a/docs/components/landing/hero-readme.tsx +++ b/docs/components/landing/hero-readme.tsx @@ -704,6 +704,29 @@ function ContributorsSection({ contributors: ContributorInfo[]; contributorCount: number; }) { + const wallRef = useRef(null); + const [wallNearViewport, setWallNearViewport] = useState(false); + + // Hundreds of avatars scroll through the wall; the links always render, + // but the avatar images are only mounted once the wall is close to the + // viewport instead of relying on the browser's generous native + // lazy-loading distance. + useEffect(() => { + const wall = wallRef.current; + if (!wall) return; + const observer = new IntersectionObserver( + ([entry]) => { + if (entry.isIntersecting) { + setWallNearViewport(true); + observer.disconnect(); + } + }, + { rootMargin: "200px" }, + ); + observer.observe(wall); + return () => observer.disconnect(); + }, []); + if (contributors.length === 0) return null; const colCount = 18; @@ -735,6 +758,7 @@ function ContributorsSection({ {contributors.length > 0 && (
- {c.login} + {wallNearViewport ? ( + {c.login} + ) : ( + + )}
{c.login}
@@ -1017,23 +1046,25 @@ function DemoVideo() { return (
+ {/* The poster is a CSS background rather than the `poster` attribute: + hidden
); diff --git a/docs/lib/fonts.ts b/docs/lib/fonts.ts index 6a7ce7a705..ce1c6950e4 100644 --- a/docs/lib/fonts.ts +++ b/docs/lib/fonts.ts @@ -1,5 +1,5 @@ -import { GeistPixelSquare } from "geist/font/pixel"; import { Geist, Geist_Mono } from "next/font/google"; +import localFont from "next/font/local"; import { cn } from "@/lib/utils"; const fontSans = Geist({ @@ -12,6 +12,16 @@ const fontMono = Geist_Mono({ variable: "--font-geist-mono", }); +// Only the Square variant is used. Importing from `geist/font/pixel` would +// declare (and preload) all five Geist Pixel fonts on every page. +const GeistPixelSquare = localFont({ + src: "../assets/GeistPixel-Square.woff2", + variable: "--font-geist-pixel-square", + weight: "500", + fallback: ["Geist Mono", "ui-monospace", "monospace"], + adjustFontFallback: false, +}); + export const fontVariables = cn( fontSans.variable, fontMono.variable, diff --git a/docs/package.json b/docs/package.json index ee252c81d7..73ac705e52 100644 --- a/docs/package.json +++ b/docs/package.json @@ -73,7 +73,6 @@ "fumadocs-mdx": "^15.0.12", "fumadocs-typescript": "^5.2.6", "fumadocs-ui": "16.12.0", - "geist": "^1.7.2", "gray-matter": "^4.0.3", "hast-util-to-jsx-runtime": "^2.3.6", "input-otp": "^1.4.2", diff --git a/docs/public/left-3d-logo-light.svg b/docs/public/left-3d-logo-light.svg deleted file mode 100644 index f257b02ada..0000000000 --- a/docs/public/left-3d-logo-light.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/public/left-3d-logo-light.webp b/docs/public/left-3d-logo-light.webp new file mode 100644 index 0000000000..047c7d8a3f Binary files /dev/null and b/docs/public/left-3d-logo-light.webp differ diff --git a/docs/public/left-3d-logo.svg b/docs/public/left-3d-logo.svg deleted file mode 100644 index 8b260df5e7..0000000000 --- a/docs/public/left-3d-logo.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/public/left-3d-logo.webp b/docs/public/left-3d-logo.webp new file mode 100644 index 0000000000..a9c7693bbb Binary files /dev/null and b/docs/public/left-3d-logo.webp differ diff --git a/docs/public/right-3d-logo-light.svg b/docs/public/right-3d-logo-light.svg deleted file mode 100644 index 16360c6f39..0000000000 --- a/docs/public/right-3d-logo-light.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/public/right-3d-logo-light.webp b/docs/public/right-3d-logo-light.webp new file mode 100644 index 0000000000..a7dac5ff9b Binary files /dev/null and b/docs/public/right-3d-logo-light.webp differ diff --git a/docs/public/right-3d-logo.svg b/docs/public/right-3d-logo.svg deleted file mode 100644 index 008dff0c6d..0000000000 --- a/docs/public/right-3d-logo.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/public/right-3d-logo.webp b/docs/public/right-3d-logo.webp new file mode 100644 index 0000000000..f47f7bd523 Binary files /dev/null and b/docs/public/right-3d-logo.webp differ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f91d4fe02b..f831036824 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -338,9 +338,6 @@ importers: fumadocs-ui: specifier: 16.12.0 version: 16.12.0(@types/mdx@2.0.14)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(fumadocs-core@16.12.0(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.17)(lucide-react@1.21.0(react@19.2.7))(next@16.3.4(@babel/core@8.0.1)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(@types/node@25.9.4)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(zod@4.5.4))(next@16.3.4(@babel/core@8.0.1)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(@types/node@25.9.4)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(tailwindcss@4.3.1) - geist: - specifier: ^1.7.2 - version: 1.7.2(next@16.3.4(@babel/core@8.0.1)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(@types/node@25.9.4)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)) gray-matter: specifier: ^4.0.3 version: 4.0.3 @@ -10448,11 +10445,6 @@ packages: fzf@0.5.2: resolution: {integrity: sha512-Tt4kuxLXFKHy8KT40zwsUPUkg1CrsgY25FxA2U/j/0WgEDCk3ddc/zLTCCcbSHX9FcKtLuVaDGtGE/STWC+j3Q==} - geist@1.7.2: - resolution: {integrity: sha512-Gu5lDFa3pLRyoBlBPf0QIFHVdWAnpco7fS1bJm41jyLPFoguBgiubseUN2oLXMgqZ7uxAxDoXcHMhCY/fOTTgg==} - peerDependencies: - next: '>=13.2.0' - generate-function@2.3.1: resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} @@ -26710,10 +26702,6 @@ snapshots: fzf@0.5.2: {} - geist@1.7.2(next@16.3.4(@babel/core@8.0.1)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(@types/node@25.9.4)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)): - dependencies: - next: 16.3.4(@babel/core@8.0.1)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(@types/node@25.9.4)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - generate-function@2.3.1: dependencies: is-property: 1.0.2