mirror of
https://github.com/vercel/chat.git
synced 2026-09-14 18:32:29 +08:00
3ae34b3ed1
Third repo in the design sync, after `vercel/geistdocs#216`/`#218` and `vercel/flags#457`. Upgrades the docs site to `@vercel/geistdocs@1.19.2` and brings the homepage onto the Geist design system. `apps/docs` is `private: true`, so no changeset. ## Dependency `1.19.2` peers on `next: ^16.2.11` and the app pinned `16.2.6`, so **next moves to `16.2.12`** alongside it — without that pnpm reports an unmet peer. Installed via `pnpm add --save-exact` per AGENTS.md. All 20 geistdocs subpaths this app imports still exist in 1.19.2; no API breakage. The footer needed no work: 1.16 already shipped the prop-less Vercel-directory `<Footer />`. ## Layout — `home-grid.css` is gone Deleted `app/styles/home-grid.css` (368 lines) and its `global.css` import, and rebuilt each section on `grid-cols-12` / `col-span-*`: | section | before (CSS) | after | |---|---|---| | OSS stats | 2×2 → 4×1 @768 | `col-span-6 min-[768px]:col-span-3` | | Features | 2-up + full-width 3rd → 3×1 @961 | `col-span-12 sm:col-span-6 lg:col-span-4` | | Code | stacked → sidebar 1/3 + code 2/3 @961 | `lg:col-span-8` / `lg:col-span-4`, pinned with `col-start` + `row-start` | | Integrations | 1×5 → tall left + 2×2 @961 | `lg:col-span-4 lg:row-span-2` + four `lg:col-span-4` | The code section needs explicit `col-start`/`row-start` because the sidebar follows the code in the DOM but sits left of it from `lg`. Other layout changes: - **Single gutter at the page root** (`mx-auto w-full max-w-[1448px] px-4 sm:px-6`); removed the per-section horizontal padding that duplicated it, so every section's content lands on the navbar/footer content edge. - **Content widened 1114px → 1400px**, the navbar's content span (1448 − 2×24). - **Bottom gap above the footer trimmed ~320px → ~176px** — layout `pb-32` → `pb-16` and page `pb-24 sm:pb-36` → `pb-12 sm:pb-16`. Three paddings were stacking. The 768px stats breakpoint is preserved with `min-[768px]:` — there's no Tailwind equivalent here (`md`=601, `lg`=961) and four KPI columns at 601px would be ~140px each. ## Design — ported from vercel.com/ai-sdk Read off the flagged source in `front/apps/vercel-marketing/.../ai-sdk`, not the live site. - **Code showcase tabs** → the `SlidingTabs` primitive: pill labels with an animated indicator, full keyboard nav (arrows/Home/End, roving tabindex), and an invisible-bold label so the tab doesn't shift width when it bolds. Four tabs per group with dot pagination for the rest, tabs above the code block. Copied into `components/ui/sliding-tabs.tsx` with `cn` rewired and the `no-scrollbar` utility inlined (geistdocs doesn't define it). - **"Scale with confidence"** → heading and paragraph on one bottom-aligned row (cols 1–4 / 8–12), then four bordered cards `col-span-12 md:col-span-6 lg:col-span-3`. Type mapped from their primitives: `SectionHeading size="48"` → `text-heading-40 lg:text-heading-48`, `SectionParagraph size="18"` → `text-copy-16 lg:text-copy-18`. - **Feature row** → icon + muted eyebrow over a prominent statement. Note this **inverts the previous emphasis**: the heading is now the small muted label and the description the larger line, matching the reference. Icons come from geistdocs' own set so they match Geist's line weight: `IconLinked`, `IconWorkflow`, `IconAcronymTs`. - **Get-started install snippet** → the shared `CommandPrompt`, with its buttons on one row from `lg`. - Remaining headings converted to `text-heading-*`. - Navbar logo drops `height={22}` to take `LogoChatSdk`'s new 18px default (renders 106.9×22 → 87.4×18). ## Two fixes worth calling out **`lib/utils.ts` — `cn` was silently dropping typography.** Geist's `text-copy-*`/`text-heading-*` share the `text-` prefix with colour utilities, so stock `tailwind-merge` classifies them as colours and drops the size whenever both appear in one `cn()` call. geistdocs ships a `cn` that registers them as `font-size` for exactly this reason but doesn't export it, so the config is replicated here. This was a latent bug across the app, not just the new code. **`Analytics`/`SpeedInsights` moved out of the `"use client"` provider** into the server layout. Both emit `<script>`, and scripts rendered inside a client tree never execute — so analytics wasn't firing on client navigations. React 19.2.7 (pulled in by this bump) now warns about it; the bug predates it. ## Verification - `pnpm --filter docs build` passes (270 pages), `tsc --noEmit` clean, `biome check` clean. - Rendered output spot-checked for the tab strip, dot pagination, card classes, and feature icons. **`pnpm validate` could not be run** — it needs Node ≥20.19 and this machine is on v20.11.1 (`pnpm check` dies on `styleText` from `node:util`). Biome, tsc and build were run directly instead, but the knip and test legs are unrun and should be confirmed in CI. Signed-off-by: christopherkindl <53372002+christopherkindl@users.noreply.github.com>
54 lines
1.2 KiB
TypeScript
54 lines
1.2 KiB
TypeScript
import { type ClassValue, clsx } from "clsx"
|
|
import { extendTailwindMerge } from "tailwind-merge"
|
|
|
|
// Geist typography utilities share the `text-` prefix with color utilities
|
|
// (e.g. text-gray-900). tailwind-merge only knows the default theme, so it
|
|
// mistakes these size tokens for colors and drops them when both are present.
|
|
// Register them as font-size members so merges keep size and color
|
|
// independent. Mirrors the `cn` inside @vercel/geistdocs, which isn't exported.
|
|
const GEIST_FONT_SIZES = [
|
|
"button-12",
|
|
"button-14",
|
|
"button-16",
|
|
"copy-13",
|
|
"copy-13-mono",
|
|
"copy-14",
|
|
"copy-14-mono",
|
|
"copy-16",
|
|
"copy-18",
|
|
"copy-20",
|
|
"copy-24",
|
|
"heading-14",
|
|
"heading-16",
|
|
"heading-20",
|
|
"heading-24",
|
|
"heading-32",
|
|
"heading-40",
|
|
"heading-48",
|
|
"heading-56",
|
|
"heading-64",
|
|
"heading-72",
|
|
"label-12",
|
|
"label-12-mono",
|
|
"label-13",
|
|
"label-13-mono",
|
|
"label-14",
|
|
"label-14-mono",
|
|
"label-16",
|
|
"label-16-mono",
|
|
"label-18",
|
|
"label-20",
|
|
]
|
|
|
|
const twMerge = extendTailwindMerge({
|
|
extend: {
|
|
classGroups: {
|
|
"font-size": [{ text: GEIST_FONT_SIZES }],
|
|
},
|
|
},
|
|
})
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs))
|
|
}
|