@fayz-ai/ui 0.6.0 → 0.7.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 (88) hide show
  1. package/dist/chunk-75EFDLST.js +274 -0
  2. package/dist/chunk-75EFDLST.js.map +1 -0
  3. package/dist/{chunk-YB5ZJKNG.cjs → chunk-7PTRAWHO.cjs} +263 -225
  4. package/dist/chunk-7PTRAWHO.cjs.map +1 -0
  5. package/dist/{chunk-CZ6X6PZT.js → chunk-COC5DDFG.js} +313 -44
  6. package/dist/chunk-COC5DDFG.js.map +1 -0
  7. package/dist/{chunk-MYZT2OG7.js → chunk-FY7OZNKU.js} +24 -68
  8. package/dist/chunk-FY7OZNKU.js.map +1 -0
  9. package/dist/chunk-H6OULCHF.cjs +81 -0
  10. package/dist/chunk-H6OULCHF.cjs.map +1 -0
  11. package/dist/{chunk-GE6XUREM.cjs → chunk-HG5RH3B3.cjs} +339 -68
  12. package/dist/chunk-HG5RH3B3.cjs.map +1 -0
  13. package/dist/{chunk-7TBDPNLY.cjs → chunk-NWPMNPGR.cjs} +76 -47
  14. package/dist/chunk-NWPMNPGR.cjs.map +1 -0
  15. package/dist/{chunk-D6SXPF4F.cjs → chunk-ODY3GZ3Y.cjs} +41 -87
  16. package/dist/chunk-ODY3GZ3Y.cjs.map +1 -0
  17. package/dist/{chunk-22J2RTMN.js → chunk-OTUH4K4B.js} +196 -150
  18. package/dist/chunk-OTUH4K4B.js.map +1 -0
  19. package/dist/chunk-OW73RZOU.cjs +313 -0
  20. package/dist/chunk-OW73RZOU.cjs.map +1 -0
  21. package/dist/{chunk-GFH5HOCO.js → chunk-W5O2X277.js} +42 -14
  22. package/dist/chunk-W5O2X277.js.map +1 -0
  23. package/dist/chunk-YRVE4FOD.js +57 -0
  24. package/dist/chunk-YRVE4FOD.js.map +1 -0
  25. package/dist/dashboard/DashboardCanvas.d.ts +5 -1
  26. package/dist/dashboard/DashboardCanvas.d.ts.map +1 -1
  27. package/dist/dashboard/GoldCard.d.ts +19 -0
  28. package/dist/dashboard/GoldCard.d.ts.map +1 -0
  29. package/dist/dashboard/KpiCard.d.ts.map +1 -1
  30. package/dist/dashboard/index.cjs +30 -26
  31. package/dist/dashboard/index.d.ts +1 -0
  32. package/dist/dashboard/index.d.ts.map +1 -1
  33. package/dist/dashboard/index.js +3 -3
  34. package/dist/index.cjs +198 -174
  35. package/dist/index.d.ts +3 -3
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +7 -7
  38. package/dist/layout/AppShell.d.ts +27 -6
  39. package/dist/layout/AppShell.d.ts.map +1 -1
  40. package/dist/layout/ContentSplit.d.ts +32 -0
  41. package/dist/layout/ContentSplit.d.ts.map +1 -0
  42. package/dist/layout/Sidebar.d.ts.map +1 -1
  43. package/dist/layout/Topbar.d.ts.map +1 -1
  44. package/dist/layout/index.cjs +31 -23
  45. package/dist/layout/index.d.ts +2 -1
  46. package/dist/layout/index.d.ts.map +1 -1
  47. package/dist/layout/index.js +3 -3
  48. package/dist/primitives/index.cjs +126 -114
  49. package/dist/primitives/index.d.ts +2 -0
  50. package/dist/primitives/index.d.ts.map +1 -1
  51. package/dist/primitives/index.js +4 -4
  52. package/dist/primitives/markdown-editor.d.ts +23 -0
  53. package/dist/primitives/markdown-editor.d.ts.map +1 -0
  54. package/dist/primitives/markdown.d.ts +9 -0
  55. package/dist/primitives/markdown.d.ts.map +1 -0
  56. package/package.json +3 -3
  57. package/src/dashboard/DashboardCanvas.tsx +13 -2
  58. package/src/dashboard/GoldCard.tsx +38 -0
  59. package/src/dashboard/KpiCard.tsx +4 -2
  60. package/src/dashboard/index.ts +1 -0
  61. package/src/index.ts +15 -0
  62. package/src/layout/AppShell.tsx +240 -20
  63. package/src/layout/ContentSplit.tsx +153 -0
  64. package/src/layout/ModulePage.tsx +2 -2
  65. package/src/layout/Sidebar.tsx +71 -20
  66. package/src/layout/Topbar.tsx +47 -17
  67. package/src/layout/index.ts +15 -1
  68. package/src/primitives/dropdown.tsx +4 -4
  69. package/src/primitives/index.ts +2 -0
  70. package/src/primitives/markdown-editor.tsx +75 -0
  71. package/src/primitives/markdown.tsx +169 -0
  72. package/src/primitives/select.tsx +1 -1
  73. package/dist/chunk-22J2RTMN.js.map +0 -1
  74. package/dist/chunk-7TBDPNLY.cjs.map +0 -1
  75. package/dist/chunk-CZ6X6PZT.js.map +0 -1
  76. package/dist/chunk-D6SXPF4F.cjs.map +0 -1
  77. package/dist/chunk-DNYVEOAX.js +0 -11
  78. package/dist/chunk-DNYVEOAX.js.map +0 -1
  79. package/dist/chunk-E526FHZ4.js +0 -169
  80. package/dist/chunk-E526FHZ4.js.map +0 -1
  81. package/dist/chunk-GE6XUREM.cjs.map +0 -1
  82. package/dist/chunk-GFH5HOCO.js.map +0 -1
  83. package/dist/chunk-MYZT2OG7.js.map +0 -1
  84. package/dist/chunk-VVVZO2LE.cjs +0 -13
  85. package/dist/chunk-VVVZO2LE.cjs.map +0 -1
  86. package/dist/chunk-W4XXXJRW.cjs +0 -196
  87. package/dist/chunk-W4XXXJRW.cjs.map +0 -1
  88. package/dist/chunk-YB5ZJKNG.cjs.map +0 -1
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkW4XXXJRW_cjs = require('./chunk-W4XXXJRW.cjs');
4
- var chunkVVVZO2LE_cjs = require('./chunk-VVVZO2LE.cjs');
3
+ var chunkOW73RZOU_cjs = require('./chunk-OW73RZOU.cjs');
4
+ var chunkH6OULCHF_cjs = require('./chunk-H6OULCHF.cjs');
5
5
  var React3 = require('react');
6
6
  var lucideReact = require('lucide-react');
7
7
  var Tooltip = require('@radix-ui/react-tooltip');
@@ -50,7 +50,9 @@ var ICON_MAP = {
50
50
  CreditCard: lucideReact.CreditCard,
51
51
  Bell: lucideReact.Bell,
52
52
  Calendar: lucideReact.Calendar,
53
+ CalendarClock: lucideReact.CalendarClock,
53
54
  Package: lucideReact.Package,
55
+ Activity: lucideReact.Activity,
54
56
  BarChart3: lucideReact.BarChart3,
55
57
  FileText: lucideReact.FileText,
56
58
  Mail: lucideReact.Mail,
@@ -59,28 +61,39 @@ var ICON_MAP = {
59
61
  ShoppingCart: lucideReact.ShoppingCart,
60
62
  Target: lucideReact.Target,
61
63
  Wrench: lucideReact.Wrench,
64
+ Receipt: lucideReact.Receipt,
65
+ ShoppingBag: lucideReact.ShoppingBag,
62
66
  ClipboardList: lucideReact.ClipboardList,
67
+ ListChecks: lucideReact.ListChecks,
63
68
  Briefcase: lucideReact.Briefcase,
64
69
  UserCog: lucideReact.UserCog,
65
70
  BookOpen: lucideReact.BookOpen,
71
+ BookOpenCheck: lucideReact.BookOpenCheck,
66
72
  MessageCircle: lucideReact.MessageCircle,
67
73
  Globe: lucideReact.Globe,
68
74
  Percent: lucideReact.Percent,
69
75
  Tag: lucideReact.Tag,
76
+ Tags: lucideReact.Tags,
70
77
  Camera: lucideReact.Camera,
71
78
  UtensilsCrossed: lucideReact.UtensilsCrossed,
72
79
  MapPin: lucideReact.MapPin,
80
+ Map: lucideReact.Map,
73
81
  Handshake: lucideReact.Handshake,
74
82
  Contact: lucideReact.Contact,
75
83
  Building2: lucideReact.Building2,
76
84
  Filter: lucideReact.Filter,
77
85
  Plus: lucideReact.Plus,
78
86
  List: lucideReact.List,
87
+ ListPlus: lucideReact.ListPlus,
79
88
  Search: lucideReact.Search,
89
+ Shield: lucideReact.Shield,
90
+ Ban: lucideReact.Ban,
91
+ Clock: lucideReact.Clock,
80
92
  Dog: lucideReact.Dog,
81
93
  Cat: lucideReact.Cat,
82
94
  PawPrint: lucideReact.PawPrint,
83
95
  Heart: lucideReact.Heart,
96
+ FolderOpen: lucideReact.FolderOpen,
84
97
  LayoutTemplate: lucideReact.LayoutTemplate,
85
98
  LeafyGreen: lucideReact.LeafyGreen,
86
99
  Apple: lucideReact.Apple,
@@ -89,7 +102,12 @@ var ICON_MAP = {
89
102
  PartyPopper: lucideReact.PartyPopper,
90
103
  Radio: lucideReact.Radio,
91
104
  CalendarDays: lucideReact.CalendarDays,
105
+ CalendarCheck2: lucideReact.CalendarCheck2,
106
+ CalendarX: lucideReact.CalendarX,
107
+ BadgeDollarSign: lucideReact.BadgeDollarSign,
92
108
  Banknote: lucideReact.Banknote,
109
+ Landmark: lucideReact.Landmark,
110
+ CircleDollarSign: lucideReact.CircleDollarSign,
93
111
  Layers: lucideReact.Layers,
94
112
  Music: lucideReact.Music,
95
113
  Eye: lucideReact.Eye,
@@ -101,8 +119,16 @@ var ICON_MAP = {
101
119
  Award: lucideReact.Award,
102
120
  LayoutDashboard: lucideReact.LayoutDashboard,
103
121
  MessageSquare: lucideReact.MessageSquare,
122
+ Inbox: lucideReact.Inbox,
104
123
  Star: lucideReact.Star,
105
- Workflow: lucideReact.Workflow
124
+ TrendingUp: lucideReact.TrendingUp,
125
+ UserCheck: lucideReact.UserCheck,
126
+ UserPlus: lucideReact.UserPlus,
127
+ UserX: lucideReact.UserX,
128
+ Workflow: lucideReact.Workflow,
129
+ Boxes: lucideReact.Boxes,
130
+ Clock3: lucideReact.Clock3,
131
+ FileCheck2: lucideReact.FileCheck2
106
132
  };
107
133
  function getIcon(name) {
108
134
  return ICON_MAP[name] ?? lucideReact.Home;
@@ -118,7 +144,7 @@ function NavItem({
118
144
  "button",
119
145
  {
120
146
  onClick: () => onNavigate(item.route),
121
- className: chunkVVVZO2LE_cjs.cn(
147
+ className: chunkH6OULCHF_cjs.cn(
122
148
  "flex w-full items-center gap-3 rounded-md px-2.5 py-1.5 text-[13px] font-medium transition-colors",
123
149
  "hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground",
124
150
  isActive ? "bg-sidebar-accent font-semibold text-sidebar-accent-foreground shadow-sm" : "text-sidebar-foreground/80",
@@ -153,26 +179,44 @@ function NavItem({
153
179
  }
154
180
  return content;
155
181
  }
182
+ function routeMatchScore(route, path) {
183
+ if (path === route) return route.length + 1;
184
+ if (route !== "/" && path.startsWith(route + "/")) return route.length;
185
+ return -1;
186
+ }
187
+ function resolveActiveRoute(navigation, path) {
188
+ let best = null;
189
+ let bestScore = 0;
190
+ const consider = (route) => {
191
+ if (!route) return;
192
+ const score = routeMatchScore(route, path);
193
+ if (score > bestScore) {
194
+ bestScore = score;
195
+ best = route;
196
+ }
197
+ };
198
+ for (const item of navigation) {
199
+ consider(item.route);
200
+ for (const child of item.children ?? []) consider(child.route);
201
+ }
202
+ return best;
203
+ }
156
204
  function NavGroup({
157
205
  item,
158
206
  collapsed,
159
- currentPath,
207
+ activeRoute,
160
208
  onNavigate
161
209
  }) {
162
- const [open, setOpen] = React3__namespace.useState(
163
- () => item.children?.some((c) => currentPath === c.route || currentPath.startsWith(c.route + "/")) ?? false
164
- );
210
+ const isChildActive = item.children?.some((c) => c.route === activeRoute);
211
+ const [open, setOpen] = React3__namespace.useState(() => isChildActive ?? false);
165
212
  const Icon = getIcon(item.icon);
166
- const isChildActive = item.children?.some(
167
- (c) => currentPath === c.route || currentPath.startsWith(c.route + "/")
168
- );
169
213
  if (collapsed) {
170
214
  return /* @__PURE__ */ jsxRuntime.jsxs(Tooltip__namespace.Root, { delayDuration: 0, children: [
171
215
  /* @__PURE__ */ jsxRuntime.jsx(Tooltip__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
172
216
  "button",
173
217
  {
174
218
  onClick: () => onNavigate(item.route),
175
- className: chunkVVVZO2LE_cjs.cn(
219
+ className: chunkH6OULCHF_cjs.cn(
176
220
  "flex w-full items-center justify-center rounded-md px-2 py-2 text-sm font-medium transition-colors",
177
221
  "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
178
222
  isChildActive ? "bg-sidebar-accent text-sidebar-accent-foreground" : "text-sidebar-muted"
@@ -191,7 +235,7 @@ function NavGroup({
191
235
  "button",
192
236
  {
193
237
  onClick: () => setOpen(!open),
194
- className: chunkVVVZO2LE_cjs.cn(
238
+ className: chunkH6OULCHF_cjs.cn(
195
239
  "flex w-full items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors",
196
240
  "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
197
241
  isChildActive ? "text-sidebar-accent-foreground" : "text-sidebar-muted"
@@ -199,18 +243,18 @@ function NavGroup({
199
243
  children: [
200
244
  /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4 shrink-0" }),
201
245
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate text-left", children: item.label }),
202
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: chunkVVVZO2LE_cjs.cn("h-3.5 w-3.5 shrink-0 transition-transform", open && "rotate-180") })
246
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: chunkH6OULCHF_cjs.cn("h-3.5 w-3.5 shrink-0 transition-transform", open && "rotate-180") })
203
247
  ]
204
248
  }
205
249
  ),
206
250
  open && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-4 mt-0.5 space-y-0.5 border-l border-sidebar-border/50 pl-3", children: item.children?.map((child) => {
207
251
  const ChildIcon = getIcon(child.icon);
208
- const isActive = currentPath === child.route || currentPath.startsWith(child.route + "/");
252
+ const isActive = child.route === activeRoute;
209
253
  return /* @__PURE__ */ jsxRuntime.jsxs(
210
254
  "button",
211
255
  {
212
256
  onClick: () => onNavigate(child.route),
213
- className: chunkVVVZO2LE_cjs.cn(
257
+ className: chunkH6OULCHF_cjs.cn(
214
258
  "flex w-full items-center gap-2.5 rounded-md px-2 py-1.5 text-sm transition-colors",
215
259
  isActive ? "font-medium text-sidebar-accent-foreground" : "text-sidebar-muted hover:text-sidebar-accent-foreground"
216
260
  ),
@@ -242,6 +286,7 @@ function Sidebar({
242
286
  }) {
243
287
  const currentPath = currentPathProp;
244
288
  const setCommandPaletteOpen = useLayoutStore((s) => s.setCommandPaletteOpen);
289
+ const activeRoute = resolveActiveRoute(navigation, currentPath);
245
290
  const mainItems = navigation.filter((item) => item.section === "main");
246
291
  const secondaryItems = navigation.filter((item) => item.section === "secondary");
247
292
  const settingsItems = navigation.filter((item) => item.section === "settings");
@@ -252,7 +297,7 @@ function Sidebar({
252
297
  "aside",
253
298
  {
254
299
  "data-print": "hide",
255
- className: chunkVVVZO2LE_cjs.cn(
300
+ className: chunkH6OULCHF_cjs.cn(
256
301
  "flex h-full flex-col bg-sidebar text-sidebar-foreground transition-all duration-200",
257
302
  !borderless && "border-r border-sidebar-border",
258
303
  collapsed ? "w-16" : "w-64"
@@ -261,7 +306,7 @@ function Sidebar({
261
306
  /* @__PURE__ */ jsxRuntime.jsxs(
262
307
  "div",
263
308
  {
264
- className: chunkVVVZO2LE_cjs.cn(
309
+ className: chunkH6OULCHF_cjs.cn(
265
310
  "flex h-14 items-center justify-between px-4",
266
311
  !borderless && "border-b border-sidebar-border",
267
312
  collapsed && "justify-center px-2"
@@ -294,43 +339,43 @@ function Sidebar({
294
339
  /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "flex-1 space-y-1 overflow-y-auto p-2", children: [
295
340
  topContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4 space-y-2", children: topContent }),
296
341
  mainItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1", children: mainItems.map(
297
- (item) => item.children && item.children.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(NavGroup, { item, collapsed, currentPath, onNavigate: handleNavigate }, item.id) : /* @__PURE__ */ jsxRuntime.jsx(
342
+ (item) => item.children && item.children.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(NavGroup, { item, collapsed, activeRoute, onNavigate: handleNavigate }, item.id) : /* @__PURE__ */ jsxRuntime.jsx(
298
343
  NavItem,
299
344
  {
300
345
  item,
301
346
  collapsed,
302
- isActive: currentPath === item.route || currentPath.startsWith(item.route + "/"),
347
+ isActive: item.route === activeRoute,
303
348
  onNavigate: handleNavigate
304
349
  },
305
350
  item.id
306
351
  )
307
352
  ) }),
308
353
  secondaryItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-6 space-y-1", children: secondaryItems.map(
309
- (item) => item.children && item.children.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(NavGroup, { item, collapsed, currentPath, onNavigate: handleNavigate }, item.id) : /* @__PURE__ */ jsxRuntime.jsx(
354
+ (item) => item.children && item.children.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(NavGroup, { item, collapsed, activeRoute, onNavigate: handleNavigate }, item.id) : /* @__PURE__ */ jsxRuntime.jsx(
310
355
  NavItem,
311
356
  {
312
357
  item,
313
358
  collapsed,
314
- isActive: currentPath === item.route || currentPath.startsWith(item.route + "/"),
359
+ isActive: item.route === activeRoute,
315
360
  onNavigate: handleNavigate
316
361
  },
317
362
  item.id
318
363
  )
319
364
  ) })
320
365
  ] }),
321
- settingsItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkVVVZO2LE_cjs.cn("p-2 space-y-1", !borderless && "border-t border-sidebar-border"), children: settingsItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
366
+ settingsItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkH6OULCHF_cjs.cn("p-2 space-y-1", !borderless && "border-t border-sidebar-border"), children: settingsItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
322
367
  NavItem,
323
368
  {
324
369
  item,
325
370
  collapsed,
326
- isActive: currentPath === item.route || currentPath.startsWith(item.route + "/"),
371
+ isActive: item.route === activeRoute,
327
372
  onNavigate: handleNavigate
328
373
  },
329
374
  item.id
330
375
  )) }),
331
- footerContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkVVVZO2LE_cjs.cn("p-2", !borderless && "border-t border-sidebar-border"), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: footerContent }) }),
376
+ footerContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkH6OULCHF_cjs.cn("p-2", !borderless && "border-t border-sidebar-border"), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: footerContent }) }),
332
377
  orgSwitcher && React3__namespace.isValidElement(orgSwitcher) ? React3__namespace.cloneElement(orgSwitcher, { collapsed }) : orgSwitcher,
333
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkVVVZO2LE_cjs.cn("p-2", !borderless && "border-t border-sidebar-border"), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkVVVZO2LE_cjs.cn(
378
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkH6OULCHF_cjs.cn("p-2", !borderless && "border-t border-sidebar-border"), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkH6OULCHF_cjs.cn(
334
379
  "flex items-center rounded-md",
335
380
  collapsed ? "flex-col gap-1" : "gap-1 px-1"
336
381
  ), children: [
@@ -432,23 +477,29 @@ var ICON_MAP2 = {
432
477
  CreditCard: lucideReact.CreditCard,
433
478
  Bell: lucideReact.Bell,
434
479
  Calendar: lucideReact.Calendar,
480
+ CalendarClock: lucideReact.CalendarClock,
435
481
  Package: lucideReact.Package,
482
+ Activity: lucideReact.Activity,
436
483
  BarChart3: lucideReact.BarChart3,
437
484
  FileText: lucideReact.FileText,
438
485
  Mail: lucideReact.Mail,
439
486
  DollarSign: lucideReact.DollarSign,
440
487
  Megaphone: lucideReact.Megaphone,
441
488
  ShoppingCart: lucideReact.ShoppingCart,
489
+ ShoppingBag: lucideReact.ShoppingBag,
442
490
  Target: lucideReact.Target,
443
491
  Wrench: lucideReact.Wrench,
444
492
  ClipboardList: lucideReact.ClipboardList,
493
+ ClipboardCheck: lucideReact.ClipboardCheck,
445
494
  Briefcase: lucideReact.Briefcase,
446
495
  UserCog: lucideReact.UserCog,
447
496
  BookOpen: lucideReact.BookOpen,
448
497
  MessageCircle: lucideReact.MessageCircle,
449
498
  Globe: lucideReact.Globe,
499
+ BookOpenCheck: lucideReact.BookOpenCheck,
450
500
  Percent: lucideReact.Percent,
451
501
  Tag: lucideReact.Tag,
502
+ Tags: lucideReact.Tags,
452
503
  Camera: lucideReact.Camera,
453
504
  UtensilsCrossed: lucideReact.UtensilsCrossed,
454
505
  Search: lucideReact.Search,
@@ -459,7 +510,10 @@ var ICON_MAP2 = {
459
510
  ChevronDown: lucideReact.ChevronDown,
460
511
  Filter: lucideReact.Filter,
461
512
  Plus: lucideReact.Plus,
513
+ Shield: lucideReact.Shield,
462
514
  List: lucideReact.List,
515
+ ListChecks: lucideReact.ListChecks,
516
+ FolderOpen: lucideReact.FolderOpen,
463
517
  Dog: lucideReact.Dog,
464
518
  Cat: lucideReact.Cat,
465
519
  PawPrint: lucideReact.PawPrint,
@@ -488,10 +542,15 @@ var ICON_MAP2 = {
488
542
  ArrowUpRight: lucideReact.ArrowUpRight,
489
543
  ArrowDownRight: lucideReact.ArrowDownRight,
490
544
  UserPlus: lucideReact.UserPlus,
545
+ UserX: lucideReact.UserX,
491
546
  TreePalm: lucideReact.TreePalm,
547
+ Boxes: lucideReact.Boxes,
548
+ Box: lucideReact.Box,
549
+ FileCheck2: lucideReact.FileCheck2,
492
550
  PartyPopper: lucideReact.PartyPopper,
493
551
  Radio: lucideReact.Radio,
494
552
  CalendarDays: lucideReact.CalendarDays,
553
+ BadgeDollarSign: lucideReact.BadgeDollarSign,
495
554
  Banknote: lucideReact.Banknote,
496
555
  Layers: lucideReact.Layers,
497
556
  Music: lucideReact.Music,
@@ -499,7 +558,18 @@ var ICON_MAP2 = {
499
558
  ListMusic: lucideReact.ListMusic,
500
559
  Disc3: lucideReact.Disc3,
501
560
  UsersRound: lucideReact.UsersRound,
502
- Mic: lucideReact.Mic
561
+ Mic: lucideReact.Mic,
562
+ CalendarCheck2: lucideReact.CalendarCheck2,
563
+ CalendarX: lucideReact.CalendarX,
564
+ ListPlus: lucideReact.ListPlus,
565
+ Map: lucideReact.Map,
566
+ Ban: lucideReact.Ban,
567
+ Clock3: lucideReact.Clock3,
568
+ Inbox: lucideReact.Inbox,
569
+ UserCheck: lucideReact.UserCheck,
570
+ Star: lucideReact.Star,
571
+ Zap: lucideReact.Zap,
572
+ Clapperboard: lucideReact.Clapperboard
503
573
  };
504
574
  function getIcon2(name) {
505
575
  return ICON_MAP2[name] ?? lucideReact.Home;
@@ -515,14 +585,14 @@ function NavDropdown({ item, currentPath, onNavigate }) {
515
585
  "button",
516
586
  {
517
587
  "data-nav-active": isChildActive || void 0,
518
- className: chunkVVVZO2LE_cjs.cn(
588
+ className: chunkH6OULCHF_cjs.cn(
519
589
  "flex items-center gap-1.5 whitespace-nowrap border-b-2 px-3 py-2 text-sm transition-colors",
520
590
  isChildActive ? "border-sidebar-accent-foreground font-semibold text-sidebar-foreground" : "border-transparent text-sidebar-muted hover:text-sidebar-foreground"
521
591
  ),
522
592
  children: [
523
593
  /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4" }),
524
594
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label }),
525
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: chunkVVVZO2LE_cjs.cn("h-3 w-3 transition-transform", open && "rotate-180") })
595
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: chunkH6OULCHF_cjs.cn("h-3 w-3 transition-transform", open && "rotate-180") })
526
596
  ]
527
597
  }
528
598
  ) }),
@@ -542,7 +612,7 @@ function NavDropdown({ item, currentPath, onNavigate }) {
542
612
  onNavigate(child.route);
543
613
  setOpen(false);
544
614
  },
545
- className: chunkVVVZO2LE_cjs.cn(
615
+ className: chunkH6OULCHF_cjs.cn(
546
616
  "flex w-full items-center gap-2.5 rounded-lg px-3 py-2 text-sm transition-colors",
547
617
  isActive ? "bg-muted font-medium text-foreground" : "text-popover-foreground hover:bg-muted/70"
548
618
  ),
@@ -584,7 +654,7 @@ function Topbar({
584
654
  return /* @__PURE__ */ jsxRuntime.jsxs("header", { "data-print": "hide", className: "sticky top-0 z-50 w-full shrink-0", children: [
585
655
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-sidebar-border bg-sidebar text-sidebar-foreground", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-14 w-full items-center justify-between px-4 md:px-6", children: [
586
656
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
587
- /* @__PURE__ */ jsxRuntime.jsx(
657
+ onMenuClick && /* @__PURE__ */ jsxRuntime.jsx(
588
658
  "button",
589
659
  {
590
660
  onClick: onMenuClick,
@@ -599,7 +669,7 @@ function Topbar({
599
669
  "button",
600
670
  {
601
671
  onClick: () => setCommandPaletteOpen(true),
602
- className: "relative flex h-8 w-full items-center rounded-md border border-sidebar-border bg-sidebar-accent px-3 pl-8 text-sm text-sidebar-muted shadow-sm transition-colors hover:bg-card",
672
+ className: "relative flex h-8 w-full items-center rounded-md border border-sidebar-border bg-sidebar-accent px-3 pl-8 text-sm text-sidebar-muted shadow-sm transition-colors hover:border-sidebar-foreground/25 hover:bg-sidebar-foreground/10 hover:text-sidebar-foreground",
603
673
  children: [
604
674
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-sidebar-muted" }),
605
675
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", children: searchPlaceholder }),
@@ -630,7 +700,7 @@ function Topbar({
630
700
  const left = active.offsetLeft - el.offsetWidth / 2 + active.offsetWidth / 2;
631
701
  el.scrollTo({ left: Math.max(0, left), behavior: "smooth" });
632
702
  }
633
- }, className: "flex items-center gap-0.5 overflow-x-auto scrollbar-hide", children: allNav.map((item) => {
703
+ }, className: "flex items-center gap-0.5 overflow-x-auto scrollbar-none", children: allNav.map((item) => {
634
704
  if (item.children && item.children.length > 0) {
635
705
  return /* @__PURE__ */ jsxRuntime.jsx(
636
706
  NavDropdown,
@@ -649,7 +719,7 @@ function Topbar({
649
719
  {
650
720
  "data-nav-active": isActive || void 0,
651
721
  onClick: () => handleNavigate(item.route),
652
- className: chunkVVVZO2LE_cjs.cn(
722
+ className: chunkH6OULCHF_cjs.cn(
653
723
  "flex items-center gap-1.5 whitespace-nowrap border-b-2 px-3 py-2 text-sm transition-colors",
654
724
  isActive ? "border-primary font-semibold text-sidebar-foreground" : "border-transparent text-sidebar-muted hover:text-sidebar-foreground"
655
725
  ),
@@ -693,14 +763,22 @@ function SidebarLayout({
693
763
  topbarEnd,
694
764
  userMenuSlot,
695
765
  notificationSlot,
696
- unreadCount = 0
766
+ unreadCount = 0,
767
+ hasBottomNav = false,
768
+ mobileHeader = "minimal"
697
769
  }) {
698
770
  const sidebarCollapsed = useLayoutStore((s) => s.sidebarCollapsed);
699
771
  const setSidebarCollapsed = useLayoutStore((s) => s.setSidebarCollapsed);
700
772
  const [mobileMenuOpen, setMobileMenuOpen] = React3__namespace.useState(false);
701
773
  const [headerSlot, setHeaderSlot] = React3__namespace.useState(null);
702
774
  const [actionsSlot, setActionsSlot] = React3__namespace.useState(null);
703
- return /* @__PURE__ */ jsxRuntime.jsx(chunkW4XXXJRW_cjs.SaveBarProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(ModuleHeaderSlotContext.Provider, { value: headerSlot, children: /* @__PURE__ */ jsxRuntime.jsx(ModuleHeaderActionsSlotContext.Provider, { value: actionsSlot, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-screen overflow-hidden bg-background", children: [
775
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkOW73RZOU_cjs.SaveBarProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(ModuleHeaderSlotContext.Provider, { value: headerSlot, children: /* @__PURE__ */ jsxRuntime.jsx(ModuleHeaderActionsSlotContext.Provider, { value: actionsSlot, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkH6OULCHF_cjs.cn(
776
+ "flex h-screen overflow-hidden bg-background",
777
+ // Frame mode: the inset gap around the framed card takes the sidebar (menu)
778
+ // color, so the white card reads as a panel floating on the same tone as the
779
+ // left menu. The card's own md:m-2 margin reveals this behind it.
780
+ frame && "md:bg-sidebar"
781
+ ), children: [
704
782
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden md:flex", children: /* @__PURE__ */ jsxRuntime.jsx(
705
783
  Sidebar,
706
784
  {
@@ -724,13 +802,16 @@ function SidebarLayout({
724
802
  unreadCount
725
803
  }
726
804
  ) }),
727
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkVVVZO2LE_cjs.cn(
805
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkH6OULCHF_cjs.cn(
728
806
  "relative flex flex-1 flex-col overflow-hidden",
729
807
  frame && "md:m-2 md:rounded-xl md:border md:border-border md:bg-card"
730
808
  ), children: [
731
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-14 shrink-0 items-center justify-between gap-3 border-b border-border bg-card px-4 py-2", children: [
809
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkH6OULCHF_cjs.cn(
810
+ "flex min-h-14 shrink-0 items-center justify-between gap-3 border-b border-border bg-card px-4 py-2",
811
+ mobileHeader !== "minimal" && "hidden md:flex"
812
+ ), children: [
732
813
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [
733
- /* @__PURE__ */ jsxRuntime.jsx(
814
+ !hasBottomNav && /* @__PURE__ */ jsxRuntime.jsx(
734
815
  "button",
735
816
  {
736
817
  onClick: () => setMobileMenuOpen(true),
@@ -748,8 +829,8 @@ function SidebarLayout({
748
829
  topbarEnd
749
830
  ] })
750
831
  ] }),
751
- /* @__PURE__ */ jsxRuntime.jsx("main", { className: "flex-1 overflow-y-auto", children }),
752
- /* @__PURE__ */ jsxRuntime.jsx(chunkW4XXXJRW_cjs.SaveBar, {})
832
+ /* @__PURE__ */ jsxRuntime.jsx("main", { className: "flex-1 overflow-y-auto pb-16 md:pb-0", children }),
833
+ /* @__PURE__ */ jsxRuntime.jsx(chunkOW73RZOU_cjs.SaveBar, {})
753
834
  ] }),
754
835
  mobileMenuOpen && /* @__PURE__ */ jsxRuntime.jsx(
755
836
  MobileOverlay,
@@ -788,10 +869,11 @@ function TopbarLayout({
788
869
  frame,
789
870
  currentPath,
790
871
  topbarStart,
791
- topbarEnd
872
+ topbarEnd,
873
+ hasBottomNav = false
792
874
  }) {
793
875
  const [mobileMenuOpen, setMobileMenuOpen] = React3__namespace.useState(false);
794
- return /* @__PURE__ */ jsxRuntime.jsx(chunkW4XXXJRW_cjs.SaveBarProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex h-screen flex-col overflow-hidden bg-background", children: [
876
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkOW73RZOU_cjs.SaveBarProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex h-screen flex-col overflow-hidden bg-background", children: [
795
877
  /* @__PURE__ */ jsxRuntime.jsx(
796
878
  Topbar,
797
879
  {
@@ -807,11 +889,11 @@ function TopbarLayout({
807
889
  userMenuExtras,
808
890
  leftContent: topbarStart,
809
891
  rightContent: topbarEnd,
810
- onMenuClick: () => setMobileMenuOpen(true)
892
+ onMenuClick: hasBottomNav ? void 0 : () => setMobileMenuOpen(true)
811
893
  }
812
894
  ),
813
- /* @__PURE__ */ jsxRuntime.jsx("main", { className: chunkVVVZO2LE_cjs.cn("flex-1 overflow-y-auto", frame && "md:p-2"), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkVVVZO2LE_cjs.cn("min-h-full", frame && "md:rounded-xl md:border md:border-border md:bg-card"), children }) }),
814
- /* @__PURE__ */ jsxRuntime.jsx(chunkW4XXXJRW_cjs.SaveBar, {}),
895
+ /* @__PURE__ */ jsxRuntime.jsx("main", { className: chunkH6OULCHF_cjs.cn("flex-1 overflow-y-auto pb-16 md:pb-0", frame && "md:bg-sidebar md:p-2"), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkH6OULCHF_cjs.cn("min-h-full", frame && "md:rounded-xl md:border md:border-border md:bg-card"), children }) }),
896
+ /* @__PURE__ */ jsxRuntime.jsx(chunkOW73RZOU_cjs.SaveBar, {}),
815
897
  mobileMenuOpen && /* @__PURE__ */ jsxRuntime.jsx(
816
898
  MobileOverlay,
817
899
  {
@@ -848,7 +930,7 @@ function MinimalLayout({
848
930
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: logo ?? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg font-bold", children: "App" }) }),
849
931
  headerEnd && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: headerEnd })
850
932
  ] }),
851
- /* @__PURE__ */ jsxRuntime.jsx("main", { className: "flex-1 overflow-y-auto", children })
933
+ /* @__PURE__ */ jsxRuntime.jsx("main", { className: "flex-1 overflow-y-auto pb-16 md:pb-0", children })
852
934
  ] });
853
935
  }
854
936
  function MobileOverlay({ onClose, onNavigate, ...sidebarProps }) {
@@ -879,7 +961,7 @@ function MobileOverlay({ onClose, onNavigate, ...sidebarProps }) {
879
961
  /* @__PURE__ */ jsxRuntime.jsx(
880
962
  "div",
881
963
  {
882
- className: chunkVVVZO2LE_cjs.cn(
964
+ className: chunkH6OULCHF_cjs.cn(
883
965
  "absolute inset-0 bg-black/50 transition-opacity duration-300 ease-out",
884
966
  visible ? "opacity-100" : "opacity-0"
885
967
  ),
@@ -889,7 +971,7 @@ function MobileOverlay({ onClose, onNavigate, ...sidebarProps }) {
889
971
  /* @__PURE__ */ jsxRuntime.jsx(
890
972
  "div",
891
973
  {
892
- className: chunkVVVZO2LE_cjs.cn(
974
+ className: chunkH6OULCHF_cjs.cn(
893
975
  "absolute inset-y-0 left-0 shadow-2xl transition-transform duration-300 ease-out will-change-transform",
894
976
  visible ? "translate-x-0" : "-translate-x-full"
895
977
  ),
@@ -910,6 +992,82 @@ function MobileOverlay({ onClose, onNavigate, ...sidebarProps }) {
910
992
  )
911
993
  ] });
912
994
  }
995
+ var BOTTOM_NAV_ICONS = {
996
+ Home: lucideReact.Home,
997
+ Receipt: lucideReact.Receipt,
998
+ ArrowLeftRight: lucideReact.ArrowLeftRight,
999
+ Calendar: lucideReact.Calendar,
1000
+ CreditCard: lucideReact.CreditCard,
1001
+ Settings: lucideReact.Settings,
1002
+ Menu: lucideReact.Menu,
1003
+ MessageCircle: lucideReact.MessageCircle,
1004
+ Wallet: lucideReact.Wallet,
1005
+ PiggyBank: lucideReact.PiggyBank,
1006
+ Plus: lucideReact.Plus
1007
+ };
1008
+ function FloatingProfileAvatar({ user, onClick }) {
1009
+ if (!user) return null;
1010
+ const label = user.fullName || user.email;
1011
+ return /* @__PURE__ */ jsxRuntime.jsx(
1012
+ "button",
1013
+ {
1014
+ type: "button",
1015
+ onClick,
1016
+ "aria-label": "Profile",
1017
+ className: "fixed right-3 top-3 z-40 md:hidden",
1018
+ children: user.avatarUrl ? /* @__PURE__ */ jsxRuntime.jsx(
1019
+ "img",
1020
+ {
1021
+ src: user.avatarUrl,
1022
+ alt: "",
1023
+ className: "h-9 w-9 rounded-full object-cover shadow-md ring-2 ring-background"
1024
+ }
1025
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-9 w-9 items-center justify-center rounded-full bg-primary text-sm font-semibold text-primary-foreground shadow-md ring-2 ring-background", children: (label || "?").charAt(0).toUpperCase() })
1026
+ }
1027
+ );
1028
+ }
1029
+ function MobileBottomNav({
1030
+ items,
1031
+ currentPath,
1032
+ onNavigate,
1033
+ onAction
1034
+ }) {
1035
+ const path = currentPath ?? "";
1036
+ return /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "fixed inset-x-0 bottom-0 z-50 flex h-16 items-center justify-around border-t border-border bg-background md:hidden", children: items.map((item) => {
1037
+ if (item.kind === "action") {
1038
+ const ActionIcon = BOTTOM_NAV_ICONS[item.icon] ?? lucideReact.Plus;
1039
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-start justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
1040
+ "button",
1041
+ {
1042
+ type: "button",
1043
+ onClick: () => onAction?.(item.id),
1044
+ "aria-label": item.label ?? "Add",
1045
+ className: "-mt-6 flex h-14 w-14 items-center justify-center rounded-full bg-primary text-primary-foreground shadow-lg shadow-primary/30 ring-4 ring-background transition-transform active:scale-95",
1046
+ children: /* @__PURE__ */ jsxRuntime.jsx(ActionIcon, { className: "h-6 w-6" })
1047
+ }
1048
+ ) }, item.id);
1049
+ }
1050
+ const isActive = item.route === "/" ? path === "/" || path === "" : path === item.route || path.startsWith(item.route + "/");
1051
+ const Icon = BOTTOM_NAV_ICONS[item.icon] ?? lucideReact.Home;
1052
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1053
+ "button",
1054
+ {
1055
+ type: "button",
1056
+ onClick: () => onNavigate?.(item.route),
1057
+ className: chunkH6OULCHF_cjs.cn(
1058
+ "flex flex-1 flex-col items-center justify-center gap-0.5 px-1 py-1 transition-colors",
1059
+ isActive ? "text-primary" : "text-muted-foreground"
1060
+ ),
1061
+ "aria-current": isActive ? "page" : void 0,
1062
+ children: [
1063
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-5 w-5" }),
1064
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", children: item.label })
1065
+ ]
1066
+ },
1067
+ item.route
1068
+ );
1069
+ }) });
1070
+ }
913
1071
  function AppShell({
914
1072
  variant,
915
1073
  contentFrame,
@@ -930,13 +1088,28 @@ function AppShell({
930
1088
  topbarEnd,
931
1089
  sidebarTopContent,
932
1090
  sidebarFooterContent,
1091
+ bottomNav,
1092
+ onBottomNavAction,
1093
+ mobileHeader = "minimal",
933
1094
  userMenuSlot,
934
1095
  notificationSlot,
935
1096
  unreadCount = 0
936
1097
  }) {
1098
+ const hasBottomNav = !!bottomNav?.length;
1099
+ const bottomBar = hasBottomNav ? /* @__PURE__ */ jsxRuntime.jsx(
1100
+ MobileBottomNav,
1101
+ {
1102
+ items: bottomNav,
1103
+ currentPath,
1104
+ onNavigate,
1105
+ onAction: onBottomNavAction
1106
+ }
1107
+ ) : null;
1108
+ const floatingAvatar = mobileHeader === "transparent" && user ? /* @__PURE__ */ jsxRuntime.jsx(FloatingProfileAvatar, { user, onClick: onProfile }) : null;
1109
+ let layoutElement;
937
1110
  switch (variant) {
938
1111
  case "sidebar":
939
- return /* @__PURE__ */ jsxRuntime.jsx(
1112
+ layoutElement = /* @__PURE__ */ jsxRuntime.jsx(
940
1113
  SidebarLayout,
941
1114
  {
942
1115
  navigation,
@@ -959,11 +1132,14 @@ function AppShell({
959
1132
  userMenuSlot,
960
1133
  notificationSlot,
961
1134
  unreadCount,
1135
+ hasBottomNav,
1136
+ mobileHeader,
962
1137
  children
963
1138
  }
964
1139
  );
1140
+ break;
965
1141
  case "topbar":
966
- return /* @__PURE__ */ jsxRuntime.jsx(
1142
+ layoutElement = /* @__PURE__ */ jsxRuntime.jsx(
967
1143
  TopbarLayout,
968
1144
  {
969
1145
  navigation,
@@ -979,15 +1155,23 @@ function AppShell({
979
1155
  currentPath,
980
1156
  topbarStart,
981
1157
  topbarEnd,
1158
+ hasBottomNav,
982
1159
  children
983
1160
  }
984
1161
  );
1162
+ break;
985
1163
  case "minimal":
986
- return /* @__PURE__ */ jsxRuntime.jsx(MinimalLayout, { logo, user, headerEnd: topbarEnd, children });
1164
+ layoutElement = /* @__PURE__ */ jsxRuntime.jsx(MinimalLayout, { logo, user, headerEnd: topbarEnd, children });
1165
+ break;
987
1166
  default: {
988
1167
  return null;
989
1168
  }
990
1169
  }
1170
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1171
+ layoutElement,
1172
+ floatingAvatar,
1173
+ bottomBar
1174
+ ] });
991
1175
  }
992
1176
  var NavTransitionContext = React3__namespace.createContext("slide");
993
1177
  function NavTransitionProvider({ value, children }) {
@@ -1011,7 +1195,7 @@ function PageTransition({
1011
1195
  }) {
1012
1196
  const transition = useNavTransition();
1013
1197
  const animClass = resolveTransitionClass(transition, direction);
1014
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkVVVZO2LE_cjs.cn(animClass, className), children }, transitionKey);
1198
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkH6OULCHF_cjs.cn(animClass, className), children }, transitionKey);
1015
1199
  }
1016
1200
  function PageHeaderActions({ children }) {
1017
1201
  const slot = useModuleHeaderActionsSlot();
@@ -1037,7 +1221,7 @@ function NavItem2({ item }) {
1037
1221
  {
1038
1222
  type: "button",
1039
1223
  onClick: () => hasChildren ? setExpanded(!expanded) : item.onClick?.(),
1040
- className: chunkVVVZO2LE_cjs.cn(
1224
+ className: chunkH6OULCHF_cjs.cn(
1041
1225
  "flex items-center gap-2 w-full rounded-md px-2.5 py-1.5 text-sm transition-colors",
1042
1226
  isActive ? "bg-primary/10 text-primary font-medium" : "text-muted-foreground hover:text-foreground hover:bg-muted/50"
1043
1227
  ),
@@ -1053,7 +1237,7 @@ function NavItem2({ item }) {
1053
1237
  {
1054
1238
  type: "button",
1055
1239
  onClick: child.onClick,
1056
- className: chunkVVVZO2LE_cjs.cn(
1240
+ className: chunkH6OULCHF_cjs.cn(
1057
1241
  "flex items-center w-full rounded-md px-2.5 py-1 text-xs transition-colors",
1058
1242
  child.active ? "text-primary font-medium bg-primary/5" : "text-muted-foreground hover:text-foreground hover:bg-muted/50"
1059
1243
  ),
@@ -1076,7 +1260,7 @@ function MobileTabs({ nav }) {
1076
1260
  }
1077
1261
  }, [nav]);
1078
1262
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:hidden -mx-1 mb-4 no-print", children: [
1079
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, className: "flex gap-1 px-1 pb-2 overflow-x-auto scrollbar-hide", children: nav.map((item) => {
1263
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, className: "flex gap-1 px-1 pb-2 overflow-x-auto scrollbar-none", children: nav.map((item) => {
1080
1264
  const Icon = item.icon ? ICON_MAP2[item.icon] ?? null : null;
1081
1265
  const hasChildren = item.children && item.children.length > 0;
1082
1266
  const isActive = item.active || item.children?.some((c) => c.active);
@@ -1094,14 +1278,14 @@ function MobileTabs({ nav }) {
1094
1278
  setExpandedId(null);
1095
1279
  }
1096
1280
  },
1097
- className: chunkVVVZO2LE_cjs.cn(
1281
+ className: chunkH6OULCHF_cjs.cn(
1098
1282
  "flex items-center gap-1.5 whitespace-nowrap rounded-full px-3 py-1.5 text-xs font-medium transition-colors shrink-0",
1099
1283
  isActive ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground hover:text-foreground"
1100
1284
  ),
1101
1285
  children: [
1102
1286
  Icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-3 w-3" }),
1103
1287
  item.label,
1104
- hasChildren && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: chunkVVVZO2LE_cjs.cn("h-2.5 w-2.5 transition-transform", isExpanded && "rotate-180") })
1288
+ hasChildren && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: chunkH6OULCHF_cjs.cn("h-2.5 w-2.5 transition-transform", isExpanded && "rotate-180") })
1105
1289
  ]
1106
1290
  },
1107
1291
  item.id
@@ -1118,7 +1302,7 @@ function MobileTabs({ nav }) {
1118
1302
  child.onClick?.();
1119
1303
  setExpandedId(null);
1120
1304
  },
1121
- className: chunkVVVZO2LE_cjs.cn(
1305
+ className: chunkH6OULCHF_cjs.cn(
1122
1306
  "whitespace-nowrap rounded-full px-2.5 py-1 text-[11px] font-medium transition-colors shrink-0",
1123
1307
  child.active ? "bg-foreground/10 text-foreground" : "text-muted-foreground hover:text-foreground"
1124
1308
  ),
@@ -1139,8 +1323,8 @@ function useBackStyle() {
1139
1323
  function SubpageHeader({ title, subtitle, icon, onBack, parentLabel, actions, backStyle }) {
1140
1324
  const t = core.useTranslation();
1141
1325
  const appStyle = useBackStyle();
1142
- const { onBack: effectiveOnBack, parentLabel: effectiveParentLabel } = chunkW4XXXJRW_cjs.useCrossModuleBack(onBack, parentLabel);
1143
- chunkW4XXXJRW_cjs.useBackHandler(effectiveOnBack);
1326
+ const { onBack: effectiveOnBack, parentLabel: effectiveParentLabel } = chunkOW73RZOU_cjs.useCrossModuleBack(onBack, parentLabel);
1327
+ chunkOW73RZOU_cjs.useBackHandler(effectiveOnBack);
1144
1328
  const Icon = icon ? ICON_MAP2[icon] ?? null : null;
1145
1329
  const style = !effectiveOnBack ? "icon" : backStyle ?? appStyle;
1146
1330
  const effectiveStyle = style !== "icon" && !effectiveParentLabel ? "icon" : style;
@@ -1199,7 +1383,7 @@ function ModuleHeader({ nav }) {
1199
1383
  const kids = item.children ?? [];
1200
1384
  return kids.find((c) => /list/i.test(c.id) || /^list$/i.test(c.label)) ?? kids[kids.length - 1];
1201
1385
  }
1202
- const content = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full min-w-0 items-center gap-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-0 items-center gap-0.5 overflow-x-auto scrollbar-hide", children: nav.map((item) => {
1386
+ const content = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full min-w-0 items-center gap-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-0 items-center gap-0.5 overflow-x-auto scrollbar-none", children: nav.map((item) => {
1203
1387
  const Icon = item.icon ? ICON_MAP2[item.icon] ?? null : null;
1204
1388
  const hasChildren = item.children && item.children.length > 0;
1205
1389
  const isActive = item.active || item.children?.some((c) => c.active);
@@ -1208,7 +1392,7 @@ function ModuleHeader({ nav }) {
1208
1392
  {
1209
1393
  type: "button",
1210
1394
  onClick: () => hasChildren ? defaultChild(item)?.onClick?.() : item.onClick?.(),
1211
- className: chunkVVVZO2LE_cjs.cn(
1395
+ className: chunkH6OULCHF_cjs.cn(
1212
1396
  "flex shrink-0 items-center gap-1.5 whitespace-nowrap border-b-2 px-2.5 py-1.5 text-sm font-medium transition-colors",
1213
1397
  isActive ? "border-primary text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"
1214
1398
  ),
@@ -1231,11 +1415,11 @@ function ModulePage({ title, subtitle, nav, children, className, headerAction, s
1231
1415
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1232
1416
  /* @__PURE__ */ jsxRuntime.jsx(ModuleHeader, { nav }),
1233
1417
  showHeader && headerAction && /* @__PURE__ */ jsxRuntime.jsx(PageHeaderActions, { children: headerAction }),
1234
- /* @__PURE__ */ jsxRuntime.jsx(PageTransition, { transitionKey, direction, className: chunkVVVZO2LE_cjs.cn("min-w-0", className), children })
1418
+ /* @__PURE__ */ jsxRuntime.jsx(PageTransition, { transitionKey, direction, className: chunkH6OULCHF_cjs.cn("min-w-0", className), children })
1235
1419
  ] });
1236
1420
  }
1237
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkVVVZO2LE_cjs.cn("flex gap-6 -mt-2", className), children: [
1238
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-48 shrink-0 hidden md:block no-print", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkVVVZO2LE_cjs.cn(sidebarFooter && "sticky top-4 flex flex-col"), style: sidebarFooter ? { height: "calc(100vh - 8rem)" } : void 0, children: [
1421
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkH6OULCHF_cjs.cn("flex gap-6 -mt-2", className), children: [
1422
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-48 shrink-0 hidden md:block no-print", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkH6OULCHF_cjs.cn(sidebarFooter && "sticky top-4 flex flex-col"), style: sidebarFooter ? { height: "calc(100vh - 8rem)" } : void 0, children: [
1239
1423
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1240
1424
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider px-2.5 mb-2", children: title }),
1241
1425
  /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "space-y-0.5", children: nav.map((item) => /* @__PURE__ */ jsxRuntime.jsx(NavItem2, { item }, item.id)) })
@@ -1255,9 +1439,96 @@ function ModulePage({ title, subtitle, nav, children, className, headerAction, s
1255
1439
  ] })
1256
1440
  ] });
1257
1441
  }
1442
+ var ContentSplitContext = React3__namespace.createContext(null);
1443
+ function ContentSplit({
1444
+ children,
1445
+ aside,
1446
+ asideTitle,
1447
+ asideDescription,
1448
+ asideWidth = "20rem",
1449
+ asideOpen,
1450
+ onAsideOpenChange,
1451
+ collapsible = false,
1452
+ defaultCollapsed = false,
1453
+ className
1454
+ }) {
1455
+ const [internalOpen, setInternalOpen] = React3__namespace.useState(false);
1456
+ const open = asideOpen ?? internalOpen;
1457
+ const setOpen = onAsideOpenChange ?? setInternalOpen;
1458
+ const [collapsed, setCollapsed] = React3__namespace.useState(collapsible && defaultCollapsed);
1459
+ return /* @__PURE__ */ jsxRuntime.jsxs(ContentSplitContext.Provider, { value: { open, setOpen }, children: [
1460
+ /* @__PURE__ */ jsxRuntime.jsxs(
1461
+ "div",
1462
+ {
1463
+ className: chunkH6OULCHF_cjs.cn("lg:grid lg:items-start lg:gap-6", className),
1464
+ style: { gridTemplateColumns: `minmax(0, 1fr) ${collapsed ? "auto" : asideWidth}` },
1465
+ children: [
1466
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children }),
1467
+ /* @__PURE__ */ jsxRuntime.jsx("aside", { className: "hidden lg:block lg:sticky lg:top-4", children: collapsed ? /* @__PURE__ */ jsxRuntime.jsx(
1468
+ chunkH6OULCHF_cjs.Button,
1469
+ {
1470
+ variant: "outline",
1471
+ size: "sm",
1472
+ onClick: () => setCollapsed(false),
1473
+ className: "h-9 w-9 p-0",
1474
+ "aria-label": typeof asideTitle === "string" ? asideTitle : void 0,
1475
+ title: typeof asideTitle === "string" ? asideTitle : void 0,
1476
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelRightOpen, { className: "h-4 w-4" })
1477
+ }
1478
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-card border border-border bg-card", children: [
1479
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2 border-b border-border px-4 py-3", children: [
1480
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
1481
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold text-foreground", children: asideTitle }),
1482
+ asideDescription && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: asideDescription })
1483
+ ] }),
1484
+ collapsible && /* @__PURE__ */ jsxRuntime.jsx(
1485
+ "button",
1486
+ {
1487
+ type: "button",
1488
+ onClick: () => setCollapsed(true),
1489
+ className: "rounded p-1 text-muted-foreground transition-colors hover:bg-muted/60 hover:text-foreground",
1490
+ "aria-label": "collapse",
1491
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelRightClose, { className: "h-4 w-4" })
1492
+ }
1493
+ )
1494
+ ] }),
1495
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: aside })
1496
+ ] }) })
1497
+ ]
1498
+ }
1499
+ ),
1500
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "lg:hidden", children: /* @__PURE__ */ jsxRuntime.jsx(chunkOW73RZOU_cjs.Sheet, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(chunkOW73RZOU_cjs.SheetContent, { width: "max-w-sm", children: [
1501
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkOW73RZOU_cjs.SheetHeader, { children: [
1502
+ /* @__PURE__ */ jsxRuntime.jsx(chunkOW73RZOU_cjs.SheetTitle, { children: asideTitle }),
1503
+ asideDescription && /* @__PURE__ */ jsxRuntime.jsx(chunkOW73RZOU_cjs.SheetDescription, { children: asideDescription })
1504
+ ] }),
1505
+ /* @__PURE__ */ jsxRuntime.jsx(chunkOW73RZOU_cjs.SheetBody, { children: aside })
1506
+ ] }) }) })
1507
+ ] });
1508
+ }
1509
+ function ContentSplitTrigger({ label, iconOnly, className }) {
1510
+ const ctx = React3__namespace.useContext(ContentSplitContext);
1511
+ if (!ctx) return null;
1512
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1513
+ chunkH6OULCHF_cjs.Button,
1514
+ {
1515
+ variant: "outline",
1516
+ size: "sm",
1517
+ onClick: () => ctx.setOpen(true),
1518
+ className: chunkH6OULCHF_cjs.cn("lg:hidden", className),
1519
+ "aria-label": typeof label === "string" ? label : void 0,
1520
+ children: [
1521
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelRight, { className: chunkH6OULCHF_cjs.cn("h-4 w-4", !iconOnly && "mr-1.5") }),
1522
+ !iconOnly && label
1523
+ ]
1524
+ }
1525
+ );
1526
+ }
1258
1527
 
1259
1528
  exports.AppShell = AppShell;
1260
1529
  exports.BackStyleProvider = BackStyleProvider;
1530
+ exports.ContentSplit = ContentSplit;
1531
+ exports.ContentSplitTrigger = ContentSplitTrigger;
1261
1532
  exports.ICON_MAP = ICON_MAP;
1262
1533
  exports.ModuleLayoutProvider = ModuleLayoutProvider;
1263
1534
  exports.ModulePage = ModulePage;
@@ -1273,5 +1544,5 @@ exports.useModuleHeaderActionsSlot = useModuleHeaderActionsSlot;
1273
1544
  exports.useModuleHeaderSlot = useModuleHeaderSlot;
1274
1545
  exports.useModuleLayout = useModuleLayout;
1275
1546
  exports.useNavTransition = useNavTransition;
1276
- //# sourceMappingURL=chunk-GE6XUREM.cjs.map
1277
- //# sourceMappingURL=chunk-GE6XUREM.cjs.map
1547
+ //# sourceMappingURL=chunk-HG5RH3B3.cjs.map
1548
+ //# sourceMappingURL=chunk-HG5RH3B3.cjs.map