@nexpress/theme-docs 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -173,18 +173,17 @@ type DocsSettings = z.infer<typeof docsSettingsSchema>;
173
173
  * right. Sidebar collapses out at the tablet breakpoint; TOC
174
174
  * collapses out below 1100px.
175
175
  *
176
- * Pairs with a `docs` collection (auto-created via
177
- * `requires.collections.docs.createIfAbsent` on the bundled-themes
178
- * prebake path). Operator-declared fields with the same names win
179
- * on collision so a site that ships its own `docs` schema is
180
- * never overwritten.
176
+ * Pairs with `posts` rows of `kind: "doc"`
177
+ * (universal-content-model #748 — docs are posts with a kind
178
+ * discriminator, not a separate collection). The doc-specific
179
+ * fields (`lede`, `stableSince`) are contributed via
180
+ * `requires.collections.posts.fields` and merged onto the
181
+ * built-in posts collection at config-resolution time.
181
182
  *
182
183
  * `seedContent.navigation` ships the primary header / footer
183
- * links; the `docs` collection rows are operator-authored.
184
- * Seeding actual doc rows requires the seedContent contract to
185
- * grow a `documents?: Record<slug, ...>` slot, which is queued as
186
- * a follow-up — without it, themes that target non-page / non-post
187
- * collections (docs, projects, products) can only seed nav.
184
+ * links. Doc rows are operator-authored; themes that want to
185
+ * seed kind="doc" content use `seedContent.posts` with the
186
+ * `kind` field set on each entry (see U.1 #749).
188
187
  */
189
188
  declare const docsTheme: _nexpress_theme.NpTheme;
190
189
 
package/dist/index.js CHANGED
@@ -411,8 +411,8 @@ async function loadBreadcrumbs(current) {
411
411
  if (!current.parent) {
412
412
  return [root, { slug: null, title: current.title }];
413
413
  }
414
- const result = await findDocuments("docs", {
415
- where: { status: "published" },
414
+ const result = await findDocuments("posts", {
415
+ where: { status: "published", kind: "doc" },
416
416
  sort: "order",
417
417
  limit: 500
418
418
  });
@@ -432,8 +432,8 @@ async function loadBreadcrumbs(current) {
432
432
  return [root, ...chain, { slug: null, title: current.title }];
433
433
  }
434
434
  async function loadPrevNext(current) {
435
- const result = await findDocuments("docs", {
436
- where: { status: "published" },
435
+ const result = await findDocuments("posts", {
436
+ where: { status: "published", kind: "doc" },
437
437
  sort: "order",
438
438
  limit: 500
439
439
  });
@@ -473,8 +473,8 @@ async function DocsDetailRoute({
473
473
  }) {
474
474
  const slug = typeof params.slug === "string" ? params.slug : "";
475
475
  if (!slug) notFound();
476
- const result = await findDocuments2("docs", {
477
- where: { slug, status: "published" },
476
+ const result = await findDocuments2("posts", {
477
+ where: { slug, status: "published", kind: "doc" },
478
478
  limit: 1
479
479
  });
480
480
  const doc = result.docs[0];
@@ -584,8 +584,8 @@ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
584
584
  async function DocsSidebar() {
585
585
  const settings = await resolveDocsSettings();
586
586
  const currentSlug = await currentPathSlug();
587
- const result = await findDocuments3("docs", {
588
- where: { status: "published" },
587
+ const result = await findDocuments3("posts", {
588
+ where: { status: "published", kind: "doc" },
589
589
  sort: "order",
590
590
  limit: 500
591
591
  });
@@ -1526,24 +1526,68 @@ var docsTheme = defineTheme({
1526
1526
  nexpress: { minVersion: "0.1.0" },
1527
1527
  requires: {
1528
1528
  collections: {
1529
- docs: {
1530
- createIfAbsent: true,
1529
+ posts: {
1530
+ // Universal-content-model #748 — docs are posts with
1531
+ // `kind: "doc"`. The framework's built-in `posts`
1532
+ // collection already supplies `title` / `body` /
1533
+ // `parent` (rel→posts) / `order`. Docs theme adds the
1534
+ // doc-specific meta pills and contributes the kind
1535
+ // option + kinds metadata block for admin / URL
1536
+ // routing.
1531
1537
  fields: {
1532
- title: { type: "text", required: true },
1533
- // Short opening paragraph rendered as a lede under the
1534
- // h1. Optional the article still renders without it.
1535
- lede: { type: "textarea", hard: false },
1536
- body: { type: "richText" },
1537
- parent: {
1538
- type: "relationship",
1539
- relationTo: "docs",
1540
- hard: false
1538
+ kind: {
1539
+ type: "select",
1540
+ options: [{ label: "Doc", value: "doc" }]
1541
1541
  },
1542
- order: { type: "number" },
1543
- // Meta-pill slotsall optional, all advisory hints
1544
- // the doc-page template surfaces in the strap row.
1545
- stableSince: { type: "text", hard: false },
1546
- badge: { type: "text", hard: false }
1542
+ // Short opening paragraph rendered as a lede under
1543
+ // the h1. Optional the article still renders
1544
+ // without it. Lives in a "Docs" sidebar group with
1545
+ // `stableSince`; the group + fields hide entirely
1546
+ // when the active kind isn't `"doc"`.
1547
+ lede: {
1548
+ type: "textarea",
1549
+ hard: false,
1550
+ admin: {
1551
+ position: "sidebar",
1552
+ group: "Docs",
1553
+ condition: { when: "kind", equals: "doc" }
1554
+ }
1555
+ },
1556
+ // Meta-pill slot — advisory hint the doc-page
1557
+ // template surfaces in the strap row. Note: portfolio
1558
+ // theme also contributes a `badge: text` field on
1559
+ // posts; the merge-requirements union picks the first
1560
+ // declarer. Docs reads `doc.badge` regardless of which
1561
+ // theme declared the column.
1562
+ stableSince: {
1563
+ type: "text",
1564
+ hard: false,
1565
+ admin: {
1566
+ position: "sidebar",
1567
+ group: "Docs",
1568
+ condition: { when: "kind", equals: "doc" }
1569
+ }
1570
+ }
1571
+ },
1572
+ groupMeta: {
1573
+ Docs: {
1574
+ icon: "BookOpen",
1575
+ description: "Doc-specific meta \u2014 lede and API stability hint."
1576
+ }
1577
+ },
1578
+ kinds: {
1579
+ doc: {
1580
+ label: "Doc",
1581
+ labelPlural: "Documentation",
1582
+ icon: "BookOpen",
1583
+ // Public-site URL pattern. The catch-all router
1584
+ // matches `/docs/<slug>` and queries posts with
1585
+ // `where: { kind: "doc", slug }`.
1586
+ urlPattern: "/docs/:slug",
1587
+ // Hint to admin: show parent + order controls and
1588
+ // render the list as a tree, not a flat table.
1589
+ hierarchical: true
1590
+ }
1547
1591
  }
1548
1592
  }
1549
1593
  }
@@ -1583,8 +1627,14 @@ var docsTheme = defineTheme({
1583
1627
  navigation: SEED_NAV
1584
1628
  },
1585
1629
  templates: {
1586
- docs: {
1587
- default: {
1630
+ // Universal-content-model #748 — docs are posts with
1631
+ // `kind: "doc"`. The template key matches the kind value so
1632
+ // the per-kind template lookup picks this up automatically.
1633
+ // Article-kind posts continue rendering through the
1634
+ // framework's inline article markup unless the operator
1635
+ // declares a `templates.posts.default` of their own.
1636
+ posts: {
1637
+ doc: {
1588
1638
  label: "Doc page",
1589
1639
  description: "Three-column reference layout \u2014 breadcrumbs + lede + meta + Lexical body + feedback + prev/next, with the docs sidebar slotted on the left and the on-page TOC on the right.",
1590
1640
  component: DocPageTemplate
@@ -1607,12 +1657,11 @@ var docsTheme = defineTheme({
1607
1657
  // by the parametric detail route below (dispatcher is
1608
1658
  // first-match-wins).
1609
1659
  { pattern: "/docs/search", component: DocsSearch },
1610
- // Doc detail dispatch (#614). The sidebar + template emit
1611
- // `/docs/<slug>` links; without this route those 404 in
1612
- // the reference app the catch-all only resolves `pages`
1613
- // rows, not arbitrary `docs` collection rows. The
1614
- // component looks up the docs row by slug and renders
1615
- // through `templates.docs.default` (DocPageTemplate).
1660
+ // Doc detail dispatch. The sidebar + template emit
1661
+ // `/docs/<slug>` links; the route component looks up the
1662
+ // doc-kind post by slug and renders through DocPageTemplate.
1663
+ // Universal-content-model #748 docs are posts with
1664
+ // `kind="doc"`; the lookup filters on kind, not collection.
1616
1665
  { pattern: "/docs/:slug", component: DocsDetailRoute }
1617
1666
  ],
1618
1667
  navLocations: {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/header.tsx","../src/settings-helpers.ts","../src/settings.ts","../src/members-not-found.tsx","../src/members-shell.tsx","../src/not-found.tsx","../src/routes/doc-detail.tsx","../src/templates/doc-page.tsx","../src/toc-scrollspy-bridge.ts","../src/search.tsx","../src/shell.tsx","../src/sidebar.tsx","../src/styles.ts"],"sourcesContent":["import { defineTheme } from \"@nexpress/theme\";\n\nimport { DocsHeader } from \"./header.js\";\nimport { DocsMembersNotFound } from \"./members-not-found.js\";\nimport { DocsMembersShell } from \"./members-shell.js\";\nimport { DocsNotFound } from \"./not-found.js\";\nimport { DocsDetailRoute } from \"./routes/doc-detail.js\";\nimport { DocsSearch } from \"./search.js\";\nimport { DocsShell } from \"./shell.js\";\nimport { DocsSidebar } from \"./sidebar.js\";\nimport { docsCss } from \"./styles.js\";\nimport { docsSettingsSchema } from \"./settings.js\";\nimport { DocPageTemplate } from \"./templates/doc-page.js\";\n\nconst SEED_NAV = {\n header: [\n { id: \"nav-docs-docs\", label: \"Docs\", type: \"link\" as const, url: \"/docs\" },\n { id: \"nav-docs-reference\", label: \"Reference\", type: \"link\" as const, url: \"/docs/reference\" },\n { id: \"nav-docs-blog\", label: \"Blog\", type: \"link\" as const, url: \"/blog\" },\n ],\n footer: [\n { id: \"nav-docs-footer-docs\", label: \"Documentation\", type: \"link\" as const, url: \"/docs\" },\n { id: \"nav-docs-footer-reference\", label: \"Reference\", type: \"link\" as const, url: \"/docs/reference\" },\n { id: \"nav-docs-footer-changelog\", label: \"Changelog\", type: \"link\" as const, url: \"/changelog\" },\n { id: \"nav-docs-footer-github\", label: \"GitHub\", type: \"link\" as const, url: \"https://github.com\" },\n ],\n};\n\n/**\n * `@nexpress/theme-docs` — documentation theme for NexPress.\n *\n * Three-column reference-docs layout: sticky search-first header\n * (brand mark + version pill + ⌘K search + primary nav + GitHub\n * link), hierarchical sidebar with bullet-eyebrow groups + nested\n * links + status badges, centered article column with breadcrumbs\n * + lede + meta pills + Lexical body, on-this-page TOC on the\n * right. Sidebar collapses out at the tablet breakpoint; TOC\n * collapses out below 1100px.\n *\n * Pairs with a `docs` collection (auto-created via\n * `requires.collections.docs.createIfAbsent` on the bundled-themes\n * prebake path). Operator-declared fields with the same names win\n * on collision so a site that ships its own `docs` schema is\n * never overwritten.\n *\n * `seedContent.navigation` ships the primary header / footer\n * links; the `docs` collection rows are operator-authored.\n * Seeding actual doc rows requires the seedContent contract to\n * grow a `documents?: Record<slug, ...>` slot, which is queued as\n * a follow-up — without it, themes that target non-page / non-post\n * collections (docs, projects, products) can only seed nav.\n */\nexport const docsTheme = defineTheme({\n manifest: {\n id: \"docs\",\n name: \"Docs\",\n version: \"0.2.0\",\n description:\n \"Documentation theme — three-column layout with hierarchical sidebar, breadcrumbs + lede + meta pills on the article column, on-this-page TOC on the right rail. Blue accent on a near-white surface; pairs with a `docs` collection.\",\n author: { name: \"NexPress\" },\n nexpress: { minVersion: \"0.1.0\" },\n requires: {\n collections: {\n docs: {\n createIfAbsent: true,\n fields: {\n title: { type: \"text\", required: true },\n // Short opening paragraph rendered as a lede under the\n // h1. Optional — the article still renders without it.\n lede: { type: \"textarea\", hard: false },\n body: { type: \"richText\" },\n parent: {\n type: \"relationship\",\n relationTo: \"docs\",\n hard: false,\n },\n order: { type: \"number\" },\n // Meta-pill slots — all optional, all advisory hints\n // the doc-page template surfaces in the strap row.\n stableSince: { type: \"text\", hard: false },\n badge: { type: \"text\", hard: false },\n },\n },\n },\n },\n settingsSchema: docsSettingsSchema,\n },\n impl: {\n shell: DocsShell,\n slots: {\n header: DocsHeader,\n sidebar: DocsSidebar,\n },\n css: docsCss,\n tokens: {\n colors: {\n primary: \"#2563eb\",\n primaryForeground: \"#ffffff\",\n background: \"#fbfcfe\",\n foreground: \"#0c1320\",\n muted: \"#f1f4f9\",\n mutedForeground: \"#5b6478\",\n border: \"#e2e7ef\",\n card: \"#ffffff\",\n },\n typography: {\n fontHeading:\n '\"Geist\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif',\n fontBody:\n '\"Geist\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif',\n fontMono:\n '\"Geist Mono\", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n },\n shape: {\n radiusSm: \"5px\",\n radiusMd: \"9px\",\n radiusLg: \"10px\",\n },\n },\n seedContent: {\n navigation: SEED_NAV,\n },\n templates: {\n docs: {\n default: {\n label: \"Doc page\",\n description:\n \"Three-column reference layout — breadcrumbs + lede + meta + Lexical body + feedback + prev/next, with the docs sidebar slotted on the left and the on-page TOC on the right.\",\n component: DocPageTemplate,\n },\n },\n },\n routes: [\n // F.2 — docs theme's scoped search route. Lives at\n // `/docs/search` rather than `/search` (#609): the host's\n // reference app has an app-explicit `/search` page route\n // that takes precedence over theme routes per the locked\n // dispatch order (app file > page > theme > plugin). The\n // theme can't override the universal search page, so it\n // scopes its own search to a `/docs/*` namespace and the\n // operator gets both routes: framework `/search` + docs\n // theme `/docs/search`.\n //\n // Order matters: search comes first so `/docs/search` is\n // matched as a literal rather than `{ slug: \"search\" }`\n // by the parametric detail route below (dispatcher is\n // first-match-wins).\n { pattern: \"/docs/search\", component: DocsSearch },\n // Doc detail dispatch (#614). The sidebar + template emit\n // `/docs/<slug>` links; without this route those 404 in\n // the reference app — the catch-all only resolves `pages`\n // rows, not arbitrary `docs` collection rows. The\n // component looks up the docs row by slug and renders\n // through `templates.docs.default` (DocPageTemplate).\n { pattern: \"/docs/:slug\", component: DocsDetailRoute },\n ],\n navLocations: {\n primary: {\n label: \"Primary header nav\",\n description: \"Inline links beside the masthead search box.\",\n maxItems: 5,\n },\n },\n notFound: DocsNotFound,\n // M.* adoption (2026-05-11). Docs gains purpose-built member\n // chrome: drops the docs sidebar (hierarchical doc nav is\n // useless on auth forms), keeps the masthead, narrows the\n // content column. Without this, the fallback chain would\n // walk back to `impl.shell` (the 3-column grid) and the\n // sidebar slot would surface alongside an auth form.\n // - `shell`: DocsMembersShell (header + narrow column, no\n // sidebar).\n // - `notFound`: DocsMembersNotFound (stale-auth-link framing\n // with /members/login CTA, monospace accent matching the\n // theme).\n // - `error`: forward-compat type marker; the actual render\n // goes through `./components/members-error`'s client\n // subpath, lazy-imported by\n // `apps/web/src/app/(member)/error.tsx`'s registry\n // (F.7.1 delegation — Next mandates `error.tsx` is \"use\n // client\").\n members: {\n shell: DocsMembersShell,\n notFound: DocsMembersNotFound,\n },\n },\n});\n\nexport {\n DocsHeader,\n DocsShell,\n DocsSidebar,\n DocsNotFound,\n DocsMembersShell,\n DocsMembersNotFound,\n DocsSearch,\n DocPageTemplate,\n};\nexport { docsCss };\nexport { docsSettingsSchema, type DocsSettings } from \"./settings.js\";\n","import * as React from \"react\";\nimport { NavMenu, getCachedSite } from \"@nexpress/next\";\n\nimport { SearchKeyboardShortcut } from \"./components/search-keyboard-shortcut.js\";\nimport { resolveDocsSettings } from \"./settings-helpers.js\";\n\nconst FALLBACK_SITE_NAME = \"NexPress\";\n\n/**\n * Docs theme masthead. Brand strap (mark + wordmark + version\n * pill) on the left, ⌘K search form centered, primary nav +\n * GitHub repo link on the right.\n *\n * Search is a plain GET form to `/docs/search` — the theme's\n * own route handles the query so the host's `(site)/search`\n * page doesn't shadow it (#609). The ⌘K affordance is purely\n * visual hint copy in a `<kbd>`; wiring it to a global hotkey\n * is a separate client island sites can add on top.\n *\n * The GitHub link reads `settings.githubRepo`. When the admin\n * setting is unset, the link is hidden.\n */\nexport async function DocsHeader(): Promise<React.ReactElement> {\n const [settings, site] = await Promise.all([\n resolveDocsSettings(),\n getCachedSite(),\n ]);\n const siteName = site?.name?.trim() || FALLBACK_SITE_NAME;\n return (\n <header className=\"np-docs-header\">\n <div className=\"np-docs-header-inner\">\n <a href=\"/\" className=\"np-docs-brand\">\n <span className=\"np-docs-brand-mark\" aria-hidden=\"true\" />\n <span className=\"np-docs-brand-name\">{siteName}</span>\n <span className=\"np-docs-brand-version\">{settings.version}</span>\n </a>\n <form\n action=\"/docs/search\"\n method=\"get\"\n className=\"np-docs-search-form\"\n role=\"search\"\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n aria-hidden=\"true\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m21 21-4.3-4.3\" />\n </svg>\n <label className=\"sr-only\" htmlFor=\"np-docs-search-input\">\n Search the docs\n </label>\n <input\n id=\"np-docs-search-input\"\n type=\"search\"\n name=\"q\"\n placeholder={settings.searchPlaceholder}\n className=\"np-docs-search-input\"\n />\n <kbd className=\"np-docs-search-kbd\">⌘K</kbd>\n </form>\n <SearchKeyboardShortcut targetId=\"np-docs-search-input\" />\n <nav className=\"np-docs-nav\" aria-label=\"Primary\">\n <NavMenu location=\"primary\" className=\"np-docs-primary-nav\" />\n {settings.githubRepo ? (\n <a\n href={settings.githubRepo}\n className=\"np-docs-github\"\n target=\"_blank\"\n rel=\"noreferrer\"\n aria-label=\"GitHub repository\"\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path d=\"M12 .5a12 12 0 0 0-3.8 23.39c.6.11.82-.26.82-.58v-2c-3.34.73-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.1-.75.08-.74.08-.74 1.21.09 1.85 1.24 1.85 1.24 1.07 1.84 2.81 1.31 3.5 1 .11-.78.42-1.31.76-1.61-2.66-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.12-.3-.54-1.52.12-3.17 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.66 1.65.25 2.87.12 3.17.77.84 1.24 1.91 1.24 3.22 0 4.61-2.81 5.62-5.49 5.92.43.37.81 1.1.81 2.22v3.29c0 .32.22.7.83.58A12 12 0 0 0 12 .5Z\" />\n </svg>\n GitHub\n </a>\n ) : null}\n </nav>\n </div>\n </header>\n );\n}\n","import { getCachedThemeSettings } from \"@nexpress/next\";\n\nimport { docsSettingsSchema, type DocsSettings } from \"./settings.js\";\n\n/**\n * Phase F.9-B / F.9.1-B — typed accessor over the cached theme\n * settings read.\n *\n * Uses `getCachedThemeSettings` so multiple resolveSettings()\n * calls in the same request (header + sidebar + page template +\n * search) share one DB hit via Next's `unstable_cache`. The\n * `nx:theme:<siteId>` tag handles invalidation.\n *\n * On parse failure (theme upgrade changed the shape, etc.)\n * falls back to the schema defaults. The admin's\n * `getThemeSettingsWithStatus` surfaces a banner when this\n * happens; the runtime keeps rendering with safe values.\n */\nexport async function resolveDocsSettings(): Promise<DocsSettings> {\n const raw = await getCachedThemeSettings(\"docs\");\n const parsed = docsSettingsSchema.safeParse(raw);\n if (parsed.success) return parsed.data;\n return docsSettingsSchema.parse({});\n}\n","import { z } from \"zod\";\n\n/**\n * Phase F.9-B — operator-tunable docs settings.\n *\n * Stresses F.3's settings auto-form on a different axis from\n * magazine: more URL inputs, a select/enum for sidebar\n * orientation, and a documentation-flavored field set.\n */\nexport const docsSettingsSchema = z.object({\n version: z\n .string()\n .default(\"v1\")\n .describe(\n \"Currently-displayed version label, shown in the masthead. Update on each release.\",\n ),\n githubRepo: z\n .string()\n .url()\n .optional()\n .describe(\n \"Optional repository URL — when set, page templates render an 'Edit on GitHub' link in the prev/next bar.\",\n ),\n sidebarHeading: z\n .string()\n .default(\"Documentation\")\n .describe(\"Heading shown above the hierarchical sidebar nav.\"),\n showTableOfContents: z\n .boolean()\n .default(true)\n .describe(\"Render the in-page TOC sidebar on doc pages.\"),\n searchPlaceholder: z\n .string()\n .default(\"Search the docs…\")\n .describe(\"Placeholder text for the search input in the masthead.\"),\n});\n\nexport type DocsSettings = z.infer<typeof docsSettingsSchema>;\n","import * as React from \"react\";\n\n/**\n * Docs theme's member-tree 404.\n *\n * Mirrors `DocsNotFound`'s technical voice but tuned for the\n * member context — CTA points at `/members/login` rather than\n * the docs index, and the copy acknowledges stale auth links\n * (the dominant cause of 404s inside `/members/*`).\n *\n * Server component; rendered by `(member)/not-found.tsx` when\n * the active theme is docs and `impl.members.notFound` is\n * declared.\n *\n * Renders a `<div>`, not `<main>`, because the framework's\n * `<ShellWrap surface=\"member\">` already emits the page's\n * `<main className=\"np-member-main\">` landmark.\n */\nexport function DocsMembersNotFound(): React.ReactElement {\n return (\n <div\n className=\"np-docs-members-not-found\"\n style={{\n maxWidth: 520,\n margin: \"5rem auto\",\n padding: \"0 1.5rem\",\n }}\n >\n <p\n style={{\n margin: 0,\n fontSize: \"0.75rem\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.12em\",\n color: \"var(--np-color-muted-foreground)\",\n fontFamily: \"var(--np-font-mono, ui-monospace, monospace)\",\n }}\n >\n 404 · account\n </p>\n <h1\n style={{\n margin: \"0.75rem 0 0\",\n fontSize: \"1.875rem\",\n fontFamily: \"var(--np-font-heading)\",\n fontWeight: 600,\n lineHeight: 1.2,\n }}\n >\n That account link is no longer valid.\n </h1>\n <p\n style={{\n margin: \"1.25rem 0 0\",\n color: \"var(--np-color-muted-foreground)\",\n fontSize: \"0.9375rem\",\n lineHeight: 1.6,\n }}\n >\n Verification and password-reset links are single-use and expire after a\n short window. Open the sign-in page and request a fresh one.\n </p>\n <p style={{ margin: \"1.75rem 0 0\" }}>\n <a\n href=\"/members/login\"\n style={{\n display: \"inline-block\",\n padding: \"0.5rem 1.25rem\",\n borderRadius: \"0.375rem\",\n background: \"var(--np-color-primary)\",\n color: \"var(--np-color-primary-foreground)\",\n textDecoration: \"none\",\n fontSize: \"0.875rem\",\n fontWeight: 500,\n }}\n >\n Go to sign in\n </a>\n </p>\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\n\nimport { DocsHeader } from \"./header.js\";\n\n/**\n * Docs theme's member-tree shell.\n *\n * Drops the docs sidebar (which is hierarchical-doc navigation —\n * useless on auth forms) and renders a narrow column under the\n * masthead. Reuses `DocsHeader` directly so a masthead bump\n * cascades to member pages — single source of truth for chrome.\n *\n * Skips the public `DocsShell`'s 3-column grid because the\n * `<ShellWrap surface=\"member\">` fallback chain only invokes\n * `impl.members.shell` (this component); the public shell never\n * wraps the member tree.\n */\nexport function DocsMembersShell({ children }: { children: ReactNode }) {\n return (\n <div className=\"np-docs np-docs-shell\">\n <DocsHeader />\n <div className=\"np-docs-members\">\n <div className=\"np-docs-members-column\">{children}</div>\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * Phase F.9-B — docs 404.\n *\n * Tighter / less editorial than magazine's; suggests search +\n * homepage as next steps.\n */\nexport function DocsNotFound(): React.ReactElement {\n // `<div>` — (site)/layout.tsx already emits the page's `<main>`.\n return (\n <div\n className=\"np-docs-not-found\"\n style={{\n maxWidth: 560,\n margin: \"5rem auto\",\n padding: \"0 1.5rem\",\n }}\n >\n <p\n style={{\n margin: 0,\n fontSize: \"0.75rem\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n color: \"var(--np-color-muted-foreground)\",\n }}\n >\n 404 — Not found\n </p>\n <h1 style={{ margin: \"0.75rem 0 0.5rem\", fontSize: \"1.75rem\" }}>\n That page isn&apos;t in the docs.\n </h1>\n <p\n style={{\n margin: \"0.75rem 0 1.5rem\",\n color: \"var(--np-color-muted-foreground)\",\n }}\n >\n It may have been renamed or merged into another section. Try the\n search bar in the header, or head to the homepage.\n </p>\n <a\n href=\"/\"\n style={{\n display: \"inline-block\",\n padding: \"0.4rem 1rem\",\n borderRadius: \"0.375rem\",\n background: \"var(--np-color-primary)\",\n color: \"var(--np-color-primary-foreground)\",\n textDecoration: \"none\",\n fontWeight: 500,\n }}\n >\n Homepage\n </a>\n </div>\n );\n}\n","import { findDocuments } from \"@nexpress/core\";\nimport type { NpRouteRenderProps, NpTemplateRenderProps } from \"@nexpress/theme\";\nimport { notFound } from \"next/navigation\";\nimport * as React from \"react\";\n\nimport { DocPageTemplate } from \"../templates/doc-page.js\";\n\n/**\n * Theme route for `/docs/:slug` — looks up a docs collection row\n * and renders it through `DocPageTemplate` (#614).\n *\n * Without this route, the sidebar's `/docs/<slug>` links and the\n * doc template's prev/next links 404 in the reference app — the\n * catch-all only resolves `pages` rows + theme archive routes;\n * arbitrary `docs` collection rows weren't reachable by URL.\n *\n * The lookup is a defensive untyped `findDocuments<DocsRow>`\n * call: the docs collection schema lives in the user's project,\n * not the theme, so we re-declare the minimal shape the template\n * needs (title + body + parent + order) and trust runtime row\n * data to match. Operators who run `theme add\n * @nexpress/theme-docs` get those fields auto-merged into their\n * docs collection by `defineConfig`.\n *\n * Membership / access: same path the catch-all uses for `pages`\n * — `findDocuments` already enforces `access.read` and\n * `community.visibility` so we don't need to gate here.\n */\n\ninterface DocsRow {\n id: string;\n slug: string;\n title: string;\n body?: unknown;\n parent?: string | null;\n order?: number;\n status?: string;\n excerpt?: string;\n}\n\nexport async function DocsDetailRoute({\n params,\n blockCtx,\n}: NpRouteRenderProps): Promise<React.ReactElement> {\n const slug = typeof params.slug === \"string\" ? params.slug : \"\";\n if (!slug) notFound();\n\n const result = await findDocuments<DocsRow>(\"docs\", {\n where: { slug, status: \"published\" },\n limit: 1,\n });\n const doc = result.docs[0];\n if (!doc) notFound();\n\n // `DocPageTemplate`'s prop generic defaults to\n // `Record<string, unknown>` — cast through `unknown` so our\n // narrower `DocsRow` shape (which doesn't carry an index\n // signature) matches the template's contract.\n const templateProps: NpTemplateRenderProps = {\n doc: doc as unknown as Record<string, unknown>,\n blockCtx,\n };\n return <DocPageTemplate {...templateProps} />;\n}\n","import * as React from \"react\";\nimport type { NpTemplateRenderProps } from \"@nexpress/theme\";\nimport { findDocuments, type NpRichTextContent } from \"@nexpress/core\";\nimport { extractHeadingToc, renderRichText } from \"@nexpress/editor/server\";\n\n// Routed via a sibling-depth bridge module (`../toc-scrollspy-\n// bridge.js`) rather than `../components/toc-scrollspy.js`\n// directly: tsup's `external` rule matches the import specifier\n// verbatim, and a parent-relative spec at this depth would\n// preserve `\"../components/...\"` in the bundled `dist/index.js`\n// (escapes dist at consume time). The bridge re-exports from a\n// sibling-depth path that DOES match the external rule, so the\n// final bundle carries `import \"./components/toc-scrollspy.js\"`\n// which resolves cleanly to `dist/components/toc-scrollspy.js`.\n// A package-subpath self-import was tried first but fails\n// during tsup's parallel dts step (the index dts can't see the\n// component's freshly-written .d.ts in time, TS7016).\nimport { TocScrollspy } from \"../toc-scrollspy-bridge.js\";\nimport { resolveDocsSettings } from \"../settings-helpers.js\";\n\ninterface DocDoc {\n id: string;\n slug: string;\n title: string;\n lede?: string;\n body?: NpRichTextContent;\n parent?: string | null;\n order?: number;\n updatedAt?: string | Date;\n publishedAt?: string | Date;\n stableSince?: string;\n readingTime?: number | string;\n}\n\n\n/**\n * Doc page template — three-zone article: header strap\n * (breadcrumbs + h1 + lede + meta pills), Lexical-rendered body,\n * footer (feedback widget + prev/next pair).\n *\n * Breadcrumbs walk the parent chain so a nested doc shows\n * `Docs / Plugins / Author quickstart` without the operator\n * configuring it explicitly. Falls back to a single \"Docs\" entry\n * for root-level pages.\n *\n * Meta pills render only when their data is present:\n *\n * - `stableSince` (e.g. `\"0.1\"`) → green pill `\"Stable since 0.1\"`.\n * - `readingTime` (number or string) → `\"X min read\"` pill.\n * - `updatedAt` → date string after a · separator.\n * - `settings.githubRepo` set → `\"Edit this page →\"` link to GH.\n *\n * Feedback row is static HTML (Yes / Could be better buttons)\n * without a wired endpoint — operators that want a real\n * feedback API drop in their own client island.\n *\n * Prev/next walks the same ordered list the sidebar uses; the\n * doc immediately before / after `current` in render-order wins.\n */\nexport async function DocPageTemplate({\n doc: rawDoc,\n}: NpTemplateRenderProps): Promise<React.ReactElement> {\n const doc = rawDoc as unknown as DocDoc;\n const settings = await resolveDocsSettings();\n const breadcrumbs = await loadBreadcrumbs(doc);\n const navInfo = await loadPrevNext(doc);\n const updatedLabel = formatUpdated(doc.updatedAt ?? doc.publishedAt);\n const readingLabel = readingMinutesLabel(doc.readingTime);\n const editHref = settings.githubRepo\n ? `${settings.githubRepo}/edit/main/docs/${doc.slug}.md`\n : null;\n const toc = extractHeadingToc(doc.body);\n const reportIssueHref = settings.githubRepo\n ? `${settings.githubRepo}/issues/new`\n : null;\n\n return (\n <>\n <article className=\"np-docs-page\">\n <nav className=\"np-docs-breadcrumbs\" aria-label=\"Breadcrumb\">\n {breadcrumbs.map((crumb, index) => {\n const isLast = index === breadcrumbs.length - 1;\n return (\n <React.Fragment key={`crumb-${index.toString()}-${crumb.slug ?? \"root\"}`}>\n {index > 0 ? (\n <span className=\"np-docs-breadcrumbs-sep\" aria-hidden=\"true\">\n /\n </span>\n ) : null}\n {isLast || !crumb.slug ? (\n <span>{crumb.title}</span>\n ) : (\n <a href={`/docs/${crumb.slug}`}>{crumb.title}</a>\n )}\n </React.Fragment>\n );\n })}\n </nav>\n\n <h1>{doc.title}</h1>\n {doc.lede ? <p className=\"np-docs-page-lede\">{doc.lede}</p> : null}\n\n {(doc.stableSince || readingLabel || updatedLabel || editHref) ? (\n <div className=\"np-docs-page-meta\">\n {doc.stableSince ? (\n <span className=\"np-docs-page-meta-pill status\">\n Stable since {doc.stableSince}\n </span>\n ) : null}\n {readingLabel ? (\n <span className=\"np-docs-page-meta-pill\">{readingLabel}</span>\n ) : null}\n {updatedLabel ? (\n <>\n <span className=\"np-docs-page-meta-sep\" aria-hidden=\"true\">\n ·\n </span>\n <span>Updated {updatedLabel}</span>\n </>\n ) : null}\n {editHref ? (\n <a href={editHref} target=\"_blank\" rel=\"noreferrer\">\n Edit this page →\n </a>\n ) : null}\n </div>\n ) : null}\n\n <div className=\"np-docs-page-body\">\n {doc.body ? (\n // Core types `NpRichTextContent` as the opaque\n // `Record<string, unknown>`; the editor's renderer\n // refines it to `{ root: ... }`. Structural cast at\n // the boundary — both sides go through the same\n // Lexical serializer.\n renderRichText(doc.body as unknown as Parameters<typeof renderRichText>[0])\n ) : (\n <p style={{ color: \"var(--np-color-muted-foreground)\" }}>\n No body content yet.\n </p>\n )}\n </div>\n\n <div className=\"np-docs-feedback\">\n <div>\n <div className=\"np-docs-feedback-title\">Was this page helpful?</div>\n <div className=\"np-docs-feedback-helper\">\n Operators wire the feedback endpoint via a plugin or a custom\n client island — the form is intentionally inert in v0.1.\n </div>\n </div>\n <div className=\"np-docs-feedback-buttons\">\n <button type=\"button\">Yes</button>\n <button type=\"button\">Could be better</button>\n </div>\n </div>\n\n <nav className=\"np-docs-prev-next\" aria-label=\"Pagination\">\n {navInfo.prev ? (\n <a\n href={`/docs/${navInfo.prev.slug}`}\n className=\"np-docs-prev-next-prev\"\n >\n <div className=\"np-docs-prev-next-dir\">← Previous</div>\n <div className=\"np-docs-prev-next-title\">{navInfo.prev.title}</div>\n </a>\n ) : (\n <span />\n )}\n {navInfo.next ? (\n <a\n href={`/docs/${navInfo.next.slug}`}\n className=\"np-docs-prev-next-next\"\n >\n <div className=\"np-docs-prev-next-dir\">Next →</div>\n <div className=\"np-docs-prev-next-title\">{navInfo.next.title}</div>\n </a>\n ) : (\n <span />\n )}\n </nav>\n </article>\n\n {toc.length > 0 ? (\n <aside className=\"np-docs-toc\" aria-label=\"On this page\">\n <p className=\"np-docs-toc-eyebrow\">On this page</p>\n <ul>\n {toc.map((entry) => (\n <li\n key={`toc-${entry.id}`}\n style={entry.level === 3 ? { marginLeft: \"0.85rem\" } : undefined}\n >\n <a href={`#${entry.id}`}>{entry.text}</a>\n </li>\n ))}\n </ul>\n <TocScrollspy ids={toc.map((entry) => entry.id)} />\n\n {(editHref || reportIssueHref) ? (\n <div className=\"np-docs-toc-secondary\">\n {editHref ? (\n <a href={editHref} target=\"_blank\" rel=\"noreferrer\">\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n aria-hidden=\"true\"\n >\n <path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\" />\n <path d=\"m18.5 2.5 3 3L12 15l-4 1 1-4 9.5-9.5z\" />\n </svg>\n Edit on GitHub\n </a>\n ) : null}\n {reportIssueHref ? (\n <a href={reportIssueHref} target=\"_blank\" rel=\"noreferrer\">\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\" />\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\n </svg>\n Report an issue\n </a>\n ) : null}\n </div>\n ) : null}\n </aside>\n ) : null}\n </>\n );\n}\n\ninterface Crumb {\n slug: string | null;\n title: string;\n}\n\nasync function loadBreadcrumbs(current: DocDoc): Promise<Crumb[]> {\n const root: Crumb = { slug: null, title: \"Docs\" };\n if (!current.parent) {\n return [root, { slug: null, title: current.title }];\n }\n // Walk parents in a single bounded query — sidebar already\n // pulls the same list so the row count is small.\n const result = await findDocuments<Record<string, unknown>>(\"docs\", {\n where: { status: \"published\" },\n sort: \"order\",\n limit: 500,\n });\n const byId = new Map<string, DocDoc>();\n for (const r of result.docs as unknown as DocDoc[]) {\n if (r.id) byId.set(r.id, r);\n }\n const chain: Crumb[] = [];\n let cursor: string | null = current.parent;\n let safety = 6;\n while (cursor && safety-- > 0) {\n const node = byId.get(cursor);\n if (!node) break;\n chain.unshift({ slug: node.slug, title: node.title });\n cursor = node.parent ?? null;\n }\n return [root, ...chain, { slug: null, title: current.title }];\n}\n\nasync function loadPrevNext(\n current: DocDoc,\n): Promise<{ prev: DocDoc | null; next: DocDoc | null }> {\n const result = await findDocuments<Record<string, unknown>>(\"docs\", {\n where: { status: \"published\" },\n sort: \"order\",\n limit: 500,\n });\n const docs = result.docs as unknown as DocDoc[];\n const idx = docs.findIndex((d) => d.id === current.id);\n if (idx < 0) return { prev: null, next: null };\n return {\n prev: idx > 0 ? docs[idx - 1] ?? null : null,\n next: idx < docs.length - 1 ? docs[idx + 1] ?? null : null,\n };\n}\n\nfunction formatUpdated(value: DocDoc[\"updatedAt\"]): string | null {\n if (!value) return null;\n try {\n const d = typeof value === \"string\" ? new Date(value) : value;\n if (Number.isNaN(d.getTime())) return null;\n return d.toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n });\n } catch {\n return null;\n }\n}\n\nfunction readingMinutesLabel(value: DocDoc[\"readingTime\"]): string | null {\n if (!value && value !== 0) return null;\n if (typeof value === \"number\") return `${value.toString()} min read`;\n return value;\n}\n","// Sibling-depth re-export of the client TocScrollspy component.\n//\n// Why this file exists: `doc-page.tsx` lives at `src/templates/`\n// and needs the client island that lives at\n// `src/components/toc-scrollspy.tsx`. Importing it directly\n// would require `../components/toc-scrollspy.js`, and tsup's\n// `external` rule matches the specifier verbatim — a parent-\n// relative spec gets baked into `dist/index.js` and escapes the\n// dist root at consume time (Turbopack reports `Module not\n// found`).\n//\n// Routing through this bridge moves the externalized import to\n// sibling-depth (`./components/toc-scrollspy.js`) which is what\n// the `dist/` layout expects.\nexport { TocScrollspy } from \"./components/toc-scrollspy.js\";\n","import * as React from \"react\";\nimport type { NpRouteRenderProps } from \"@nexpress/theme\";\nimport { getCollectionConfig, searchCollections } from \"@nexpress/core\";\n\n/**\n * Resolves a search-result URL via the collection's\n * `seo.urlPath` config when available, falling back to\n * `/<collection>/<slug>` convention. Without this, posts (which\n * typically live under `/blog/`) would 404 from search hits.\n * Wrapped in try/catch because `getCollectionConfig` throws for\n * unknown collections — a search adapter that returns rows from\n * a no-longer-registered collection shouldn't crash the page.\n */\nfunction resolveResultUrl(\n collection: string,\n doc: Record<string, unknown>,\n): string {\n try {\n const config = getCollectionConfig(collection);\n const urlPath = config.seo?.urlPath;\n if (typeof urlPath === \"function\") {\n const result = urlPath(doc);\n if (typeof result === \"string\" && result.length > 0) return result;\n }\n } catch {\n // Unknown collection or missing seo config — fall through.\n }\n const slug = typeof doc.slug === \"string\" ? doc.slug : \"\";\n return slug ? `/${collection}/${slug}` : \"#\";\n}\n\n/**\n * Phase F.9-B — `/search` route component.\n *\n * Reads `?q=` from searchParams, runs `searchCollections` (the\n * full-text search API), and renders the hits. Empty query →\n * empty results pane with hint copy. Stresses F.2's route\n * dispatch with a non-collection-walk shape (search is\n * cross-collection by design).\n */\n\nexport async function DocsSearch({\n searchParams,\n}: NpRouteRenderProps): Promise<React.ReactElement> {\n const raw = searchParams.q;\n const query = typeof raw === \"string\" ? raw.trim() : \"\";\n\n if (query.length === 0) {\n return (\n <div className=\"np-docs-search\">\n <h1>Search</h1>\n <p style={{ color: \"var(--np-color-muted-foreground)\" }}>\n Enter a query in the masthead search box to find pages.\n </p>\n </div>\n );\n }\n\n const result = await searchCollections({ q: query, limit: 20 });\n return (\n <div className=\"np-docs-search\">\n <h1>Search results for &ldquo;{query}&rdquo;</h1>\n {result.results.length === 0 ? (\n <p style={{ color: \"var(--np-color-muted-foreground)\" }}>No matches.</p>\n ) : (\n <ul style={{ listStyle: \"none\", padding: 0, margin: \"1.5rem 0 0\" }}>\n {result.results.map((item, i) => {\n const doc = item.doc;\n const slug = typeof doc.slug === \"string\" ? doc.slug : null;\n const title =\n typeof doc.title === \"string\" ? doc.title : (slug ?? \"Untitled\");\n const url = resolveResultUrl(item.collection, doc);\n return (\n <li\n key={`${item.collection}:${(doc.id as string | undefined) ?? i}`}\n style={{\n padding: \"1rem 0\",\n borderBottom: \"1px solid var(--np-color-border)\",\n }}\n >\n <p\n style={{\n margin: 0,\n fontSize: \"0.75rem\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n color: \"var(--np-color-muted-foreground)\",\n }}\n >\n {item.collection}\n </p>\n <h2 style={{ margin: \"0.25rem 0 0.5rem\", fontSize: \"1.125rem\" }}>\n <a\n href={url}\n style={{ color: \"inherit\", textDecoration: \"none\" }}\n >\n {title}\n </a>\n </h2>\n {typeof doc.excerpt === \"string\" ? (\n <p\n style={{\n margin: 0,\n color: \"var(--np-color-muted-foreground)\",\n }}\n >\n {doc.excerpt}\n </p>\n ) : null}\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n","import * as React from \"react\";\nimport type { NpThemeShellProps } from \"@nexpress/theme\";\n\n/**\n * Phase F.9-B — docs theme shell.\n *\n * Body grid: header on top, then a 3-column row of sidebar +\n * main + (optional) TOC. The sidebar slot reads the docs\n * collection hierarchy; main is the page render; TOC is left\n * to the page template (it knows which headings the doc has).\n */\nexport function DocsShell({ children }: NpThemeShellProps): React.ReactElement {\n return (\n <div className=\"np-docs-shell\">\n <div className=\"np-docs-grid\">{children}</div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { findDocuments } from \"@nexpress/core\";\n\nimport { resolveDocsSettings } from \"./settings-helpers.js\";\n\ninterface DocNode {\n id: string;\n slug: string;\n title: string;\n parent: string | null;\n order: number;\n /**\n * Optional small label rendered next to the link\n * (`new` / `beta` / `api`). Renders as a pill via the\n * `.np-docs-sidebar-badge.{value}` selector in styles.ts.\n * Treated as advisory; sites without the field render no\n * badge.\n */\n badge: string | null;\n children: DocNode[];\n}\n\n/**\n * Hierarchical sidebar for the docs theme.\n *\n * Top-level docs (those without a `parent`) become **group\n * eyebrows** rendered with a bullet dot indicator; each\n * group's children are the linkable items under the eyebrow.\n * Deeper levels render as nested lists with a hairline left\n * rule.\n *\n * The current doc is highlighted via `data-current=\"true\"`\n * resolved from the request's pathname. Wired through\n * `next/headers` (`x-np-pathname`) so the highlight survives\n * server rendering with no client-side hydration.\n */\nexport async function DocsSidebar(): Promise<React.ReactElement> {\n const settings = await resolveDocsSettings();\n const currentSlug = await currentPathSlug();\n\n // Pull every doc and assemble the hierarchy. Capped at 500 to\n // keep the query bounded — typical doc sites stay well under.\n const result = await findDocuments<Record<string, unknown>>(\"docs\", {\n where: { status: \"published\" },\n sort: \"order\",\n limit: 500,\n });\n\n const tree = buildTree(result.docs);\n\n if (tree.length === 0) {\n return (\n <aside className=\"np-docs-sidebar\" aria-label=\"Docs navigation\">\n <div className=\"np-docs-sidebar-group\">\n <h2 className=\"np-docs-sidebar-eyebrow\">\n <span className=\"np-docs-sidebar-eyebrow-dot\" aria-hidden=\"true\" />\n {settings.sidebarHeading}\n </h2>\n <p\n style={{\n padding: \"0.34rem 0.6rem\",\n fontSize: \"0.875rem\",\n color: \"var(--np-color-muted-foreground)\",\n margin: 0,\n }}\n >\n No docs yet.\n </p>\n </div>\n </aside>\n );\n }\n\n return (\n <aside className=\"np-docs-sidebar\" aria-label=\"Docs navigation\">\n {tree.map((group) => (\n <div className=\"np-docs-sidebar-group\" key={group.id}>\n <h2 className=\"np-docs-sidebar-eyebrow\">\n <span className=\"np-docs-sidebar-eyebrow-dot\" aria-hidden=\"true\" />\n {group.title}\n </h2>\n {group.children.length > 0 ? (\n <NavTree nodes={group.children} currentSlug={currentSlug} />\n ) : (\n <ul>\n <SidebarLink node={group} currentSlug={currentSlug} />\n </ul>\n )}\n </div>\n ))}\n </aside>\n );\n}\n\ninterface DocRow {\n id: unknown;\n slug: unknown;\n title: unknown;\n parent: unknown;\n order: unknown;\n badge: unknown;\n}\n\nasync function currentPathSlug(): Promise<string | null> {\n try {\n const { headers } = await import(\"next/headers\");\n const list = await headers();\n const pathname = list.get(\"x-np-pathname\");\n if (!pathname) return null;\n const m = /^\\/docs\\/(.+?)\\/?$/.exec(pathname);\n return m ? (m[1] ?? null) : null;\n } catch {\n return null;\n }\n}\n\nfunction buildTree(rawDocs: Record<string, unknown>[]): DocNode[] {\n const docs = rawDocs as unknown as DocRow[];\n const byId = new Map<string, DocNode>();\n // First pass: every doc as a flat node with empty children.\n for (const d of docs) {\n if (typeof d.id !== \"string\") continue;\n if (typeof d.slug !== \"string\") continue;\n byId.set(d.id, {\n id: d.id,\n slug: d.slug,\n title: typeof d.title === \"string\" ? d.title : d.slug,\n parent: typeof d.parent === \"string\" ? d.parent : null,\n order: typeof d.order === \"number\" ? d.order : 0,\n badge: typeof d.badge === \"string\" ? d.badge : null,\n children: [],\n });\n }\n // Second pass: hang each non-root under its parent.\n const roots: DocNode[] = [];\n for (const node of byId.values()) {\n if (node.parent && byId.has(node.parent)) {\n byId.get(node.parent)!.children.push(node);\n } else {\n roots.push(node);\n }\n }\n // Sort by order at every level.\n const sortRec = (list: DocNode[]) => {\n list.sort((a, b) => a.order - b.order);\n for (const n of list) sortRec(n.children);\n };\n sortRec(roots);\n return roots;\n}\n\nfunction NavTree({\n nodes,\n currentSlug,\n}: {\n nodes: DocNode[];\n currentSlug: string | null;\n}): React.ReactElement {\n return (\n <ul>\n {nodes.map((n) => (\n <li key={n.id}>\n <SidebarLink node={n} currentSlug={currentSlug} />\n {n.children.length > 0 ? (\n <NavTree nodes={n.children} currentSlug={currentSlug} />\n ) : null}\n </li>\n ))}\n </ul>\n );\n}\n\nfunction SidebarLink({\n node,\n currentSlug,\n}: {\n node: DocNode;\n currentSlug: string | null;\n}): React.ReactElement {\n const isCurrent = currentSlug !== null && currentSlug === node.slug;\n const badgeClass = node.badge\n ? `np-docs-sidebar-badge ${node.badge.toLowerCase()}`\n : null;\n return (\n <a\n href={`/docs/${node.slug}`}\n data-current={isCurrent ? \"true\" : undefined}\n aria-current={isCurrent ? \"page\" : undefined}\n >\n {node.title}\n {badgeClass ? (\n <span className={badgeClass}>{node.badge!.toUpperCase()}</span>\n ) : null}\n </a>\n );\n}\n","/**\n * `@nexpress/theme-docs` — CSS layout.\n *\n * Three-column reference-docs layout: sticky search-first header,\n * hierarchical sidebar (groups with bullet eyebrows + nested\n * links + status badges), centered article column, on-this-page\n * TOC on the right. Sidebar + TOC collapse out below the\n * tablet / phone breakpoints respectively.\n *\n * Scoped under `.np-docs-*` so a theme swap to another v0.2\n * theme doesn't leave residue. All colors resolve through the\n * `--np-color-*` tokens so admin overrides on top still apply.\n *\n * The terminal-style shell command snippet uses `.np-docs-cmdline`\n * (not `.np-docs-shell`) because `.np-docs-shell` is already\n * claimed by the route shell's root container.\n */\nexport const docsCss = `\n.np-docs-shell {\n display: flex;\n flex-direction: column;\n min-height: 100vh;\n background: var(--np-color-background);\n color: var(--np-color-foreground);\n font-family: var(--np-font-body, \"Geist\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif);\n line-height: 1.6;\n -webkit-font-smoothing: antialiased;\n}\n.np-docs-shell a { color: inherit; }\n.np-docs-shell code,\n.np-docs-shell pre,\n.np-docs-shell kbd {\n font-family: var(--np-font-mono, \"Geist Mono\", ui-monospace, SFMono-Regular, Menlo, monospace);\n}\n\n/* ============================================================\n * Header — sticky bar with brand + version pill, ⌘K search in\n * the center, primary nav + GitHub link on the right. Grid\n * keeps everything anchored regardless of viewport width.\n * ============================================================ */\n.np-docs-header {\n position: sticky;\n top: 0;\n z-index: 30;\n background: color-mix(in oklab, var(--np-color-background) 80%, transparent);\n backdrop-filter: saturate(140%) blur(14px);\n -webkit-backdrop-filter: saturate(140%) blur(14px);\n border-bottom: 1px solid var(--np-color-border);\n}\n.np-docs-header-inner {\n max-width: 1380px;\n margin: 0 auto;\n padding: 0.7rem 1.5rem;\n display: grid;\n grid-template-columns: minmax(220px, 1fr) minmax(0, 2fr) auto;\n gap: 1.5rem;\n align-items: center;\n}\n.np-docs-brand {\n display: inline-flex;\n align-items: center;\n gap: 0.55rem;\n font-weight: 700;\n font-size: 1.0625rem;\n letter-spacing: -0.02em;\n text-decoration: none;\n}\n.np-docs-brand-mark {\n width: 1.55rem;\n height: 1.55rem;\n border-radius: 6px;\n background: linear-gradient(135deg, var(--np-color-primary, #2563eb), #0ea5e9);\n position: relative;\n flex: none;\n}\n.np-docs-brand-mark::after {\n content: \"\";\n position: absolute;\n inset: 5px;\n border-radius: 2px;\n background: var(--np-color-background, #fff);\n opacity: 0.95;\n clip-path: polygon(0 0, 100% 0, 100% 100%, 60% 100%, 0 35%);\n}\n.np-docs-brand-name { font-weight: 700; }\n.np-docs-brand-version {\n font-family: var(--np-font-mono);\n font-size: 0.72rem;\n font-weight: 500;\n color: var(--np-color-primary);\n background: color-mix(in oklab, var(--np-color-primary) 14%, var(--np-color-card));\n padding: 0.15rem 0.45rem;\n border-radius: 5px;\n}\n\n.np-docs-search-form {\n max-width: 520px;\n width: 100%;\n position: relative;\n justify-self: center;\n}\n.np-docs-search-form svg {\n position: absolute;\n top: 50%;\n left: 0.85rem;\n transform: translateY(-50%);\n color: var(--np-color-muted-foreground);\n}\n.np-docs-search-input {\n width: 100%;\n padding: 0.55rem 0.85rem 0.55rem 2.4rem;\n font: inherit;\n font-size: 0.875rem;\n color: var(--np-color-foreground);\n background: var(--np-color-card);\n border: 1px solid var(--np-color-border);\n border-radius: 9px;\n}\n.np-docs-search-input::placeholder {\n color: var(--np-color-muted-foreground);\n}\n.np-docs-search-input:focus {\n outline: none;\n border-color: var(--np-color-primary);\n box-shadow: 0 0 0 3px color-mix(in oklab, var(--np-color-primary) 22%, transparent);\n}\n.np-docs-search-kbd {\n position: absolute;\n right: 0.6rem;\n top: 50%;\n transform: translateY(-50%);\n font-size: 0.7rem;\n padding: 0.1rem 0.4rem;\n color: var(--np-color-muted-foreground);\n border: 1px solid var(--np-color-border);\n border-radius: 4px;\n}\n\n.np-docs-nav {\n display: flex;\n align-items: center;\n gap: 1.25rem;\n}\n.np-docs-primary-nav {\n display: flex;\n list-style: none;\n gap: 1.25rem;\n margin: 0;\n padding: 0;\n}\n.np-docs-primary-nav a {\n color: var(--np-color-muted-foreground);\n font-size: 0.875rem;\n font-weight: 500;\n text-decoration: none;\n}\n.np-docs-primary-nav a:hover,\n.np-docs-primary-nav a[aria-current=\"page\"] {\n color: var(--np-color-foreground);\n}\n.np-docs-github,\n.np-docs-github-link {\n display: inline-flex;\n align-items: center;\n gap: 0.45rem;\n padding: 0.4rem 0.7rem;\n font-size: 0.8125rem;\n color: var(--np-color-muted-foreground);\n background: var(--np-color-muted);\n border: 1px solid var(--np-color-border);\n border-radius: 7px;\n text-decoration: none;\n}\n.np-docs-github:hover,\n.np-docs-github-link:hover {\n color: var(--np-color-foreground);\n}\n\n@media (max-width: 800px) {\n .np-docs-header-inner {\n grid-template-columns: auto 1fr auto;\n gap: 0.75rem;\n }\n .np-docs-search-form { display: none; }\n .np-docs-primary-nav { display: none; }\n}\n\n/* ============================================================\n * 3-column layout: sidebar + article + on-page TOC.\n * ============================================================ */\n.np-docs-grid,\n.np-docs-body {\n max-width: 1380px;\n margin: 0 auto;\n width: 100%;\n display: grid;\n grid-template-columns: 260px minmax(0, 1fr) 220px;\n gap: 3rem;\n padding: 2.25rem 1.5rem 4rem;\n}\n@media (max-width: 1100px) {\n .np-docs-grid,\n .np-docs-body {\n grid-template-columns: 240px minmax(0, 1fr);\n }\n .np-docs-toc { display: none; }\n}\n@media (max-width: 800px) {\n .np-docs-grid,\n .np-docs-body {\n grid-template-columns: 1fr;\n }\n .np-docs-sidebar { display: none; }\n}\n\n/* ============================================================\n * Sidebar — grouped link list with bullet eyebrow + badges.\n * ============================================================ */\n.np-docs-sidebar {\n position: sticky;\n top: 4.25rem;\n align-self: start;\n max-height: calc(100vh - 5rem);\n overflow-y: auto;\n padding-right: 0.5rem;\n}\n.np-docs-sidebar-group { margin-bottom: 1.5rem; }\n.np-docs-sidebar-eyebrow {\n display: flex;\n align-items: center;\n gap: 0.4rem;\n font-family: var(--np-font-mono);\n font-size: 0.7rem;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n color: var(--np-color-muted-foreground);\n margin: 0 0 0.65rem;\n font-weight: 600;\n}\n.np-docs-sidebar-eyebrow-dot {\n width: 0.4rem;\n height: 0.4rem;\n border-radius: 50%;\n background: var(--np-color-primary);\n}\n.np-docs-sidebar ul {\n list-style: none;\n padding: 0;\n margin: 0;\n}\n.np-docs-sidebar li { margin: 0.05rem 0; }\n.np-docs-sidebar a {\n display: block;\n padding: 0.34rem 0.6rem;\n font-size: 0.875rem;\n color: var(--np-color-muted-foreground);\n text-decoration: none;\n border-radius: 6px;\n line-height: 1.35;\n}\n.np-docs-sidebar a:hover {\n background: var(--np-color-muted);\n color: var(--np-color-foreground);\n}\n.np-docs-sidebar a[data-current=\"true\"],\n.np-docs-sidebar a[aria-current=\"page\"] {\n color: var(--np-color-primary);\n background: color-mix(in oklab, var(--np-color-primary) 14%, var(--np-color-card));\n font-weight: 500;\n}\n.np-docs-sidebar ul ul {\n margin-left: 0.5rem;\n padding-left: 0.85rem;\n border-left: 1px solid var(--np-color-border);\n}\n.np-docs-sidebar-badge {\n display: inline-block;\n font-family: var(--np-font-mono);\n font-size: 0.62rem;\n padding: 0.02rem 0.34rem;\n margin-left: 0.4rem;\n vertical-align: 1px;\n border-radius: 4px;\n background: var(--np-color-muted);\n color: var(--np-color-muted-foreground);\n font-weight: 500;\n}\n.np-docs-sidebar-badge.new { background: #dcfce7; color: #166534; }\n.np-docs-sidebar-badge.beta { background: #fef3c7; color: #92400e; }\n.np-docs-sidebar-badge.api {\n background: color-mix(in oklab, var(--np-color-primary) 16%, var(--np-color-card));\n color: var(--np-color-primary);\n}\n\n/* ============================================================\n * Doc page — article column. h1 + lede + meta row + sections\n * with hovered anchor link icon.\n * ============================================================ */\n.np-docs-page {\n max-width: 760px;\n min-width: 0;\n}\n.np-docs-breadcrumbs {\n display: flex;\n align-items: center;\n gap: 0.4rem;\n font-size: 0.8125rem;\n color: var(--np-color-muted-foreground);\n margin-bottom: 1rem;\n}\n.np-docs-breadcrumbs a {\n color: inherit;\n text-decoration: none;\n}\n.np-docs-breadcrumbs a:hover { color: var(--np-color-foreground); }\n.np-docs-breadcrumbs-sep { opacity: 0.5; }\n\n.np-docs-page h1 {\n font-size: clamp(2rem, 3.6vw, 2.5rem);\n font-weight: 700;\n letter-spacing: -0.03em;\n line-height: 1.1;\n margin: 0 0 0.5rem;\n text-wrap: balance;\n}\n.np-docs-page-lede {\n font-size: 1.125rem;\n color: var(--np-color-muted-foreground);\n line-height: 1.55;\n margin: 0 0 2rem;\n max-width: 38rem;\n text-wrap: pretty;\n}\n.np-docs-page-meta {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n align-items: center;\n font-size: 0.8125rem;\n color: var(--np-color-muted-foreground);\n padding: 0.85rem 0;\n margin-bottom: 2rem;\n border-top: 1px solid var(--np-color-border);\n border-bottom: 1px solid var(--np-color-border);\n}\n.np-docs-page-meta-pill {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.15rem 0.55rem;\n font-family: var(--np-font-mono);\n font-size: 0.72rem;\n border: 1px solid var(--np-color-border);\n border-radius: 999px;\n background: var(--np-color-card);\n}\n.np-docs-page-meta-pill.status {\n color: #047857;\n border-color: #bbf7d0;\n background: #f0fdf4;\n}\n.np-docs-page-meta-pill.status::before {\n content: \"\";\n width: 0.4rem;\n height: 0.4rem;\n border-radius: 50%;\n background: #047857;\n}\n.np-docs-page-meta-sep { opacity: 0.4; }\n.np-docs-page-meta a {\n color: var(--np-color-primary);\n text-decoration: none;\n margin-left: auto;\n}\n.np-docs-page-meta a:hover { text-decoration: underline; }\n\n.np-docs-page h2 {\n font-size: 1.5rem;\n font-weight: 600;\n letter-spacing: -0.02em;\n line-height: 1.25;\n margin: 3rem 0 0.85rem;\n scroll-margin-top: 5rem;\n position: relative;\n}\n.np-docs-page h2:first-of-type { margin-top: 2.5rem; }\n.np-docs-page h3 {\n font-size: 1.1rem;\n font-weight: 600;\n letter-spacing: -0.01em;\n margin: 2.25rem 0 0.7rem;\n scroll-margin-top: 5rem;\n position: relative;\n}\n.np-docs-page p { margin: 0 0 1rem; }\n.np-docs-page p code,\n.np-docs-page li code {\n font-size: 0.875em;\n padding: 0.1em 0.35em;\n background: var(--np-color-muted);\n border: 1px solid var(--np-color-border);\n border-radius: 4px;\n}\n.np-docs-page strong { font-weight: 600; }\n.np-docs-page ul,\n.np-docs-page ol {\n margin: 0 0 1rem;\n padding-left: 1.4rem;\n}\n.np-docs-page li { margin: 0.35rem 0; }\n.np-docs-page a:not(.np-docs-prev-next a):not(.np-docs-anchor) {\n color: var(--np-color-primary);\n text-decoration: underline;\n text-underline-offset: 3px;\n text-decoration-thickness: 1px;\n text-decoration-color: color-mix(in oklab, var(--np-color-primary) 45%, transparent);\n}\n.np-docs-page a:not(.np-docs-prev-next a):not(.np-docs-anchor):hover {\n text-decoration-color: currentColor;\n}\n\n/* Anchor icon — visible only on heading hover. */\n.np-docs-anchor {\n position: absolute;\n left: -1.3rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--np-color-muted-foreground);\n opacity: 0;\n text-decoration: none !important;\n font-weight: 400;\n}\n.np-docs-page h2:hover .np-docs-anchor,\n.np-docs-page h3:hover .np-docs-anchor { opacity: 1; }\n\n/* ============================================================\n * Callouts — info (default) / note (indigo) / warn (amber) /\n * danger (red). 3px left rule carries the variant color.\n * ============================================================ */\n.np-docs-callout {\n display: grid;\n grid-template-columns: auto 1fr;\n gap: 0.85rem;\n padding: 1rem 1.15rem;\n border: 1px solid var(--np-color-border);\n border-left: 3px solid var(--np-color-primary);\n border-radius: 8px;\n background: var(--np-color-card);\n margin: 1.25rem 0;\n font-size: 0.95rem;\n line-height: 1.55;\n}\n.np-docs-callout > svg,\n.np-docs-callout-icon {\n width: 1.25rem;\n height: 1.25rem;\n flex-shrink: 0;\n color: var(--np-color-primary);\n margin-top: 0.1rem;\n}\n.np-docs-callout p { margin: 0; }\n.np-docs-callout-title {\n font-weight: 600;\n margin-bottom: 0.15rem;\n color: var(--np-color-foreground);\n}\n.np-docs-callout--warn {\n border-left-color: #b45309;\n background: #fffbeb;\n border-color: #fde68a;\n}\n.np-docs-callout--warn .np-docs-callout-icon,\n.np-docs-callout--warn > svg { color: #b45309; }\n.np-docs-callout--note {\n border-left-color: #6366f1;\n background: #eef2ff;\n border-color: #c7d2fe;\n}\n.np-docs-callout--note .np-docs-callout-icon,\n.np-docs-callout--note > svg { color: #4338ca; }\n.np-docs-callout--danger {\n border-left-color: #b91c1c;\n background: #fef2f2;\n border-color: #fecaca;\n}\n.np-docs-callout--danger .np-docs-callout-icon,\n.np-docs-callout--danger > svg { color: #b91c1c; }\n\n/* ============================================================\n * Code blocks — dark surface with a file-named header and a\n * copy button. Syntax tokens (.tk-*) cover the common slots\n * (keyword / string / function / number / type / punctuation /\n * comment) using a muted neutral-paired palette so the block\n * reads at the same contrast as the page chrome.\n * ============================================================ */\n.np-docs-code {\n margin: 1.25rem 0;\n border-radius: 10px;\n background: #0b1220;\n color: #e6edf6;\n overflow: hidden;\n border: 1px solid #1e2939;\n}\n.np-docs-code-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.55rem 0.85rem;\n background: #0f1a2b;\n border-bottom: 1px solid #1e293b;\n}\n.np-docs-code-file {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n font-family: var(--np-font-mono);\n font-size: 0.78rem;\n color: #94a3b8;\n}\n.np-docs-code-file svg { color: #64748b; }\n.np-docs-code-copy {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.25rem 0.55rem;\n font-size: 0.72rem;\n font-family: var(--np-font-mono);\n color: #94a3b8;\n background: transparent;\n border: 1px solid #1e293b;\n border-radius: 5px;\n cursor: pointer;\n}\n.np-docs-code-copy:hover {\n color: #e2e8f0;\n border-color: #334155;\n}\n.np-docs-code pre {\n margin: 0;\n padding: 1rem 1.1rem;\n font-size: 0.825rem;\n line-height: 1.65;\n overflow-x: auto;\n}\n.np-docs-code pre code {\n display: block;\n font-family: inherit;\n background: transparent;\n border: 0;\n padding: 0;\n color: inherit;\n}\n.tk-c { color: #64748b; font-style: italic; }\n.tk-k { color: #c084fc; }\n.tk-s { color: #86efac; }\n.tk-f { color: #93c5fd; }\n.tk-t { color: #fcd34d; }\n.tk-n { color: #f9a8d4; }\n.tk-p { color: #e2e8f0; }\n\n/* Inline shell snippet — for terse \\`pnpm dev\\` style commands.\n * Named \\`cmdline\\` (not \\`shell\\`) so it doesn't collide with the\n * route shell container at \\`.np-docs-shell\\`. */\n.np-docs-cmdline {\n display: grid;\n grid-template-columns: auto 1fr auto;\n gap: 0.7rem;\n align-items: center;\n padding: 0.75rem 1rem;\n margin: 1.25rem 0;\n background: #0b1220;\n color: #e6edf6;\n border-radius: 9px;\n font-family: var(--np-font-mono);\n font-size: 0.875rem;\n}\n.np-docs-cmdline-prompt { color: #34d399; }\n.np-docs-cmdline-cmd { color: #e2e8f0; }\n.np-docs-cmdline-copy {\n padding: 0.2rem 0.55rem;\n font-size: 0.7rem;\n color: #94a3b8;\n background: transparent;\n border: 1px solid #1e293b;\n border-radius: 5px;\n cursor: pointer;\n}\n.np-docs-cmdline-copy:hover { color: #e2e8f0; border-color: #334155; }\n\n/* ============================================================\n * Numbered steps — counter on a soft pill before each step.\n * ============================================================ */\n.np-docs-steps {\n counter-reset: step;\n list-style: none;\n padding: 0;\n margin: 1.5rem 0;\n display: grid;\n gap: 1rem;\n}\n.np-docs-steps > li {\n counter-increment: step;\n display: grid;\n grid-template-columns: 2.1rem 1fr;\n gap: 0.85rem;\n align-items: start;\n}\n.np-docs-steps > li::before {\n content: counter(step);\n width: 1.85rem;\n height: 1.85rem;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-family: var(--np-font-mono);\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--np-color-primary);\n background: color-mix(in oklab, var(--np-color-primary) 14%, var(--np-color-card));\n border-radius: 50%;\n}\n.np-docs-step-title {\n font-weight: 600;\n margin: 0.25rem 0 0.25rem;\n}\n.np-docs-step-body {\n margin: 0;\n color: var(--np-color-muted-foreground);\n}\n\n/* ============================================================\n * API / reference tables — uppercase mono headers.\n * ============================================================ */\n.np-docs-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.875rem;\n margin: 1.25rem 0;\n}\n.np-docs-table thead { background: var(--np-color-muted); }\n.np-docs-table th,\n.np-docs-table td {\n text-align: left;\n padding: 0.7rem 0.85rem;\n border-bottom: 1px solid var(--np-color-border);\n vertical-align: top;\n}\n.np-docs-table th {\n font-family: var(--np-font-mono);\n font-size: 0.72rem;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--np-color-muted-foreground);\n font-weight: 600;\n}\n.np-docs-table td:first-child code {\n color: var(--np-color-foreground);\n font-weight: 500;\n}\n.np-docs-table-required {\n display: inline-block;\n font-family: var(--np-font-mono);\n font-size: 0.65rem;\n padding: 0.05rem 0.35rem;\n margin-left: 0.4rem;\n background: #fef3c7;\n color: #92400e;\n border-radius: 4px;\n vertical-align: 1px;\n}\n\n/* ============================================================\n * Prev / next — symmetric pair at the foot of every doc page.\n * Hover lifts the bordered card and tints the border primary.\n * ============================================================ */\n.np-docs-prev-next {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 1rem;\n margin: 3.5rem 0 1rem;\n padding-top: 2rem;\n border-top: 1px solid var(--np-color-border);\n}\n.np-docs-prev-next a {\n display: block;\n padding: 1rem 1.15rem;\n background: var(--np-color-card);\n border: 1px solid var(--np-color-border);\n border-radius: 10px;\n text-decoration: none;\n transition: border-color 0.15s ease, transform 0.2s ease;\n}\n.np-docs-prev-next a:hover {\n border-color: var(--np-color-primary);\n transform: translateY(-1px);\n}\n.np-docs-prev-next-dir,\n.np-docs-prev-next-label {\n font-family: var(--np-font-mono);\n font-size: 0.72rem;\n color: var(--np-color-muted-foreground);\n letter-spacing: 0.05em;\n margin-bottom: 0.25rem;\n}\n.np-docs-prev-next-title {\n font-weight: 600;\n font-size: 0.95rem;\n}\n.np-docs-prev-next a.np-docs-prev-next-next,\n.np-docs-prev-next a:last-child { text-align: right; }\n\n/* ============================================================\n * Feedback row — Yes / Could be better buttons under each page.\n * ============================================================ */\n.np-docs-feedback {\n margin-top: 3rem;\n padding: 1.25rem;\n background: var(--np-color-muted);\n border: 1px solid var(--np-color-border);\n border-radius: 10px;\n display: flex;\n gap: 1rem;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n}\n.np-docs-feedback-title { font-weight: 600; font-size: 0.95rem; }\n.np-docs-feedback-helper {\n font-size: 0.825rem;\n color: var(--np-color-muted-foreground);\n margin-top: 0.15rem;\n}\n.np-docs-feedback-buttons {\n display: flex;\n gap: 0.5rem;\n}\n.np-docs-feedback-buttons button {\n padding: 0.4rem 0.85rem;\n font: inherit;\n font-size: 0.825rem;\n background: var(--np-color-card);\n border: 1px solid var(--np-color-border);\n border-radius: 7px;\n cursor: pointer;\n}\n.np-docs-feedback-buttons button:hover {\n border-color: var(--np-color-primary);\n color: var(--np-color-primary);\n}\n\n/* ============================================================\n * On-page TOC — right rail, sticky, current section gets a\n * primary border + soft gradient.\n * ============================================================ */\n.np-docs-toc {\n position: sticky;\n top: 4.25rem;\n align-self: start;\n max-height: calc(100vh - 5rem);\n overflow-y: auto;\n font-size: 0.825rem;\n}\n.np-docs-toc-eyebrow {\n font-family: var(--np-font-mono);\n font-size: 0.7rem;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n color: var(--np-color-muted-foreground);\n margin: 0 0 0.75rem;\n font-weight: 600;\n}\n.np-docs-toc ul {\n list-style: none;\n padding: 0;\n margin: 0;\n}\n.np-docs-toc li { margin: 0.05rem 0; }\n.np-docs-toc a {\n display: block;\n padding: 0.3rem 0.5rem;\n color: var(--np-color-muted-foreground);\n text-decoration: none;\n border-left: 2px solid transparent;\n margin-left: -2px;\n line-height: 1.4;\n}\n.np-docs-toc a:hover { color: var(--np-color-foreground); }\n.np-docs-toc a[data-current=\"true\"],\n.np-docs-toc a[aria-current=\"location\"],\n.np-docs-toc a[aria-current=\"true\"] {\n color: var(--np-color-primary);\n border-left-color: var(--np-color-primary);\n background: linear-gradient(\n to right,\n color-mix(in oklab, var(--np-color-primary) 14%, var(--np-color-card)),\n transparent 80%\n );\n}\n.np-docs-toc ul ul { margin-left: 0.85rem; }\n.np-docs-toc-secondary {\n margin-top: 1.5rem;\n padding-top: 1rem;\n border-top: 1px solid var(--np-color-border);\n}\n.np-docs-toc-secondary a {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.2rem 0;\n border-left: 0;\n margin: 0;\n}\n.np-docs-toc-secondary a:hover { background: transparent; }\n\n/* Empty / not-found surfaces — used by routes/not-found and\n * the docs collection's empty state. */\n.np-docs-empty {\n padding: 4rem 1.5rem;\n text-align: center;\n color: var(--np-color-muted-foreground);\n}\n.np-docs-empty h1 {\n font-size: 1.5rem;\n margin: 0 0 0.5rem;\n color: var(--np-color-foreground);\n}\n`;\n"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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","names":["jsx","jsxs","jsx","jsxs","jsx","jsxs","findDocuments","Fragment","jsx","jsxs","jsx","findDocuments","jsx","jsxs","jsx","findDocuments","jsx","jsxs","findDocuments"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/header.tsx","../src/settings-helpers.ts","../src/settings.ts","../src/members-not-found.tsx","../src/members-shell.tsx","../src/not-found.tsx","../src/routes/doc-detail.tsx","../src/templates/doc-page.tsx","../src/toc-scrollspy-bridge.ts","../src/search.tsx","../src/shell.tsx","../src/sidebar.tsx","../src/styles.ts"],"sourcesContent":["import { defineTheme } from \"@nexpress/theme\";\n\nimport { DocsHeader } from \"./header.js\";\nimport { DocsMembersNotFound } from \"./members-not-found.js\";\nimport { DocsMembersShell } from \"./members-shell.js\";\nimport { DocsNotFound } from \"./not-found.js\";\nimport { DocsDetailRoute } from \"./routes/doc-detail.js\";\nimport { DocsSearch } from \"./search.js\";\nimport { DocsShell } from \"./shell.js\";\nimport { DocsSidebar } from \"./sidebar.js\";\nimport { docsCss } from \"./styles.js\";\nimport { docsSettingsSchema } from \"./settings.js\";\nimport { DocPageTemplate } from \"./templates/doc-page.js\";\n\nconst SEED_NAV = {\n header: [\n { id: \"nav-docs-docs\", label: \"Docs\", type: \"link\" as const, url: \"/docs\" },\n { id: \"nav-docs-reference\", label: \"Reference\", type: \"link\" as const, url: \"/docs/reference\" },\n { id: \"nav-docs-blog\", label: \"Blog\", type: \"link\" as const, url: \"/blog\" },\n ],\n footer: [\n { id: \"nav-docs-footer-docs\", label: \"Documentation\", type: \"link\" as const, url: \"/docs\" },\n { id: \"nav-docs-footer-reference\", label: \"Reference\", type: \"link\" as const, url: \"/docs/reference\" },\n { id: \"nav-docs-footer-changelog\", label: \"Changelog\", type: \"link\" as const, url: \"/changelog\" },\n { id: \"nav-docs-footer-github\", label: \"GitHub\", type: \"link\" as const, url: \"https://github.com\" },\n ],\n};\n\n/**\n * `@nexpress/theme-docs` — documentation theme for NexPress.\n *\n * Three-column reference-docs layout: sticky search-first header\n * (brand mark + version pill + ⌘K search + primary nav + GitHub\n * link), hierarchical sidebar with bullet-eyebrow groups + nested\n * links + status badges, centered article column with breadcrumbs\n * + lede + meta pills + Lexical body, on-this-page TOC on the\n * right. Sidebar collapses out at the tablet breakpoint; TOC\n * collapses out below 1100px.\n *\n * Pairs with `posts` rows of `kind: \"doc\"`\n * (universal-content-model #748 — docs are posts with a kind\n * discriminator, not a separate collection). The doc-specific\n * fields (`lede`, `stableSince`) are contributed via\n * `requires.collections.posts.fields` and merged onto the\n * built-in posts collection at config-resolution time.\n *\n * `seedContent.navigation` ships the primary header / footer\n * links. Doc rows are operator-authored; themes that want to\n * seed kind=\"doc\" content use `seedContent.posts` with the\n * `kind` field set on each entry (see U.1 #749).\n */\nexport const docsTheme = defineTheme({\n manifest: {\n id: \"docs\",\n name: \"Docs\",\n version: \"0.2.0\",\n description:\n \"Documentation theme — three-column layout with hierarchical sidebar, breadcrumbs + lede + meta pills on the article column, on-this-page TOC on the right rail. Blue accent on a near-white surface; pairs with a `docs` collection.\",\n author: { name: \"NexPress\" },\n nexpress: { minVersion: \"0.1.0\" },\n requires: {\n collections: {\n posts: {\n // Universal-content-model #748 — docs are posts with\n // `kind: \"doc\"`. The framework's built-in `posts`\n // collection already supplies `title` / `body` /\n // `parent` (rel→posts) / `order`. Docs theme adds the\n // doc-specific meta pills and contributes the kind\n // option + kinds metadata block for admin / URL\n // routing.\n fields: {\n kind: {\n type: \"select\",\n options: [{ label: \"Doc\", value: \"doc\" }],\n },\n // Short opening paragraph rendered as a lede under\n // the h1. Optional — the article still renders\n // without it. Lives in a \"Docs\" sidebar group with\n // `stableSince`; the group + fields hide entirely\n // when the active kind isn't `\"doc\"`.\n lede: {\n type: \"textarea\",\n hard: false,\n admin: {\n position: \"sidebar\",\n group: \"Docs\",\n condition: { when: \"kind\", equals: \"doc\" },\n },\n },\n // Meta-pill slot — advisory hint the doc-page\n // template surfaces in the strap row. Note: portfolio\n // theme also contributes a `badge: text` field on\n // posts; the merge-requirements union picks the first\n // declarer. Docs reads `doc.badge` regardless of which\n // theme declared the column.\n stableSince: {\n type: \"text\",\n hard: false,\n admin: {\n position: \"sidebar\",\n group: \"Docs\",\n condition: { when: \"kind\", equals: \"doc\" },\n },\n },\n },\n groupMeta: {\n Docs: {\n icon: \"BookOpen\",\n description: \"Doc-specific meta — lede and API stability hint.\",\n },\n },\n kinds: {\n doc: {\n label: \"Doc\",\n labelPlural: \"Documentation\",\n icon: \"BookOpen\",\n // Public-site URL pattern. The catch-all router\n // matches `/docs/<slug>` and queries posts with\n // `where: { kind: \"doc\", slug }`.\n urlPattern: \"/docs/:slug\",\n // Hint to admin: show parent + order controls and\n // render the list as a tree, not a flat table.\n hierarchical: true,\n },\n },\n },\n },\n },\n settingsSchema: docsSettingsSchema,\n },\n impl: {\n shell: DocsShell,\n slots: {\n header: DocsHeader,\n sidebar: DocsSidebar,\n },\n css: docsCss,\n tokens: {\n colors: {\n primary: \"#2563eb\",\n primaryForeground: \"#ffffff\",\n background: \"#fbfcfe\",\n foreground: \"#0c1320\",\n muted: \"#f1f4f9\",\n mutedForeground: \"#5b6478\",\n border: \"#e2e7ef\",\n card: \"#ffffff\",\n },\n typography: {\n fontHeading:\n '\"Geist\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif',\n fontBody:\n '\"Geist\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif',\n fontMono:\n '\"Geist Mono\", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n },\n shape: {\n radiusSm: \"5px\",\n radiusMd: \"9px\",\n radiusLg: \"10px\",\n },\n },\n seedContent: {\n navigation: SEED_NAV,\n },\n templates: {\n // Universal-content-model #748 — docs are posts with\n // `kind: \"doc\"`. The template key matches the kind value so\n // the per-kind template lookup picks this up automatically.\n // Article-kind posts continue rendering through the\n // framework's inline article markup unless the operator\n // declares a `templates.posts.default` of their own.\n posts: {\n doc: {\n label: \"Doc page\",\n description:\n \"Three-column reference layout — breadcrumbs + lede + meta + Lexical body + feedback + prev/next, with the docs sidebar slotted on the left and the on-page TOC on the right.\",\n component: DocPageTemplate,\n },\n },\n },\n routes: [\n // F.2 — docs theme's scoped search route. Lives at\n // `/docs/search` rather than `/search` (#609): the host's\n // reference app has an app-explicit `/search` page route\n // that takes precedence over theme routes per the locked\n // dispatch order (app file > page > theme > plugin). The\n // theme can't override the universal search page, so it\n // scopes its own search to a `/docs/*` namespace and the\n // operator gets both routes: framework `/search` + docs\n // theme `/docs/search`.\n //\n // Order matters: search comes first so `/docs/search` is\n // matched as a literal rather than `{ slug: \"search\" }`\n // by the parametric detail route below (dispatcher is\n // first-match-wins).\n { pattern: \"/docs/search\", component: DocsSearch },\n // Doc detail dispatch. The sidebar + template emit\n // `/docs/<slug>` links; the route component looks up the\n // doc-kind post by slug and renders through DocPageTemplate.\n // Universal-content-model #748 — docs are posts with\n // `kind=\"doc\"`; the lookup filters on kind, not collection.\n { pattern: \"/docs/:slug\", component: DocsDetailRoute },\n ],\n navLocations: {\n primary: {\n label: \"Primary header nav\",\n description: \"Inline links beside the masthead search box.\",\n maxItems: 5,\n },\n },\n notFound: DocsNotFound,\n // M.* adoption (2026-05-11). Docs gains purpose-built member\n // chrome: drops the docs sidebar (hierarchical doc nav is\n // useless on auth forms), keeps the masthead, narrows the\n // content column. Without this, the fallback chain would\n // walk back to `impl.shell` (the 3-column grid) and the\n // sidebar slot would surface alongside an auth form.\n // - `shell`: DocsMembersShell (header + narrow column, no\n // sidebar).\n // - `notFound`: DocsMembersNotFound (stale-auth-link framing\n // with /members/login CTA, monospace accent matching the\n // theme).\n // - `error`: forward-compat type marker; the actual render\n // goes through `./components/members-error`'s client\n // subpath, lazy-imported by\n // `apps/web/src/app/(member)/error.tsx`'s registry\n // (F.7.1 delegation — Next mandates `error.tsx` is \"use\n // client\").\n members: {\n shell: DocsMembersShell,\n notFound: DocsMembersNotFound,\n },\n },\n});\n\nexport {\n DocsHeader,\n DocsShell,\n DocsSidebar,\n DocsNotFound,\n DocsMembersShell,\n DocsMembersNotFound,\n DocsSearch,\n DocPageTemplate,\n};\nexport { docsCss };\nexport { docsSettingsSchema, type DocsSettings } from \"./settings.js\";\n","import * as React from \"react\";\nimport { NavMenu, getCachedSite } from \"@nexpress/next\";\n\nimport { SearchKeyboardShortcut } from \"./components/search-keyboard-shortcut.js\";\nimport { resolveDocsSettings } from \"./settings-helpers.js\";\n\nconst FALLBACK_SITE_NAME = \"NexPress\";\n\n/**\n * Docs theme masthead. Brand strap (mark + wordmark + version\n * pill) on the left, ⌘K search form centered, primary nav +\n * GitHub repo link on the right.\n *\n * Search is a plain GET form to `/docs/search` — the theme's\n * own route handles the query so the host's `(site)/search`\n * page doesn't shadow it (#609). The ⌘K affordance is purely\n * visual hint copy in a `<kbd>`; wiring it to a global hotkey\n * is a separate client island sites can add on top.\n *\n * The GitHub link reads `settings.githubRepo`. When the admin\n * setting is unset, the link is hidden.\n */\nexport async function DocsHeader(): Promise<React.ReactElement> {\n const [settings, site] = await Promise.all([\n resolveDocsSettings(),\n getCachedSite(),\n ]);\n const siteName = site?.name?.trim() || FALLBACK_SITE_NAME;\n return (\n <header className=\"np-docs-header\">\n <div className=\"np-docs-header-inner\">\n <a href=\"/\" className=\"np-docs-brand\">\n <span className=\"np-docs-brand-mark\" aria-hidden=\"true\" />\n <span className=\"np-docs-brand-name\">{siteName}</span>\n <span className=\"np-docs-brand-version\">{settings.version}</span>\n </a>\n <form\n action=\"/docs/search\"\n method=\"get\"\n className=\"np-docs-search-form\"\n role=\"search\"\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n aria-hidden=\"true\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m21 21-4.3-4.3\" />\n </svg>\n <label className=\"sr-only\" htmlFor=\"np-docs-search-input\">\n Search the docs\n </label>\n <input\n id=\"np-docs-search-input\"\n type=\"search\"\n name=\"q\"\n placeholder={settings.searchPlaceholder}\n className=\"np-docs-search-input\"\n />\n <kbd className=\"np-docs-search-kbd\">⌘K</kbd>\n </form>\n <SearchKeyboardShortcut targetId=\"np-docs-search-input\" />\n <nav className=\"np-docs-nav\" aria-label=\"Primary\">\n <NavMenu location=\"primary\" className=\"np-docs-primary-nav\" />\n {settings.githubRepo ? (\n <a\n href={settings.githubRepo}\n className=\"np-docs-github\"\n target=\"_blank\"\n rel=\"noreferrer\"\n aria-label=\"GitHub repository\"\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path d=\"M12 .5a12 12 0 0 0-3.8 23.39c.6.11.82-.26.82-.58v-2c-3.34.73-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.1-.75.08-.74.08-.74 1.21.09 1.85 1.24 1.85 1.24 1.07 1.84 2.81 1.31 3.5 1 .11-.78.42-1.31.76-1.61-2.66-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.12-.3-.54-1.52.12-3.17 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.66 1.65.25 2.87.12 3.17.77.84 1.24 1.91 1.24 3.22 0 4.61-2.81 5.62-5.49 5.92.43.37.81 1.1.81 2.22v3.29c0 .32.22.7.83.58A12 12 0 0 0 12 .5Z\" />\n </svg>\n GitHub\n </a>\n ) : null}\n </nav>\n </div>\n </header>\n );\n}\n","import { getCachedThemeSettings } from \"@nexpress/next\";\n\nimport { docsSettingsSchema, type DocsSettings } from \"./settings.js\";\n\n/**\n * Phase F.9-B / F.9.1-B — typed accessor over the cached theme\n * settings read.\n *\n * Uses `getCachedThemeSettings` so multiple resolveSettings()\n * calls in the same request (header + sidebar + page template +\n * search) share one DB hit via Next's `unstable_cache`. The\n * `nx:theme:<siteId>` tag handles invalidation.\n *\n * On parse failure (theme upgrade changed the shape, etc.)\n * falls back to the schema defaults. The admin's\n * `getThemeSettingsWithStatus` surfaces a banner when this\n * happens; the runtime keeps rendering with safe values.\n */\nexport async function resolveDocsSettings(): Promise<DocsSettings> {\n const raw = await getCachedThemeSettings(\"docs\");\n const parsed = docsSettingsSchema.safeParse(raw);\n if (parsed.success) return parsed.data;\n return docsSettingsSchema.parse({});\n}\n","import { z } from \"zod\";\n\n/**\n * Phase F.9-B — operator-tunable docs settings.\n *\n * Stresses F.3's settings auto-form on a different axis from\n * magazine: more URL inputs, a select/enum for sidebar\n * orientation, and a documentation-flavored field set.\n */\nexport const docsSettingsSchema = z.object({\n version: z\n .string()\n .default(\"v1\")\n .describe(\n \"Currently-displayed version label, shown in the masthead. Update on each release.\",\n ),\n githubRepo: z\n .string()\n .url()\n .optional()\n .describe(\n \"Optional repository URL — when set, page templates render an 'Edit on GitHub' link in the prev/next bar.\",\n ),\n sidebarHeading: z\n .string()\n .default(\"Documentation\")\n .describe(\"Heading shown above the hierarchical sidebar nav.\"),\n showTableOfContents: z\n .boolean()\n .default(true)\n .describe(\"Render the in-page TOC sidebar on doc pages.\"),\n searchPlaceholder: z\n .string()\n .default(\"Search the docs…\")\n .describe(\"Placeholder text for the search input in the masthead.\"),\n});\n\nexport type DocsSettings = z.infer<typeof docsSettingsSchema>;\n","import * as React from \"react\";\n\n/**\n * Docs theme's member-tree 404.\n *\n * Mirrors `DocsNotFound`'s technical voice but tuned for the\n * member context — CTA points at `/members/login` rather than\n * the docs index, and the copy acknowledges stale auth links\n * (the dominant cause of 404s inside `/members/*`).\n *\n * Server component; rendered by `(member)/not-found.tsx` when\n * the active theme is docs and `impl.members.notFound` is\n * declared.\n *\n * Renders a `<div>`, not `<main>`, because the framework's\n * `<ShellWrap surface=\"member\">` already emits the page's\n * `<main className=\"np-member-main\">` landmark.\n */\nexport function DocsMembersNotFound(): React.ReactElement {\n return (\n <div\n className=\"np-docs-members-not-found\"\n style={{\n maxWidth: 520,\n margin: \"5rem auto\",\n padding: \"0 1.5rem\",\n }}\n >\n <p\n style={{\n margin: 0,\n fontSize: \"0.75rem\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.12em\",\n color: \"var(--np-color-muted-foreground)\",\n fontFamily: \"var(--np-font-mono, ui-monospace, monospace)\",\n }}\n >\n 404 · account\n </p>\n <h1\n style={{\n margin: \"0.75rem 0 0\",\n fontSize: \"1.875rem\",\n fontFamily: \"var(--np-font-heading)\",\n fontWeight: 600,\n lineHeight: 1.2,\n }}\n >\n That account link is no longer valid.\n </h1>\n <p\n style={{\n margin: \"1.25rem 0 0\",\n color: \"var(--np-color-muted-foreground)\",\n fontSize: \"0.9375rem\",\n lineHeight: 1.6,\n }}\n >\n Verification and password-reset links are single-use and expire after a\n short window. Open the sign-in page and request a fresh one.\n </p>\n <p style={{ margin: \"1.75rem 0 0\" }}>\n <a\n href=\"/members/login\"\n style={{\n display: \"inline-block\",\n padding: \"0.5rem 1.25rem\",\n borderRadius: \"0.375rem\",\n background: \"var(--np-color-primary)\",\n color: \"var(--np-color-primary-foreground)\",\n textDecoration: \"none\",\n fontSize: \"0.875rem\",\n fontWeight: 500,\n }}\n >\n Go to sign in\n </a>\n </p>\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\n\nimport { DocsHeader } from \"./header.js\";\n\n/**\n * Docs theme's member-tree shell.\n *\n * Drops the docs sidebar (which is hierarchical-doc navigation —\n * useless on auth forms) and renders a narrow column under the\n * masthead. Reuses `DocsHeader` directly so a masthead bump\n * cascades to member pages — single source of truth for chrome.\n *\n * Skips the public `DocsShell`'s 3-column grid because the\n * `<ShellWrap surface=\"member\">` fallback chain only invokes\n * `impl.members.shell` (this component); the public shell never\n * wraps the member tree.\n */\nexport function DocsMembersShell({ children }: { children: ReactNode }) {\n return (\n <div className=\"np-docs np-docs-shell\">\n <DocsHeader />\n <div className=\"np-docs-members\">\n <div className=\"np-docs-members-column\">{children}</div>\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * Phase F.9-B — docs 404.\n *\n * Tighter / less editorial than magazine's; suggests search +\n * homepage as next steps.\n */\nexport function DocsNotFound(): React.ReactElement {\n // `<div>` — (site)/layout.tsx already emits the page's `<main>`.\n return (\n <div\n className=\"np-docs-not-found\"\n style={{\n maxWidth: 560,\n margin: \"5rem auto\",\n padding: \"0 1.5rem\",\n }}\n >\n <p\n style={{\n margin: 0,\n fontSize: \"0.75rem\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n color: \"var(--np-color-muted-foreground)\",\n }}\n >\n 404 — Not found\n </p>\n <h1 style={{ margin: \"0.75rem 0 0.5rem\", fontSize: \"1.75rem\" }}>\n That page isn&apos;t in the docs.\n </h1>\n <p\n style={{\n margin: \"0.75rem 0 1.5rem\",\n color: \"var(--np-color-muted-foreground)\",\n }}\n >\n It may have been renamed or merged into another section. Try the\n search bar in the header, or head to the homepage.\n </p>\n <a\n href=\"/\"\n style={{\n display: \"inline-block\",\n padding: \"0.4rem 1rem\",\n borderRadius: \"0.375rem\",\n background: \"var(--np-color-primary)\",\n color: \"var(--np-color-primary-foreground)\",\n textDecoration: \"none\",\n fontWeight: 500,\n }}\n >\n Homepage\n </a>\n </div>\n );\n}\n","import { findDocuments } from \"@nexpress/core\";\nimport type { NpRouteRenderProps, NpTemplateRenderProps } from \"@nexpress/theme\";\nimport { notFound } from \"next/navigation\";\nimport * as React from \"react\";\n\nimport { DocPageTemplate } from \"../templates/doc-page.js\";\n\n/**\n * Theme route for `/docs/:slug` — looks up a doc-kind post and\n * renders it through `DocPageTemplate`.\n *\n * Universal-content-model #748: docs are posts with `kind=\"doc\"`.\n * The framework's catch-all also matches `/docs/:slug` via the\n * theme's `kinds.doc.urlPattern` metadata; this explicit theme\n * route stays for two reasons:\n *\n * 1. It's the supported path for theme-internal navigation\n * that bypasses the kinds-metadata dispatcher (prev/next,\n * sidebar links).\n * 2. It runs ahead of the kinds dispatcher in the precedence\n * order so a future themes feature that needs to wrap\n * doc-page rendering (e.g. signing-aware drafts) can hook\n * in here without touching the framework.\n *\n * Membership / access: same path the catch-all uses for `pages`\n * — `findDocuments` already enforces `access.read` and\n * `community.visibility` so we don't need to gate here.\n */\n\ninterface DocsRow {\n id: string;\n slug: string;\n title: string;\n body?: unknown;\n parent?: string | null;\n order?: number;\n status?: string;\n excerpt?: string;\n kind?: string;\n}\n\nexport async function DocsDetailRoute({\n params,\n blockCtx,\n}: NpRouteRenderProps): Promise<React.ReactElement> {\n const slug = typeof params.slug === \"string\" ? params.slug : \"\";\n if (!slug) notFound();\n\n const result = await findDocuments<DocsRow>(\"posts\", {\n where: { slug, status: \"published\", kind: \"doc\" },\n limit: 1,\n });\n const doc = result.docs[0];\n if (!doc) notFound();\n\n // `DocPageTemplate`'s prop generic defaults to\n // `Record<string, unknown>` — cast through `unknown` so our\n // narrower `DocsRow` shape (which doesn't carry an index\n // signature) matches the template's contract.\n const templateProps: NpTemplateRenderProps = {\n doc: doc as unknown as Record<string, unknown>,\n blockCtx,\n };\n return <DocPageTemplate {...templateProps} />;\n}\n","import * as React from \"react\";\nimport type { NpTemplateRenderProps } from \"@nexpress/theme\";\nimport { findDocuments, type NpRichTextContent } from \"@nexpress/core\";\nimport { extractHeadingToc, renderRichText } from \"@nexpress/editor/server\";\n\n// Routed via a sibling-depth bridge module (`../toc-scrollspy-\n// bridge.js`) rather than `../components/toc-scrollspy.js`\n// directly: tsup's `external` rule matches the import specifier\n// verbatim, and a parent-relative spec at this depth would\n// preserve `\"../components/...\"` in the bundled `dist/index.js`\n// (escapes dist at consume time). The bridge re-exports from a\n// sibling-depth path that DOES match the external rule, so the\n// final bundle carries `import \"./components/toc-scrollspy.js\"`\n// which resolves cleanly to `dist/components/toc-scrollspy.js`.\n// A package-subpath self-import was tried first but fails\n// during tsup's parallel dts step (the index dts can't see the\n// component's freshly-written .d.ts in time, TS7016).\nimport { TocScrollspy } from \"../toc-scrollspy-bridge.js\";\nimport { resolveDocsSettings } from \"../settings-helpers.js\";\n\ninterface DocDoc {\n id: string;\n slug: string;\n title: string;\n lede?: string;\n body?: NpRichTextContent;\n parent?: string | null;\n order?: number;\n updatedAt?: string | Date;\n publishedAt?: string | Date;\n stableSince?: string;\n readingTime?: number | string;\n}\n\n\n/**\n * Doc page template — three-zone article: header strap\n * (breadcrumbs + h1 + lede + meta pills), Lexical-rendered body,\n * footer (feedback widget + prev/next pair).\n *\n * Breadcrumbs walk the parent chain so a nested doc shows\n * `Docs / Plugins / Author quickstart` without the operator\n * configuring it explicitly. Falls back to a single \"Docs\" entry\n * for root-level pages.\n *\n * Meta pills render only when their data is present:\n *\n * - `stableSince` (e.g. `\"0.1\"`) → green pill `\"Stable since 0.1\"`.\n * - `readingTime` (number or string) → `\"X min read\"` pill.\n * - `updatedAt` → date string after a · separator.\n * - `settings.githubRepo` set → `\"Edit this page →\"` link to GH.\n *\n * Feedback row is static HTML (Yes / Could be better buttons)\n * without a wired endpoint — operators that want a real\n * feedback API drop in their own client island.\n *\n * Prev/next walks the same ordered list the sidebar uses; the\n * doc immediately before / after `current` in render-order wins.\n */\nexport async function DocPageTemplate({\n doc: rawDoc,\n}: NpTemplateRenderProps): Promise<React.ReactElement> {\n const doc = rawDoc as unknown as DocDoc;\n const settings = await resolveDocsSettings();\n const breadcrumbs = await loadBreadcrumbs(doc);\n const navInfo = await loadPrevNext(doc);\n const updatedLabel = formatUpdated(doc.updatedAt ?? doc.publishedAt);\n const readingLabel = readingMinutesLabel(doc.readingTime);\n const editHref = settings.githubRepo\n ? `${settings.githubRepo}/edit/main/docs/${doc.slug}.md`\n : null;\n const toc = extractHeadingToc(doc.body);\n const reportIssueHref = settings.githubRepo\n ? `${settings.githubRepo}/issues/new`\n : null;\n\n return (\n <>\n <article className=\"np-docs-page\">\n <nav className=\"np-docs-breadcrumbs\" aria-label=\"Breadcrumb\">\n {breadcrumbs.map((crumb, index) => {\n const isLast = index === breadcrumbs.length - 1;\n return (\n <React.Fragment key={`crumb-${index.toString()}-${crumb.slug ?? \"root\"}`}>\n {index > 0 ? (\n <span className=\"np-docs-breadcrumbs-sep\" aria-hidden=\"true\">\n /\n </span>\n ) : null}\n {isLast || !crumb.slug ? (\n <span>{crumb.title}</span>\n ) : (\n <a href={`/docs/${crumb.slug}`}>{crumb.title}</a>\n )}\n </React.Fragment>\n );\n })}\n </nav>\n\n <h1>{doc.title}</h1>\n {doc.lede ? <p className=\"np-docs-page-lede\">{doc.lede}</p> : null}\n\n {(doc.stableSince || readingLabel || updatedLabel || editHref) ? (\n <div className=\"np-docs-page-meta\">\n {doc.stableSince ? (\n <span className=\"np-docs-page-meta-pill status\">\n Stable since {doc.stableSince}\n </span>\n ) : null}\n {readingLabel ? (\n <span className=\"np-docs-page-meta-pill\">{readingLabel}</span>\n ) : null}\n {updatedLabel ? (\n <>\n <span className=\"np-docs-page-meta-sep\" aria-hidden=\"true\">\n ·\n </span>\n <span>Updated {updatedLabel}</span>\n </>\n ) : null}\n {editHref ? (\n <a href={editHref} target=\"_blank\" rel=\"noreferrer\">\n Edit this page →\n </a>\n ) : null}\n </div>\n ) : null}\n\n <div className=\"np-docs-page-body\">\n {doc.body ? (\n // Core types `NpRichTextContent` as the opaque\n // `Record<string, unknown>`; the editor's renderer\n // refines it to `{ root: ... }`. Structural cast at\n // the boundary — both sides go through the same\n // Lexical serializer.\n renderRichText(doc.body as unknown as Parameters<typeof renderRichText>[0])\n ) : (\n <p style={{ color: \"var(--np-color-muted-foreground)\" }}>\n No body content yet.\n </p>\n )}\n </div>\n\n <div className=\"np-docs-feedback\">\n <div>\n <div className=\"np-docs-feedback-title\">Was this page helpful?</div>\n <div className=\"np-docs-feedback-helper\">\n Operators wire the feedback endpoint via a plugin or a custom\n client island — the form is intentionally inert in v0.1.\n </div>\n </div>\n <div className=\"np-docs-feedback-buttons\">\n <button type=\"button\">Yes</button>\n <button type=\"button\">Could be better</button>\n </div>\n </div>\n\n <nav className=\"np-docs-prev-next\" aria-label=\"Pagination\">\n {navInfo.prev ? (\n <a\n href={`/docs/${navInfo.prev.slug}`}\n className=\"np-docs-prev-next-prev\"\n >\n <div className=\"np-docs-prev-next-dir\">← Previous</div>\n <div className=\"np-docs-prev-next-title\">{navInfo.prev.title}</div>\n </a>\n ) : (\n <span />\n )}\n {navInfo.next ? (\n <a\n href={`/docs/${navInfo.next.slug}`}\n className=\"np-docs-prev-next-next\"\n >\n <div className=\"np-docs-prev-next-dir\">Next →</div>\n <div className=\"np-docs-prev-next-title\">{navInfo.next.title}</div>\n </a>\n ) : (\n <span />\n )}\n </nav>\n </article>\n\n {toc.length > 0 ? (\n <aside className=\"np-docs-toc\" aria-label=\"On this page\">\n <p className=\"np-docs-toc-eyebrow\">On this page</p>\n <ul>\n {toc.map((entry) => (\n <li\n key={`toc-${entry.id}`}\n style={entry.level === 3 ? { marginLeft: \"0.85rem\" } : undefined}\n >\n <a href={`#${entry.id}`}>{entry.text}</a>\n </li>\n ))}\n </ul>\n <TocScrollspy ids={toc.map((entry) => entry.id)} />\n\n {(editHref || reportIssueHref) ? (\n <div className=\"np-docs-toc-secondary\">\n {editHref ? (\n <a href={editHref} target=\"_blank\" rel=\"noreferrer\">\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n aria-hidden=\"true\"\n >\n <path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\" />\n <path d=\"m18.5 2.5 3 3L12 15l-4 1 1-4 9.5-9.5z\" />\n </svg>\n Edit on GitHub\n </a>\n ) : null}\n {reportIssueHref ? (\n <a href={reportIssueHref} target=\"_blank\" rel=\"noreferrer\">\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\" />\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\n </svg>\n Report an issue\n </a>\n ) : null}\n </div>\n ) : null}\n </aside>\n ) : null}\n </>\n );\n}\n\ninterface Crumb {\n slug: string | null;\n title: string;\n}\n\nasync function loadBreadcrumbs(current: DocDoc): Promise<Crumb[]> {\n const root: Crumb = { slug: null, title: \"Docs\" };\n if (!current.parent) {\n return [root, { slug: null, title: current.title }];\n }\n // Walk parents in a single bounded query — sidebar already\n // pulls the same list so the row count is small.\n const result = await findDocuments<Record<string, unknown>>(\"posts\", {\n where: { status: \"published\", kind: \"doc\" },\n sort: \"order\",\n limit: 500,\n });\n const byId = new Map<string, DocDoc>();\n for (const r of result.docs as unknown as DocDoc[]) {\n if (r.id) byId.set(r.id, r);\n }\n const chain: Crumb[] = [];\n let cursor: string | null = current.parent;\n let safety = 6;\n while (cursor && safety-- > 0) {\n const node = byId.get(cursor);\n if (!node) break;\n chain.unshift({ slug: node.slug, title: node.title });\n cursor = node.parent ?? null;\n }\n return [root, ...chain, { slug: null, title: current.title }];\n}\n\nasync function loadPrevNext(\n current: DocDoc,\n): Promise<{ prev: DocDoc | null; next: DocDoc | null }> {\n const result = await findDocuments<Record<string, unknown>>(\"posts\", {\n where: { status: \"published\", kind: \"doc\" },\n sort: \"order\",\n limit: 500,\n });\n const docs = result.docs as unknown as DocDoc[];\n const idx = docs.findIndex((d) => d.id === current.id);\n if (idx < 0) return { prev: null, next: null };\n return {\n prev: idx > 0 ? docs[idx - 1] ?? null : null,\n next: idx < docs.length - 1 ? docs[idx + 1] ?? null : null,\n };\n}\n\nfunction formatUpdated(value: DocDoc[\"updatedAt\"]): string | null {\n if (!value) return null;\n try {\n const d = typeof value === \"string\" ? new Date(value) : value;\n if (Number.isNaN(d.getTime())) return null;\n return d.toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n });\n } catch {\n return null;\n }\n}\n\nfunction readingMinutesLabel(value: DocDoc[\"readingTime\"]): string | null {\n if (!value && value !== 0) return null;\n if (typeof value === \"number\") return `${value.toString()} min read`;\n return value;\n}\n","// Sibling-depth re-export of the client TocScrollspy component.\n//\n// Why this file exists: `doc-page.tsx` lives at `src/templates/`\n// and needs the client island that lives at\n// `src/components/toc-scrollspy.tsx`. Importing it directly\n// would require `../components/toc-scrollspy.js`, and tsup's\n// `external` rule matches the specifier verbatim — a parent-\n// relative spec gets baked into `dist/index.js` and escapes the\n// dist root at consume time (Turbopack reports `Module not\n// found`).\n//\n// Routing through this bridge moves the externalized import to\n// sibling-depth (`./components/toc-scrollspy.js`) which is what\n// the `dist/` layout expects.\nexport { TocScrollspy } from \"./components/toc-scrollspy.js\";\n","import * as React from \"react\";\nimport type { NpRouteRenderProps } from \"@nexpress/theme\";\nimport { getCollectionConfig, searchCollections } from \"@nexpress/core\";\n\n/**\n * Resolves a search-result URL via the collection's\n * `seo.urlPath` config when available, falling back to\n * `/<collection>/<slug>` convention. Without this, posts (which\n * typically live under `/blog/`) would 404 from search hits.\n * Wrapped in try/catch because `getCollectionConfig` throws for\n * unknown collections — a search adapter that returns rows from\n * a no-longer-registered collection shouldn't crash the page.\n */\nfunction resolveResultUrl(\n collection: string,\n doc: Record<string, unknown>,\n): string {\n try {\n const config = getCollectionConfig(collection);\n const urlPath = config.seo?.urlPath;\n if (typeof urlPath === \"function\") {\n const result = urlPath(doc);\n if (typeof result === \"string\" && result.length > 0) return result;\n }\n } catch {\n // Unknown collection or missing seo config — fall through.\n }\n const slug = typeof doc.slug === \"string\" ? doc.slug : \"\";\n return slug ? `/${collection}/${slug}` : \"#\";\n}\n\n/**\n * Phase F.9-B — `/search` route component.\n *\n * Reads `?q=` from searchParams, runs `searchCollections` (the\n * full-text search API), and renders the hits. Empty query →\n * empty results pane with hint copy. Stresses F.2's route\n * dispatch with a non-collection-walk shape (search is\n * cross-collection by design).\n */\n\nexport async function DocsSearch({\n searchParams,\n}: NpRouteRenderProps): Promise<React.ReactElement> {\n const raw = searchParams.q;\n const query = typeof raw === \"string\" ? raw.trim() : \"\";\n\n if (query.length === 0) {\n return (\n <div className=\"np-docs-search\">\n <h1>Search</h1>\n <p style={{ color: \"var(--np-color-muted-foreground)\" }}>\n Enter a query in the masthead search box to find pages.\n </p>\n </div>\n );\n }\n\n const result = await searchCollections({ q: query, limit: 20 });\n return (\n <div className=\"np-docs-search\">\n <h1>Search results for &ldquo;{query}&rdquo;</h1>\n {result.results.length === 0 ? (\n <p style={{ color: \"var(--np-color-muted-foreground)\" }}>No matches.</p>\n ) : (\n <ul style={{ listStyle: \"none\", padding: 0, margin: \"1.5rem 0 0\" }}>\n {result.results.map((item, i) => {\n const doc = item.doc;\n const slug = typeof doc.slug === \"string\" ? doc.slug : null;\n const title =\n typeof doc.title === \"string\" ? doc.title : (slug ?? \"Untitled\");\n const url = resolveResultUrl(item.collection, doc);\n return (\n <li\n key={`${item.collection}:${(doc.id as string | undefined) ?? i}`}\n style={{\n padding: \"1rem 0\",\n borderBottom: \"1px solid var(--np-color-border)\",\n }}\n >\n <p\n style={{\n margin: 0,\n fontSize: \"0.75rem\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n color: \"var(--np-color-muted-foreground)\",\n }}\n >\n {item.collection}\n </p>\n <h2 style={{ margin: \"0.25rem 0 0.5rem\", fontSize: \"1.125rem\" }}>\n <a\n href={url}\n style={{ color: \"inherit\", textDecoration: \"none\" }}\n >\n {title}\n </a>\n </h2>\n {typeof doc.excerpt === \"string\" ? (\n <p\n style={{\n margin: 0,\n color: \"var(--np-color-muted-foreground)\",\n }}\n >\n {doc.excerpt}\n </p>\n ) : null}\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n","import * as React from \"react\";\nimport type { NpThemeShellProps } from \"@nexpress/theme\";\n\n/**\n * Phase F.9-B — docs theme shell.\n *\n * Body grid: header on top, then a 3-column row of sidebar +\n * main + (optional) TOC. The sidebar slot reads the docs\n * collection hierarchy; main is the page render; TOC is left\n * to the page template (it knows which headings the doc has).\n */\nexport function DocsShell({ children }: NpThemeShellProps): React.ReactElement {\n return (\n <div className=\"np-docs-shell\">\n <div className=\"np-docs-grid\">{children}</div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { findDocuments } from \"@nexpress/core\";\n\nimport { resolveDocsSettings } from \"./settings-helpers.js\";\n\ninterface DocNode {\n id: string;\n slug: string;\n title: string;\n parent: string | null;\n order: number;\n /**\n * Optional small label rendered next to the link\n * (`new` / `beta` / `api`). Renders as a pill via the\n * `.np-docs-sidebar-badge.{value}` selector in styles.ts.\n * Treated as advisory; sites without the field render no\n * badge.\n */\n badge: string | null;\n children: DocNode[];\n}\n\n/**\n * Hierarchical sidebar for the docs theme.\n *\n * Top-level docs (those without a `parent`) become **group\n * eyebrows** rendered with a bullet dot indicator; each\n * group's children are the linkable items under the eyebrow.\n * Deeper levels render as nested lists with a hairline left\n * rule.\n *\n * The current doc is highlighted via `data-current=\"true\"`\n * resolved from the request's pathname. Wired through\n * `next/headers` (`x-np-pathname`) so the highlight survives\n * server rendering with no client-side hydration.\n */\nexport async function DocsSidebar(): Promise<React.ReactElement> {\n const settings = await resolveDocsSettings();\n const currentSlug = await currentPathSlug();\n\n // Pull every doc and assemble the hierarchy. Capped at 500 to\n // keep the query bounded — typical doc sites stay well under.\n // Universal-content-model #748: docs are posts with kind=\"doc\".\n const result = await findDocuments<Record<string, unknown>>(\"posts\", {\n where: { status: \"published\", kind: \"doc\" },\n sort: \"order\",\n limit: 500,\n });\n\n const tree = buildTree(result.docs);\n\n if (tree.length === 0) {\n return (\n <aside className=\"np-docs-sidebar\" aria-label=\"Docs navigation\">\n <div className=\"np-docs-sidebar-group\">\n <h2 className=\"np-docs-sidebar-eyebrow\">\n <span className=\"np-docs-sidebar-eyebrow-dot\" aria-hidden=\"true\" />\n {settings.sidebarHeading}\n </h2>\n <p\n style={{\n padding: \"0.34rem 0.6rem\",\n fontSize: \"0.875rem\",\n color: \"var(--np-color-muted-foreground)\",\n margin: 0,\n }}\n >\n No docs yet.\n </p>\n </div>\n </aside>\n );\n }\n\n return (\n <aside className=\"np-docs-sidebar\" aria-label=\"Docs navigation\">\n {tree.map((group) => (\n <div className=\"np-docs-sidebar-group\" key={group.id}>\n <h2 className=\"np-docs-sidebar-eyebrow\">\n <span className=\"np-docs-sidebar-eyebrow-dot\" aria-hidden=\"true\" />\n {group.title}\n </h2>\n {group.children.length > 0 ? (\n <NavTree nodes={group.children} currentSlug={currentSlug} />\n ) : (\n <ul>\n <SidebarLink node={group} currentSlug={currentSlug} />\n </ul>\n )}\n </div>\n ))}\n </aside>\n );\n}\n\ninterface DocRow {\n id: unknown;\n slug: unknown;\n title: unknown;\n parent: unknown;\n order: unknown;\n badge: unknown;\n}\n\nasync function currentPathSlug(): Promise<string | null> {\n try {\n const { headers } = await import(\"next/headers\");\n const list = await headers();\n const pathname = list.get(\"x-np-pathname\");\n if (!pathname) return null;\n const m = /^\\/docs\\/(.+?)\\/?$/.exec(pathname);\n return m ? (m[1] ?? null) : null;\n } catch {\n return null;\n }\n}\n\nfunction buildTree(rawDocs: Record<string, unknown>[]): DocNode[] {\n const docs = rawDocs as unknown as DocRow[];\n const byId = new Map<string, DocNode>();\n // First pass: every doc as a flat node with empty children.\n for (const d of docs) {\n if (typeof d.id !== \"string\") continue;\n if (typeof d.slug !== \"string\") continue;\n byId.set(d.id, {\n id: d.id,\n slug: d.slug,\n title: typeof d.title === \"string\" ? d.title : d.slug,\n parent: typeof d.parent === \"string\" ? d.parent : null,\n order: typeof d.order === \"number\" ? d.order : 0,\n badge: typeof d.badge === \"string\" ? d.badge : null,\n children: [],\n });\n }\n // Second pass: hang each non-root under its parent.\n const roots: DocNode[] = [];\n for (const node of byId.values()) {\n if (node.parent && byId.has(node.parent)) {\n byId.get(node.parent)!.children.push(node);\n } else {\n roots.push(node);\n }\n }\n // Sort by order at every level.\n const sortRec = (list: DocNode[]) => {\n list.sort((a, b) => a.order - b.order);\n for (const n of list) sortRec(n.children);\n };\n sortRec(roots);\n return roots;\n}\n\nfunction NavTree({\n nodes,\n currentSlug,\n}: {\n nodes: DocNode[];\n currentSlug: string | null;\n}): React.ReactElement {\n return (\n <ul>\n {nodes.map((n) => (\n <li key={n.id}>\n <SidebarLink node={n} currentSlug={currentSlug} />\n {n.children.length > 0 ? (\n <NavTree nodes={n.children} currentSlug={currentSlug} />\n ) : null}\n </li>\n ))}\n </ul>\n );\n}\n\nfunction SidebarLink({\n node,\n currentSlug,\n}: {\n node: DocNode;\n currentSlug: string | null;\n}): React.ReactElement {\n const isCurrent = currentSlug !== null && currentSlug === node.slug;\n const badgeClass = node.badge\n ? `np-docs-sidebar-badge ${node.badge.toLowerCase()}`\n : null;\n return (\n <a\n href={`/docs/${node.slug}`}\n data-current={isCurrent ? \"true\" : undefined}\n aria-current={isCurrent ? \"page\" : undefined}\n >\n {node.title}\n {badgeClass ? (\n <span className={badgeClass}>{node.badge!.toUpperCase()}</span>\n ) : null}\n </a>\n );\n}\n","/**\n * `@nexpress/theme-docs` — CSS layout.\n *\n * Three-column reference-docs layout: sticky search-first header,\n * hierarchical sidebar (groups with bullet eyebrows + nested\n * links + status badges), centered article column, on-this-page\n * TOC on the right. Sidebar + TOC collapse out below the\n * tablet / phone breakpoints respectively.\n *\n * Scoped under `.np-docs-*` so a theme swap to another v0.2\n * theme doesn't leave residue. All colors resolve through the\n * `--np-color-*` tokens so admin overrides on top still apply.\n *\n * The terminal-style shell command snippet uses `.np-docs-cmdline`\n * (not `.np-docs-shell`) because `.np-docs-shell` is already\n * claimed by the route shell's root container.\n */\nexport const docsCss = `\n.np-docs-shell {\n display: flex;\n flex-direction: column;\n min-height: 100vh;\n background: var(--np-color-background);\n color: var(--np-color-foreground);\n font-family: var(--np-font-body, \"Geist\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif);\n line-height: 1.6;\n -webkit-font-smoothing: antialiased;\n}\n.np-docs-shell a { color: inherit; }\n.np-docs-shell code,\n.np-docs-shell pre,\n.np-docs-shell kbd {\n font-family: var(--np-font-mono, \"Geist Mono\", ui-monospace, SFMono-Regular, Menlo, monospace);\n}\n\n/* ============================================================\n * Header — sticky bar with brand + version pill, ⌘K search in\n * the center, primary nav + GitHub link on the right. Grid\n * keeps everything anchored regardless of viewport width.\n * ============================================================ */\n.np-docs-header {\n position: sticky;\n top: 0;\n z-index: 30;\n background: color-mix(in oklab, var(--np-color-background) 80%, transparent);\n backdrop-filter: saturate(140%) blur(14px);\n -webkit-backdrop-filter: saturate(140%) blur(14px);\n border-bottom: 1px solid var(--np-color-border);\n}\n.np-docs-header-inner {\n max-width: 1380px;\n margin: 0 auto;\n padding: 0.7rem 1.5rem;\n display: grid;\n grid-template-columns: minmax(220px, 1fr) minmax(0, 2fr) auto;\n gap: 1.5rem;\n align-items: center;\n}\n.np-docs-brand {\n display: inline-flex;\n align-items: center;\n gap: 0.55rem;\n font-weight: 700;\n font-size: 1.0625rem;\n letter-spacing: -0.02em;\n text-decoration: none;\n}\n.np-docs-brand-mark {\n width: 1.55rem;\n height: 1.55rem;\n border-radius: 6px;\n background: linear-gradient(135deg, var(--np-color-primary, #2563eb), #0ea5e9);\n position: relative;\n flex: none;\n}\n.np-docs-brand-mark::after {\n content: \"\";\n position: absolute;\n inset: 5px;\n border-radius: 2px;\n background: var(--np-color-background, #fff);\n opacity: 0.95;\n clip-path: polygon(0 0, 100% 0, 100% 100%, 60% 100%, 0 35%);\n}\n.np-docs-brand-name { font-weight: 700; }\n.np-docs-brand-version {\n font-family: var(--np-font-mono);\n font-size: 0.72rem;\n font-weight: 500;\n color: var(--np-color-primary);\n background: color-mix(in oklab, var(--np-color-primary) 14%, var(--np-color-card));\n padding: 0.15rem 0.45rem;\n border-radius: 5px;\n}\n\n.np-docs-search-form {\n max-width: 520px;\n width: 100%;\n position: relative;\n justify-self: center;\n}\n.np-docs-search-form svg {\n position: absolute;\n top: 50%;\n left: 0.85rem;\n transform: translateY(-50%);\n color: var(--np-color-muted-foreground);\n}\n.np-docs-search-input {\n width: 100%;\n padding: 0.55rem 0.85rem 0.55rem 2.4rem;\n font: inherit;\n font-size: 0.875rem;\n color: var(--np-color-foreground);\n background: var(--np-color-card);\n border: 1px solid var(--np-color-border);\n border-radius: 9px;\n}\n.np-docs-search-input::placeholder {\n color: var(--np-color-muted-foreground);\n}\n.np-docs-search-input:focus {\n outline: none;\n border-color: var(--np-color-primary);\n box-shadow: 0 0 0 3px color-mix(in oklab, var(--np-color-primary) 22%, transparent);\n}\n.np-docs-search-kbd {\n position: absolute;\n right: 0.6rem;\n top: 50%;\n transform: translateY(-50%);\n font-size: 0.7rem;\n padding: 0.1rem 0.4rem;\n color: var(--np-color-muted-foreground);\n border: 1px solid var(--np-color-border);\n border-radius: 4px;\n}\n\n.np-docs-nav {\n display: flex;\n align-items: center;\n gap: 1.25rem;\n}\n.np-docs-primary-nav {\n display: flex;\n list-style: none;\n gap: 1.25rem;\n margin: 0;\n padding: 0;\n}\n.np-docs-primary-nav a {\n color: var(--np-color-muted-foreground);\n font-size: 0.875rem;\n font-weight: 500;\n text-decoration: none;\n}\n.np-docs-primary-nav a:hover,\n.np-docs-primary-nav a[aria-current=\"page\"] {\n color: var(--np-color-foreground);\n}\n.np-docs-github,\n.np-docs-github-link {\n display: inline-flex;\n align-items: center;\n gap: 0.45rem;\n padding: 0.4rem 0.7rem;\n font-size: 0.8125rem;\n color: var(--np-color-muted-foreground);\n background: var(--np-color-muted);\n border: 1px solid var(--np-color-border);\n border-radius: 7px;\n text-decoration: none;\n}\n.np-docs-github:hover,\n.np-docs-github-link:hover {\n color: var(--np-color-foreground);\n}\n\n@media (max-width: 800px) {\n .np-docs-header-inner {\n grid-template-columns: auto 1fr auto;\n gap: 0.75rem;\n }\n .np-docs-search-form { display: none; }\n .np-docs-primary-nav { display: none; }\n}\n\n/* ============================================================\n * 3-column layout: sidebar + article + on-page TOC.\n * ============================================================ */\n.np-docs-grid,\n.np-docs-body {\n max-width: 1380px;\n margin: 0 auto;\n width: 100%;\n display: grid;\n grid-template-columns: 260px minmax(0, 1fr) 220px;\n gap: 3rem;\n padding: 2.25rem 1.5rem 4rem;\n}\n@media (max-width: 1100px) {\n .np-docs-grid,\n .np-docs-body {\n grid-template-columns: 240px minmax(0, 1fr);\n }\n .np-docs-toc { display: none; }\n}\n@media (max-width: 800px) {\n .np-docs-grid,\n .np-docs-body {\n grid-template-columns: 1fr;\n }\n .np-docs-sidebar { display: none; }\n}\n\n/* ============================================================\n * Sidebar — grouped link list with bullet eyebrow + badges.\n * ============================================================ */\n.np-docs-sidebar {\n position: sticky;\n top: 4.25rem;\n align-self: start;\n max-height: calc(100vh - 5rem);\n overflow-y: auto;\n padding-right: 0.5rem;\n}\n.np-docs-sidebar-group { margin-bottom: 1.5rem; }\n.np-docs-sidebar-eyebrow {\n display: flex;\n align-items: center;\n gap: 0.4rem;\n font-family: var(--np-font-mono);\n font-size: 0.7rem;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n color: var(--np-color-muted-foreground);\n margin: 0 0 0.65rem;\n font-weight: 600;\n}\n.np-docs-sidebar-eyebrow-dot {\n width: 0.4rem;\n height: 0.4rem;\n border-radius: 50%;\n background: var(--np-color-primary);\n}\n.np-docs-sidebar ul {\n list-style: none;\n padding: 0;\n margin: 0;\n}\n.np-docs-sidebar li { margin: 0.05rem 0; }\n.np-docs-sidebar a {\n display: block;\n padding: 0.34rem 0.6rem;\n font-size: 0.875rem;\n color: var(--np-color-muted-foreground);\n text-decoration: none;\n border-radius: 6px;\n line-height: 1.35;\n}\n.np-docs-sidebar a:hover {\n background: var(--np-color-muted);\n color: var(--np-color-foreground);\n}\n.np-docs-sidebar a[data-current=\"true\"],\n.np-docs-sidebar a[aria-current=\"page\"] {\n color: var(--np-color-primary);\n background: color-mix(in oklab, var(--np-color-primary) 14%, var(--np-color-card));\n font-weight: 500;\n}\n.np-docs-sidebar ul ul {\n margin-left: 0.5rem;\n padding-left: 0.85rem;\n border-left: 1px solid var(--np-color-border);\n}\n.np-docs-sidebar-badge {\n display: inline-block;\n font-family: var(--np-font-mono);\n font-size: 0.62rem;\n padding: 0.02rem 0.34rem;\n margin-left: 0.4rem;\n vertical-align: 1px;\n border-radius: 4px;\n background: var(--np-color-muted);\n color: var(--np-color-muted-foreground);\n font-weight: 500;\n}\n.np-docs-sidebar-badge.new { background: #dcfce7; color: #166534; }\n.np-docs-sidebar-badge.beta { background: #fef3c7; color: #92400e; }\n.np-docs-sidebar-badge.api {\n background: color-mix(in oklab, var(--np-color-primary) 16%, var(--np-color-card));\n color: var(--np-color-primary);\n}\n\n/* ============================================================\n * Doc page — article column. h1 + lede + meta row + sections\n * with hovered anchor link icon.\n * ============================================================ */\n.np-docs-page {\n max-width: 760px;\n min-width: 0;\n}\n.np-docs-breadcrumbs {\n display: flex;\n align-items: center;\n gap: 0.4rem;\n font-size: 0.8125rem;\n color: var(--np-color-muted-foreground);\n margin-bottom: 1rem;\n}\n.np-docs-breadcrumbs a {\n color: inherit;\n text-decoration: none;\n}\n.np-docs-breadcrumbs a:hover { color: var(--np-color-foreground); }\n.np-docs-breadcrumbs-sep { opacity: 0.5; }\n\n.np-docs-page h1 {\n font-size: clamp(2rem, 3.6vw, 2.5rem);\n font-weight: 700;\n letter-spacing: -0.03em;\n line-height: 1.1;\n margin: 0 0 0.5rem;\n text-wrap: balance;\n}\n.np-docs-page-lede {\n font-size: 1.125rem;\n color: var(--np-color-muted-foreground);\n line-height: 1.55;\n margin: 0 0 2rem;\n max-width: 38rem;\n text-wrap: pretty;\n}\n.np-docs-page-meta {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n align-items: center;\n font-size: 0.8125rem;\n color: var(--np-color-muted-foreground);\n padding: 0.85rem 0;\n margin-bottom: 2rem;\n border-top: 1px solid var(--np-color-border);\n border-bottom: 1px solid var(--np-color-border);\n}\n.np-docs-page-meta-pill {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.15rem 0.55rem;\n font-family: var(--np-font-mono);\n font-size: 0.72rem;\n border: 1px solid var(--np-color-border);\n border-radius: 999px;\n background: var(--np-color-card);\n}\n.np-docs-page-meta-pill.status {\n color: #047857;\n border-color: #bbf7d0;\n background: #f0fdf4;\n}\n.np-docs-page-meta-pill.status::before {\n content: \"\";\n width: 0.4rem;\n height: 0.4rem;\n border-radius: 50%;\n background: #047857;\n}\n.np-docs-page-meta-sep { opacity: 0.4; }\n.np-docs-page-meta a {\n color: var(--np-color-primary);\n text-decoration: none;\n margin-left: auto;\n}\n.np-docs-page-meta a:hover { text-decoration: underline; }\n\n.np-docs-page h2 {\n font-size: 1.5rem;\n font-weight: 600;\n letter-spacing: -0.02em;\n line-height: 1.25;\n margin: 3rem 0 0.85rem;\n scroll-margin-top: 5rem;\n position: relative;\n}\n.np-docs-page h2:first-of-type { margin-top: 2.5rem; }\n.np-docs-page h3 {\n font-size: 1.1rem;\n font-weight: 600;\n letter-spacing: -0.01em;\n margin: 2.25rem 0 0.7rem;\n scroll-margin-top: 5rem;\n position: relative;\n}\n.np-docs-page p { margin: 0 0 1rem; }\n.np-docs-page p code,\n.np-docs-page li code {\n font-size: 0.875em;\n padding: 0.1em 0.35em;\n background: var(--np-color-muted);\n border: 1px solid var(--np-color-border);\n border-radius: 4px;\n}\n.np-docs-page strong { font-weight: 600; }\n.np-docs-page ul,\n.np-docs-page ol {\n margin: 0 0 1rem;\n padding-left: 1.4rem;\n}\n.np-docs-page li { margin: 0.35rem 0; }\n.np-docs-page a:not(.np-docs-prev-next a):not(.np-docs-anchor) {\n color: var(--np-color-primary);\n text-decoration: underline;\n text-underline-offset: 3px;\n text-decoration-thickness: 1px;\n text-decoration-color: color-mix(in oklab, var(--np-color-primary) 45%, transparent);\n}\n.np-docs-page a:not(.np-docs-prev-next a):not(.np-docs-anchor):hover {\n text-decoration-color: currentColor;\n}\n\n/* Anchor icon — visible only on heading hover. */\n.np-docs-anchor {\n position: absolute;\n left: -1.3rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--np-color-muted-foreground);\n opacity: 0;\n text-decoration: none !important;\n font-weight: 400;\n}\n.np-docs-page h2:hover .np-docs-anchor,\n.np-docs-page h3:hover .np-docs-anchor { opacity: 1; }\n\n/* ============================================================\n * Callouts — info (default) / note (indigo) / warn (amber) /\n * danger (red). 3px left rule carries the variant color.\n * ============================================================ */\n.np-docs-callout {\n display: grid;\n grid-template-columns: auto 1fr;\n gap: 0.85rem;\n padding: 1rem 1.15rem;\n border: 1px solid var(--np-color-border);\n border-left: 3px solid var(--np-color-primary);\n border-radius: 8px;\n background: var(--np-color-card);\n margin: 1.25rem 0;\n font-size: 0.95rem;\n line-height: 1.55;\n}\n.np-docs-callout > svg,\n.np-docs-callout-icon {\n width: 1.25rem;\n height: 1.25rem;\n flex-shrink: 0;\n color: var(--np-color-primary);\n margin-top: 0.1rem;\n}\n.np-docs-callout p { margin: 0; }\n.np-docs-callout-title {\n font-weight: 600;\n margin-bottom: 0.15rem;\n color: var(--np-color-foreground);\n}\n.np-docs-callout--warn {\n border-left-color: #b45309;\n background: #fffbeb;\n border-color: #fde68a;\n}\n.np-docs-callout--warn .np-docs-callout-icon,\n.np-docs-callout--warn > svg { color: #b45309; }\n.np-docs-callout--note {\n border-left-color: #6366f1;\n background: #eef2ff;\n border-color: #c7d2fe;\n}\n.np-docs-callout--note .np-docs-callout-icon,\n.np-docs-callout--note > svg { color: #4338ca; }\n.np-docs-callout--danger {\n border-left-color: #b91c1c;\n background: #fef2f2;\n border-color: #fecaca;\n}\n.np-docs-callout--danger .np-docs-callout-icon,\n.np-docs-callout--danger > svg { color: #b91c1c; }\n\n/* ============================================================\n * Code blocks — dark surface with a file-named header and a\n * copy button. Syntax tokens (.tk-*) cover the common slots\n * (keyword / string / function / number / type / punctuation /\n * comment) using a muted neutral-paired palette so the block\n * reads at the same contrast as the page chrome.\n * ============================================================ */\n.np-docs-code {\n margin: 1.25rem 0;\n border-radius: 10px;\n background: #0b1220;\n color: #e6edf6;\n overflow: hidden;\n border: 1px solid #1e2939;\n}\n.np-docs-code-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.55rem 0.85rem;\n background: #0f1a2b;\n border-bottom: 1px solid #1e293b;\n}\n.np-docs-code-file {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n font-family: var(--np-font-mono);\n font-size: 0.78rem;\n color: #94a3b8;\n}\n.np-docs-code-file svg { color: #64748b; }\n.np-docs-code-copy {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.25rem 0.55rem;\n font-size: 0.72rem;\n font-family: var(--np-font-mono);\n color: #94a3b8;\n background: transparent;\n border: 1px solid #1e293b;\n border-radius: 5px;\n cursor: pointer;\n}\n.np-docs-code-copy:hover {\n color: #e2e8f0;\n border-color: #334155;\n}\n.np-docs-code pre {\n margin: 0;\n padding: 1rem 1.1rem;\n font-size: 0.825rem;\n line-height: 1.65;\n overflow-x: auto;\n}\n.np-docs-code pre code {\n display: block;\n font-family: inherit;\n background: transparent;\n border: 0;\n padding: 0;\n color: inherit;\n}\n.tk-c { color: #64748b; font-style: italic; }\n.tk-k { color: #c084fc; }\n.tk-s { color: #86efac; }\n.tk-f { color: #93c5fd; }\n.tk-t { color: #fcd34d; }\n.tk-n { color: #f9a8d4; }\n.tk-p { color: #e2e8f0; }\n\n/* Inline shell snippet — for terse \\`pnpm dev\\` style commands.\n * Named \\`cmdline\\` (not \\`shell\\`) so it doesn't collide with the\n * route shell container at \\`.np-docs-shell\\`. */\n.np-docs-cmdline {\n display: grid;\n grid-template-columns: auto 1fr auto;\n gap: 0.7rem;\n align-items: center;\n padding: 0.75rem 1rem;\n margin: 1.25rem 0;\n background: #0b1220;\n color: #e6edf6;\n border-radius: 9px;\n font-family: var(--np-font-mono);\n font-size: 0.875rem;\n}\n.np-docs-cmdline-prompt { color: #34d399; }\n.np-docs-cmdline-cmd { color: #e2e8f0; }\n.np-docs-cmdline-copy {\n padding: 0.2rem 0.55rem;\n font-size: 0.7rem;\n color: #94a3b8;\n background: transparent;\n border: 1px solid #1e293b;\n border-radius: 5px;\n cursor: pointer;\n}\n.np-docs-cmdline-copy:hover { color: #e2e8f0; border-color: #334155; }\n\n/* ============================================================\n * Numbered steps — counter on a soft pill before each step.\n * ============================================================ */\n.np-docs-steps {\n counter-reset: step;\n list-style: none;\n padding: 0;\n margin: 1.5rem 0;\n display: grid;\n gap: 1rem;\n}\n.np-docs-steps > li {\n counter-increment: step;\n display: grid;\n grid-template-columns: 2.1rem 1fr;\n gap: 0.85rem;\n align-items: start;\n}\n.np-docs-steps > li::before {\n content: counter(step);\n width: 1.85rem;\n height: 1.85rem;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-family: var(--np-font-mono);\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--np-color-primary);\n background: color-mix(in oklab, var(--np-color-primary) 14%, var(--np-color-card));\n border-radius: 50%;\n}\n.np-docs-step-title {\n font-weight: 600;\n margin: 0.25rem 0 0.25rem;\n}\n.np-docs-step-body {\n margin: 0;\n color: var(--np-color-muted-foreground);\n}\n\n/* ============================================================\n * API / reference tables — uppercase mono headers.\n * ============================================================ */\n.np-docs-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.875rem;\n margin: 1.25rem 0;\n}\n.np-docs-table thead { background: var(--np-color-muted); }\n.np-docs-table th,\n.np-docs-table td {\n text-align: left;\n padding: 0.7rem 0.85rem;\n border-bottom: 1px solid var(--np-color-border);\n vertical-align: top;\n}\n.np-docs-table th {\n font-family: var(--np-font-mono);\n font-size: 0.72rem;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--np-color-muted-foreground);\n font-weight: 600;\n}\n.np-docs-table td:first-child code {\n color: var(--np-color-foreground);\n font-weight: 500;\n}\n.np-docs-table-required {\n display: inline-block;\n font-family: var(--np-font-mono);\n font-size: 0.65rem;\n padding: 0.05rem 0.35rem;\n margin-left: 0.4rem;\n background: #fef3c7;\n color: #92400e;\n border-radius: 4px;\n vertical-align: 1px;\n}\n\n/* ============================================================\n * Prev / next — symmetric pair at the foot of every doc page.\n * Hover lifts the bordered card and tints the border primary.\n * ============================================================ */\n.np-docs-prev-next {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 1rem;\n margin: 3.5rem 0 1rem;\n padding-top: 2rem;\n border-top: 1px solid var(--np-color-border);\n}\n.np-docs-prev-next a {\n display: block;\n padding: 1rem 1.15rem;\n background: var(--np-color-card);\n border: 1px solid var(--np-color-border);\n border-radius: 10px;\n text-decoration: none;\n transition: border-color 0.15s ease, transform 0.2s ease;\n}\n.np-docs-prev-next a:hover {\n border-color: var(--np-color-primary);\n transform: translateY(-1px);\n}\n.np-docs-prev-next-dir,\n.np-docs-prev-next-label {\n font-family: var(--np-font-mono);\n font-size: 0.72rem;\n color: var(--np-color-muted-foreground);\n letter-spacing: 0.05em;\n margin-bottom: 0.25rem;\n}\n.np-docs-prev-next-title {\n font-weight: 600;\n font-size: 0.95rem;\n}\n.np-docs-prev-next a.np-docs-prev-next-next,\n.np-docs-prev-next a:last-child { text-align: right; }\n\n/* ============================================================\n * Feedback row — Yes / Could be better buttons under each page.\n * ============================================================ */\n.np-docs-feedback {\n margin-top: 3rem;\n padding: 1.25rem;\n background: var(--np-color-muted);\n border: 1px solid var(--np-color-border);\n border-radius: 10px;\n display: flex;\n gap: 1rem;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n}\n.np-docs-feedback-title { font-weight: 600; font-size: 0.95rem; }\n.np-docs-feedback-helper {\n font-size: 0.825rem;\n color: var(--np-color-muted-foreground);\n margin-top: 0.15rem;\n}\n.np-docs-feedback-buttons {\n display: flex;\n gap: 0.5rem;\n}\n.np-docs-feedback-buttons button {\n padding: 0.4rem 0.85rem;\n font: inherit;\n font-size: 0.825rem;\n background: var(--np-color-card);\n border: 1px solid var(--np-color-border);\n border-radius: 7px;\n cursor: pointer;\n}\n.np-docs-feedback-buttons button:hover {\n border-color: var(--np-color-primary);\n color: var(--np-color-primary);\n}\n\n/* ============================================================\n * On-page TOC — right rail, sticky, current section gets a\n * primary border + soft gradient.\n * ============================================================ */\n.np-docs-toc {\n position: sticky;\n top: 4.25rem;\n align-self: start;\n max-height: calc(100vh - 5rem);\n overflow-y: auto;\n font-size: 0.825rem;\n}\n.np-docs-toc-eyebrow {\n font-family: var(--np-font-mono);\n font-size: 0.7rem;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n color: var(--np-color-muted-foreground);\n margin: 0 0 0.75rem;\n font-weight: 600;\n}\n.np-docs-toc ul {\n list-style: none;\n padding: 0;\n margin: 0;\n}\n.np-docs-toc li { margin: 0.05rem 0; }\n.np-docs-toc a {\n display: block;\n padding: 0.3rem 0.5rem;\n color: var(--np-color-muted-foreground);\n text-decoration: none;\n border-left: 2px solid transparent;\n margin-left: -2px;\n line-height: 1.4;\n}\n.np-docs-toc a:hover { color: var(--np-color-foreground); }\n.np-docs-toc a[data-current=\"true\"],\n.np-docs-toc a[aria-current=\"location\"],\n.np-docs-toc a[aria-current=\"true\"] {\n color: var(--np-color-primary);\n border-left-color: var(--np-color-primary);\n background: linear-gradient(\n to right,\n color-mix(in oklab, var(--np-color-primary) 14%, var(--np-color-card)),\n transparent 80%\n );\n}\n.np-docs-toc ul ul { margin-left: 0.85rem; }\n.np-docs-toc-secondary {\n margin-top: 1.5rem;\n padding-top: 1rem;\n border-top: 1px solid var(--np-color-border);\n}\n.np-docs-toc-secondary a {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.2rem 0;\n border-left: 0;\n margin: 0;\n}\n.np-docs-toc-secondary a:hover { background: transparent; }\n\n/* Empty / not-found surfaces — used by routes/not-found and\n * the docs collection's empty state. */\n.np-docs-empty {\n padding: 4rem 1.5rem;\n text-align: center;\n color: var(--np-color-muted-foreground);\n}\n.np-docs-empty h1 {\n font-size: 1.5rem;\n margin: 0 0 0.5rem;\n color: var(--np-color-foreground);\n}\n`;\n"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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","names":["jsx","jsxs","jsx","jsxs","jsx","jsxs","findDocuments","Fragment","jsx","jsxs","jsx","findDocuments","jsx","jsxs","jsx","findDocuments","jsx","jsxs","findDocuments"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexpress/theme-docs",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Documentation theme for NexPress — hierarchical sidebar, prev/next nav, in-page TOC.",
5
5
  "license": "MIT",
6
6
  "author": "Nexpress",
@@ -48,11 +48,11 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "zod": "^4.4.3",
51
- "@nexpress/blocks": "0.3.0",
52
- "@nexpress/core": "0.3.0",
53
- "@nexpress/editor": "0.3.0",
54
- "@nexpress/next": "0.3.0",
55
- "@nexpress/theme": "0.3.0"
51
+ "@nexpress/blocks": "0.3.1",
52
+ "@nexpress/core": "0.3.1",
53
+ "@nexpress/editor": "0.3.1",
54
+ "@nexpress/next": "0.3.1",
55
+ "@nexpress/theme": "0.3.1"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/react": "^19.0.0",