@clarify-labs/renderer 0.2.0 → 0.5.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 (97) hide show
  1. package/output/AppShell-D3FsVHQK.js +390 -0
  2. package/output/AppShell-D3FsVHQK.js.map +1 -0
  3. package/output/AppShell-DeaJ-rgo.cjs +409 -0
  4. package/output/AppShell-DeaJ-rgo.cjs.map +1 -0
  5. package/output/OpenApiOperation-DYXG-6Rw.js +1772 -0
  6. package/output/OpenApiOperation-DYXG-6Rw.js.map +1 -0
  7. package/output/OpenApiOperation-mhoi-s4N.cjs +1840 -0
  8. package/output/OpenApiOperation-mhoi-s4N.cjs.map +1 -0
  9. package/output/app/PageNavigation.d.ts +7 -0
  10. package/output/app/PageSkeleton.d.ts +1 -0
  11. package/output/{components → app}/SectionProvider.d.ts +3 -2
  12. package/output/chunk-DakpK96I.cjs +43 -0
  13. package/output/client.cjs +1 -1
  14. package/output/client.js +1 -1
  15. package/output/components/Button.d.ts +18 -0
  16. package/output/components/Code.d.ts +11 -7
  17. package/output/components/Collapse.d.ts +9 -0
  18. package/output/components/Heading.d.ts +10 -0
  19. package/output/components/Logo.d.ts +2 -0
  20. package/output/components/Prose.d.ts +7 -0
  21. package/output/components/Tag.d.ts +34 -0
  22. package/output/components/index.d.ts +9 -79
  23. package/output/components/patterns.d.ts +4 -2
  24. package/output/context.d.ts +1 -6
  25. package/output/core/context.d.ts +8 -0
  26. package/output/core/i18n.d.ts +5 -0
  27. package/output/core/index.d.ts +3 -0
  28. package/output/core/types.d.ts +174 -0
  29. package/output/i18n.d.ts +1 -0
  30. package/output/index.cjs +135 -766
  31. package/output/index.cjs.map +1 -1
  32. package/output/index.d.ts +15 -4
  33. package/output/index.js +108 -751
  34. package/output/index.js.map +1 -1
  35. package/output/markdown.cjs +3 -0
  36. package/output/markdown.d.ts +1 -0
  37. package/output/markdown.js +2 -0
  38. package/output/mdx/DocShell.d.ts +7 -0
  39. package/output/mdx/Markdown.d.ts +7 -0
  40. package/output/mdx/components.d.ts +7 -7
  41. package/output/mdx/primitives.d.ts +18 -12
  42. package/output/mdx/remark.d.ts +2 -0
  43. package/output/openapi/components/ExamplePanels.d.ts +36 -0
  44. package/output/openapi/components/OpenApiOperation.d.ts +33 -0
  45. package/output/openapi/components/SchemaProperties.d.ts +20 -0
  46. package/output/openapi/entry.d.ts +13 -0
  47. package/output/openapi/index.d.ts +3 -20
  48. package/output/openapi/lib/helpers.d.ts +25 -0
  49. package/output/openapi/lib/request-code.d.ts +18 -0
  50. package/output/openapi/lib/spec-path.d.ts +2 -0
  51. package/output/openapi/types.d.ts +70 -0
  52. package/output/preview/openapi.d.ts +28 -0
  53. package/output/preview.cjs +734 -0
  54. package/output/preview.cjs.map +1 -0
  55. package/output/preview.d.ts +19 -0
  56. package/output/preview.js +731 -0
  57. package/output/preview.js.map +1 -0
  58. package/output/remark-DNOdJz5i.cjs +14 -0
  59. package/output/remark-DNOdJz5i.cjs.map +1 -0
  60. package/output/remark-o5sg9Ilv.js +7 -0
  61. package/output/remark-o5sg9Ilv.js.map +1 -0
  62. package/output/{render-bPMMBoDH.js → render-BpavVnAe.js} +3 -2
  63. package/output/render-BpavVnAe.js.map +1 -0
  64. package/output/{render-z9rSQ00n.cjs → render-CjZt3edL.cjs} +6 -5
  65. package/output/render-CjZt3edL.cjs.map +1 -0
  66. package/output/renderer.css +1702 -591
  67. package/output/server.cjs +7 -5
  68. package/output/server.cjs.map +1 -1
  69. package/output/server.js +4 -2
  70. package/output/server.js.map +1 -1
  71. package/output/shell/ContentActions.d.ts +1 -0
  72. package/output/shell/Header.d.ts +4 -3
  73. package/output/shell/Navigation.d.ts +3 -2
  74. package/output/shell/Search.d.ts +6 -4
  75. package/output/{components → shell}/SiteLogo.d.ts +1 -1
  76. package/output/shell/icons.d.ts +5 -0
  77. package/output/shell/mobile.d.ts +5 -3
  78. package/output/{AppShell-Ci894P_0.js → shell-BlMMdTpZ.js} +1228 -867
  79. package/output/shell-BlMMdTpZ.js.map +1 -0
  80. package/output/{AppShell-4KB3lU-n.cjs → shell-_MyLsMUI.cjs} +1403 -1036
  81. package/output/shell-_MyLsMUI.cjs.map +1 -0
  82. package/output/{components → theme}/ThemeProvider.d.ts +3 -2
  83. package/output/types.d.ts +1 -121
  84. package/output/utils/clipboard.d.ts +1 -0
  85. package/output/utils/hash.d.ts +1 -0
  86. package/output/utils/href.d.ts +5 -0
  87. package/output/utils/lucide.d.ts +17 -0
  88. package/output/utils/path.d.ts +2 -0
  89. package/package.json +24 -10
  90. package/output/AppShell-4KB3lU-n.cjs.map +0 -1
  91. package/output/AppShell-Ci894P_0.js.map +0 -1
  92. package/output/render-bPMMBoDH.js.map +0 -1
  93. package/output/render-z9rSQ00n.cjs.map +0 -1
  94. /package/output/{components → app}/BuiltWithClarify.d.ts +0 -0
  95. /package/output/{components → app}/PageFooter.d.ts +0 -0
  96. /package/output/openapi/{utils.d.ts → lib/utils.d.ts} +0 -0
  97. /package/output/{components → theme}/ThemeToggle.d.ts +0 -0
@@ -1,50 +1,582 @@
1
- //#region \0rolldown/runtime.js
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __exportAll = (all, no_symbols) => {
9
- let target = {};
10
- for (var name in all) __defProp(target, name, {
11
- get: all[name],
12
- enumerable: true
13
- });
14
- if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
15
- return target;
16
- };
17
- var __copyProps = (to, from, except, desc) => {
18
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
19
- key = keys[i];
20
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
21
- get: ((k) => from[k]).bind(null, key),
22
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
23
- });
24
- }
25
- return to;
26
- };
27
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
28
- value: mod,
29
- enumerable: true
30
- }) : target, mod));
31
- //#endregion
32
- let framer_motion = require("framer-motion");
1
+ const require_chunk = require("./chunk-DakpK96I.cjs");
2
+ let clsx = require("clsx");
3
+ clsx = require_chunk.__toESM(clsx, 1);
33
4
  let react = require("react");
34
5
  let react_router_dom = require("react-router-dom");
35
- let zustand = require("zustand");
36
- let react_jsx_runtime = require("react/jsx-runtime");
37
- let clsx = require("clsx");
38
- clsx = __toESM(clsx, 1);
39
6
  let _headlessui_react = require("@headlessui/react");
40
7
  let lucide_react = require("lucide-react");
41
- lucide_react = __toESM(lucide_react, 1);
8
+ lucide_react = require_chunk.__toESM(lucide_react, 1);
9
+ let react_jsx_runtime = require("react/jsx-runtime");
10
+ let framer_motion = require("framer-motion");
11
+ let zustand = require("zustand");
12
+ //#region source/core/context.tsx
13
+ var ClarifyConfigContext = (0, react.createContext)(null);
14
+ var ClarifyLocaleContext = (0, react.createContext)(void 0);
15
+ var OpenApisContext = (0, react.createContext)({});
16
+ function useClarifyConfig() {
17
+ const config = (0, react.useContext)(ClarifyConfigContext);
18
+ if (!config) throw new Error("[clarify] useClarifyConfig must be used within a ClarifyConfigContext.Provider");
19
+ return config;
20
+ }
21
+ function useOpenApis() {
22
+ return (0, react.useContext)(OpenApisContext);
23
+ }
24
+ //#endregion
25
+ //#region source/core/i18n.ts
26
+ var builtInText = {
27
+ en: {
28
+ "actions.code": "Code",
29
+ "actions.copy": "Copy",
30
+ "actions.copied": "Copied!",
31
+ "builtWith.label": "Built with Clarify",
32
+ "builtWith.prefix": "Built with",
33
+ "callout.danger": "Danger",
34
+ "callout.info": "Info",
35
+ "callout.note": "Note",
36
+ "callout.success": "Success",
37
+ "callout.tip": "Tip",
38
+ "callout.warning": "Warning",
39
+ "contentActions.copyContent": "Copy page",
40
+ "contentActions.copyContentDescription": "Copy this page as {contentType} for LLMs",
41
+ "contentActions.copyLink": "Copy {contentType} link",
42
+ "contentActions.copyLinkDescription": "Copy the raw {contentType} content link for this page",
43
+ "contentActions.copyLlms": "Copy llms.txt",
44
+ "contentActions.copyLlmsDescription": "Copy the llms.txt link for this site",
45
+ "contentActions.copiedLlms": "Copied llms.txt",
46
+ "contentActions.copyOptions": "Choose copy option",
47
+ "contentActions.copiedContent": "Copied page",
48
+ "contentActions.copiedLink": "Copied link",
49
+ "contentActions.viewMarkdown": "View as Markdown",
50
+ "contentActions.viewMarkdownDescription": "View this page as plain text",
51
+ "contentActions.viewOpenApi": "View raw OpenAPI",
52
+ "contentActions.viewOpenApiDescription": "Open the API description file in a new tab",
53
+ "feedback.no": "No",
54
+ "feedback.prompt": "Was this page helpful?",
55
+ "feedback.thanks": "Thanks for your feedback!",
56
+ "feedback.yes": "Yes",
57
+ "navigation.documentation": "Documentation",
58
+ "navigation.next": "Next",
59
+ "navigation.previous": "Previous",
60
+ "navigation.previousNext": "Previous and next pages",
61
+ "navigation.toggle": "Toggle navigation",
62
+ "navbar.home": "Home",
63
+ "navbar.openLinks": "Open navigation links",
64
+ "navbar.sections": "Documentation sections",
65
+ "openapi.apiDocumentation": "API Documentation",
66
+ "openapi.bodyProperties": "Body properties",
67
+ "openapi.collapse": "Collapse",
68
+ "openapi.endpointNotFound": "Endpoint not found: {endpoint}",
69
+ "openapi.example": "Example",
70
+ "openapi.expand": "Expand",
71
+ "openapi.headers": "Headers",
72
+ "openapi.language": "Language",
73
+ "openapi.client": "Client",
74
+ "openapi.mediaType": "Media type",
75
+ "openapi.openApiReference": "OpenAPI Reference",
76
+ "openapi.operationParameter": "Operation parameter.",
77
+ "openapi.optional": "Optional.",
78
+ "openapi.parameter": "parameter",
79
+ "openapi.pathParameters": "Path parameters",
80
+ "openapi.queryParameters": "Query parameters",
81
+ "openapi.request": "Request",
82
+ "openapi.requestBody": "Request body",
83
+ "openapi.required": "Required.",
84
+ "openapi.requiredBadge": "required",
85
+ "openapi.response": "Response",
86
+ "openapi.responses": "Responses",
87
+ "openapi.schemaExample": "Schema example",
88
+ "openapi.scrollExamplesLeft": "Scroll examples left",
89
+ "openapi.scrollExamplesRight": "Scroll examples right",
90
+ "openapi.specNotFound": "OpenAPI spec not found: {specPath}",
91
+ "openapi.specPathMissing": "spec or specPath was not provided",
92
+ "openapi.status": "Status",
93
+ "openapi.version": "Version {version}",
94
+ "search.button": "Search...",
95
+ "search.noResults": "Nothing found for {query}.",
96
+ "search.placeholder": "Find something...",
97
+ "search.shortcutCtrl": "Ctrl ",
98
+ "theme.switchToDark": "Switch to dark theme",
99
+ "theme.switchToLight": "Switch to light theme",
100
+ "language.switch": "Switch language"
101
+ },
102
+ "zh-CN": {
103
+ "actions.code": "代码",
104
+ "actions.copy": "复制",
105
+ "actions.copied": "已复制!",
106
+ "builtWith.label": "由 Clarify 构建",
107
+ "builtWith.prefix": "构建来自",
108
+ "callout.danger": "危险",
109
+ "callout.info": "信息",
110
+ "callout.note": "注意",
111
+ "callout.success": "成功",
112
+ "callout.tip": "提示",
113
+ "callout.warning": "警告",
114
+ "contentActions.copyContent": "复制页面",
115
+ "contentActions.copyContentDescription": "将页面以 {contentType} 格式复制给 LLMs",
116
+ "contentActions.copyLink": "复制 {contentType} 链接",
117
+ "contentActions.copyLinkDescription": "复制当前页面的 {contentType} 原始内容链接",
118
+ "contentActions.copyLlms": "复制 llms.txt",
119
+ "contentActions.copyLlmsDescription": "复制此站点的 llms.txt 链接",
120
+ "contentActions.copiedLlms": "已复制 llms.txt",
121
+ "contentActions.copyOptions": "选择复制选项",
122
+ "contentActions.copiedContent": "已复制页面",
123
+ "contentActions.copiedLink": "已复制链接",
124
+ "contentActions.viewMarkdown": "以 Markdown 格式查看",
125
+ "contentActions.viewMarkdownDescription": "以纯文本查看此页面",
126
+ "contentActions.viewOpenApi": "查看 OpenAPI 原始内容",
127
+ "contentActions.viewOpenApiDescription": "在新标签页打开 API 描述文件",
128
+ "feedback.no": "否",
129
+ "feedback.prompt": "这个页面有帮助吗?",
130
+ "feedback.thanks": "感谢你的反馈!",
131
+ "feedback.yes": "是",
132
+ "navigation.documentation": "文档",
133
+ "navigation.next": "下一页",
134
+ "navigation.previous": "上一页",
135
+ "navigation.previousNext": "上一页和下一页",
136
+ "navigation.toggle": "切换导航",
137
+ "navbar.home": "首页",
138
+ "navbar.openLinks": "打开导航链接",
139
+ "navbar.sections": "文档栏目",
140
+ "openapi.apiDocumentation": "API 文档",
141
+ "openapi.bodyProperties": "请求体属性",
142
+ "openapi.collapse": "收起",
143
+ "openapi.endpointNotFound": "未找到端点:{endpoint}",
144
+ "openapi.example": "示例",
145
+ "openapi.expand": "展开",
146
+ "openapi.headers": "请求头",
147
+ "openapi.language": "语言",
148
+ "openapi.client": "客户端",
149
+ "openapi.mediaType": "媒体类型",
150
+ "openapi.openApiReference": "OpenAPI 参考",
151
+ "openapi.operationParameter": "操作参数。",
152
+ "openapi.optional": "可选。",
153
+ "openapi.parameter": "参数",
154
+ "openapi.pathParameters": "路径参数",
155
+ "openapi.queryParameters": "查询参数",
156
+ "openapi.request": "请求",
157
+ "openapi.requestBody": "请求体",
158
+ "openapi.required": "必填。",
159
+ "openapi.requiredBadge": "必填",
160
+ "openapi.response": "响应",
161
+ "openapi.responses": "响应",
162
+ "openapi.schemaExample": "Schema 示例",
163
+ "openapi.scrollExamplesLeft": "向左滚动示例",
164
+ "openapi.scrollExamplesRight": "向右滚动示例",
165
+ "openapi.specNotFound": "未找到 OpenAPI 描述文件:{specPath}",
166
+ "openapi.specPathMissing": "未提供 spec 或 specPath",
167
+ "openapi.status": "状态",
168
+ "openapi.version": "版本 {version}",
169
+ "search.button": "搜索...",
170
+ "search.noResults": "没有找到与 {query} 相关的结果。",
171
+ "search.placeholder": "搜索内容...",
172
+ "search.shortcutCtrl": "Ctrl ",
173
+ "theme.switchToDark": "切换到深色主题",
174
+ "theme.switchToLight": "切换到浅色主题",
175
+ "language.switch": "切换语言"
176
+ }
177
+ };
178
+ function resolveBuiltInLocale(locale) {
179
+ return locale === "zh-CN" || locale?.toLowerCase().startsWith("zh") ? "zh-CN" : "en";
180
+ }
181
+ function translateBuiltInText(locale, key, replacements = {}) {
182
+ let value = builtInText[resolveBuiltInLocale(locale)]?.[key] ?? builtInText.en[key];
183
+ for (const [name, replacement] of Object.entries(replacements)) value = value.replaceAll(`{${name}}`, replacement);
184
+ return value;
185
+ }
186
+ function useBuiltInText(locale) {
187
+ const config = (0, react.useContext)(ClarifyConfigContext);
188
+ const currentLocale = (0, react.useContext)(ClarifyLocaleContext);
189
+ const resolvedLocale = locale ?? currentLocale ?? config?.i18n?.defaultLocale;
190
+ return (key, replacements) => translateBuiltInText(resolvedLocale, key, replacements);
191
+ }
192
+ //#endregion
193
+ //#region source/utils/clipboard.ts
194
+ async function copyTextToClipboard(text) {
195
+ if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) try {
196
+ await navigator.clipboard.writeText(text);
197
+ return true;
198
+ } catch {}
199
+ if (typeof document === "undefined") return false;
200
+ const textarea = document.createElement("textarea");
201
+ textarea.value = text;
202
+ textarea.setAttribute("readonly", "");
203
+ textarea.style.position = "fixed";
204
+ textarea.style.top = "-9999px";
205
+ textarea.style.opacity = "0";
206
+ document.body.appendChild(textarea);
207
+ try {
208
+ textarea.select();
209
+ return document.execCommand("copy");
210
+ } catch {
211
+ return false;
212
+ } finally {
213
+ textarea.remove();
214
+ }
215
+ }
216
+ //#endregion
217
+ //#region source/utils/href.ts
218
+ function isExternalHref(href) {
219
+ return /^[a-z][a-z\d+.-]*:/i.test(href) || href.startsWith("//");
220
+ }
221
+ function hasLocalePrefix(href, config) {
222
+ const firstSegment = href.replace(/^\/+/, "").split("/")[0];
223
+ return Boolean(firstSegment && config.i18n?.locales.some((locale) => locale.code === firstSegment));
224
+ }
225
+ function localizeHref(href, config, locale) {
226
+ if (!locale || !config.i18n || isExternalHref(href) || href.startsWith("#")) return href;
227
+ if (locale === config.i18n.defaultLocale || hasLocalePrefix(href, config)) return href;
228
+ const cleanHref = href === "/" ? "" : href.replace(/^\/+/, "");
229
+ return `/${locale}${cleanHref ? `/${cleanHref}` : ""}`;
230
+ }
231
+ function prefixHref(href, routePrefix = "/") {
232
+ if (isExternalHref(href) || href.startsWith("#")) return href;
233
+ if (!routePrefix || routePrefix === "/") return href.startsWith("/") ? href : `/${href}`;
234
+ const prefix = routePrefix.replace(/^\/+|\/+$/g, "");
235
+ const path = href.replace(/^\/+/, "");
236
+ if (!path) return `/${prefix}`;
237
+ if (path === prefix || path.startsWith(`${prefix}/`)) return `/${path}`;
238
+ return `/${prefix}/${path}`;
239
+ }
240
+ //#endregion
241
+ //#region source/shell/ContentActions.tsx
242
+ function resolveContentArtifactUrl(contentArtifactUrl, routePrefix = "/") {
243
+ return prefixHref(contentArtifactUrl, routePrefix);
244
+ }
245
+ function getAbsoluteUrl(path) {
246
+ if (typeof window === "undefined") return path;
247
+ return new URL(path, window.location.href).href;
248
+ }
249
+ function ContentActions(arg0) {
250
+ const { hasTabs = false, route, routePrefix } = arg0;
251
+ const t = useBuiltInText();
252
+ const [copied, setCopied] = (0, react.useState)("idle");
253
+ if (!route?.contentArtifactUrl) return null;
254
+ const contentArtifactUrl = resolveContentArtifactUrl(route.contentArtifactUrl, routePrefix);
255
+ const isOpenApi = route.kind === "openapi";
256
+ const replacements = { contentType: isOpenApi ? "OpenAPI" : "Markdown" };
257
+ const viewLabel = isOpenApi ? t("contentActions.viewOpenApi") : t("contentActions.viewMarkdown");
258
+ const viewDescription = isOpenApi ? t("contentActions.viewOpenApiDescription") : t("contentActions.viewMarkdownDescription");
259
+ function markCopied(state) {
260
+ setCopied(state);
261
+ window.setTimeout(() => setCopied("idle"), 1600);
262
+ }
263
+ async function handleCopyContent() {
264
+ if (await copyTextToClipboard(await (await fetch(contentArtifactUrl)).text())) markCopied("content");
265
+ }
266
+ const llmsArtifactUrl = resolveContentArtifactUrl("/llms.txt", routePrefix);
267
+ async function handleCopyLink() {
268
+ if (await copyTextToClipboard(getAbsoluteUrl(contentArtifactUrl))) markCopied("link");
269
+ }
270
+ async function handleCopyLlms() {
271
+ if (await copyTextToClipboard(getAbsoluteUrl(llmsArtifactUrl))) markCopied("llms");
272
+ }
273
+ const actions = [{
274
+ key: "content",
275
+ label: t("contentActions.copyContent"),
276
+ description: t("contentActions.copyContentDescription", replacements),
277
+ icon: lucide_react.Copy,
278
+ run: handleCopyContent,
279
+ copiedLabel: t("contentActions.copiedContent")
280
+ }, {
281
+ key: "link",
282
+ label: t("contentActions.copyLink", replacements),
283
+ description: t("contentActions.copyLinkDescription", replacements),
284
+ icon: lucide_react.Link2,
285
+ run: handleCopyLink,
286
+ copiedLabel: t("contentActions.copiedLink")
287
+ }];
288
+ const llmsAction = {
289
+ key: "llms",
290
+ label: t("contentActions.copyLlms"),
291
+ description: t("contentActions.copyLlmsDescription"),
292
+ icon: lucide_react.FileText,
293
+ run: handleCopyLlms,
294
+ copiedLabel: t("contentActions.copiedLlms")
295
+ };
296
+ const primaryAction = actions[0];
297
+ const PrimaryIcon = copied === primaryAction.key ? lucide_react.Check : primaryAction.icon;
298
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
299
+ className: `clarify-content-actions sticky z-20 flex justify-end py-4 ${hasTabs ? "top-16 lg:top-30" : "top-16"}`,
300
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.Menu, {
301
+ as: "div",
302
+ className: "clarify-content-actions-menu relative inline-flex text-sm font-medium",
303
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
304
+ 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",
305
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
306
+ type: "button",
307
+ onClick: primaryAction.run,
308
+ className: "clarify-content-actions-primary clarify-ui-control inline-flex h-8 items-center gap-1.5 px-3 transition",
309
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrimaryIcon, { className: "h-3.5 w-3.5" }), copied === primaryAction.key ? t("actions.copied") : primaryAction.label]
310
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuButton, {
311
+ 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",
312
+ "aria-label": t("contentActions.copyOptions"),
313
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronDown, { className: "h-3.5 w-3.5" })
314
+ })]
315
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.MenuItems, {
316
+ anchor: "bottom end",
317
+ 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",
318
+ children: [
319
+ actions.slice(0, 1).map((action) => {
320
+ const Icon = action.icon;
321
+ const isCopied = copied === action.key;
322
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
323
+ type: "button",
324
+ onClick: action.run,
325
+ 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",
326
+ children: [
327
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
328
+ 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",
329
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { className: "h-4 w-4" })
330
+ }),
331
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
332
+ className: "flex min-w-0 flex-1 flex-col px-1",
333
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
334
+ className: "clarify-ui-menu-title",
335
+ children: isCopied ? t("contentActions.copiedContent") : action.label
336
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
337
+ className: "clarify-ui-menu-description truncate",
338
+ children: action.description
339
+ })]
340
+ }),
341
+ /* @__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"}` })
342
+ ]
343
+ }) }, action.key);
344
+ }),
345
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
346
+ href: contentArtifactUrl,
347
+ target: "_blank",
348
+ rel: "noreferrer",
349
+ 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",
350
+ children: [
351
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
352
+ 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",
353
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.FileText, { className: "h-4 w-4" })
354
+ }),
355
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
356
+ className: "flex min-w-0 flex-1 flex-col px-1",
357
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
358
+ className: "clarify-ui-menu-title flex items-center gap-1",
359
+ children: [viewLabel, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ExternalLink, { className: "clarify-ui-menu-icon h-3 w-3" })]
360
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
361
+ className: "clarify-ui-menu-description truncate",
362
+ children: viewDescription
363
+ })]
364
+ }),
365
+ /* @__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" })
366
+ ]
367
+ }) }),
368
+ actions.slice(1).map((action) => {
369
+ const Icon = action.icon;
370
+ const isCopied = copied === action.key;
371
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
372
+ type: "button",
373
+ onClick: action.run,
374
+ 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",
375
+ children: [
376
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
377
+ 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",
378
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { className: "h-4 w-4" })
379
+ }),
380
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
381
+ className: "flex min-w-0 flex-1 flex-col px-1",
382
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
383
+ className: "clarify-ui-menu-title",
384
+ children: isCopied ? action.copiedLabel ?? action.label : action.label
385
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
386
+ className: "clarify-ui-menu-description truncate",
387
+ children: action.description
388
+ })]
389
+ }),
390
+ /* @__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"}` })
391
+ ]
392
+ }) }, action.key);
393
+ }),
394
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
395
+ type: "button",
396
+ onClick: llmsAction.run,
397
+ 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",
398
+ children: [
399
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
400
+ 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",
401
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.FileText, { className: "h-4 w-4" })
402
+ }),
403
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
404
+ className: "flex min-w-0 flex-1 flex-col px-1",
405
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
406
+ className: "clarify-ui-menu-title",
407
+ children: copied === llmsAction.key ? llmsAction.copiedLabel ?? llmsAction.label : llmsAction.label
408
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
409
+ className: "clarify-ui-menu-description truncate",
410
+ children: llmsAction.description
411
+ })]
412
+ }),
413
+ /* @__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 ${copied === llmsAction.key ? "opacity-100" : "opacity-0"}` })
414
+ ]
415
+ }) }, llmsAction.key)
416
+ ]
417
+ })]
418
+ })
419
+ });
420
+ }
421
+ //#endregion
422
+ //#region source/theme/ThemeProvider.tsx
423
+ var ThemeContext = (0, react.createContext)(null);
424
+ var storageKey = "clarify:theme";
425
+ function getSystemTheme() {
426
+ if (typeof window === "undefined") return "light";
427
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
428
+ }
429
+ function getStoredTheme() {
430
+ if (typeof window === "undefined") return "system";
431
+ try {
432
+ const storedTheme = window.localStorage.getItem(storageKey);
433
+ return storedTheme === "light" || storedTheme === "dark" || storedTheme === "system" ? storedTheme : "system";
434
+ } catch {
435
+ return "system";
436
+ }
437
+ }
438
+ function storeTheme(theme) {
439
+ if (typeof window === "undefined") return;
440
+ try {
441
+ window.localStorage.setItem(storageKey, theme);
442
+ } catch {}
443
+ }
444
+ function applyTheme(resolvedTheme) {
445
+ if (typeof document === "undefined") return;
446
+ document.documentElement.classList.toggle("dark", resolvedTheme === "dark");
447
+ document.documentElement.style.colorScheme = resolvedTheme;
448
+ }
449
+ function ThemeProvider(arg0) {
450
+ const { children } = arg0;
451
+ const [theme, setThemeState] = (0, react.useState)(() => getStoredTheme());
452
+ const [systemTheme, setSystemTheme] = (0, react.useState)(() => getSystemTheme());
453
+ const resolvedTheme = theme === "system" ? systemTheme : theme;
454
+ (0, react.useEffect)(() => {
455
+ applyTheme(resolvedTheme);
456
+ }, [resolvedTheme]);
457
+ (0, react.useEffect)(() => {
458
+ if (typeof window === "undefined") return;
459
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
460
+ function updateSystemTheme() {
461
+ setSystemTheme(mediaQuery.matches ? "dark" : "light");
462
+ }
463
+ updateSystemTheme();
464
+ mediaQuery.addEventListener("change", updateSystemTheme);
465
+ return () => mediaQuery.removeEventListener("change", updateSystemTheme);
466
+ }, []);
467
+ const value = (0, react.useMemo)(() => ({
468
+ theme,
469
+ resolvedTheme,
470
+ setTheme(nextTheme) {
471
+ setThemeState(nextTheme);
472
+ storeTheme(nextTheme);
473
+ }
474
+ }), [resolvedTheme, theme]);
475
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThemeContext.Provider, {
476
+ value,
477
+ children
478
+ });
479
+ }
480
+ function useTheme() {
481
+ const context = (0, react.useContext)(ThemeContext);
482
+ if (!context) throw new Error("[clarify] useTheme must be used within ThemeProvider");
483
+ return context;
484
+ }
485
+ //#endregion
486
+ //#region source/theme/ThemeToggle.tsx
487
+ function SunIcon(props) {
488
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
489
+ viewBox: "0 0 20 20",
490
+ fill: "none",
491
+ "aria-hidden": "true",
492
+ ...props,
493
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M12.5 10a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0Z" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
494
+ strokeLinecap: "round",
495
+ d: "M10 5.5v-1M13.182 6.818l.707-.707M14.5 10h1M13.182 13.182l.707.707M10 15.5v-1M6.11 13.889l.708-.707M4.5 10h1M6.11 6.111l.708.707"
496
+ })]
497
+ });
498
+ }
499
+ function MoonIcon(props) {
500
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
501
+ viewBox: "0 0 20 20",
502
+ fill: "none",
503
+ "aria-hidden": "true",
504
+ ...props,
505
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M15.224 11.724a5.5 5.5 0 0 1-6.949-6.949 5.5 5.5 0 1 0 6.949 6.949Z" })
506
+ });
507
+ }
508
+ function ThemeToggle() {
509
+ const { resolvedTheme, setTheme } = useTheme();
510
+ const t = useBuiltInText();
511
+ const otherTheme = resolvedTheme === "dark" ? "light" : "dark";
512
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
513
+ type: "button",
514
+ 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",
515
+ "aria-label": otherTheme === "dark" ? t("theme.switchToDark") : t("theme.switchToLight"),
516
+ onClick: () => setTheme(otherTheme),
517
+ children: [
518
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "absolute size-12 pointer-fine:hidden" }),
519
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SunIcon, { className: "h-5 w-5 stroke-(--clarify-theme-tokens-colors-foreground) dark:hidden" }),
520
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MoonIcon, { className: "hidden h-5 w-5 stroke-white dark:block" })
521
+ ]
522
+ });
523
+ }
524
+ //#endregion
525
+ //#region source/utils/path.ts
526
+ function normalizeRoutePath(path) {
527
+ const [pathname, suffix = ""] = path.split(/([?#].*)/, 2);
528
+ return `${pathname.replace(/^\/+/, "/").replace(/\/+$/, "") || "/"}${suffix}`;
529
+ }
530
+ function isSameRoutePath(a, b) {
531
+ if (!a || !b) return false;
532
+ return normalizeRoutePath(a) === normalizeRoutePath(b);
533
+ }
534
+ //#endregion
535
+ //#region source/utils/lucide.ts
536
+ /**
537
+ * Registry of all Lucide icon components keyed by their PascalCase export name.
538
+ *
539
+ * Access icons via index lookup (e.g. `lucideIconRegistry[name]`) so React
540
+ * tooling does not mistake the access for a component created during render.
541
+ */
542
+ var lucideIconRegistry = lucide_react;
543
+ function toPascalCase(value) {
544
+ return value.split(/[^a-zA-Z0-9]+/).filter(Boolean).map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`).join("");
545
+ }
546
+ /**
547
+ * Resolve an icon name into the matching Lucide registry key.
548
+ *
549
+ * Accepts both the exact PascalCase export name (e.g. `ArrowRight`) and
550
+ * kebab/space/snake variants (e.g. `arrow-right`), returning `undefined`
551
+ * when no matching icon exists.
552
+ */
553
+ function resolveLucideIconName(name) {
554
+ if (!name) return void 0;
555
+ if (lucideIconRegistry[name]) return name;
556
+ const pascalName = toPascalCase(name);
557
+ return lucideIconRegistry[pascalName] ? pascalName : void 0;
558
+ }
559
+ //#endregion
560
+ //#region source/shell/icons.tsx
561
+ function NavigationIcon(arg0) {
562
+ const { name, className } = arg0;
563
+ if (!name) return null;
564
+ const iconName = resolveLucideIconName(name);
565
+ if (!iconName) return null;
566
+ const Icon = lucideIconRegistry[iconName];
567
+ if (!Icon) return null;
568
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
569
+ className: (0, clsx.default)("shrink-0 stroke-current", className),
570
+ "aria-hidden": "true"
571
+ });
572
+ }
573
+ //#endregion
42
574
  //#region source/utils/remToPx.ts
43
575
  function remToPx(remValue) {
44
576
  return remValue * (typeof window === "undefined" ? 16 : Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize));
45
577
  }
46
578
  //#endregion
47
- //#region source/components/SectionProvider.tsx
579
+ //#region source/app/SectionProvider.tsx
48
580
  function createSectionStore(sections) {
49
581
  return (0, zustand.createStore)()((set) => ({
50
582
  sections,
@@ -63,16 +595,16 @@ function useVisibleSections(sectionStore) {
63
595
  (0, react.useEffect)(() => {
64
596
  function checkVisibleSections() {
65
597
  const { innerHeight, scrollY } = window;
598
+ const viewportTop = scrollY;
599
+ const viewportBottom = scrollY + innerHeight;
66
600
  const newVisibleSections = [];
67
601
  for (let sectionIndex = 0; sectionIndex < sections.length; sectionIndex += 1) {
68
602
  const { id, headingRef, offsetRem = 0 } = sections[sectionIndex];
69
603
  if (!headingRef?.current) continue;
70
604
  const offset = remToPx(offsetRem);
71
605
  const top = headingRef.current.getBoundingClientRect().top + scrollY;
72
- if (sectionIndex === 0 && top - offset > scrollY) newVisibleSections.push("_top");
73
- const nextSection = sections[sectionIndex + 1];
74
- const bottom = (nextSection?.headingRef?.current?.getBoundingClientRect().top ?? Infinity) + scrollY - remToPx(nextSection?.offsetRem ?? 0);
75
- if (top > scrollY && top < scrollY + innerHeight || bottom > scrollY && bottom < scrollY + innerHeight || top <= scrollY && bottom >= scrollY + innerHeight) newVisibleSections.push(id);
606
+ if (sectionIndex === 0 && top - offset > viewportTop) newVisibleSections.push("_top");
607
+ if ((sections[sectionIndex + 1]?.headingRef?.current?.getBoundingClientRect().top ?? Infinity) + scrollY > viewportTop && top < viewportBottom) newVisibleSections.push(id);
76
608
  }
77
609
  setVisibleSections(newVisibleSections);
78
610
  }
@@ -93,7 +625,17 @@ function SectionProvider(arg0) {
93
625
  const [sectionStore] = (0, react.useState)(() => createSectionStore(sections));
94
626
  useVisibleSections(sectionStore);
95
627
  useIsomorphicLayoutEffect(() => {
96
- sectionStore.setState({ sections });
628
+ sectionStore.setState((state) => ({
629
+ sections: sections.map((section) => {
630
+ const registeredSection = state.sections.find((item) => item.id === section.id);
631
+ return {
632
+ ...section,
633
+ headingRef: registeredSection?.headingRef,
634
+ offsetRem: registeredSection?.offsetRem ?? section.offsetRem
635
+ };
636
+ }),
637
+ visibleSections: []
638
+ }));
97
639
  }, [sectionStore, sections]);
98
640
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SectionStoreContext.Provider, {
99
641
  value: sectionStore,
@@ -106,151 +648,46 @@ function useSectionStore(selector) {
106
648
  return (0, zustand.useStore)(store, selector);
107
649
  }
108
650
  //#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)
651
+ //#region source/components/Button.tsx
652
+ function ArrowIcon(props) {
653
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
654
+ viewBox: "0 0 20 20",
655
+ fill: "none",
656
+ "aria-hidden": "true",
657
+ ...props,
658
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
659
+ stroke: "currentColor",
660
+ strokeLinecap: "round",
661
+ strokeLinejoin: "round",
662
+ d: "m11.5 6.5 3 3.5m0 0-3 3.5m3-3.5h-9"
663
+ })
125
664
  });
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
- })] });
135
- }
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}`;
141
- }
142
- function getAbsoluteUrl(path) {
143
- if (typeof window === "undefined") return path;
144
- return new URL(path, window.location.href).href;
145
- }
146
- async function copyText(text) {
147
- await navigator.clipboard.writeText(text);
148
665
  }
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
- });
213
- }
214
- //#endregion
215
- //#region source/components/BuiltWithClarify.tsx
216
- function ClarifyMark(props) {
217
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
218
- viewBox: "0 0 279 200",
219
- "aria-hidden": "true",
666
+ var buttonVariantStyles = {
667
+ 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",
668
+ 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",
669
+ 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",
670
+ 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",
671
+ text: "text-(--clarify-theme-tokens-colors-primary) hover:opacity-80 dark:text-(--clarify-theme-tokens-colors-primary) dark:hover:opacity-80"
672
+ };
673
+ function Button(arg0) {
674
+ const { variant = "primary", className, children, arrow, ...props } = arg0;
675
+ const classes = (0, clsx.default)("clarify-button inline-flex justify-center gap-0.5 overflow-hidden text-sm font-medium transition", buttonVariantStyles[variant], className);
676
+ const arrowIcon = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArrowIcon, { className: (0, clsx.default)("mt-0.5 h-5 w-5", variant === "text" && "relative top-px", arrow === "left" && "-ml-1 rotate-180", arrow === "right" && "-mr-1") });
677
+ const inner = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
678
+ arrow === "left" ? arrowIcon : null,
679
+ children,
680
+ arrow === "right" ? arrowIcon : null
681
+ ] });
682
+ if (typeof props.href === "undefined") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
683
+ className: classes,
220
684
  ...props,
221
- children: [
222
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
223
- d: "M44.867217 0.00543761C130.715579 1.00591567 200 70.9091172 200 156.994562L199.986321 155.127494C199.384888 180.009127 179.026368 199.994562 154 199.994562H46C20.5949015 199.994562 0 179.399661 0 153.994562V45.9945624C0 21.0975659 19.7793434 0.820282524 44.4815926 0.0191499894Z",
224
- fill: "#00D492"
225
- }),
226
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
227
- d: "M123.867217 0.00543761C209.715579 1.00591567 279 70.9091172 279 156.994562L278.986321 155.127494C278.384888 180.009127 258.026368 199.994562 233 199.994562H125C99.5949015 199.994562 79 179.399661 79 153.994562V45.9945624C79 21.0975659 98.7793434 0.820282524 123.481593 0.0191499894Z",
228
- fill: "#00F6C9",
229
- fillOpacity: "0.6",
230
- transform: "rotate(-90 179 100)"
231
- }),
232
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
233
- d: "M199.979267 154.416906L199.984438 155.157125L199.962366 155.872459C198.977251 180.406837 178.776104 199.994562 154 199.994562L124.372438 199.994125L124.249053 199.994081C99.6939678 199.603921 79.8122712 179.973634 79.01915 155.518407L79.0054376 155.132783C79.5830823 105.566626 103.129768 61.5221348 139.498462 33.1463428C175.69419 61.3871018 199.186123 105.143863 199.979267 154.416906Z",
234
- fill: "#00F692"
235
- })
236
- ]
685
+ children: inner
237
686
  });
238
- }
239
- function BuiltWithClarify() {
240
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
241
- href: "https://clarify.pub",
242
- target: "_blank",
243
- 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",
246
- children: [
247
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Built with" }),
248
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ClarifyMark, { className: "clarify-built-with-logo h-3.5 w-5 flex-none" }),
249
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
250
- className: "font-semibold text-zinc-700 dark:text-zinc-300",
251
- children: "Clarify"
252
- })
253
- ]
687
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
688
+ className: classes,
689
+ ...props,
690
+ children: inner
254
691
  });
255
692
  }
256
693
  //#endregion
@@ -293,21 +730,22 @@ var calloutStyles = {
293
730
  Icon: lucide_react.CheckCircle2
294
731
  }
295
732
  };
296
- var defaultTitles = {
297
- info: "Info",
298
- note: "Note",
299
- tip: "Tip",
300
- warning: "Warning",
301
- danger: "Danger",
302
- success: "Success"
733
+ var defaultTitleKeys = {
734
+ info: "callout.info",
735
+ note: "callout.note",
736
+ tip: "callout.tip",
737
+ warning: "callout.warning",
738
+ danger: "callout.danger",
739
+ success: "callout.success"
303
740
  };
304
741
  function Callout(arg0) {
305
742
  const { children, type = "info", title, icon = true, className, ...props } = arg0;
743
+ const t = useBuiltInText();
306
744
  const style = calloutStyles[type];
307
745
  const Icon = style.Icon;
308
- const resolvedTitle = title === void 0 ? defaultTitles[type] : title;
746
+ const resolvedTitle = title === void 0 ? t(defaultTitleKeys[type]) : title;
309
747
  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),
748
+ 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
749
  ...props,
312
750
  children: [icon ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
313
751
  className: (0, clsx.default)("mt-1 size-4 flex-none", style.icon),
@@ -326,16 +764,15 @@ function Callout(arg0) {
326
764
  }
327
765
  //#endregion
328
766
  //#region source/components/Card.tsx
329
- function toPascalCase(value) {
330
- return value.split(/[^a-zA-Z0-9]+/).filter(Boolean).map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`).join("");
331
- }
332
767
  function CardIcon(arg0) {
333
768
  const { name } = arg0;
334
769
  if (!name) return null;
335
- const Icon = lucide_react[toPascalCase(name)];
770
+ const iconName = resolveLucideIconName(name);
771
+ if (!iconName) return null;
772
+ const Icon = lucideIconRegistry[iconName];
336
773
  if (!Icon) return null;
337
774
  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",
775
+ className: "flex size-9 flex-none items-center justify-center rounded-(--clarify-theme-tokens-radius-lg) bg-(--clarify-ui-accent-background) text-(--clarify-ui-accent-text) ring-1 ring-(--clarify-ui-accent-border)",
339
776
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
340
777
  className: "size-5",
341
778
  "aria-hidden": "true"
@@ -362,18 +799,18 @@ function Card(arg0) {
362
799
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CardIcon, { name: icon }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
363
800
  className: "min-w-0 flex-1",
364
801
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
365
- className: "m-0 text-base font-semibold text-zinc-900 dark:text-white",
802
+ className: "m-0 text-base font-semibold text-(--clarify-theme-tokens-colors-foreground) dark:text-white",
366
803
  children: title
367
804
  }), children ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
368
- className: "mt-2 text-sm/6 text-zinc-600 dark:text-zinc-400 *:m-0",
805
+ className: "mt-2 text-sm/6 text-(--clarify-theme-tokens-colors-muted) dark:text-zinc-400 *:m-0",
369
806
  children
370
807
  }) : null]
371
808
  })]
372
809
  }), href ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
373
- className: "absolute inset-0 rounded-2xl",
810
+ className: "absolute inset-0 rounded-(--clarify-theme-tokens-radius-xl)",
374
811
  "aria-hidden": "true"
375
812
  }) : 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);
813
+ const classes = (0, clsx.default)("group relative block rounded-(--clarify-theme-tokens-radius-xl) border border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-surface) p-5 shadow-(--clarify-ui-accent-glow) transition hover:border-(--clarify-ui-accent-border) hover:shadow-md dark:bg-zinc-900/50", className);
377
814
  if (!href) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
378
815
  className: classes,
379
816
  children: content
@@ -410,10 +847,10 @@ var languageNames = {
410
847
  json: "JSON"
411
848
  };
412
849
  function getPanelTitle(arg0) {
413
- const { title, language } = arg0;
850
+ const { title, language, fallbackTitle = "Code" } = arg0;
414
851
  if (title) return title;
415
852
  if (language && language in languageNames) return languageNames[language];
416
- return "Code";
853
+ return fallbackTitle;
417
854
  }
418
855
  function getNodeText(node) {
419
856
  if (typeof node === "string" || typeof node === "number") return String(node);
@@ -438,6 +875,7 @@ function ClipboardIcon(props) {
438
875
  }
439
876
  function CopyButton(arg0) {
440
877
  const { code } = arg0;
878
+ const t = useBuiltInText();
441
879
  const [copyCount, setCopyCount] = (0, react.useState)(0);
442
880
  const copied = copyCount > 0;
443
881
  (0, react.useEffect)(() => {
@@ -448,20 +886,20 @@ function CopyButton(arg0) {
448
886
  if (!code) return null;
449
887
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
450
888
  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"),
889
+ 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
890
  onClick: () => {
453
- window.navigator.clipboard.writeText(code).then(() => {
454
- setCopyCount((count) => count + 1);
891
+ copyTextToClipboard(code).then((ok) => {
892
+ if (ok) setCopyCount((count) => count + 1);
455
893
  });
456
894
  },
457
895
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
458
896
  "aria-hidden": copied,
459
897
  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"]
898
+ 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
899
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
462
900
  "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!"
901
+ className: (0, clsx.default)("pointer-events-none absolute inset-0 flex items-center justify-center text-(--clarify-theme-tokens-colors-primary) transition duration-300", !copied && "translate-y-1.5 opacity-0"),
902
+ children: t("actions.copied")
465
903
  })]
466
904
  });
467
905
  }
@@ -472,12 +910,12 @@ function CodePanelHeader(arg0) {
472
910
  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
911
  children: [
474
912
  tag ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
475
- className: "font-mono text-[0.625rem]/6 font-semibold text-emerald-400",
913
+ className: "clarify-code-panel-tag font-semibold text-(--clarify-theme-tokens-colors-primary)",
476
914
  children: tag
477
915
  }) : null,
478
916
  tag && label ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "h-0.5 w-0.5 rounded-full bg-zinc-500" }) : null,
479
917
  label ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
480
- className: "font-mono text-xs text-zinc-400",
918
+ className: "text-xs text-zinc-400",
481
919
  children: label
482
920
  }) : null
483
921
  ]
@@ -510,6 +948,7 @@ function CodePanel(arg0) {
510
948
  }
511
949
  function CodeGroupHeader(arg0) {
512
950
  const { title, children, selectedIndex } = arg0;
951
+ const t = useBuiltInText();
513
952
  const hasTabs = react.Children.count(children) > 1;
514
953
  if (!title && !hasTabs) return null;
515
954
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -520,8 +959,11 @@ function CodeGroupHeader(arg0) {
520
959
  }) : null, hasTabs ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.TabList, {
521
960
  className: "clarify-code-tabs -mb-px flex gap-4 text-xs font-medium",
522
961
  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 : {})
962
+ className: (0, clsx.default)("clarify-code-tab border-b py-3 transition data-selected:not-data-focus:outline-hidden", childIndex === selectedIndex ? "border-(--clarify-theme-tokens-colors-primary) text-(--clarify-theme-tokens-colors-primary)" : "border-transparent text-zinc-400 hover:text-zinc-300"),
963
+ children: getPanelTitle({
964
+ ...(0, react.isValidElement)(child) ? child.props : {},
965
+ fallbackTitle: t("actions.code")
966
+ })
525
967
  }))
526
968
  }) : null]
527
969
  });
@@ -556,459 +998,219 @@ function usePreventLayoutShift() {
556
998
  window.scrollBy(0, newTop - initialTop);
557
999
  });
558
1000
  }
559
- };
560
- }
561
- var usePreferredLanguageStore = (0, zustand.create)()((set) => ({
562
- preferredLanguages: [],
563
- addPreferredLanguage: (language) => set((state) => ({ preferredLanguages: [...state.preferredLanguages.filter((preferredLanguage) => preferredLanguage !== language), language] }))
564
- }));
565
- function useTabGroupProps(availableLanguages) {
566
- const { preferredLanguages, addPreferredLanguage } = usePreferredLanguageStore();
567
- const [selectedIndex, setSelectedIndex] = (0, react.useState)(0);
568
- const activeLanguage = [...availableLanguages].sort((a, z) => preferredLanguages.indexOf(z) - preferredLanguages.indexOf(a))[0];
569
- const languageIndex = availableLanguages.indexOf(activeLanguage);
570
- const newSelectedIndex = languageIndex === -1 ? selectedIndex : languageIndex;
571
- if (newSelectedIndex !== selectedIndex) setSelectedIndex(newSelectedIndex);
572
- const { positionRef, preventLayoutShift } = usePreventLayoutShift();
573
- return {
574
- as: "div",
575
- ref: positionRef,
576
- selectedIndex,
577
- onChange: (nextSelectedIndex) => {
578
- preventLayoutShift(() => addPreferredLanguage(availableLanguages[nextSelectedIndex]));
579
- }
580
- };
581
- }
582
- var CodeGroupContext = (0, react.createContext)(false);
583
- function CodeGroup(arg0) {
584
- const { children, title, ...props } = arg0;
585
- const tabGroupProps = useTabGroupProps(react.Children.map(children, (child) => getPanelTitle((0, react.isValidElement)(child) ? child.props : {})) ?? []);
586
- const hasTabs = react.Children.count(children) > 1;
587
- const containerClassName = "clarify-code-group my-6 overflow-hidden rounded-2xl bg-zinc-900 shadow-md dark:ring-1 dark:ring-white/10";
588
- const header = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeGroupHeader, {
589
- title,
590
- selectedIndex: tabGroupProps.selectedIndex,
591
- children
592
- });
593
- const panels = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeGroupPanels, {
594
- ...props,
595
- children
596
- });
597
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeGroupContext.Provider, {
598
- value: true,
599
- children: hasTabs ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.TabGroup, {
600
- ...tabGroupProps,
601
- className: containerClassName,
602
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
603
- className: "not-prose",
604
- children: [header, panels]
605
- })
606
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
607
- className: containerClassName,
608
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
609
- className: "not-prose",
610
- children: [header, panels]
611
- })
612
- })
613
- });
614
- }
615
- function Code(arg0) {
616
- const { children, ...props } = arg0;
617
- if ((0, react.useContext)(CodeGroupContext) && typeof children === "string") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
618
- ...props,
619
- dangerouslySetInnerHTML: { __html: children }
620
- });
621
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
622
- ...props,
623
- children
624
- });
625
- }
626
- function Pre(arg0) {
627
- const { children, ...props } = arg0;
628
- if ((0, react.useContext)(CodeGroupContext)) return children;
629
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeGroup, {
630
- ...props,
631
- children
632
- });
633
- }
634
- //#endregion
635
- //#region source/components/Feedback.tsx
636
- function CheckIcon(props) {
637
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
638
- viewBox: "0 0 20 20",
639
- "aria-hidden": "true",
640
- ...props,
641
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
642
- cx: "10",
643
- cy: "10",
644
- r: "10",
645
- strokeWidth: "0"
646
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
647
- fill: "none",
648
- strokeLinecap: "round",
649
- strokeLinejoin: "round",
650
- strokeWidth: "1.5",
651
- d: "m6.75 10.813 2.438 2.437c1.218-4.469 4.062-6.5 4.062-6.5"
652
- })]
653
- });
654
- }
655
- function FeedbackButton(props) {
656
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
657
- type: "submit",
658
- className: "clarify-feedback-button px-3 text-sm font-medium text-zinc-600 transition hover:bg-zinc-900/2.5 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-white/5 dark:hover:text-white",
659
- ...props
660
- });
661
- }
662
- var FeedbackForm = (0, react.forwardRef)(function FeedbackForm(arg0, ref) {
663
- const { onSubmit, className, ...props } = arg0;
664
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
665
- ...props,
666
- ref,
667
- onSubmit,
668
- className: (0, clsx.default)(className, "clarify-feedback-form absolute inset-0 flex items-center justify-center gap-6 md:justify-start"),
669
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
670
- className: "text-sm text-zinc-600 dark:text-zinc-400",
671
- children: "Was this page helpful?"
672
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
673
- 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
- children: [
675
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FeedbackButton, {
676
- "data-response": "yes",
677
- children: "Yes"
678
- }),
679
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "bg-zinc-900/10 dark:bg-white/10" }),
680
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FeedbackButton, {
681
- "data-response": "no",
682
- children: "No"
683
- })
684
- ]
685
- })]
686
- });
687
- });
688
- var FeedbackThanks = (0, react.forwardRef)(function FeedbackThanks(arg0, ref) {
689
- const { className, ...props } = arg0;
690
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
691
- ...props,
692
- ref,
693
- className: (0, clsx.default)(className, "clarify-feedback-thanks absolute inset-0 flex justify-center md:justify-start"),
694
- 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!"]
697
- })
698
- });
699
- });
700
- function Feedback() {
701
- const [submitted, setSubmitted] = (0, react.useState)(false);
702
- function onSubmit(event) {
703
- event.preventDefault();
704
- setSubmitted(true);
705
- }
706
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
707
- className: "clarify-feedback relative h-8",
708
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.Transition, {
709
- show: !submitted,
710
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FeedbackForm, {
711
- className: "duration-300 data-closed:opacity-0 data-leave:pointer-events-none",
712
- onSubmit
713
- })
714
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.Transition, {
715
- show: submitted,
716
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FeedbackThanks, { className: "delay-150 duration-300 data-closed:opacity-0" })
717
- })]
718
- });
719
- }
720
- //#endregion
721
- //#region source/components/patterns.tsx
722
- function GridPattern(arg0) {
723
- const { width, height, x, y, squares, ...props } = arg0;
724
- const patternId = (0, react.useId)();
725
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
726
- "aria-hidden": "true",
727
- ...props,
728
- children: [
729
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pattern", {
730
- id: patternId,
731
- width,
732
- height,
733
- patternUnits: "userSpaceOnUse",
734
- x,
735
- y,
736
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
737
- d: `M.5 ${height}V.5H${width}`,
738
- fill: "none"
739
- })
740
- }) }),
741
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
742
- width: "100%",
743
- height: "100%",
744
- strokeWidth: 0,
745
- fill: `url(#${patternId})`
746
- }),
747
- squares ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
748
- x,
749
- y,
750
- className: "overflow-visible",
751
- children: squares.map(([squareX, squareY]) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
752
- width: width + 1,
753
- height: height + 1,
754
- x: squareX * width,
755
- y: squareY * height,
756
- strokeWidth: "0"
757
- }, `${squareX}-${squareY}`))
758
- }) : null
759
- ]
760
- });
761
- }
762
- function HeroPattern() {
763
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
764
- className: "absolute inset-0 -z-10 mx-0 max-w-none overflow-hidden",
765
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
766
- className: "absolute top-0 left-1/2 -ml-152 h-100 w-325 dark:mask-[linear-gradient(white,transparent)]",
767
- 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",
769
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GridPattern, {
770
- width: 72,
771
- height: 56,
772
- x: -12,
773
- y: 4,
774
- squares: [
775
- [4, 3],
776
- [2, 1],
777
- [7, 3],
778
- [10, 6]
779
- ],
780
- className: "absolute inset-x-0 inset-y-[-50%] h-[200%] w-full -skew-y-18 fill-black/40 stroke-black/50 mix-blend-overlay dark:fill-white/2.5 dark:stroke-white/5"
781
- })
782
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
783
- viewBox: "0 0 1113 440",
784
- "aria-hidden": "true",
785
- className: "absolute top-0 left-1/2 -ml-76 w-278.25 fill-white blur-[26px] dark:hidden",
786
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M.016 439.5s-9.5-300 434-300S882.516 20 882.516 20V0h230.004v439.5H.016Z" })
787
- })]
788
- })
789
- });
790
- }
791
- //#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
- //#region source/components/PageFooter.tsx
805
- function resolveLocalizedText$1(text, locale, fallbackLocale) {
806
- if (typeof text === "string") return text;
807
- return (locale ? text[locale] : void 0) ?? (fallbackLocale ? text[fallbackLocale] : void 0) ?? Object.values(text)[0] ?? "";
808
- }
809
- function isExternalHref$1(href) {
810
- return /^[a-z][a-z0-9+.-]*:/i.test(href) || href.startsWith("//");
811
- }
812
- function localeForPath$1(config, pathname) {
813
- const i18n = config.i18n;
814
- if (!i18n) return void 0;
815
- const firstSegment = pathname.split("/").filter(Boolean)[0];
816
- return i18n.locales.find((locale) => locale.code === firstSegment)?.code ?? i18n.defaultLocale;
817
- }
818
- function localizeHref$1(href, config, locale) {
819
- if (!locale || !config.i18n || isExternalHref$1(href) || href.startsWith("#")) return href;
820
- if (locale === config.i18n.defaultLocale) return href;
821
- const cleanHref = href === "/" ? "" : href.replace(/^\/+/, "");
822
- return `/${locale}${cleanHref ? `/${cleanHref}` : ""}`;
823
- }
824
- function FooterLink(arg0) {
825
- const { link, locale, config } = arg0;
826
- const external = link.external ?? isExternalHref$1(link.href);
827
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
828
- href: external ? link.href : localizeHref$1(link.href, config, locale),
829
- target: external ? "_blank" : void 0,
830
- 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",
832
- children: resolveLocalizedText$1(link.label, locale, config.i18n?.defaultLocale)
833
- });
834
- }
835
- function SocialLink(arg0) {
836
- const { name, href } = arg0;
837
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
838
- href,
839
- target: "_blank",
840
- 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",
842
- children: name
843
- });
844
- }
845
- function PageFooter() {
846
- const config = useClarifyConfig();
847
- const locale = localeForPath$1(config, (0, react_router_dom.useLocation)().pathname);
848
- const footer = config.footer;
849
- const links = footer?.links ?? [];
850
- const socials = Object.entries(footer?.socials ?? {});
851
- const copyright = footer?.copyright ? resolveLocalizedText$1(footer.copyright, locale, config.i18n?.defaultLocale) : void 0;
852
- const hasCustomFooter = Boolean(copyright || links.length > 0 || socials.length > 0);
853
- 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"),
855
- children: [hasCustomFooter ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
856
- className: "clarify-footer-content flex flex-col gap-3 text-right sm:text-left",
857
- 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",
859
- children: copyright
860
- }) : null, links.length > 0 || socials.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
861
- className: "clarify-footer-links flex flex-wrap justify-end gap-x-4 gap-y-2 sm:justify-start",
862
- children: [links.map((link) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FooterLink, {
863
- link,
864
- locale,
865
- config
866
- }, `${link.href}-${resolveLocalizedText$1(link.label, locale, config.i18n?.defaultLocale)}`)), socials.map(([name, href]) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SocialLink, {
867
- name,
868
- href
869
- }, name))]
870
- }) : null]
871
- }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
872
- className: "clarify-footer-brand flex justify-end",
873
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BuiltWithClarify, {})
874
- })]
875
- });
876
- }
877
- //#endregion
878
- //#region source/components/ThemeProvider.tsx
879
- var ThemeContext = (0, react.createContext)(null);
880
- var storageKey = "clarify:theme";
881
- function getSystemTheme() {
882
- if (typeof window === "undefined") return "light";
883
- return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
884
- }
885
- function getStoredTheme() {
886
- if (typeof window === "undefined") return "system";
887
- const storedTheme = window.localStorage.getItem(storageKey);
888
- return storedTheme === "light" || storedTheme === "dark" || storedTheme === "system" ? storedTheme : "system";
889
- }
890
- function applyTheme(resolvedTheme) {
891
- if (typeof document === "undefined") return;
892
- document.documentElement.classList.toggle("dark", resolvedTheme === "dark");
893
- document.documentElement.style.colorScheme = resolvedTheme;
894
- }
895
- function ThemeProvider(arg0) {
896
- const { children } = arg0;
897
- const [theme, setThemeState] = (0, react.useState)(() => getStoredTheme());
898
- const [systemTheme, setSystemTheme] = (0, react.useState)(() => getSystemTheme());
899
- const resolvedTheme = theme === "system" ? systemTheme : theme;
900
- (0, react.useEffect)(() => {
901
- applyTheme(resolvedTheme);
902
- }, [resolvedTheme]);
903
- (0, react.useEffect)(() => {
904
- if (typeof window === "undefined") return;
905
- const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
906
- function updateSystemTheme() {
907
- setSystemTheme(mediaQuery.matches ? "dark" : "light");
908
- }
909
- updateSystemTheme();
910
- mediaQuery.addEventListener("change", updateSystemTheme);
911
- return () => mediaQuery.removeEventListener("change", updateSystemTheme);
912
- }, []);
913
- const value = (0, react.useMemo)(() => ({
914
- theme,
915
- resolvedTheme,
916
- setTheme(nextTheme) {
917
- setThemeState(nextTheme);
918
- if (typeof window !== "undefined") window.localStorage.setItem(storageKey, nextTheme);
919
- }
920
- }), [resolvedTheme, theme]);
921
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThemeContext.Provider, {
922
- value,
1001
+ };
1002
+ }
1003
+ var usePreferredLanguageStore = (0, zustand.create)()((set) => ({
1004
+ preferredLanguages: [],
1005
+ addPreferredLanguage: (language) => set((state) => ({ preferredLanguages: [...state.preferredLanguages.filter((preferredLanguage) => preferredLanguage !== language), language] }))
1006
+ }));
1007
+ function useTabGroupProps(availableLanguages) {
1008
+ const { preferredLanguages, addPreferredLanguage } = usePreferredLanguageStore();
1009
+ const [selectedIndex, setSelectedIndex] = (0, react.useState)(0);
1010
+ if (new Set(availableLanguages).size === availableLanguages.length) {
1011
+ const activeLanguage = [...availableLanguages].sort((a, z) => preferredLanguages.indexOf(z) - preferredLanguages.indexOf(a))[0];
1012
+ const languageIndex = availableLanguages.indexOf(activeLanguage);
1013
+ const newSelectedIndex = languageIndex === -1 ? selectedIndex : languageIndex;
1014
+ if (newSelectedIndex !== selectedIndex) setSelectedIndex(newSelectedIndex);
1015
+ }
1016
+ const { positionRef, preventLayoutShift } = usePreventLayoutShift();
1017
+ return {
1018
+ as: "div",
1019
+ ref: positionRef,
1020
+ selectedIndex,
1021
+ onChange: (nextSelectedIndex) => {
1022
+ setSelectedIndex(nextSelectedIndex);
1023
+ preventLayoutShift(() => addPreferredLanguage(availableLanguages[nextSelectedIndex]));
1024
+ }
1025
+ };
1026
+ }
1027
+ var CodeGroupContext = (0, react.createContext)(false);
1028
+ function CodeGroup(arg0) {
1029
+ const { children, title, ...props } = arg0;
1030
+ const t = useBuiltInText();
1031
+ const tabGroupProps = useTabGroupProps(react.Children.map(children, (child) => getPanelTitle({
1032
+ ...(0, react.isValidElement)(child) ? child.props : {},
1033
+ fallbackTitle: t("actions.code")
1034
+ })) ?? []);
1035
+ const hasTabs = react.Children.count(children) > 1;
1036
+ const containerClassName = "clarify-code-group my-6 overflow-hidden rounded-2xl bg-zinc-900 shadow-md dark:ring-1 dark:ring-white/10";
1037
+ const header = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeGroupHeader, {
1038
+ title,
1039
+ selectedIndex: tabGroupProps.selectedIndex,
923
1040
  children
924
1041
  });
1042
+ const panels = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeGroupPanels, {
1043
+ ...props,
1044
+ children
1045
+ });
1046
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeGroupContext.Provider, {
1047
+ value: true,
1048
+ children: hasTabs ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.TabGroup, {
1049
+ ...tabGroupProps,
1050
+ className: containerClassName,
1051
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1052
+ className: "not-prose",
1053
+ children: [header, panels]
1054
+ })
1055
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1056
+ className: containerClassName,
1057
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1058
+ className: "not-prose",
1059
+ children: [header, panels]
1060
+ })
1061
+ })
1062
+ });
925
1063
  }
926
- function useTheme() {
927
- const context = (0, react.useContext)(ThemeContext);
928
- if (!context) throw new Error("[clarify] useTheme must be used within ThemeProvider");
929
- return context;
930
- }
931
- //#endregion
932
- //#region source/components/ThemeToggle.tsx
933
- function SunIcon(props) {
934
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
935
- viewBox: "0 0 20 20",
936
- fill: "none",
937
- "aria-hidden": "true",
1064
+ function Code(arg0) {
1065
+ const { children, ...props } = arg0;
1066
+ if ((0, react.useContext)(CodeGroupContext) && typeof children === "string") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
938
1067
  ...props,
939
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M12.5 10a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0Z" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
940
- strokeLinecap: "round",
941
- d: "M10 5.5v-1M13.182 6.818l.707-.707M14.5 10h1M13.182 13.182l.707.707M10 15.5v-1M6.11 13.889l.708-.707M4.5 10h1M6.11 6.111l.708.707"
942
- })]
1068
+ dangerouslySetInnerHTML: { __html: children }
1069
+ });
1070
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
1071
+ ...props,
1072
+ children
943
1073
  });
944
1074
  }
945
- function MoonIcon(props) {
946
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
947
- viewBox: "0 0 20 20",
948
- fill: "none",
949
- "aria-hidden": "true",
1075
+ function Pre(arg0) {
1076
+ const { children, ...props } = arg0;
1077
+ if ((0, react.useContext)(CodeGroupContext)) return children;
1078
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeGroup, {
950
1079
  ...props,
951
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M15.224 11.724a5.5 5.5 0 0 1-6.949-6.949 5.5 5.5 0 1 0 6.949 6.949Z" })
1080
+ children
952
1081
  });
953
1082
  }
954
- function ThemeToggle() {
955
- const { resolvedTheme, setTheme } = useTheme();
956
- const otherTheme = resolvedTheme === "dark" ? "light" : "dark";
957
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
958
- 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`,
961
- onClick: () => setTheme(otherTheme),
962
- children: [
963
- /* @__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" }),
965
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MoonIcon, { className: "hidden h-5 w-5 stroke-white dark:block" })
966
- ]
1083
+ //#endregion
1084
+ //#region source/components/Collapse.tsx
1085
+ function Collapse(arg0) {
1086
+ const { children, title, summary, defaultOpen = false, className, ...props } = arg0;
1087
+ const [open, setOpen] = (0, react.useState)(defaultOpen);
1088
+ const contentRef = (0, react.useRef)(null);
1089
+ const [maxHeight, setMaxHeight] = (0, react.useState)("0px");
1090
+ const summaryLabel = title ?? summary ?? "Details";
1091
+ const contentId = (0, react.useId)();
1092
+ (0, react.useLayoutEffect)(() => {
1093
+ if (!contentRef.current) return;
1094
+ setMaxHeight(open ? `${contentRef.current.scrollHeight}px` : "0px");
1095
+ }, [open, children]);
1096
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1097
+ className: (0, clsx.default)("clarify-collapse my-6 overflow-hidden rounded-(--clarify-theme-tokens-radius-xl) border border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-surface) shadow-sm dark:border-white/10 dark:bg-zinc-950", className),
1098
+ ...props,
1099
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1100
+ type: "button",
1101
+ className: "flex w-full cursor-pointer items-center justify-between gap-3 px-4 py-3 text-left text-sm font-semibold text-(--clarify-theme-tokens-colors-foreground) transition hover:bg-(--clarify-ui-hover-background) dark:text-white dark:hover:bg-white/5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-(--clarify-theme-tokens-colors-primary) focus-visible:ring-offset-2 focus-visible:ring-offset-(--clarify-theme-tokens-colors-background) dark:focus-visible:ring-offset-zinc-950",
1102
+ "aria-expanded": open,
1103
+ "aria-controls": contentId,
1104
+ onClick: () => setOpen((value) => !value),
1105
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: summaryLabel }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronDown, {
1106
+ className: (0, clsx.default)("h-4 w-4 text-(--clarify-theme-tokens-colors-muted) transition-transform duration-200", open && "rotate-180"),
1107
+ "aria-hidden": "true"
1108
+ })]
1109
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1110
+ id: contentId,
1111
+ className: "overflow-hidden border-t border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-background) transition-[max-height,opacity,transform] duration-200 ease-out dark:border-white/10 dark:bg-zinc-950/95",
1112
+ style: {
1113
+ maxHeight,
1114
+ willChange: "max-height, opacity, transform"
1115
+ },
1116
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1117
+ ref: contentRef,
1118
+ className: (0, clsx.default)("px-4 py-4 text-sm/6 text-(--clarify-theme-tokens-colors-foreground) transition-opacity duration-200 ease-out", open ? "opacity-100 translate-y-0" : "opacity-0 -translate-y-1"),
1119
+ children
1120
+ })
1121
+ })]
967
1122
  });
968
1123
  }
969
1124
  //#endregion
970
- //#region source/components/index.tsx
971
- function ArrowIcon(props) {
972
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
1125
+ //#region source/components/Feedback.tsx
1126
+ function CheckIcon(props) {
1127
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
973
1128
  viewBox: "0 0 20 20",
974
- fill: "none",
975
1129
  "aria-hidden": "true",
976
1130
  ...props,
977
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
978
- stroke: "currentColor",
1131
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
1132
+ cx: "10",
1133
+ cy: "10",
1134
+ r: "10",
1135
+ strokeWidth: "0"
1136
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1137
+ fill: "none",
979
1138
  strokeLinecap: "round",
980
1139
  strokeLinejoin: "round",
981
- d: "m11.5 6.5 3 3.5m0 0-3 3.5m3-3.5h-9"
982
- })
1140
+ strokeWidth: "1.5",
1141
+ d: "m6.75 10.813 2.438 2.437c1.218-4.469 4.062-6.5 4.062-6.5"
1142
+ })]
983
1143
  });
984
1144
  }
985
- 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"
991
- };
992
- function Button(arg0) {
993
- const { variant = "primary", className, children, arrow, ...props } = arg0;
994
- const classes = (0, clsx.default)("clarify-button inline-flex justify-center gap-0.5 overflow-hidden text-sm font-medium transition", buttonVariantStyles[variant], className);
995
- const arrowIcon = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArrowIcon, { className: (0, clsx.default)("mt-0.5 h-5 w-5", variant === "text" && "relative top-px", arrow === "left" && "-ml-1 rotate-180", arrow === "right" && "-mr-1") });
996
- const inner = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
997
- arrow === "left" ? arrowIcon : null,
998
- children,
999
- arrow === "right" ? arrowIcon : null
1000
- ] });
1001
- if (typeof props.href === "undefined") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1002
- className: classes,
1145
+ function FeedbackButton(props) {
1146
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1147
+ type: "submit",
1148
+ className: "clarify-feedback-button px-3 text-sm font-medium text-zinc-600 transition hover:bg-zinc-900/2.5 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-white/5 dark:hover:text-white",
1149
+ ...props
1150
+ });
1151
+ }
1152
+ var FeedbackForm = (0, react.forwardRef)(function FeedbackForm(arg0, ref) {
1153
+ const { onSubmit, className, ...props } = arg0;
1154
+ const t = useBuiltInText();
1155
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
1003
1156
  ...props,
1004
- children: inner
1157
+ ref,
1158
+ onSubmit,
1159
+ className: (0, clsx.default)(className, "clarify-feedback-form absolute inset-0 flex items-center justify-center gap-6 md:justify-start"),
1160
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1161
+ className: "text-sm text-zinc-600 dark:text-zinc-400",
1162
+ children: t("feedback.prompt")
1163
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1164
+ 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",
1165
+ children: [
1166
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FeedbackButton, {
1167
+ "data-response": "yes",
1168
+ children: t("feedback.yes")
1169
+ }),
1170
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "bg-zinc-900/10 dark:bg-white/10" }),
1171
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FeedbackButton, {
1172
+ "data-response": "no",
1173
+ children: t("feedback.no")
1174
+ })
1175
+ ]
1176
+ })]
1005
1177
  });
1006
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
1007
- className: classes,
1178
+ });
1179
+ var FeedbackThanks = (0, react.forwardRef)(function FeedbackThanks(arg0, ref) {
1180
+ const { className, ...props } = arg0;
1181
+ const t = useBuiltInText();
1182
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1008
1183
  ...props,
1009
- children: inner
1184
+ ref,
1185
+ className: (0, clsx.default)(className, "clarify-feedback-thanks absolute inset-0 flex justify-center md:justify-start"),
1186
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1187
+ 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",
1188
+ 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")]
1189
+ })
1190
+ });
1191
+ });
1192
+ function Feedback() {
1193
+ const [submitted, setSubmitted] = (0, react.useState)(false);
1194
+ function onSubmit(event) {
1195
+ event.preventDefault();
1196
+ setSubmitted(true);
1197
+ }
1198
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1199
+ className: "clarify-feedback relative h-8",
1200
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.Transition, {
1201
+ show: !submitted,
1202
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FeedbackForm, {
1203
+ className: "duration-300 data-closed:opacity-0 data-leave:pointer-events-none",
1204
+ onSubmit
1205
+ })
1206
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.Transition, {
1207
+ show: submitted,
1208
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FeedbackThanks, { className: "delay-150 duration-300 data-closed:opacity-0" })
1209
+ })]
1010
1210
  });
1011
1211
  }
1212
+ //#endregion
1213
+ //#region source/components/Tag.tsx
1012
1214
  var tagVariantStyles = {
1013
1215
  small: "",
1014
1216
  medium: "rounded-lg px-1.5 ring-1 ring-inset"
@@ -1031,8 +1233,8 @@ var tagColorStyles = {
1031
1233
  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
1234
  },
1033
1235
  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"
1236
+ small: "text-(--clarify-theme-tokens-colors-muted) dark:text-zinc-500",
1237
+ 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
1238
  }
1037
1239
  };
1038
1240
  var tagValueColorMap = {
@@ -1047,32 +1249,12 @@ function Tag(arg0) {
1047
1249
  const value = typeof children === "string" ? children.toUpperCase() : "";
1048
1250
  const resolvedColor = color ?? tagValueColorMap[value] ?? "emerald";
1049
1251
  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]),
1252
+ className: (0, clsx.default)("clarify-tag font-bold", tagVariantStyles[variant], tagColorStyles[resolvedColor][variant]),
1051
1253
  children
1052
1254
  });
1053
1255
  }
1054
- function Logo(props) {
1055
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
1056
- viewBox: "0 0 99 24",
1057
- "aria-hidden": "true",
1058
- ...props,
1059
- className: (0, clsx.default)("clarify-logo", props.className),
1060
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1061
- className: "fill-emerald-400",
1062
- 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
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1064
- className: "fill-zinc-900 dark:fill-white",
1065
- 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
- })]
1067
- });
1068
- }
1069
- function Prose(arg0) {
1070
- const { as, className, ...props } = arg0;
1071
- 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]"),
1073
- ...props
1074
- });
1075
- }
1256
+ //#endregion
1257
+ //#region source/components/Heading.tsx
1076
1258
  function AnchorIcon(props) {
1077
1259
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
1078
1260
  viewBox: "0 0 20 20",
@@ -1092,7 +1274,7 @@ function Eyebrow(arg0) {
1092
1274
  tag ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tag, { children: tag }) : null,
1093
1275
  tag && label ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "h-0.5 w-0.5 rounded-full bg-zinc-300 dark:bg-zinc-600" }) : null,
1094
1276
  label ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1095
- className: "font-mono text-xs text-zinc-400",
1277
+ className: "text-xs text-zinc-400",
1096
1278
  children: label
1097
1279
  }) : null
1098
1280
  ]
@@ -1113,7 +1295,7 @@ function Anchor(arg0) {
1113
1295
  });
1114
1296
  }
1115
1297
  function Heading(arg0) {
1116
- const { children, tag, label, level, anchor = true, ...props } = arg0;
1298
+ const { children, className, tag, label, level, anchor = true, ...props } = arg0;
1117
1299
  const resolvedLevel = level ?? 2;
1118
1300
  const Component = `h${resolvedLevel}`;
1119
1301
  const ref = (0, react.useRef)(null);
@@ -1140,7 +1322,7 @@ function Heading(arg0) {
1140
1322
  label
1141
1323
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, {
1142
1324
  ref,
1143
- className: (0, clsx.default)("clarify-heading", tag || label ? "mt-2 scroll-mt-32" : "scroll-mt-24"),
1325
+ className: (0, clsx.default)("clarify-heading", tag || label ? "mt-2 scroll-mt-32" : "scroll-mt-24", className),
1144
1326
  ...props,
1145
1327
  children: anchor ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Anchor, {
1146
1328
  id: props.id,
@@ -1149,54 +1331,114 @@ function Heading(arg0) {
1149
1331
  }) : children
1150
1332
  })] });
1151
1333
  }
1152
- function DocShell(arg0) {
1153
- const { title, subtitle, children } = arg0;
1154
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("main", {
1155
- className: "clarify-doc-shell min-h-screen bg-white px-6 py-10 text-zinc-900 dark:bg-zinc-950 dark:text-white md:px-10",
1334
+ //#endregion
1335
+ //#region source/components/Logo.tsx
1336
+ function Logo(props) {
1337
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
1338
+ viewBox: "0 0 99 24",
1339
+ "aria-hidden": "true",
1340
+ ...props,
1341
+ className: (0, clsx.default)("clarify-logo", props.className),
1342
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1343
+ className: "fill-(--clarify-theme-tokens-colors-primary)",
1344
+ 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"
1345
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1346
+ className: "fill-(--clarify-theme-tokens-colors-foreground) dark:fill-white",
1347
+ 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"
1348
+ })]
1349
+ });
1350
+ }
1351
+ //#endregion
1352
+ //#region source/components/patterns.tsx
1353
+ function GridPattern(arg0) {
1354
+ const { width, height, x, y, squares, ...props } = arg0;
1355
+ const patternId = (0, react.useId)();
1356
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
1357
+ "aria-hidden": "true",
1358
+ ...props,
1359
+ children: [
1360
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pattern", {
1361
+ id: patternId,
1362
+ width,
1363
+ height,
1364
+ patternUnits: "userSpaceOnUse",
1365
+ x,
1366
+ y,
1367
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1368
+ d: `M.5 ${height}V.5H${width}`,
1369
+ fill: "none"
1370
+ })
1371
+ }) }),
1372
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
1373
+ width: "100%",
1374
+ height: "100%",
1375
+ strokeWidth: 0,
1376
+ fill: `url(#${patternId})`
1377
+ }),
1378
+ squares ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
1379
+ x,
1380
+ y,
1381
+ className: "overflow-visible",
1382
+ children: squares.map(([squareX, squareY]) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
1383
+ width: width + 1,
1384
+ height: height + 1,
1385
+ x: squareX * width,
1386
+ y: squareY * height,
1387
+ strokeWidth: "0"
1388
+ }, `${squareX}-${squareY}`))
1389
+ }) : null
1390
+ ]
1391
+ });
1392
+ }
1393
+ function HeroPattern() {
1394
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1395
+ className: "absolute inset-0 -z-10 mx-0 max-w-none overflow-hidden",
1156
1396
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1157
- className: "mx-auto max-w-6xl",
1158
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
1159
- className: "mb-10",
1160
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
1161
- className: "text-3xl font-bold tracking-tight md:text-5xl",
1162
- children: title
1163
- }), subtitle ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1164
- className: "mt-3 max-w-2xl text-zinc-600 dark:text-zinc-400",
1165
- children: subtitle
1166
- }) : null]
1167
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Prose, { children })]
1397
+ className: "absolute top-0 left-1/2 -ml-152 h-100 w-325 dark:mask-[linear-gradient(white,transparent)]",
1398
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1399
+ 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",
1400
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GridPattern, {
1401
+ width: 72,
1402
+ height: 56,
1403
+ x: -12,
1404
+ y: 4,
1405
+ squares: [
1406
+ [4, 3],
1407
+ [2, 1],
1408
+ [7, 3],
1409
+ [10, 6]
1410
+ ],
1411
+ className: "absolute inset-x-0 inset-y-[-50%] h-[200%] w-full -skew-y-18 fill-black/40 stroke-black/50 mix-blend-overlay dark:fill-white/2.5 dark:stroke-white/5"
1412
+ })
1413
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
1414
+ viewBox: "0 0 1113 440",
1415
+ "aria-hidden": "true",
1416
+ className: "absolute top-0 left-1/2 -ml-76 w-278.25 fill-white blur-[26px] dark:hidden",
1417
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M.016 439.5s-9.5-300 434-300S882.516 20 882.516 20V0h230.004v439.5H.016Z" })
1418
+ })]
1168
1419
  })
1169
1420
  });
1170
1421
  }
1171
- function ApiEndpointCard(arg0) {
1172
- const { method, path, description, id } = arg0;
1173
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
1174
- id,
1175
- className: "clarify-api-endpoint-card scroll-mt-20 rounded-2xl border border-zinc-900/10 bg-white p-5 shadow-sm dark:border-white/10 dark:bg-zinc-900",
1176
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1177
- className: "flex items-center gap-3",
1178
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tag, { children: method }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
1179
- className: "text-sm font-medium text-zinc-800 dark:text-zinc-200",
1180
- children: path
1181
- })]
1182
- }), description ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1183
- className: "mt-3 text-sm text-zinc-600 dark:text-zinc-400",
1184
- children: description
1185
- }) : null]
1422
+ //#endregion
1423
+ //#region source/components/Prose.tsx
1424
+ function Prose(arg0) {
1425
+ const { as, className, ...props } = arg0;
1426
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(as ?? "div", {
1427
+ 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"),
1428
+ ...props
1186
1429
  });
1187
1430
  }
1188
1431
  //#endregion
1189
- //#region source/shell/Navigation.tsx
1190
- function NavigationIcon(arg0) {
1191
- const { name, className } = arg0;
1192
- if (!name) return null;
1193
- const Icon = lucide_react[name];
1194
- if (!Icon) return null;
1195
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
1196
- className: (0, clsx.default)("shrink-0 stroke-current", className),
1197
- "aria-hidden": "true"
1198
- });
1432
+ //#region source/utils/hash.ts
1433
+ function safeDecodeURIComponent(value) {
1434
+ try {
1435
+ return decodeURIComponent(value);
1436
+ } catch {
1437
+ return value;
1438
+ }
1199
1439
  }
1440
+ //#endregion
1441
+ //#region source/shell/Navigation.tsx
1200
1442
  function useInitialValue(value, condition = true) {
1201
1443
  const [initialValue] = (0, react.useState)(value);
1202
1444
  return condition ? initialValue : value;
@@ -1204,11 +1446,11 @@ function useInitialValue(value, condition = true) {
1204
1446
  function normalizePath(path) {
1205
1447
  return path === "" ? "/" : path;
1206
1448
  }
1207
- function navigationToGroups(navigation) {
1449
+ function navigationToGroups(navigation, defaultTitle) {
1208
1450
  return navigation.map((node) => {
1209
1451
  const children = node.children?.length ? node.children : [node];
1210
1452
  return {
1211
- title: node.children?.length ? node.title : "Documentation",
1453
+ title: node.children?.length ? node.title : defaultTitle,
1212
1454
  icon: node.icon,
1213
1455
  links: children.map((child) => ({
1214
1456
  title: child.title,
@@ -1218,18 +1460,6 @@ function navigationToGroups(navigation) {
1218
1460
  };
1219
1461
  });
1220
1462
  }
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
1463
  var sectionBadgeColorStyles = {
1234
1464
  GET: "text-emerald-500 dark:text-emerald-400",
1235
1465
  POST: "text-sky-500 dark:text-sky-400",
@@ -1243,7 +1473,7 @@ var sectionBadgeColorStyles = {
1243
1473
  function SectionBadge(arg0) {
1244
1474
  const { children } = arg0;
1245
1475
  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"),
1476
+ className: (0, clsx.default)("clarify-navigation-section-badge inline-flex shrink-0 justify-end font-semibold uppercase tracking-wide", sectionBadgeColorStyles[children.toUpperCase()] ?? "clarify-ui-menu-description"),
1247
1477
  children
1248
1478
  });
1249
1479
  }
@@ -1253,9 +1483,12 @@ function NavLink(arg0) {
1253
1483
  if (!isAnchorLink) return;
1254
1484
  const hashIndex = href.indexOf("#");
1255
1485
  if (hashIndex === -1) return;
1256
- const targetId = decodeURIComponent(href.slice(hashIndex + 1));
1486
+ const targetId = safeDecodeURIComponent(href.slice(hashIndex + 1));
1257
1487
  window.requestAnimationFrame(() => {
1258
1488
  document.getElementById(targetId)?.scrollIntoView();
1489
+ window.requestAnimationFrame(() => {
1490
+ window.dispatchEvent(new Event("scroll"));
1491
+ });
1259
1492
  });
1260
1493
  }
1261
1494
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.CloseButton, {
@@ -1263,7 +1496,7 @@ function NavLink(arg0) {
1263
1496
  to: href,
1264
1497
  "aria-current": active ? "page" : void 0,
1265
1498
  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"),
1499
+ 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
1500
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1268
1501
  className: "flex min-w-0 flex-1 items-center gap-2",
1269
1502
  children: [
@@ -1273,7 +1506,7 @@ function NavLink(arg0) {
1273
1506
  }) : null,
1274
1507
  badge ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SectionBadge, { children: badge }) : null,
1275
1508
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1276
- className: "min-w-0 truncate",
1509
+ className: "min-w-0 truncate whitespace-nowrap",
1277
1510
  children
1278
1511
  })
1279
1512
  ]
@@ -1294,18 +1527,32 @@ function VisibleSectionHighlight(arg0) {
1294
1527
  const firstVisibleSectionIndex = Math.max(0, [{ id: "_top" }, ...sections].findIndex((section) => section.id === visibleSections[0]));
1295
1528
  const itemHeight = remToPx(2);
1296
1529
  const height = isPresent ? Math.max(1, visibleSections.length) * itemHeight : itemHeight;
1297
- const top = group.links.findIndex((link) => link.href === pathname) * itemHeight + firstVisibleSectionIndex * itemHeight;
1530
+ const top = group.links.findIndex((link) => isSameRoutePath(link.href, pathname)) * itemHeight + firstVisibleSectionIndex * itemHeight;
1298
1531
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.div, {
1299
- layout: true,
1300
- initial: { opacity: 0 },
1532
+ initial: {
1533
+ opacity: 0,
1534
+ height: 0
1535
+ },
1301
1536
  animate: {
1302
1537
  opacity: 1,
1303
- transition: { delay: .2 }
1538
+ top,
1539
+ height,
1540
+ transition: {
1541
+ duration: .2,
1542
+ ease: "easeOut"
1543
+ }
1544
+ },
1545
+ exit: {
1546
+ opacity: 0,
1547
+ height: 0,
1548
+ transition: {
1549
+ duration: .15,
1550
+ ease: "easeIn"
1551
+ }
1304
1552
  },
1305
- exit: { opacity: 0 },
1306
- className: "absolute inset-x-0 top-0 bg-zinc-800/2.5 will-change-transform dark:bg-white/2.5",
1553
+ className: "clarify-navigation-section-highlight absolute inset-x-0 top-0 will-change-transform",
1307
1554
  style: {
1308
- borderRadius: 8,
1555
+ borderRadius: "var(--clarify-theme-tokens-radius-sm)",
1309
1556
  height,
1310
1557
  top
1311
1558
  }
@@ -1314,32 +1561,43 @@ function VisibleSectionHighlight(arg0) {
1314
1561
  function ActivePageMarker(arg0) {
1315
1562
  const { group, pathname } = arg0;
1316
1563
  const itemHeight = remToPx(2);
1317
- const top = remToPx(.25) + group.links.findIndex((link) => link.href === pathname) * itemHeight;
1564
+ const top = remToPx(.25) + group.links.findIndex((link) => isSameRoutePath(link.href, pathname)) * itemHeight;
1318
1565
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.div, {
1319
- layout: true,
1320
- className: "absolute left-2 h-6 w-px bg-emerald-500",
1321
- initial: { opacity: 0 },
1566
+ className: "absolute left-2 h-6 w-px bg-(--clarify-theme-tokens-colors-primary)",
1567
+ initial: {
1568
+ opacity: 0,
1569
+ top
1570
+ },
1322
1571
  animate: {
1323
1572
  opacity: 1,
1324
- transition: { delay: .2 }
1573
+ top,
1574
+ transition: {
1575
+ duration: .2,
1576
+ ease: "easeOut"
1577
+ }
1578
+ },
1579
+ exit: {
1580
+ opacity: 0,
1581
+ transition: {
1582
+ duration: .15,
1583
+ ease: "easeIn"
1584
+ }
1325
1585
  },
1326
- exit: { opacity: 0 },
1327
1586
  style: { top }
1328
1587
  });
1329
1588
  }
1330
1589
  function NavigationGroup(arg0) {
1331
1590
  const { group, className } = arg0;
1332
1591
  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;
1592
+ const [pathname, sections] = useInitialValue([normalizeRoutePath((0, react_router_dom.useLocation)().pathname), useSectionStore((s) => s.sections)], isInsideMobileNavigation);
1593
+ const isActiveGroup = group.links.findIndex((link) => isSameRoutePath(link.href, pathname)) !== -1;
1335
1594
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
1336
1595
  className: (0, clsx.default)("clarify-navigation-group relative mt-6", className),
1337
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(framer_motion.motion.h2, {
1338
- layout: "position",
1339
- className: "clarify-navigation-group-title flex items-center gap-2 text-xs font-semibold text-zinc-900 dark:text-white",
1596
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("h2", {
1597
+ className: "clarify-navigation-group-title flex items-center gap-2",
1340
1598
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavigationIcon, {
1341
1599
  name: group.icon,
1342
- className: "h-3.5 w-3.5"
1600
+ className: "clarify-navigation-group-title-icon h-3.5 w-3.5"
1343
1601
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: group.title })]
1344
1602
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1345
1603
  className: "relative mt-3 pl-2",
@@ -1351,10 +1609,7 @@ function NavigationGroup(arg0) {
1351
1609
  pathname
1352
1610
  }) : null
1353
1611
  }),
1354
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.div, {
1355
- layout: true,
1356
- className: "absolute inset-y-0 left-2 w-px bg-zinc-900/10 dark:bg-white/5"
1357
- }),
1612
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "absolute inset-y-0 left-2 w-px bg-(--clarify-theme-tokens-colors-border) dark:bg-white/5" }),
1358
1613
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.AnimatePresence, {
1359
1614
  initial: false,
1360
1615
  children: isActiveGroup ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActivePageMarker, {
@@ -1365,38 +1620,39 @@ function NavigationGroup(arg0) {
1365
1620
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
1366
1621
  role: "list",
1367
1622
  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))
1623
+ children: group.links.map((link) => {
1624
+ const active = isSameRoutePath(link.href, pathname);
1625
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
1626
+ className: "relative",
1627
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavLink, {
1628
+ href: link.href,
1629
+ icon: link.icon,
1630
+ active,
1631
+ children: link.title
1632
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.AnimatePresence, {
1633
+ initial: false,
1634
+ children: active && sections.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.ul, {
1635
+ role: "list",
1636
+ initial: { opacity: 0 },
1637
+ animate: {
1638
+ opacity: 1,
1639
+ transition: { delay: .1 }
1640
+ },
1641
+ exit: {
1642
+ opacity: 0,
1643
+ transition: { duration: .15 }
1644
+ },
1645
+ children: sections.map((section) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavLink, {
1646
+ href: `${link.href}#${section.id}`,
1647
+ badge: section.badge,
1648
+ tags: section.tags,
1649
+ isAnchorLink: true,
1650
+ children: section.title
1651
+ }) }, section.id))
1652
+ }) : null
1653
+ })]
1654
+ }, link.href);
1655
+ })
1400
1656
  })
1401
1657
  ]
1402
1658
  })]
@@ -1404,19 +1660,16 @@ function NavigationGroup(arg0) {
1404
1660
  }
1405
1661
  function Navigation(arg0) {
1406
1662
  const { navigation, className } = arg0;
1407
- const groups = navigationToGroups(navigation);
1663
+ const groups = navigationToGroups(navigation, useBuiltInText()("navigation.documentation"));
1408
1664
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("nav", {
1409
1665
  className: (0, clsx.default)("clarify-navigation", className),
1410
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("ul", {
1666
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
1411
1667
  role: "list",
1412
1668
  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, {
1669
+ children: groups.map((group, groupIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavigationGroup, {
1417
1670
  group,
1418
- className: groupIndex === 0 ? "md:mt-0" : ""
1419
- }, group.title))]
1671
+ className: groupIndex === 0 ? "mt-0" : ""
1672
+ }, group.title))
1420
1673
  })
1421
1674
  });
1422
1675
  }
@@ -1443,8 +1696,84 @@ function XIcon(props) {
1443
1696
  });
1444
1697
  }
1445
1698
  var IsInsideMobileNavigationContext = (0, react.createContext)(false);
1699
+ function hasPath$1(nodes, pathname) {
1700
+ return nodes.some((node) => isSameRoutePath(node.path, pathname) || hasPath$1(node.children ?? [], pathname));
1701
+ }
1702
+ function isActiveTab$1(tab, pathname) {
1703
+ return isSameRoutePath(tab.path, pathname) || hasPath$1(tab.children, pathname);
1704
+ }
1705
+ function MobileTabsSelect(arg0) {
1706
+ const { tabs } = arg0;
1707
+ const pathname = normalizeRoutePath((0, react_router_dom.useLocation)().pathname);
1708
+ const { close } = useMobileNavigationStore();
1709
+ if (!tabs?.length) return null;
1710
+ const activeTab = tabs.find((tab) => isActiveTab$1(tab, pathname)) ?? tabs[0];
1711
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.Menu, {
1712
+ as: "div",
1713
+ className: "clarify-mobile-tabs-select mb-6",
1714
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.MenuButton, {
1715
+ 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",
1716
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1717
+ className: "flex min-w-0 items-center gap-2",
1718
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavigationIcon, {
1719
+ name: activeTab.icon,
1720
+ className: "h-4 w-4 shrink-0 text-(--clarify-theme-tokens-colors-primary)"
1721
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1722
+ className: "truncate",
1723
+ children: activeTab.title
1724
+ })]
1725
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
1726
+ width: "8",
1727
+ height: "24",
1728
+ viewBox: "0 -9 3 24",
1729
+ "aria-hidden": "true",
1730
+ className: "shrink-0 overflow-visible text-(--clarify-theme-tokens-colors-muted) transition-transform group-aria-expanded:rotate-180",
1731
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1732
+ d: "M0 0L3 3L0 6",
1733
+ fill: "none",
1734
+ stroke: "currentColor",
1735
+ strokeWidth: "1.5",
1736
+ strokeLinecap: "round"
1737
+ })
1738
+ })]
1739
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItems, {
1740
+ 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",
1741
+ children: tabs.map((tab) => {
1742
+ const active = isActiveTab$1(tab, pathname);
1743
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_router_dom.Link, {
1744
+ to: tab.path,
1745
+ onClick: close,
1746
+ 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"),
1747
+ "aria-current": active ? "page" : void 0,
1748
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1749
+ className: "flex min-w-0 items-start gap-2",
1750
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavigationIcon, {
1751
+ name: tab.icon,
1752
+ className: "mt-0.5 h-4 w-4 shrink-0"
1753
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1754
+ className: "min-w-0 whitespace-normal wrap-anywhere font-medium leading-5",
1755
+ children: tab.title
1756
+ })]
1757
+ }), active ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
1758
+ viewBox: "0 0 20 20",
1759
+ fill: "none",
1760
+ "aria-hidden": "true",
1761
+ className: "mt-0.5 h-4 w-4 shrink-0",
1762
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1763
+ d: "m5 10 3 3 7-7",
1764
+ stroke: "currentColor",
1765
+ strokeWidth: "1.8",
1766
+ strokeLinecap: "round",
1767
+ strokeLinejoin: "round"
1768
+ })
1769
+ }) : null]
1770
+ }) }, `${tab.title}-${tab.path}`);
1771
+ })
1772
+ })]
1773
+ });
1774
+ }
1446
1775
  function MobileNavigationDialog(arg0) {
1447
- const { config, isOpen, navigation, routes, currentLocale, currentRoute, close } = arg0;
1776
+ const { config, isOpen, navigation, tabs, routes, currentLocale, currentRoute, close } = arg0;
1448
1777
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.Dialog, {
1449
1778
  transition: true,
1450
1779
  open: isOpen,
@@ -1452,18 +1781,19 @@ function MobileNavigationDialog(arg0) {
1452
1781
  className: "clarify-mobile-navigation-dialog fixed inset-0 z-50 lg:hidden",
1453
1782
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.DialogBackdrop, {
1454
1783
  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"
1784
+ 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
1785
  }), /* @__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
1786
  config,
1458
1787
  navigation,
1788
+ tabs,
1459
1789
  routes,
1460
1790
  currentLocale,
1461
1791
  currentRoute,
1462
1792
  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, {
1793
+ }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.TransitionChild, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(framer_motion.motion.div, {
1464
1794
  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 })
1795
+ 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",
1796
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MobileTabsSelect, { tabs }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Navigation, { navigation })]
1467
1797
  }) })] })]
1468
1798
  });
1469
1799
  }
@@ -1477,23 +1807,25 @@ var useMobileNavigationStore = (0, zustand.create)()((set) => ({
1477
1807
  toggle: () => set((state) => ({ isOpen: !state.isOpen }))
1478
1808
  }));
1479
1809
  function MobileNavigation(arg0) {
1480
- const { config, navigation, routes, currentLocale, currentRoute } = arg0;
1810
+ const { config, navigation, tabs, routes, currentLocale, currentRoute } = arg0;
1481
1811
  const isInsideMobileNavigation = useIsInsideMobileNavigation();
1482
1812
  const { isOpen, toggle, close } = useMobileNavigationStore();
1813
+ const t = useBuiltInText();
1483
1814
  const ToggleIcon = isOpen ? XIcon : MenuIcon;
1484
1815
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(IsInsideMobileNavigationContext.Provider, {
1485
1816
  value: true,
1486
1817
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1487
1818
  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",
1819
+ className: "clarify-mobile-navigation-button clarify-ui-icon-button relative flex size-6 items-center justify-center rounded-(--clarify-theme-tokens-radius-md) transition",
1820
+ "aria-label": t("navigation.toggle"),
1490
1821
  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" })]
1822
+ 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
1823
  }), !isInsideMobileNavigation ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Suspense, {
1493
1824
  fallback: null,
1494
1825
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MobileNavigationDialog, {
1495
1826
  config,
1496
1827
  navigation,
1828
+ tabs,
1497
1829
  routes,
1498
1830
  currentLocale,
1499
1831
  currentRoute,
@@ -1574,7 +1906,7 @@ function HighlightQuery(arg0) {
1574
1906
  const { text, query } = arg0;
1575
1907
  if (!query) return text;
1576
1908
  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",
1909
+ className: "bg-transparent text-(--clarify-theme-tokens-colors-primary) underline",
1578
1910
  children: part
1579
1911
  }, index) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: part }, index)) });
1580
1912
  }
@@ -1584,25 +1916,25 @@ function SearchResult(arg0) {
1584
1916
  const hierarchy = [result.sectionTitle, result.pageTitle].filter((value) => typeof value === "string");
1585
1917
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
1586
1918
  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"),
1919
+ className: (0, clsx.default)("clarify-search-result group block cursor-default px-4 py-3", active && "clarify-search-result-active"),
1588
1920
  "aria-selected": active,
1589
1921
  onMouseDown: (event) => {
1590
1922
  event.preventDefault();
1591
1923
  onSelect();
1592
1924
  },
1593
1925
  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",
1926
+ className: "clarify-search-result-title",
1595
1927
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HighlightQuery, {
1596
1928
  text: result.title,
1597
1929
  query
1598
1930
  })
1599
1931
  }), hierarchy.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1600
- className: "mt-1 truncate text-2xs whitespace-nowrap text-zinc-500",
1932
+ className: "clarify-search-result-hierarchy mt-1 truncate whitespace-nowrap",
1601
1933
  children: hierarchy.map((item, itemIndex, items) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(HighlightQuery, {
1602
1934
  text: item,
1603
1935
  query
1604
1936
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1605
- className: itemIndex === items.length - 1 ? "sr-only" : "mx-2 text-zinc-300 dark:text-zinc-700",
1937
+ className: itemIndex === items.length - 1 ? "sr-only" : "clarify-search-result-separator mx-2",
1606
1938
  children: "/"
1607
1939
  })] }, `${item}-${itemIndex}`))
1608
1940
  }) : null]
@@ -1610,9 +1942,10 @@ function SearchResult(arg0) {
1610
1942
  }
1611
1943
  var SearchInput = (0, react.forwardRef)(function SearchInput(arg0, inputRef) {
1612
1944
  const { query, setQuery, onClose, onSubmit, activeDescendantId } = arg0;
1945
+ const t = useBuiltInText();
1613
1946
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1614
1947
  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", {
1948
+ 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
1949
  ref: inputRef,
1617
1950
  "data-autofocus": true,
1618
1951
  role: "combobox",
@@ -1629,13 +1962,14 @@ var SearchInput = (0, react.forwardRef)(function SearchInput(arg0, inputRef) {
1629
1962
  onSubmit();
1630
1963
  }
1631
1964
  },
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"
1965
+ placeholder: t("search.placeholder"),
1966
+ 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
1967
  })]
1635
1968
  });
1636
1969
  });
1637
1970
  function SearchDialog(arg0) {
1638
1971
  const { open, setOpen, routes, navigation, className, onNavigate = () => {} } = arg0;
1972
+ const t = useBuiltInText();
1639
1973
  const navigate = (0, react_router_dom.useNavigate)();
1640
1974
  const location = (0, react_router_dom.useLocation)();
1641
1975
  const inputRef = (0, react.useRef)(null);
@@ -1686,12 +2020,12 @@ function SearchDialog(arg0) {
1686
2020
  className: (0, clsx.default)("clarify-search-dialog fixed inset-0 z-50", className),
1687
2021
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.DialogBackdrop, {
1688
2022
  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"
2023
+ 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
2024
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1691
2025
  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
2026
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.DialogPanel, {
1693
2027
  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",
2028
+ 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
2029
  onKeyDown: (event) => {
1696
2030
  if (event.key === "ArrowDown") {
1697
2031
  event.preventDefault();
@@ -1709,24 +2043,12 @@ function SearchDialog(arg0) {
1709
2043
  onClose: closeDialog,
1710
2044
  onSubmit: () => selectResult()
1711
2045
  }), /* @__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",
2046
+ 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
2047
  children: [query && results.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1714
2048
  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
- ]
2049
+ 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", {
2050
+ className: "mt-2 text-xs text-(--clarify-theme-tokens-colors-muted) dark:text-zinc-400",
2051
+ children: t("search.noResults", { query })
1730
2052
  })]
1731
2053
  }) : null, results.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
1732
2054
  id: "clarify-search-results",
@@ -1766,19 +2088,20 @@ function getModifierKey() {
1766
2088
  }
1767
2089
  function Search(arg0) {
1768
2090
  const { routes, navigation } = arg0;
2091
+ const t = useBuiltInText();
1769
2092
  const modifierKey = getModifierKey();
1770
2093
  const { buttonProps, dialogProps } = useSearchProps();
1771
2094
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1772
- className: "clarify-search hidden lg:block lg:max-w-md lg:flex-auto",
2095
+ className: "clarify-search hidden w-80 max-w-[36vw] lg:block",
1773
2096
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1774
2097
  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",
2098
+ 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
2099
  ...buttonProps,
1777
2100
  children: [
1778
2101
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchIcon, { className: "h-5 w-5 stroke-current" }),
1779
- "Find something...",
2102
+ t("search.button"),
1780
2103
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("kbd", {
1781
- className: "ml-auto text-2xs text-zinc-400 dark:text-zinc-500",
2104
+ 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
2105
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("kbd", {
1783
2106
  className: "font-sans",
1784
2107
  children: modifierKey
@@ -1801,15 +2124,16 @@ function Search(arg0) {
1801
2124
  }
1802
2125
  function MobileSearch(arg0) {
1803
2126
  const { routes, navigation, onNavigate } = arg0;
2127
+ const t = useBuiltInText();
1804
2128
  const { buttonProps, dialogProps } = useSearchProps();
1805
2129
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1806
2130
  className: "clarify-mobile-search contents lg:hidden",
1807
2131
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1808
2132
  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...",
2133
+ 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",
2134
+ "aria-label": t("search.placeholder"),
1811
2135
  ...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" })]
2136
+ 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
2137
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Suspense, {
1814
2138
  fallback: null,
1815
2139
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchDialog, {
@@ -1823,20 +2147,39 @@ function MobileSearch(arg0) {
1823
2147
  });
1824
2148
  }
1825
2149
  //#endregion
2150
+ //#region source/shell/SiteLogo.tsx
2151
+ function SiteLogo(arg0) {
2152
+ const { logo, className } = arg0;
2153
+ if (!logo) return null;
2154
+ if (typeof logo === "string") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
2155
+ src: logo,
2156
+ alt: "",
2157
+ className: (0, clsx.default)("clarify-logo", className)
2158
+ });
2159
+ const lightLogo = logo.light ?? logo.dark;
2160
+ const darkLogo = logo.dark ?? logo.light;
2161
+ if (!lightLogo || !darkLogo) return null;
2162
+ if (lightLogo === darkLogo) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
2163
+ src: lightLogo,
2164
+ alt: "",
2165
+ className: (0, clsx.default)("clarify-logo", className)
2166
+ });
2167
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
2168
+ src: lightLogo,
2169
+ alt: "",
2170
+ className: (0, clsx.default)("clarify-logo clarify-logo-light", className, "dark:hidden")
2171
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
2172
+ src: darkLogo,
2173
+ alt: "",
2174
+ className: (0, clsx.default)("clarify-logo clarify-logo-dark", className, "hidden dark:block")
2175
+ })] });
2176
+ }
2177
+ //#endregion
1826
2178
  //#region source/shell/Header.tsx
1827
2179
  function resolveLocalizedText(text, locale, fallbackLocale) {
1828
2180
  if (typeof text === "string") return text;
1829
2181
  return (locale ? text[locale] : void 0) ?? (fallbackLocale ? text[fallbackLocale] : void 0) ?? Object.values(text)[0] ?? "";
1830
2182
  }
1831
- function isExternalHref(href) {
1832
- return /^[a-z][a-z0-9+.-]*:/i.test(href) || href.startsWith("//");
1833
- }
1834
- function localizeHref(href, config, locale) {
1835
- if (!locale || !config.i18n || isExternalHref(href) || href.startsWith("#")) return href;
1836
- if (locale === config.i18n.defaultLocale) return href;
1837
- const cleanHref = href === "/" ? "" : href.replace(/^\/+/, "");
1838
- return `/${locale}${cleanHref ? `/${cleanHref}` : ""}`;
1839
- }
1840
2183
  function localizedRoutePath(config, locale, route) {
1841
2184
  const alternatePath = route?.alternates?.[locale];
1842
2185
  if (alternatePath) return alternatePath;
@@ -1854,6 +2197,7 @@ function LanguageIcon(props) {
1854
2197
  }
1855
2198
  function LanguageSwitcher(arg0) {
1856
2199
  const { config, currentLocale, currentRoute } = arg0;
2200
+ const t = useBuiltInText();
1857
2201
  const location = (0, react_router_dom.useLocation)();
1858
2202
  const i18n = config.i18n;
1859
2203
  if (!i18n || i18n.locales.length < 2) return null;
@@ -1864,8 +2208,8 @@ function LanguageSwitcher(arg0) {
1864
2208
  as: "div",
1865
2209
  className: "clarify-language-switcher relative",
1866
2210
  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",
2211
+ 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",
2212
+ "aria-label": t("language.switch"),
1869
2213
  children: [
1870
2214
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "absolute size-12 pointer-fine:hidden" }),
1871
2215
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LanguageIcon, { className: "h-5 w-5 stroke-current" }),
@@ -1876,19 +2220,19 @@ function LanguageSwitcher(arg0) {
1876
2220
  ]
1877
2221
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItems, {
1878
2222
  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",
2223
+ 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
2224
  children: i18n.locales.flatMap((locale) => {
1881
2225
  const localizedPath = localizedRoutePath(config, locale.code, currentRoute);
1882
2226
  if (!localizedPath) return [];
1883
2227
  const selected = locale.code === selectedLocale;
1884
2228
  return [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItem, { children: ({ focus }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_router_dom.Link, {
1885
2229
  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"),
2230
+ 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
2231
  "aria-current": selected ? "true" : void 0,
1888
2232
  lang: locale.code,
1889
2233
  dir: locale.dir,
1890
2234
  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",
2235
+ className: "clarify-ui-menu-code",
1892
2236
  children: locale.code
1893
2237
  })]
1894
2238
  }) }, locale.code)];
@@ -1900,217 +2244,186 @@ function TopLevelNavItem(arg0) {
1900
2244
  const { href, children } = arg0;
1901
2245
  if (isExternalHref(href)) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
1902
2246
  href,
1903
- className: "text-sm/5 text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white",
2247
+ className: "clarify-ui-top-link transition",
1904
2248
  target: "_blank",
1905
2249
  rel: "noreferrer",
1906
2250
  children
1907
2251
  }) });
1908
2252
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_router_dom.Link, {
1909
2253
  to: href,
1910
- className: "text-sm/5 text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white",
2254
+ className: "clarify-ui-top-link transition",
1911
2255
  children
1912
2256
  }) });
1913
2257
  }
2258
+ function MobileNavbarMenu(arg0) {
2259
+ const { links, config, currentLocale } = arg0;
2260
+ const t = useBuiltInText();
2261
+ if (!links?.length) return null;
2262
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.Menu, {
2263
+ as: "div",
2264
+ className: "clarify-mobile-navbar-menu relative md:hidden",
2265
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.MenuButton, {
2266
+ className: "clarify-mobile-navbar-menu-button clarify-ui-control relative flex size-8 items-center justify-center rounded-(--clarify-theme-tokens-radius-md) transition",
2267
+ "aria-label": t("navbar.openLinks"),
2268
+ 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" })]
2269
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItems, {
2270
+ transition: true,
2271
+ anchor: "bottom end",
2272
+ 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",
2273
+ children: links.map((link) => {
2274
+ const label = resolveLocalizedText(link.label, currentLocale, config.i18n?.defaultLocale);
2275
+ const href = localizeHref(link.href, config, currentLocale);
2276
+ const external = isExternalHref(href);
2277
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.MenuItem, { children: ({ focus }) => {
2278
+ 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");
2279
+ return external ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
2280
+ href,
2281
+ target: "_blank",
2282
+ rel: "noreferrer",
2283
+ className,
2284
+ children: label
2285
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_router_dom.Link, {
2286
+ to: href,
2287
+ className,
2288
+ children: label
2289
+ });
2290
+ } }, link.href);
2291
+ })
2292
+ })]
2293
+ });
2294
+ }
2295
+ function hasPath(nodes, pathname) {
2296
+ return nodes.some((node) => isSameRoutePath(node.path, pathname) || hasPath(node.children ?? [], pathname));
2297
+ }
2298
+ function isActiveTab(tab, pathname) {
2299
+ return isSameRoutePath(tab.path, pathname) || hasPath(tab.children, pathname);
2300
+ }
2301
+ function ProductTabs(arg0) {
2302
+ const { tabs } = arg0;
2303
+ const t = useBuiltInText();
2304
+ const pathname = normalizeRoutePath((0, react_router_dom.useLocation)().pathname);
2305
+ if (!tabs?.length) return null;
2306
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2307
+ className: "clarify-product-tabs hidden h-14 border-t border-(--clarify-theme-tokens-colors-border) lg:block dark:border-white/10",
2308
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("nav", {
2309
+ 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",
2310
+ "aria-label": t("navbar.sections"),
2311
+ children: tabs.map((tab) => {
2312
+ const active = isActiveTab(tab, pathname);
2313
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_router_dom.Link, {
2314
+ to: tab.path,
2315
+ "aria-current": active ? "page" : void 0,
2316
+ className: (0, clsx.default)("clarify-product-tab clarify-ui-tab relative inline-flex h-full shrink-0 items-center gap-2 px-0 transition", active && "clarify-ui-tab-active"),
2317
+ children: [
2318
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavigationIcon, {
2319
+ name: tab.icon,
2320
+ className: "h-4 w-4"
2321
+ }),
2322
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tab.title }),
2323
+ active ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.span, {
2324
+ layoutId: "clarify-product-tab-indicator",
2325
+ className: "absolute inset-x-0 bottom-0 h-0.5 rounded-full bg-(--clarify-theme-tokens-colors-foreground) dark:bg-white",
2326
+ transition: {
2327
+ type: "tween",
2328
+ duration: .16,
2329
+ ease: "easeOut"
2330
+ }
2331
+ }) : null
2332
+ ]
2333
+ }, `${tab.title}-${tab.path}`);
2334
+ })
2335
+ })
2336
+ });
2337
+ }
1914
2338
  var Header = (0, react.forwardRef)(function Header(arg0, ref) {
1915
- const { config, navigation, routes, currentLocale, currentRoute, className, ...props } = arg0;
2339
+ const { config, navigation, tabs, routes, currentLocale, currentRoute, className, ...props } = arg0;
2340
+ const t = useBuiltInText();
1916
2341
  const { isOpen: mobileNavIsOpen } = useMobileNavigationStore();
1917
2342
  const isInsideMobileNavigation = useIsInsideMobileNavigation();
1918
2343
  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, {
2344
+ const bgOpacityLight = (0, framer_motion.useTransform)(scrollY, [0, 72], ["70%", "95%"]);
2345
+ const bgOpacityDark = (0, framer_motion.useTransform)(scrollY, [0, 72], ["60%", "92%"]);
2346
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(framer_motion.motion.header, {
1922
2347
  ...props,
1923
2348
  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)"),
2349
+ 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
2350
  style: {
1926
2351
  "--bg-opacity-light": bgOpacityLight,
1927
2352
  "--bg-opacity-dark": bgOpacityDark
1928
2353
  },
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
1951
- })]
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, {
1958
- routes,
1959
- 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))
2354
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2355
+ 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"),
2356
+ children: [
2357
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2358
+ className: "clarify-header-left flex min-w-0 items-center gap-5",
2359
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2360
+ className: "clarify-mobile-brand flex items-center gap-5 lg:hidden",
2361
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MobileNavigation, {
2362
+ config,
2363
+ navigation,
2364
+ tabs,
2365
+ routes,
2366
+ currentLocale,
2367
+ currentRoute
1970
2368
  })
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, {
2369
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.CloseButton, {
2370
+ as: react_router_dom.Link,
2371
+ to: localizeHref("/", config, currentLocale),
2372
+ "aria-label": t("navbar.home"),
2373
+ className: "clarify-brand flex min-w-0 items-center gap-2 no-underline",
2374
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SiteLogo, {
2375
+ logo: config.logo,
2376
+ className: "h-6 w-6 shrink-0"
2377
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2378
+ className: "clarify-brand-title truncate font-semibold",
2379
+ children: config.title
2380
+ })]
2381
+ })]
2382
+ }),
2383
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2384
+ className: "clarify-header-center absolute left-1/2 hidden -translate-x-1/2 lg:block",
2385
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Search, {
1974
2386
  routes,
1975
2387
  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
- ]
1986
- });
1987
- });
1988
- //#endregion
1989
- //#region source/app/AppShell.tsx
1990
- function routeForPath(routes, pathname) {
1991
- return routes.find((route) => route.path === pathname || `/${route.path}` === pathname);
1992
- }
1993
- function sectionsForRoute(route) {
1994
- return route?.sections?.map((section) => ({
1995
- id: section.id,
1996
- title: section.title,
1997
- badge: section.badge,
1998
- tags: section.tags
1999
- })) ?? [];
2000
- }
2001
- function scrollToHash(hash) {
2002
- if (!hash) return;
2003
- const targetId = decodeURIComponent(hash.slice(1));
2004
- window.requestAnimationFrame(() => {
2005
- document.getElementById(targetId)?.scrollIntoView();
2006
- });
2007
- }
2008
- function localeForPath(config, pathname, route) {
2009
- if (route?.locale) return route.locale;
2010
- const i18n = config.i18n;
2011
- if (!i18n) return void 0;
2012
- const firstSegment = pathname.split("/").filter(Boolean)[0];
2013
- return i18n.locales.find((locale) => locale.code === firstSegment)?.code ?? i18n.defaultLocale;
2014
- }
2015
- function navigationForLocale(navigation, locale) {
2016
- if (Array.isArray(navigation)) return navigation;
2017
- if (!locale) return [];
2018
- return navigation[locale] ?? [];
2019
- }
2020
- function homePathForLocale(config, locale) {
2021
- if (!locale || !config.i18n || locale === config.i18n.defaultLocale) return "/";
2022
- return `/${locale}`;
2023
- }
2024
- function AppShell(arg0) {
2025
- const { config, routes, navigation } = arg0;
2026
- const location = (0, react_router_dom.useLocation)();
2027
- const currentRoute = routeForPath(routes, location.pathname);
2028
- const currentLocale = localeForPath(config, location.pathname, currentRoute);
2029
- const currentLocaleConfig = config.i18n?.locales.find((locale) => locale.code === currentLocale);
2030
- const currentNavigation = navigationForLocale(navigation, currentLocale);
2031
- const sections = sectionsForRoute(currentRoute);
2032
- (0, react.useEffect)(() => {
2033
- scrollToHash(location.hash);
2034
- }, [location.hash, location.pathname]);
2035
- (0, react.useEffect)(() => {
2036
- if (!currentLocale) return;
2037
- document.documentElement.lang = currentLocale;
2038
- if (currentLocaleConfig?.dir) document.documentElement.dir = currentLocaleConfig.dir;
2039
- else document.documentElement.removeAttribute("dir");
2040
- }, [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",
2388
+ })
2389
+ }),
2390
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2391
+ className: "clarify-header-actions flex shrink-0 items-center gap-5",
2050
2392
  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
- })]
2393
+ config.navbar?.links?.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("nav", {
2394
+ className: "clarify-top-nav hidden md:block",
2395
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
2396
+ role: "list",
2397
+ className: "flex items-center gap-8",
2398
+ children: config.navbar.links.map((link) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TopLevelNavItem, {
2399
+ href: localizeHref(link.href, config, currentLocale),
2400
+ children: resolveLocalizedText(link.label, currentLocale, config.i18n?.defaultLocale)
2401
+ }, link.href))
2064
2402
  })
2403
+ }) : null,
2404
+ 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,
2405
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MobileSearch, {
2406
+ routes,
2407
+ navigation
2065
2408
  }),
2066
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Header, {
2409
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LanguageSwitcher, {
2067
2410
  config,
2068
- navigation: currentNavigation,
2069
- routes,
2070
2411
  currentLocale,
2071
2412
  currentRoute
2072
2413
  }),
2073
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Navigation, {
2074
- navigation: currentNavigation,
2075
- className: "clarify-navigation hidden lg:mt-10 lg:block"
2414
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThemeToggle, {}),
2415
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MobileNavbarMenu, {
2416
+ links: config.navbar?.links,
2417
+ config,
2418
+ currentLocale
2076
2419
  })
2077
2420
  ]
2078
2421
  })
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
- })]
2092
- })
2422
+ ]
2423
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProductTabs, { tabs })]
2093
2424
  });
2094
- }
2095
- //#endregion
2096
- Object.defineProperty(exports, "ApiEndpointCard", {
2097
- enumerable: true,
2098
- get: function() {
2099
- return ApiEndpointCard;
2100
- }
2101
- });
2102
- Object.defineProperty(exports, "AppShell", {
2103
- enumerable: true,
2104
- get: function() {
2105
- return AppShell;
2106
- }
2107
- });
2108
- Object.defineProperty(exports, "BuiltWithClarify", {
2109
- enumerable: true,
2110
- get: function() {
2111
- return BuiltWithClarify;
2112
- }
2113
2425
  });
2426
+ //#endregion
2114
2427
  Object.defineProperty(exports, "Button", {
2115
2428
  enumerable: true,
2116
2429
  get: function() {
@@ -2141,6 +2454,12 @@ Object.defineProperty(exports, "ClarifyConfigContext", {
2141
2454
  return ClarifyConfigContext;
2142
2455
  }
2143
2456
  });
2457
+ Object.defineProperty(exports, "ClarifyLocaleContext", {
2458
+ enumerable: true,
2459
+ get: function() {
2460
+ return ClarifyLocaleContext;
2461
+ }
2462
+ });
2144
2463
  Object.defineProperty(exports, "Code", {
2145
2464
  enumerable: true,
2146
2465
  get: function() {
@@ -2153,10 +2472,16 @@ Object.defineProperty(exports, "CodeGroup", {
2153
2472
  return CodeGroup;
2154
2473
  }
2155
2474
  });
2156
- Object.defineProperty(exports, "DocShell", {
2475
+ Object.defineProperty(exports, "Collapse", {
2476
+ enumerable: true,
2477
+ get: function() {
2478
+ return Collapse;
2479
+ }
2480
+ });
2481
+ Object.defineProperty(exports, "ContentActions", {
2157
2482
  enumerable: true,
2158
2483
  get: function() {
2159
- return DocShell;
2484
+ return ContentActions;
2160
2485
  }
2161
2486
  });
2162
2487
  Object.defineProperty(exports, "Feedback", {
@@ -2171,6 +2496,12 @@ Object.defineProperty(exports, "GridPattern", {
2171
2496
  return GridPattern;
2172
2497
  }
2173
2498
  });
2499
+ Object.defineProperty(exports, "Header", {
2500
+ enumerable: true,
2501
+ get: function() {
2502
+ return Header;
2503
+ }
2504
+ });
2174
2505
  Object.defineProperty(exports, "Heading", {
2175
2506
  enumerable: true,
2176
2507
  get: function() {
@@ -2189,16 +2520,16 @@ Object.defineProperty(exports, "Logo", {
2189
2520
  return Logo;
2190
2521
  }
2191
2522
  });
2192
- Object.defineProperty(exports, "OpenApisContext", {
2523
+ Object.defineProperty(exports, "Navigation", {
2193
2524
  enumerable: true,
2194
2525
  get: function() {
2195
- return OpenApisContext;
2526
+ return Navigation;
2196
2527
  }
2197
2528
  });
2198
- Object.defineProperty(exports, "PageFooter", {
2529
+ Object.defineProperty(exports, "OpenApisContext", {
2199
2530
  enumerable: true,
2200
2531
  get: function() {
2201
- return PageFooter;
2532
+ return OpenApisContext;
2202
2533
  }
2203
2534
  });
2204
2535
  Object.defineProperty(exports, "Pre", {
@@ -2237,16 +2568,40 @@ Object.defineProperty(exports, "ThemeToggle", {
2237
2568
  return ThemeToggle;
2238
2569
  }
2239
2570
  });
2240
- Object.defineProperty(exports, "__exportAll", {
2571
+ Object.defineProperty(exports, "copyTextToClipboard", {
2572
+ enumerable: true,
2573
+ get: function() {
2574
+ return copyTextToClipboard;
2575
+ }
2576
+ });
2577
+ Object.defineProperty(exports, "isExternalHref", {
2578
+ enumerable: true,
2579
+ get: function() {
2580
+ return isExternalHref;
2581
+ }
2582
+ });
2583
+ Object.defineProperty(exports, "isSameRoutePath", {
2241
2584
  enumerable: true,
2242
2585
  get: function() {
2243
- return __exportAll;
2586
+ return isSameRoutePath;
2244
2587
  }
2245
2588
  });
2246
- Object.defineProperty(exports, "__toESM", {
2589
+ Object.defineProperty(exports, "localizeHref", {
2247
2590
  enumerable: true,
2248
2591
  get: function() {
2249
- return __toESM;
2592
+ return localizeHref;
2593
+ }
2594
+ });
2595
+ Object.defineProperty(exports, "normalizeRoutePath", {
2596
+ enumerable: true,
2597
+ get: function() {
2598
+ return normalizeRoutePath;
2599
+ }
2600
+ });
2601
+ Object.defineProperty(exports, "prefixHref", {
2602
+ enumerable: true,
2603
+ get: function() {
2604
+ return prefixHref;
2250
2605
  }
2251
2606
  });
2252
2607
  Object.defineProperty(exports, "remToPx", {
@@ -2255,6 +2610,18 @@ Object.defineProperty(exports, "remToPx", {
2255
2610
  return remToPx;
2256
2611
  }
2257
2612
  });
2613
+ Object.defineProperty(exports, "safeDecodeURIComponent", {
2614
+ enumerable: true,
2615
+ get: function() {
2616
+ return safeDecodeURIComponent;
2617
+ }
2618
+ });
2619
+ Object.defineProperty(exports, "useBuiltInText", {
2620
+ enumerable: true,
2621
+ get: function() {
2622
+ return useBuiltInText;
2623
+ }
2624
+ });
2258
2625
  Object.defineProperty(exports, "useClarifyConfig", {
2259
2626
  enumerable: true,
2260
2627
  get: function() {
@@ -2280,4 +2647,4 @@ Object.defineProperty(exports, "useTheme", {
2280
2647
  }
2281
2648
  });
2282
2649
 
2283
- //# sourceMappingURL=AppShell-4KB3lU-n.cjs.map
2650
+ //# sourceMappingURL=shell-_MyLsMUI.cjs.map