@clarify-labs/renderer 0.2.0 → 0.4.0

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.
Files changed (38) hide show
  1. package/output/{AppShell-4KB3lU-n.cjs → AppShell-CZw1MrPG.cjs} +977 -408
  2. package/output/AppShell-CZw1MrPG.cjs.map +1 -0
  3. package/output/{AppShell-Ci894P_0.js → AppShell-nQnuKyn2.js} +974 -411
  4. package/output/AppShell-nQnuKyn2.js.map +1 -0
  5. package/output/client.cjs +1 -1
  6. package/output/client.js +1 -1
  7. package/output/components/PageNavigation.d.ts +5 -0
  8. package/output/components/index.d.ts +1 -0
  9. package/output/context.d.ts +2 -0
  10. package/output/i18n.d.ts +5 -0
  11. package/output/index.cjs +1351 -346
  12. package/output/index.cjs.map +1 -1
  13. package/output/index.js +1351 -346
  14. package/output/index.js.map +1 -1
  15. package/output/openapi/example-panels.d.ts +31 -0
  16. package/output/openapi/helpers.d.ts +24 -0
  17. package/output/openapi/index.d.ts +2 -19
  18. package/output/openapi/openapi-page.d.ts +19 -0
  19. package/output/openapi/request-code.d.ts +16 -0
  20. package/output/openapi/schema-properties.d.ts +15 -0
  21. package/output/openapi/spec-path.d.ts +2 -0
  22. package/output/openapi/types.d.ts +66 -0
  23. package/output/{render-bPMMBoDH.js → render-BCiQn6Q1.js} +2 -2
  24. package/output/{render-bPMMBoDH.js.map → render-BCiQn6Q1.js.map} +1 -1
  25. package/output/{render-z9rSQ00n.cjs → render-CZsdzmme.cjs} +2 -2
  26. package/output/{render-z9rSQ00n.cjs.map → render-CZsdzmme.cjs.map} +1 -1
  27. package/output/renderer.css +1374 -603
  28. package/output/server.cjs +1 -1
  29. package/output/server.js +1 -1
  30. package/output/shell/ContentActions.d.ts +1 -0
  31. package/output/shell/Header.d.ts +4 -3
  32. package/output/shell/icons.d.ts +4 -0
  33. package/output/shell/mobile.d.ts +2 -1
  34. package/output/types.d.ts +62 -9
  35. package/output/utils/path.d.ts +2 -0
  36. package/package.json +10 -9
  37. package/output/AppShell-4KB3lU-n.cjs.map +0 -1
  38. package/output/AppShell-Ci894P_0.js.map +0 -1
@@ -1,12 +1,12 @@
1
+ import clsx from "clsx";
1
2
  import { AnimatePresence, motion, useInView, useIsPresent, useScroll, useTransform } from "framer-motion";
2
- import { Children, Fragment, Suspense, createContext, forwardRef, isValidElement, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
3
+ import { Children, Fragment, Suspense, createContext, forwardRef, isValidElement, lazy, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
3
4
  import { Link, Route, Routes, useLocation, useNavigate } from "react-router-dom";
4
5
  import { create, createStore, useStore } from "zustand";
5
6
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
- import clsx from "clsx";
7
- import { CloseButton, Dialog, DialogBackdrop, DialogPanel, Menu, MenuButton, MenuItem, MenuItems, Tab, TabGroup, TabList, TabPanel, TabPanels, Transition, TransitionChild } from "@headlessui/react";
8
7
  import * as LucideIcons from "lucide-react";
9
- import { AlertTriangle, Check, CheckCircle2, ChevronDown, Copy, Info, Lightbulb, Link2, XCircle } from "lucide-react";
8
+ import { AlertTriangle, Check, CheckCircle2, ChevronDown, ChevronLeft, ChevronRight, Copy, ExternalLink, FileText, Info, Lightbulb, Link2, MoreHorizontal, XCircle } from "lucide-react";
9
+ import { CloseButton, Dialog, DialogBackdrop, DialogPanel, Menu, MenuButton, MenuItem, MenuItems, Tab, TabGroup, TabList, TabPanel, TabPanels, Transition, TransitionChild } from "@headlessui/react";
10
10
  //#region source/utils/remToPx.ts
11
11
  function remToPx(remValue) {
12
12
  return remValue * (typeof window === "undefined" ? 16 : Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize));
@@ -61,7 +61,14 @@ function SectionProvider(arg0) {
61
61
  const [sectionStore] = useState(() => createSectionStore(sections));
62
62
  useVisibleSections(sectionStore);
63
63
  useIsomorphicLayoutEffect(() => {
64
- sectionStore.setState({ sections });
64
+ sectionStore.setState((state) => ({ sections: sections.map((section) => {
65
+ const registeredSection = state.sections.find((item) => item.id === section.id);
66
+ return {
67
+ ...section,
68
+ headingRef: registeredSection?.headingRef,
69
+ offsetRem: registeredSection?.offsetRem ?? section.offsetRem
70
+ };
71
+ }) }));
65
72
  }, [sectionStore, sections]);
66
73
  return /* @__PURE__ */ jsx(SectionStoreContext.Provider, {
67
74
  value: sectionStore,
@@ -74,110 +81,179 @@ function useSectionStore(selector) {
74
81
  return useStore(store, selector);
75
82
  }
76
83
  //#endregion
77
- //#region source/components/SiteLogo.tsx
78
- function SiteLogo(arg0) {
79
- const { logo, className } = arg0;
80
- if (!logo) return null;
81
- if (typeof logo === "string") return /* @__PURE__ */ jsx("img", {
82
- src: logo,
83
- alt: "",
84
- className: clsx("clarify-logo", className)
85
- });
86
- const lightLogo = logo.light ?? logo.dark;
87
- const darkLogo = logo.dark ?? logo.light;
88
- if (!lightLogo || !darkLogo) return null;
89
- if (lightLogo === darkLogo) return /* @__PURE__ */ jsx("img", {
90
- src: lightLogo,
91
- alt: "",
92
- className: clsx("clarify-logo", className)
93
- });
94
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("img", {
95
- src: lightLogo,
96
- alt: "",
97
- className: clsx("clarify-logo clarify-logo-light", className, "dark:hidden")
98
- }), /* @__PURE__ */ jsx("img", {
99
- src: darkLogo,
100
- alt: "",
101
- className: clsx("clarify-logo clarify-logo-dark", className, "hidden dark:block")
102
- })] });
84
+ //#region source/context.tsx
85
+ var ClarifyConfigContext = createContext(null);
86
+ var ClarifyLocaleContext = createContext(void 0);
87
+ var OpenApisContext = createContext({});
88
+ function useClarifyConfig() {
89
+ const config = useContext(ClarifyConfigContext);
90
+ if (!config) throw new Error("[clarify] useClarifyConfig must be used within a ClarifyConfigContext.Provider");
91
+ return config;
103
92
  }
104
- //#endregion
105
- //#region source/shell/ContentActions.tsx
106
- function resolveRawContentUrl(rawContentUrl, routePrefix = "/") {
107
- if (!routePrefix || routePrefix === "/") return rawContentUrl;
108
- return `/${routePrefix.replace(/^\/+|\/+$/g, "")}${rawContentUrl}`;
93
+ function useOpenApis() {
94
+ return useContext(OpenApisContext);
109
95
  }
110
- function getAbsoluteUrl(path) {
111
- if (typeof window === "undefined") return path;
112
- return new URL(path, window.location.href).href;
96
+ //#endregion
97
+ //#region source/i18n.ts
98
+ var builtInText = {
99
+ en: {
100
+ "actions.code": "Code",
101
+ "actions.copy": "Copy",
102
+ "actions.copied": "Copied!",
103
+ "builtWith.label": "Built with Clarify",
104
+ "builtWith.prefix": "Built with",
105
+ "callout.danger": "Danger",
106
+ "callout.info": "Info",
107
+ "callout.note": "Note",
108
+ "callout.success": "Success",
109
+ "callout.tip": "Tip",
110
+ "callout.warning": "Warning",
111
+ "contentActions.copyContent": "Copy page",
112
+ "contentActions.copyContentDescription": "Copy this page as {contentType} for LLMs",
113
+ "contentActions.copyLink": "Copy {contentType} link",
114
+ "contentActions.copyLinkDescription": "Copy the raw {contentType} content link for this page",
115
+ "contentActions.copyOptions": "Choose copy option",
116
+ "contentActions.copiedContent": "Copied page",
117
+ "contentActions.copiedLink": "Copied link",
118
+ "contentActions.viewMarkdown": "View as Markdown",
119
+ "contentActions.viewMarkdownDescription": "View this page as plain text",
120
+ "contentActions.viewOpenApi": "View raw OpenAPI",
121
+ "contentActions.viewOpenApiDescription": "Open the API description file in a new tab",
122
+ "feedback.no": "No",
123
+ "feedback.prompt": "Was this page helpful?",
124
+ "feedback.thanks": "Thanks for your feedback!",
125
+ "feedback.yes": "Yes",
126
+ "navigation.documentation": "Documentation",
127
+ "navigation.next": "Next",
128
+ "navigation.previous": "Previous",
129
+ "navigation.previousNext": "Previous and next pages",
130
+ "navigation.toggle": "Toggle navigation",
131
+ "navbar.home": "Home",
132
+ "navbar.openLinks": "Open navigation links",
133
+ "navbar.sections": "Documentation sections",
134
+ "openapi.apiDocumentation": "API Documentation",
135
+ "openapi.bodyProperties": "Body properties",
136
+ "openapi.collapse": "Collapse",
137
+ "openapi.endpointNotFound": "Endpoint not found: {endpoint}",
138
+ "openapi.example": "Example",
139
+ "openapi.expand": "Expand",
140
+ "openapi.headers": "Headers",
141
+ "openapi.language": "Language",
142
+ "openapi.client": "Client",
143
+ "openapi.mediaType": "Media type",
144
+ "openapi.openApiReference": "OpenAPI Reference",
145
+ "openapi.operationParameter": "Operation parameter.",
146
+ "openapi.optional": "Optional.",
147
+ "openapi.parameter": "parameter",
148
+ "openapi.pathParameters": "Path parameters",
149
+ "openapi.queryParameters": "Query parameters",
150
+ "openapi.request": "Request",
151
+ "openapi.requestBody": "Request body",
152
+ "openapi.required": "Required.",
153
+ "openapi.requiredBadge": "required",
154
+ "openapi.response": "Response",
155
+ "openapi.responses": "Responses",
156
+ "openapi.schemaExample": "Schema example",
157
+ "openapi.scrollExamplesLeft": "Scroll examples left",
158
+ "openapi.scrollExamplesRight": "Scroll examples right",
159
+ "openapi.specNotFound": "OpenAPI spec not found: {specPath}",
160
+ "openapi.specPathMissing": "spec or specPath was not provided",
161
+ "openapi.status": "Status",
162
+ "openapi.version": "Version {version}",
163
+ "search.button": "Search...",
164
+ "search.noResults": "Nothing found for {query}.",
165
+ "search.placeholder": "Find something...",
166
+ "search.shortcutCtrl": "Ctrl ",
167
+ "theme.switchToDark": "Switch to dark theme",
168
+ "theme.switchToLight": "Switch to light theme",
169
+ "language.switch": "Switch language"
170
+ },
171
+ "zh-CN": {
172
+ "actions.code": "代码",
173
+ "actions.copy": "复制",
174
+ "actions.copied": "已复制!",
175
+ "builtWith.label": "由 Clarify 构建",
176
+ "builtWith.prefix": "构建来自",
177
+ "callout.danger": "危险",
178
+ "callout.info": "信息",
179
+ "callout.note": "注意",
180
+ "callout.success": "成功",
181
+ "callout.tip": "提示",
182
+ "callout.warning": "警告",
183
+ "contentActions.copyContent": "复制页面",
184
+ "contentActions.copyContentDescription": "将页面以 {contentType} 格式复制给 LLMs",
185
+ "contentActions.copyLink": "复制 {contentType} 链接",
186
+ "contentActions.copyLinkDescription": "复制当前页面的 {contentType} 原始内容链接",
187
+ "contentActions.copyOptions": "选择复制选项",
188
+ "contentActions.copiedContent": "已复制页面",
189
+ "contentActions.copiedLink": "已复制链接",
190
+ "contentActions.viewMarkdown": "以 Markdown 格式查看",
191
+ "contentActions.viewMarkdownDescription": "以纯文本查看此页面",
192
+ "contentActions.viewOpenApi": "查看 OpenAPI 原始内容",
193
+ "contentActions.viewOpenApiDescription": "在新标签页打开 API 描述文件",
194
+ "feedback.no": "否",
195
+ "feedback.prompt": "这个页面有帮助吗?",
196
+ "feedback.thanks": "感谢你的反馈!",
197
+ "feedback.yes": "是",
198
+ "navigation.documentation": "文档",
199
+ "navigation.next": "下一页",
200
+ "navigation.previous": "上一页",
201
+ "navigation.previousNext": "上一页和下一页",
202
+ "navigation.toggle": "切换导航",
203
+ "navbar.home": "首页",
204
+ "navbar.openLinks": "打开导航链接",
205
+ "navbar.sections": "文档栏目",
206
+ "openapi.apiDocumentation": "API 文档",
207
+ "openapi.bodyProperties": "请求体属性",
208
+ "openapi.collapse": "收起",
209
+ "openapi.endpointNotFound": "未找到端点:{endpoint}",
210
+ "openapi.example": "示例",
211
+ "openapi.expand": "展开",
212
+ "openapi.headers": "请求头",
213
+ "openapi.language": "语言",
214
+ "openapi.client": "客户端",
215
+ "openapi.mediaType": "媒体类型",
216
+ "openapi.openApiReference": "OpenAPI 参考",
217
+ "openapi.operationParameter": "操作参数。",
218
+ "openapi.optional": "可选。",
219
+ "openapi.parameter": "参数",
220
+ "openapi.pathParameters": "路径参数",
221
+ "openapi.queryParameters": "查询参数",
222
+ "openapi.request": "请求",
223
+ "openapi.requestBody": "请求体",
224
+ "openapi.required": "必填。",
225
+ "openapi.requiredBadge": "必填",
226
+ "openapi.response": "响应",
227
+ "openapi.responses": "响应",
228
+ "openapi.schemaExample": "Schema 示例",
229
+ "openapi.scrollExamplesLeft": "向左滚动示例",
230
+ "openapi.scrollExamplesRight": "向右滚动示例",
231
+ "openapi.specNotFound": "未找到 OpenAPI 描述文件:{specPath}",
232
+ "openapi.specPathMissing": "未提供 spec 或 specPath",
233
+ "openapi.status": "状态",
234
+ "openapi.version": "版本 {version}",
235
+ "search.button": "搜索...",
236
+ "search.noResults": "没有找到与 {query} 相关的结果。",
237
+ "search.placeholder": "搜索内容...",
238
+ "search.shortcutCtrl": "Ctrl ",
239
+ "theme.switchToDark": "切换到深色主题",
240
+ "theme.switchToLight": "切换到浅色主题",
241
+ "language.switch": "切换语言"
242
+ }
243
+ };
244
+ function resolveBuiltInLocale(locale) {
245
+ return locale === "zh-CN" || locale?.toLowerCase().startsWith("zh") ? "zh-CN" : "en";
113
246
  }
114
- async function copyText(text) {
115
- await navigator.clipboard.writeText(text);
247
+ function translateBuiltInText(locale, key, replacements = {}) {
248
+ let value = builtInText[resolveBuiltInLocale(locale)]?.[key] ?? builtInText.en[key];
249
+ for (const [name, replacement] of Object.entries(replacements)) value = value.replaceAll(`{${name}}`, replacement);
250
+ return value;
116
251
  }
117
- function ContentActions(arg0) {
118
- const { route, routePrefix } = arg0;
119
- const [copied, setCopied] = useState("idle");
120
- if (!route?.rawContentUrl) return null;
121
- const rawContentUrl = resolveRawContentUrl(route.rawContentUrl, routePrefix);
122
- const isOpenApi = route.kind === "openapi";
123
- const contentLabel = isOpenApi ? "复制 OpenAPI 内容" : "复制 Markdown 内容";
124
- const linkLabel = isOpenApi ? "复制 OpenAPI 链接" : "复制 Markdown 链接";
125
- function markCopied(state) {
126
- setCopied(state);
127
- window.setTimeout(() => setCopied("idle"), 1600);
128
- }
129
- async function handleCopyContent() {
130
- await copyText(await (await fetch(rawContentUrl)).text());
131
- markCopied("content");
132
- }
133
- async function handleCopyLink() {
134
- await copyText(getAbsoluteUrl(rawContentUrl));
135
- markCopied("link");
136
- }
137
- const actions = [{
138
- key: "content",
139
- label: contentLabel,
140
- icon: Copy,
141
- run: handleCopyContent
142
- }, {
143
- key: "link",
144
- label: linkLabel,
145
- icon: Link2,
146
- run: handleCopyLink
147
- }];
148
- const primaryAction = actions[0];
149
- return /* @__PURE__ */ jsx("div", {
150
- className: "clarify-content-actions sticky top-16 z-20 flex justify-end py-4",
151
- children: /* @__PURE__ */ jsxs(Menu, {
152
- as: "div",
153
- className: "clarify-content-actions-menu relative inline-flex text-xs font-medium",
154
- children: [/* @__PURE__ */ jsxs("div", {
155
- className: "clarify-content-actions-group inline-flex overflow-hidden rounded-full border border-zinc-900/10 bg-white/85 backdrop-blur dark:border-white/10 dark:bg-white/5",
156
- children: [/* @__PURE__ */ jsxs("button", {
157
- type: "button",
158
- onClick: primaryAction.run,
159
- className: "clarify-content-actions-primary inline-flex h-8 items-center gap-1.5 px-3 text-zinc-600 transition hover:bg-zinc-100 hover:text-zinc-950 dark:text-zinc-300 dark:hover:bg-white/10 dark:hover:text-white",
160
- children: [copied === primaryAction.key ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(primaryAction.icon, { className: "h-3.5 w-3.5" }), copied === primaryAction.key ? "已复制" : "复制页面"]
161
- }), /* @__PURE__ */ jsx(MenuButton, {
162
- className: "clarify-content-actions-trigger inline-flex h-8 w-8 items-center justify-center border-l border-zinc-900/10 text-zinc-500 transition hover:bg-zinc-100 hover:text-zinc-950 dark:border-white/10 dark:text-zinc-400 dark:hover:bg-white/10 dark:hover:text-white",
163
- "aria-label": "选择复制选项",
164
- children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5" })
165
- })]
166
- }), /* @__PURE__ */ jsx(MenuItems, {
167
- anchor: "bottom end",
168
- className: "clarify-content-actions-list z-30 mt-2 w-52 origin-top-right rounded-2xl border border-zinc-900/10 bg-white p-1 text-xs shadow-md transition [--anchor-gap:--spacing(2)] focus:outline-none data-closed:scale-95 data-closed:opacity-0 dark:border-white/10 dark:bg-zinc-900",
169
- children: actions.map((action) => {
170
- const Icon = copied === action.key ? Check : action.icon;
171
- return /* @__PURE__ */ jsx(MenuItem, { children: /* @__PURE__ */ jsxs("button", {
172
- type: "button",
173
- onClick: action.run,
174
- className: "clarify-content-actions-item flex w-full items-center gap-2 rounded-xl px-3 py-2 text-left text-zinc-600 transition data-focus:bg-zinc-100 data-focus:text-zinc-950 dark:text-zinc-300 dark:data-focus:bg-white/10 dark:data-focus:text-white",
175
- children: [/* @__PURE__ */ jsx(Icon, { className: "h-3.5 w-3.5" }), /* @__PURE__ */ jsx("span", { children: copied === action.key ? "已复制" : action.label })]
176
- }) }, action.key);
177
- })
178
- })]
179
- })
180
- });
252
+ function useBuiltInText(locale) {
253
+ const config = useContext(ClarifyConfigContext);
254
+ const currentLocale = useContext(ClarifyLocaleContext);
255
+ const resolvedLocale = locale ?? currentLocale ?? config?.i18n?.defaultLocale;
256
+ return (key, replacements) => translateBuiltInText(resolvedLocale, key, replacements);
181
257
  }
182
258
  //#endregion
183
259
  //#region source/components/BuiltWithClarify.tsx
@@ -205,17 +281,18 @@ function ClarifyMark(props) {
205
281
  });
206
282
  }
207
283
  function BuiltWithClarify() {
284
+ const t = useBuiltInText();
208
285
  return /* @__PURE__ */ jsxs("a", {
209
286
  href: "https://clarify.pub",
210
287
  target: "_blank",
211
288
  rel: "noreferrer",
212
- "aria-label": "Built with Clarify",
213
- className: "clarify-built-with inline-flex items-center gap-1.5 rounded-full px-2 py-1 text-xs font-medium text-zinc-500 no-underline transition hover:bg-zinc-900/2.5 hover:text-zinc-900 dark:text-zinc-500 dark:hover:bg-white/5 dark:hover:text-white",
289
+ "aria-label": t("builtWith.label"),
290
+ className: "clarify-built-with inline-flex items-center gap-1.5 rounded-full px-2 py-1 font-medium no-underline transition",
214
291
  children: [
215
- /* @__PURE__ */ jsx("span", { children: "Built with" }),
292
+ /* @__PURE__ */ jsx("span", { children: t("builtWith.prefix") }),
216
293
  /* @__PURE__ */ jsx(ClarifyMark, { className: "clarify-built-with-logo h-3.5 w-5 flex-none" }),
217
294
  /* @__PURE__ */ jsx("span", {
218
- className: "font-semibold text-zinc-700 dark:text-zinc-300",
295
+ className: "clarify-built-with-brand font-semibold",
219
296
  children: "Clarify"
220
297
  })
221
298
  ]
@@ -261,21 +338,22 @@ var calloutStyles = {
261
338
  Icon: CheckCircle2
262
339
  }
263
340
  };
264
- var defaultTitles = {
265
- info: "Info",
266
- note: "Note",
267
- tip: "Tip",
268
- warning: "Warning",
269
- danger: "Danger",
270
- success: "Success"
341
+ var defaultTitleKeys = {
342
+ info: "callout.info",
343
+ note: "callout.note",
344
+ tip: "callout.tip",
345
+ warning: "callout.warning",
346
+ danger: "callout.danger",
347
+ success: "callout.success"
271
348
  };
272
349
  function Callout(arg0) {
273
350
  const { children, type = "info", title, icon = true, className, ...props } = arg0;
351
+ const t = useBuiltInText();
274
352
  const style = calloutStyles[type];
275
353
  const Icon = style.Icon;
276
- const resolvedTitle = title === void 0 ? defaultTitles[type] : title;
354
+ const resolvedTitle = title === void 0 ? t(defaultTitleKeys[type]) : title;
277
355
  return /* @__PURE__ */ jsxs("div", {
278
- className: clsx("clarify-callout my-6 flex gap-3 rounded-2xl border p-4 text-sm/6", style.container, className),
356
+ className: clsx("clarify-callout my-6 flex gap-3 rounded-(--clarify-theme-tokens-radius-xl) border p-4 text-sm/6", style.container, className),
279
357
  ...props,
280
358
  children: [icon ? /* @__PURE__ */ jsx(Icon, {
281
359
  className: clsx("mt-1 size-4 flex-none", style.icon),
@@ -303,7 +381,7 @@ function CardIcon(arg0) {
303
381
  const Icon = LucideIcons[toPascalCase(name)];
304
382
  if (!Icon) return null;
305
383
  return /* @__PURE__ */ jsx("span", {
306
- className: "flex size-9 flex-none items-center justify-center rounded-lg bg-emerald-50 text-emerald-600 ring-1 ring-emerald-500/10 dark:bg-emerald-400/10 dark:text-emerald-400 dark:ring-emerald-400/20",
384
+ className: "flex size-9 flex-none items-center justify-center rounded-[var(--clarify-theme-tokens-radius-lg)] bg-(--clarify-ui-accent-background) text-(--clarify-ui-accent-text) ring-1 ring-(--clarify-ui-accent-border)",
307
385
  children: /* @__PURE__ */ jsx(Icon, {
308
386
  className: "size-5",
309
387
  "aria-hidden": "true"
@@ -330,18 +408,18 @@ function Card(arg0) {
330
408
  children: [/* @__PURE__ */ jsx(CardIcon, { name: icon }), /* @__PURE__ */ jsxs("div", {
331
409
  className: "min-w-0 flex-1",
332
410
  children: [/* @__PURE__ */ jsx("h3", {
333
- className: "m-0 text-base font-semibold text-zinc-900 dark:text-white",
411
+ className: "m-0 text-base font-semibold text-[var(--clarify-theme-tokens-colors-foreground)] dark:text-white",
334
412
  children: title
335
413
  }), children ? /* @__PURE__ */ jsx("div", {
336
- className: "mt-2 text-sm/6 text-zinc-600 dark:text-zinc-400 *:m-0",
414
+ className: "mt-2 text-sm/6 text-[var(--clarify-theme-tokens-colors-muted)] dark:text-zinc-400 *:m-0",
337
415
  children
338
416
  }) : null]
339
417
  })]
340
418
  }), href ? /* @__PURE__ */ jsx("span", {
341
- className: "absolute inset-0 rounded-2xl",
419
+ className: "absolute inset-0 rounded-[var(--clarify-theme-tokens-radius-xl)]",
342
420
  "aria-hidden": "true"
343
421
  }) : null] });
344
- const classes = clsx("group relative block rounded-2xl border border-zinc-200 bg-white p-5 shadow-sm transition hover:border-emerald-300 hover:shadow-md dark:border-white/10 dark:bg-zinc-900/50 dark:hover:border-emerald-400/40", className);
422
+ const classes = clsx("group relative block rounded-[var(--clarify-theme-tokens-radius-xl)] border border-[color:var(--clarify-theme-tokens-colors-border)] bg-[var(--clarify-theme-tokens-colors-surface)] p-5 shadow-sm shadow-(--clarify-ui-accent-glow) transition hover:border-(--clarify-ui-accent-border) hover:shadow-md dark:bg-zinc-900/50", className);
345
423
  if (!href) return /* @__PURE__ */ jsx("div", {
346
424
  className: classes,
347
425
  children: content
@@ -378,10 +456,10 @@ var languageNames = {
378
456
  json: "JSON"
379
457
  };
380
458
  function getPanelTitle(arg0) {
381
- const { title, language } = arg0;
459
+ const { title, language, fallbackTitle = "Code" } = arg0;
382
460
  if (title) return title;
383
461
  if (language && language in languageNames) return languageNames[language];
384
- return "Code";
462
+ return fallbackTitle;
385
463
  }
386
464
  function getNodeText(node) {
387
465
  if (typeof node === "string" || typeof node === "number") return String(node);
@@ -389,7 +467,7 @@ function getNodeText(node) {
389
467
  if (isValidElement(node)) return getNodeText(node.props.children);
390
468
  return "";
391
469
  }
392
- function ClipboardIcon(props) {
470
+ function ClipboardIcon$1(props) {
393
471
  return /* @__PURE__ */ jsxs("svg", {
394
472
  viewBox: "0 0 20 20",
395
473
  "aria-hidden": "true",
@@ -406,6 +484,7 @@ function ClipboardIcon(props) {
406
484
  }
407
485
  function CopyButton(arg0) {
408
486
  const { code } = arg0;
487
+ const t = useBuiltInText();
409
488
  const [copyCount, setCopyCount] = useState(0);
410
489
  const copied = copyCount > 0;
411
490
  useEffect(() => {
@@ -416,7 +495,7 @@ function CopyButton(arg0) {
416
495
  if (!code) return null;
417
496
  return /* @__PURE__ */ jsxs("button", {
418
497
  type: "button",
419
- className: clsx("clarify-code-copy group/button absolute top-3.5 right-4 overflow-hidden rounded-full py-1 pr-3 pl-2 text-2xs font-medium opacity-0 backdrop-blur-sm transition group-hover:opacity-100 focus:opacity-100", copied ? "bg-emerald-400/10 ring-1 ring-emerald-400/20 ring-inset" : "bg-white/5 hover:bg-white/7.5 dark:bg-white/2.5 dark:hover:bg-white/5"),
498
+ className: clsx("clarify-code-copy group/button absolute top-3.5 right-4 overflow-hidden rounded-full py-1 pr-3 pl-2 text-2xs font-medium opacity-0 backdrop-blur-sm transition group-hover:opacity-100 focus:opacity-100", copied ? "bg-[color-mix(in_srgb,var(--clarify-theme-tokens-colors-primary)_12%,transparent)] ring-1 ring-[color-mix(in_srgb,var(--clarify-theme-tokens-colors-primary)_24%,transparent)] ring-inset" : "bg-white/5 hover:bg-white/7.5 dark:bg-white/2.5 dark:hover:bg-white/5"),
420
499
  onClick: () => {
421
500
  window.navigator.clipboard.writeText(code).then(() => {
422
501
  setCopyCount((count) => count + 1);
@@ -425,11 +504,11 @@ function CopyButton(arg0) {
425
504
  children: [/* @__PURE__ */ jsxs("span", {
426
505
  "aria-hidden": copied,
427
506
  className: clsx("pointer-events-none flex items-center gap-0.5 text-zinc-400 transition duration-300", copied && "-translate-y-1.5 opacity-0"),
428
- children: [/* @__PURE__ */ jsx(ClipboardIcon, { className: "h-5 w-5 fill-zinc-500/20 stroke-zinc-500 transition-colors group-hover/button:stroke-zinc-400" }), "Copy"]
507
+ children: [/* @__PURE__ */ jsx(ClipboardIcon$1, { className: "h-5 w-5 fill-zinc-500/20 stroke-zinc-500 transition-colors group-hover/button:stroke-zinc-400" }), t("actions.copy")]
429
508
  }), /* @__PURE__ */ jsx("span", {
430
509
  "aria-hidden": !copied,
431
- className: clsx("pointer-events-none absolute inset-0 flex items-center justify-center text-emerald-400 transition duration-300", !copied && "translate-y-1.5 opacity-0"),
432
- children: "Copied!"
510
+ className: clsx("pointer-events-none absolute inset-0 flex items-center justify-center text-[var(--clarify-theme-tokens-colors-primary)] transition duration-300", !copied && "translate-y-1.5 opacity-0"),
511
+ children: t("actions.copied")
433
512
  })]
434
513
  });
435
514
  }
@@ -440,7 +519,7 @@ function CodePanelHeader(arg0) {
440
519
  className: "clarify-code-panel-header flex h-9 items-center gap-2 border-y border-t-transparent border-b-white/7.5 bg-zinc-900 px-4 dark:border-b-white/5 dark:bg-white/1",
441
520
  children: [
442
521
  tag ? /* @__PURE__ */ jsx("span", {
443
- className: "font-mono text-[0.625rem]/6 font-semibold text-emerald-400",
522
+ className: "font-mono text-[0.625rem]/6 font-semibold text-[var(--clarify-theme-tokens-colors-primary)]",
444
523
  children: tag
445
524
  }) : null,
446
525
  tag && label ? /* @__PURE__ */ jsx("span", { className: "h-0.5 w-0.5 rounded-full bg-zinc-500" }) : null,
@@ -478,6 +557,7 @@ function CodePanel(arg0) {
478
557
  }
479
558
  function CodeGroupHeader(arg0) {
480
559
  const { title, children, selectedIndex } = arg0;
560
+ const t = useBuiltInText();
481
561
  const hasTabs = Children.count(children) > 1;
482
562
  if (!title && !hasTabs) return null;
483
563
  return /* @__PURE__ */ jsxs("div", {
@@ -488,8 +568,11 @@ function CodeGroupHeader(arg0) {
488
568
  }) : null, hasTabs ? /* @__PURE__ */ jsx(TabList, {
489
569
  className: "clarify-code-tabs -mb-px flex gap-4 text-xs font-medium",
490
570
  children: Children.map(children, (child, childIndex) => /* @__PURE__ */ jsx(Tab, {
491
- className: clsx("clarify-code-tab border-b py-3 transition data-selected:not-data-focus:outline-hidden", childIndex === selectedIndex ? "border-emerald-500 text-emerald-400" : "border-transparent text-zinc-400 hover:text-zinc-300"),
492
- children: getPanelTitle(isValidElement(child) ? child.props : {})
571
+ className: clsx("clarify-code-tab border-b py-3 transition data-selected:not-data-focus:outline-hidden", childIndex === selectedIndex ? "border-[var(--clarify-theme-tokens-colors-primary)] text-[var(--clarify-theme-tokens-colors-primary)]" : "border-transparent text-zinc-400 hover:text-zinc-300"),
572
+ children: getPanelTitle({
573
+ ...isValidElement(child) ? child.props : {},
574
+ fallbackTitle: t("actions.code")
575
+ })
493
576
  }))
494
577
  }) : null]
495
578
  });
@@ -550,7 +633,11 @@ function useTabGroupProps(availableLanguages) {
550
633
  var CodeGroupContext = createContext(false);
551
634
  function CodeGroup(arg0) {
552
635
  const { children, title, ...props } = arg0;
553
- const tabGroupProps = useTabGroupProps(Children.map(children, (child) => getPanelTitle(isValidElement(child) ? child.props : {})) ?? []);
636
+ const t = useBuiltInText();
637
+ const tabGroupProps = useTabGroupProps(Children.map(children, (child) => getPanelTitle({
638
+ ...isValidElement(child) ? child.props : {},
639
+ fallbackTitle: t("actions.code")
640
+ })) ?? []);
554
641
  const hasTabs = Children.count(children) > 1;
555
642
  const containerClassName = "clarify-code-group my-6 overflow-hidden rounded-2xl bg-zinc-900 shadow-md dark:ring-1 dark:ring-white/10";
556
643
  const header = /* @__PURE__ */ jsx(CodeGroupHeader, {
@@ -629,6 +716,7 @@ function FeedbackButton(props) {
629
716
  }
630
717
  var FeedbackForm = forwardRef(function FeedbackForm(arg0, ref) {
631
718
  const { onSubmit, className, ...props } = arg0;
719
+ const t = useBuiltInText();
632
720
  return /* @__PURE__ */ jsxs("form", {
633
721
  ...props,
634
722
  ref,
@@ -636,18 +724,18 @@ var FeedbackForm = forwardRef(function FeedbackForm(arg0, ref) {
636
724
  className: clsx(className, "clarify-feedback-form absolute inset-0 flex items-center justify-center gap-6 md:justify-start"),
637
725
  children: [/* @__PURE__ */ jsx("p", {
638
726
  className: "text-sm text-zinc-600 dark:text-zinc-400",
639
- children: "Was this page helpful?"
727
+ children: t("feedback.prompt")
640
728
  }), /* @__PURE__ */ jsxs("div", {
641
729
  className: "clarify-feedback-actions group grid h-8 grid-cols-[1fr_1px_1fr] overflow-hidden rounded-full border border-zinc-900/10 dark:border-white/10",
642
730
  children: [
643
731
  /* @__PURE__ */ jsx(FeedbackButton, {
644
732
  "data-response": "yes",
645
- children: "Yes"
733
+ children: t("feedback.yes")
646
734
  }),
647
735
  /* @__PURE__ */ jsx("div", { className: "bg-zinc-900/10 dark:bg-white/10" }),
648
736
  /* @__PURE__ */ jsx(FeedbackButton, {
649
737
  "data-response": "no",
650
- children: "No"
738
+ children: t("feedback.no")
651
739
  })
652
740
  ]
653
741
  })]
@@ -655,13 +743,14 @@ var FeedbackForm = forwardRef(function FeedbackForm(arg0, ref) {
655
743
  });
656
744
  var FeedbackThanks = forwardRef(function FeedbackThanks(arg0, ref) {
657
745
  const { className, ...props } = arg0;
746
+ const t = useBuiltInText();
658
747
  return /* @__PURE__ */ jsx("div", {
659
748
  ...props,
660
749
  ref,
661
750
  className: clsx(className, "clarify-feedback-thanks absolute inset-0 flex justify-center md:justify-start"),
662
751
  children: /* @__PURE__ */ jsxs("div", {
663
- className: "flex items-center gap-3 rounded-full bg-emerald-50/50 py-1 pr-3 pl-1.5 text-sm text-emerald-900 ring-1 ring-emerald-500/20 ring-inset dark:bg-emerald-500/5 dark:text-emerald-200 dark:ring-emerald-500/30",
664
- children: [/* @__PURE__ */ jsx(CheckIcon$1, { className: "h-5 w-5 flex-none fill-emerald-500 stroke-white dark:fill-emerald-200/20 dark:stroke-emerald-200" }), "Thanks for your feedback!"]
752
+ className: "flex items-center gap-3 rounded-full bg-(--clarify-ui-accent-background) py-1 pr-3 pl-1.5 text-sm text-(--clarify-ui-accent-text) ring-1 ring-(--clarify-ui-accent-border) ring-inset",
753
+ children: [/* @__PURE__ */ jsx(CheckIcon$1, { className: "h-5 w-5 flex-none fill-(--clarify-ui-accent-text) stroke-white dark:fill-(--clarify-ui-accent-background) dark:stroke-(--clarify-ui-accent-text)" }), t("feedback.thanks")]
665
754
  })
666
755
  });
667
756
  });
@@ -733,7 +822,7 @@ function HeroPattern() {
733
822
  children: /* @__PURE__ */ jsxs("div", {
734
823
  className: "absolute top-0 left-1/2 -ml-152 h-100 w-325 dark:mask-[linear-gradient(white,transparent)]",
735
824
  children: [/* @__PURE__ */ jsx("div", {
736
- className: "absolute inset-0 bg-linear-to-r from-[#36b49f] to-[#DBFF75] opacity-40 mask-[radial-gradient(farthest-side_at_top,white,transparent)] dark:from-[#36b49f]/30 dark:to-[#DBFF75]/30 dark:opacity-100",
825
+ className: "absolute inset-0 bg-[linear-gradient(to_right,var(--clarify-theme-tokens-colors-primary),var(--clarify-theme-tokens-colors-accent))] opacity-35 mask-[radial-gradient(farthest-side_at_top,white,transparent)] dark:opacity-55",
737
826
  children: /* @__PURE__ */ jsx(GridPattern, {
738
827
  width: 72,
739
828
  height: 56,
@@ -757,18 +846,6 @@ function HeroPattern() {
757
846
  });
758
847
  }
759
848
  //#endregion
760
- //#region source/context.tsx
761
- var ClarifyConfigContext = createContext(null);
762
- var OpenApisContext = createContext({});
763
- function useClarifyConfig() {
764
- const config = useContext(ClarifyConfigContext);
765
- if (!config) throw new Error("[clarify] useClarifyConfig must be used within a ClarifyConfigContext.Provider");
766
- return config;
767
- }
768
- function useOpenApis() {
769
- return useContext(OpenApisContext);
770
- }
771
- //#endregion
772
849
  //#region source/components/PageFooter.tsx
773
850
  function resolveLocalizedText$1(text, locale, fallbackLocale) {
774
851
  if (typeof text === "string") return text;
@@ -796,7 +873,7 @@ function FooterLink(arg0) {
796
873
  href: external ? link.href : localizeHref$1(link.href, config, locale),
797
874
  target: external ? "_blank" : void 0,
798
875
  rel: external ? "noreferrer" : void 0,
799
- className: "clarify-footer-link text-sm text-zinc-500 no-underline transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white",
876
+ className: "clarify-footer-link no-underline transition",
800
877
  children: resolveLocalizedText$1(link.label, locale, config.i18n?.defaultLocale)
801
878
  });
802
879
  }
@@ -806,7 +883,7 @@ function SocialLink(arg0) {
806
883
  href,
807
884
  target: "_blank",
808
885
  rel: "noreferrer",
809
- className: "clarify-footer-social text-sm capitalize text-zinc-500 no-underline transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white",
886
+ className: "clarify-footer-social capitalize no-underline transition",
810
887
  children: name
811
888
  });
812
889
  }
@@ -819,11 +896,11 @@ function PageFooter() {
819
896
  const copyright = footer?.copyright ? resolveLocalizedText$1(footer.copyright, locale, config.i18n?.defaultLocale) : void 0;
820
897
  const hasCustomFooter = Boolean(copyright || links.length > 0 || socials.length > 0);
821
898
  return /* @__PURE__ */ jsxs("footer", {
822
- className: clsx("clarify-page-footer mx-auto mt-16 flex w-full max-w-3xl flex-col items-end gap-4 border-t border-zinc-900/10 pt-8 xl:max-w-[56rem] 2xl:max-w-[64rem] dark:border-white/10", hasCustomFooter && "sm:flex-row sm:items-center sm:justify-between"),
899
+ className: clsx("clarify-page-footer mx-auto mt-16 flex w-full max-w-(--clarify-theme-layout-max-width) flex-col items-end gap-4 border-t border-(--clarify-theme-tokens-colors-border) px-4 py-8 sm:px-6 lg:mt-24 lg:px-5 dark:border-white/10", hasCustomFooter && "sm:flex-row sm:items-center sm:justify-between"),
823
900
  children: [hasCustomFooter ? /* @__PURE__ */ jsxs("div", {
824
901
  className: "clarify-footer-content flex flex-col gap-3 text-right sm:text-left",
825
902
  children: [copyright ? /* @__PURE__ */ jsx("p", {
826
- className: "clarify-footer-copyright m-0 text-sm text-zinc-500 dark:text-zinc-400",
903
+ className: "clarify-footer-copyright m-0",
827
904
  children: copyright
828
905
  }) : null, links.length > 0 || socials.length > 0 ? /* @__PURE__ */ jsxs("div", {
829
906
  className: "clarify-footer-links flex flex-wrap justify-end gap-x-4 gap-y-2 sm:justify-start",
@@ -843,6 +920,95 @@ function PageFooter() {
843
920
  });
844
921
  }
845
922
  //#endregion
923
+ //#region source/utils/path.ts
924
+ function normalizeRoutePath(path) {
925
+ const [pathname, suffix = ""] = path.split(/([?#].*)/, 2);
926
+ return `${pathname.replace(/^\/+/, "/").replace(/\/+$/, "") || "/"}${suffix}`;
927
+ }
928
+ function isSameRoutePath(a, b) {
929
+ if (!a || !b) return false;
930
+ return normalizeRoutePath(a) === normalizeRoutePath(b);
931
+ }
932
+ //#endregion
933
+ //#region source/components/PageNavigation.tsx
934
+ function flattenNavigation(nodes) {
935
+ return nodes.flatMap((node) => node.children?.length ? flattenNavigation(node.children) : [node]);
936
+ }
937
+ function PageNavigation(arg0) {
938
+ const { navigation, currentRoute } = arg0;
939
+ const t = useBuiltInText();
940
+ if (!currentRoute) return null;
941
+ const pageRoutes = flattenNavigation(navigation);
942
+ const currentIndex = pageRoutes.findIndex((route) => isSameRoutePath(route.path, currentRoute.path));
943
+ if (currentIndex === -1) return null;
944
+ const previous = pageRoutes[currentIndex - 1];
945
+ const next = pageRoutes[currentIndex + 1];
946
+ if (!previous && !next) return null;
947
+ return /* @__PURE__ */ jsxs("nav", {
948
+ className: "clarify-page-navigation mt-6 grid gap-3 @3xl:grid-cols-2",
949
+ "aria-label": t("navigation.previousNext"),
950
+ children: [/* @__PURE__ */ jsx(PageNavigationLink, {
951
+ direction: "previous",
952
+ route: previous
953
+ }), /* @__PURE__ */ jsx(PageNavigationLink, {
954
+ direction: "next",
955
+ route: next
956
+ })]
957
+ });
958
+ }
959
+ function PageNavigationLink(arg0) {
960
+ const { direction, route } = arg0;
961
+ const t = useBuiltInText();
962
+ if (!route) return /* @__PURE__ */ jsx("div", { className: "hidden @3xl:block" });
963
+ const isNext = direction === "next";
964
+ return /* @__PURE__ */ jsxs(Link, {
965
+ to: normalizeRoutePath(route.path),
966
+ className: clsx("group flex min-w-0 items-center gap-3 rounded-lg border border-(--clarify-theme-tokens-colors-border) px-4 py-3 no-underline transition hover:border-(--clarify-theme-tokens-colors-primary) hover:bg-(--clarify-theme-tokens-colors-surface) dark:border-white/10 dark:hover:border-(--clarify-theme-tokens-colors-primary) dark:hover:bg-white/2.5", isNext && "@3xl:justify-end @3xl:text-right"),
967
+ children: [
968
+ !isNext ? /* @__PURE__ */ jsx(ChevronLeft, { className: "h-3.5 w-3.5 shrink-0 text-(--clarify-theme-tokens-colors-muted) transition group-hover:text-(--clarify-theme-tokens-colors-primary)" }) : null,
969
+ /* @__PURE__ */ jsxs("span", {
970
+ className: "min-w-0 flex-1",
971
+ children: [/* @__PURE__ */ jsx("span", {
972
+ className: "block text-[0.6875rem] font-medium uppercase tracking-wide text-(--clarify-theme-tokens-colors-muted)",
973
+ children: isNext ? t("navigation.next") : t("navigation.previous")
974
+ }), /* @__PURE__ */ jsx("span", {
975
+ className: "mt-0.5 block truncate text-[0.8125rem] font-semibold text-(--clarify-theme-tokens-colors-foreground) dark:text-white",
976
+ children: route.title
977
+ })]
978
+ }),
979
+ isNext ? /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5 shrink-0 text-(--clarify-theme-tokens-colors-muted) transition group-hover:text-(--clarify-theme-tokens-colors-primary)" }) : null
980
+ ]
981
+ });
982
+ }
983
+ //#endregion
984
+ //#region source/components/SiteLogo.tsx
985
+ function SiteLogo(arg0) {
986
+ const { logo, className } = arg0;
987
+ if (!logo) return null;
988
+ if (typeof logo === "string") return /* @__PURE__ */ jsx("img", {
989
+ src: logo,
990
+ alt: "",
991
+ className: clsx("clarify-logo", className)
992
+ });
993
+ const lightLogo = logo.light ?? logo.dark;
994
+ const darkLogo = logo.dark ?? logo.light;
995
+ if (!lightLogo || !darkLogo) return null;
996
+ if (lightLogo === darkLogo) return /* @__PURE__ */ jsx("img", {
997
+ src: lightLogo,
998
+ alt: "",
999
+ className: clsx("clarify-logo", className)
1000
+ });
1001
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("img", {
1002
+ src: lightLogo,
1003
+ alt: "",
1004
+ className: clsx("clarify-logo clarify-logo-light", className, "dark:hidden")
1005
+ }), /* @__PURE__ */ jsx("img", {
1006
+ src: darkLogo,
1007
+ alt: "",
1008
+ className: clsx("clarify-logo clarify-logo-dark", className, "hidden dark:block")
1009
+ })] });
1010
+ }
1011
+ //#endregion
846
1012
  //#region source/components/ThemeProvider.tsx
847
1013
  var ThemeContext = createContext(null);
848
1014
  var storageKey = "clarify:theme";
@@ -921,15 +1087,16 @@ function MoonIcon(props) {
921
1087
  }
922
1088
  function ThemeToggle() {
923
1089
  const { resolvedTheme, setTheme } = useTheme();
1090
+ const t = useBuiltInText();
924
1091
  const otherTheme = resolvedTheme === "dark" ? "light" : "dark";
925
1092
  return /* @__PURE__ */ jsxs("button", {
926
1093
  type: "button",
927
- className: "clarify-theme-toggle flex size-6 items-center justify-center rounded-md transition hover:bg-zinc-900/5 dark:hover:bg-white/5",
928
- "aria-label": `Switch to ${otherTheme} theme`,
1094
+ className: "clarify-theme-toggle relative flex size-8 items-center justify-center rounded-(--clarify-theme-tokens-radius-md) transition hover:bg-[color-mix(in_srgb,var(--clarify-theme-tokens-colors-foreground)_5%,transparent)] dark:hover:bg-white/5",
1095
+ "aria-label": otherTheme === "dark" ? t("theme.switchToDark") : t("theme.switchToLight"),
929
1096
  onClick: () => setTheme(otherTheme),
930
1097
  children: [
931
1098
  /* @__PURE__ */ jsx("span", { className: "absolute size-12 pointer-fine:hidden" }),
932
- /* @__PURE__ */ jsx(SunIcon, { className: "h-5 w-5 stroke-zinc-900 dark:hidden" }),
1099
+ /* @__PURE__ */ jsx(SunIcon, { className: "h-5 w-5 stroke-(--clarify-theme-tokens-colors-foreground) dark:hidden" }),
933
1100
  /* @__PURE__ */ jsx(MoonIcon, { className: "hidden h-5 w-5 stroke-white dark:block" })
934
1101
  ]
935
1102
  });
@@ -951,11 +1118,11 @@ function ArrowIcon(props) {
951
1118
  });
952
1119
  }
953
1120
  var buttonVariantStyles = {
954
- primary: "rounded-full bg-zinc-900 px-3 py-1 text-white hover:bg-zinc-700 dark:bg-emerald-400/10 dark:text-emerald-400 dark:ring-1 dark:ring-inset dark:ring-emerald-400/20 dark:hover:text-emerald-300 dark:hover:ring-emerald-300",
955
- secondary: "rounded-full bg-zinc-100 px-3 py-1 text-zinc-900 hover:bg-zinc-200 dark:bg-zinc-800/40 dark:text-zinc-400 dark:ring-1 dark:ring-inset dark:ring-zinc-800 dark:hover:bg-zinc-800 dark:hover:text-zinc-300",
956
- filled: "rounded-full bg-zinc-900 px-3 py-1 text-white hover:bg-zinc-700 dark:bg-emerald-500 dark:hover:bg-emerald-400",
957
- outline: "rounded-full px-3 py-1 text-zinc-700 ring-1 ring-inset ring-zinc-900/10 hover:bg-zinc-900/2.5 hover:text-zinc-900 dark:text-zinc-400 dark:ring-white/10 dark:hover:bg-white/5 dark:hover:text-white",
958
- text: "text-emerald-500 hover:text-emerald-600 dark:text-emerald-400 dark:hover:text-emerald-500"
1121
+ primary: "rounded-full bg-(--clarify-theme-tokens-colors-foreground) px-3 py-1 text-white hover:opacity-80 dark:bg-(--clarify-theme-tokens-colors-primary)/10 dark:text-(--clarify-theme-tokens-colors-primary) dark:ring-1 dark:ring-inset dark:ring-(--clarify-theme-tokens-colors-primary)/20 dark:hover:opacity-80",
1122
+ secondary: "rounded-full bg-(--clarify-theme-tokens-colors-code-background) px-3 py-1 text-(--clarify-theme-tokens-colors-foreground) hover:opacity-80 dark:bg-zinc-800/40 dark:text-zinc-400 dark:ring-1 dark:ring-inset dark:ring-zinc-800 dark:hover:bg-zinc-800 dark:hover:text-zinc-300",
1123
+ filled: "rounded-full bg-(--clarify-theme-tokens-colors-foreground) px-3 py-1 text-white hover:opacity-80 dark:bg-(--clarify-theme-tokens-colors-primary) dark:hover:opacity-80",
1124
+ outline: "rounded-full px-3 py-1 text-(--clarify-theme-tokens-colors-muted) ring-1 ring-inset ring-(--clarify-theme-tokens-colors-border) hover:bg-[color-mix(in_srgb,var(--clarify-theme-tokens-colors-foreground)_2.5%,transparent)] hover:text-(--clarify-theme-tokens-colors-foreground) dark:text-zinc-400 dark:ring-white/10 dark:hover:bg-white/5 dark:hover:text-white",
1125
+ text: "text-(--clarify-theme-tokens-colors-primary) hover:opacity-80 dark:text-(--clarify-theme-tokens-colors-primary) dark:hover:opacity-80"
959
1126
  };
960
1127
  function Button(arg0) {
961
1128
  const { variant = "primary", className, children, arrow, ...props } = arg0;
@@ -999,8 +1166,8 @@ var tagColorStyles = {
999
1166
  medium: "bg-rose-50 text-red-500 ring-rose-200 dark:bg-rose-400/10 dark:text-rose-400 dark:ring-rose-500/20"
1000
1167
  },
1001
1168
  zinc: {
1002
- small: "text-zinc-400 dark:text-zinc-500",
1003
- medium: "bg-zinc-50 text-zinc-500 ring-zinc-200 dark:bg-zinc-400/10 dark:text-zinc-400 dark:ring-zinc-500/20"
1169
+ small: "text-(--clarify-theme-tokens-colors-muted) dark:text-zinc-500",
1170
+ medium: "bg-(--clarify-theme-tokens-colors-code-background) text-(--clarify-theme-tokens-colors-muted) ring-(--clarify-theme-tokens-colors-border) dark:bg-zinc-400/10 dark:text-zinc-400 dark:ring-zinc-500/20"
1004
1171
  }
1005
1172
  };
1006
1173
  var tagValueColorMap = {
@@ -1015,7 +1182,7 @@ function Tag(arg0) {
1015
1182
  const value = typeof children === "string" ? children.toUpperCase() : "";
1016
1183
  const resolvedColor = color ?? tagValueColorMap[value] ?? "emerald";
1017
1184
  return /* @__PURE__ */ jsx("span", {
1018
- className: clsx("clarify-tag font-mono text-[0.625rem]/6 font-semibold", tagVariantStyles[variant], tagColorStyles[resolvedColor][variant]),
1185
+ className: clsx("clarify-tag font-mono text-[0.625rem]/6 font-bold", tagVariantStyles[variant], tagColorStyles[resolvedColor][variant]),
1019
1186
  children
1020
1187
  });
1021
1188
  }
@@ -1026,10 +1193,10 @@ function Logo(props) {
1026
1193
  ...props,
1027
1194
  className: clsx("clarify-logo", props.className),
1028
1195
  children: [/* @__PURE__ */ jsx("path", {
1029
- className: "fill-emerald-400",
1196
+ className: "fill-(--clarify-theme-tokens-colors-primary)",
1030
1197
  d: "M16 8a5 5 0 0 0-5-5H5a5 5 0 0 0-5 5v13.927a1 1 0 0 0 1.623.782l3.684-2.93a4 4 0 0 1 2.49-.87H11a5 5 0 0 0 5-5V8Z"
1031
1198
  }), /* @__PURE__ */ jsx("path", {
1032
- className: "fill-zinc-900 dark:fill-white",
1199
+ className: "fill-(--clarify-theme-tokens-colors-foreground) dark:fill-white",
1033
1200
  d: "M26.538 18h2.654v-3.999h2.576c2.672 0 4.456-1.723 4.456-4.333V9.65c0-2.61-1.784-4.333-4.456-4.333h-5.23V18Zm4.58-10.582c1.52 0 2.416.8 2.416 2.241v.018c0 1.441-.896 2.25-2.417 2.25h-1.925V7.418h1.925ZM38.051 18h2.566v-5.414c0-1.371.923-2.206 2.382-2.206.396 0 .791.061 1.178.15V8.287a3.843 3.843 0 0 0-.958-.123c-1.257 0-2.136.615-2.443 1.661h-.159V8.323h-2.566V18Zm11.55.202c2.979 0 4.772-1.88 4.772-5.036v-.018c0-3.128-1.82-5.036-4.773-5.036-2.953 0-4.772 1.916-4.772 5.036v.018c0 3.146 1.793 5.036 4.772 5.036Zm0-2.013c-1.372 0-2.145-1.116-2.145-3.023v-.018c0-1.89.782-3.023 2.144-3.023 1.354 0 2.145 1.134 2.145 3.023v.018c0 1.907-.782 3.023-2.145 3.023Zm10.52 1.846c.492 0 .967-.053 1.283-.114v-1.907a6.057 6.057 0 0 1-.755.044c-.87 0-1.24-.387-1.24-1.257v-4.544h1.995V8.323H59.41V6.012h-2.592v2.311h-1.495v1.934h1.495v5.133c0 1.88.949 2.645 3.304 2.645Zm7.287.167c2.98 0 4.772-1.88 4.772-5.036v-.018c0-3.128-1.82-5.036-4.772-5.036-2.954 0-4.773 1.916-4.773 5.036v.018c0 3.146 1.793 5.036 4.773 5.036Zm0-2.013c-1.372 0-2.145-1.116-2.145-3.023v-.018c0-1.89.782-3.023 2.145-3.023 1.353 0 2.144 1.134 2.144 3.023v.018c0 1.907-.782 3.023-2.144 3.023Zm10.767 2.013c2.522 0 4.034-1.353 4.297-3.463l.01-.053h-2.374l-.017.036c-.229.966-.853 1.467-1.908 1.467-1.37 0-2.135-1.08-2.135-3.04v-.018c0-1.934.755-3.006 2.135-3.006 1.099 0 1.74.615 1.908 1.556l.008.017h2.391v-.026c-.228-2.162-1.749-3.56-4.315-3.56-3.033 0-4.738 1.837-4.738 5.019v.017c0 3.217 1.714 5.054 4.738 5.054Zm10.257 0c2.98 0 4.772-1.88 4.772-5.036v-.018c0-3.128-1.82-5.036-4.772-5.036-2.953 0-4.773 1.916-4.773 5.036v.018c0 3.146 1.793 5.036 4.773 5.036Zm0-2.013c-1.371 0-2.145-1.116-2.145-3.023v-.018c0-1.89.782-3.023 2.145-3.023 1.353 0 2.144 1.134 2.144 3.023v.018c0 1.907-.782 3.023-2.144 3.023ZM95.025 18h2.566V4.623h-2.566V18Z"
1034
1201
  })]
1035
1202
  });
@@ -1037,7 +1204,7 @@ function Logo(props) {
1037
1204
  function Prose(arg0) {
1038
1205
  const { as, className, ...props } = arg0;
1039
1206
  return /* @__PURE__ */ jsx(as ?? "div", {
1040
- className: clsx(className, "clarify-prose prose dark:prose-invert", "[html_:where(&>*)]:mx-auto [html_:where(&>*)]:w-full [html_:where(&>*)]:max-w-3xl xl:[html_:where(&>*)]:max-w-[56rem] 2xl:[html_:where(&>*)]:max-w-[64rem] [html_:where(&>.not-prose)]:max-w-5xl 2xl:[html_:where(&>.not-prose)]:max-w-[76rem]"),
1207
+ className: clsx(className, "clarify-prose prose max-w-none dark:prose-invert", "[html_:where(&>*)]:w-full [html_:where(&>*)]:min-w-0 [html_:where(&>*)]:max-w-full"),
1041
1208
  ...props
1042
1209
  });
1043
1210
  }
@@ -1081,7 +1248,7 @@ function Anchor(arg0) {
1081
1248
  });
1082
1249
  }
1083
1250
  function Heading(arg0) {
1084
- const { children, tag, label, level, anchor = true, ...props } = arg0;
1251
+ const { children, className, tag, label, level, anchor = true, ...props } = arg0;
1085
1252
  const resolvedLevel = level ?? 2;
1086
1253
  const Component = `h${resolvedLevel}`;
1087
1254
  const ref = useRef(null);
@@ -1108,7 +1275,7 @@ function Heading(arg0) {
1108
1275
  label
1109
1276
  }), /* @__PURE__ */ jsx(Component, {
1110
1277
  ref,
1111
- className: clsx("clarify-heading", tag || label ? "mt-2 scroll-mt-32" : "scroll-mt-24"),
1278
+ className: clsx("clarify-heading", tag || label ? "mt-2 scroll-mt-32" : "scroll-mt-24", className),
1112
1279
  ...props,
1113
1280
  children: anchor ? /* @__PURE__ */ jsx(Anchor, {
1114
1281
  id: props.id,
@@ -1154,7 +1321,158 @@ function ApiEndpointCard(arg0) {
1154
1321
  });
1155
1322
  }
1156
1323
  //#endregion
1157
- //#region source/shell/Navigation.tsx
1324
+ //#region source/shell/ContentActions.tsx
1325
+ function resolveContentArtifactUrl(contentArtifactUrl, routePrefix = "/") {
1326
+ if (!routePrefix || routePrefix === "/") return contentArtifactUrl;
1327
+ return `/${routePrefix.replace(/^\/+|\/+$/g, "")}${contentArtifactUrl}`;
1328
+ }
1329
+ function getAbsoluteUrl(path) {
1330
+ if (typeof window === "undefined") return path;
1331
+ return new URL(path, window.location.href).href;
1332
+ }
1333
+ async function copyText(text) {
1334
+ await navigator.clipboard.writeText(text);
1335
+ }
1336
+ function ContentActions(arg0) {
1337
+ const { hasTabs = false, route, routePrefix } = arg0;
1338
+ const t = useBuiltInText();
1339
+ const [copied, setCopied] = useState("idle");
1340
+ if (!route?.contentArtifactUrl) return null;
1341
+ const contentArtifactUrl = resolveContentArtifactUrl(route.contentArtifactUrl, routePrefix);
1342
+ const isOpenApi = route.kind === "openapi";
1343
+ const replacements = { contentType: isOpenApi ? "OpenAPI" : "Markdown" };
1344
+ const viewLabel = isOpenApi ? t("contentActions.viewOpenApi") : t("contentActions.viewMarkdown");
1345
+ const viewDescription = isOpenApi ? t("contentActions.viewOpenApiDescription") : t("contentActions.viewMarkdownDescription");
1346
+ function markCopied(state) {
1347
+ setCopied(state);
1348
+ window.setTimeout(() => setCopied("idle"), 1600);
1349
+ }
1350
+ async function handleCopyContent() {
1351
+ await copyText(await (await fetch(contentArtifactUrl)).text());
1352
+ markCopied("content");
1353
+ }
1354
+ async function handleCopyLink() {
1355
+ await copyText(getAbsoluteUrl(contentArtifactUrl));
1356
+ markCopied("link");
1357
+ }
1358
+ const actions = [{
1359
+ key: "content",
1360
+ label: t("contentActions.copyContent"),
1361
+ description: t("contentActions.copyContentDescription", replacements),
1362
+ icon: Copy,
1363
+ run: handleCopyContent
1364
+ }, {
1365
+ key: "link",
1366
+ label: t("contentActions.copyLink", replacements),
1367
+ description: t("contentActions.copyLinkDescription", replacements),
1368
+ icon: Link2,
1369
+ run: handleCopyLink
1370
+ }];
1371
+ const primaryAction = actions[0];
1372
+ const PrimaryIcon = copied === primaryAction.key ? Check : primaryAction.icon;
1373
+ return /* @__PURE__ */ jsx("div", {
1374
+ className: `clarify-content-actions sticky z-20 flex justify-end py-4 ${hasTabs ? "top-16 lg:top-30" : "top-16"}`,
1375
+ children: /* @__PURE__ */ jsxs(Menu, {
1376
+ as: "div",
1377
+ className: "clarify-content-actions-menu relative inline-flex text-sm font-medium",
1378
+ children: [/* @__PURE__ */ jsxs("div", {
1379
+ className: "clarify-content-actions-group inline-flex overflow-hidden rounded-full border border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-surface)/90 shadow-sm shadow-zinc-900/5 backdrop-blur dark:border-white/10 dark:bg-zinc-900/80 dark:shadow-none",
1380
+ children: [/* @__PURE__ */ jsxs("button", {
1381
+ type: "button",
1382
+ onClick: primaryAction.run,
1383
+ className: "clarify-content-actions-primary clarify-ui-control inline-flex h-8 items-center gap-1.5 px-3 transition",
1384
+ children: [/* @__PURE__ */ jsx(PrimaryIcon, { className: "h-3.5 w-3.5" }), copied === primaryAction.key ? t("actions.copied") : primaryAction.label]
1385
+ }), /* @__PURE__ */ jsx(MenuButton, {
1386
+ className: "clarify-content-actions-trigger clarify-ui-control inline-flex h-8 w-8 items-center justify-center border-l border-(--clarify-theme-tokens-colors-border) transition dark:border-white/10",
1387
+ "aria-label": t("contentActions.copyOptions"),
1388
+ children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5" })
1389
+ })]
1390
+ }), /* @__PURE__ */ jsxs(MenuItems, {
1391
+ anchor: "bottom end",
1392
+ className: "clarify-content-actions-list clarify-ui-menu z-30 mt-2 w-(--clarify-ui-action-menu-width) origin-top-right rounded-(--clarify-theme-tokens-radius-xl) border border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-surface) p-1.5 shadow-xl shadow-zinc-900/5 transition [--anchor-gap:--spacing(2)] focus:outline-none data-closed:scale-95 data-closed:opacity-0 dark:border-white/10 dark:bg-zinc-900 dark:shadow-none",
1393
+ children: [
1394
+ actions.slice(0, 1).map((action) => {
1395
+ const Icon = action.icon;
1396
+ const isCopied = copied === action.key;
1397
+ return /* @__PURE__ */ jsx(MenuItem, { children: /* @__PURE__ */ jsxs("button", {
1398
+ type: "button",
1399
+ onClick: action.run,
1400
+ className: "clarify-content-actions-item clarify-ui-menu-item group flex w-full items-center gap-2 rounded-(--clarify-theme-tokens-radius-lg) px-1.5 py-1.5 text-left transition",
1401
+ children: [
1402
+ /* @__PURE__ */ jsx("span", {
1403
+ className: "clarify-ui-menu-icon flex shrink-0 rounded-(--clarify-theme-tokens-radius-md) border border-(--clarify-theme-tokens-colors-border) p-1.5 dark:border-white/10",
1404
+ children: /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4" })
1405
+ }),
1406
+ /* @__PURE__ */ jsxs("span", {
1407
+ className: "flex min-w-0 flex-1 flex-col px-1",
1408
+ children: [/* @__PURE__ */ jsx("span", {
1409
+ className: "clarify-ui-menu-title",
1410
+ children: isCopied ? t("contentActions.copiedContent") : action.label
1411
+ }), /* @__PURE__ */ jsx("span", {
1412
+ className: "clarify-ui-menu-description truncate",
1413
+ children: action.description
1414
+ })]
1415
+ }),
1416
+ /* @__PURE__ */ jsx(Check, { className: `h-3.5 w-3.5 shrink-0 text-(--clarify-theme-tokens-colors-primary) transition ${isCopied ? "opacity-100" : "opacity-0"}` })
1417
+ ]
1418
+ }) }, action.key);
1419
+ }),
1420
+ /* @__PURE__ */ jsx(MenuItem, { children: /* @__PURE__ */ jsxs("a", {
1421
+ href: contentArtifactUrl,
1422
+ target: "_blank",
1423
+ rel: "noreferrer",
1424
+ className: "clarify-content-actions-item clarify-ui-menu-item group flex w-full items-center gap-2 rounded-(--clarify-theme-tokens-radius-lg) px-1.5 py-1.5 text-left no-underline transition",
1425
+ children: [
1426
+ /* @__PURE__ */ jsx("span", {
1427
+ className: "clarify-ui-menu-icon flex shrink-0 rounded-(--clarify-theme-tokens-radius-md) border border-(--clarify-theme-tokens-colors-border) p-1.5 dark:border-white/10",
1428
+ children: /* @__PURE__ */ jsx(FileText, { className: "h-4 w-4" })
1429
+ }),
1430
+ /* @__PURE__ */ jsxs("span", {
1431
+ className: "flex min-w-0 flex-1 flex-col px-1",
1432
+ children: [/* @__PURE__ */ jsxs("span", {
1433
+ className: "clarify-ui-menu-title flex items-center gap-1",
1434
+ children: [viewLabel, /* @__PURE__ */ jsx(ExternalLink, { className: "clarify-ui-menu-icon h-3 w-3" })]
1435
+ }), /* @__PURE__ */ jsx("span", {
1436
+ className: "clarify-ui-menu-description truncate",
1437
+ children: viewDescription
1438
+ })]
1439
+ }),
1440
+ /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 shrink-0 text-(--clarify-theme-tokens-colors-primary) opacity-0" })
1441
+ ]
1442
+ }) }),
1443
+ actions.slice(1).map((action) => {
1444
+ const Icon = action.icon;
1445
+ const isCopied = copied === action.key;
1446
+ return /* @__PURE__ */ jsx(MenuItem, { children: /* @__PURE__ */ jsxs("button", {
1447
+ type: "button",
1448
+ onClick: action.run,
1449
+ className: "clarify-content-actions-item clarify-ui-menu-item group flex w-full items-center gap-2 rounded-(--clarify-theme-tokens-radius-lg) px-1.5 py-1.5 text-left transition",
1450
+ children: [
1451
+ /* @__PURE__ */ jsx("span", {
1452
+ className: "clarify-ui-menu-icon flex shrink-0 rounded-(--clarify-theme-tokens-radius-md) border border-(--clarify-theme-tokens-colors-border) p-1.5 dark:border-white/10",
1453
+ children: /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4" })
1454
+ }),
1455
+ /* @__PURE__ */ jsxs("span", {
1456
+ className: "flex min-w-0 flex-1 flex-col px-1",
1457
+ children: [/* @__PURE__ */ jsx("span", {
1458
+ className: "clarify-ui-menu-title",
1459
+ children: isCopied ? t("contentActions.copiedLink") : action.label
1460
+ }), /* @__PURE__ */ jsx("span", {
1461
+ className: "clarify-ui-menu-description truncate",
1462
+ children: action.description
1463
+ })]
1464
+ }),
1465
+ /* @__PURE__ */ jsx(Check, { className: `h-3.5 w-3.5 shrink-0 text-(--clarify-theme-tokens-colors-primary) transition ${isCopied ? "opacity-100" : "opacity-0"}` })
1466
+ ]
1467
+ }) }, action.key);
1468
+ })
1469
+ ]
1470
+ })]
1471
+ })
1472
+ });
1473
+ }
1474
+ //#endregion
1475
+ //#region source/shell/icons.tsx
1158
1476
  function NavigationIcon(arg0) {
1159
1477
  const { name, className } = arg0;
1160
1478
  if (!name) return null;
@@ -1165,6 +1483,8 @@ function NavigationIcon(arg0) {
1165
1483
  "aria-hidden": "true"
1166
1484
  });
1167
1485
  }
1486
+ //#endregion
1487
+ //#region source/shell/Navigation.tsx
1168
1488
  function useInitialValue(value, condition = true) {
1169
1489
  const [initialValue] = useState(value);
1170
1490
  return condition ? initialValue : value;
@@ -1172,11 +1492,11 @@ function useInitialValue(value, condition = true) {
1172
1492
  function normalizePath(path) {
1173
1493
  return path === "" ? "/" : path;
1174
1494
  }
1175
- function navigationToGroups(navigation) {
1495
+ function navigationToGroups(navigation, defaultTitle) {
1176
1496
  return navigation.map((node) => {
1177
1497
  const children = node.children?.length ? node.children : [node];
1178
1498
  return {
1179
- title: node.children?.length ? node.title : "Documentation",
1499
+ title: node.children?.length ? node.title : defaultTitle,
1180
1500
  icon: node.icon,
1181
1501
  links: children.map((child) => ({
1182
1502
  title: child.title,
@@ -1186,18 +1506,6 @@ function navigationToGroups(navigation) {
1186
1506
  };
1187
1507
  });
1188
1508
  }
1189
- function TopLevelNavItem$1(arg0) {
1190
- const { href, children } = arg0;
1191
- return /* @__PURE__ */ jsx("li", {
1192
- className: "md:hidden",
1193
- children: /* @__PURE__ */ jsx(CloseButton, {
1194
- as: Link,
1195
- to: href,
1196
- className: "block py-1 text-sm text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white",
1197
- children
1198
- })
1199
- });
1200
- }
1201
1509
  var sectionBadgeColorStyles = {
1202
1510
  GET: "text-emerald-500 dark:text-emerald-400",
1203
1511
  POST: "text-sky-500 dark:text-sky-400",
@@ -1211,7 +1519,7 @@ var sectionBadgeColorStyles = {
1211
1519
  function SectionBadge(arg0) {
1212
1520
  const { children } = arg0;
1213
1521
  return /* @__PURE__ */ jsx("span", {
1214
- className: clsx("inline-flex shrink-0 justify-end font-mono text-[0.625rem]/6 font-semibold uppercase tracking-wide", sectionBadgeColorStyles[children.toUpperCase()] ?? "text-zinc-500 dark:text-zinc-400"),
1522
+ className: clsx("clarify-navigation-section-badge inline-flex shrink-0 justify-end font-mono font-semibold uppercase tracking-wide", sectionBadgeColorStyles[children.toUpperCase()] ?? "clarify-ui-menu-description"),
1215
1523
  children
1216
1524
  });
1217
1525
  }
@@ -1224,6 +1532,9 @@ function NavLink(arg0) {
1224
1532
  const targetId = decodeURIComponent(href.slice(hashIndex + 1));
1225
1533
  window.requestAnimationFrame(() => {
1226
1534
  document.getElementById(targetId)?.scrollIntoView();
1535
+ window.requestAnimationFrame(() => {
1536
+ window.dispatchEvent(new Event("scroll"));
1537
+ });
1227
1538
  });
1228
1539
  }
1229
1540
  return /* @__PURE__ */ jsxs(CloseButton, {
@@ -1231,7 +1542,7 @@ function NavLink(arg0) {
1231
1542
  to: href,
1232
1543
  "aria-current": active ? "page" : void 0,
1233
1544
  onClick: handleClick,
1234
- className: clsx("clarify-navigation-link flex justify-between gap-2 py-1 pr-3 text-sm transition", isAnchorLink ? "clarify-navigation-anchor-link pl-7" : "pl-4", active ? "text-zinc-900 dark:text-white" : "text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white"),
1545
+ className: clsx("clarify-navigation-link flex h-8 items-center justify-between gap-2 pr-3 transition", isAnchorLink ? "clarify-navigation-anchor-link pl-7" : "pl-4"),
1235
1546
  children: [/* @__PURE__ */ jsxs("span", {
1236
1547
  className: "flex min-w-0 flex-1 items-center gap-2",
1237
1548
  children: [
@@ -1262,7 +1573,7 @@ function VisibleSectionHighlight(arg0) {
1262
1573
  const firstVisibleSectionIndex = Math.max(0, [{ id: "_top" }, ...sections].findIndex((section) => section.id === visibleSections[0]));
1263
1574
  const itemHeight = remToPx(2);
1264
1575
  const height = isPresent ? Math.max(1, visibleSections.length) * itemHeight : itemHeight;
1265
- const top = group.links.findIndex((link) => link.href === pathname) * itemHeight + firstVisibleSectionIndex * itemHeight;
1576
+ const top = group.links.findIndex((link) => isSameRoutePath(link.href, pathname)) * itemHeight + firstVisibleSectionIndex * itemHeight;
1266
1577
  return /* @__PURE__ */ jsx(motion.div, {
1267
1578
  layout: true,
1268
1579
  initial: { opacity: 0 },
@@ -1271,9 +1582,9 @@ function VisibleSectionHighlight(arg0) {
1271
1582
  transition: { delay: .2 }
1272
1583
  },
1273
1584
  exit: { opacity: 0 },
1274
- className: "absolute inset-x-0 top-0 bg-zinc-800/2.5 will-change-transform dark:bg-white/2.5",
1585
+ className: "clarify-navigation-section-highlight absolute inset-x-0 top-0 will-change-transform",
1275
1586
  style: {
1276
- borderRadius: 8,
1587
+ borderRadius: "var(--clarify-theme-tokens-radius-sm)",
1277
1588
  height,
1278
1589
  top
1279
1590
  }
@@ -1282,10 +1593,10 @@ function VisibleSectionHighlight(arg0) {
1282
1593
  function ActivePageMarker(arg0) {
1283
1594
  const { group, pathname } = arg0;
1284
1595
  const itemHeight = remToPx(2);
1285
- const top = remToPx(.25) + group.links.findIndex((link) => link.href === pathname) * itemHeight;
1596
+ const top = remToPx(.25) + group.links.findIndex((link) => isSameRoutePath(link.href, pathname)) * itemHeight;
1286
1597
  return /* @__PURE__ */ jsx(motion.div, {
1287
1598
  layout: true,
1288
- className: "absolute left-2 h-6 w-px bg-emerald-500",
1599
+ className: "absolute left-2 h-6 w-px bg-(--clarify-theme-tokens-colors-primary)",
1289
1600
  initial: { opacity: 0 },
1290
1601
  animate: {
1291
1602
  opacity: 1,
@@ -1298,16 +1609,16 @@ function ActivePageMarker(arg0) {
1298
1609
  function NavigationGroup(arg0) {
1299
1610
  const { group, className } = arg0;
1300
1611
  const isInsideMobileNavigation = useIsInsideMobileNavigation();
1301
- const [pathname, sections] = useInitialValue([useLocation().pathname, useSectionStore((s) => s.sections)], isInsideMobileNavigation);
1302
- const isActiveGroup = group.links.findIndex((link) => link.href === pathname) !== -1;
1612
+ const [pathname, sections] = useInitialValue([normalizeRoutePath(useLocation().pathname), useSectionStore((s) => s.sections)], isInsideMobileNavigation);
1613
+ const isActiveGroup = group.links.findIndex((link) => isSameRoutePath(link.href, pathname)) !== -1;
1303
1614
  return /* @__PURE__ */ jsxs("li", {
1304
1615
  className: clsx("clarify-navigation-group relative mt-6", className),
1305
1616
  children: [/* @__PURE__ */ jsxs(motion.h2, {
1306
1617
  layout: "position",
1307
- className: "clarify-navigation-group-title flex items-center gap-2 text-xs font-semibold text-zinc-900 dark:text-white",
1618
+ className: "clarify-navigation-group-title flex items-center gap-2",
1308
1619
  children: [/* @__PURE__ */ jsx(NavigationIcon, {
1309
1620
  name: group.icon,
1310
- className: "h-3.5 w-3.5"
1621
+ className: "clarify-navigation-group-title-icon h-3.5 w-3.5"
1311
1622
  }), /* @__PURE__ */ jsx("span", { children: group.title })]
1312
1623
  }), /* @__PURE__ */ jsxs("div", {
1313
1624
  className: "relative mt-3 pl-2",
@@ -1321,7 +1632,7 @@ function NavigationGroup(arg0) {
1321
1632
  }),
1322
1633
  /* @__PURE__ */ jsx(motion.div, {
1323
1634
  layout: true,
1324
- className: "absolute inset-y-0 left-2 w-px bg-zinc-900/10 dark:bg-white/5"
1635
+ className: "absolute inset-y-0 left-2 w-px bg-(--clarify-theme-tokens-colors-border) dark:bg-white/5"
1325
1636
  }),
1326
1637
  /* @__PURE__ */ jsx(AnimatePresence, {
1327
1638
  initial: false,
@@ -1333,38 +1644,41 @@ function NavigationGroup(arg0) {
1333
1644
  /* @__PURE__ */ jsx("ul", {
1334
1645
  role: "list",
1335
1646
  className: "border-l border-transparent",
1336
- children: group.links.map((link) => /* @__PURE__ */ jsxs(motion.li, {
1337
- layout: "position",
1338
- className: "relative",
1339
- children: [/* @__PURE__ */ jsx(NavLink, {
1340
- href: link.href,
1341
- icon: link.icon,
1342
- active: link.href === pathname,
1343
- children: link.title
1344
- }), /* @__PURE__ */ jsx(AnimatePresence, {
1345
- mode: "popLayout",
1346
- initial: false,
1347
- children: link.href === pathname && sections.length > 0 ? /* @__PURE__ */ jsx(motion.ul, {
1348
- role: "list",
1349
- initial: { opacity: 0 },
1350
- animate: {
1351
- opacity: 1,
1352
- transition: { delay: .1 }
1353
- },
1354
- exit: {
1355
- opacity: 0,
1356
- transition: { duration: .15 }
1357
- },
1358
- children: sections.map((section) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(NavLink, {
1359
- href: `${link.href}#${section.id}`,
1360
- badge: section.badge,
1361
- tags: section.tags,
1362
- isAnchorLink: true,
1363
- children: section.title
1364
- }) }, section.id))
1365
- }) : null
1366
- })]
1367
- }, link.href))
1647
+ children: group.links.map((link) => {
1648
+ const active = isSameRoutePath(link.href, pathname);
1649
+ return /* @__PURE__ */ jsxs(motion.li, {
1650
+ layout: "position",
1651
+ className: "relative",
1652
+ children: [/* @__PURE__ */ jsx(NavLink, {
1653
+ href: link.href,
1654
+ icon: link.icon,
1655
+ active,
1656
+ children: link.title
1657
+ }), /* @__PURE__ */ jsx(AnimatePresence, {
1658
+ mode: "popLayout",
1659
+ initial: false,
1660
+ children: active && sections.length > 0 ? /* @__PURE__ */ jsx(motion.ul, {
1661
+ role: "list",
1662
+ initial: { opacity: 0 },
1663
+ animate: {
1664
+ opacity: 1,
1665
+ transition: { delay: .1 }
1666
+ },
1667
+ exit: {
1668
+ opacity: 0,
1669
+ transition: { duration: .15 }
1670
+ },
1671
+ children: sections.map((section) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(NavLink, {
1672
+ href: `${link.href}#${section.id}`,
1673
+ badge: section.badge,
1674
+ tags: section.tags,
1675
+ isAnchorLink: true,
1676
+ children: section.title
1677
+ }) }, section.id))
1678
+ }) : null
1679
+ })]
1680
+ }, link.href);
1681
+ })
1368
1682
  })
1369
1683
  ]
1370
1684
  })]
@@ -1372,19 +1686,16 @@ function NavigationGroup(arg0) {
1372
1686
  }
1373
1687
  function Navigation(arg0) {
1374
1688
  const { navigation, className } = arg0;
1375
- const groups = navigationToGroups(navigation);
1689
+ const groups = navigationToGroups(navigation, useBuiltInText()("navigation.documentation"));
1376
1690
  return /* @__PURE__ */ jsx("nav", {
1377
1691
  className: clsx("clarify-navigation", className),
1378
- children: /* @__PURE__ */ jsxs("ul", {
1692
+ children: /* @__PURE__ */ jsx("ul", {
1379
1693
  role: "list",
1380
1694
  className: "clarify-navigation-list",
1381
- children: [/* @__PURE__ */ jsx(TopLevelNavItem$1, {
1382
- href: "/",
1383
- children: "Home"
1384
- }), groups.map((group, groupIndex) => /* @__PURE__ */ jsx(NavigationGroup, {
1695
+ children: groups.map((group, groupIndex) => /* @__PURE__ */ jsx(NavigationGroup, {
1385
1696
  group,
1386
- className: groupIndex === 0 ? "md:mt-0" : ""
1387
- }, group.title))]
1697
+ className: groupIndex === 0 ? "mt-0" : ""
1698
+ }, group.title))
1388
1699
  })
1389
1700
  });
1390
1701
  }
@@ -1411,8 +1722,84 @@ function XIcon(props) {
1411
1722
  });
1412
1723
  }
1413
1724
  var IsInsideMobileNavigationContext = createContext(false);
1725
+ function hasPath$2(nodes, pathname) {
1726
+ return nodes.some((node) => isSameRoutePath(node.path, pathname) || hasPath$2(node.children ?? [], pathname));
1727
+ }
1728
+ function isActiveTab$1(tab, pathname) {
1729
+ return isSameRoutePath(tab.path, pathname) || hasPath$2(tab.children, pathname);
1730
+ }
1731
+ function MobileTabsSelect(arg0) {
1732
+ const { tabs } = arg0;
1733
+ const pathname = normalizeRoutePath(useLocation().pathname);
1734
+ const { close } = useMobileNavigationStore();
1735
+ if (!tabs?.length) return null;
1736
+ const activeTab = tabs.find((tab) => isActiveTab$1(tab, pathname)) ?? tabs[0];
1737
+ return /* @__PURE__ */ jsxs(Menu, {
1738
+ as: "div",
1739
+ className: "clarify-mobile-tabs-select mb-6",
1740
+ children: [/* @__PURE__ */ jsxs(MenuButton, {
1741
+ className: "clarify-mobile-tabs-select-trigger clarify-ui-control group flex h-10 w-full items-center justify-between gap-2 rounded-(--clarify-theme-tokens-radius-xl) border border-(--clarify-theme-tokens-colors-border) px-4 text-left font-semibold shadow-xs shadow-zinc-900/5 transition dark:border-white/10",
1742
+ children: [/* @__PURE__ */ jsxs("span", {
1743
+ className: "flex min-w-0 items-center gap-2",
1744
+ children: [/* @__PURE__ */ jsx(NavigationIcon, {
1745
+ name: activeTab.icon,
1746
+ className: "h-4 w-4 shrink-0 text-(--clarify-theme-tokens-colors-primary)"
1747
+ }), /* @__PURE__ */ jsx("span", {
1748
+ className: "truncate tracking-[-0.01em]",
1749
+ children: activeTab.title
1750
+ })]
1751
+ }), /* @__PURE__ */ jsx("svg", {
1752
+ width: "8",
1753
+ height: "24",
1754
+ viewBox: "0 -9 3 24",
1755
+ "aria-hidden": "true",
1756
+ className: "shrink-0 overflow-visible text-(--clarify-theme-tokens-colors-muted) transition-transform group-aria-expanded:rotate-180",
1757
+ children: /* @__PURE__ */ jsx("path", {
1758
+ d: "M0 0L3 3L0 6",
1759
+ fill: "none",
1760
+ stroke: "currentColor",
1761
+ strokeWidth: "1.5",
1762
+ strokeLinecap: "round"
1763
+ })
1764
+ })]
1765
+ }), /* @__PURE__ */ jsx(MenuItems, {
1766
+ className: "clarify-mobile-tabs-select-list clarify-ui-menu mt-2 flex flex-col gap-1 rounded-(--clarify-theme-tokens-radius-xl) border border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-surface) p-1 shadow-lg shadow-zinc-900/5 focus:outline-none dark:border-white/10 dark:bg-zinc-900 dark:shadow-none",
1767
+ children: tabs.map((tab) => {
1768
+ const active = isActiveTab$1(tab, pathname);
1769
+ return /* @__PURE__ */ jsx(MenuItem, { children: /* @__PURE__ */ jsxs(Link, {
1770
+ to: tab.path,
1771
+ onClick: close,
1772
+ className: clsx("clarify-mobile-tabs-select-item clarify-ui-menu-item flex items-center justify-between gap-3 rounded-(--clarify-theme-tokens-radius-lg) px-3 py-2.5 no-underline transition", active && "clarify-ui-menu-item-active"),
1773
+ "aria-current": active ? "page" : void 0,
1774
+ children: [/* @__PURE__ */ jsxs("span", {
1775
+ className: "flex min-w-0 items-start gap-2",
1776
+ children: [/* @__PURE__ */ jsx(NavigationIcon, {
1777
+ name: tab.icon,
1778
+ className: "mt-0.5 h-4 w-4 shrink-0"
1779
+ }), /* @__PURE__ */ jsx("span", {
1780
+ className: "min-w-0 whitespace-normal wrap-anywhere font-medium leading-5",
1781
+ children: tab.title
1782
+ })]
1783
+ }), active ? /* @__PURE__ */ jsx("svg", {
1784
+ viewBox: "0 0 20 20",
1785
+ fill: "none",
1786
+ "aria-hidden": "true",
1787
+ className: "mt-0.5 h-4 w-4 shrink-0",
1788
+ children: /* @__PURE__ */ jsx("path", {
1789
+ d: "m5 10 3 3 7-7",
1790
+ stroke: "currentColor",
1791
+ strokeWidth: "1.8",
1792
+ strokeLinecap: "round",
1793
+ strokeLinejoin: "round"
1794
+ })
1795
+ }) : null]
1796
+ }) }, `${tab.title}-${tab.path}`);
1797
+ })
1798
+ })]
1799
+ });
1800
+ }
1414
1801
  function MobileNavigationDialog(arg0) {
1415
- const { config, isOpen, navigation, routes, currentLocale, currentRoute, close } = arg0;
1802
+ const { config, isOpen, navigation, tabs, routes, currentLocale, currentRoute, close } = arg0;
1416
1803
  return /* @__PURE__ */ jsxs(Dialog, {
1417
1804
  transition: true,
1418
1805
  open: isOpen,
@@ -1420,18 +1807,19 @@ function MobileNavigationDialog(arg0) {
1420
1807
  className: "clarify-mobile-navigation-dialog fixed inset-0 z-50 lg:hidden",
1421
1808
  children: [/* @__PURE__ */ jsx(DialogBackdrop, {
1422
1809
  transition: true,
1423
- className: "clarify-mobile-navigation-backdrop fixed inset-0 top-14 bg-zinc-400/20 backdrop-blur-xs data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in dark:bg-black/40"
1810
+ className: "clarify-mobile-navigation-backdrop clarify-ui-backdrop fixed inset-0 top-14 backdrop-blur-xs data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in"
1424
1811
  }), /* @__PURE__ */ jsxs(DialogPanel, { children: [/* @__PURE__ */ jsx(TransitionChild, { children: /* @__PURE__ */ jsx(Header, {
1425
1812
  config,
1426
1813
  navigation,
1814
+ tabs,
1427
1815
  routes,
1428
1816
  currentLocale,
1429
1817
  currentRoute,
1430
1818
  className: "data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in"
1431
- }) }), /* @__PURE__ */ jsx(TransitionChild, { children: /* @__PURE__ */ jsx(motion.div, {
1819
+ }) }), /* @__PURE__ */ jsx(TransitionChild, { children: /* @__PURE__ */ jsxs(motion.div, {
1432
1820
  layoutScroll: true,
1433
- className: "clarify-mobile-navigation-panel fixed top-14 bottom-0 left-0 w-full overflow-y-auto bg-white px-4 pt-6 pb-4 shadow-lg ring-1 shadow-zinc-900/10 ring-zinc-900/7.5 duration-500 ease-in-out data-closed:-translate-x-full min-[416px]:max-w-sm sm:px-6 sm:pb-10 dark:bg-zinc-950 dark:ring-zinc-800",
1434
- children: /* @__PURE__ */ jsx(Navigation, { navigation })
1821
+ className: "clarify-mobile-navigation-panel fixed top-14 bottom-0 left-0 w-full overflow-y-auto bg-(--clarify-theme-tokens-colors-background) px-4 pt-6 pb-4 shadow-lg ring-1 shadow-zinc-900/10 ring-(--clarify-theme-tokens-colors-border) duration-500 ease-in-out data-closed:-translate-x-full min-[416px]:max-w-sm sm:px-6 sm:pb-10 dark:bg-zinc-950 dark:ring-zinc-800",
1822
+ children: [/* @__PURE__ */ jsx(MobileTabsSelect, { tabs }), /* @__PURE__ */ jsx(Navigation, { navigation })]
1435
1823
  }) })] })]
1436
1824
  });
1437
1825
  }
@@ -1445,23 +1833,25 @@ var useMobileNavigationStore = create()((set) => ({
1445
1833
  toggle: () => set((state) => ({ isOpen: !state.isOpen }))
1446
1834
  }));
1447
1835
  function MobileNavigation(arg0) {
1448
- const { config, navigation, routes, currentLocale, currentRoute } = arg0;
1836
+ const { config, navigation, tabs, routes, currentLocale, currentRoute } = arg0;
1449
1837
  const isInsideMobileNavigation = useIsInsideMobileNavigation();
1450
1838
  const { isOpen, toggle, close } = useMobileNavigationStore();
1839
+ const t = useBuiltInText();
1451
1840
  const ToggleIcon = isOpen ? XIcon : MenuIcon;
1452
1841
  return /* @__PURE__ */ jsxs(IsInsideMobileNavigationContext.Provider, {
1453
1842
  value: true,
1454
1843
  children: [/* @__PURE__ */ jsxs("button", {
1455
1844
  type: "button",
1456
- className: "clarify-mobile-navigation-button relative flex size-6 items-center justify-center rounded-md transition hover:bg-zinc-900/5 dark:hover:bg-white/5",
1457
- "aria-label": "Toggle navigation",
1845
+ className: "clarify-mobile-navigation-button clarify-ui-icon-button relative flex size-6 items-center justify-center rounded-(--clarify-theme-tokens-radius-md) transition",
1846
+ "aria-label": t("navigation.toggle"),
1458
1847
  onClick: toggle,
1459
- children: [/* @__PURE__ */ jsx("span", { className: "absolute size-12 pointer-fine:hidden" }), /* @__PURE__ */ jsx(ToggleIcon, { className: "w-2.5 stroke-zinc-900 dark:stroke-white" })]
1848
+ children: [/* @__PURE__ */ jsx("span", { className: "absolute size-12 pointer-fine:hidden" }), /* @__PURE__ */ jsx(ToggleIcon, { className: "w-2.5 stroke-(--clarify-theme-tokens-colors-foreground) dark:stroke-white" })]
1460
1849
  }), !isInsideMobileNavigation ? /* @__PURE__ */ jsx(Suspense, {
1461
1850
  fallback: null,
1462
1851
  children: /* @__PURE__ */ jsx(MobileNavigationDialog, {
1463
1852
  config,
1464
1853
  navigation,
1854
+ tabs,
1465
1855
  routes,
1466
1856
  currentLocale,
1467
1857
  currentRoute,
@@ -1542,7 +1932,7 @@ function HighlightQuery(arg0) {
1542
1932
  const { text, query } = arg0;
1543
1933
  if (!query) return text;
1544
1934
  return /* @__PURE__ */ jsx(Fragment$1, { children: text.split(new RegExp(`(${escapeRegExp(query)})`, "ig")).map((part, index) => part.toLowerCase() === query.toLowerCase() ? /* @__PURE__ */ jsx("mark", {
1545
- className: "bg-transparent text-emerald-500 underline",
1935
+ className: "bg-transparent text-(--clarify-theme-tokens-colors-primary) underline",
1546
1936
  children: part
1547
1937
  }, index) : /* @__PURE__ */ jsx(Fragment, { children: part }, index)) });
1548
1938
  }
@@ -1552,25 +1942,25 @@ function SearchResult(arg0) {
1552
1942
  const hierarchy = [result.sectionTitle, result.pageTitle].filter((value) => typeof value === "string");
1553
1943
  return /* @__PURE__ */ jsxs("li", {
1554
1944
  id,
1555
- className: clsx("clarify-search-result group block cursor-default px-4 py-3 aria-selected:bg-zinc-50 dark:aria-selected:bg-zinc-800/50", active && "bg-zinc-50 dark:bg-zinc-800/50"),
1945
+ className: clsx("clarify-search-result group block cursor-default px-4 py-3", active && "clarify-search-result-active"),
1556
1946
  "aria-selected": active,
1557
1947
  onMouseDown: (event) => {
1558
1948
  event.preventDefault();
1559
1949
  onSelect();
1560
1950
  },
1561
1951
  children: [/* @__PURE__ */ jsx("div", {
1562
- className: "text-sm font-medium text-zinc-900 group-aria-selected:text-emerald-500 dark:text-white",
1952
+ className: "clarify-search-result-title",
1563
1953
  children: /* @__PURE__ */ jsx(HighlightQuery, {
1564
1954
  text: result.title,
1565
1955
  query
1566
1956
  })
1567
1957
  }), hierarchy.length > 0 ? /* @__PURE__ */ jsx("div", {
1568
- className: "mt-1 truncate text-2xs whitespace-nowrap text-zinc-500",
1958
+ className: "clarify-search-result-hierarchy mt-1 truncate whitespace-nowrap",
1569
1959
  children: hierarchy.map((item, itemIndex, items) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(HighlightQuery, {
1570
1960
  text: item,
1571
1961
  query
1572
1962
  }), /* @__PURE__ */ jsx("span", {
1573
- className: itemIndex === items.length - 1 ? "sr-only" : "mx-2 text-zinc-300 dark:text-zinc-700",
1963
+ className: itemIndex === items.length - 1 ? "sr-only" : "clarify-search-result-separator mx-2",
1574
1964
  children: "/"
1575
1965
  })] }, `${item}-${itemIndex}`))
1576
1966
  }) : null]
@@ -1578,9 +1968,10 @@ function SearchResult(arg0) {
1578
1968
  }
1579
1969
  var SearchInput = forwardRef(function SearchInput(arg0, inputRef) {
1580
1970
  const { query, setQuery, onClose, onSubmit, activeDescendantId } = arg0;
1971
+ const t = useBuiltInText();
1581
1972
  return /* @__PURE__ */ jsxs("div", {
1582
1973
  className: "clarify-search-input group relative flex h-12",
1583
- children: [/* @__PURE__ */ jsx(SearchIcon, { className: "pointer-events-none absolute top-0 left-3 h-full w-5 stroke-zinc-500" }), /* @__PURE__ */ jsx("input", {
1974
+ children: [/* @__PURE__ */ jsx(SearchIcon, { className: "pointer-events-none absolute top-0 left-3 h-full w-5 stroke-(--clarify-theme-tokens-colors-muted)" }), /* @__PURE__ */ jsx("input", {
1584
1975
  ref: inputRef,
1585
1976
  "data-autofocus": true,
1586
1977
  role: "combobox",
@@ -1597,13 +1988,14 @@ var SearchInput = forwardRef(function SearchInput(arg0, inputRef) {
1597
1988
  onSubmit();
1598
1989
  }
1599
1990
  },
1600
- placeholder: "Find something...",
1601
- className: "flex-auto appearance-none bg-transparent pr-4 pl-10 text-zinc-900 outline-hidden placeholder:text-zinc-500 focus:w-full focus:flex-none sm:text-sm dark:text-white [&::-webkit-search-cancel-button]:hidden [&::-webkit-search-decoration]:hidden [&::-webkit-search-results-button]:hidden [&::-webkit-search-results-decoration]:hidden"
1991
+ placeholder: t("search.placeholder"),
1992
+ className: "clarify-search-field flex-auto appearance-none bg-transparent pr-4 pl-10 outline-hidden focus:w-full focus:flex-none [&::-webkit-search-cancel-button]:hidden [&::-webkit-search-decoration]:hidden [&::-webkit-search-results-button]:hidden [&::-webkit-search-results-decoration]:hidden"
1602
1993
  })]
1603
1994
  });
1604
1995
  });
1605
1996
  function SearchDialog(arg0) {
1606
1997
  const { open, setOpen, routes, navigation, className, onNavigate = () => {} } = arg0;
1998
+ const t = useBuiltInText();
1607
1999
  const navigate = useNavigate();
1608
2000
  const location = useLocation();
1609
2001
  const inputRef = useRef(null);
@@ -1654,12 +2046,12 @@ function SearchDialog(arg0) {
1654
2046
  className: clsx("clarify-search-dialog fixed inset-0 z-50", className),
1655
2047
  children: [/* @__PURE__ */ jsx(DialogBackdrop, {
1656
2048
  transition: true,
1657
- className: "clarify-search-backdrop fixed inset-0 bg-zinc-400/25 backdrop-blur-xs data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in dark:bg-black/40"
2049
+ className: "clarify-search-backdrop clarify-ui-backdrop fixed inset-0 backdrop-blur-xs data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in"
1658
2050
  }), /* @__PURE__ */ jsx("div", {
1659
2051
  className: "fixed inset-0 overflow-y-auto px-4 py-4 sm:px-6 sm:py-20 md:py-32 lg:px-8 lg:py-[15vh]",
1660
2052
  children: /* @__PURE__ */ jsxs(DialogPanel, {
1661
2053
  transition: true,
1662
- className: "clarify-search-panel mx-auto transform-gpu overflow-hidden rounded-lg bg-zinc-50 shadow-xl ring-1 ring-zinc-900/7.5 data-closed:scale-95 data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in sm:max-w-xl dark:bg-zinc-900 dark:ring-zinc-800",
2054
+ className: "clarify-search-panel mx-auto transform-gpu overflow-hidden rounded-(--clarify-theme-tokens-radius-lg) bg-(--clarify-theme-tokens-colors-surface) shadow-xl ring-1 ring-(--clarify-theme-tokens-colors-border) data-closed:scale-95 data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in sm:max-w-xl dark:bg-zinc-900 dark:ring-zinc-800",
1663
2055
  onKeyDown: (event) => {
1664
2056
  if (event.key === "ArrowDown") {
1665
2057
  event.preventDefault();
@@ -1677,24 +2069,12 @@ function SearchDialog(arg0) {
1677
2069
  onClose: closeDialog,
1678
2070
  onSubmit: () => selectResult()
1679
2071
  }), /* @__PURE__ */ jsxs("div", {
1680
- className: "border-t border-zinc-200 bg-white empty:hidden dark:border-zinc-100/5 dark:bg-white/2.5",
2072
+ className: "border-t border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-background) empty:hidden dark:border-zinc-100/5 dark:bg-white/2.5",
1681
2073
  children: [query && results.length === 0 ? /* @__PURE__ */ jsxs("div", {
1682
2074
  className: "p-6 text-center",
1683
- children: [/* @__PURE__ */ jsx(NoResultsIcon, { className: "mx-auto h-5 w-5 stroke-zinc-900 dark:stroke-zinc-600" }), /* @__PURE__ */ jsxs("p", {
1684
- className: "mt-2 text-xs text-zinc-700 dark:text-zinc-400",
1685
- children: [
1686
- "Nothing found for",
1687
- " ",
1688
- /* @__PURE__ */ jsxs("strong", {
1689
- className: "font-semibold wrap-break-word text-zinc-900 dark:text-white",
1690
- children: [
1691
- "‘",
1692
- query,
1693
- "’"
1694
- ]
1695
- }),
1696
- "."
1697
- ]
2075
+ children: [/* @__PURE__ */ jsx(NoResultsIcon, { className: "mx-auto h-5 w-5 stroke-(--clarify-theme-tokens-colors-foreground) dark:stroke-zinc-600" }), /* @__PURE__ */ jsx("p", {
2076
+ className: "mt-2 text-xs text-(--clarify-theme-tokens-colors-muted) dark:text-zinc-400",
2077
+ children: t("search.noResults", { query })
1698
2078
  })]
1699
2079
  }) : null, results.length ? /* @__PURE__ */ jsx("ul", {
1700
2080
  id: "clarify-search-results",
@@ -1734,19 +2114,20 @@ function getModifierKey() {
1734
2114
  }
1735
2115
  function Search(arg0) {
1736
2116
  const { routes, navigation } = arg0;
2117
+ const t = useBuiltInText();
1737
2118
  const modifierKey = getModifierKey();
1738
2119
  const { buttonProps, dialogProps } = useSearchProps();
1739
2120
  return /* @__PURE__ */ jsxs("div", {
1740
- className: "clarify-search hidden lg:block lg:max-w-md lg:flex-auto",
2121
+ className: "clarify-search hidden w-80 max-w-[36vw] lg:block",
1741
2122
  children: [/* @__PURE__ */ jsxs("button", {
1742
2123
  type: "button",
1743
- className: "clarify-search-button hidden h-8 w-full items-center gap-2 rounded-full bg-white pr-3 pl-2 text-sm text-zinc-500 ring-1 ring-zinc-900/10 transition hover:ring-zinc-900/20 lg:flex dark:bg-white/5 dark:text-zinc-400 dark:ring-white/10 dark:ring-inset dark:hover:ring-white/20",
2124
+ className: "clarify-search-button hidden h-9 w-full items-center gap-2 rounded-(--clarify-theme-tokens-radius-lg) bg-(--clarify-theme-tokens-colors-surface) pr-3 pl-2.5 font-medium ring-1 ring-(--clarify-theme-tokens-colors-border) transition hover:bg-(--clarify-theme-tokens-colors-background) lg:flex dark:bg-white/5 dark:ring-white/10 dark:ring-inset dark:hover:bg-white/10",
1744
2125
  ...buttonProps,
1745
2126
  children: [
1746
2127
  /* @__PURE__ */ jsx(SearchIcon, { className: "h-5 w-5 stroke-current" }),
1747
- "Find something...",
2128
+ t("search.button"),
1748
2129
  /* @__PURE__ */ jsxs("kbd", {
1749
- className: "ml-auto text-2xs text-zinc-400 dark:text-zinc-500",
2130
+ className: "clarify-search-shortcut ml-auto rounded-(--clarify-theme-tokens-radius-sm) bg-(--clarify-theme-tokens-colors-background) px-1.5 py-0.5 ring-1 ring-(--clarify-theme-tokens-colors-border) dark:bg-white/5 dark:ring-white/10",
1750
2131
  children: [/* @__PURE__ */ jsx("kbd", {
1751
2132
  className: "font-sans",
1752
2133
  children: modifierKey
@@ -1769,15 +2150,16 @@ function Search(arg0) {
1769
2150
  }
1770
2151
  function MobileSearch(arg0) {
1771
2152
  const { routes, navigation, onNavigate } = arg0;
2153
+ const t = useBuiltInText();
1772
2154
  const { buttonProps, dialogProps } = useSearchProps();
1773
2155
  return /* @__PURE__ */ jsxs("div", {
1774
2156
  className: "clarify-mobile-search contents lg:hidden",
1775
2157
  children: [/* @__PURE__ */ jsxs("button", {
1776
2158
  type: "button",
1777
- className: "clarify-mobile-search-button relative flex size-6 items-center justify-center rounded-md transition hover:bg-zinc-900/5 lg:hidden dark:hover:bg-white/5",
1778
- "aria-label": "Find something...",
2159
+ className: "clarify-mobile-search-button clarify-ui-control relative flex size-6 items-center justify-center rounded-(--clarify-theme-tokens-radius-md) transition lg:hidden",
2160
+ "aria-label": t("search.placeholder"),
1779
2161
  ...buttonProps,
1780
- children: [/* @__PURE__ */ jsx("span", { className: "absolute size-12 pointer-fine:hidden" }), /* @__PURE__ */ jsx(SearchIcon, { className: "h-5 w-5 stroke-zinc-900 dark:stroke-white" })]
2162
+ children: [/* @__PURE__ */ jsx("span", { className: "absolute size-12 pointer-fine:hidden" }), /* @__PURE__ */ jsx(SearchIcon, { className: "h-5 w-5 stroke-(--clarify-theme-tokens-colors-foreground) dark:stroke-white" })]
1781
2163
  }), /* @__PURE__ */ jsx(Suspense, {
1782
2164
  fallback: null,
1783
2165
  children: /* @__PURE__ */ jsx(SearchDialog, {
@@ -1822,6 +2204,7 @@ function LanguageIcon(props) {
1822
2204
  }
1823
2205
  function LanguageSwitcher(arg0) {
1824
2206
  const { config, currentLocale, currentRoute } = arg0;
2207
+ const t = useBuiltInText();
1825
2208
  const location = useLocation();
1826
2209
  const i18n = config.i18n;
1827
2210
  if (!i18n || i18n.locales.length < 2) return null;
@@ -1832,8 +2215,8 @@ function LanguageSwitcher(arg0) {
1832
2215
  as: "div",
1833
2216
  className: "clarify-language-switcher relative",
1834
2217
  children: [/* @__PURE__ */ jsxs(MenuButton, {
1835
- className: "clarify-language-switcher-button flex h-7 items-center gap-1.5 rounded-md px-1.5 text-sm/5 font-medium text-zinc-600 transition hover:bg-zinc-900/5 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-white/5 dark:hover:text-white",
1836
- "aria-label": "Switch language",
2218
+ className: "clarify-language-switcher-button clarify-ui-control flex h-7 items-center gap-1.5 rounded-(--clarify-theme-tokens-radius-md) px-1.5 transition",
2219
+ "aria-label": t("language.switch"),
1837
2220
  children: [
1838
2221
  /* @__PURE__ */ jsx("span", { className: "absolute size-12 pointer-fine:hidden" }),
1839
2222
  /* @__PURE__ */ jsx(LanguageIcon, { className: "h-5 w-5 stroke-current" }),
@@ -1844,19 +2227,19 @@ function LanguageSwitcher(arg0) {
1844
2227
  ]
1845
2228
  }), /* @__PURE__ */ jsx(MenuItems, {
1846
2229
  transition: true,
1847
- className: "clarify-language-switcher-menu absolute right-0 z-50 mt-2 w-44 rounded-xl bg-white p-1 text-sm shadow-lg ring-1 shadow-zinc-900/5 ring-zinc-900/10 transition data-closed:scale-95 data-closed:opacity-0 data-enter:duration-100 data-enter:ease-out data-leave:duration-75 data-leave:ease-in dark:bg-zinc-900 dark:ring-white/10",
2230
+ className: "clarify-language-switcher-menu clarify-ui-menu absolute right-0 z-50 mt-2 w-(--clarify-ui-menu-width) rounded-(--clarify-theme-tokens-radius-xl) bg-(--clarify-theme-tokens-colors-surface) p-1 shadow-lg ring-1 shadow-zinc-900/5 ring-(--clarify-theme-tokens-colors-border) transition data-closed:scale-95 data-closed:opacity-0 data-enter:duration-100 data-enter:ease-out data-leave:duration-75 data-leave:ease-in dark:bg-zinc-900 dark:ring-white/10",
1848
2231
  children: i18n.locales.flatMap((locale) => {
1849
2232
  const localizedPath = localizedRoutePath(config, locale.code, currentRoute);
1850
2233
  if (!localizedPath) return [];
1851
2234
  const selected = locale.code === selectedLocale;
1852
2235
  return [/* @__PURE__ */ jsx(MenuItem, { children: ({ focus }) => /* @__PURE__ */ jsxs(Link, {
1853
2236
  to: `${localizedPath}${suffix}`,
1854
- className: clsx("clarify-language-switcher-item flex items-center justify-between rounded-lg px-3 py-2 no-underline transition", focus && "bg-zinc-100 dark:bg-white/5", selected ? "text-zinc-900 dark:text-white" : "text-zinc-600 dark:text-zinc-400"),
2237
+ className: clsx("clarify-language-switcher-item clarify-ui-menu-item flex items-center justify-between rounded-(--clarify-theme-tokens-radius-lg) px-3 py-2 no-underline transition", focus && "clarify-ui-menu-item-focus", selected && "clarify-ui-menu-item-active"),
1855
2238
  "aria-current": selected ? "true" : void 0,
1856
2239
  lang: locale.code,
1857
2240
  dir: locale.dir,
1858
2241
  children: [/* @__PURE__ */ jsx("span", { children: locale.label }), /* @__PURE__ */ jsx("span", {
1859
- className: "text-xs text-zinc-400 dark:text-zinc-500",
2242
+ className: "clarify-ui-menu-code",
1860
2243
  children: locale.code
1861
2244
  })]
1862
2245
  }) }, locale.code)];
@@ -1868,95 +2251,189 @@ function TopLevelNavItem(arg0) {
1868
2251
  const { href, children } = arg0;
1869
2252
  if (isExternalHref(href)) return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", {
1870
2253
  href,
1871
- className: "text-sm/5 text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white",
2254
+ className: "clarify-ui-top-link transition",
1872
2255
  target: "_blank",
1873
2256
  rel: "noreferrer",
1874
2257
  children
1875
2258
  }) });
1876
2259
  return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(Link, {
1877
2260
  to: href,
1878
- className: "text-sm/5 text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white",
2261
+ className: "clarify-ui-top-link transition",
1879
2262
  children
1880
2263
  }) });
1881
2264
  }
2265
+ function MobileNavbarMenu(arg0) {
2266
+ const { links, config, currentLocale } = arg0;
2267
+ const t = useBuiltInText();
2268
+ if (!links?.length) return null;
2269
+ return /* @__PURE__ */ jsxs(Menu, {
2270
+ as: "div",
2271
+ className: "clarify-mobile-navbar-menu relative md:hidden",
2272
+ children: [/* @__PURE__ */ jsxs(MenuButton, {
2273
+ className: "clarify-mobile-navbar-menu-button clarify-ui-control relative flex size-8 items-center justify-center rounded-(--clarify-theme-tokens-radius-md) transition",
2274
+ "aria-label": t("navbar.openLinks"),
2275
+ children: [/* @__PURE__ */ jsx("span", { className: "absolute size-12 pointer-fine:hidden" }), /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-5 w-5" })]
2276
+ }), /* @__PURE__ */ jsx(MenuItems, {
2277
+ transition: true,
2278
+ anchor: "bottom end",
2279
+ className: "clarify-mobile-navbar-menu-list clarify-ui-menu z-50 mt-2 w-(--clarify-ui-menu-width) rounded-(--clarify-theme-tokens-radius-xl) border border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-surface) p-1 shadow-lg transition [--anchor-gap:--spacing(2)] focus:outline-none data-closed:scale-95 data-closed:opacity-0 dark:border-white/10 dark:bg-zinc-900",
2280
+ children: links.map((link) => {
2281
+ const label = resolveLocalizedText(link.label, currentLocale, config.i18n?.defaultLocale);
2282
+ const href = localizeHref(link.href, config, currentLocale);
2283
+ const external = isExternalHref(href);
2284
+ return /* @__PURE__ */ jsx(MenuItem, { children: ({ focus }) => {
2285
+ const className = clsx("clarify-mobile-navbar-menu-item clarify-ui-menu-item block rounded-(--clarify-theme-tokens-radius-lg) px-3 py-2 no-underline transition", focus && "clarify-ui-menu-item-focus");
2286
+ return external ? /* @__PURE__ */ jsx("a", {
2287
+ href,
2288
+ target: "_blank",
2289
+ rel: "noreferrer",
2290
+ className,
2291
+ children: label
2292
+ }) : /* @__PURE__ */ jsx(Link, {
2293
+ to: href,
2294
+ className,
2295
+ children: label
2296
+ });
2297
+ } }, link.href);
2298
+ })
2299
+ })]
2300
+ });
2301
+ }
2302
+ function hasPath$1(nodes, pathname) {
2303
+ return nodes.some((node) => isSameRoutePath(node.path, pathname) || hasPath$1(node.children ?? [], pathname));
2304
+ }
2305
+ function isActiveTab(tab, pathname) {
2306
+ return isSameRoutePath(tab.path, pathname) || hasPath$1(tab.children, pathname);
2307
+ }
2308
+ function ProductTabs(arg0) {
2309
+ const { tabs } = arg0;
2310
+ const t = useBuiltInText();
2311
+ const pathname = normalizeRoutePath(useLocation().pathname);
2312
+ if (!tabs?.length) return null;
2313
+ return /* @__PURE__ */ jsx("div", {
2314
+ className: "clarify-product-tabs hidden h-14 border-t border-(--clarify-theme-tokens-colors-border) lg:block dark:border-white/10",
2315
+ children: /* @__PURE__ */ jsx("nav", {
2316
+ className: "clarify-product-tabs-nav mx-auto flex h-full w-full max-w-(--clarify-theme-layout-max-width) items-stretch gap-6 overflow-x-auto px-5",
2317
+ "aria-label": t("navbar.sections"),
2318
+ children: tabs.map((tab) => {
2319
+ const active = isActiveTab(tab, pathname);
2320
+ return /* @__PURE__ */ jsxs(Link, {
2321
+ to: tab.path,
2322
+ "aria-current": active ? "page" : void 0,
2323
+ className: clsx("clarify-product-tab clarify-ui-tab relative inline-flex shrink-0 items-center gap-2 px-0 transition", active && "clarify-ui-tab-active"),
2324
+ children: [
2325
+ /* @__PURE__ */ jsx(NavigationIcon, {
2326
+ name: tab.icon,
2327
+ className: "h-4 w-4"
2328
+ }),
2329
+ /* @__PURE__ */ jsx("span", { children: tab.title }),
2330
+ active ? /* @__PURE__ */ jsx(motion.span, {
2331
+ layoutId: "clarify-product-tab-indicator",
2332
+ className: "absolute inset-x-0 bottom-0 h-0.5 rounded-full bg-(--clarify-theme-tokens-colors-foreground) dark:bg-white",
2333
+ transition: {
2334
+ type: "spring",
2335
+ stiffness: 420,
2336
+ damping: 36
2337
+ }
2338
+ }) : null
2339
+ ]
2340
+ }, `${tab.title}-${tab.path}`);
2341
+ })
2342
+ })
2343
+ });
2344
+ }
1882
2345
  var Header = forwardRef(function Header(arg0, ref) {
1883
- const { config, navigation, routes, currentLocale, currentRoute, className, ...props } = arg0;
2346
+ const { config, navigation, tabs, routes, currentLocale, currentRoute, className, ...props } = arg0;
2347
+ const t = useBuiltInText();
1884
2348
  const { isOpen: mobileNavIsOpen } = useMobileNavigationStore();
1885
2349
  const isInsideMobileNavigation = useIsInsideMobileNavigation();
1886
2350
  const { scrollY } = useScroll();
1887
- const bgOpacityLight = useTransform(scrollY, [0, 72], ["50%", "90%"]);
1888
- const bgOpacityDark = useTransform(scrollY, [0, 72], ["20%", "80%"]);
1889
- return /* @__PURE__ */ jsxs(motion.div, {
2351
+ const bgOpacityLight = useTransform(scrollY, [0, 72], ["70%", "95%"]);
2352
+ const bgOpacityDark = useTransform(scrollY, [0, 72], ["60%", "92%"]);
2353
+ return /* @__PURE__ */ jsxs(motion.header, {
1890
2354
  ...props,
1891
2355
  ref,
1892
- className: clsx(className, "clarify-header fixed inset-x-0 top-0 z-50 flex h-14 items-center justify-between gap-12 px-4 transition sm:px-6 lg:left-72 lg:z-30 lg:px-8 xl:left-80", !isInsideMobileNavigation && "backdrop-blur-xs lg:left-72 xl:left-80 dark:backdrop-blur-sm", isInsideMobileNavigation ? "bg-white dark:bg-zinc-950" : "bg-white/(--bg-opacity-light) dark:bg-zinc-950/(--bg-opacity-dark)"),
2356
+ className: clsx(className, "clarify-header fixed inset-x-0 top-0 z-50 border-b border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-background)/(--bg-opacity-light) backdrop-blur-xs transition dark:border-white/10 dark:bg-zinc-950/(--bg-opacity-dark) dark:backdrop-blur-sm", isInsideMobileNavigation && "bg-(--clarify-theme-tokens-colors-background) dark:bg-zinc-950"),
1893
2357
  style: {
1894
2358
  "--bg-opacity-light": bgOpacityLight,
1895
2359
  "--bg-opacity-dark": bgOpacityDark
1896
2360
  },
1897
- children: [
1898
- /* @__PURE__ */ jsx("div", { className: clsx("absolute inset-x-0 top-full h-px transition", (isInsideMobileNavigation || !mobileNavIsOpen) && "bg-zinc-900/7.5 dark:bg-white/7.5") }),
1899
- /* @__PURE__ */ jsx("div", { className: "hidden lg:block" }),
1900
- /* @__PURE__ */ jsxs("div", {
1901
- className: "clarify-mobile-brand flex items-center gap-5 lg:hidden",
1902
- children: [/* @__PURE__ */ jsx(MobileNavigation, {
1903
- config,
1904
- navigation,
1905
- routes,
1906
- currentLocale,
1907
- currentRoute
1908
- }), config.logo ? /* @__PURE__ */ jsxs(CloseButton, {
1909
- as: Link,
1910
- to: localizeHref("/", config, currentLocale),
1911
- "aria-label": "Home",
1912
- className: "clarify-brand flex items-center gap-2 no-underline",
1913
- children: [/* @__PURE__ */ jsx(SiteLogo, {
1914
- logo: config.logo,
1915
- className: "h-6 w-6"
1916
- }), /* @__PURE__ */ jsx("span", {
1917
- className: "sr-only",
1918
- children: config.title
2361
+ children: [/* @__PURE__ */ jsxs("div", {
2362
+ className: clsx("clarify-header-main relative mx-auto flex h-14 w-full max-w-(--clarify-theme-layout-max-width) items-center justify-between gap-6 px-4 sm:px-6 lg:px-5", (isInsideMobileNavigation || !mobileNavIsOpen) && "shadow-none"),
2363
+ children: [
2364
+ /* @__PURE__ */ jsxs("div", {
2365
+ className: "clarify-header-left flex min-w-0 items-center gap-5",
2366
+ children: [/* @__PURE__ */ jsx("div", {
2367
+ className: "clarify-mobile-brand flex items-center gap-5 lg:hidden",
2368
+ children: /* @__PURE__ */ jsx(MobileNavigation, {
2369
+ config,
2370
+ navigation,
2371
+ tabs,
2372
+ routes,
2373
+ currentLocale,
2374
+ currentRoute
2375
+ })
2376
+ }), /* @__PURE__ */ jsxs(CloseButton, {
2377
+ as: Link,
2378
+ to: localizeHref("/", config, currentLocale),
2379
+ "aria-label": t("navbar.home"),
2380
+ className: "clarify-brand flex min-w-0 items-center gap-2 no-underline",
2381
+ children: [/* @__PURE__ */ jsx(SiteLogo, {
2382
+ logo: config.logo,
2383
+ className: "h-6 w-6 shrink-0"
2384
+ }), /* @__PURE__ */ jsx("span", {
2385
+ className: "clarify-brand-title truncate font-semibold",
2386
+ children: config.title
2387
+ })]
1919
2388
  })]
1920
- }) : null]
1921
- }),
1922
- /* @__PURE__ */ jsxs("div", {
1923
- className: "clarify-header-actions flex items-center gap-5",
1924
- children: [
1925
- /* @__PURE__ */ jsx(Search, {
2389
+ }),
2390
+ /* @__PURE__ */ jsx("div", {
2391
+ className: "clarify-header-center absolute left-1/2 hidden -translate-x-1/2 lg:block",
2392
+ children: /* @__PURE__ */ jsx(Search, {
1926
2393
  routes,
1927
2394
  navigation
1928
- }),
1929
- config.navbar?.links?.length ? /* @__PURE__ */ jsx("nav", {
1930
- className: "clarify-top-nav hidden md:block",
1931
- children: /* @__PURE__ */ jsx("ul", {
1932
- role: "list",
1933
- className: "flex items-center gap-8",
1934
- children: config.navbar.links.map((link) => /* @__PURE__ */ jsx(TopLevelNavItem, {
1935
- href: localizeHref(link.href, config, currentLocale),
1936
- children: resolveLocalizedText(link.label, currentLocale, config.i18n?.defaultLocale)
1937
- }, link.href))
2395
+ })
2396
+ }),
2397
+ /* @__PURE__ */ jsxs("div", {
2398
+ className: "clarify-header-actions flex shrink-0 items-center gap-5",
2399
+ children: [
2400
+ config.navbar?.links?.length ? /* @__PURE__ */ jsx("nav", {
2401
+ className: "clarify-top-nav hidden md:block",
2402
+ children: /* @__PURE__ */ jsx("ul", {
2403
+ role: "list",
2404
+ className: "flex items-center gap-8",
2405
+ children: config.navbar.links.map((link) => /* @__PURE__ */ jsx(TopLevelNavItem, {
2406
+ href: localizeHref(link.href, config, currentLocale),
2407
+ children: resolveLocalizedText(link.label, currentLocale, config.i18n?.defaultLocale)
2408
+ }, link.href))
2409
+ })
2410
+ }) : null,
2411
+ config.navbar?.links?.length ? /* @__PURE__ */ jsx("div", { className: "hidden md:block md:h-5 md:w-px md:bg-(--clarify-theme-tokens-colors-border) md:dark:bg-white/15" }) : null,
2412
+ /* @__PURE__ */ jsx(MobileSearch, {
2413
+ routes,
2414
+ navigation
2415
+ }),
2416
+ /* @__PURE__ */ jsx(LanguageSwitcher, {
2417
+ config,
2418
+ currentLocale,
2419
+ currentRoute
2420
+ }),
2421
+ /* @__PURE__ */ jsx(ThemeToggle, {}),
2422
+ /* @__PURE__ */ jsx(MobileNavbarMenu, {
2423
+ links: config.navbar?.links,
2424
+ config,
2425
+ currentLocale
1938
2426
  })
1939
- }) : null,
1940
- config.navbar?.links?.length ? /* @__PURE__ */ jsx("div", { className: "hidden md:block md:h-5 md:w-px md:bg-zinc-900/10 md:dark:bg-white/15" }) : null,
1941
- /* @__PURE__ */ jsx(MobileSearch, {
1942
- routes,
1943
- navigation
1944
- }),
1945
- /* @__PURE__ */ jsx(LanguageSwitcher, {
1946
- config,
1947
- currentLocale,
1948
- currentRoute
1949
- }),
1950
- /* @__PURE__ */ jsx(ThemeToggle, {})
1951
- ]
1952
- })
1953
- ]
2427
+ ]
2428
+ })
2429
+ ]
2430
+ }), /* @__PURE__ */ jsx(ProductTabs, { tabs })]
1954
2431
  });
1955
2432
  });
1956
2433
  //#endregion
1957
2434
  //#region source/app/AppShell.tsx
1958
2435
  function routeForPath(routes, pathname) {
1959
- return routes.find((route) => route.path === pathname || `/${route.path}` === pathname);
2436
+ return routes.find((route) => isSameRoutePath(route.path, pathname));
1960
2437
  }
1961
2438
  function sectionsForRoute(route) {
1962
2439
  return route?.sections?.map((section) => ({
@@ -1966,11 +2443,18 @@ function sectionsForRoute(route) {
1966
2443
  tags: section.tags
1967
2444
  })) ?? [];
1968
2445
  }
2446
+ function resolveRouteComponent(route) {
2447
+ if (route.lazy) return lazy(route.component);
2448
+ return route.component;
2449
+ }
1969
2450
  function scrollToHash(hash) {
1970
2451
  if (!hash) return;
1971
2452
  const targetId = decodeURIComponent(hash.slice(1));
1972
2453
  window.requestAnimationFrame(() => {
1973
2454
  document.getElementById(targetId)?.scrollIntoView();
2455
+ window.requestAnimationFrame(() => {
2456
+ window.dispatchEvent(new Event("scroll"));
2457
+ });
1974
2458
  });
1975
2459
  }
1976
2460
  function localeForPath(config, pathname, route) {
@@ -1980,25 +2464,101 @@ function localeForPath(config, pathname, route) {
1980
2464
  const firstSegment = pathname.split("/").filter(Boolean)[0];
1981
2465
  return i18n.locales.find((locale) => locale.code === firstSegment)?.code ?? i18n.defaultLocale;
1982
2466
  }
1983
- function navigationForLocale(navigation, locale) {
1984
- if (Array.isArray(navigation)) return navigation;
1985
- if (!locale) return [];
1986
- return navigation[locale] ?? [];
2467
+ function isTabbedNavigation(navigation) {
2468
+ return !Array.isArray(navigation) && "tabs" in navigation;
1987
2469
  }
1988
- function homePathForLocale(config, locale) {
1989
- if (!locale || !config.i18n || locale === config.i18n.defaultLocale) return "/";
1990
- return `/${locale}`;
2470
+ function hasPath(nodes, pathname) {
2471
+ return nodes.some((node) => isSameRoutePath(node.path, pathname) || hasPath(node.children ?? [], pathname));
2472
+ }
2473
+ function navigationFromTabs(navigation, pathname) {
2474
+ return {
2475
+ items: navigation.tabs.find((tab) => isSameRoutePath(tab.path, pathname) || hasPath(tab.children, pathname))?.children ?? navigation.tabs[0]?.children ?? [],
2476
+ tabs: navigation.tabs
2477
+ };
2478
+ }
2479
+ function navigationForLocale(navigation, locale, pathname) {
2480
+ if (Array.isArray(navigation)) return { items: navigation };
2481
+ if (isTabbedNavigation(navigation)) return navigationFromTabs(navigation, pathname);
2482
+ if (!locale) return { items: [] };
2483
+ const localizedNavigation = navigation[locale];
2484
+ if (!localizedNavigation) return { items: [] };
2485
+ return Array.isArray(localizedNavigation) ? { items: localizedNavigation } : navigationFromTabs(localizedNavigation, pathname);
2486
+ }
2487
+ function themeStyle(config) {
2488
+ const { colors, radius } = config.theme.tokens;
2489
+ const { layout } = config.theme;
2490
+ return {
2491
+ "--clarify-theme-tokens-colors-primary": colors.primary,
2492
+ "--clarify-theme-tokens-colors-accent": colors.accent,
2493
+ "--clarify-theme-tokens-colors-background": colors.background,
2494
+ "--clarify-theme-tokens-colors-foreground": colors.foreground,
2495
+ "--clarify-theme-tokens-colors-surface": colors.surface,
2496
+ "--clarify-theme-tokens-colors-muted": colors.muted,
2497
+ "--clarify-theme-tokens-colors-border": colors.border,
2498
+ "--clarify-theme-tokens-colors-code-background": colors.codeBackground,
2499
+ "--clarify-theme-tokens-radius-sm": radius.sm,
2500
+ "--clarify-theme-tokens-radius-md": radius.md,
2501
+ "--clarify-theme-tokens-radius-lg": radius.lg,
2502
+ "--clarify-theme-tokens-radius-xl": radius.xl,
2503
+ "--clarify-theme-layout-max-width": layout.maxWidth
2504
+ };
2505
+ }
2506
+ function pageTitle(config, route) {
2507
+ const routeTitle = route?.title?.trim();
2508
+ if (!routeTitle || routeTitle === config.title) return config.title;
2509
+ return `${routeTitle} - ${config.title}`;
2510
+ }
2511
+ function setNamedMeta(name, content) {
2512
+ const existing = document.head.querySelector(`meta[name="${name}"]`);
2513
+ if (!content) {
2514
+ existing?.remove();
2515
+ return;
2516
+ }
2517
+ const meta = existing ?? document.createElement("meta");
2518
+ meta.name = name;
2519
+ meta.content = content;
2520
+ if (!existing) document.head.appendChild(meta);
2521
+ }
2522
+ function applyDocumentMetadata(config, route) {
2523
+ document.title = pageTitle(config, route);
2524
+ setNamedMeta("description", route?.description ?? config.description);
2525
+ setNamedMeta("keywords", route?.keywords?.join(", "));
2526
+ }
2527
+ function applyRootThemeVariables(themeVariables) {
2528
+ const rootStyle = document.documentElement.style;
2529
+ for (const [property, value] of Object.entries(themeVariables)) rootStyle.setProperty(property, value);
2530
+ return () => {
2531
+ for (const property of Object.keys(themeVariables)) rootStyle.removeProperty(property);
2532
+ };
1991
2533
  }
1992
2534
  function AppShell(arg0) {
1993
2535
  const { config, routes, navigation } = arg0;
1994
2536
  const location = useLocation();
1995
- const currentRoute = routeForPath(routes, location.pathname);
1996
- const currentLocale = localeForPath(config, location.pathname, currentRoute);
2537
+ const pathname = normalizeRoutePath(location.pathname);
2538
+ const currentRoute = routeForPath(routes, pathname);
2539
+ const currentLocale = localeForPath(config, pathname, currentRoute);
1997
2540
  const currentLocaleConfig = config.i18n?.locales.find((locale) => locale.code === currentLocale);
1998
- const currentNavigation = navigationForLocale(navigation, currentLocale);
2541
+ const currentNavigation = navigationForLocale(navigation, currentLocale, pathname);
1999
2542
  const sections = sectionsForRoute(currentRoute);
2543
+ const hasTabs = Boolean(currentNavigation.tabs?.length);
2544
+ const themeVariables = themeStyle(config);
2545
+ const renderRoutes = useMemo(() => routes.map((route) => ({
2546
+ ...route,
2547
+ component: resolveRouteComponent(route)
2548
+ })), [routes]);
2549
+ useEffect(() => applyRootThemeVariables(themeVariables), [themeVariables]);
2000
2550
  useEffect(() => {
2001
- scrollToHash(location.hash);
2551
+ if (location.hash) {
2552
+ scrollToHash(location.hash);
2553
+ return;
2554
+ }
2555
+ window.scrollTo({
2556
+ top: 0,
2557
+ left: 0
2558
+ });
2559
+ window.requestAnimationFrame(() => {
2560
+ window.dispatchEvent(new Event("scroll"));
2561
+ });
2002
2562
  }, [location.hash, location.pathname]);
2003
2563
  useEffect(() => {
2004
2564
  if (!currentLocale) return;
@@ -2006,61 +2566,64 @@ function AppShell(arg0) {
2006
2566
  if (currentLocaleConfig?.dir) document.documentElement.dir = currentLocaleConfig.dir;
2007
2567
  else document.documentElement.removeAttribute("dir");
2008
2568
  }, [currentLocale, currentLocaleConfig?.dir]);
2009
- return /* @__PURE__ */ jsx(SectionProvider, {
2010
- sections,
2011
- children: /* @__PURE__ */ jsxs("div", {
2012
- className: "clarify-app h-full min-h-screen bg-white lg:ml-72 xl:ml-80 dark:bg-zinc-950",
2013
- children: [/* @__PURE__ */ jsx(motion.header, {
2014
- layoutScroll: true,
2015
- className: "clarify-shell contents lg:pointer-events-none lg:fixed lg:inset-0 lg:z-40 lg:flex",
2016
- children: /* @__PURE__ */ jsxs("div", {
2017
- className: "clarify-sidebar contents lg:pointer-events-auto lg:block lg:w-72 lg:overflow-y-auto lg:border-r lg:border-zinc-900/10 lg:bg-white lg:px-6 lg:pt-4 lg:pb-8 xl:w-80 lg:dark:border-white/10 lg:dark:bg-zinc-950",
2018
- children: [
2019
- /* @__PURE__ */ jsx("div", {
2020
- className: "clarify-sidebar-brand hidden lg:flex",
2021
- children: /* @__PURE__ */ jsxs(Link, {
2022
- to: homePathForLocale(config, currentLocale),
2023
- "aria-label": "Home",
2024
- className: "clarify-brand flex items-center gap-2 no-underline",
2025
- children: [/* @__PURE__ */ jsx(SiteLogo, {
2026
- logo: config.logo,
2027
- className: "h-6 w-6"
2028
- }), /* @__PURE__ */ jsx("span", {
2029
- className: "clarify-brand-title text-sm font-semibold text-zinc-900 dark:text-white",
2030
- children: config.title
2031
- })]
2032
- })
2033
- }),
2034
- /* @__PURE__ */ jsx(Header, {
2035
- config,
2036
- navigation: currentNavigation,
2037
- routes,
2038
- currentLocale,
2039
- currentRoute
2040
- }),
2041
- /* @__PURE__ */ jsx(Navigation, {
2042
- navigation: currentNavigation,
2043
- className: "clarify-navigation hidden lg:mt-10 lg:block"
2044
- })
2045
- ]
2046
- })
2047
- }), /* @__PURE__ */ jsxs("div", {
2048
- className: "clarify-content relative flex min-h-screen flex-col px-4 pt-14 sm:px-6 lg:px-8",
2049
- children: [/* @__PURE__ */ jsx(ContentActions, {
2050
- route: currentRoute,
2051
- routePrefix: config.routePrefix
2052
- }), /* @__PURE__ */ jsx("main", {
2053
- className: "clarify-main flex-auto",
2054
- children: /* @__PURE__ */ jsx(Routes, { children: routes.map((route) => /* @__PURE__ */ jsx(Route, {
2055
- path: route.path,
2056
- element: /* @__PURE__ */ jsx(route.component, {})
2057
- }, route.path)) })
2058
- })]
2059
- })]
2569
+ useEffect(() => {
2570
+ applyDocumentMetadata(config, currentRoute);
2571
+ }, [config, currentRoute]);
2572
+ return /* @__PURE__ */ jsx(ClarifyLocaleContext.Provider, {
2573
+ value: currentLocale,
2574
+ children: /* @__PURE__ */ jsx(SectionProvider, {
2575
+ sections,
2576
+ children: /* @__PURE__ */ jsxs("div", {
2577
+ className: "clarify-app h-full min-h-screen bg-(--clarify-theme-tokens-colors-background) text-(--clarify-theme-tokens-colors-foreground) dark:bg-zinc-950 dark:text-white",
2578
+ "data-theme-preset": config.theme.preset,
2579
+ style: themeVariables,
2580
+ children: [
2581
+ /* @__PURE__ */ jsx(Header, {
2582
+ config,
2583
+ navigation: currentNavigation.items,
2584
+ tabs: currentNavigation.tabs,
2585
+ routes,
2586
+ currentLocale,
2587
+ currentRoute
2588
+ }),
2589
+ /* @__PURE__ */ jsxs("div", {
2590
+ className: "clarify-layout mx-auto grid w-full max-w-(--clarify-theme-layout-max-width) grid-cols-1 lg:grid-cols-[18rem_minmax(0,1fr)] xl:grid-cols-[20rem_minmax(0,1fr)]",
2591
+ children: [/* @__PURE__ */ jsx(motion.aside, {
2592
+ layoutScroll: true,
2593
+ className: clsx("clarify-sidebar hidden lg:sticky lg:z-30 lg:block lg:h-[calc(100vh-3.5rem)] lg:self-start lg:overflow-y-auto lg:bg-(--clarify-theme-tokens-colors-background) lg:px-5 lg:pb-8 xl:px-6 lg:dark:bg-zinc-950", hasTabs ? "lg:top-28 lg:h-[calc(100vh-7rem)] lg:pt-6" : "lg:top-14 lg:pt-6"),
2594
+ children: /* @__PURE__ */ jsx(Navigation, { navigation: currentNavigation.items })
2595
+ }), /* @__PURE__ */ jsxs("div", {
2596
+ className: clsx("clarify-content @container relative flex min-h-screen min-w-0 flex-col px-4 sm:px-6 lg:px-8 xl:px-10", hasTabs ? "pt-14 lg:pt-28" : "pt-14"),
2597
+ children: [
2598
+ /* @__PURE__ */ jsx(ContentActions, {
2599
+ hasTabs,
2600
+ route: currentRoute,
2601
+ routePrefix: config.routePrefix
2602
+ }),
2603
+ /* @__PURE__ */ jsx("main", {
2604
+ className: "clarify-main min-w-0 flex-auto",
2605
+ children: /* @__PURE__ */ jsx(Suspense, {
2606
+ fallback: null,
2607
+ children: /* @__PURE__ */ jsx(Routes, { children: renderRoutes.map((route) => /* @__PURE__ */ jsx(Route, {
2608
+ path: route.path,
2609
+ element: /* @__PURE__ */ jsx(route.component, {})
2610
+ }, route.path)) })
2611
+ })
2612
+ }),
2613
+ /* @__PURE__ */ jsx(PageNavigation, {
2614
+ navigation: currentNavigation.items,
2615
+ currentRoute
2616
+ })
2617
+ ]
2618
+ })]
2619
+ }),
2620
+ /* @__PURE__ */ jsx(PageFooter, {})
2621
+ ]
2622
+ })
2060
2623
  })
2061
2624
  });
2062
2625
  }
2063
2626
  //#endregion
2064
- export { Card as C, SectionProvider as D, BuiltWithClarify as E, useSectionStore as O, Pre as S, Callout as T, GridPattern as _, Heading as a, Code as b, Tag as c, useTheme as d, PageFooter as f, useOpenApis as g, useClarifyConfig as h, DocShell as i, remToPx as k, ThemeToggle as l, OpenApisContext as m, ApiEndpointCard as n, Logo as o, ClarifyConfigContext as p, Button as r, Prose as s, AppShell as t, ThemeProvider as u, HeroPattern as v, CardGroup as w, CodeGroup as x, Feedback as y };
2627
+ export { remToPx as A, useBuiltInText as C, useOpenApis as D, useClarifyConfig as E, SectionProvider as O, BuiltWithClarify as S, OpenApisContext as T, CodeGroup as _, Heading as a, CardGroup as b, Tag as c, useTheme as d, PageFooter as f, Code as g, Feedback as h, DocShell as i, useSectionStore as k, ThemeToggle as l, HeroPattern as m, ApiEndpointCard as n, Logo as o, GridPattern as p, Button as r, Prose as s, AppShell as t, ThemeProvider as u, Pre as v, ClarifyConfigContext as w, Callout as x, Card as y };
2065
2628
 
2066
- //# sourceMappingURL=AppShell-Ci894P_0.js.map
2629
+ //# sourceMappingURL=AppShell-nQnuKyn2.js.map