diff --git a/docs-site/astro.config.mjs b/docs-site/astro.config.mjs index f69d696cf28..2423554b630 100644 --- a/docs-site/astro.config.mjs +++ b/docs-site/astro.config.mjs @@ -27,15 +27,17 @@ export default defineConfig({ "Universal provider proxy for OpenAI Codex & Claude Code — use any LLM with Codex CLI, App, SDK, and Claude Code.", tagline: "Use any LLM with OpenAI Codex and Claude Code.", logo: { - light: "./src/assets/logo-light.png", - dark: "./src/assets/logo-dark.png", + light: "./src/assets/logo-light.svg", + dark: "./src/assets/logo-dark.svg", replacesTitle: false, }, favicon: "/favicon.ico", customCss: [ "@fontsource-variable/geist", - "pretendard/dist/web/variable/pretendardvariable-dynamic-subset.css", + "@fontsource-variable/geist-mono", + "wanted-sans/fonts/webfonts/variable/split/WantedSansVariable.css", "./src/styles/custom.css", + "./src/styles/site-theme.css", ], components: { Header: "./src/components/Header.astro", @@ -44,6 +46,10 @@ export default defineConfig({ head: [ // Google favicon guidelines: PNG at a multiple of 48px, exposed via rel="icon". { tag: "link", attrs: { rel: "icon", type: "image/png", sizes: "192x192", href: "/favicon.png" } }, + // The vector mark recolours itself for dark browser chrome; browsers that + // understand SVG icons prefer it over the generated ICO/PNG (scripts/brand-favicons.ts). + { tag: "link", attrs: { rel: "icon", type: "image/svg+xml", href: "/favicon.svg" } }, + { tag: "link", attrs: { rel: "apple-touch-icon", href: "/favicon.png" } }, { tag: "meta", attrs: { property: "og:image", content: `${SITE_URL}/og.png` } }, { tag: "meta", attrs: { property: "og:image:width", content: "1200" } }, { tag: "meta", attrs: { property: "og:image:height", content: "630" } }, diff --git a/docs-site/bun.lock b/docs-site/bun.lock index 092f7d2349d..954219debae 100644 --- a/docs-site/bun.lock +++ b/docs-site/bun.lock @@ -7,11 +7,13 @@ "dependencies": { "@astrojs/starlight": "^0.41.7", "@fontsource-variable/geist": "^5.3.0", + "@fontsource-variable/geist-mono": "5.3.0", "astro": "^7.3.3", "echarts": "^6.1.0", "pretendard": "^1.3.9", "sharp": "^0.35.4", "simple-icons": "^16.28.0", + "wanted-sans": "1.0.3", }, }, }, @@ -165,6 +167,8 @@ "@fontsource-variable/geist": ["@fontsource-variable/geist@5.3.0", "", {}, "sha512-j0m+vLQuG5XAYoHtGCVu0spvlGreR3EzpECUVzkFmI1mTVnAO38l/NEPDCFgZ177JxzYJCLSmTQibIiYPilGrA=="], + "@fontsource-variable/geist-mono": ["@fontsource-variable/geist-mono@5.3.0", "", {}, "sha512-vBbuwDEo9AkrqADMXOrlAR3DFcJi4/JxeuU43FoiQERnNwsfXNnvxvReZG02cQKmyk4DZkZdBZX3oTDvy2zBAw=="], + "@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="], "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.3.3" }, "os": "darwin", "cpu": "arm64" }, "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA=="], @@ -927,6 +931,8 @@ "vitefu": ["vitefu@1.1.3", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["vite"] }, "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg=="], + "wanted-sans": ["wanted-sans@1.0.3", "", {}, "sha512-YU+mQRJMc97zMGFmxFjOvjdrF5Hi2zagc69bNP9n//i77Dlf9AWGfziZWYKdhQzPK5tw+e0iHcjLrZXDatxRTQ=="], + "web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="], "xxhash-wasm": ["xxhash-wasm@1.1.0", "", {}, "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA=="], diff --git a/docs-site/package.json b/docs-site/package.json index 2c1f923c83d..59cdbdd766e 100644 --- a/docs-site/package.json +++ b/docs-site/package.json @@ -13,11 +13,13 @@ "dependencies": { "@astrojs/starlight": "^0.41.7", "@fontsource-variable/geist": "^5.3.0", + "@fontsource-variable/geist-mono": "5.3.0", "astro": "^7.3.3", "echarts": "^6.1.0", "pretendard": "^1.3.9", "sharp": "^0.35.4", - "simple-icons": "^16.28.0" + "simple-icons": "^16.28.0", + "wanted-sans": "1.0.3" }, "overrides": { "svgo": "4.1.0", diff --git a/docs-site/public/favicon.svg b/docs-site/public/favicon.svg new file mode 100644 index 00000000000..bd0cf20828f --- /dev/null +++ b/docs-site/public/favicon.svg @@ -0,0 +1,14 @@ + diff --git a/docs-site/public/grain.svg b/docs-site/public/grain.svg new file mode 100644 index 00000000000..9b7a1133c22 --- /dev/null +++ b/docs-site/public/grain.svg @@ -0,0 +1 @@ + diff --git a/docs-site/src/assets/logo-dark.svg b/docs-site/src/assets/logo-dark.svg new file mode 100644 index 00000000000..5b5acb93733 --- /dev/null +++ b/docs-site/src/assets/logo-dark.svg @@ -0,0 +1,14 @@ + diff --git a/docs-site/src/assets/logo-light.svg b/docs-site/src/assets/logo-light.svg new file mode 100644 index 00000000000..0797892fe07 --- /dev/null +++ b/docs-site/src/assets/logo-light.svg @@ -0,0 +1,14 @@ + diff --git a/docs-site/src/components/CloudCanvas.astro b/docs-site/src/components/CloudCanvas.astro new file mode 100644 index 00000000000..6abc9d88474 --- /dev/null +++ b/docs-site/src/components/CloudCanvas.astro @@ -0,0 +1,316 @@ +--- +// Animated WebGL2 cloud sky for the hero and closing panel. Renders into an +// absolutely positioned host that fills its nearest positioned ancestor. +// Without WebGL2 the host keeps its CSS sky colour, so the section still reads. +// Under reduced motion one still frame is drawn and re-drawn on theme change. +interface Props { + class?: string; + /** `sky` paints a full daylight sky; `overlay` draws only the clouds, + * dusk-lit and translucent, over whatever sits behind the canvas. */ + variant?: 'sky' | 'overlay'; +} +const { class: className, variant = 'sky' } = Astro.props; +--- + +
+ + diff --git a/docs-site/src/components/Header.astro b/docs-site/src/components/Header.astro index 7457c6d4210..7e86a7de5dc 100644 --- a/docs-site/src/components/Header.astro +++ b/docs-site/src/components/Header.astro @@ -17,7 +17,34 @@ const base = import.meta.env.BASE_URL.replace(/\/?$/, '/'); const prefix = locale ? `${base}${locale}/` : base; type NavLink = { label: string; href: string }; -type NavGroup = { label: string; links: NavLink[] }; +type NavGroup = { label: string; links: NavLink[]; more?: NavLink }; + +// Dropdown rows: every entry gets an icon tile. +// Lucide outline paths (24x24, stroke), keyed by the link's slug. +const ICONS: Record