@caffeinebounce/ui 0.62.2

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 (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +39 -0
  3. package/dist/FinancialStatementTable-BNUrdTU4.d.cts +249 -0
  4. package/dist/FinancialStatementTable-BNUrdTU4.d.ts +249 -0
  5. package/dist/NewsletterSignup-BPreFi5W.d.cts +37 -0
  6. package/dist/NewsletterSignup-BPreFi5W.d.ts +37 -0
  7. package/dist/TestimonialsSection-DtPu2OeR.d.ts +736 -0
  8. package/dist/TestimonialsSection-z-yotRfv.d.cts +736 -0
  9. package/dist/UnifiedTableControls-CG299y9h.d.ts +1233 -0
  10. package/dist/UnifiedTableControls-CIjRpNhy.d.cts +1233 -0
  11. package/dist/blog.d.cts +99 -0
  12. package/dist/blog.d.ts +99 -0
  13. package/dist/blog.js +292 -0
  14. package/dist/blog.mjs +279 -0
  15. package/dist/button-BHnoRUkF.d.cts +34 -0
  16. package/dist/button-BHnoRUkF.d.ts +34 -0
  17. package/dist/charts.d.cts +80 -0
  18. package/dist/charts.d.ts +80 -0
  19. package/dist/charts.js +19 -0
  20. package/dist/charts.mjs +2 -0
  21. package/dist/chunk-33JR5SYE.js +44 -0
  22. package/dist/chunk-3NDB4YPC.js +247 -0
  23. package/dist/chunk-5RW4PYZ6.js +1504 -0
  24. package/dist/chunk-5THF4YP6.mjs +155 -0
  25. package/dist/chunk-6BUBNZPG.mjs +164 -0
  26. package/dist/chunk-6DVWMJ3H.mjs +7029 -0
  27. package/dist/chunk-6TGV2DNP.js +120 -0
  28. package/dist/chunk-72JGQ7IJ.mjs +1498 -0
  29. package/dist/chunk-7DHKQODW.mjs +2932 -0
  30. package/dist/chunk-7IKHZKAC.js +160 -0
  31. package/dist/chunk-ADIDI7AJ.js +11 -0
  32. package/dist/chunk-BFWX5GJZ.mjs +940 -0
  33. package/dist/chunk-BMFQG6RA.mjs +5537 -0
  34. package/dist/chunk-C4UT5V3P.js +65 -0
  35. package/dist/chunk-CC4KUIKC.js +2004 -0
  36. package/dist/chunk-D3QXPL47.mjs +1814 -0
  37. package/dist/chunk-DQWHYBV2.js +36 -0
  38. package/dist/chunk-E42B4GSB.js +993 -0
  39. package/dist/chunk-ESZ7CBA2.js +1007 -0
  40. package/dist/chunk-EYJJQVV4.js +111 -0
  41. package/dist/chunk-FRRS2YZH.mjs +129 -0
  42. package/dist/chunk-G5TQWWQA.mjs +37 -0
  43. package/dist/chunk-GAIQJCAZ.js +5612 -0
  44. package/dist/chunk-GMBGWOCR.mjs +48 -0
  45. package/dist/chunk-GUSTCU2W.mjs +105 -0
  46. package/dist/chunk-HBLKVQIQ.mjs +23 -0
  47. package/dist/chunk-HMAMMC72.js +26 -0
  48. package/dist/chunk-IMKLN273.mjs +9 -0
  49. package/dist/chunk-J6OLBSZR.js +250 -0
  50. package/dist/chunk-JAE45W2T.js +28 -0
  51. package/dist/chunk-JORVSG52.js +606 -0
  52. package/dist/chunk-KB7UXIQZ.mjs +984 -0
  53. package/dist/chunk-KGGQ5NZV.js +186 -0
  54. package/dist/chunk-KHCC5UKW.mjs +22 -0
  55. package/dist/chunk-KRRIRS6A.mjs +1945 -0
  56. package/dist/chunk-LQCVRWVF.js +48 -0
  57. package/dist/chunk-MHZXUOGN.mjs +168 -0
  58. package/dist/chunk-MPZFPU4X.js +349 -0
  59. package/dist/chunk-MVYRNJA6.js +74 -0
  60. package/dist/chunk-N6AFNFZR.mjs +565 -0
  61. package/dist/chunk-OFQLWSUR.mjs +214 -0
  62. package/dist/chunk-OLAAXLXY.mjs +219 -0
  63. package/dist/chunk-OZZWDIOY.js +1859 -0
  64. package/dist/chunk-PZRI43EZ.js +111 -0
  65. package/dist/chunk-Q256HRYD.js +176 -0
  66. package/dist/chunk-Q52ZEL62.mjs +223 -0
  67. package/dist/chunk-R26Y7LGJ.js +142 -0
  68. package/dist/chunk-RBUYW6QQ.js +39 -0
  69. package/dist/chunk-RVEFPVZF.mjs +43 -0
  70. package/dist/chunk-SORWLKOK.js +96 -0
  71. package/dist/chunk-STEP6C4C.mjs +33 -0
  72. package/dist/chunk-T5R6HUDG.mjs +22 -0
  73. package/dist/chunk-T6ZBA6VJ.js +7109 -0
  74. package/dist/chunk-UM7WMXIU.js +2995 -0
  75. package/dist/chunk-VBD4Q5LL.mjs +117 -0
  76. package/dist/chunk-WOITB4JL.js +195 -0
  77. package/dist/chunk-YKZEKJMZ.mjs +71 -0
  78. package/dist/chunk-YL7RZRHM.mjs +103 -0
  79. package/dist/chunk-YSLD2HLP.mjs +346 -0
  80. package/dist/chunk-ZFLZA7UP.mjs +140 -0
  81. package/dist/chunk-ZKUIUE7W.mjs +26 -0
  82. package/dist/chunk-ZOA7B32D.js +248 -0
  83. package/dist/data-table.d.cts +46 -0
  84. package/dist/data-table.d.ts +46 -0
  85. package/dist/data-table.js +270 -0
  86. package/dist/data-table.mjs +13 -0
  87. package/dist/editor.d.cts +89 -0
  88. package/dist/editor.d.ts +89 -0
  89. package/dist/editor.js +10 -0
  90. package/dist/editor.mjs +1 -0
  91. package/dist/forms.d.cts +142 -0
  92. package/dist/forms.d.ts +142 -0
  93. package/dist/forms.js +24 -0
  94. package/dist/forms.mjs +11 -0
  95. package/dist/hooks-8ORd7T1A.d.cts +751 -0
  96. package/dist/hooks-B2jU1GVT.d.ts +751 -0
  97. package/dist/hooks.d.cts +6 -0
  98. package/dist/hooks.d.ts +6 -0
  99. package/dist/hooks.js +99 -0
  100. package/dist/hooks.mjs +10 -0
  101. package/dist/index.d.cts +3141 -0
  102. package/dist/index.d.ts +3141 -0
  103. package/dist/index.js +7332 -0
  104. package/dist/index.mjs +5876 -0
  105. package/dist/layouts-DPfDDF53.d.cts +1001 -0
  106. package/dist/layouts-DPfDDF53.d.ts +1001 -0
  107. package/dist/layouts.d.cts +4 -0
  108. package/dist/layouts.d.ts +4 -0
  109. package/dist/layouts.js +100 -0
  110. package/dist/layouts.mjs +11 -0
  111. package/dist/marketing-3d.d.cts +51 -0
  112. package/dist/marketing-3d.d.ts +51 -0
  113. package/dist/marketing-3d.js +553 -0
  114. package/dist/marketing-3d.mjs +526 -0
  115. package/dist/marketing.d.cts +583 -0
  116. package/dist/marketing.d.ts +583 -0
  117. package/dist/marketing.js +299 -0
  118. package/dist/marketing.mjs +10 -0
  119. package/dist/media.d.cts +29 -0
  120. package/dist/media.d.ts +29 -0
  121. package/dist/media.js +189 -0
  122. package/dist/media.mjs +182 -0
  123. package/dist/navigation.d.cts +591 -0
  124. package/dist/navigation.d.ts +591 -0
  125. package/dist/navigation.js +108 -0
  126. package/dist/navigation.mjs +15 -0
  127. package/dist/portal.d.cts +58 -0
  128. package/dist/portal.d.ts +58 -0
  129. package/dist/portal.js +403 -0
  130. package/dist/portal.mjs +395 -0
  131. package/dist/primitives.d.cts +508 -0
  132. package/dist/primitives.d.ts +508 -0
  133. package/dist/primitives.js +295 -0
  134. package/dist/primitives.mjs +14 -0
  135. package/dist/settings.d.cts +216 -0
  136. package/dist/settings.d.ts +216 -0
  137. package/dist/settings.js +34 -0
  138. package/dist/settings.mjs +9 -0
  139. package/dist/shared-Dqn36QHZ.d.cts +4 -0
  140. package/dist/shared-Dqn36QHZ.d.ts +4 -0
  141. package/dist/styles.css +1213 -0
  142. package/package.json +189 -0
  143. package/styles.css +1 -0
@@ -0,0 +1,2004 @@
1
+ 'use strict';
2
+
3
+ var chunkMVYRNJA6_js = require('./chunk-MVYRNJA6.js');
4
+ var chunkE42B4GSB_js = require('./chunk-E42B4GSB.js');
5
+ var chunkHMAMMC72_js = require('./chunk-HMAMMC72.js');
6
+ var chunkJ6OLBSZR_js = require('./chunk-J6OLBSZR.js');
7
+ var chunkSORWLKOK_js = require('./chunk-SORWLKOK.js');
8
+ var chunkQ256HRYD_js = require('./chunk-Q256HRYD.js');
9
+ var chunkADIDI7AJ_js = require('./chunk-ADIDI7AJ.js');
10
+ var sharedUtils = require('@caffeinebounce/shared-utils');
11
+ var React = require('react');
12
+ var jsxRuntime = require('react/jsx-runtime');
13
+ var lucideReact = require('lucide-react');
14
+ var Link2 = require('next/link');
15
+ var nextThemes = require('next-themes');
16
+ var CollapsiblePrimitive = require('@radix-ui/react-collapsible');
17
+ var sonner = require('sonner');
18
+
19
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
20
+
21
+ function _interopNamespace(e) {
22
+ if (e && e.__esModule) return e;
23
+ var n = Object.create(null);
24
+ if (e) {
25
+ Object.keys(e).forEach(function (k) {
26
+ if (k !== 'default') {
27
+ var d = Object.getOwnPropertyDescriptor(e, k);
28
+ Object.defineProperty(n, k, d.get ? d : {
29
+ enumerable: true,
30
+ get: function () { return e[k]; }
31
+ });
32
+ }
33
+ });
34
+ }
35
+ n.default = e;
36
+ return Object.freeze(n);
37
+ }
38
+
39
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
40
+ var Link2__default = /*#__PURE__*/_interopDefault(Link2);
41
+ var CollapsiblePrimitive__namespace = /*#__PURE__*/_interopNamespace(CollapsiblePrimitive);
42
+
43
+ function ClarityAnalytics({
44
+ projectId,
45
+ enabled = true
46
+ }) {
47
+ React.useEffect(() => {
48
+ if (!enabled) {
49
+ return;
50
+ }
51
+ const normalizedProjectId = sharedUtils.normalizeMicrosoftClarityProjectId(projectId);
52
+ if (!normalizedProjectId) {
53
+ if (projectId?.trim()) {
54
+ console.warn(
55
+ `Invalid Microsoft Clarity project ID: ${projectId}. Expected letters, numbers, underscores, or dashes.`
56
+ );
57
+ }
58
+ return;
59
+ }
60
+ if (window.clarity) {
61
+ return;
62
+ }
63
+ const queuedClarity = (...args) => {
64
+ queuedClarity.q ??= [];
65
+ queuedClarity.q.push(args);
66
+ };
67
+ window.clarity = queuedClarity;
68
+ const script = document.createElement("script");
69
+ script.async = true;
70
+ script.src = sharedUtils.getMicrosoftClarityScriptUrl(normalizedProjectId);
71
+ const firstScript = document.getElementsByTagName("script")[0];
72
+ if (firstScript?.parentNode) {
73
+ firstScript.parentNode.insertBefore(script, firstScript);
74
+ } else {
75
+ document.head.appendChild(script);
76
+ }
77
+ }, [enabled, projectId]);
78
+ return null;
79
+ }
80
+ function GoogleAnalytics({ measurementId }) {
81
+ React.useEffect(() => {
82
+ if (!measurementId) {
83
+ return;
84
+ }
85
+ if (!/^G-[A-Z0-9]+$/.test(measurementId)) {
86
+ console.warn(
87
+ `Invalid Google Analytics measurement ID: ${measurementId}. Expected format: G-XXXXXXXXXX`
88
+ );
89
+ return;
90
+ }
91
+ if (window.gtag) {
92
+ return;
93
+ }
94
+ window.dataLayer = window.dataLayer || [];
95
+ function gtag(...args) {
96
+ window.dataLayer?.push(args);
97
+ }
98
+ window.gtag = gtag;
99
+ const script = document.createElement("script");
100
+ script.async = true;
101
+ script.src = `https://www.googletagmanager.com/gtag/js?id=${measurementId}`;
102
+ script.onload = () => {
103
+ gtag("js", /* @__PURE__ */ new Date());
104
+ gtag("config", measurementId);
105
+ };
106
+ document.head.appendChild(script);
107
+ }, [measurementId]);
108
+ return null;
109
+ }
110
+ function GoogleTagManager({
111
+ containerId,
112
+ dataLayerName = "dataLayer",
113
+ enabled = true
114
+ }) {
115
+ const normalizedContainerId = sharedUtils.normalizeGoogleTagManagerContainerId(containerId);
116
+ React.useEffect(() => {
117
+ if (!enabled) {
118
+ return;
119
+ }
120
+ if (!normalizedContainerId) {
121
+ if (containerId?.trim()) {
122
+ console.warn(
123
+ `Invalid Google Tag Manager container ID: ${containerId}. Expected format: GTM-XXXXXXX`
124
+ );
125
+ }
126
+ return;
127
+ }
128
+ if (document.querySelector(
129
+ `[data-google-tag-manager="${normalizedContainerId}"]`
130
+ )) {
131
+ return;
132
+ }
133
+ const dataLayers = window;
134
+ dataLayers[dataLayerName] ??= [];
135
+ dataLayers[dataLayerName]?.push({
136
+ "gtm.start": Date.now(),
137
+ event: "gtm.js"
138
+ });
139
+ const script = document.createElement("script");
140
+ script.async = true;
141
+ script.dataset.googleTagManager = normalizedContainerId;
142
+ script.src = sharedUtils.getGoogleTagManagerScriptUrl(
143
+ normalizedContainerId,
144
+ dataLayerName
145
+ );
146
+ const firstScript = document.getElementsByTagName("script")[0];
147
+ if (firstScript?.parentNode) {
148
+ firstScript.parentNode.insertBefore(script, firstScript);
149
+ } else {
150
+ document.head.appendChild(script);
151
+ }
152
+ }, [containerId, dataLayerName, enabled, normalizedContainerId]);
153
+ if (!enabled || !normalizedContainerId) {
154
+ return null;
155
+ }
156
+ return /* @__PURE__ */ jsxRuntime.jsx("noscript", { children: /* @__PURE__ */ jsxRuntime.jsx(
157
+ "iframe",
158
+ {
159
+ height: "0",
160
+ src: sharedUtils.getGoogleTagManagerNoScriptUrl(
161
+ normalizedContainerId,
162
+ dataLayerName
163
+ ),
164
+ style: { display: "none", visibility: "hidden" },
165
+ title: "Google Tag Manager",
166
+ width: "0"
167
+ }
168
+ ) });
169
+ }
170
+ var BackLink = React__namespace.forwardRef(
171
+ ({ href, children = "Back", className, ...props }, ref) => {
172
+ return /* @__PURE__ */ jsxRuntime.jsxs(
173
+ Link2__default.default,
174
+ {
175
+ ref,
176
+ href,
177
+ className: chunkADIDI7AJ_js.cn(
178
+ "inline-flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground transition-colors",
179
+ className
180
+ ),
181
+ ...props,
182
+ children: [
183
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { className: "size-4" }),
184
+ children
185
+ ]
186
+ }
187
+ );
188
+ }
189
+ );
190
+ BackLink.displayName = "BackLink";
191
+ function PageLayoutShell({
192
+ title,
193
+ description,
194
+ actions,
195
+ children,
196
+ className,
197
+ contentClassName,
198
+ footer,
199
+ beforeHeader,
200
+ showHeader = Boolean(title || description || actions),
201
+ contentBaseClassName = "flex-1",
202
+ innerClassName
203
+ }) {
204
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkADIDI7AJ_js.cn("flex flex-1 flex-col min-w-0 min-h-full", className), children: [
205
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkADIDI7AJ_js.cn("flex flex-1 flex-col gap-4 p-4", innerClassName), children: [
206
+ beforeHeader,
207
+ showHeader && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
208
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
209
+ title && /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-semibold", children: title }),
210
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: description })
211
+ ] }),
212
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: actions })
213
+ ] }),
214
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkADIDI7AJ_js.cn(contentBaseClassName, contentClassName), children })
215
+ ] }),
216
+ footer
217
+ ] });
218
+ }
219
+ function BasePageLayout({
220
+ title,
221
+ description,
222
+ actions,
223
+ children,
224
+ className,
225
+ contentClassName,
226
+ footer
227
+ }) {
228
+ return /* @__PURE__ */ jsxRuntime.jsx(
229
+ PageLayoutShell,
230
+ {
231
+ title,
232
+ description,
233
+ actions,
234
+ className,
235
+ contentClassName,
236
+ footer,
237
+ children
238
+ }
239
+ );
240
+ }
241
+ function AdminPageLayout({
242
+ title,
243
+ description,
244
+ actions,
245
+ children,
246
+ className,
247
+ contentClassName,
248
+ footer,
249
+ backLink
250
+ }) {
251
+ const showHeader = !backLink && Boolean(title || description || actions);
252
+ return /* @__PURE__ */ jsxRuntime.jsx(
253
+ PageLayoutShell,
254
+ {
255
+ title,
256
+ description,
257
+ actions,
258
+ className,
259
+ contentClassName,
260
+ footer,
261
+ showHeader,
262
+ beforeHeader: backLink ? /* @__PURE__ */ jsxRuntime.jsx(BackLink, { href: backLink.href, children: backLink.label }) : null,
263
+ contentBaseClassName: "flex-1 min-w-0",
264
+ innerClassName: "min-w-0",
265
+ children
266
+ }
267
+ );
268
+ }
269
+ function AppFooter({ children, className }) {
270
+ return /* @__PURE__ */ jsxRuntime.jsx(
271
+ "div",
272
+ {
273
+ className: chunkADIDI7AJ_js.cn(
274
+ "sticky bottom-0 z-10 mt-auto border-t bg-background/95 px-4 py-1 backdrop-blur supports-[backdrop-filter]:bg-background/60",
275
+ className
276
+ ),
277
+ children
278
+ }
279
+ );
280
+ }
281
+ function getResolvedTheme(resolvedTheme) {
282
+ return resolvedTheme === "dark" ? "dark" : "light";
283
+ }
284
+ function getDocumentTheme() {
285
+ return document.documentElement.classList.contains("dark") ? "dark" : "light";
286
+ }
287
+ function prefersDarkMode() {
288
+ return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-color-scheme: dark)").matches;
289
+ }
290
+ function getCurrentSelection(includeSystem, theme, resolvedTheme) {
291
+ if (includeSystem && theme === "system") {
292
+ return "system";
293
+ }
294
+ return resolvedTheme;
295
+ }
296
+ function getNextThemeSelection(currentSelection, includeSystem) {
297
+ if (!includeSystem) {
298
+ return currentSelection === "dark" ? "light" : "dark";
299
+ }
300
+ if (currentSelection === "light") {
301
+ return "dark";
302
+ }
303
+ if (currentSelection === "dark") {
304
+ return "system";
305
+ }
306
+ return "light";
307
+ }
308
+ function getThemeToggleLabel(nextTheme) {
309
+ return `Switch theme to ${nextTheme}`;
310
+ }
311
+ function getThemeIcon(nextTheme) {
312
+ if (nextTheme === "light") {
313
+ return lucideReact.Sun;
314
+ }
315
+ if (nextTheme === "dark") {
316
+ return lucideReact.Moon;
317
+ }
318
+ return lucideReact.Monitor;
319
+ }
320
+ function useTheme() {
321
+ const { resolvedTheme } = nextThemes.useTheme();
322
+ if (typeof document !== "undefined") {
323
+ return document.documentElement.classList.contains("dark") ? "dark" : "light";
324
+ }
325
+ return resolvedTheme === "dark" ? "dark" : "light";
326
+ }
327
+ function matchesShortcut(event, shortcut) {
328
+ const ctrlMatch = shortcut.ctrl ? event.ctrlKey : !event.ctrlKey;
329
+ const shiftMatch = shortcut.shift ? event.shiftKey : !event.shiftKey;
330
+ const altMatch = shortcut.alt ? event.altKey : !event.altKey;
331
+ const metaMatch = shortcut.meta ? event.metaKey : !event.metaKey;
332
+ const keyMatch = event.key === shortcut.key;
333
+ return ctrlMatch && shiftMatch && altMatch && metaMatch && keyMatch;
334
+ }
335
+ function ThemeToggle({
336
+ includeSystem = false,
337
+ shortcut,
338
+ shortcutDisplay,
339
+ showShortcut = true,
340
+ shortcutsVisible,
341
+ tooltip,
342
+ className
343
+ }) {
344
+ const { resolvedTheme, setTheme, theme } = nextThemes.useTheme();
345
+ const [mounted, setMounted] = React.useState(false);
346
+ const shouldShowShortcut = shortcutsVisible ?? showShortcut;
347
+ const renderedTheme = mounted && typeof document !== "undefined" ? getDocumentTheme() : getResolvedTheme(resolvedTheme);
348
+ const currentSelection = getCurrentSelection(
349
+ includeSystem,
350
+ theme,
351
+ renderedTheme
352
+ );
353
+ const nextTheme = getNextThemeSelection(currentSelection, includeSystem);
354
+ const ariaLabel = getThemeToggleLabel(nextTheme);
355
+ const Icon = getThemeIcon(nextTheme);
356
+ const toggleTheme = React.useCallback(() => {
357
+ setTheme(nextTheme);
358
+ if (typeof document !== "undefined") {
359
+ const nextIsDark = nextTheme === "dark" || nextTheme === "system" && prefersDarkMode();
360
+ document.documentElement.classList.toggle("dark", nextIsDark);
361
+ try {
362
+ localStorage.setItem("theme", nextTheme);
363
+ } catch {
364
+ }
365
+ }
366
+ }, [nextTheme, setTheme]);
367
+ React.useEffect(() => {
368
+ setMounted(true);
369
+ }, []);
370
+ React.useEffect(() => {
371
+ if (!shortcut) return;
372
+ const handleKeyDown = (e) => {
373
+ if (matchesShortcut(e, shortcut)) {
374
+ e.preventDefault();
375
+ toggleTheme();
376
+ }
377
+ };
378
+ window.addEventListener("keydown", handleKeyDown);
379
+ return () => window.removeEventListener("keydown", handleKeyDown);
380
+ }, [shortcut, toggleTheme]);
381
+ if (!mounted) {
382
+ if (includeSystem) {
383
+ return /* @__PURE__ */ jsxRuntime.jsx(
384
+ "button",
385
+ {
386
+ type: "button",
387
+ className: `inline-flex h-8 w-8 items-center justify-center text-icon transition-colors ${className ?? ""}`,
388
+ "aria-label": "Toggle theme",
389
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Monitor, { className: "h-4 w-4" })
390
+ }
391
+ );
392
+ }
393
+ return /* @__PURE__ */ jsxRuntime.jsx(
394
+ "button",
395
+ {
396
+ type: "button",
397
+ className: `inline-flex h-8 w-8 items-center justify-center text-icon transition-colors ${className ?? ""}`,
398
+ "aria-label": "Toggle theme",
399
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-4 w-4", children: [
400
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sun, { className: "absolute inset-0 h-4 w-4 opacity-0 dark:opacity-100 transition-opacity duration-150" }),
401
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Moon, { className: "absolute inset-0 h-4 w-4 opacity-100 dark:opacity-0 transition-opacity duration-150" })
402
+ ] })
403
+ }
404
+ );
405
+ }
406
+ const tooltipContent = tooltip ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
407
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: ariaLabel }),
408
+ shouldShowShortcut && shortcutDisplay && /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.KeyboardShortcut, { className: "ml-2 text-xs", children: shortcutDisplay })
409
+ ] });
410
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunkSORWLKOK_js.Tooltip, { children: [
411
+ /* @__PURE__ */ jsxRuntime.jsx(chunkSORWLKOK_js.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
412
+ "button",
413
+ {
414
+ type: "button",
415
+ onClick: toggleTheme,
416
+ className: `group inline-flex h-8 w-8 items-center justify-center text-icon hover:text-icon-hover transition-colors ${className ?? ""}`,
417
+ "aria-label": ariaLabel,
418
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4 transition-transform duration-150 group-hover:rotate-12" })
419
+ }
420
+ ) }),
421
+ /* @__PURE__ */ jsxRuntime.jsx(chunkSORWLKOK_js.TooltipContent, { side: "bottom", children: tooltipContent })
422
+ ] });
423
+ }
424
+ function AppHeader({
425
+ showSidebarTrigger = true,
426
+ showThemeToggle = true,
427
+ themeToggleShortcut,
428
+ shortcutsVisible,
429
+ helpLink,
430
+ aboutLink,
431
+ actions,
432
+ leadingContent,
433
+ className,
434
+ LinkComponent = "a",
435
+ ShortcutComponent
436
+ }) {
437
+ const Link3 = LinkComponent;
438
+ const helpConfig = helpLink ? typeof helpLink === "string" ? { href: helpLink, label: "Help", icon: lucideReact.CircleHelp, tooltip: "Get help" } : { icon: lucideReact.CircleHelp, tooltip: "Get help", ...helpLink } : null;
439
+ const aboutConfig = aboutLink ? typeof aboutLink === "string" ? { href: aboutLink, label: "About", icon: lucideReact.Info, tooltip: "About" } : { icon: lucideReact.Info, tooltip: "About", ...aboutLink } : null;
440
+ const renderLink = (config) => {
441
+ const Icon = config.icon;
442
+ const content = /* @__PURE__ */ jsxRuntime.jsxs(
443
+ Link3,
444
+ {
445
+ href: config.href,
446
+ className: "inline-flex h-8 w-8 items-center justify-center text-icon transition-colors hover:text-icon-hover",
447
+ children: [
448
+ Icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4 transition-transform duration-300 hover:rotate-12" }),
449
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: config.label })
450
+ ]
451
+ }
452
+ );
453
+ if (config.tooltip || config.shortcutDisplay) {
454
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunkSORWLKOK_js.Tooltip, { children: [
455
+ /* @__PURE__ */ jsxRuntime.jsx(chunkSORWLKOK_js.TooltipTrigger, { asChild: true, children: content }),
456
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkSORWLKOK_js.TooltipContent, { side: "bottom", children: [
457
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: config.tooltip || config.label }),
458
+ config.shortcutDisplay && ShortcutComponent && /* @__PURE__ */ jsxRuntime.jsx(ShortcutComponent, { className: "ml-2 text-[10px]", children: config.shortcutDisplay })
459
+ ] })
460
+ ] });
461
+ }
462
+ return content;
463
+ };
464
+ return /* @__PURE__ */ jsxRuntime.jsxs(
465
+ "header",
466
+ {
467
+ className: chunkADIDI7AJ_js.cn(
468
+ "sticky top-0 z-10 flex h-14 shrink-0 items-center gap-2 border-b bg-background px-4",
469
+ className
470
+ ),
471
+ children: [
472
+ showSidebarTrigger && /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarTrigger, { className: "-ml-1" }),
473
+ leadingContent,
474
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" }),
475
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
476
+ actions,
477
+ helpConfig && renderLink(helpConfig),
478
+ aboutConfig && renderLink(aboutConfig),
479
+ showThemeToggle && /* @__PURE__ */ jsxRuntime.jsx(
480
+ ThemeToggle,
481
+ {
482
+ shortcutDisplay: themeToggleShortcut,
483
+ shortcutsVisible
484
+ }
485
+ )
486
+ ] })
487
+ ]
488
+ }
489
+ );
490
+ }
491
+ var Collapsible = CollapsiblePrimitive__namespace.Root;
492
+ var CollapsibleTrigger2 = CollapsiblePrimitive__namespace.CollapsibleTrigger;
493
+ var CollapsibleContent2 = CollapsiblePrimitive__namespace.CollapsibleContent;
494
+ function isNavItem(element) {
495
+ return "label" in element && "href" in element && "icon" in element && !("type" in element);
496
+ }
497
+ function isNavSection(element) {
498
+ return "type" in element && element.type === "section";
499
+ }
500
+ function isNavDivider(element) {
501
+ return "type" in element && element.type === "divider";
502
+ }
503
+ function AppSidebar({
504
+ navItems,
505
+ pathname = "",
506
+ user,
507
+ userMenuItems = [],
508
+ userLoading = false,
509
+ header,
510
+ onSignOut,
511
+ signInHref = "/auth/signin",
512
+ profilePath = "/profile",
513
+ collapsible = "icon",
514
+ LinkComponent = "a",
515
+ ShortcutComponent,
516
+ userMenuShortcut,
517
+ onNavigate,
518
+ enableKeyboardShortcuts = true,
519
+ shortcutsVisible
520
+ }) {
521
+ const Link3 = LinkComponent;
522
+ const [menuOpen, setMenuOpen] = React.useState(false);
523
+ const [suppressSectionTooltip, setSuppressSectionTooltip] = React.useState(null);
524
+ const isOnProfilePage = pathname === profilePath || pathname.startsWith(`${profilePath}/`);
525
+ const allMenuItems = React.useMemo(() => {
526
+ const items = [...userMenuItems];
527
+ if (onSignOut && !items.some((item) => item.label === "Sign Out")) {
528
+ items.push({
529
+ label: "Sign Out",
530
+ icon: lucideReact.LogOut,
531
+ onClick: onSignOut,
532
+ destructive: true,
533
+ separatorBefore: items.length > 0
534
+ });
535
+ }
536
+ return items;
537
+ }, [userMenuItems, onSignOut]);
538
+ const allNavItems = React.useMemo(() => {
539
+ const items = [];
540
+ for (const element of navItems) {
541
+ if (isNavItem(element)) {
542
+ items.push(element);
543
+ } else if (isNavSection(element)) {
544
+ items.push(...element.items);
545
+ }
546
+ }
547
+ return items;
548
+ }, [navItems]);
549
+ const processedNavGroups = React.useMemo(() => {
550
+ const groups = [];
551
+ let dividerCount = 0;
552
+ let i = 0;
553
+ while (i < navItems.length) {
554
+ const element = navItems[i];
555
+ if (isNavDivider(element)) {
556
+ groups.push({ type: "divider", key: `divider-${dividerCount++}` });
557
+ i++;
558
+ } else if (isNavSection(element)) {
559
+ groups.push({ type: "section", section: element });
560
+ i++;
561
+ } else if (isNavItem(element)) {
562
+ const plainItems = [element];
563
+ const startHref = element.href;
564
+ i++;
565
+ while (i < navItems.length && isNavItem(navItems[i])) {
566
+ plainItems.push(navItems[i]);
567
+ i++;
568
+ }
569
+ groups.push({
570
+ type: "plain-group",
571
+ items: plainItems,
572
+ key: `plain-group-${startHref}`
573
+ });
574
+ } else {
575
+ i++;
576
+ }
577
+ }
578
+ return groups;
579
+ }, [navItems]);
580
+ React.useEffect(() => {
581
+ if (!enableKeyboardShortcuts || !onNavigate) return;
582
+ const handleKeyDown = (e) => {
583
+ if (!e.ctrlKey || e.shiftKey || e.altKey || e.metaKey) return;
584
+ const matchingItem = allNavItems.find(
585
+ (item) => item.shortcutKey === e.key && !item.disabled
586
+ );
587
+ if (matchingItem) {
588
+ e.preventDefault();
589
+ onNavigate(matchingItem.href);
590
+ }
591
+ };
592
+ window.addEventListener("keydown", handleKeyDown);
593
+ return () => window.removeEventListener("keydown", handleKeyDown);
594
+ }, [enableKeyboardShortcuts, allNavItems, onNavigate]);
595
+ const activeHref = React.useMemo(() => {
596
+ if (!pathname || allNavItems.length === 0) return null;
597
+ const matches = allNavItems.filter((item) => {
598
+ if (item.href === "/" || item.href === "/dashboard" || item.href === "/finance") {
599
+ return pathname === item.href;
600
+ }
601
+ return pathname === item.href || pathname.startsWith(`${item.href}/`);
602
+ }).sort((a, b) => b.href.length - a.href.length);
603
+ return matches[0]?.href ?? null;
604
+ }, [pathname, allNavItems]);
605
+ const [sectionOpenState, setSectionOpenState] = React.useState({});
606
+ React.useEffect(() => {
607
+ setSectionOpenState((prev) => {
608
+ const nextState = {};
609
+ for (const group of processedNavGroups) {
610
+ if (group.type === "section" && group.section.collapsible) {
611
+ nextState[group.section.label] = prev[group.section.label] ?? group.section.defaultOpen === true;
612
+ }
613
+ }
614
+ const nextKeys = Object.keys(nextState);
615
+ const prevKeys = Object.keys(prev);
616
+ const hasChanged = nextKeys.length !== prevKeys.length || nextKeys.some((key) => prev[key] !== nextState[key]);
617
+ return hasChanged ? nextState : prev;
618
+ });
619
+ }, [processedNavGroups]);
620
+ const getIsActive = (item) => {
621
+ if (item.isActive !== void 0) return item.isActive;
622
+ if (!pathname) return false;
623
+ return activeHref === item.href;
624
+ };
625
+ const getIconAnimationClass = (animation) => {
626
+ switch (animation) {
627
+ case "rotate":
628
+ return "motion-safe:group-hover:rotate-90 motion-safe:transition-transform motion-safe:duration-150";
629
+ case "bounce":
630
+ return "motion-safe:group-hover:scale-110 motion-safe:transition-transform motion-safe:duration-150";
631
+ case "scale":
632
+ return "motion-safe:group-hover:scale-110 motion-safe:transition-transform motion-safe:duration-150";
633
+ case "none":
634
+ return "";
635
+ default:
636
+ return "motion-safe:group-hover:scale-110 motion-safe:transition-transform motion-safe:duration-150";
637
+ }
638
+ };
639
+ const renderNavItem = (item) => {
640
+ const isActive = getIsActive(item);
641
+ const Icon = item.icon;
642
+ const Shortcut = ShortcutComponent || chunkE42B4GSB_js.KeyboardShortcut;
643
+ const iconAnimationClass = item.disabled ? "" : getIconAnimationClass(item.iconAnimation);
644
+ if (item.disabled) {
645
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunkSORWLKOK_js.Tooltip, { children: [
646
+ /* @__PURE__ */ jsxRuntime.jsx(chunkSORWLKOK_js.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
647
+ chunkE42B4GSB_js.SidebarMenuButton,
648
+ {
649
+ className: "cursor-not-allowed opacity-40",
650
+ isActive: false,
651
+ "aria-disabled": "true",
652
+ tabIndex: 0,
653
+ children: [
654
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "shrink-0" }),
655
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label })
656
+ ]
657
+ }
658
+ ) }),
659
+ /* @__PURE__ */ jsxRuntime.jsx(chunkSORWLKOK_js.TooltipContent, { side: "right", children: item.disabledTooltip || "Coming soon" })
660
+ ] });
661
+ }
662
+ return /* @__PURE__ */ jsxRuntime.jsx(
663
+ chunkE42B4GSB_js.SidebarMenuButton,
664
+ {
665
+ asChild: true,
666
+ isActive,
667
+ className: "group",
668
+ tooltip: item.label,
669
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Link3, { href: item.href, children: [
670
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: `shrink-0 ${iconAnimationClass}` }),
671
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label }),
672
+ shortcutsVisible && item.shortcutDisplay && /* @__PURE__ */ jsxRuntime.jsx(Shortcut, { className: "ml-auto text-[10px] text-muted-foreground", children: item.shortcutDisplay })
673
+ ] })
674
+ }
675
+ );
676
+ };
677
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunkE42B4GSB_js.Sidebar, { collapsible, children: [
678
+ header && /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarHeader, { children: header }),
679
+ /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarContent, { children: processedNavGroups.map((group) => {
680
+ if (group.type === "divider") {
681
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarSeparator, { className: "my-2" }, group.key);
682
+ }
683
+ if (group.type === "section") {
684
+ const section = group.section;
685
+ if (section.visible === false) return null;
686
+ if (section.collapsible) {
687
+ const SectionIcon = section.icon ?? section.items[0]?.icon;
688
+ const sectionHref = section.items[0]?.href;
689
+ return /* @__PURE__ */ jsxRuntime.jsx(
690
+ Collapsible,
691
+ {
692
+ open: sectionOpenState[section.label] ?? section.defaultOpen === true,
693
+ onOpenChange: (open) => setSectionOpenState((prev) => ({
694
+ ...prev,
695
+ [section.label]: open
696
+ })),
697
+ className: "group/collapsible",
698
+ children: /* @__PURE__ */ jsxRuntime.jsxs(chunkE42B4GSB_js.SidebarGroup, { children: [
699
+ SectionIcon && sectionHref && /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarGroupContent, { className: "hidden group-data-[collapsible=icon]:block", children: /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarMenu, { children: /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsxs(
700
+ chunkJ6OLBSZR_js.DropdownMenu,
701
+ {
702
+ onOpenChange: (open) => {
703
+ setSuppressSectionTooltip(section.label);
704
+ if (!open && document.activeElement instanceof HTMLElement) {
705
+ document.activeElement.blur();
706
+ }
707
+ },
708
+ children: [
709
+ /* @__PURE__ */ jsxRuntime.jsx(chunkJ6OLBSZR_js.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
710
+ chunkE42B4GSB_js.SidebarMenuButton,
711
+ {
712
+ "aria-label": section.label,
713
+ tooltip: suppressSectionTooltip === section.label ? void 0 : section.label,
714
+ onMouseLeave: () => {
715
+ setSuppressSectionTooltip(
716
+ (prev) => prev === section.label ? null : prev
717
+ );
718
+ },
719
+ className: "!bg-transparent !text-sidebar-foreground !hover:bg-transparent !hover:text-sidebar-foreground !active:bg-transparent !active:text-sidebar-foreground focus-visible:ring-0",
720
+ children: [
721
+ /* @__PURE__ */ jsxRuntime.jsx(SectionIcon, { className: "shrink-0" }),
722
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: section.label })
723
+ ]
724
+ }
725
+ ) }),
726
+ /* @__PURE__ */ jsxRuntime.jsx(
727
+ chunkJ6OLBSZR_js.DropdownMenuContent,
728
+ {
729
+ side: "right",
730
+ align: "start",
731
+ className: "w-64",
732
+ children: section.items.map((item) => {
733
+ const ItemIcon = item.icon;
734
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkJ6OLBSZR_js.DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
735
+ Link3,
736
+ {
737
+ href: item.href,
738
+ className: "flex items-center gap-2",
739
+ children: [
740
+ /* @__PURE__ */ jsxRuntime.jsx(ItemIcon, { className: "size-4" }),
741
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label })
742
+ ]
743
+ }
744
+ ) }, item.href);
745
+ })
746
+ }
747
+ )
748
+ ]
749
+ }
750
+ ) }) }) }),
751
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group-data-[collapsible=icon]:hidden", children: [
752
+ /* @__PURE__ */ jsxRuntime.jsx(
753
+ chunkE42B4GSB_js.SidebarGroupLabel,
754
+ {
755
+ asChild: true,
756
+ className: "text-xs font-medium uppercase tracking-wider text-sidebar-foreground",
757
+ children: /* @__PURE__ */ jsxRuntime.jsxs(CollapsibleTrigger2, { className: "flex w-full items-center justify-between [&[data-state=open]>svg.chevron-icon]:rotate-180", children: [
758
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1.5", children: [
759
+ SectionIcon && /* @__PURE__ */ jsxRuntime.jsx(SectionIcon, { className: "size-3.5 shrink-0" }),
760
+ section.label
761
+ ] }),
762
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "chevron-icon ml-auto size-4 transition-transform duration-200" })
763
+ ] })
764
+ }
765
+ ),
766
+ /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContent2, { children: /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarGroupContent, { children: /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarMenu, { children: section.items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarMenuItem, { children: renderNavItem(item) }, item.href)) }) }) })
767
+ ] })
768
+ ] })
769
+ },
770
+ `section-${section.label}`
771
+ );
772
+ }
773
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunkE42B4GSB_js.SidebarGroup, { children: [
774
+ /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarGroupLabel, { className: "text-xs font-medium uppercase tracking-wider text-sidebar-foreground", children: section.label }),
775
+ /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarGroupContent, { children: /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarMenu, { children: section.items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarMenuItem, { children: renderNavItem(item) }, item.href)) }) })
776
+ ] }, `section-${section.label}`);
777
+ }
778
+ if (group.type === "plain-group") {
779
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarGroup, { children: /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarGroupContent, { children: /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarMenu, { children: group.items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarMenuItem, { children: renderNavItem(item) }, item.href)) }) }) }, group.key);
780
+ }
781
+ return null;
782
+ }) }),
783
+ /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarFooter, { children: userLoading ? /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarMenu, { children: /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-2 py-1.5", children: [
784
+ /* @__PURE__ */ jsxRuntime.jsx(chunkHMAMMC72_js.Spinner, { size: "sm" }),
785
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Loading..." })
786
+ ] }) }) }) : user ? /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarMenu, { children: /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsx(
787
+ chunkE42B4GSB_js.UserAvatarMenu,
788
+ {
789
+ user: {
790
+ id: user.id,
791
+ email: user.email ?? void 0,
792
+ avatarUrl: user.avatarUrl ?? void 0,
793
+ name: user.name || user.email || "User",
794
+ initials: user.initials || user.name?.[0]?.toUpperCase() || "U"
795
+ },
796
+ items: allMenuItems,
797
+ open: menuOpen,
798
+ onOpenChange: setMenuOpen,
799
+ side: "top",
800
+ align: "start",
801
+ menuWidth: "w-[calc(var(--sidebar-width)-1rem)]",
802
+ LinkComponent,
803
+ ShortcutComponent,
804
+ trigger: /* @__PURE__ */ jsxRuntime.jsxs(
805
+ chunkE42B4GSB_js.SidebarMenuButton,
806
+ {
807
+ size: "lg",
808
+ className: `rounded-xl focus-visible:ring-0 ${menuOpen || isOnProfilePage ? "bg-sidebar-accent text-sidebar-accent-foreground" : ""}`,
809
+ children: [
810
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkE42B4GSB_js.Avatar, { className: "h-8 w-8 rounded-full", children: [
811
+ user.avatarUrl && /* @__PURE__ */ jsxRuntime.jsx(
812
+ chunkE42B4GSB_js.AvatarImage,
813
+ {
814
+ src: user.avatarUrl,
815
+ alt: user.name || ""
816
+ }
817
+ ),
818
+ /* @__PURE__ */ jsxRuntime.jsx(
819
+ chunkE42B4GSB_js.AvatarFallback,
820
+ {
821
+ className: "rounded-full text-xs font-medium text-white",
822
+ style: chunkQ256HRYD_js.getAvatarGradient(user.id).style,
823
+ children: user.initials || user.name?.[0]?.toUpperCase() || "U"
824
+ }
825
+ )
826
+ ] }),
827
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid flex-1 min-w-0 text-left text-sm leading-tight", children: [
828
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-semibold", children: user.name || "User" }),
829
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs text-muted-foreground", children: user.email })
830
+ ] }),
831
+ ShortcutComponent && userMenuShortcut && /* @__PURE__ */ jsxRuntime.jsx(ShortcutComponent, { className: "ml-auto hidden text-xs text-muted-foreground md:inline-flex", children: userMenuShortcut }),
832
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: "ml-1 size-4" })
833
+ ]
834
+ }
835
+ )
836
+ }
837
+ ) }) }) : /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarMenu, { children: /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarMenuButton, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Link3, { href: signInHref, children: [
838
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.User, {}),
839
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Sign In" })
840
+ ] }) }) }) }) }),
841
+ /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.SidebarRail, {})
842
+ ] });
843
+ }
844
+ function FloatingUserMenu({
845
+ user,
846
+ menuItems = [],
847
+ loading = false,
848
+ onSignOut,
849
+ pathname = "",
850
+ profilePath = "/profile",
851
+ LinkComponent = "a"
852
+ }) {
853
+ const { isMobile } = chunkE42B4GSB_js.useSidebar();
854
+ const [open, setOpen] = React.useState(false);
855
+ const isOnProfilePage = pathname === profilePath || pathname.startsWith(`${profilePath}/`);
856
+ const allMenuItems = React.useMemo(() => {
857
+ const items = [...menuItems];
858
+ if (onSignOut && !items.some((item) => item.label === "Sign Out")) {
859
+ items.push({
860
+ label: "Sign Out",
861
+ icon: lucideReact.LogOut,
862
+ onClick: onSignOut,
863
+ destructive: true,
864
+ separatorBefore: items.length > 0
865
+ });
866
+ }
867
+ return items;
868
+ }, [menuItems, onSignOut]);
869
+ if (!isMobile) return null;
870
+ if (loading) {
871
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed bottom-2 left-2 z-50 flex h-8 w-8 items-center justify-center rounded-full bg-background shadow-md border", children: /* @__PURE__ */ jsxRuntime.jsx(chunkHMAMMC72_js.Spinner, { size: "sm" }) });
872
+ }
873
+ if (!user) return null;
874
+ const displayName = user.name || user.email || "User";
875
+ const initials = user.initials || user.name?.[0]?.toUpperCase() || "U";
876
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed bottom-2 left-2 z-50", children: /* @__PURE__ */ jsxRuntime.jsx(
877
+ chunkE42B4GSB_js.UserAvatarMenu,
878
+ {
879
+ user: {
880
+ id: user.id,
881
+ email: user.email ?? void 0,
882
+ avatarUrl: user.avatarUrl ?? void 0,
883
+ name: displayName,
884
+ initials
885
+ },
886
+ items: allMenuItems,
887
+ open,
888
+ onOpenChange: setOpen,
889
+ side: "top",
890
+ align: "start",
891
+ isActive: isOnProfilePage,
892
+ showUserInfo: true,
893
+ LinkComponent,
894
+ trigger: /* @__PURE__ */ jsxRuntime.jsxs(
895
+ "button",
896
+ {
897
+ type: "button",
898
+ className: `flex h-8 w-8 items-center justify-center rounded-full shadow-md border bg-background transition-all hover:scale-105 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${open || isOnProfilePage ? "ring-2 ring-primary" : ""}`,
899
+ children: [
900
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkE42B4GSB_js.Avatar, { className: "h-8 w-8 rounded-full", children: [
901
+ user.avatarUrl && /* @__PURE__ */ jsxRuntime.jsx(chunkE42B4GSB_js.AvatarImage, { src: user.avatarUrl, alt: displayName }),
902
+ /* @__PURE__ */ jsxRuntime.jsx(
903
+ chunkE42B4GSB_js.AvatarFallback,
904
+ {
905
+ className: "rounded-full text-xs font-medium text-white",
906
+ style: chunkQ256HRYD_js.getAvatarGradient(user.id).style,
907
+ children: initials
908
+ }
909
+ )
910
+ ] }),
911
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "User menu" })
912
+ ]
913
+ }
914
+ )
915
+ }
916
+ ) });
917
+ }
918
+ function AppLayout({
919
+ children,
920
+ // Sidebar props
921
+ navItems = [],
922
+ sidebarHeader,
923
+ sidebar: customSidebar,
924
+ sidebarCollapsible = "icon",
925
+ // User props
926
+ user,
927
+ userLoading = false,
928
+ userMenuItems = [],
929
+ onSignOut,
930
+ signInHref,
931
+ pathname = "",
932
+ // Header props
933
+ showHeader = true,
934
+ showSidebarTrigger = true,
935
+ showThemeToggle = true,
936
+ themeToggleShortcut,
937
+ shortcutsVisible,
938
+ helpLink,
939
+ aboutLink,
940
+ headerActions,
941
+ headerLeading,
942
+ header: customHeader,
943
+ headerClassName,
944
+ // Floating user menu
945
+ showFloatingUserMenu = true,
946
+ // General props
947
+ className,
948
+ defaultOpen,
949
+ open,
950
+ onOpenChange,
951
+ LinkComponent,
952
+ ShortcutComponent,
953
+ userMenuShortcut,
954
+ onNavigate,
955
+ enableNavShortcuts = true
956
+ }) {
957
+ const sidebarElement = customSidebar ?? /* @__PURE__ */ jsxRuntime.jsx(
958
+ AppSidebar,
959
+ {
960
+ navItems,
961
+ pathname,
962
+ user,
963
+ userMenuItems,
964
+ userLoading,
965
+ header: sidebarHeader,
966
+ onSignOut,
967
+ signInHref,
968
+ collapsible: sidebarCollapsible,
969
+ LinkComponent,
970
+ ShortcutComponent,
971
+ userMenuShortcut,
972
+ onNavigate,
973
+ enableKeyboardShortcuts: enableNavShortcuts,
974
+ shortcutsVisible
975
+ }
976
+ );
977
+ const headerElement = customHeader !== void 0 ? customHeader : showHeader ? /* @__PURE__ */ jsxRuntime.jsx(
978
+ AppHeader,
979
+ {
980
+ showSidebarTrigger,
981
+ showThemeToggle,
982
+ themeToggleShortcut,
983
+ shortcutsVisible,
984
+ helpLink,
985
+ aboutLink,
986
+ actions: headerActions,
987
+ leadingContent: headerLeading,
988
+ className: headerClassName,
989
+ LinkComponent,
990
+ ShortcutComponent
991
+ }
992
+ ) : null;
993
+ return /* @__PURE__ */ jsxRuntime.jsxs(
994
+ chunkE42B4GSB_js.SidebarProvider,
995
+ {
996
+ defaultOpen,
997
+ open,
998
+ onOpenChange,
999
+ className: chunkADIDI7AJ_js.cn("h-dvh", className),
1000
+ children: [
1001
+ sidebarElement,
1002
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkE42B4GSB_js.SidebarInset, { children: [
1003
+ headerElement,
1004
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto overflow-x-hidden min-w-0", children })
1005
+ ] }),
1006
+ showFloatingUserMenu && /* @__PURE__ */ jsxRuntime.jsx(
1007
+ FloatingUserMenu,
1008
+ {
1009
+ user,
1010
+ menuItems: userMenuItems,
1011
+ loading: userLoading,
1012
+ onSignOut,
1013
+ pathname,
1014
+ LinkComponent
1015
+ }
1016
+ )
1017
+ ]
1018
+ }
1019
+ );
1020
+ }
1021
+ function DashboardGrid({ children, className }) {
1022
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkADIDI7AJ_js.cn("flex flex-col gap-6", className), children });
1023
+ }
1024
+ function HelpLayout({
1025
+ children,
1026
+ panel,
1027
+ isOpen,
1028
+ className
1029
+ }) {
1030
+ return (
1031
+ // Inherits height from parent (h-full), handles horizontal layout only
1032
+ // min-h-0 allows shrinking below content size for proper overflow handling
1033
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkADIDI7AJ_js.cn("flex h-full min-h-0", className), children: [
1034
+ /* @__PURE__ */ jsxRuntime.jsx(
1035
+ "div",
1036
+ {
1037
+ className: chunkADIDI7AJ_js.cn(
1038
+ "h-full min-h-0 min-w-0 flex-1 transition-all duration-200 ease-out",
1039
+ isOpen && "sm:mr-100"
1040
+ ),
1041
+ children
1042
+ }
1043
+ ),
1044
+ panel
1045
+ ] })
1046
+ );
1047
+ }
1048
+ function HelpPageLayout({
1049
+ breadcrumbs = [],
1050
+ title,
1051
+ description,
1052
+ children,
1053
+ sidebar,
1054
+ relatedContent,
1055
+ className,
1056
+ contentClassName,
1057
+ homeHref = "/admin/help"
1058
+ }) {
1059
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1060
+ "div",
1061
+ {
1062
+ className: chunkADIDI7AJ_js.cn(
1063
+ "flex flex-1 flex-col gap-6 p-4 max-w-7xl w-full",
1064
+ className
1065
+ ),
1066
+ children: [
1067
+ /* @__PURE__ */ jsxRuntime.jsxs(
1068
+ "nav",
1069
+ {
1070
+ "aria-label": "Breadcrumb",
1071
+ className: "flex items-center text-sm text-muted-foreground",
1072
+ children: [
1073
+ /* @__PURE__ */ jsxRuntime.jsxs(
1074
+ Link2__default.default,
1075
+ {
1076
+ href: homeHref,
1077
+ className: "flex items-center hover:text-foreground transition-colors",
1078
+ "data-prevent-help-intercept": "true",
1079
+ children: [
1080
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Home, { className: "size-4 mr-2" }),
1081
+ "Help Center"
1082
+ ]
1083
+ }
1084
+ ),
1085
+ breadcrumbs.map((crumb, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
1086
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "size-4 mx-2" }),
1087
+ /* @__PURE__ */ jsxRuntime.jsx(
1088
+ Link2__default.default,
1089
+ {
1090
+ href: crumb.href,
1091
+ className: chunkADIDI7AJ_js.cn(
1092
+ "hover:text-foreground transition-colors",
1093
+ index === breadcrumbs.length - 1 && "text-foreground font-medium pointer-events-none"
1094
+ ),
1095
+ children: crumb.label
1096
+ }
1097
+ )
1098
+ ] }, crumb.href))
1099
+ ]
1100
+ }
1101
+ ),
1102
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col lg:flex-row gap-8 lg:gap-12", children: [
1103
+ sidebar && /* @__PURE__ */ jsxRuntime.jsx("aside", { className: "w-full lg:w-64 shrink-0 hidden lg:block", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-8", children: sidebar }) }),
1104
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
1105
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 mb-8", children: [
1106
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-bold tracking-tight", children: title }),
1107
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg text-muted-foreground max-w-3xl", children: description })
1108
+ ] }),
1109
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: contentClassName, children }),
1110
+ relatedContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-8 border-t mt-8", children: relatedContent })
1111
+ ] })
1112
+ ] })
1113
+ ]
1114
+ }
1115
+ );
1116
+ }
1117
+ function HelpPanelLayout({
1118
+ isOpen,
1119
+ onClose,
1120
+ onBack,
1121
+ canGoBack,
1122
+ searchQuery,
1123
+ onSearchChange,
1124
+ children,
1125
+ footer,
1126
+ className
1127
+ }) {
1128
+ const searchInputRef = React.useRef(null);
1129
+ const [isSearchExpanded, setIsSearchExpanded] = React.useState(false);
1130
+ React.useEffect(() => {
1131
+ if (isOpen && isSearchExpanded && searchInputRef.current) {
1132
+ setTimeout(() => {
1133
+ searchInputRef.current?.focus();
1134
+ }, 50);
1135
+ }
1136
+ }, [isOpen, isSearchExpanded]);
1137
+ React.useEffect(() => {
1138
+ if (searchQuery) {
1139
+ setIsSearchExpanded(true);
1140
+ }
1141
+ }, [searchQuery]);
1142
+ if (!isOpen) return null;
1143
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1144
+ "aside",
1145
+ {
1146
+ className: chunkADIDI7AJ_js.cn(
1147
+ "fixed right-0 top-0 z-40 h-full w-full sm:w-[400px] bg-background border-l shadow-xl",
1148
+ "flex flex-col",
1149
+ "animate-in slide-in-from-right duration-200",
1150
+ className
1151
+ ),
1152
+ "aria-label": "Help panel",
1153
+ children: [
1154
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-14 items-center justify-between gap-3 border-b px-3", children: [
1155
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [
1156
+ canGoBack && /* @__PURE__ */ jsxRuntime.jsx(
1157
+ "button",
1158
+ {
1159
+ type: "button",
1160
+ className: "text-muted-foreground hover:text-foreground transition-colors",
1161
+ onClick: onBack,
1162
+ "aria-label": "Go back",
1163
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { className: "size-4 transition-transform duration-300 hover:-translate-x-0.5" })
1164
+ }
1165
+ ),
1166
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs(
1167
+ "div",
1168
+ {
1169
+ className: chunkADIDI7AJ_js.cn(
1170
+ "relative flex items-center rounded-md border border-transparent transition-all duration-300 ease-out",
1171
+ isSearchExpanded ? "flex-1 border-input bg-background" : "w-7 hover:bg-accent/50 cursor-pointer"
1172
+ ),
1173
+ children: [
1174
+ /* @__PURE__ */ jsxRuntime.jsx(
1175
+ "button",
1176
+ {
1177
+ type: "button",
1178
+ onMouseDown: (e) => {
1179
+ if (isSearchExpanded) {
1180
+ e.preventDefault();
1181
+ }
1182
+ },
1183
+ onClick: () => {
1184
+ if (isSearchExpanded) {
1185
+ onSearchChange("");
1186
+ setIsSearchExpanded(false);
1187
+ } else {
1188
+ setIsSearchExpanded(true);
1189
+ }
1190
+ },
1191
+ className: "flex size-7 items-center justify-center shrink-0 cursor-pointer",
1192
+ "aria-label": isSearchExpanded ? "Close search" : "Search help",
1193
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "size-4 text-muted-foreground" })
1194
+ }
1195
+ ),
1196
+ /* @__PURE__ */ jsxRuntime.jsx(
1197
+ "input",
1198
+ {
1199
+ ref: searchInputRef,
1200
+ type: "text",
1201
+ placeholder: "Search help...",
1202
+ value: searchQuery,
1203
+ onChange: (e) => onSearchChange(e.target.value),
1204
+ onBlur: () => {
1205
+ if (!searchQuery) {
1206
+ setIsSearchExpanded(false);
1207
+ }
1208
+ },
1209
+ onKeyDown: (e) => {
1210
+ if (e.key === "Escape") {
1211
+ onSearchChange("");
1212
+ setIsSearchExpanded(false);
1213
+ }
1214
+ },
1215
+ className: chunkADIDI7AJ_js.cn(
1216
+ "h-7 bg-transparent text-sm outline-none placeholder:text-muted-foreground transition-all duration-300",
1217
+ isSearchExpanded ? "w-full pr-7 opacity-100" : "w-0 opacity-0 p-0"
1218
+ )
1219
+ }
1220
+ ),
1221
+ /* @__PURE__ */ jsxRuntime.jsx(
1222
+ "div",
1223
+ {
1224
+ className: chunkADIDI7AJ_js.cn(
1225
+ "absolute right-1.5 transition-opacity duration-200",
1226
+ isSearchExpanded && searchQuery ? "opacity-100" : "opacity-0 pointer-events-none"
1227
+ ),
1228
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1229
+ "button",
1230
+ {
1231
+ type: "button",
1232
+ onClick: (e) => {
1233
+ e.stopPropagation();
1234
+ onSearchChange("");
1235
+ searchInputRef.current?.focus();
1236
+ },
1237
+ className: "flex items-center justify-center size-5 rounded-sm text-muted-foreground hover:text-foreground hover:bg-accent/50 transition-colors",
1238
+ "aria-label": "Clear search",
1239
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-3.5" })
1240
+ }
1241
+ )
1242
+ }
1243
+ )
1244
+ ]
1245
+ }
1246
+ ) })
1247
+ ] }),
1248
+ /* @__PURE__ */ jsxRuntime.jsx(
1249
+ "button",
1250
+ {
1251
+ type: "button",
1252
+ onClick: onClose,
1253
+ className: "text-muted-foreground hover:text-foreground transition-colors",
1254
+ "aria-label": "Close help",
1255
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-4 transition-transform duration-300 hover:rotate-90" })
1256
+ }
1257
+ )
1258
+ ] }),
1259
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children }) }),
1260
+ footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t px-3 py-2", children: footer })
1261
+ ]
1262
+ }
1263
+ );
1264
+ }
1265
+ function LegalLayout({
1266
+ title,
1267
+ lastUpdated,
1268
+ archiveUrl,
1269
+ backHref,
1270
+ backLabel = "Back",
1271
+ tableOfContents,
1272
+ children,
1273
+ className
1274
+ }) {
1275
+ const [activeSection, setActiveSection] = React.useState("");
1276
+ const hasMetadata = Boolean(lastUpdated || archiveUrl);
1277
+ React.useEffect(() => {
1278
+ if (!tableOfContents || tableOfContents.length === 0) return;
1279
+ const observer = new IntersectionObserver(
1280
+ (entries) => {
1281
+ for (const entry of entries) {
1282
+ if (entry.isIntersecting) {
1283
+ setActiveSection(entry.target.id);
1284
+ }
1285
+ }
1286
+ },
1287
+ {
1288
+ rootMargin: "-80px 0px -70% 0px",
1289
+ threshold: 0
1290
+ }
1291
+ );
1292
+ for (const item of tableOfContents) {
1293
+ const element = document.getElementById(item.id);
1294
+ if (element) {
1295
+ observer.observe(element);
1296
+ }
1297
+ }
1298
+ return () => observer.disconnect();
1299
+ }, [tableOfContents]);
1300
+ const scrollToSection = (event, sectionId) => {
1301
+ const target = document.getElementById(sectionId);
1302
+ if (!target) {
1303
+ return;
1304
+ }
1305
+ event.preventDefault();
1306
+ const prefersReducedMotion = typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
1307
+ const targetHeading = target.querySelector("h2, h3, h4, h5, h6") ?? target;
1308
+ const stickyHeader = document.querySelector(
1309
+ '[data-slot="legal-page-header"]'
1310
+ );
1311
+ const stickyHeaderBottom = stickyHeader?.getBoundingClientRect().bottom ?? 0;
1312
+ const targetTop = targetHeading.getBoundingClientRect().top + window.scrollY - stickyHeaderBottom - 8;
1313
+ window.scrollTo({
1314
+ top: Math.max(targetTop, 0),
1315
+ behavior: prefersReducedMotion ? "auto" : "smooth"
1316
+ });
1317
+ window.history.pushState(null, "", `#${sectionId}`);
1318
+ setActiveSection(sectionId);
1319
+ };
1320
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1321
+ "div",
1322
+ {
1323
+ className: chunkADIDI7AJ_js.cn(
1324
+ "mx-auto max-w-7xl px-4 pb-8 sm:px-6 lg:px-8",
1325
+ "print:max-w-none print:px-0",
1326
+ className
1327
+ ),
1328
+ children: [
1329
+ /* @__PURE__ */ jsxRuntime.jsx(
1330
+ "header",
1331
+ {
1332
+ "data-slot": "legal-page-header",
1333
+ className: chunkADIDI7AJ_js.cn(
1334
+ "sticky top-[3px] z-20 -mx-4 mb-8 border-b border-border bg-background px-4 py-5 sm:-mx-6 sm:px-6 lg:-mx-8 lg:mb-10 lg:px-8",
1335
+ "print:static print:mb-6 print:border-b print:bg-transparent print:p-0 print:backdrop-blur-none"
1336
+ ),
1337
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
1338
+ backHref && /* @__PURE__ */ jsxRuntime.jsxs(
1339
+ "a",
1340
+ {
1341
+ href: backHref,
1342
+ className: "inline-flex w-fit items-center gap-2 text-sm font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background print:hidden",
1343
+ children: [
1344
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { className: "h-4 w-4", "aria-hidden": "true" }),
1345
+ backLabel
1346
+ ]
1347
+ }
1348
+ ),
1349
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between", children: [
1350
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-4xl font-bold tracking-tight text-foreground sm:text-5xl print:text-3xl", children: title }),
1351
+ hasMetadata && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-x-4 gap-y-2 text-sm text-muted-foreground sm:justify-end", children: [
1352
+ lastUpdated && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1353
+ "Last updated: ",
1354
+ lastUpdated
1355
+ ] }),
1356
+ archiveUrl && /* @__PURE__ */ jsxRuntime.jsxs(
1357
+ "a",
1358
+ {
1359
+ href: archiveUrl,
1360
+ className: "inline-flex items-center gap-1.5 text-primary hover:underline print:hidden",
1361
+ children: [
1362
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-3.5 w-3.5" }),
1363
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "View version history" })
1364
+ ]
1365
+ }
1366
+ )
1367
+ ] })
1368
+ ] })
1369
+ ] })
1370
+ },
1371
+ "legal-page-header"
1372
+ ),
1373
+ /* @__PURE__ */ jsxRuntime.jsxs(
1374
+ "div",
1375
+ {
1376
+ className: "lg:grid lg:grid-cols-12 lg:gap-8",
1377
+ children: [
1378
+ tableOfContents && tableOfContents.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("aside", { className: "hidden lg:col-span-3 lg:sticky lg:top-[10.5rem] lg:block lg:max-h-[calc(100vh-11.5rem)] lg:self-start lg:overflow-y-auto print:hidden", children: /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "space-y-1", "aria-label": "Table of contents", children: [
1379
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold text-foreground mb-4", children: "On this page" }),
1380
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-2", children: tableOfContents.map((item) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
1381
+ "a",
1382
+ {
1383
+ href: `#${item.id}`,
1384
+ onClick: (event) => scrollToSection(event, item.id),
1385
+ className: chunkADIDI7AJ_js.cn(
1386
+ "block text-sm transition-all duration-200 py-1",
1387
+ "border-l-2 pl-3 -ml-px",
1388
+ activeSection === item.id ? "text-primary border-primary font-medium" : "text-muted-foreground border-transparent hover:text-foreground hover:border-muted-foreground/50"
1389
+ ),
1390
+ children: item.title
1391
+ }
1392
+ ) }, item.id)) })
1393
+ ] }) }),
1394
+ /* @__PURE__ */ jsxRuntime.jsxs(
1395
+ "main",
1396
+ {
1397
+ className: chunkADIDI7AJ_js.cn(
1398
+ tableOfContents && tableOfContents.length > 0 ? "lg:col-span-9" : "lg:col-span-12",
1399
+ "print:col-span-12"
1400
+ ),
1401
+ children: [
1402
+ tableOfContents && tableOfContents.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
1403
+ "nav",
1404
+ {
1405
+ className: "mb-8 rounded-lg border border-border bg-muted/30 p-4 lg:hidden print:hidden",
1406
+ "aria-label": "Table of contents",
1407
+ children: [
1408
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold text-foreground mb-3", children: "On this page" }),
1409
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-2", children: tableOfContents.map((item) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
1410
+ "a",
1411
+ {
1412
+ href: `#${item.id}`,
1413
+ onClick: (event) => scrollToSection(event, item.id),
1414
+ className: "block text-sm text-muted-foreground hover:text-foreground transition-colors",
1415
+ children: item.title
1416
+ }
1417
+ ) }, item.id)) })
1418
+ ]
1419
+ }
1420
+ ),
1421
+ /* @__PURE__ */ jsxRuntime.jsx(
1422
+ "div",
1423
+ {
1424
+ className: chunkADIDI7AJ_js.cn(
1425
+ "prose prose-slate dark:prose-invert max-w-none",
1426
+ // Headings
1427
+ "prose-headings:scroll-mt-32 prose-headings:font-semibold",
1428
+ "prose-h2:text-2xl prose-h2:mt-8 prose-h2:mb-2",
1429
+ "prose-h3:text-xl prose-h3:mt-6 prose-h3:mb-2",
1430
+ // Paragraphs - reduced top margin
1431
+ "prose-p:text-base prose-p:leading-7 prose-p:mb-4 prose-p:mt-0",
1432
+ // Links - explicit styling for visibility (but not on section header links)
1433
+ "[&>section>a]:no-underline [&>section>a:hover]:no-underline",
1434
+ "prose-a:text-primary prose-a:underline prose-a:underline-offset-2",
1435
+ "hover:prose-a:text-primary/80",
1436
+ // Lists - ensure bullets/numbers are visible
1437
+ "prose-ul:my-4 prose-ul:list-disc prose-ul:pl-6 prose-ul:space-y-2",
1438
+ "prose-ol:my-4 prose-ol:list-decimal prose-ol:pl-6 prose-ol:space-y-2",
1439
+ "prose-li:my-0 prose-li:pl-2",
1440
+ // Strong text
1441
+ "prose-strong:font-semibold prose-strong:text-foreground",
1442
+ // Print styles
1443
+ "print:prose-headings:text-black print:prose-p:text-black",
1444
+ "print:prose-h2:text-xl print:prose-h3:text-lg"
1445
+ ),
1446
+ children
1447
+ }
1448
+ )
1449
+ ]
1450
+ }
1451
+ )
1452
+ ]
1453
+ },
1454
+ "legal-page-content"
1455
+ )
1456
+ ]
1457
+ }
1458
+ );
1459
+ }
1460
+ function LegalSection({
1461
+ id,
1462
+ title,
1463
+ children,
1464
+ className
1465
+ }) {
1466
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { id, className: chunkADIDI7AJ_js.cn("mb-8 scroll-mt-20 print:mb-6", className), children: [
1467
+ /* @__PURE__ */ jsxRuntime.jsxs(
1468
+ "a",
1469
+ {
1470
+ href: `#${id}`,
1471
+ className: "group inline-flex items-center gap-2 no-underline hover:no-underline text-foreground print:no-underline mb-4",
1472
+ children: [
1473
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold border-b border-muted-foreground/30 group-hover:border-foreground pb-1 print:text-xl print:border-0 my-0!", children: title }),
1474
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link2, { className: "h-5 w-5 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity print:hidden shrink-0" })
1475
+ ]
1476
+ }
1477
+ ),
1478
+ children
1479
+ ] });
1480
+ }
1481
+ function MarketingLayout({
1482
+ navbar,
1483
+ children,
1484
+ footer,
1485
+ mainClassName,
1486
+ className
1487
+ }) {
1488
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkADIDI7AJ_js.cn("flex min-h-screen flex-col", className), children: [
1489
+ navbar,
1490
+ /* @__PURE__ */ jsxRuntime.jsx("main", { className: chunkADIDI7AJ_js.cn("flex-1", mainClassName), children }),
1491
+ footer
1492
+ ] });
1493
+ }
1494
+ function Toaster({ ...props }) {
1495
+ return /* @__PURE__ */ jsxRuntime.jsx(sonner.Toaster, { ...props });
1496
+ }
1497
+ var themeScript = `
1498
+ (function() {
1499
+ try {
1500
+ var theme = localStorage.getItem('theme');
1501
+ var isDark =
1502
+ theme === 'dark' ||
1503
+ ((theme === 'system' || !theme) &&
1504
+ window.matchMedia('(prefers-color-scheme: dark)').matches);
1505
+ document.documentElement.classList.toggle('dark', isDark);
1506
+ } catch (e) {}
1507
+ })();
1508
+ `;
1509
+ function RootLayout({
1510
+ children,
1511
+ font,
1512
+ fontClassName = "",
1513
+ analytics,
1514
+ toast,
1515
+ className
1516
+ }) {
1517
+ const baseClasses = "font-sans min-h-dvh bg-background text-foreground flex flex-col antialiased overflow-x-hidden";
1518
+ const showToaster = toast?.enabled !== false;
1519
+ const toasterPosition = toast?.position ?? "bottom-right";
1520
+ let fontClasses = "";
1521
+ const fontStyles = {};
1522
+ if (font) {
1523
+ if (font.variables) {
1524
+ fontClasses = font.variables;
1525
+ }
1526
+ if (font.body) {
1527
+ fontStyles["--font-body"] = font.body;
1528
+ }
1529
+ if (font.headers) {
1530
+ fontStyles["--font-headers"] = font.headers;
1531
+ }
1532
+ if (font.mono) {
1533
+ fontStyles["--font-mono"] = font.mono;
1534
+ }
1535
+ }
1536
+ if (!font?.variables && fontClassName) {
1537
+ fontClasses = fontClassName;
1538
+ }
1539
+ const combinedClassName = [fontClasses, baseClasses, className].filter(Boolean).join(" ");
1540
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1541
+ "div",
1542
+ {
1543
+ className: combinedClassName,
1544
+ style: Object.keys(fontStyles).length > 0 ? fontStyles : void 0,
1545
+ suppressHydrationWarning: true,
1546
+ children: [
1547
+ analytics?.clarityProjectId && /* @__PURE__ */ jsxRuntime.jsx(ClarityAnalytics, { projectId: analytics.clarityProjectId }),
1548
+ analytics?.googleAnalyticsId && /* @__PURE__ */ jsxRuntime.jsx(GoogleAnalytics, { measurementId: analytics.googleAnalyticsId }),
1549
+ children,
1550
+ showToaster && /* @__PURE__ */ jsxRuntime.jsx(Toaster, { richColors: true, position: toasterPosition })
1551
+ ]
1552
+ }
1553
+ );
1554
+ }
1555
+ function UserPageLayout({
1556
+ title,
1557
+ description,
1558
+ actions,
1559
+ className,
1560
+ contentClassName,
1561
+ loading = false,
1562
+ loadingSkeleton,
1563
+ children,
1564
+ tabs,
1565
+ defaultTab,
1566
+ onTabChange,
1567
+ footer,
1568
+ backLink
1569
+ }) {
1570
+ const showHeader = !backLink && Boolean(title || description || actions);
1571
+ return /* @__PURE__ */ jsxRuntime.jsx(
1572
+ PageLayoutShell,
1573
+ {
1574
+ title,
1575
+ description,
1576
+ actions,
1577
+ className,
1578
+ contentClassName,
1579
+ footer,
1580
+ showHeader,
1581
+ beforeHeader: backLink ? /* @__PURE__ */ jsxRuntime.jsx(BackLink, { href: backLink.href, children: backLink.label }) : null,
1582
+ children: loading && loadingSkeleton ? loadingSkeleton : tabs && tabs.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
1583
+ chunkMVYRNJA6_js.Tabs,
1584
+ {
1585
+ defaultValue: defaultTab || tabs[0].value,
1586
+ onValueChange: onTabChange,
1587
+ className: "space-y-4",
1588
+ children: [
1589
+ /* @__PURE__ */ jsxRuntime.jsx(chunkMVYRNJA6_js.TabsList, { children: tabs.map((tab) => /* @__PURE__ */ jsxRuntime.jsxs(chunkMVYRNJA6_js.TabsTrigger, { value: tab.value, className: "gap-2", children: [
1590
+ tab.icon && /* @__PURE__ */ jsxRuntime.jsx(tab.icon, { className: "h-4 w-4" }),
1591
+ tab.label
1592
+ ] }, tab.value)) }),
1593
+ tabs.map((tab) => /* @__PURE__ */ jsxRuntime.jsx(chunkMVYRNJA6_js.TabsContent, { value: tab.value, className: "mt-2", children: tab.content }, tab.value))
1594
+ ]
1595
+ }
1596
+ ) : children
1597
+ }
1598
+ );
1599
+ }
1600
+ function AutoSaveIndicator({
1601
+ status,
1602
+ className,
1603
+ ...props
1604
+ }) {
1605
+ if (status === "idle") return null;
1606
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1607
+ "span",
1608
+ {
1609
+ className: chunkADIDI7AJ_js.cn(
1610
+ "inline-flex items-center gap-1.5 text-xs transition-opacity",
1611
+ className
1612
+ ),
1613
+ "aria-live": "polite",
1614
+ ...props,
1615
+ children: [
1616
+ status === "saving" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1617
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "w-3 h-3 animate-spin text-muted-foreground" }),
1618
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Saving..." })
1619
+ ] }),
1620
+ status === "saved" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1621
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "w-3 h-3 text-green-600" }),
1622
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-green-600", children: "Saved" })
1623
+ ] }),
1624
+ status === "error" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1625
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3 h-3 text-destructive" }),
1626
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive", children: "Save failed" })
1627
+ ] })
1628
+ ]
1629
+ }
1630
+ );
1631
+ }
1632
+ function ProgressBar({
1633
+ value,
1634
+ max = 100,
1635
+ showLabel = true,
1636
+ size = "md",
1637
+ className,
1638
+ ...props
1639
+ }) {
1640
+ const percentage = Math.min(Math.max(value / max * 100, 0), 100);
1641
+ const sizeClasses = {
1642
+ sm: "h-1.5",
1643
+ md: "h-2.5",
1644
+ lg: "h-4"
1645
+ };
1646
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkADIDI7AJ_js.cn("w-full", className), ...props, children: [
1647
+ showLabel && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center mb-1", children: [
1648
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-muted-foreground", children: "Application Progress" }),
1649
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-medium text-foreground", children: [
1650
+ Math.round(percentage),
1651
+ "%"
1652
+ ] })
1653
+ ] }),
1654
+ /* @__PURE__ */ jsxRuntime.jsx(
1655
+ "div",
1656
+ {
1657
+ className: chunkADIDI7AJ_js.cn(
1658
+ "w-full bg-muted rounded-full overflow-hidden",
1659
+ sizeClasses[size]
1660
+ ),
1661
+ role: "progressbar",
1662
+ "aria-valuenow": value,
1663
+ "aria-valuemin": 0,
1664
+ "aria-valuemax": max,
1665
+ "aria-label": `Application ${Math.round(percentage)}% complete`,
1666
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1667
+ "div",
1668
+ {
1669
+ className: chunkADIDI7AJ_js.cn(
1670
+ "h-full bg-primary rounded-full transition-all duration-300 ease-out"
1671
+ ),
1672
+ style: { width: `${percentage}%` }
1673
+ }
1674
+ )
1675
+ }
1676
+ )
1677
+ ] });
1678
+ }
1679
+ var stepperSizes = {
1680
+ default: {
1681
+ circle: "w-8 h-8",
1682
+ connector: "mx-4",
1683
+ gap: "gap-2",
1684
+ icon: "w-4 h-4",
1685
+ label: "text-sm",
1686
+ mobileLabel: "text-[11px]",
1687
+ number: "text-sm"
1688
+ },
1689
+ compact: {
1690
+ circle: "w-7 h-7",
1691
+ connector: "mx-2",
1692
+ gap: "gap-1.5",
1693
+ icon: "w-3.5 h-3.5",
1694
+ label: "text-xs",
1695
+ mobileLabel: "text-[11px]",
1696
+ number: "text-xs"
1697
+ }
1698
+ };
1699
+ function Stepper({
1700
+ steps,
1701
+ currentStep,
1702
+ completedSteps,
1703
+ onStepClick,
1704
+ mobileVariant = "summary",
1705
+ size = "default",
1706
+ className,
1707
+ ...props
1708
+ }) {
1709
+ const currentIndex = steps.findIndex((s) => s.id === currentStep);
1710
+ const styles = stepperSizes[size];
1711
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1712
+ "nav",
1713
+ {
1714
+ "aria-label": "Application progress",
1715
+ className: chunkADIDI7AJ_js.cn("w-full", className),
1716
+ ...props,
1717
+ children: [
1718
+ /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "hidden md:flex items-center w-full", children: steps.map((step, index) => {
1719
+ const isCompleted = completedSteps.includes(step.id);
1720
+ const isCurrent = step.id === currentStep;
1721
+ const isClickable = isCompleted || isCurrent;
1722
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1723
+ "li",
1724
+ {
1725
+ className: chunkADIDI7AJ_js.cn(
1726
+ "flex items-center",
1727
+ index < steps.length - 1 && "flex-1"
1728
+ ),
1729
+ children: [
1730
+ /* @__PURE__ */ jsxRuntime.jsxs(
1731
+ "button",
1732
+ {
1733
+ type: "button",
1734
+ onClick: () => isClickable && onStepClick?.(step.id),
1735
+ disabled: !isClickable,
1736
+ className: chunkADIDI7AJ_js.cn(
1737
+ "flex items-center group",
1738
+ styles.gap,
1739
+ isClickable && "cursor-pointer",
1740
+ !isClickable && "cursor-not-allowed opacity-50"
1741
+ ),
1742
+ "aria-current": isCurrent ? "step" : void 0,
1743
+ children: [
1744
+ /* @__PURE__ */ jsxRuntime.jsx(
1745
+ "span",
1746
+ {
1747
+ className: chunkADIDI7AJ_js.cn(
1748
+ "flex items-center justify-center rounded-full border-2 shrink-0 transition-colors",
1749
+ styles.circle,
1750
+ isCompleted && "bg-primary border-primary text-primary-foreground",
1751
+ isCurrent && !isCompleted && "border-primary text-primary bg-background",
1752
+ !isCompleted && !isCurrent && "border-muted-foreground/30 text-muted-foreground"
1753
+ ),
1754
+ children: isCompleted ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: styles.icon }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: chunkADIDI7AJ_js.cn(styles.number, "font-medium"), children: index + 1 })
1755
+ }
1756
+ ),
1757
+ /* @__PURE__ */ jsxRuntime.jsx(
1758
+ "span",
1759
+ {
1760
+ className: chunkADIDI7AJ_js.cn(
1761
+ "font-medium hidden lg:block",
1762
+ styles.label,
1763
+ isCurrent && "text-primary",
1764
+ !isCurrent && "text-muted-foreground",
1765
+ isClickable && "group-hover:text-foreground"
1766
+ ),
1767
+ children: step.label
1768
+ }
1769
+ )
1770
+ ]
1771
+ }
1772
+ ),
1773
+ index < steps.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
1774
+ "div",
1775
+ {
1776
+ className: chunkADIDI7AJ_js.cn(
1777
+ "flex-1 h-0.5",
1778
+ styles.connector,
1779
+ isCompleted ? "bg-primary" : "bg-muted"
1780
+ )
1781
+ }
1782
+ )
1783
+ ]
1784
+ },
1785
+ step.id
1786
+ );
1787
+ }) }),
1788
+ mobileVariant === "steps" ? /* @__PURE__ */ jsxRuntime.jsx(
1789
+ "ol",
1790
+ {
1791
+ "data-slot": "stepper-mobile-steps",
1792
+ className: "md:hidden flex items-start w-full",
1793
+ children: steps.map((step, index) => {
1794
+ const isCompleted = completedSteps.includes(step.id);
1795
+ const isCurrent = step.id === currentStep;
1796
+ const isClickable = isCompleted || isCurrent;
1797
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1798
+ "li",
1799
+ {
1800
+ className: chunkADIDI7AJ_js.cn(
1801
+ "flex items-start min-w-0",
1802
+ index < steps.length - 1 && "flex-1"
1803
+ ),
1804
+ children: [
1805
+ /* @__PURE__ */ jsxRuntime.jsxs(
1806
+ "button",
1807
+ {
1808
+ type: "button",
1809
+ onClick: () => isClickable && onStepClick?.(step.id),
1810
+ disabled: !isClickable,
1811
+ className: chunkADIDI7AJ_js.cn(
1812
+ "group flex min-w-0 flex-col items-center gap-1 text-center",
1813
+ isClickable && "cursor-pointer",
1814
+ !isClickable && "cursor-not-allowed opacity-50"
1815
+ ),
1816
+ "aria-current": isCurrent ? "step" : void 0,
1817
+ children: [
1818
+ /* @__PURE__ */ jsxRuntime.jsx(
1819
+ "span",
1820
+ {
1821
+ className: chunkADIDI7AJ_js.cn(
1822
+ "flex items-center justify-center rounded-full border-2 shrink-0 transition-colors",
1823
+ styles.circle,
1824
+ isCompleted && "bg-primary border-primary text-primary-foreground",
1825
+ isCurrent && !isCompleted && "border-primary text-primary bg-background",
1826
+ !isCompleted && !isCurrent && "border-muted-foreground/30 text-muted-foreground"
1827
+ ),
1828
+ children: isCompleted ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: styles.icon }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: chunkADIDI7AJ_js.cn(styles.number, "font-medium"), children: index + 1 })
1829
+ }
1830
+ ),
1831
+ /* @__PURE__ */ jsxRuntime.jsx(
1832
+ "span",
1833
+ {
1834
+ className: chunkADIDI7AJ_js.cn(
1835
+ "max-w-16 truncate font-medium leading-tight",
1836
+ styles.mobileLabel,
1837
+ isCurrent && "text-primary",
1838
+ !isCurrent && "text-muted-foreground",
1839
+ isClickable && "group-hover:text-foreground"
1840
+ ),
1841
+ children: step.label
1842
+ }
1843
+ )
1844
+ ]
1845
+ }
1846
+ ),
1847
+ index < steps.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
1848
+ "div",
1849
+ {
1850
+ className: chunkADIDI7AJ_js.cn(
1851
+ "mt-3.5 h-0.5 min-w-3 flex-1 mx-1",
1852
+ isCompleted ? "bg-primary" : "bg-muted"
1853
+ )
1854
+ }
1855
+ )
1856
+ ]
1857
+ },
1858
+ step.id
1859
+ );
1860
+ })
1861
+ }
1862
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:hidden flex items-center justify-between", children: [
1863
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-medium text-muted-foreground", children: [
1864
+ "Step ",
1865
+ currentIndex + 1,
1866
+ " of ",
1867
+ steps.length
1868
+ ] }),
1869
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: steps[currentIndex]?.label })
1870
+ ] })
1871
+ ]
1872
+ }
1873
+ );
1874
+ }
1875
+ function TimeEstimate({ minutes, className, ...props }) {
1876
+ const displayText = minutes < 1 ? "Less than a minute" : minutes === 1 ? "~1 minute" : `~${Math.round(minutes)} minutes`;
1877
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1878
+ "div",
1879
+ {
1880
+ className: chunkADIDI7AJ_js.cn(
1881
+ "flex items-center gap-1.5 text-sm text-muted-foreground",
1882
+ className
1883
+ ),
1884
+ ...props,
1885
+ children: [
1886
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "w-4 h-4" }),
1887
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1888
+ "Estimated time remaining: ",
1889
+ displayText
1890
+ ] })
1891
+ ]
1892
+ }
1893
+ );
1894
+ }
1895
+ function WizardLayout({
1896
+ children,
1897
+ steps,
1898
+ currentStep,
1899
+ completedSteps,
1900
+ onStepClick,
1901
+ progress,
1902
+ timeRemaining,
1903
+ saveStatus = "idle",
1904
+ deadline,
1905
+ isSubmitted = false,
1906
+ submittedTitle = "Your application has been submitted",
1907
+ submittedSubtitle = "You will receive an email confirmation shortly.",
1908
+ loading = false,
1909
+ loadingMessage = "Loading...",
1910
+ error,
1911
+ className
1912
+ }) {
1913
+ const [daysRemaining, setDaysRemaining] = React.useState(null);
1914
+ React.useEffect(() => {
1915
+ if (deadline?.daysRemaining !== void 0) {
1916
+ setDaysRemaining(deadline.daysRemaining);
1917
+ }
1918
+ }, [deadline?.daysRemaining]);
1919
+ if (loading) {
1920
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center min-h-[400px]", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-pulse text-muted-foreground", children: loadingMessage }) });
1921
+ }
1922
+ if (error) {
1923
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center min-h-[400px] gap-4", children: [
1924
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { className: "w-12 h-12 text-destructive" }),
1925
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-destructive", children: error })
1926
+ ] });
1927
+ }
1928
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkADIDI7AJ_js.cn("max-w-4xl mx-auto px-4 py-8", className), children: [
1929
+ deadline && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
1930
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold mb-1", children: deadline.label }),
1931
+ daysRemaining !== null && daysRemaining <= 7 && !isSubmitted && /* @__PURE__ */ jsxRuntime.jsx(
1932
+ "div",
1933
+ {
1934
+ className: chunkADIDI7AJ_js.cn(
1935
+ "text-sm",
1936
+ daysRemaining <= 1 ? "text-destructive font-medium" : "text-amber-600"
1937
+ ),
1938
+ children: daysRemaining <= 0 ? "Applications close today!" : daysRemaining === 1 ? "1 day remaining to submit" : `${daysRemaining} days remaining to submit`
1939
+ }
1940
+ )
1941
+ ] }),
1942
+ !isSubmitted && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-8 space-y-4", children: [
1943
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
1944
+ /* @__PURE__ */ jsxRuntime.jsx(ProgressBar, { value: progress, size: "md" }),
1945
+ /* @__PURE__ */ jsxRuntime.jsx(AutoSaveIndicator, { status: saveStatus, className: "ml-4" })
1946
+ ] }),
1947
+ timeRemaining !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(TimeEstimate, { minutes: timeRemaining })
1948
+ ] }),
1949
+ /* @__PURE__ */ jsxRuntime.jsx(
1950
+ Stepper,
1951
+ {
1952
+ steps,
1953
+ currentStep,
1954
+ completedSteps: isSubmitted ? steps.map((s) => s.id) : completedSteps,
1955
+ onStepClick: isSubmitted ? void 0 : onStepClick,
1956
+ className: "mb-8"
1957
+ }
1958
+ ),
1959
+ isSubmitted && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6 p-4 bg-green-50 dark:bg-green-950 border border-green-200 dark:border-green-800 rounded-lg", children: [
1960
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-green-800 dark:text-green-200 font-medium", children: [
1961
+ "\u2713 ",
1962
+ submittedTitle
1963
+ ] }),
1964
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-green-600 dark:text-green-400 mt-1", children: submittedSubtitle })
1965
+ ] }),
1966
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-card border rounded-lg p-6", children })
1967
+ ] });
1968
+ }
1969
+
1970
+ exports.AdminPageLayout = AdminPageLayout;
1971
+ exports.AppFooter = AppFooter;
1972
+ exports.AppHeader = AppHeader;
1973
+ exports.AppLayout = AppLayout;
1974
+ exports.AppSidebar = AppSidebar;
1975
+ exports.AutoSaveIndicator = AutoSaveIndicator;
1976
+ exports.BackLink = BackLink;
1977
+ exports.BasePageLayout = BasePageLayout;
1978
+ exports.ClarityAnalytics = ClarityAnalytics;
1979
+ exports.Collapsible = Collapsible;
1980
+ exports.CollapsibleContent = CollapsibleContent2;
1981
+ exports.CollapsibleTrigger = CollapsibleTrigger2;
1982
+ exports.DashboardGrid = DashboardGrid;
1983
+ exports.FloatingUserMenu = FloatingUserMenu;
1984
+ exports.GoogleAnalytics = GoogleAnalytics;
1985
+ exports.GoogleTagManager = GoogleTagManager;
1986
+ exports.HelpLayout = HelpLayout;
1987
+ exports.HelpPageLayout = HelpPageLayout;
1988
+ exports.HelpPanelLayout = HelpPanelLayout;
1989
+ exports.LegalLayout = LegalLayout;
1990
+ exports.LegalSection = LegalSection;
1991
+ exports.MarketingLayout = MarketingLayout;
1992
+ exports.ProgressBar = ProgressBar;
1993
+ exports.RootLayout = RootLayout;
1994
+ exports.Stepper = Stepper;
1995
+ exports.ThemeToggle = ThemeToggle;
1996
+ exports.TimeEstimate = TimeEstimate;
1997
+ exports.Toaster = Toaster;
1998
+ exports.UserPageLayout = UserPageLayout;
1999
+ exports.WizardLayout = WizardLayout;
2000
+ exports.isNavDivider = isNavDivider;
2001
+ exports.isNavItem = isNavItem;
2002
+ exports.isNavSection = isNavSection;
2003
+ exports.themeScript = themeScript;
2004
+ exports.useTheme = useTheme;