@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
@@ -29,16 +29,16 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
29
  enumerable: true
30
30
  }) : target, mod));
31
31
  //#endregion
32
+ let clsx = require("clsx");
33
+ clsx = __toESM(clsx, 1);
32
34
  let framer_motion = require("framer-motion");
33
35
  let react = require("react");
34
36
  let react_router_dom = require("react-router-dom");
35
37
  let zustand = require("zustand");
36
38
  let react_jsx_runtime = require("react/jsx-runtime");
37
- let clsx = require("clsx");
38
- clsx = __toESM(clsx, 1);
39
- let _headlessui_react = require("@headlessui/react");
40
39
  let lucide_react = require("lucide-react");
41
40
  lucide_react = __toESM(lucide_react, 1);
41
+ let _headlessui_react = require("@headlessui/react");
42
42
  //#region source/utils/remToPx.ts
43
43
  function remToPx(remValue) {
44
44
  return remValue * (typeof window === "undefined" ? 16 : Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize));
@@ -93,7 +93,14 @@ function SectionProvider(arg0) {
93
93
  const [sectionStore] = (0, react.useState)(() => createSectionStore(sections));
94
94
  useVisibleSections(sectionStore);
95
95
  useIsomorphicLayoutEffect(() => {
96
- sectionStore.setState({ sections });
96
+ sectionStore.setState((state) => ({ sections: sections.map((section) => {
97
+ const registeredSection = state.sections.find((item) => item.id === section.id);
98
+ return {
99
+ ...section,
100
+ headingRef: registeredSection?.headingRef,
101
+ offsetRem: registeredSection?.offsetRem ?? section.offsetRem
102
+ };
103
+ }) }));
97
104
  }, [sectionStore, sections]);
98
105
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SectionStoreContext.Provider, {
99
106
  value: sectionStore,
@@ -106,110 +113,179 @@ function useSectionStore(selector) {
106
113
  return (0, zustand.useStore)(store, selector);
107
114
  }
108
115
  //#endregion
109
- //#region source/components/SiteLogo.tsx
110
- function SiteLogo(arg0) {
111
- const { logo, className } = arg0;
112
- if (!logo) return null;
113
- if (typeof logo === "string") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
114
- src: logo,
115
- alt: "",
116
- className: (0, clsx.default)("clarify-logo", className)
117
- });
118
- const lightLogo = logo.light ?? logo.dark;
119
- const darkLogo = logo.dark ?? logo.light;
120
- if (!lightLogo || !darkLogo) return null;
121
- if (lightLogo === darkLogo) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
122
- src: lightLogo,
123
- alt: "",
124
- className: (0, clsx.default)("clarify-logo", className)
125
- });
126
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
127
- src: lightLogo,
128
- alt: "",
129
- className: (0, clsx.default)("clarify-logo clarify-logo-light", className, "dark:hidden")
130
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
131
- src: darkLogo,
132
- alt: "",
133
- className: (0, clsx.default)("clarify-logo clarify-logo-dark", className, "hidden dark:block")
134
- })] });
116
+ //#region source/context.tsx
117
+ var ClarifyConfigContext = (0, react.createContext)(null);
118
+ var ClarifyLocaleContext = (0, react.createContext)(void 0);
119
+ var OpenApisContext = (0, react.createContext)({});
120
+ function useClarifyConfig() {
121
+ const config = (0, react.useContext)(ClarifyConfigContext);
122
+ if (!config) throw new Error("[clarify] useClarifyConfig must be used within a ClarifyConfigContext.Provider");
123
+ return config;
135
124
  }
136
- //#endregion
137
- //#region source/shell/ContentActions.tsx
138
- function resolveRawContentUrl(rawContentUrl, routePrefix = "/") {
139
- if (!routePrefix || routePrefix === "/") return rawContentUrl;
140
- return `/${routePrefix.replace(/^\/+|\/+$/g, "")}${rawContentUrl}`;
125
+ function useOpenApis() {
126
+ return (0, react.useContext)(OpenApisContext);
141
127
  }
142
- function getAbsoluteUrl(path) {
143
- if (typeof window === "undefined") return path;
144
- return new URL(path, window.location.href).href;
128
+ //#endregion
129
+ //#region source/i18n.ts
130
+ var builtInText = {
131
+ en: {
132
+ "actions.code": "Code",
133
+ "actions.copy": "Copy",
134
+ "actions.copied": "Copied!",
135
+ "builtWith.label": "Built with Clarify",
136
+ "builtWith.prefix": "Built with",
137
+ "callout.danger": "Danger",
138
+ "callout.info": "Info",
139
+ "callout.note": "Note",
140
+ "callout.success": "Success",
141
+ "callout.tip": "Tip",
142
+ "callout.warning": "Warning",
143
+ "contentActions.copyContent": "Copy page",
144
+ "contentActions.copyContentDescription": "Copy this page as {contentType} for LLMs",
145
+ "contentActions.copyLink": "Copy {contentType} link",
146
+ "contentActions.copyLinkDescription": "Copy the raw {contentType} content link for this page",
147
+ "contentActions.copyOptions": "Choose copy option",
148
+ "contentActions.copiedContent": "Copied page",
149
+ "contentActions.copiedLink": "Copied link",
150
+ "contentActions.viewMarkdown": "View as Markdown",
151
+ "contentActions.viewMarkdownDescription": "View this page as plain text",
152
+ "contentActions.viewOpenApi": "View raw OpenAPI",
153
+ "contentActions.viewOpenApiDescription": "Open the API description file in a new tab",
154
+ "feedback.no": "No",
155
+ "feedback.prompt": "Was this page helpful?",
156
+ "feedback.thanks": "Thanks for your feedback!",
157
+ "feedback.yes": "Yes",
158
+ "navigation.documentation": "Documentation",
159
+ "navigation.next": "Next",
160
+ "navigation.previous": "Previous",
161
+ "navigation.previousNext": "Previous and next pages",
162
+ "navigation.toggle": "Toggle navigation",
163
+ "navbar.home": "Home",
164
+ "navbar.openLinks": "Open navigation links",
165
+ "navbar.sections": "Documentation sections",
166
+ "openapi.apiDocumentation": "API Documentation",
167
+ "openapi.bodyProperties": "Body properties",
168
+ "openapi.collapse": "Collapse",
169
+ "openapi.endpointNotFound": "Endpoint not found: {endpoint}",
170
+ "openapi.example": "Example",
171
+ "openapi.expand": "Expand",
172
+ "openapi.headers": "Headers",
173
+ "openapi.language": "Language",
174
+ "openapi.client": "Client",
175
+ "openapi.mediaType": "Media type",
176
+ "openapi.openApiReference": "OpenAPI Reference",
177
+ "openapi.operationParameter": "Operation parameter.",
178
+ "openapi.optional": "Optional.",
179
+ "openapi.parameter": "parameter",
180
+ "openapi.pathParameters": "Path parameters",
181
+ "openapi.queryParameters": "Query parameters",
182
+ "openapi.request": "Request",
183
+ "openapi.requestBody": "Request body",
184
+ "openapi.required": "Required.",
185
+ "openapi.requiredBadge": "required",
186
+ "openapi.response": "Response",
187
+ "openapi.responses": "Responses",
188
+ "openapi.schemaExample": "Schema example",
189
+ "openapi.scrollExamplesLeft": "Scroll examples left",
190
+ "openapi.scrollExamplesRight": "Scroll examples right",
191
+ "openapi.specNotFound": "OpenAPI spec not found: {specPath}",
192
+ "openapi.specPathMissing": "spec or specPath was not provided",
193
+ "openapi.status": "Status",
194
+ "openapi.version": "Version {version}",
195
+ "search.button": "Search...",
196
+ "search.noResults": "Nothing found for {query}.",
197
+ "search.placeholder": "Find something...",
198
+ "search.shortcutCtrl": "Ctrl ",
199
+ "theme.switchToDark": "Switch to dark theme",
200
+ "theme.switchToLight": "Switch to light theme",
201
+ "language.switch": "Switch language"
202
+ },
203
+ "zh-CN": {
204
+ "actions.code": "代码",
205
+ "actions.copy": "复制",
206
+ "actions.copied": "已复制!",
207
+ "builtWith.label": "由 Clarify 构建",
208
+ "builtWith.prefix": "构建来自",
209
+ "callout.danger": "危险",
210
+ "callout.info": "信息",
211
+ "callout.note": "注意",
212
+ "callout.success": "成功",
213
+ "callout.tip": "提示",
214
+ "callout.warning": "警告",
215
+ "contentActions.copyContent": "复制页面",
216
+ "contentActions.copyContentDescription": "将页面以 {contentType} 格式复制给 LLMs",
217
+ "contentActions.copyLink": "复制 {contentType} 链接",
218
+ "contentActions.copyLinkDescription": "复制当前页面的 {contentType} 原始内容链接",
219
+ "contentActions.copyOptions": "选择复制选项",
220
+ "contentActions.copiedContent": "已复制页面",
221
+ "contentActions.copiedLink": "已复制链接",
222
+ "contentActions.viewMarkdown": "以 Markdown 格式查看",
223
+ "contentActions.viewMarkdownDescription": "以纯文本查看此页面",
224
+ "contentActions.viewOpenApi": "查看 OpenAPI 原始内容",
225
+ "contentActions.viewOpenApiDescription": "在新标签页打开 API 描述文件",
226
+ "feedback.no": "否",
227
+ "feedback.prompt": "这个页面有帮助吗?",
228
+ "feedback.thanks": "感谢你的反馈!",
229
+ "feedback.yes": "是",
230
+ "navigation.documentation": "文档",
231
+ "navigation.next": "下一页",
232
+ "navigation.previous": "上一页",
233
+ "navigation.previousNext": "上一页和下一页",
234
+ "navigation.toggle": "切换导航",
235
+ "navbar.home": "首页",
236
+ "navbar.openLinks": "打开导航链接",
237
+ "navbar.sections": "文档栏目",
238
+ "openapi.apiDocumentation": "API 文档",
239
+ "openapi.bodyProperties": "请求体属性",
240
+ "openapi.collapse": "收起",
241
+ "openapi.endpointNotFound": "未找到端点:{endpoint}",
242
+ "openapi.example": "示例",
243
+ "openapi.expand": "展开",
244
+ "openapi.headers": "请求头",
245
+ "openapi.language": "语言",
246
+ "openapi.client": "客户端",
247
+ "openapi.mediaType": "媒体类型",
248
+ "openapi.openApiReference": "OpenAPI 参考",
249
+ "openapi.operationParameter": "操作参数。",
250
+ "openapi.optional": "可选。",
251
+ "openapi.parameter": "参数",
252
+ "openapi.pathParameters": "路径参数",
253
+ "openapi.queryParameters": "查询参数",
254
+ "openapi.request": "请求",
255
+ "openapi.requestBody": "请求体",
256
+ "openapi.required": "必填。",
257
+ "openapi.requiredBadge": "必填",
258
+ "openapi.response": "响应",
259
+ "openapi.responses": "响应",
260
+ "openapi.schemaExample": "Schema 示例",
261
+ "openapi.scrollExamplesLeft": "向左滚动示例",
262
+ "openapi.scrollExamplesRight": "向右滚动示例",
263
+ "openapi.specNotFound": "未找到 OpenAPI 描述文件:{specPath}",
264
+ "openapi.specPathMissing": "未提供 spec 或 specPath",
265
+ "openapi.status": "状态",
266
+ "openapi.version": "版本 {version}",
267
+ "search.button": "搜索...",
268
+ "search.noResults": "没有找到与 {query} 相关的结果。",
269
+ "search.placeholder": "搜索内容...",
270
+ "search.shortcutCtrl": "Ctrl ",
271
+ "theme.switchToDark": "切换到深色主题",
272
+ "theme.switchToLight": "切换到浅色主题",
273
+ "language.switch": "切换语言"
274
+ }
275
+ };
276
+ function resolveBuiltInLocale(locale) {
277
+ return locale === "zh-CN" || locale?.toLowerCase().startsWith("zh") ? "zh-CN" : "en";
145
278
  }
146
- async function copyText(text) {
147
- await navigator.clipboard.writeText(text);
279
+ function translateBuiltInText(locale, key, replacements = {}) {
280
+ let value = builtInText[resolveBuiltInLocale(locale)]?.[key] ?? builtInText.en[key];
281
+ for (const [name, replacement] of Object.entries(replacements)) value = value.replaceAll(`{${name}}`, replacement);
282
+ return value;
148
283
  }
149
- function ContentActions(arg0) {
150
- const { route, routePrefix } = arg0;
151
- const [copied, setCopied] = (0, react.useState)("idle");
152
- if (!route?.rawContentUrl) return null;
153
- const rawContentUrl = resolveRawContentUrl(route.rawContentUrl, routePrefix);
154
- const isOpenApi = route.kind === "openapi";
155
- const contentLabel = isOpenApi ? "复制 OpenAPI 内容" : "复制 Markdown 内容";
156
- const linkLabel = isOpenApi ? "复制 OpenAPI 链接" : "复制 Markdown 链接";
157
- function markCopied(state) {
158
- setCopied(state);
159
- window.setTimeout(() => setCopied("idle"), 1600);
160
- }
161
- async function handleCopyContent() {
162
- await copyText(await (await fetch(rawContentUrl)).text());
163
- markCopied("content");
164
- }
165
- async function handleCopyLink() {
166
- await copyText(getAbsoluteUrl(rawContentUrl));
167
- markCopied("link");
168
- }
169
- const actions = [{
170
- key: "content",
171
- label: contentLabel,
172
- icon: lucide_react.Copy,
173
- run: handleCopyContent
174
- }, {
175
- key: "link",
176
- label: linkLabel,
177
- icon: lucide_react.Link2,
178
- run: handleCopyLink
179
- }];
180
- const primaryAction = actions[0];
181
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
182
- className: "clarify-content-actions sticky top-16 z-20 flex justify-end py-4",
183
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.Menu, {
184
- as: "div",
185
- className: "clarify-content-actions-menu relative inline-flex text-xs font-medium",
186
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
187
- 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",
188
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
189
- type: "button",
190
- onClick: primaryAction.run,
191
- 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",
192
- children: [copied === primaryAction.key ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(primaryAction.icon, { className: "h-3.5 w-3.5" }), copied === primaryAction.key ? "已复制" : "复制页面"]
193
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuButton, {
194
- 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",
195
- "aria-label": "选择复制选项",
196
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronDown, { className: "h-3.5 w-3.5" })
197
- })]
198
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItems, {
199
- anchor: "bottom end",
200
- 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",
201
- children: actions.map((action) => {
202
- const Icon = copied === action.key ? lucide_react.Check : action.icon;
203
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
204
- type: "button",
205
- onClick: action.run,
206
- 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",
207
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { className: "h-3.5 w-3.5" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: copied === action.key ? "已复制" : action.label })]
208
- }) }, action.key);
209
- })
210
- })]
211
- })
212
- });
284
+ function useBuiltInText(locale) {
285
+ const config = (0, react.useContext)(ClarifyConfigContext);
286
+ const currentLocale = (0, react.useContext)(ClarifyLocaleContext);
287
+ const resolvedLocale = locale ?? currentLocale ?? config?.i18n?.defaultLocale;
288
+ return (key, replacements) => translateBuiltInText(resolvedLocale, key, replacements);
213
289
  }
214
290
  //#endregion
215
291
  //#region source/components/BuiltWithClarify.tsx
@@ -237,17 +313,18 @@ function ClarifyMark(props) {
237
313
  });
238
314
  }
239
315
  function BuiltWithClarify() {
316
+ const t = useBuiltInText();
240
317
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
241
318
  href: "https://clarify.pub",
242
319
  target: "_blank",
243
320
  rel: "noreferrer",
244
- "aria-label": "Built with Clarify",
245
- 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",
321
+ "aria-label": t("builtWith.label"),
322
+ className: "clarify-built-with inline-flex items-center gap-1.5 rounded-full px-2 py-1 font-medium no-underline transition",
246
323
  children: [
247
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Built with" }),
324
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("builtWith.prefix") }),
248
325
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ClarifyMark, { className: "clarify-built-with-logo h-3.5 w-5 flex-none" }),
249
326
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
250
- className: "font-semibold text-zinc-700 dark:text-zinc-300",
327
+ className: "clarify-built-with-brand font-semibold",
251
328
  children: "Clarify"
252
329
  })
253
330
  ]
@@ -293,21 +370,22 @@ var calloutStyles = {
293
370
  Icon: lucide_react.CheckCircle2
294
371
  }
295
372
  };
296
- var defaultTitles = {
297
- info: "Info",
298
- note: "Note",
299
- tip: "Tip",
300
- warning: "Warning",
301
- danger: "Danger",
302
- success: "Success"
373
+ var defaultTitleKeys = {
374
+ info: "callout.info",
375
+ note: "callout.note",
376
+ tip: "callout.tip",
377
+ warning: "callout.warning",
378
+ danger: "callout.danger",
379
+ success: "callout.success"
303
380
  };
304
381
  function Callout(arg0) {
305
382
  const { children, type = "info", title, icon = true, className, ...props } = arg0;
383
+ const t = useBuiltInText();
306
384
  const style = calloutStyles[type];
307
385
  const Icon = style.Icon;
308
- const resolvedTitle = title === void 0 ? defaultTitles[type] : title;
386
+ const resolvedTitle = title === void 0 ? t(defaultTitleKeys[type]) : title;
309
387
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
310
- className: (0, clsx.default)("clarify-callout my-6 flex gap-3 rounded-2xl border p-4 text-sm/6", style.container, className),
388
+ className: (0, clsx.default)("clarify-callout my-6 flex gap-3 rounded-(--clarify-theme-tokens-radius-xl) border p-4 text-sm/6", style.container, className),
311
389
  ...props,
312
390
  children: [icon ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
313
391
  className: (0, clsx.default)("mt-1 size-4 flex-none", style.icon),
@@ -335,7 +413,7 @@ function CardIcon(arg0) {
335
413
  const Icon = lucide_react[toPascalCase(name)];
336
414
  if (!Icon) return null;
337
415
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
338
- 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",
416
+ 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)",
339
417
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
340
418
  className: "size-5",
341
419
  "aria-hidden": "true"
@@ -362,18 +440,18 @@ function Card(arg0) {
362
440
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CardIcon, { name: icon }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
363
441
  className: "min-w-0 flex-1",
364
442
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
365
- className: "m-0 text-base font-semibold text-zinc-900 dark:text-white",
443
+ className: "m-0 text-base font-semibold text-[var(--clarify-theme-tokens-colors-foreground)] dark:text-white",
366
444
  children: title
367
445
  }), children ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
368
- className: "mt-2 text-sm/6 text-zinc-600 dark:text-zinc-400 *:m-0",
446
+ className: "mt-2 text-sm/6 text-[var(--clarify-theme-tokens-colors-muted)] dark:text-zinc-400 *:m-0",
369
447
  children
370
448
  }) : null]
371
449
  })]
372
450
  }), href ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
373
- className: "absolute inset-0 rounded-2xl",
451
+ className: "absolute inset-0 rounded-[var(--clarify-theme-tokens-radius-xl)]",
374
452
  "aria-hidden": "true"
375
453
  }) : null] });
376
- const classes = (0, clsx.default)("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);
454
+ const classes = (0, clsx.default)("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);
377
455
  if (!href) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
378
456
  className: classes,
379
457
  children: content
@@ -410,10 +488,10 @@ var languageNames = {
410
488
  json: "JSON"
411
489
  };
412
490
  function getPanelTitle(arg0) {
413
- const { title, language } = arg0;
491
+ const { title, language, fallbackTitle = "Code" } = arg0;
414
492
  if (title) return title;
415
493
  if (language && language in languageNames) return languageNames[language];
416
- return "Code";
494
+ return fallbackTitle;
417
495
  }
418
496
  function getNodeText(node) {
419
497
  if (typeof node === "string" || typeof node === "number") return String(node);
@@ -438,6 +516,7 @@ function ClipboardIcon(props) {
438
516
  }
439
517
  function CopyButton(arg0) {
440
518
  const { code } = arg0;
519
+ const t = useBuiltInText();
441
520
  const [copyCount, setCopyCount] = (0, react.useState)(0);
442
521
  const copied = copyCount > 0;
443
522
  (0, react.useEffect)(() => {
@@ -448,7 +527,7 @@ function CopyButton(arg0) {
448
527
  if (!code) return null;
449
528
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
450
529
  type: "button",
451
- className: (0, clsx.default)("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"),
530
+ className: (0, clsx.default)("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"),
452
531
  onClick: () => {
453
532
  window.navigator.clipboard.writeText(code).then(() => {
454
533
  setCopyCount((count) => count + 1);
@@ -457,11 +536,11 @@ function CopyButton(arg0) {
457
536
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
458
537
  "aria-hidden": copied,
459
538
  className: (0, clsx.default)("pointer-events-none flex items-center gap-0.5 text-zinc-400 transition duration-300", copied && "-translate-y-1.5 opacity-0"),
460
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ClipboardIcon, { className: "h-5 w-5 fill-zinc-500/20 stroke-zinc-500 transition-colors group-hover/button:stroke-zinc-400" }), "Copy"]
539
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ClipboardIcon, { className: "h-5 w-5 fill-zinc-500/20 stroke-zinc-500 transition-colors group-hover/button:stroke-zinc-400" }), t("actions.copy")]
461
540
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
462
541
  "aria-hidden": !copied,
463
- className: (0, clsx.default)("pointer-events-none absolute inset-0 flex items-center justify-center text-emerald-400 transition duration-300", !copied && "translate-y-1.5 opacity-0"),
464
- children: "Copied!"
542
+ className: (0, clsx.default)("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"),
543
+ children: t("actions.copied")
465
544
  })]
466
545
  });
467
546
  }
@@ -472,7 +551,7 @@ function CodePanelHeader(arg0) {
472
551
  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",
473
552
  children: [
474
553
  tag ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
475
- className: "font-mono text-[0.625rem]/6 font-semibold text-emerald-400",
554
+ className: "font-mono text-[0.625rem]/6 font-semibold text-[var(--clarify-theme-tokens-colors-primary)]",
476
555
  children: tag
477
556
  }) : null,
478
557
  tag && label ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "h-0.5 w-0.5 rounded-full bg-zinc-500" }) : null,
@@ -510,6 +589,7 @@ function CodePanel(arg0) {
510
589
  }
511
590
  function CodeGroupHeader(arg0) {
512
591
  const { title, children, selectedIndex } = arg0;
592
+ const t = useBuiltInText();
513
593
  const hasTabs = react.Children.count(children) > 1;
514
594
  if (!title && !hasTabs) return null;
515
595
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -520,8 +600,11 @@ function CodeGroupHeader(arg0) {
520
600
  }) : null, hasTabs ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.TabList, {
521
601
  className: "clarify-code-tabs -mb-px flex gap-4 text-xs font-medium",
522
602
  children: react.Children.map(children, (child, childIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.Tab, {
523
- className: (0, clsx.default)("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"),
524
- children: getPanelTitle((0, react.isValidElement)(child) ? child.props : {})
603
+ className: (0, clsx.default)("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"),
604
+ children: getPanelTitle({
605
+ ...(0, react.isValidElement)(child) ? child.props : {},
606
+ fallbackTitle: t("actions.code")
607
+ })
525
608
  }))
526
609
  }) : null]
527
610
  });
@@ -582,7 +665,11 @@ function useTabGroupProps(availableLanguages) {
582
665
  var CodeGroupContext = (0, react.createContext)(false);
583
666
  function CodeGroup(arg0) {
584
667
  const { children, title, ...props } = arg0;
585
- const tabGroupProps = useTabGroupProps(react.Children.map(children, (child) => getPanelTitle((0, react.isValidElement)(child) ? child.props : {})) ?? []);
668
+ const t = useBuiltInText();
669
+ const tabGroupProps = useTabGroupProps(react.Children.map(children, (child) => getPanelTitle({
670
+ ...(0, react.isValidElement)(child) ? child.props : {},
671
+ fallbackTitle: t("actions.code")
672
+ })) ?? []);
586
673
  const hasTabs = react.Children.count(children) > 1;
587
674
  const containerClassName = "clarify-code-group my-6 overflow-hidden rounded-2xl bg-zinc-900 shadow-md dark:ring-1 dark:ring-white/10";
588
675
  const header = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeGroupHeader, {
@@ -661,6 +748,7 @@ function FeedbackButton(props) {
661
748
  }
662
749
  var FeedbackForm = (0, react.forwardRef)(function FeedbackForm(arg0, ref) {
663
750
  const { onSubmit, className, ...props } = arg0;
751
+ const t = useBuiltInText();
664
752
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
665
753
  ...props,
666
754
  ref,
@@ -668,18 +756,18 @@ var FeedbackForm = (0, react.forwardRef)(function FeedbackForm(arg0, ref) {
668
756
  className: (0, clsx.default)(className, "clarify-feedback-form absolute inset-0 flex items-center justify-center gap-6 md:justify-start"),
669
757
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
670
758
  className: "text-sm text-zinc-600 dark:text-zinc-400",
671
- children: "Was this page helpful?"
759
+ children: t("feedback.prompt")
672
760
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
673
761
  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",
674
762
  children: [
675
763
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FeedbackButton, {
676
764
  "data-response": "yes",
677
- children: "Yes"
765
+ children: t("feedback.yes")
678
766
  }),
679
767
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "bg-zinc-900/10 dark:bg-white/10" }),
680
768
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FeedbackButton, {
681
769
  "data-response": "no",
682
- children: "No"
770
+ children: t("feedback.no")
683
771
  })
684
772
  ]
685
773
  })]
@@ -687,13 +775,14 @@ var FeedbackForm = (0, react.forwardRef)(function FeedbackForm(arg0, ref) {
687
775
  });
688
776
  var FeedbackThanks = (0, react.forwardRef)(function FeedbackThanks(arg0, ref) {
689
777
  const { className, ...props } = arg0;
778
+ const t = useBuiltInText();
690
779
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
691
780
  ...props,
692
781
  ref,
693
782
  className: (0, clsx.default)(className, "clarify-feedback-thanks absolute inset-0 flex justify-center md:justify-start"),
694
783
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
695
- 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",
696
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckIcon, { 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!"]
784
+ 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",
785
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckIcon, { 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")]
697
786
  })
698
787
  });
699
788
  });
@@ -765,7 +854,7 @@ function HeroPattern() {
765
854
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
766
855
  className: "absolute top-0 left-1/2 -ml-152 h-100 w-325 dark:mask-[linear-gradient(white,transparent)]",
767
856
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
768
- 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",
857
+ 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",
769
858
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GridPattern, {
770
859
  width: 72,
771
860
  height: 56,
@@ -789,18 +878,6 @@ function HeroPattern() {
789
878
  });
790
879
  }
791
880
  //#endregion
792
- //#region source/context.tsx
793
- var ClarifyConfigContext = (0, react.createContext)(null);
794
- var OpenApisContext = (0, react.createContext)({});
795
- function useClarifyConfig() {
796
- const config = (0, react.useContext)(ClarifyConfigContext);
797
- if (!config) throw new Error("[clarify] useClarifyConfig must be used within a ClarifyConfigContext.Provider");
798
- return config;
799
- }
800
- function useOpenApis() {
801
- return (0, react.useContext)(OpenApisContext);
802
- }
803
- //#endregion
804
881
  //#region source/components/PageFooter.tsx
805
882
  function resolveLocalizedText$1(text, locale, fallbackLocale) {
806
883
  if (typeof text === "string") return text;
@@ -828,7 +905,7 @@ function FooterLink(arg0) {
828
905
  href: external ? link.href : localizeHref$1(link.href, config, locale),
829
906
  target: external ? "_blank" : void 0,
830
907
  rel: external ? "noreferrer" : void 0,
831
- className: "clarify-footer-link text-sm text-zinc-500 no-underline transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white",
908
+ className: "clarify-footer-link no-underline transition",
832
909
  children: resolveLocalizedText$1(link.label, locale, config.i18n?.defaultLocale)
833
910
  });
834
911
  }
@@ -838,7 +915,7 @@ function SocialLink(arg0) {
838
915
  href,
839
916
  target: "_blank",
840
917
  rel: "noreferrer",
841
- 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",
918
+ className: "clarify-footer-social capitalize no-underline transition",
842
919
  children: name
843
920
  });
844
921
  }
@@ -851,11 +928,11 @@ function PageFooter() {
851
928
  const copyright = footer?.copyright ? resolveLocalizedText$1(footer.copyright, locale, config.i18n?.defaultLocale) : void 0;
852
929
  const hasCustomFooter = Boolean(copyright || links.length > 0 || socials.length > 0);
853
930
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("footer", {
854
- className: (0, clsx.default)("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"),
931
+ className: (0, clsx.default)("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"),
855
932
  children: [hasCustomFooter ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
856
933
  className: "clarify-footer-content flex flex-col gap-3 text-right sm:text-left",
857
934
  children: [copyright ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
858
- className: "clarify-footer-copyright m-0 text-sm text-zinc-500 dark:text-zinc-400",
935
+ className: "clarify-footer-copyright m-0",
859
936
  children: copyright
860
937
  }) : null, links.length > 0 || socials.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
861
938
  className: "clarify-footer-links flex flex-wrap justify-end gap-x-4 gap-y-2 sm:justify-start",
@@ -875,6 +952,95 @@ function PageFooter() {
875
952
  });
876
953
  }
877
954
  //#endregion
955
+ //#region source/utils/path.ts
956
+ function normalizeRoutePath(path) {
957
+ const [pathname, suffix = ""] = path.split(/([?#].*)/, 2);
958
+ return `${pathname.replace(/^\/+/, "/").replace(/\/+$/, "") || "/"}${suffix}`;
959
+ }
960
+ function isSameRoutePath(a, b) {
961
+ if (!a || !b) return false;
962
+ return normalizeRoutePath(a) === normalizeRoutePath(b);
963
+ }
964
+ //#endregion
965
+ //#region source/components/PageNavigation.tsx
966
+ function flattenNavigation(nodes) {
967
+ return nodes.flatMap((node) => node.children?.length ? flattenNavigation(node.children) : [node]);
968
+ }
969
+ function PageNavigation(arg0) {
970
+ const { navigation, currentRoute } = arg0;
971
+ const t = useBuiltInText();
972
+ if (!currentRoute) return null;
973
+ const pageRoutes = flattenNavigation(navigation);
974
+ const currentIndex = pageRoutes.findIndex((route) => isSameRoutePath(route.path, currentRoute.path));
975
+ if (currentIndex === -1) return null;
976
+ const previous = pageRoutes[currentIndex - 1];
977
+ const next = pageRoutes[currentIndex + 1];
978
+ if (!previous && !next) return null;
979
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
980
+ className: "clarify-page-navigation mt-6 grid gap-3 @3xl:grid-cols-2",
981
+ "aria-label": t("navigation.previousNext"),
982
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PageNavigationLink, {
983
+ direction: "previous",
984
+ route: previous
985
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PageNavigationLink, {
986
+ direction: "next",
987
+ route: next
988
+ })]
989
+ });
990
+ }
991
+ function PageNavigationLink(arg0) {
992
+ const { direction, route } = arg0;
993
+ const t = useBuiltInText();
994
+ if (!route) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "hidden @3xl:block" });
995
+ const isNext = direction === "next";
996
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_router_dom.Link, {
997
+ to: normalizeRoutePath(route.path),
998
+ className: (0, clsx.default)("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"),
999
+ children: [
1000
+ !isNext ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.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,
1001
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1002
+ className: "min-w-0 flex-1",
1003
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1004
+ className: "block text-[0.6875rem] font-medium uppercase tracking-wide text-(--clarify-theme-tokens-colors-muted)",
1005
+ children: isNext ? t("navigation.next") : t("navigation.previous")
1006
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1007
+ className: "mt-0.5 block truncate text-[0.8125rem] font-semibold text-(--clarify-theme-tokens-colors-foreground) dark:text-white",
1008
+ children: route.title
1009
+ })]
1010
+ }),
1011
+ isNext ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.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
1012
+ ]
1013
+ });
1014
+ }
1015
+ //#endregion
1016
+ //#region source/components/SiteLogo.tsx
1017
+ function SiteLogo(arg0) {
1018
+ const { logo, className } = arg0;
1019
+ if (!logo) return null;
1020
+ if (typeof logo === "string") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
1021
+ src: logo,
1022
+ alt: "",
1023
+ className: (0, clsx.default)("clarify-logo", className)
1024
+ });
1025
+ const lightLogo = logo.light ?? logo.dark;
1026
+ const darkLogo = logo.dark ?? logo.light;
1027
+ if (!lightLogo || !darkLogo) return null;
1028
+ if (lightLogo === darkLogo) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
1029
+ src: lightLogo,
1030
+ alt: "",
1031
+ className: (0, clsx.default)("clarify-logo", className)
1032
+ });
1033
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
1034
+ src: lightLogo,
1035
+ alt: "",
1036
+ className: (0, clsx.default)("clarify-logo clarify-logo-light", className, "dark:hidden")
1037
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
1038
+ src: darkLogo,
1039
+ alt: "",
1040
+ className: (0, clsx.default)("clarify-logo clarify-logo-dark", className, "hidden dark:block")
1041
+ })] });
1042
+ }
1043
+ //#endregion
878
1044
  //#region source/components/ThemeProvider.tsx
879
1045
  var ThemeContext = (0, react.createContext)(null);
880
1046
  var storageKey = "clarify:theme";
@@ -953,15 +1119,16 @@ function MoonIcon(props) {
953
1119
  }
954
1120
  function ThemeToggle() {
955
1121
  const { resolvedTheme, setTheme } = useTheme();
1122
+ const t = useBuiltInText();
956
1123
  const otherTheme = resolvedTheme === "dark" ? "light" : "dark";
957
1124
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
958
1125
  type: "button",
959
- className: "clarify-theme-toggle flex size-6 items-center justify-center rounded-md transition hover:bg-zinc-900/5 dark:hover:bg-white/5",
960
- "aria-label": `Switch to ${otherTheme} theme`,
1126
+ 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",
1127
+ "aria-label": otherTheme === "dark" ? t("theme.switchToDark") : t("theme.switchToLight"),
961
1128
  onClick: () => setTheme(otherTheme),
962
1129
  children: [
963
1130
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "absolute size-12 pointer-fine:hidden" }),
964
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SunIcon, { className: "h-5 w-5 stroke-zinc-900 dark:hidden" }),
1131
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SunIcon, { className: "h-5 w-5 stroke-(--clarify-theme-tokens-colors-foreground) dark:hidden" }),
965
1132
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MoonIcon, { className: "hidden h-5 w-5 stroke-white dark:block" })
966
1133
  ]
967
1134
  });
@@ -983,11 +1150,11 @@ function ArrowIcon(props) {
983
1150
  });
984
1151
  }
985
1152
  var buttonVariantStyles = {
986
- 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",
987
- 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",
988
- 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",
989
- 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",
990
- text: "text-emerald-500 hover:text-emerald-600 dark:text-emerald-400 dark:hover:text-emerald-500"
1153
+ 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",
1154
+ 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",
1155
+ 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",
1156
+ 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",
1157
+ text: "text-(--clarify-theme-tokens-colors-primary) hover:opacity-80 dark:text-(--clarify-theme-tokens-colors-primary) dark:hover:opacity-80"
991
1158
  };
992
1159
  function Button(arg0) {
993
1160
  const { variant = "primary", className, children, arrow, ...props } = arg0;
@@ -1031,8 +1198,8 @@ var tagColorStyles = {
1031
1198
  medium: "bg-rose-50 text-red-500 ring-rose-200 dark:bg-rose-400/10 dark:text-rose-400 dark:ring-rose-500/20"
1032
1199
  },
1033
1200
  zinc: {
1034
- small: "text-zinc-400 dark:text-zinc-500",
1035
- medium: "bg-zinc-50 text-zinc-500 ring-zinc-200 dark:bg-zinc-400/10 dark:text-zinc-400 dark:ring-zinc-500/20"
1201
+ small: "text-(--clarify-theme-tokens-colors-muted) dark:text-zinc-500",
1202
+ 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"
1036
1203
  }
1037
1204
  };
1038
1205
  var tagValueColorMap = {
@@ -1047,7 +1214,7 @@ function Tag(arg0) {
1047
1214
  const value = typeof children === "string" ? children.toUpperCase() : "";
1048
1215
  const resolvedColor = color ?? tagValueColorMap[value] ?? "emerald";
1049
1216
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1050
- className: (0, clsx.default)("clarify-tag font-mono text-[0.625rem]/6 font-semibold", tagVariantStyles[variant], tagColorStyles[resolvedColor][variant]),
1217
+ className: (0, clsx.default)("clarify-tag font-mono text-[0.625rem]/6 font-bold", tagVariantStyles[variant], tagColorStyles[resolvedColor][variant]),
1051
1218
  children
1052
1219
  });
1053
1220
  }
@@ -1058,10 +1225,10 @@ function Logo(props) {
1058
1225
  ...props,
1059
1226
  className: (0, clsx.default)("clarify-logo", props.className),
1060
1227
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1061
- className: "fill-emerald-400",
1228
+ className: "fill-(--clarify-theme-tokens-colors-primary)",
1062
1229
  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"
1063
1230
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1064
- className: "fill-zinc-900 dark:fill-white",
1231
+ className: "fill-(--clarify-theme-tokens-colors-foreground) dark:fill-white",
1065
1232
  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"
1066
1233
  })]
1067
1234
  });
@@ -1069,7 +1236,7 @@ function Logo(props) {
1069
1236
  function Prose(arg0) {
1070
1237
  const { as, className, ...props } = arg0;
1071
1238
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(as ?? "div", {
1072
- className: (0, clsx.default)(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]"),
1239
+ className: (0, clsx.default)(className, "clarify-prose prose max-w-none dark:prose-invert", "[html_:where(&>*)]:w-full [html_:where(&>*)]:min-w-0 [html_:where(&>*)]:max-w-full"),
1073
1240
  ...props
1074
1241
  });
1075
1242
  }
@@ -1113,7 +1280,7 @@ function Anchor(arg0) {
1113
1280
  });
1114
1281
  }
1115
1282
  function Heading(arg0) {
1116
- const { children, tag, label, level, anchor = true, ...props } = arg0;
1283
+ const { children, className, tag, label, level, anchor = true, ...props } = arg0;
1117
1284
  const resolvedLevel = level ?? 2;
1118
1285
  const Component = `h${resolvedLevel}`;
1119
1286
  const ref = (0, react.useRef)(null);
@@ -1140,7 +1307,7 @@ function Heading(arg0) {
1140
1307
  label
1141
1308
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, {
1142
1309
  ref,
1143
- className: (0, clsx.default)("clarify-heading", tag || label ? "mt-2 scroll-mt-32" : "scroll-mt-24"),
1310
+ className: (0, clsx.default)("clarify-heading", tag || label ? "mt-2 scroll-mt-32" : "scroll-mt-24", className),
1144
1311
  ...props,
1145
1312
  children: anchor ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Anchor, {
1146
1313
  id: props.id,
@@ -1186,7 +1353,158 @@ function ApiEndpointCard(arg0) {
1186
1353
  });
1187
1354
  }
1188
1355
  //#endregion
1189
- //#region source/shell/Navigation.tsx
1356
+ //#region source/shell/ContentActions.tsx
1357
+ function resolveContentArtifactUrl(contentArtifactUrl, routePrefix = "/") {
1358
+ if (!routePrefix || routePrefix === "/") return contentArtifactUrl;
1359
+ return `/${routePrefix.replace(/^\/+|\/+$/g, "")}${contentArtifactUrl}`;
1360
+ }
1361
+ function getAbsoluteUrl(path) {
1362
+ if (typeof window === "undefined") return path;
1363
+ return new URL(path, window.location.href).href;
1364
+ }
1365
+ async function copyText(text) {
1366
+ await navigator.clipboard.writeText(text);
1367
+ }
1368
+ function ContentActions(arg0) {
1369
+ const { hasTabs = false, route, routePrefix } = arg0;
1370
+ const t = useBuiltInText();
1371
+ const [copied, setCopied] = (0, react.useState)("idle");
1372
+ if (!route?.contentArtifactUrl) return null;
1373
+ const contentArtifactUrl = resolveContentArtifactUrl(route.contentArtifactUrl, routePrefix);
1374
+ const isOpenApi = route.kind === "openapi";
1375
+ const replacements = { contentType: isOpenApi ? "OpenAPI" : "Markdown" };
1376
+ const viewLabel = isOpenApi ? t("contentActions.viewOpenApi") : t("contentActions.viewMarkdown");
1377
+ const viewDescription = isOpenApi ? t("contentActions.viewOpenApiDescription") : t("contentActions.viewMarkdownDescription");
1378
+ function markCopied(state) {
1379
+ setCopied(state);
1380
+ window.setTimeout(() => setCopied("idle"), 1600);
1381
+ }
1382
+ async function handleCopyContent() {
1383
+ await copyText(await (await fetch(contentArtifactUrl)).text());
1384
+ markCopied("content");
1385
+ }
1386
+ async function handleCopyLink() {
1387
+ await copyText(getAbsoluteUrl(contentArtifactUrl));
1388
+ markCopied("link");
1389
+ }
1390
+ const actions = [{
1391
+ key: "content",
1392
+ label: t("contentActions.copyContent"),
1393
+ description: t("contentActions.copyContentDescription", replacements),
1394
+ icon: lucide_react.Copy,
1395
+ run: handleCopyContent
1396
+ }, {
1397
+ key: "link",
1398
+ label: t("contentActions.copyLink", replacements),
1399
+ description: t("contentActions.copyLinkDescription", replacements),
1400
+ icon: lucide_react.Link2,
1401
+ run: handleCopyLink
1402
+ }];
1403
+ const primaryAction = actions[0];
1404
+ const PrimaryIcon = copied === primaryAction.key ? lucide_react.Check : primaryAction.icon;
1405
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1406
+ className: `clarify-content-actions sticky z-20 flex justify-end py-4 ${hasTabs ? "top-16 lg:top-30" : "top-16"}`,
1407
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.Menu, {
1408
+ as: "div",
1409
+ className: "clarify-content-actions-menu relative inline-flex text-sm font-medium",
1410
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1411
+ 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",
1412
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1413
+ type: "button",
1414
+ onClick: primaryAction.run,
1415
+ className: "clarify-content-actions-primary clarify-ui-control inline-flex h-8 items-center gap-1.5 px-3 transition",
1416
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrimaryIcon, { className: "h-3.5 w-3.5" }), copied === primaryAction.key ? t("actions.copied") : primaryAction.label]
1417
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuButton, {
1418
+ 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",
1419
+ "aria-label": t("contentActions.copyOptions"),
1420
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronDown, { className: "h-3.5 w-3.5" })
1421
+ })]
1422
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.MenuItems, {
1423
+ anchor: "bottom end",
1424
+ 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",
1425
+ children: [
1426
+ actions.slice(0, 1).map((action) => {
1427
+ const Icon = action.icon;
1428
+ const isCopied = copied === action.key;
1429
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1430
+ type: "button",
1431
+ onClick: action.run,
1432
+ 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",
1433
+ children: [
1434
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1435
+ 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",
1436
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { className: "h-4 w-4" })
1437
+ }),
1438
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1439
+ className: "flex min-w-0 flex-1 flex-col px-1",
1440
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1441
+ className: "clarify-ui-menu-title",
1442
+ children: isCopied ? t("contentActions.copiedContent") : action.label
1443
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1444
+ className: "clarify-ui-menu-description truncate",
1445
+ children: action.description
1446
+ })]
1447
+ }),
1448
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, { className: `h-3.5 w-3.5 shrink-0 text-(--clarify-theme-tokens-colors-primary) transition ${isCopied ? "opacity-100" : "opacity-0"}` })
1449
+ ]
1450
+ }) }, action.key);
1451
+ }),
1452
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
1453
+ href: contentArtifactUrl,
1454
+ target: "_blank",
1455
+ rel: "noreferrer",
1456
+ 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",
1457
+ children: [
1458
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1459
+ 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",
1460
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.FileText, { className: "h-4 w-4" })
1461
+ }),
1462
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1463
+ className: "flex min-w-0 flex-1 flex-col px-1",
1464
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1465
+ className: "clarify-ui-menu-title flex items-center gap-1",
1466
+ children: [viewLabel, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ExternalLink, { className: "clarify-ui-menu-icon h-3 w-3" })]
1467
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1468
+ className: "clarify-ui-menu-description truncate",
1469
+ children: viewDescription
1470
+ })]
1471
+ }),
1472
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, { className: "h-3.5 w-3.5 shrink-0 text-(--clarify-theme-tokens-colors-primary) opacity-0" })
1473
+ ]
1474
+ }) }),
1475
+ actions.slice(1).map((action) => {
1476
+ const Icon = action.icon;
1477
+ const isCopied = copied === action.key;
1478
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1479
+ type: "button",
1480
+ onClick: action.run,
1481
+ 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",
1482
+ children: [
1483
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1484
+ 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",
1485
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { className: "h-4 w-4" })
1486
+ }),
1487
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1488
+ className: "flex min-w-0 flex-1 flex-col px-1",
1489
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1490
+ className: "clarify-ui-menu-title",
1491
+ children: isCopied ? t("contentActions.copiedLink") : action.label
1492
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1493
+ className: "clarify-ui-menu-description truncate",
1494
+ children: action.description
1495
+ })]
1496
+ }),
1497
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, { className: `h-3.5 w-3.5 shrink-0 text-(--clarify-theme-tokens-colors-primary) transition ${isCopied ? "opacity-100" : "opacity-0"}` })
1498
+ ]
1499
+ }) }, action.key);
1500
+ })
1501
+ ]
1502
+ })]
1503
+ })
1504
+ });
1505
+ }
1506
+ //#endregion
1507
+ //#region source/shell/icons.tsx
1190
1508
  function NavigationIcon(arg0) {
1191
1509
  const { name, className } = arg0;
1192
1510
  if (!name) return null;
@@ -1197,6 +1515,8 @@ function NavigationIcon(arg0) {
1197
1515
  "aria-hidden": "true"
1198
1516
  });
1199
1517
  }
1518
+ //#endregion
1519
+ //#region source/shell/Navigation.tsx
1200
1520
  function useInitialValue(value, condition = true) {
1201
1521
  const [initialValue] = (0, react.useState)(value);
1202
1522
  return condition ? initialValue : value;
@@ -1204,11 +1524,11 @@ function useInitialValue(value, condition = true) {
1204
1524
  function normalizePath(path) {
1205
1525
  return path === "" ? "/" : path;
1206
1526
  }
1207
- function navigationToGroups(navigation) {
1527
+ function navigationToGroups(navigation, defaultTitle) {
1208
1528
  return navigation.map((node) => {
1209
1529
  const children = node.children?.length ? node.children : [node];
1210
1530
  return {
1211
- title: node.children?.length ? node.title : "Documentation",
1531
+ title: node.children?.length ? node.title : defaultTitle,
1212
1532
  icon: node.icon,
1213
1533
  links: children.map((child) => ({
1214
1534
  title: child.title,
@@ -1218,18 +1538,6 @@ function navigationToGroups(navigation) {
1218
1538
  };
1219
1539
  });
1220
1540
  }
1221
- function TopLevelNavItem$1(arg0) {
1222
- const { href, children } = arg0;
1223
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
1224
- className: "md:hidden",
1225
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.CloseButton, {
1226
- as: react_router_dom.Link,
1227
- to: href,
1228
- className: "block py-1 text-sm text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white",
1229
- children
1230
- })
1231
- });
1232
- }
1233
1541
  var sectionBadgeColorStyles = {
1234
1542
  GET: "text-emerald-500 dark:text-emerald-400",
1235
1543
  POST: "text-sky-500 dark:text-sky-400",
@@ -1243,7 +1551,7 @@ var sectionBadgeColorStyles = {
1243
1551
  function SectionBadge(arg0) {
1244
1552
  const { children } = arg0;
1245
1553
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1246
- className: (0, clsx.default)("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"),
1554
+ className: (0, clsx.default)("clarify-navigation-section-badge inline-flex shrink-0 justify-end font-mono font-semibold uppercase tracking-wide", sectionBadgeColorStyles[children.toUpperCase()] ?? "clarify-ui-menu-description"),
1247
1555
  children
1248
1556
  });
1249
1557
  }
@@ -1256,6 +1564,9 @@ function NavLink(arg0) {
1256
1564
  const targetId = decodeURIComponent(href.slice(hashIndex + 1));
1257
1565
  window.requestAnimationFrame(() => {
1258
1566
  document.getElementById(targetId)?.scrollIntoView();
1567
+ window.requestAnimationFrame(() => {
1568
+ window.dispatchEvent(new Event("scroll"));
1569
+ });
1259
1570
  });
1260
1571
  }
1261
1572
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.CloseButton, {
@@ -1263,7 +1574,7 @@ function NavLink(arg0) {
1263
1574
  to: href,
1264
1575
  "aria-current": active ? "page" : void 0,
1265
1576
  onClick: handleClick,
1266
- className: (0, clsx.default)("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"),
1577
+ className: (0, clsx.default)("clarify-navigation-link flex h-8 items-center justify-between gap-2 pr-3 transition", isAnchorLink ? "clarify-navigation-anchor-link pl-7" : "pl-4"),
1267
1578
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1268
1579
  className: "flex min-w-0 flex-1 items-center gap-2",
1269
1580
  children: [
@@ -1294,7 +1605,7 @@ function VisibleSectionHighlight(arg0) {
1294
1605
  const firstVisibleSectionIndex = Math.max(0, [{ id: "_top" }, ...sections].findIndex((section) => section.id === visibleSections[0]));
1295
1606
  const itemHeight = remToPx(2);
1296
1607
  const height = isPresent ? Math.max(1, visibleSections.length) * itemHeight : itemHeight;
1297
- const top = group.links.findIndex((link) => link.href === pathname) * itemHeight + firstVisibleSectionIndex * itemHeight;
1608
+ const top = group.links.findIndex((link) => isSameRoutePath(link.href, pathname)) * itemHeight + firstVisibleSectionIndex * itemHeight;
1298
1609
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.div, {
1299
1610
  layout: true,
1300
1611
  initial: { opacity: 0 },
@@ -1303,9 +1614,9 @@ function VisibleSectionHighlight(arg0) {
1303
1614
  transition: { delay: .2 }
1304
1615
  },
1305
1616
  exit: { opacity: 0 },
1306
- className: "absolute inset-x-0 top-0 bg-zinc-800/2.5 will-change-transform dark:bg-white/2.5",
1617
+ className: "clarify-navigation-section-highlight absolute inset-x-0 top-0 will-change-transform",
1307
1618
  style: {
1308
- borderRadius: 8,
1619
+ borderRadius: "var(--clarify-theme-tokens-radius-sm)",
1309
1620
  height,
1310
1621
  top
1311
1622
  }
@@ -1314,10 +1625,10 @@ function VisibleSectionHighlight(arg0) {
1314
1625
  function ActivePageMarker(arg0) {
1315
1626
  const { group, pathname } = arg0;
1316
1627
  const itemHeight = remToPx(2);
1317
- const top = remToPx(.25) + group.links.findIndex((link) => link.href === pathname) * itemHeight;
1628
+ const top = remToPx(.25) + group.links.findIndex((link) => isSameRoutePath(link.href, pathname)) * itemHeight;
1318
1629
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.div, {
1319
1630
  layout: true,
1320
- className: "absolute left-2 h-6 w-px bg-emerald-500",
1631
+ className: "absolute left-2 h-6 w-px bg-(--clarify-theme-tokens-colors-primary)",
1321
1632
  initial: { opacity: 0 },
1322
1633
  animate: {
1323
1634
  opacity: 1,
@@ -1330,16 +1641,16 @@ function ActivePageMarker(arg0) {
1330
1641
  function NavigationGroup(arg0) {
1331
1642
  const { group, className } = arg0;
1332
1643
  const isInsideMobileNavigation = useIsInsideMobileNavigation();
1333
- const [pathname, sections] = useInitialValue([(0, react_router_dom.useLocation)().pathname, useSectionStore((s) => s.sections)], isInsideMobileNavigation);
1334
- const isActiveGroup = group.links.findIndex((link) => link.href === pathname) !== -1;
1644
+ const [pathname, sections] = useInitialValue([normalizeRoutePath((0, react_router_dom.useLocation)().pathname), useSectionStore((s) => s.sections)], isInsideMobileNavigation);
1645
+ const isActiveGroup = group.links.findIndex((link) => isSameRoutePath(link.href, pathname)) !== -1;
1335
1646
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
1336
1647
  className: (0, clsx.default)("clarify-navigation-group relative mt-6", className),
1337
1648
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(framer_motion.motion.h2, {
1338
1649
  layout: "position",
1339
- className: "clarify-navigation-group-title flex items-center gap-2 text-xs font-semibold text-zinc-900 dark:text-white",
1650
+ className: "clarify-navigation-group-title flex items-center gap-2",
1340
1651
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavigationIcon, {
1341
1652
  name: group.icon,
1342
- className: "h-3.5 w-3.5"
1653
+ className: "clarify-navigation-group-title-icon h-3.5 w-3.5"
1343
1654
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: group.title })]
1344
1655
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1345
1656
  className: "relative mt-3 pl-2",
@@ -1353,7 +1664,7 @@ function NavigationGroup(arg0) {
1353
1664
  }),
1354
1665
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.div, {
1355
1666
  layout: true,
1356
- className: "absolute inset-y-0 left-2 w-px bg-zinc-900/10 dark:bg-white/5"
1667
+ className: "absolute inset-y-0 left-2 w-px bg-(--clarify-theme-tokens-colors-border) dark:bg-white/5"
1357
1668
  }),
1358
1669
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.AnimatePresence, {
1359
1670
  initial: false,
@@ -1365,38 +1676,41 @@ function NavigationGroup(arg0) {
1365
1676
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
1366
1677
  role: "list",
1367
1678
  className: "border-l border-transparent",
1368
- children: group.links.map((link) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(framer_motion.motion.li, {
1369
- layout: "position",
1370
- className: "relative",
1371
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavLink, {
1372
- href: link.href,
1373
- icon: link.icon,
1374
- active: link.href === pathname,
1375
- children: link.title
1376
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.AnimatePresence, {
1377
- mode: "popLayout",
1378
- initial: false,
1379
- children: link.href === pathname && sections.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.ul, {
1380
- role: "list",
1381
- initial: { opacity: 0 },
1382
- animate: {
1383
- opacity: 1,
1384
- transition: { delay: .1 }
1385
- },
1386
- exit: {
1387
- opacity: 0,
1388
- transition: { duration: .15 }
1389
- },
1390
- children: sections.map((section) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavLink, {
1391
- href: `${link.href}#${section.id}`,
1392
- badge: section.badge,
1393
- tags: section.tags,
1394
- isAnchorLink: true,
1395
- children: section.title
1396
- }) }, section.id))
1397
- }) : null
1398
- })]
1399
- }, link.href))
1679
+ children: group.links.map((link) => {
1680
+ const active = isSameRoutePath(link.href, pathname);
1681
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(framer_motion.motion.li, {
1682
+ layout: "position",
1683
+ className: "relative",
1684
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavLink, {
1685
+ href: link.href,
1686
+ icon: link.icon,
1687
+ active,
1688
+ children: link.title
1689
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.AnimatePresence, {
1690
+ mode: "popLayout",
1691
+ initial: false,
1692
+ children: active && sections.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.ul, {
1693
+ role: "list",
1694
+ initial: { opacity: 0 },
1695
+ animate: {
1696
+ opacity: 1,
1697
+ transition: { delay: .1 }
1698
+ },
1699
+ exit: {
1700
+ opacity: 0,
1701
+ transition: { duration: .15 }
1702
+ },
1703
+ children: sections.map((section) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavLink, {
1704
+ href: `${link.href}#${section.id}`,
1705
+ badge: section.badge,
1706
+ tags: section.tags,
1707
+ isAnchorLink: true,
1708
+ children: section.title
1709
+ }) }, section.id))
1710
+ }) : null
1711
+ })]
1712
+ }, link.href);
1713
+ })
1400
1714
  })
1401
1715
  ]
1402
1716
  })]
@@ -1404,19 +1718,16 @@ function NavigationGroup(arg0) {
1404
1718
  }
1405
1719
  function Navigation(arg0) {
1406
1720
  const { navigation, className } = arg0;
1407
- const groups = navigationToGroups(navigation);
1721
+ const groups = navigationToGroups(navigation, useBuiltInText()("navigation.documentation"));
1408
1722
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("nav", {
1409
1723
  className: (0, clsx.default)("clarify-navigation", className),
1410
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("ul", {
1724
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
1411
1725
  role: "list",
1412
1726
  className: "clarify-navigation-list",
1413
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TopLevelNavItem$1, {
1414
- href: "/",
1415
- children: "Home"
1416
- }), groups.map((group, groupIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavigationGroup, {
1727
+ children: groups.map((group, groupIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavigationGroup, {
1417
1728
  group,
1418
- className: groupIndex === 0 ? "md:mt-0" : ""
1419
- }, group.title))]
1729
+ className: groupIndex === 0 ? "mt-0" : ""
1730
+ }, group.title))
1420
1731
  })
1421
1732
  });
1422
1733
  }
@@ -1443,8 +1754,84 @@ function XIcon(props) {
1443
1754
  });
1444
1755
  }
1445
1756
  var IsInsideMobileNavigationContext = (0, react.createContext)(false);
1757
+ function hasPath$2(nodes, pathname) {
1758
+ return nodes.some((node) => isSameRoutePath(node.path, pathname) || hasPath$2(node.children ?? [], pathname));
1759
+ }
1760
+ function isActiveTab$1(tab, pathname) {
1761
+ return isSameRoutePath(tab.path, pathname) || hasPath$2(tab.children, pathname);
1762
+ }
1763
+ function MobileTabsSelect(arg0) {
1764
+ const { tabs } = arg0;
1765
+ const pathname = normalizeRoutePath((0, react_router_dom.useLocation)().pathname);
1766
+ const { close } = useMobileNavigationStore();
1767
+ if (!tabs?.length) return null;
1768
+ const activeTab = tabs.find((tab) => isActiveTab$1(tab, pathname)) ?? tabs[0];
1769
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.Menu, {
1770
+ as: "div",
1771
+ className: "clarify-mobile-tabs-select mb-6",
1772
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.MenuButton, {
1773
+ 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",
1774
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1775
+ className: "flex min-w-0 items-center gap-2",
1776
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavigationIcon, {
1777
+ name: activeTab.icon,
1778
+ className: "h-4 w-4 shrink-0 text-(--clarify-theme-tokens-colors-primary)"
1779
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1780
+ className: "truncate tracking-[-0.01em]",
1781
+ children: activeTab.title
1782
+ })]
1783
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
1784
+ width: "8",
1785
+ height: "24",
1786
+ viewBox: "0 -9 3 24",
1787
+ "aria-hidden": "true",
1788
+ className: "shrink-0 overflow-visible text-(--clarify-theme-tokens-colors-muted) transition-transform group-aria-expanded:rotate-180",
1789
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1790
+ d: "M0 0L3 3L0 6",
1791
+ fill: "none",
1792
+ stroke: "currentColor",
1793
+ strokeWidth: "1.5",
1794
+ strokeLinecap: "round"
1795
+ })
1796
+ })]
1797
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItems, {
1798
+ 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",
1799
+ children: tabs.map((tab) => {
1800
+ const active = isActiveTab$1(tab, pathname);
1801
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_router_dom.Link, {
1802
+ to: tab.path,
1803
+ onClick: close,
1804
+ className: (0, clsx.default)("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"),
1805
+ "aria-current": active ? "page" : void 0,
1806
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1807
+ className: "flex min-w-0 items-start gap-2",
1808
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavigationIcon, {
1809
+ name: tab.icon,
1810
+ className: "mt-0.5 h-4 w-4 shrink-0"
1811
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1812
+ className: "min-w-0 whitespace-normal wrap-anywhere font-medium leading-5",
1813
+ children: tab.title
1814
+ })]
1815
+ }), active ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
1816
+ viewBox: "0 0 20 20",
1817
+ fill: "none",
1818
+ "aria-hidden": "true",
1819
+ className: "mt-0.5 h-4 w-4 shrink-0",
1820
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1821
+ d: "m5 10 3 3 7-7",
1822
+ stroke: "currentColor",
1823
+ strokeWidth: "1.8",
1824
+ strokeLinecap: "round",
1825
+ strokeLinejoin: "round"
1826
+ })
1827
+ }) : null]
1828
+ }) }, `${tab.title}-${tab.path}`);
1829
+ })
1830
+ })]
1831
+ });
1832
+ }
1446
1833
  function MobileNavigationDialog(arg0) {
1447
- const { config, isOpen, navigation, routes, currentLocale, currentRoute, close } = arg0;
1834
+ const { config, isOpen, navigation, tabs, routes, currentLocale, currentRoute, close } = arg0;
1448
1835
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.Dialog, {
1449
1836
  transition: true,
1450
1837
  open: isOpen,
@@ -1452,18 +1839,19 @@ function MobileNavigationDialog(arg0) {
1452
1839
  className: "clarify-mobile-navigation-dialog fixed inset-0 z-50 lg:hidden",
1453
1840
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.DialogBackdrop, {
1454
1841
  transition: true,
1455
- 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"
1842
+ 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"
1456
1843
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.DialogPanel, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.TransitionChild, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Header, {
1457
1844
  config,
1458
1845
  navigation,
1846
+ tabs,
1459
1847
  routes,
1460
1848
  currentLocale,
1461
1849
  currentRoute,
1462
1850
  className: "data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in"
1463
- }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.TransitionChild, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.div, {
1851
+ }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.TransitionChild, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(framer_motion.motion.div, {
1464
1852
  layoutScroll: true,
1465
- 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",
1466
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Navigation, { navigation })
1853
+ 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",
1854
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MobileTabsSelect, { tabs }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Navigation, { navigation })]
1467
1855
  }) })] })]
1468
1856
  });
1469
1857
  }
@@ -1477,23 +1865,25 @@ var useMobileNavigationStore = (0, zustand.create)()((set) => ({
1477
1865
  toggle: () => set((state) => ({ isOpen: !state.isOpen }))
1478
1866
  }));
1479
1867
  function MobileNavigation(arg0) {
1480
- const { config, navigation, routes, currentLocale, currentRoute } = arg0;
1868
+ const { config, navigation, tabs, routes, currentLocale, currentRoute } = arg0;
1481
1869
  const isInsideMobileNavigation = useIsInsideMobileNavigation();
1482
1870
  const { isOpen, toggle, close } = useMobileNavigationStore();
1871
+ const t = useBuiltInText();
1483
1872
  const ToggleIcon = isOpen ? XIcon : MenuIcon;
1484
1873
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(IsInsideMobileNavigationContext.Provider, {
1485
1874
  value: true,
1486
1875
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1487
1876
  type: "button",
1488
- 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",
1489
- "aria-label": "Toggle navigation",
1877
+ className: "clarify-mobile-navigation-button clarify-ui-icon-button relative flex size-6 items-center justify-center rounded-(--clarify-theme-tokens-radius-md) transition",
1878
+ "aria-label": t("navigation.toggle"),
1490
1879
  onClick: toggle,
1491
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "absolute size-12 pointer-fine:hidden" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToggleIcon, { className: "w-2.5 stroke-zinc-900 dark:stroke-white" })]
1880
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "absolute size-12 pointer-fine:hidden" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToggleIcon, { className: "w-2.5 stroke-(--clarify-theme-tokens-colors-foreground) dark:stroke-white" })]
1492
1881
  }), !isInsideMobileNavigation ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Suspense, {
1493
1882
  fallback: null,
1494
1883
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MobileNavigationDialog, {
1495
1884
  config,
1496
1885
  navigation,
1886
+ tabs,
1497
1887
  routes,
1498
1888
  currentLocale,
1499
1889
  currentRoute,
@@ -1574,7 +1964,7 @@ function HighlightQuery(arg0) {
1574
1964
  const { text, query } = arg0;
1575
1965
  if (!query) return text;
1576
1966
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: text.split(new RegExp(`(${escapeRegExp(query)})`, "ig")).map((part, index) => part.toLowerCase() === query.toLowerCase() ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("mark", {
1577
- className: "bg-transparent text-emerald-500 underline",
1967
+ className: "bg-transparent text-(--clarify-theme-tokens-colors-primary) underline",
1578
1968
  children: part
1579
1969
  }, index) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: part }, index)) });
1580
1970
  }
@@ -1584,25 +1974,25 @@ function SearchResult(arg0) {
1584
1974
  const hierarchy = [result.sectionTitle, result.pageTitle].filter((value) => typeof value === "string");
1585
1975
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
1586
1976
  id,
1587
- className: (0, clsx.default)("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"),
1977
+ className: (0, clsx.default)("clarify-search-result group block cursor-default px-4 py-3", active && "clarify-search-result-active"),
1588
1978
  "aria-selected": active,
1589
1979
  onMouseDown: (event) => {
1590
1980
  event.preventDefault();
1591
1981
  onSelect();
1592
1982
  },
1593
1983
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1594
- className: "text-sm font-medium text-zinc-900 group-aria-selected:text-emerald-500 dark:text-white",
1984
+ className: "clarify-search-result-title",
1595
1985
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HighlightQuery, {
1596
1986
  text: result.title,
1597
1987
  query
1598
1988
  })
1599
1989
  }), hierarchy.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1600
- className: "mt-1 truncate text-2xs whitespace-nowrap text-zinc-500",
1990
+ className: "clarify-search-result-hierarchy mt-1 truncate whitespace-nowrap",
1601
1991
  children: hierarchy.map((item, itemIndex, items) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(HighlightQuery, {
1602
1992
  text: item,
1603
1993
  query
1604
1994
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1605
- className: itemIndex === items.length - 1 ? "sr-only" : "mx-2 text-zinc-300 dark:text-zinc-700",
1995
+ className: itemIndex === items.length - 1 ? "sr-only" : "clarify-search-result-separator mx-2",
1606
1996
  children: "/"
1607
1997
  })] }, `${item}-${itemIndex}`))
1608
1998
  }) : null]
@@ -1610,9 +2000,10 @@ function SearchResult(arg0) {
1610
2000
  }
1611
2001
  var SearchInput = (0, react.forwardRef)(function SearchInput(arg0, inputRef) {
1612
2002
  const { query, setQuery, onClose, onSubmit, activeDescendantId } = arg0;
2003
+ const t = useBuiltInText();
1613
2004
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1614
2005
  className: "clarify-search-input group relative flex h-12",
1615
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchIcon, { className: "pointer-events-none absolute top-0 left-3 h-full w-5 stroke-zinc-500" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2006
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchIcon, { className: "pointer-events-none absolute top-0 left-3 h-full w-5 stroke-(--clarify-theme-tokens-colors-muted)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1616
2007
  ref: inputRef,
1617
2008
  "data-autofocus": true,
1618
2009
  role: "combobox",
@@ -1629,13 +2020,14 @@ var SearchInput = (0, react.forwardRef)(function SearchInput(arg0, inputRef) {
1629
2020
  onSubmit();
1630
2021
  }
1631
2022
  },
1632
- placeholder: "Find something...",
1633
- 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"
2023
+ placeholder: t("search.placeholder"),
2024
+ 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"
1634
2025
  })]
1635
2026
  });
1636
2027
  });
1637
2028
  function SearchDialog(arg0) {
1638
2029
  const { open, setOpen, routes, navigation, className, onNavigate = () => {} } = arg0;
2030
+ const t = useBuiltInText();
1639
2031
  const navigate = (0, react_router_dom.useNavigate)();
1640
2032
  const location = (0, react_router_dom.useLocation)();
1641
2033
  const inputRef = (0, react.useRef)(null);
@@ -1686,12 +2078,12 @@ function SearchDialog(arg0) {
1686
2078
  className: (0, clsx.default)("clarify-search-dialog fixed inset-0 z-50", className),
1687
2079
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.DialogBackdrop, {
1688
2080
  transition: true,
1689
- 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"
2081
+ 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"
1690
2082
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1691
2083
  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]",
1692
2084
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.DialogPanel, {
1693
2085
  transition: true,
1694
- 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",
2086
+ 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",
1695
2087
  onKeyDown: (event) => {
1696
2088
  if (event.key === "ArrowDown") {
1697
2089
  event.preventDefault();
@@ -1709,24 +2101,12 @@ function SearchDialog(arg0) {
1709
2101
  onClose: closeDialog,
1710
2102
  onSubmit: () => selectResult()
1711
2103
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1712
- className: "border-t border-zinc-200 bg-white empty:hidden dark:border-zinc-100/5 dark:bg-white/2.5",
2104
+ 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",
1713
2105
  children: [query && results.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1714
2106
  className: "p-6 text-center",
1715
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NoResultsIcon, { className: "mx-auto h-5 w-5 stroke-zinc-900 dark:stroke-zinc-600" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1716
- className: "mt-2 text-xs text-zinc-700 dark:text-zinc-400",
1717
- children: [
1718
- "Nothing found for",
1719
- " ",
1720
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", {
1721
- className: "font-semibold wrap-break-word text-zinc-900 dark:text-white",
1722
- children: [
1723
- "‘",
1724
- query,
1725
- "’"
1726
- ]
1727
- }),
1728
- "."
1729
- ]
2107
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NoResultsIcon, { className: "mx-auto h-5 w-5 stroke-(--clarify-theme-tokens-colors-foreground) dark:stroke-zinc-600" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2108
+ className: "mt-2 text-xs text-(--clarify-theme-tokens-colors-muted) dark:text-zinc-400",
2109
+ children: t("search.noResults", { query })
1730
2110
  })]
1731
2111
  }) : null, results.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
1732
2112
  id: "clarify-search-results",
@@ -1766,19 +2146,20 @@ function getModifierKey() {
1766
2146
  }
1767
2147
  function Search(arg0) {
1768
2148
  const { routes, navigation } = arg0;
2149
+ const t = useBuiltInText();
1769
2150
  const modifierKey = getModifierKey();
1770
2151
  const { buttonProps, dialogProps } = useSearchProps();
1771
2152
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1772
- className: "clarify-search hidden lg:block lg:max-w-md lg:flex-auto",
2153
+ className: "clarify-search hidden w-80 max-w-[36vw] lg:block",
1773
2154
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1774
2155
  type: "button",
1775
- 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",
2156
+ 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",
1776
2157
  ...buttonProps,
1777
2158
  children: [
1778
2159
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchIcon, { className: "h-5 w-5 stroke-current" }),
1779
- "Find something...",
2160
+ t("search.button"),
1780
2161
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("kbd", {
1781
- className: "ml-auto text-2xs text-zinc-400 dark:text-zinc-500",
2162
+ 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",
1782
2163
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("kbd", {
1783
2164
  className: "font-sans",
1784
2165
  children: modifierKey
@@ -1801,15 +2182,16 @@ function Search(arg0) {
1801
2182
  }
1802
2183
  function MobileSearch(arg0) {
1803
2184
  const { routes, navigation, onNavigate } = arg0;
2185
+ const t = useBuiltInText();
1804
2186
  const { buttonProps, dialogProps } = useSearchProps();
1805
2187
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1806
2188
  className: "clarify-mobile-search contents lg:hidden",
1807
2189
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1808
2190
  type: "button",
1809
- 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",
1810
- "aria-label": "Find something...",
2191
+ 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",
2192
+ "aria-label": t("search.placeholder"),
1811
2193
  ...buttonProps,
1812
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "absolute size-12 pointer-fine:hidden" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchIcon, { className: "h-5 w-5 stroke-zinc-900 dark:stroke-white" })]
2194
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "absolute size-12 pointer-fine:hidden" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchIcon, { className: "h-5 w-5 stroke-(--clarify-theme-tokens-colors-foreground) dark:stroke-white" })]
1813
2195
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Suspense, {
1814
2196
  fallback: null,
1815
2197
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchDialog, {
@@ -1854,6 +2236,7 @@ function LanguageIcon(props) {
1854
2236
  }
1855
2237
  function LanguageSwitcher(arg0) {
1856
2238
  const { config, currentLocale, currentRoute } = arg0;
2239
+ const t = useBuiltInText();
1857
2240
  const location = (0, react_router_dom.useLocation)();
1858
2241
  const i18n = config.i18n;
1859
2242
  if (!i18n || i18n.locales.length < 2) return null;
@@ -1864,8 +2247,8 @@ function LanguageSwitcher(arg0) {
1864
2247
  as: "div",
1865
2248
  className: "clarify-language-switcher relative",
1866
2249
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.MenuButton, {
1867
- 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",
1868
- "aria-label": "Switch language",
2250
+ 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",
2251
+ "aria-label": t("language.switch"),
1869
2252
  children: [
1870
2253
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "absolute size-12 pointer-fine:hidden" }),
1871
2254
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LanguageIcon, { className: "h-5 w-5 stroke-current" }),
@@ -1876,19 +2259,19 @@ function LanguageSwitcher(arg0) {
1876
2259
  ]
1877
2260
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItems, {
1878
2261
  transition: true,
1879
- 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",
2262
+ 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",
1880
2263
  children: i18n.locales.flatMap((locale) => {
1881
2264
  const localizedPath = localizedRoutePath(config, locale.code, currentRoute);
1882
2265
  if (!localizedPath) return [];
1883
2266
  const selected = locale.code === selectedLocale;
1884
2267
  return [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItem, { children: ({ focus }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_router_dom.Link, {
1885
2268
  to: `${localizedPath}${suffix}`,
1886
- className: (0, clsx.default)("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"),
2269
+ className: (0, clsx.default)("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"),
1887
2270
  "aria-current": selected ? "true" : void 0,
1888
2271
  lang: locale.code,
1889
2272
  dir: locale.dir,
1890
2273
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: locale.label }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1891
- className: "text-xs text-zinc-400 dark:text-zinc-500",
2274
+ className: "clarify-ui-menu-code",
1892
2275
  children: locale.code
1893
2276
  })]
1894
2277
  }) }, locale.code)];
@@ -1900,95 +2283,189 @@ function TopLevelNavItem(arg0) {
1900
2283
  const { href, children } = arg0;
1901
2284
  if (isExternalHref(href)) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
1902
2285
  href,
1903
- className: "text-sm/5 text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white",
2286
+ className: "clarify-ui-top-link transition",
1904
2287
  target: "_blank",
1905
2288
  rel: "noreferrer",
1906
2289
  children
1907
2290
  }) });
1908
2291
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_router_dom.Link, {
1909
2292
  to: href,
1910
- className: "text-sm/5 text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white",
2293
+ className: "clarify-ui-top-link transition",
1911
2294
  children
1912
2295
  }) });
1913
2296
  }
2297
+ function MobileNavbarMenu(arg0) {
2298
+ const { links, config, currentLocale } = arg0;
2299
+ const t = useBuiltInText();
2300
+ if (!links?.length) return null;
2301
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.Menu, {
2302
+ as: "div",
2303
+ className: "clarify-mobile-navbar-menu relative md:hidden",
2304
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.MenuButton, {
2305
+ className: "clarify-mobile-navbar-menu-button clarify-ui-control relative flex size-8 items-center justify-center rounded-(--clarify-theme-tokens-radius-md) transition",
2306
+ "aria-label": t("navbar.openLinks"),
2307
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "absolute size-12 pointer-fine:hidden" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.MoreHorizontal, { className: "h-5 w-5" })]
2308
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItems, {
2309
+ transition: true,
2310
+ anchor: "bottom end",
2311
+ 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",
2312
+ children: links.map((link) => {
2313
+ const label = resolveLocalizedText(link.label, currentLocale, config.i18n?.defaultLocale);
2314
+ const href = localizeHref(link.href, config, currentLocale);
2315
+ const external = isExternalHref(href);
2316
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItem, { children: ({ focus }) => {
2317
+ const className = (0, clsx.default)("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");
2318
+ return external ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
2319
+ href,
2320
+ target: "_blank",
2321
+ rel: "noreferrer",
2322
+ className,
2323
+ children: label
2324
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_router_dom.Link, {
2325
+ to: href,
2326
+ className,
2327
+ children: label
2328
+ });
2329
+ } }, link.href);
2330
+ })
2331
+ })]
2332
+ });
2333
+ }
2334
+ function hasPath$1(nodes, pathname) {
2335
+ return nodes.some((node) => isSameRoutePath(node.path, pathname) || hasPath$1(node.children ?? [], pathname));
2336
+ }
2337
+ function isActiveTab(tab, pathname) {
2338
+ return isSameRoutePath(tab.path, pathname) || hasPath$1(tab.children, pathname);
2339
+ }
2340
+ function ProductTabs(arg0) {
2341
+ const { tabs } = arg0;
2342
+ const t = useBuiltInText();
2343
+ const pathname = normalizeRoutePath((0, react_router_dom.useLocation)().pathname);
2344
+ if (!tabs?.length) return null;
2345
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2346
+ className: "clarify-product-tabs hidden h-14 border-t border-(--clarify-theme-tokens-colors-border) lg:block dark:border-white/10",
2347
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("nav", {
2348
+ 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",
2349
+ "aria-label": t("navbar.sections"),
2350
+ children: tabs.map((tab) => {
2351
+ const active = isActiveTab(tab, pathname);
2352
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_router_dom.Link, {
2353
+ to: tab.path,
2354
+ "aria-current": active ? "page" : void 0,
2355
+ className: (0, clsx.default)("clarify-product-tab clarify-ui-tab relative inline-flex shrink-0 items-center gap-2 px-0 transition", active && "clarify-ui-tab-active"),
2356
+ children: [
2357
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavigationIcon, {
2358
+ name: tab.icon,
2359
+ className: "h-4 w-4"
2360
+ }),
2361
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tab.title }),
2362
+ active ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.span, {
2363
+ layoutId: "clarify-product-tab-indicator",
2364
+ className: "absolute inset-x-0 bottom-0 h-0.5 rounded-full bg-(--clarify-theme-tokens-colors-foreground) dark:bg-white",
2365
+ transition: {
2366
+ type: "spring",
2367
+ stiffness: 420,
2368
+ damping: 36
2369
+ }
2370
+ }) : null
2371
+ ]
2372
+ }, `${tab.title}-${tab.path}`);
2373
+ })
2374
+ })
2375
+ });
2376
+ }
1914
2377
  var Header = (0, react.forwardRef)(function Header(arg0, ref) {
1915
- const { config, navigation, routes, currentLocale, currentRoute, className, ...props } = arg0;
2378
+ const { config, navigation, tabs, routes, currentLocale, currentRoute, className, ...props } = arg0;
2379
+ const t = useBuiltInText();
1916
2380
  const { isOpen: mobileNavIsOpen } = useMobileNavigationStore();
1917
2381
  const isInsideMobileNavigation = useIsInsideMobileNavigation();
1918
2382
  const { scrollY } = (0, framer_motion.useScroll)();
1919
- const bgOpacityLight = (0, framer_motion.useTransform)(scrollY, [0, 72], ["50%", "90%"]);
1920
- const bgOpacityDark = (0, framer_motion.useTransform)(scrollY, [0, 72], ["20%", "80%"]);
1921
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(framer_motion.motion.div, {
2383
+ const bgOpacityLight = (0, framer_motion.useTransform)(scrollY, [0, 72], ["70%", "95%"]);
2384
+ const bgOpacityDark = (0, framer_motion.useTransform)(scrollY, [0, 72], ["60%", "92%"]);
2385
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(framer_motion.motion.header, {
1922
2386
  ...props,
1923
2387
  ref,
1924
- className: (0, clsx.default)(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)"),
2388
+ className: (0, clsx.default)(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"),
1925
2389
  style: {
1926
2390
  "--bg-opacity-light": bgOpacityLight,
1927
2391
  "--bg-opacity-dark": bgOpacityDark
1928
2392
  },
1929
- children: [
1930
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: (0, clsx.default)("absolute inset-x-0 top-full h-px transition", (isInsideMobileNavigation || !mobileNavIsOpen) && "bg-zinc-900/7.5 dark:bg-white/7.5") }),
1931
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "hidden lg:block" }),
1932
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1933
- className: "clarify-mobile-brand flex items-center gap-5 lg:hidden",
1934
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MobileNavigation, {
1935
- config,
1936
- navigation,
1937
- routes,
1938
- currentLocale,
1939
- currentRoute
1940
- }), config.logo ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.CloseButton, {
1941
- as: react_router_dom.Link,
1942
- to: localizeHref("/", config, currentLocale),
1943
- "aria-label": "Home",
1944
- className: "clarify-brand flex items-center gap-2 no-underline",
1945
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SiteLogo, {
1946
- logo: config.logo,
1947
- className: "h-6 w-6"
1948
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1949
- className: "sr-only",
1950
- children: config.title
2393
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2394
+ className: (0, clsx.default)("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"),
2395
+ children: [
2396
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2397
+ className: "clarify-header-left flex min-w-0 items-center gap-5",
2398
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2399
+ className: "clarify-mobile-brand flex items-center gap-5 lg:hidden",
2400
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MobileNavigation, {
2401
+ config,
2402
+ navigation,
2403
+ tabs,
2404
+ routes,
2405
+ currentLocale,
2406
+ currentRoute
2407
+ })
2408
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.CloseButton, {
2409
+ as: react_router_dom.Link,
2410
+ to: localizeHref("/", config, currentLocale),
2411
+ "aria-label": t("navbar.home"),
2412
+ className: "clarify-brand flex min-w-0 items-center gap-2 no-underline",
2413
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SiteLogo, {
2414
+ logo: config.logo,
2415
+ className: "h-6 w-6 shrink-0"
2416
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2417
+ className: "clarify-brand-title truncate font-semibold",
2418
+ children: config.title
2419
+ })]
1951
2420
  })]
1952
- }) : null]
1953
- }),
1954
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1955
- className: "clarify-header-actions flex items-center gap-5",
1956
- children: [
1957
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Search, {
2421
+ }),
2422
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2423
+ className: "clarify-header-center absolute left-1/2 hidden -translate-x-1/2 lg:block",
2424
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Search, {
1958
2425
  routes,
1959
2426
  navigation
1960
- }),
1961
- config.navbar?.links?.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("nav", {
1962
- className: "clarify-top-nav hidden md:block",
1963
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
1964
- role: "list",
1965
- className: "flex items-center gap-8",
1966
- children: config.navbar.links.map((link) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TopLevelNavItem, {
1967
- href: localizeHref(link.href, config, currentLocale),
1968
- children: resolveLocalizedText(link.label, currentLocale, config.i18n?.defaultLocale)
1969
- }, link.href))
2427
+ })
2428
+ }),
2429
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2430
+ className: "clarify-header-actions flex shrink-0 items-center gap-5",
2431
+ children: [
2432
+ config.navbar?.links?.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("nav", {
2433
+ className: "clarify-top-nav hidden md:block",
2434
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
2435
+ role: "list",
2436
+ className: "flex items-center gap-8",
2437
+ children: config.navbar.links.map((link) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TopLevelNavItem, {
2438
+ href: localizeHref(link.href, config, currentLocale),
2439
+ children: resolveLocalizedText(link.label, currentLocale, config.i18n?.defaultLocale)
2440
+ }, link.href))
2441
+ })
2442
+ }) : null,
2443
+ config.navbar?.links?.length ? /* @__PURE__ */ (0, react_jsx_runtime.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,
2444
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MobileSearch, {
2445
+ routes,
2446
+ navigation
2447
+ }),
2448
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LanguageSwitcher, {
2449
+ config,
2450
+ currentLocale,
2451
+ currentRoute
2452
+ }),
2453
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThemeToggle, {}),
2454
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MobileNavbarMenu, {
2455
+ links: config.navbar?.links,
2456
+ config,
2457
+ currentLocale
1970
2458
  })
1971
- }) : null,
1972
- config.navbar?.links?.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "hidden md:block md:h-5 md:w-px md:bg-zinc-900/10 md:dark:bg-white/15" }) : null,
1973
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MobileSearch, {
1974
- routes,
1975
- navigation
1976
- }),
1977
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LanguageSwitcher, {
1978
- config,
1979
- currentLocale,
1980
- currentRoute
1981
- }),
1982
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThemeToggle, {})
1983
- ]
1984
- })
1985
- ]
2459
+ ]
2460
+ })
2461
+ ]
2462
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProductTabs, { tabs })]
1986
2463
  });
1987
2464
  });
1988
2465
  //#endregion
1989
2466
  //#region source/app/AppShell.tsx
1990
2467
  function routeForPath(routes, pathname) {
1991
- return routes.find((route) => route.path === pathname || `/${route.path}` === pathname);
2468
+ return routes.find((route) => isSameRoutePath(route.path, pathname));
1992
2469
  }
1993
2470
  function sectionsForRoute(route) {
1994
2471
  return route?.sections?.map((section) => ({
@@ -1998,11 +2475,18 @@ function sectionsForRoute(route) {
1998
2475
  tags: section.tags
1999
2476
  })) ?? [];
2000
2477
  }
2478
+ function resolveRouteComponent(route) {
2479
+ if (route.lazy) return (0, react.lazy)(route.component);
2480
+ return route.component;
2481
+ }
2001
2482
  function scrollToHash(hash) {
2002
2483
  if (!hash) return;
2003
2484
  const targetId = decodeURIComponent(hash.slice(1));
2004
2485
  window.requestAnimationFrame(() => {
2005
2486
  document.getElementById(targetId)?.scrollIntoView();
2487
+ window.requestAnimationFrame(() => {
2488
+ window.dispatchEvent(new Event("scroll"));
2489
+ });
2006
2490
  });
2007
2491
  }
2008
2492
  function localeForPath(config, pathname, route) {
@@ -2012,25 +2496,101 @@ function localeForPath(config, pathname, route) {
2012
2496
  const firstSegment = pathname.split("/").filter(Boolean)[0];
2013
2497
  return i18n.locales.find((locale) => locale.code === firstSegment)?.code ?? i18n.defaultLocale;
2014
2498
  }
2015
- function navigationForLocale(navigation, locale) {
2016
- if (Array.isArray(navigation)) return navigation;
2017
- if (!locale) return [];
2018
- return navigation[locale] ?? [];
2499
+ function isTabbedNavigation(navigation) {
2500
+ return !Array.isArray(navigation) && "tabs" in navigation;
2019
2501
  }
2020
- function homePathForLocale(config, locale) {
2021
- if (!locale || !config.i18n || locale === config.i18n.defaultLocale) return "/";
2022
- return `/${locale}`;
2502
+ function hasPath(nodes, pathname) {
2503
+ return nodes.some((node) => isSameRoutePath(node.path, pathname) || hasPath(node.children ?? [], pathname));
2504
+ }
2505
+ function navigationFromTabs(navigation, pathname) {
2506
+ return {
2507
+ items: navigation.tabs.find((tab) => isSameRoutePath(tab.path, pathname) || hasPath(tab.children, pathname))?.children ?? navigation.tabs[0]?.children ?? [],
2508
+ tabs: navigation.tabs
2509
+ };
2510
+ }
2511
+ function navigationForLocale(navigation, locale, pathname) {
2512
+ if (Array.isArray(navigation)) return { items: navigation };
2513
+ if (isTabbedNavigation(navigation)) return navigationFromTabs(navigation, pathname);
2514
+ if (!locale) return { items: [] };
2515
+ const localizedNavigation = navigation[locale];
2516
+ if (!localizedNavigation) return { items: [] };
2517
+ return Array.isArray(localizedNavigation) ? { items: localizedNavigation } : navigationFromTabs(localizedNavigation, pathname);
2518
+ }
2519
+ function themeStyle(config) {
2520
+ const { colors, radius } = config.theme.tokens;
2521
+ const { layout } = config.theme;
2522
+ return {
2523
+ "--clarify-theme-tokens-colors-primary": colors.primary,
2524
+ "--clarify-theme-tokens-colors-accent": colors.accent,
2525
+ "--clarify-theme-tokens-colors-background": colors.background,
2526
+ "--clarify-theme-tokens-colors-foreground": colors.foreground,
2527
+ "--clarify-theme-tokens-colors-surface": colors.surface,
2528
+ "--clarify-theme-tokens-colors-muted": colors.muted,
2529
+ "--clarify-theme-tokens-colors-border": colors.border,
2530
+ "--clarify-theme-tokens-colors-code-background": colors.codeBackground,
2531
+ "--clarify-theme-tokens-radius-sm": radius.sm,
2532
+ "--clarify-theme-tokens-radius-md": radius.md,
2533
+ "--clarify-theme-tokens-radius-lg": radius.lg,
2534
+ "--clarify-theme-tokens-radius-xl": radius.xl,
2535
+ "--clarify-theme-layout-max-width": layout.maxWidth
2536
+ };
2537
+ }
2538
+ function pageTitle(config, route) {
2539
+ const routeTitle = route?.title?.trim();
2540
+ if (!routeTitle || routeTitle === config.title) return config.title;
2541
+ return `${routeTitle} - ${config.title}`;
2542
+ }
2543
+ function setNamedMeta(name, content) {
2544
+ const existing = document.head.querySelector(`meta[name="${name}"]`);
2545
+ if (!content) {
2546
+ existing?.remove();
2547
+ return;
2548
+ }
2549
+ const meta = existing ?? document.createElement("meta");
2550
+ meta.name = name;
2551
+ meta.content = content;
2552
+ if (!existing) document.head.appendChild(meta);
2553
+ }
2554
+ function applyDocumentMetadata(config, route) {
2555
+ document.title = pageTitle(config, route);
2556
+ setNamedMeta("description", route?.description ?? config.description);
2557
+ setNamedMeta("keywords", route?.keywords?.join(", "));
2558
+ }
2559
+ function applyRootThemeVariables(themeVariables) {
2560
+ const rootStyle = document.documentElement.style;
2561
+ for (const [property, value] of Object.entries(themeVariables)) rootStyle.setProperty(property, value);
2562
+ return () => {
2563
+ for (const property of Object.keys(themeVariables)) rootStyle.removeProperty(property);
2564
+ };
2023
2565
  }
2024
2566
  function AppShell(arg0) {
2025
2567
  const { config, routes, navigation } = arg0;
2026
2568
  const location = (0, react_router_dom.useLocation)();
2027
- const currentRoute = routeForPath(routes, location.pathname);
2028
- const currentLocale = localeForPath(config, location.pathname, currentRoute);
2569
+ const pathname = normalizeRoutePath(location.pathname);
2570
+ const currentRoute = routeForPath(routes, pathname);
2571
+ const currentLocale = localeForPath(config, pathname, currentRoute);
2029
2572
  const currentLocaleConfig = config.i18n?.locales.find((locale) => locale.code === currentLocale);
2030
- const currentNavigation = navigationForLocale(navigation, currentLocale);
2573
+ const currentNavigation = navigationForLocale(navigation, currentLocale, pathname);
2031
2574
  const sections = sectionsForRoute(currentRoute);
2575
+ const hasTabs = Boolean(currentNavigation.tabs?.length);
2576
+ const themeVariables = themeStyle(config);
2577
+ const renderRoutes = (0, react.useMemo)(() => routes.map((route) => ({
2578
+ ...route,
2579
+ component: resolveRouteComponent(route)
2580
+ })), [routes]);
2581
+ (0, react.useEffect)(() => applyRootThemeVariables(themeVariables), [themeVariables]);
2032
2582
  (0, react.useEffect)(() => {
2033
- scrollToHash(location.hash);
2583
+ if (location.hash) {
2584
+ scrollToHash(location.hash);
2585
+ return;
2586
+ }
2587
+ window.scrollTo({
2588
+ top: 0,
2589
+ left: 0
2590
+ });
2591
+ window.requestAnimationFrame(() => {
2592
+ window.dispatchEvent(new Event("scroll"));
2593
+ });
2034
2594
  }, [location.hash, location.pathname]);
2035
2595
  (0, react.useEffect)(() => {
2036
2596
  if (!currentLocale) return;
@@ -2038,57 +2598,60 @@ function AppShell(arg0) {
2038
2598
  if (currentLocaleConfig?.dir) document.documentElement.dir = currentLocaleConfig.dir;
2039
2599
  else document.documentElement.removeAttribute("dir");
2040
2600
  }, [currentLocale, currentLocaleConfig?.dir]);
2041
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SectionProvider, {
2042
- sections,
2043
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2044
- className: "clarify-app h-full min-h-screen bg-white lg:ml-72 xl:ml-80 dark:bg-zinc-950",
2045
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.header, {
2046
- layoutScroll: true,
2047
- className: "clarify-shell contents lg:pointer-events-none lg:fixed lg:inset-0 lg:z-40 lg:flex",
2048
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2049
- 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",
2050
- children: [
2051
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2052
- className: "clarify-sidebar-brand hidden lg:flex",
2053
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_router_dom.Link, {
2054
- to: homePathForLocale(config, currentLocale),
2055
- "aria-label": "Home",
2056
- className: "clarify-brand flex items-center gap-2 no-underline",
2057
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SiteLogo, {
2058
- logo: config.logo,
2059
- className: "h-6 w-6"
2060
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2061
- className: "clarify-brand-title text-sm font-semibold text-zinc-900 dark:text-white",
2062
- children: config.title
2063
- })]
2064
- })
2065
- }),
2066
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Header, {
2067
- config,
2068
- navigation: currentNavigation,
2069
- routes,
2070
- currentLocale,
2071
- currentRoute
2072
- }),
2073
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Navigation, {
2074
- navigation: currentNavigation,
2075
- className: "clarify-navigation hidden lg:mt-10 lg:block"
2076
- })
2077
- ]
2078
- })
2079
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2080
- className: "clarify-content relative flex min-h-screen flex-col px-4 pt-14 sm:px-6 lg:px-8",
2081
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContentActions, {
2082
- route: currentRoute,
2083
- routePrefix: config.routePrefix
2084
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("main", {
2085
- className: "clarify-main flex-auto",
2086
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_router_dom.Routes, { children: routes.map((route) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_router_dom.Route, {
2087
- path: route.path,
2088
- element: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(route.component, {})
2089
- }, route.path)) })
2090
- })]
2091
- })]
2601
+ (0, react.useEffect)(() => {
2602
+ applyDocumentMetadata(config, currentRoute);
2603
+ }, [config, currentRoute]);
2604
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ClarifyLocaleContext.Provider, {
2605
+ value: currentLocale,
2606
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SectionProvider, {
2607
+ sections,
2608
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2609
+ 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",
2610
+ "data-theme-preset": config.theme.preset,
2611
+ style: themeVariables,
2612
+ children: [
2613
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Header, {
2614
+ config,
2615
+ navigation: currentNavigation.items,
2616
+ tabs: currentNavigation.tabs,
2617
+ routes,
2618
+ currentLocale,
2619
+ currentRoute
2620
+ }),
2621
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2622
+ 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)]",
2623
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.aside, {
2624
+ layoutScroll: true,
2625
+ className: (0, clsx.default)("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"),
2626
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Navigation, { navigation: currentNavigation.items })
2627
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2628
+ className: (0, clsx.default)("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"),
2629
+ children: [
2630
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContentActions, {
2631
+ hasTabs,
2632
+ route: currentRoute,
2633
+ routePrefix: config.routePrefix
2634
+ }),
2635
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("main", {
2636
+ className: "clarify-main min-w-0 flex-auto",
2637
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Suspense, {
2638
+ fallback: null,
2639
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_router_dom.Routes, { children: renderRoutes.map((route) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_router_dom.Route, {
2640
+ path: route.path,
2641
+ element: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(route.component, {})
2642
+ }, route.path)) })
2643
+ })
2644
+ }),
2645
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PageNavigation, {
2646
+ navigation: currentNavigation.items,
2647
+ currentRoute
2648
+ })
2649
+ ]
2650
+ })]
2651
+ }),
2652
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PageFooter, {})
2653
+ ]
2654
+ })
2092
2655
  })
2093
2656
  });
2094
2657
  }
@@ -2255,6 +2818,12 @@ Object.defineProperty(exports, "remToPx", {
2255
2818
  return remToPx;
2256
2819
  }
2257
2820
  });
2821
+ Object.defineProperty(exports, "useBuiltInText", {
2822
+ enumerable: true,
2823
+ get: function() {
2824
+ return useBuiltInText;
2825
+ }
2826
+ });
2258
2827
  Object.defineProperty(exports, "useClarifyConfig", {
2259
2828
  enumerable: true,
2260
2829
  get: function() {
@@ -2280,4 +2849,4 @@ Object.defineProperty(exports, "useTheme", {
2280
2849
  }
2281
2850
  });
2282
2851
 
2283
- //# sourceMappingURL=AppShell-4KB3lU-n.cjs.map
2852
+ //# sourceMappingURL=AppShell-CZw1MrPG.cjs.map