/CLAUDE.md
CLAUDE.md at /CLAUDE.md
Path: CLAUDE.md
Zudo Sg
Documentation site built with zudo-doc — a zfb-based documentation framework with MDX, Tailwind CSS v4, and Preact islands.
Tech Stack
zfb — documentation build framework. The
@takazudo/zfb*family is pinned to the stable2.15.1release in lockstep with zudo-doc 5.19.0.MDX — content format
Tailwind CSS v4 — via
@tailwindcss/vitePreact — for interactive islands only (with compat mode for React API)
syntax highlighting — built-in class-mode code highlighting, run by zfb's Rust pipeline at build time: fences render as semantic
hi-*token classes underpre.hi-root, mapped to this project's--zd-syntax-*design tokens via@takazudo/'szudo- doc/ features. css --zfb-hi-*bridge — no project-owned renderer, theme, orcodeHighlightconfig required. This superseded the old project-owned WCAG-AAbase16-oceantmTheme pair from #169, so syntax colors inherit the site's existing semantic tokens rather than being baked per-span at build time.
Commands
pnpm dev— zfb dev server (port 4321)pnpm build— static HTML export todist/pnpm check— TypeScript type checking
Key Directories
pages/ # File-based routing (host-owned: /, /components/*, /docs/versions)
│ # zudo-doc's package injects the rest (docs, 404, robots;
│ # sitemap only when settings.sitemap is on — it is off here)
src/
├── components/ # JSX + Preact components
│ └── content/ # MDX content components (admonitions, code-group, ...)
├── config/ # Settings, color schemes, design token manifests
├── content/
│ └── docs/ # Slim root guide content
├── features/
│ └── styleguide/ # /components catalog: chrome, preview, code-panel, search, token-tweak
├── styleguide/
│ └── data/ # Codegen-backed component registry + nav nodes (#103)
└── styles/
└── global.css # Design tokens & Tailwind config There is no src/pages/ or src/layouts/ — routing lives in the root pages/ directory, and page-level chrome (header, footer, doc-route shells) is owned by @takazudo/zudo-doc's package-injected routes (packageOwnedRoutes, see src/).
The tree above covers only the root host's own src/. packages/ui's component tree and apps/demo's content/route tree are separate workspace packages — see "Monorepo Structure" below.
Root / is intentionally slim and currently contains the root Guide. The full documentation site lives in doc/ and is deployed separately at https:; root nav/footer entries link there instead of duplicating that content.
Content Conventions
Frontmatter
Required:
title(string)Optional:
description,sidebar_position(number),categorySidebar order is driven by
sidebar_position
Admonitions
Available in all MDX files without imports: <Note>, <Tip>, <Info>, <Warning>, <Danger>, <Caution>, <Details> (via :::name directives, registered in zfb.config.ts) — plus <Important> from GitHub-style [!IMPORTANT] blockquote alerts. Each accepts an optional title prop; Details renders as a collapsible section.
Headings
Do NOT use h1 (#) in doc content — the page title from frontmatter is rendered as h1. Start content headings from h2 (##).
Components
Default to server-rendered JSX components (
.tsx) — zero JS, server-renderedUse Preact islands only when client-side interactivity is needed: mark the component module
"use client"and mount it via zfb's<Island ssrFallback={...}>wrapper (when: "load"or"idle") — seepages/for the pattern. There is nolib/ _ body- end- islands. tsx client:load-style directive; that was an Astro-era convention this project no longer uses.
Component provider and product split
zudo-sg owns the provider — components, stories, typed
*.composer.tsxsidecars, generatedpackages/, and the explicitui/ src/ composer- pack. ts packages/entry live here.ui/ styles/ composer. css Authoring rule — use
defineComponentfrom@zudo-composer/component-contractin a co-located sidecar. Persisted componentid,schemaVersion, fieldprop, and slotid/propare explicit stable keys.source.moduleis the public@zudo-sg/uipackage export, never a private/path. Export display metadata from the sidecar; the story imports/spreads it, but no provider code imports stories.src/ * Generated boundary —
pnpm gen:composer-packdiscovers sidecars and generates the manifest/runtime pack.pnpm check:composer-packrejects drift. Consumers import@zudo-andsg/ ui/ composer- pack @zudo-.sg/ ui/ styles/ composer. css Immutable handoff —
ui-provider-handoff.jsonrecords the package tree, package-only commit, exact Git spec, and exact component-contract commit. Finish package docs/code first, advance localpackage/ui-v1, then runpnpm verify:ui-provider-install -- --exact. Never pre-claim the post-merge source SHA or CI URL.Local gate sequencing —
packages/uiis also a standalone package with its own lockfile; runningpnpmwith a working directory or--dirinsidepackages/ui(even a no-op) auto-installs its standalone dependency set and diverges the tree from the root workspace. The canonical local sequence, the lockfile-refresh procedure, and therm -recovery are documented inrf packages/ ui/ node_ modules & & pnpm install doc/("Standalone provider package gate").src/ content/ docs/ development/ quality- gates. mdx pnpm test:ui-provider-packageandpnpm verify:ui-provider-install -- --exactare already isolated and safe to run as-is.zudo-composer owns the products — the standalone repository owns both Composer and Sitemapper, including their clean storage/schema identities, routes, application UI, and deployment.
zudo-sg owns the styleguide and provider — the host routes, catalog, stories, provider sidecars/pack/CSS, and provider verification remain here; no Composer or Sitemapper application code lives in this repository.
No compatibility contract — there are zero users and zero production Composer/Sitemapper data. Destructive current-only cleanup is required; do not add backward-compatibility readers, migrations, redirects, aliases, or old-name and old-storage fallbacks.
Route invariant — the styleguide-only root build emits 82 HTML routes (zfb reports 83 pages, the 83rd being
/). Since zudo-doc 5.17.0 the package injectsrobots. txt /only whensitemap. xml settings.sitemapis enabled, and this project sets it tofalse, so no sitemap route is emitted. Do not remove provider guides or unrelated routes while cleaning product ownership.
See packages/ §10, packages/, and ui-provider-handoff.json for the permanent provider contract.
Monorepo Structure
This is a pnpm workspace monorepo:
Root (
.) — the zudo-doc styleguide host and component catalogdoc/(@zudo-sg/doc) — the full docs workspace; owns Claude resource generation and doc-lookup skill setuppackages/ui(@zudo-sg/ui) — shared Preact component library: ~70 components undersrc/<category>/<component>/, grouped into 9 category directories (cards/ chrome/ content/ forms/ landing/ media/ news/ search/ shared/)apps/demo(@zudo-sg/demo) — multi-page corporate demo site (Tailwind v4, no SSR): a ~70-entry content collection undercontent/drives nav/footer/breadcrumbs from frontmatter, plus cross-site search (/), an SPA-style client router with View Transitions (search components/router/), and per-business-line theming (config/,lines. ts styles/)lines. css
@zudo-sg/ui is consumed from source — its exports map points at . directly and it has no build script, so edits are picked up by consumers immediately; there is no dist step to run.
To build all packages: pnpm install && pnpm build (root only; apps/demo builds with pnpm --filter @zudo-sg/demo build).
Design tokens
@zudo-sg/ui colors follow a grouped three-tier strategy: Tier-1 --palette-{group}-{n} ramps (base, accent, state, plus a line-* ramp per business line) feed Tier-2 semantic @theme roles (bg, surface, surface-2, border, fg, muted, accent, accent-hover, on-accent, focus, the rail-* family, and the state colors), defined in packages/. Components bind only to the Tier-2 semantic utilities (bg-accent, text-fg, border-border, …) — the Tier-1 palette is a plain :root block, never @theme, so no bg-palette-* utility is ever generated. Full contract: packages/ §"Three-tier color system". This is independent of the doc-chrome's own --zd-* token world (src/) — see . for how the two worlds relate.
Enabled Features
search — Full-text search via MiniSearch (
pages/); the sidebar also has its own real-time filter input, implemented in thelib/ _ search- widget. tsx @takazudo/package island (not a separate toggleable feature)zudo- doc/ sidebar- tree- island imageEnlarge — Click-to-enlarge images
claudeResources — Moved to the
doc/workspaceclaudeSkills — The
doc/workspace ships zudo-doc-design-system, zudo-doc-translate, zudo-doc-version-bump skillsdesignTokenPanel — Interactive tabbed panel for tweaking spacing, font, size, and color tokens
dynamicPageTransition — SPA client-router page swaps with View Transitions and page-loading overlay
sidebarResizer — Draggable sidebar width
sidebarToggle — Show/hide desktop sidebar
versioning — Multi-version documentation support
llmsTxt — Generates llms.txt for LLM consumption
skillSymlinker — Moved to the
doc/workspace (pnpm --filter @zudo-sg/doc setup:doc-skill)footerNavGroup — Footer navigation link groups
footerCopyright — Footer copyright notice