|
| 1 | +--- |
| 2 | +description: Docs site UI — Phase 7/8 shadcn/ui parity (layout, CodeBlock, typography) |
| 3 | +globs: apps/docs/**/* |
| 4 | +alwaysApply: false |
| 5 | +--- |
| 6 | + |
| 7 | +# Docs UI — shadcn/ui parity (solidcn) |
| 8 | + |
| 9 | +## Theme |
| 10 | + |
| 11 | +- **Default: light** — `:root` uses white background, dark foreground, subtle `border-border`. |
| 12 | +- **Dark:** `dark` class on `<html>` (see `apps/docs/src/lib/theme.ts`). |
| 13 | +- Font: **Inter** (linked in `entry-server.tsx`), `antialiased` on `body`. |
| 14 | + |
| 15 | +## Layout (`apps/docs/src/components/layout/`) |
| 16 | + |
| 17 | +- **Header:** `h-14`, `border-b border-border`, `bg-background/95`, backdrop blur. Only one top-nav item is “active” — check order: Components → Registry → CLI → Docs (Docs is **not** active on `/docs/cli` or `/docs/components/*`). |
| 18 | +- **Desktop sidebar:** `w-[220px]` / `xl:w-[240px]`, `border-r`, group titles `uppercase tracking-widest text-[11px]`, active item `bg-muted font-medium`. |
| 19 | +- **Mobile:** drawer + overlay; menu state in `app.tsx` (not in `DocLayout`). |
| 20 | +- **DocLayout:** `max-w-screen-2xl` wrapper, **no** duplicate `MobileSidebar`. Main: `article.docs-prose` + right TOC (`xl`+), **`xl:gap-16`** between columns. |
| 21 | +- **DocPage:** optional `docPath` → **`DocsSeo`** (title, description, OG, canonical via `lib/site.ts`), **Copy page** (markdown export), **`DocPager`** (prev/next from `getDocNeighbors` / sidebar order). Optional **`playground`** = StackBlitz iframe. |
| 22 | +- **404:** `routes/[...404].tsx` + prerender `/404` in `app.config.ts`. |
| 23 | +- **TableOfContents:** label **“On this page”**, nav with `border-l` + active indicator `border-foreground`. Active section uses **scroll spy** (`getBoundingClientRect().top <= headerOffset`), not `IntersectionObserver` alone — so at the bottom of the page the last item (e.g. **API Reference**) stays highlighted instead of sticking on **Sizes**. |
| 24 | + |
| 25 | +## CodeBlock (`components/ui/CodeBlock.tsx`) |
| 26 | + |
| 27 | +- **Shiki** follows docs theme: `docsTheme()` → `github-light` / `github-dark` (use `createEffect`, not only `onMount`). |
| 28 | +- **`variant="card"` (default):** bordered blocks in prose. **No `filename` (light):** `#f6f8fa`, **dark:** `zinc-950`. Do **not** use a global `.shiki { background: transparent }` on these — it breaks contrast. |
| 29 | +- **`variant="figure"`** (component demos): flat panel using **`--docs-code` / `--docs-code-foreground`** in `app.css`; root has `docs-code-figure` + **`pre.shiki { background: transparent !important }`** so one surface matches **ui.shadcn.com**. **Copy** = icon (`Copy` / `Check`), top-right. **`border-t`** separates preview from code. |
| 30 | +- **With `filename`:** header bar is theme-aware — **light:** `bg-muted/50` (card) or code surface (figure); **dark:** zinc bars. Copy text button in header row. |
| 31 | + |
| 32 | +## Component demo |
| 33 | + |
| 34 | +- `ComponentDemo` (shadcn order): **(1)** preview with bottom border → **(2)** **View code** / **Hide code** pill on the seam → **(3)** `CodeBlock variant="figure"`; collapsed: **`max-h-64`** (~shadcn `CodeCollapsibleWrapper`) + **bottom-only** fade (`linear-gradient` to `hsl(var(--docs-code))`, not a full-panel dark wash); expanded: full height. `ChevronDown` rotates when open. Outer card avoids `overflow-hidden` so the pill isn’t clipped. |
| 35 | + |
| 36 | +## Content pages (prose) |
| 37 | + |
| 38 | +- Main doc title: `text-4xl font-bold tracking-tight`. |
| 39 | +- Subsections: `text-xl font-semibold` (h2), `leading-7` on explanatory paragraphs. |
| 40 | +- Inline code: `rounded-md border border-border bg-muted px-1.5 py-0.5 font-mono text-xs` (or `text-[13px]` for short names). |
| 41 | +- **CLI** page: use **TOC** (`TocItem[]`) + `id` / `scroll-mt-24` on each block linked from the TOC. |
| 42 | + |
| 43 | +## Global CSS (`app.css`) |
| 44 | + |
| 45 | +- HSL tokens on `:root` and `.dark`. |
| 46 | +- `.docs-prose` utility — `max-width: 48rem`, `scroll-margin` for headings. |
| 47 | + |
| 48 | +## Don’ts |
| 49 | + |
| 50 | +- No emoji as icons in public docs UI — **lucide-solid** only. |
| 51 | +- Don’t hardcode dark zinc for normal code blocks in light mode (except dark filename bar in dark theme). **Home “Quick install”:** light = soft strip `#f6f8fa` + `bg-card` terminal; dark = `zinc-950` strip + `zinc-900` panel. |
0 commit comments