@wealthx/shadcn 1.2.2 → 1.3.1

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 (230) hide show
  1. package/.turbo/turbo-build.log +193 -149
  2. package/CHANGELOG.md +28 -0
  3. package/dist/{chunk-4Y6R4WEC.mjs → chunk-2A5RRQGG.mjs} +9 -22
  4. package/dist/{chunk-TS2ZX2VS.mjs → chunk-2UM72RJ7.mjs} +11 -15
  5. package/dist/{chunk-A56YQQHG.mjs → chunk-3NCUZIFP.mjs} +2 -2
  6. package/dist/chunk-3OYFOX3X.mjs +79 -0
  7. package/dist/{chunk-RP3SQYA3.mjs → chunk-3TTACBDP.mjs} +9 -4
  8. package/dist/chunk-4GAWMKMI.mjs +710 -0
  9. package/dist/{chunk-VGSESELX.mjs → chunk-5FQIKDKP.mjs} +5 -5
  10. package/dist/{chunk-K3JYD4IU.mjs → chunk-5IS7G74I.mjs} +11 -4
  11. package/dist/chunk-6AW4KJHE.mjs +235 -0
  12. package/dist/chunk-6CR5N2JW.mjs +302 -0
  13. package/dist/{chunk-XIRTEFKH.mjs → chunk-6DZEXFNB.mjs} +36 -8
  14. package/dist/chunk-6O6KD7CE.mjs +271 -0
  15. package/dist/chunk-7PV3IWCN.mjs +33 -0
  16. package/dist/{chunk-SPJ5KXW7.mjs → chunk-7S5AESZO.mjs} +5 -5
  17. package/dist/{chunk-RYCLWMZ7.mjs → chunk-ABFDMHOR.mjs} +9 -7
  18. package/dist/{chunk-SWGT756Z.mjs → chunk-AMQZRHEZ.mjs} +10 -4
  19. package/dist/{chunk-WAZD7NFU.mjs → chunk-BKNFWEH2.mjs} +6 -6
  20. package/dist/{chunk-CLIN5525.mjs → chunk-C7CQJNMR.mjs} +1 -1
  21. package/dist/{chunk-D4ILTPOG.mjs → chunk-CFMQP5QS.mjs} +5 -4
  22. package/dist/{chunk-VPBN3WOO.mjs → chunk-DGHAXJBN.mjs} +9 -7
  23. package/dist/chunk-DOEO3CDL.mjs +27 -0
  24. package/dist/{chunk-5MEWU56Z.mjs → chunk-DUJTAXMH.mjs} +11 -6
  25. package/dist/{chunk-GGM2UYGG.mjs → chunk-EBXQWIYG.mjs} +10 -4
  26. package/dist/chunk-EWRB4PAD.mjs +468 -0
  27. package/dist/{chunk-ZSHYDDRB.mjs → chunk-FAKPBKLT.mjs} +6 -2
  28. package/dist/{chunk-A6AAWBPF.mjs → chunk-GHC7LLUX.mjs} +13 -4
  29. package/dist/chunk-HBZLGDIN.mjs +507 -0
  30. package/dist/{chunk-SIZMLSRU.mjs → chunk-HISNT2MG.mjs} +8 -6
  31. package/dist/{chunk-CGH4DRNG.mjs → chunk-HVY6KCCF.mjs} +10 -7
  32. package/dist/chunk-I3RZS7V2.mjs +136 -0
  33. package/dist/chunk-IAE3F7DR.mjs +1962 -0
  34. package/dist/{chunk-UT4KJR7V.mjs → chunk-IHMFS7NZ.mjs} +35 -74
  35. package/dist/{chunk-PCPLO5HT.mjs → chunk-IOJRDS6V.mjs} +96 -14
  36. package/dist/{chunk-LHYCMLVA.mjs → chunk-JKGDCQTZ.mjs} +11 -4
  37. package/dist/{chunk-H45TKD34.mjs → chunk-JMHR3YGZ.mjs} +1 -1
  38. package/dist/{chunk-4MN6UQHG.mjs → chunk-K5A5L6T2.mjs} +17 -39
  39. package/dist/chunk-LV35NGVG.mjs +272 -0
  40. package/dist/{chunk-FZIXGLMV.mjs → chunk-M3FV7LOK.mjs} +5 -12
  41. package/dist/{chunk-FMAXJ2SI.mjs → chunk-MBON7YRJ.mjs} +1 -1
  42. package/dist/chunk-MIZQHHUO.mjs +441 -0
  43. package/dist/chunk-MLNEWRWV.mjs +449 -0
  44. package/dist/chunk-MN5NYQCL.mjs +29 -0
  45. package/dist/chunk-NL3ZO62D.mjs +31 -0
  46. package/dist/{chunk-Q76O3RIQ.mjs → chunk-NMOI6CQD.mjs} +1 -1
  47. package/dist/{chunk-P6AM5V7O.mjs → chunk-OODBHKG7.mjs} +1 -1
  48. package/dist/chunk-PBL4OQV2.mjs +283 -0
  49. package/dist/{chunk-Y4QFWRNR.mjs → chunk-PU4YZQXV.mjs} +17 -18
  50. package/dist/chunk-Q2BGOAMG.mjs +202 -0
  51. package/dist/chunk-QMY3AZJH.mjs +80 -0
  52. package/dist/{chunk-BL3DXM2X.mjs → chunk-QZ4RE6NA.mjs} +11 -4
  53. package/dist/{chunk-VACKZOMY.mjs → chunk-R3VSPKNP.mjs} +3 -3
  54. package/dist/{chunk-OPNQAVVH.mjs → chunk-RJI6GKVF.mjs} +8 -6
  55. package/dist/{chunk-WG6JGJXB.mjs → chunk-T4BJLT57.mjs} +1 -1
  56. package/dist/chunk-UMTOX62O.mjs +415 -0
  57. package/dist/{chunk-7MMXNK3C.mjs → chunk-VLARHE5V.mjs} +8 -6
  58. package/dist/{chunk-2I5S2AMY.mjs → chunk-XREGSKX3.mjs} +2 -2
  59. package/dist/{chunk-JNQORUPP.mjs → chunk-YJG55G2H.mjs} +14 -11
  60. package/dist/components/ui/add-column-modal.js +42 -14
  61. package/dist/components/ui/add-column-modal.mjs +5 -5
  62. package/dist/components/ui/add-lead-modal.js +42 -11
  63. package/dist/components/ui/add-lead-modal.mjs +3 -3
  64. package/dist/components/ui/advisor-card.js +530 -0
  65. package/dist/components/ui/advisor-card.mjs +15 -0
  66. package/dist/components/ui/ai-assistant-drawer.js +11 -10
  67. package/dist/components/ui/ai-assistant-drawer.mjs +3 -3
  68. package/dist/components/ui/alert-dialog.js +2 -2
  69. package/dist/components/ui/alert-dialog.mjs +2 -2
  70. package/dist/components/ui/appointment-action-dialogs.js +1160 -0
  71. package/dist/components/ui/appointment-action-dialogs.mjs +23 -0
  72. package/dist/components/ui/appointment-availability-settings.js +1590 -0
  73. package/dist/components/ui/appointment-availability-settings.mjs +23 -0
  74. package/dist/components/ui/appointment-book-dialog.js +1744 -0
  75. package/dist/components/ui/appointment-book-dialog.mjs +27 -0
  76. package/dist/components/ui/appointment-calendar-view.js +833 -0
  77. package/dist/components/ui/appointment-calendar-view.mjs +14 -0
  78. package/dist/components/ui/appointment-detail-sheet.js +1517 -0
  79. package/dist/components/ui/appointment-detail-sheet.mjs +24 -0
  80. package/dist/components/ui/appointment-gmail-connect.js +467 -0
  81. package/dist/components/ui/appointment-gmail-connect.mjs +14 -0
  82. package/dist/components/ui/appointment-mini-card.js +345 -0
  83. package/dist/components/ui/appointment-mini-card.mjs +11 -0
  84. package/dist/components/ui/appointment-time-slot-picker.js +311 -0
  85. package/dist/components/ui/appointment-time-slot-picker.mjs +13 -0
  86. package/dist/components/ui/appointment-upcoming-card.js +1268 -0
  87. package/dist/components/ui/appointment-upcoming-card.mjs +21 -0
  88. package/dist/components/ui/backoffice-alert-history-chart.js +11 -5
  89. package/dist/components/ui/backoffice-alert-history-chart.mjs +5 -4
  90. package/dist/components/ui/backoffice-alerts-chart.js +786 -0
  91. package/dist/components/ui/backoffice-alerts-chart.mjs +19 -0
  92. package/dist/components/ui/backoffice-connections-chart.js +817 -0
  93. package/dist/components/ui/backoffice-connections-chart.mjs +19 -0
  94. package/dist/components/ui/backoffice-contact-history-chart.js +11 -5
  95. package/dist/components/ui/backoffice-contact-history-chart.mjs +5 -4
  96. package/dist/components/ui/badge.js +6 -6
  97. package/dist/components/ui/badge.mjs +1 -1
  98. package/dist/components/ui/borrowing-capacity-line-chart.js +30 -21
  99. package/dist/components/ui/borrowing-capacity-line-chart.mjs +5 -4
  100. package/dist/components/ui/button.js +2 -2
  101. package/dist/components/ui/button.mjs +1 -1
  102. package/dist/components/ui/calendar.js +2 -2
  103. package/dist/components/ui/calendar.mjs +2 -2
  104. package/dist/components/ui/card.js +1 -1
  105. package/dist/components/ui/card.mjs +1 -1
  106. package/dist/components/ui/cash-balance-line-chart.js +31 -23
  107. package/dist/components/ui/cash-balance-line-chart.mjs +5 -4
  108. package/dist/components/ui/cashflow-bar-chart.js +12 -5
  109. package/dist/components/ui/cashflow-bar-chart.mjs +5 -4
  110. package/dist/components/ui/chip.js +97 -18
  111. package/dist/components/ui/chip.mjs +3 -2
  112. package/dist/components/ui/color-picker.js +158 -28
  113. package/dist/components/ui/color-picker.mjs +3 -1
  114. package/dist/components/ui/data-table.js +140 -119
  115. package/dist/components/ui/data-table.mjs +3 -2
  116. package/dist/components/ui/date-picker.js +48 -27
  117. package/dist/components/ui/date-picker.mjs +4 -3
  118. package/dist/components/ui/dialog.js +37 -9
  119. package/dist/components/ui/dialog.mjs +2 -2
  120. package/dist/components/ui/expense-bar-chart.js +12 -5
  121. package/dist/components/ui/expense-bar-chart.mjs +5 -4
  122. package/dist/components/ui/field.mjs +2 -2
  123. package/dist/components/ui/financial-cards.js +322 -155
  124. package/dist/components/ui/financial-cards.mjs +5 -3
  125. package/dist/components/ui/financial-drawers.js +2 -2
  126. package/dist/components/ui/financial-drawers.mjs +3 -3
  127. package/dist/components/ui/financial-sections.js +14 -10
  128. package/dist/components/ui/financial-sections.mjs +6 -5
  129. package/dist/components/ui/income-bar-chart.js +12 -5
  130. package/dist/components/ui/income-bar-chart.mjs +5 -4
  131. package/dist/components/ui/input-group.js +2 -2
  132. package/dist/components/ui/input-group.mjs +2 -2
  133. package/dist/components/ui/kanban-column.js +52 -44
  134. package/dist/components/ui/kanban-column.mjs +7 -5
  135. package/dist/components/ui/opportunity-card.js +52 -44
  136. package/dist/components/ui/opportunity-card.mjs +6 -4
  137. package/dist/components/ui/opportunity-edit-modals.js +1367 -1263
  138. package/dist/components/ui/opportunity-edit-modals.mjs +8 -8
  139. package/dist/components/ui/opportunity-summary-tab.js +2744 -2157
  140. package/dist/components/ui/opportunity-summary-tab.mjs +14 -14
  141. package/dist/components/ui/page-header.js +92 -0
  142. package/dist/components/ui/page-header.mjs +8 -0
  143. package/dist/components/ui/page-top-bar.js +88 -0
  144. package/dist/components/ui/page-top-bar.mjs +8 -0
  145. package/dist/components/ui/pagination.js +303 -19
  146. package/dist/components/ui/pagination.mjs +11 -4
  147. package/dist/components/ui/pipeline-board.js +205 -191
  148. package/dist/components/ui/pipeline-board.mjs +9 -7
  149. package/dist/components/ui/pipeline-dialogs.js +114 -65
  150. package/dist/components/ui/pipeline-dialogs.mjs +7 -6
  151. package/dist/components/ui/pipeline-primitives.js +6 -6
  152. package/dist/components/ui/pipeline-primitives.mjs +2 -2
  153. package/dist/components/ui/property-cashflow-doughnut-chart.js +14 -12
  154. package/dist/components/ui/property-cashflow-doughnut-chart.mjs +5 -4
  155. package/dist/components/ui/property-debt-equity-doughnut-chart.js +14 -12
  156. package/dist/components/ui/property-debt-equity-doughnut-chart.mjs +5 -4
  157. package/dist/components/ui/property-mobile-estimate-line-chart.js +16 -14
  158. package/dist/components/ui/property-mobile-estimate-line-chart.mjs +5 -4
  159. package/dist/components/ui/sidebar-nav.js +426 -191
  160. package/dist/components/ui/sidebar-nav.mjs +5 -1
  161. package/dist/components/ui/stage-timeline.js +6 -6
  162. package/dist/components/ui/stage-timeline.mjs +3 -3
  163. package/dist/components/ui/transactions-expense-categories-doughnut-chart.js +18 -16
  164. package/dist/components/ui/transactions-expense-categories-doughnut-chart.mjs +5 -4
  165. package/dist/components/ui/transactions-income-expense-bar-chart.js +28 -12
  166. package/dist/components/ui/transactions-income-expense-bar-chart.mjs +5 -4
  167. package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.js +18 -16
  168. package/dist/components/ui/transactions-liabilities-breakdown-doughnut-chart.mjs +5 -4
  169. package/dist/index.js +12258 -8611
  170. package/dist/index.mjs +258 -190
  171. package/dist/styles.css +1 -1
  172. package/package.json +71 -1
  173. package/src/components/index.tsx +115 -9
  174. package/src/components/ui/add-column-modal.tsx +7 -7
  175. package/src/components/ui/add-lead-modal.tsx +6 -3
  176. package/src/components/ui/advisor-card.tsx +284 -0
  177. package/src/components/ui/ai-assistant-drawer.tsx +4 -3
  178. package/src/components/ui/appointment-action-dialogs.tsx +297 -0
  179. package/src/components/ui/appointment-availability-settings.tsx +645 -0
  180. package/src/components/ui/appointment-book-dialog.tsx +618 -0
  181. package/src/components/ui/appointment-calendar-view.tsx +510 -0
  182. package/src/components/ui/appointment-detail-sheet.tsx +415 -0
  183. package/src/components/ui/appointment-gmail-connect.tsx +188 -0
  184. package/src/components/ui/appointment-mini-card.tsx +104 -0
  185. package/src/components/ui/appointment-time-slot-picker.tsx +123 -0
  186. package/src/components/ui/appointment-upcoming-card.tsx +635 -0
  187. package/src/components/ui/backoffice-alert-history-chart.tsx +10 -2
  188. package/src/components/ui/backoffice-alerts-chart.tsx +312 -0
  189. package/src/components/ui/backoffice-connections-chart.tsx +339 -0
  190. package/src/components/ui/backoffice-contact-history-chart.tsx +10 -2
  191. package/src/components/ui/badge.tsx +12 -6
  192. package/src/components/ui/borrowing-capacity-line-chart.tsx +4 -11
  193. package/src/components/ui/button.tsx +2 -2
  194. package/src/components/ui/card.tsx +1 -1
  195. package/src/components/ui/cash-balance-line-chart.tsx +4 -23
  196. package/src/components/ui/cashflow-bar-chart.tsx +9 -2
  197. package/src/components/ui/chart-shared.tsx +4 -11
  198. package/src/components/ui/chip.tsx +23 -19
  199. package/src/components/ui/color-picker.tsx +4 -2
  200. package/src/components/ui/data-table.tsx +28 -74
  201. package/src/components/ui/date-picker.tsx +42 -37
  202. package/src/components/ui/dialog.tsx +72 -6
  203. package/src/components/ui/expense-bar-chart.tsx +11 -2
  204. package/src/components/ui/financial-cards.tsx +99 -10
  205. package/src/components/ui/income-bar-chart.tsx +11 -2
  206. package/src/components/ui/opportunity-card.tsx +10 -39
  207. package/src/components/ui/opportunity-edit-modals.tsx +98 -36
  208. package/src/components/ui/opportunity-summary-tab.tsx +548 -232
  209. package/src/components/ui/page-header.tsx +57 -0
  210. package/src/components/ui/page-top-bar.tsx +48 -0
  211. package/src/components/ui/pagination.tsx +171 -22
  212. package/src/components/ui/pipeline-board.tsx +12 -5
  213. package/src/components/ui/property-cashflow-doughnut-chart.tsx +3 -1
  214. package/src/components/ui/property-debt-equity-doughnut-chart.tsx +3 -1
  215. package/src/components/ui/property-mobile-estimate-line-chart.tsx +3 -1
  216. package/src/components/ui/sidebar-nav.tsx +213 -157
  217. package/src/components/ui/transactions-expense-categories-doughnut-chart.tsx +3 -1
  218. package/src/components/ui/transactions-income-expense-bar-chart.tsx +12 -9
  219. package/src/components/ui/transactions-liabilities-breakdown-doughnut-chart.tsx +3 -1
  220. package/src/lib/format-currency.ts +44 -0
  221. package/src/lib/format-date.ts +50 -0
  222. package/src/lib/opportunity-constants.ts +12 -0
  223. package/src/styles/globals.css +17 -15
  224. package/src/styles/styles-css.ts +1 -1
  225. package/tsup.config.ts +14 -0
  226. package/dist/chunk-S4QRUQNW.mjs +0 -475
  227. package/dist/chunk-URGMJAE3.mjs +0 -1885
  228. package/dist/chunk-WNGWBVLV.mjs +0 -148
  229. package/dist/chunk-ZRSDX6OW.mjs +0 -385
  230. package/dist/{chunk-LLVQKSU3.mjs → chunk-GD4BJDJR.mjs} +3 -3
@@ -62,8 +62,9 @@ __export(sidebar_nav_exports, {
62
62
  SidebarNav: () => SidebarNav
63
63
  });
64
64
  module.exports = __toCommonJS(sidebar_nav_exports);
65
- var React2 = __toESM(require("react"));
66
- var import_lucide_react = require("lucide-react");
65
+ var React3 = __toESM(require("react"));
66
+ var import_lucide_react3 = require("lucide-react");
67
+ var import_accordion2 = require("@base-ui/react/accordion");
67
68
 
68
69
  // src/lib/utils.ts
69
70
  var import_clsx = require("clsx");
@@ -104,26 +105,208 @@ function cn(...inputs) {
104
105
  return twMerge((0, import_clsx.clsx)(inputs));
105
106
  }
106
107
 
108
+ // src/lib/format-currency.ts
109
+ function formatCurrency(value, options) {
110
+ const { decimals = 0, showSign = false } = options != null ? options : {};
111
+ const abs = Math.abs(value);
112
+ const formatted = new Intl.NumberFormat("en-AU", {
113
+ style: "currency",
114
+ currency: "AUD",
115
+ minimumFractionDigits: decimals,
116
+ maximumFractionDigits: decimals
117
+ }).format(abs);
118
+ if (!showSign) return value < 0 ? `-${formatted}` : formatted;
119
+ if (value > 0) return `+${formatted}`;
120
+ if (value < 0) return `-${formatted}`;
121
+ return formatted;
122
+ }
123
+
124
+ // src/components/ui/accordion.tsx
125
+ var import_lucide_react = require("lucide-react");
126
+ var import_accordion = require("@base-ui/react/accordion");
127
+ var import_jsx_runtime = require("react/jsx-runtime");
128
+ function Accordion(props) {
129
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_accordion.Accordion.Root, __spreadValues({ "data-slot": "accordion" }, props));
130
+ }
131
+ function AccordionItem(_a) {
132
+ var _b = _a, {
133
+ className
134
+ } = _b, props = __objRest(_b, [
135
+ "className"
136
+ ]);
137
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
138
+ import_accordion.Accordion.Item,
139
+ __spreadValues({
140
+ className: cn("border-b", className),
141
+ "data-slot": "accordion-item"
142
+ }, props)
143
+ );
144
+ }
145
+ function AccordionContent(_a) {
146
+ var _b = _a, {
147
+ className,
148
+ children
149
+ } = _b, props = __objRest(_b, [
150
+ "className",
151
+ "children"
152
+ ]);
153
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
154
+ import_accordion.Accordion.Panel,
155
+ __spreadProps(__spreadValues({
156
+ className: "overflow-hidden text-body-small h-(--accordion-panel-height) transition-[height] duration-200 ease-out data-starting-style:h-0 data-ending-style:h-0",
157
+ "data-slot": "accordion-content"
158
+ }, props), {
159
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: cn("pb-4 text-muted-foreground", className), children })
160
+ })
161
+ );
162
+ }
163
+
164
+ // src/components/ui/button.tsx
165
+ var import_react = require("react");
166
+ var import_class_variance_authority = require("class-variance-authority");
167
+ var import_lucide_react2 = require("lucide-react");
168
+
169
+ // src/lib/slot.tsx
170
+ var React = __toESM(require("react"));
171
+ function mergeRefs(...refs) {
172
+ return (value) => {
173
+ for (const ref of refs) {
174
+ if (typeof ref === "function") ref(value);
175
+ else if (ref !== null)
176
+ ref.current = value;
177
+ }
178
+ };
179
+ }
180
+ var Slot = React.forwardRef(
181
+ (_a, forwardedRef) => {
182
+ var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
183
+ const child = React.Children.only(children);
184
+ if (!React.isValidElement(child)) return null;
185
+ const childProps = child.props;
186
+ const merged = __spreadValues({}, props);
187
+ for (const key of Object.keys(childProps)) {
188
+ if (key === "className") {
189
+ merged.className = [props.className, childProps.className].filter(Boolean).join(" ");
190
+ } else if (key === "style") {
191
+ merged.style = __spreadValues(__spreadValues({}, props.style), childProps.style);
192
+ } else if (key.startsWith("on") && typeof childProps[key] === "function") {
193
+ const parentHandler = props[key];
194
+ if (typeof parentHandler === "function") {
195
+ merged[key] = (...args) => {
196
+ childProps[key](...args);
197
+ parentHandler(...args);
198
+ };
199
+ } else {
200
+ merged[key] = childProps[key];
201
+ }
202
+ } else {
203
+ merged[key] = childProps[key];
204
+ }
205
+ }
206
+ const childRef = child.ref;
207
+ merged.ref = forwardedRef ? mergeRefs(forwardedRef, childRef) : childRef;
208
+ return React.cloneElement(
209
+ child,
210
+ merged
211
+ );
212
+ }
213
+ );
214
+ Slot.displayName = "Slot";
215
+
216
+ // src/components/ui/button.tsx
217
+ var import_jsx_runtime2 = require("react/jsx-runtime");
218
+ var buttonVariants = (0, import_class_variance_authority.cva)(
219
+ "inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 font-sans text-button whitespace-nowrap transition-all active:scale-[0.98] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
220
+ {
221
+ variants: {
222
+ variant: {
223
+ default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
224
+ secondary: "bg-brand-secondary text-brand-secondary-foreground shadow-xs hover:bg-brand-secondary/80 focus-visible:ring-brand-secondary/30",
225
+ destructive: "bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
226
+ outline: "border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground focus-visible:ring-border/50 dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
227
+ "outline-primary": "border border-primary text-foreground bg-transparent shadow-xs hover:bg-primary/5 focus-visible:ring-primary/50",
228
+ "outline-secondary": "border border-brand-secondary text-brand-secondary bg-transparent shadow-xs hover:bg-brand-secondary/10 focus-visible:ring-brand-secondary/30",
229
+ ghost: "hover:bg-accent hover:text-accent-foreground hover:shadow-xs focus-visible:ring-border/50 dark:hover:bg-accent/50",
230
+ link: "text-primary underline-offset-4 hover:underline"
231
+ },
232
+ size: {
233
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
234
+ xs: "h-6 gap-1 px-2 text-button-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
235
+ sm: "h-8 gap-1.5 px-3 has-[>svg]:px-2.5",
236
+ lg: "h-10 px-6 has-[>svg]:px-4",
237
+ icon: "size-9",
238
+ "icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
239
+ "icon-sm": "size-8",
240
+ "icon-lg": "size-10"
241
+ }
242
+ },
243
+ defaultVariants: {
244
+ variant: "default",
245
+ size: "default"
246
+ }
247
+ }
248
+ );
249
+ var Button = (0, import_react.forwardRef)(function Button2(_a, ref) {
250
+ var _b = _a, {
251
+ className,
252
+ variant,
253
+ size,
254
+ asChild = false,
255
+ loading = false,
256
+ disabled,
257
+ type = "button",
258
+ children
259
+ } = _b, props = __objRest(_b, [
260
+ "className",
261
+ "variant",
262
+ "size",
263
+ "asChild",
264
+ "loading",
265
+ "disabled",
266
+ "type",
267
+ "children"
268
+ ]);
269
+ const Comp = asChild ? Slot : "button";
270
+ const isIconOnly = size === "icon" || size === "icon-xs" || size === "icon-sm" || size === "icon-lg";
271
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
272
+ Comp,
273
+ __spreadProps(__spreadValues({
274
+ className: cn(buttonVariants({ variant, size, className })),
275
+ "data-size": size,
276
+ "data-slot": "button",
277
+ "data-variant": variant,
278
+ disabled: loading || disabled,
279
+ ref,
280
+ type
281
+ }, props), {
282
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
283
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Loader2, { "aria-hidden": "true", className: "animate-spin" }),
284
+ !isIconOnly && children
285
+ ] }) : children
286
+ })
287
+ );
288
+ });
289
+
107
290
  // src/components/ui/tooltip.tsx
108
291
  var import_tooltip = require("@base-ui/react/tooltip");
109
292
 
110
293
  // src/lib/theme-provider.tsx
111
- var import_react = require("react");
112
- var import_jsx_runtime = require("react/jsx-runtime");
113
- var ThemeVarsContext = (0, import_react.createContext)({});
294
+ var import_react2 = require("react");
295
+ var import_jsx_runtime3 = require("react/jsx-runtime");
296
+ var ThemeVarsContext = (0, import_react2.createContext)({});
114
297
  function useThemeVars() {
115
- return (0, import_react.useContext)(ThemeVarsContext);
298
+ return (0, import_react2.useContext)(ThemeVarsContext);
116
299
  }
117
300
 
118
301
  // src/components/ui/tooltip.tsx
119
- var import_jsx_runtime2 = require("react/jsx-runtime");
302
+ var import_jsx_runtime4 = require("react/jsx-runtime");
120
303
  function TooltipProvider(_a) {
121
304
  var _b = _a, {
122
305
  delay = 0
123
306
  } = _b, props = __objRest(_b, [
124
307
  "delay"
125
308
  ]);
126
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
309
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
127
310
  import_tooltip.Tooltip.Provider,
128
311
  __spreadValues({
129
312
  "data-slot": "tooltip-provider",
@@ -133,11 +316,11 @@ function TooltipProvider(_a) {
133
316
  }
134
317
  function Tooltip(_a) {
135
318
  var props = __objRest(_a, []);
136
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_tooltip.Tooltip.Root, __spreadValues({ "data-slot": "tooltip" }, props));
319
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_tooltip.Tooltip.Root, __spreadValues({ "data-slot": "tooltip" }, props));
137
320
  }
138
321
  function TooltipTrigger(_a) {
139
322
  var props = __objRest(_a, []);
140
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_tooltip.Tooltip.Trigger, __spreadValues({ "data-slot": "tooltip-trigger" }, props));
323
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_tooltip.Tooltip.Trigger, __spreadValues({ "data-slot": "tooltip-trigger" }, props));
141
324
  }
142
325
  function TooltipContent(_a) {
143
326
  var _b = _a, {
@@ -154,7 +337,7 @@ function TooltipContent(_a) {
154
337
  "style"
155
338
  ]);
156
339
  const themeVars = useThemeVars();
157
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_tooltip.Tooltip.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_tooltip.Tooltip.Positioner, { sideOffset, side, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
340
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_tooltip.Tooltip.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_tooltip.Tooltip.Positioner, { sideOffset, side, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
158
341
  import_tooltip.Tooltip.Popup,
159
342
  __spreadProps(__spreadValues({
160
343
  className: cn(
@@ -166,30 +349,17 @@ function TooltipContent(_a) {
166
349
  }, props), {
167
350
  children: [
168
351
  children,
169
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_tooltip.Tooltip.Arrow, { className: "z-50 size-2.5 rotate-45 bg-brand-secondary data-[side=bottom]:-top-1 data-[side=left]:-right-1 data-[side=right]:-left-1 data-[side=top]:-bottom-1" })
352
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_tooltip.Tooltip.Arrow, { className: "z-50 size-2.5 rotate-45 bg-brand-secondary data-[side=bottom]:-top-1 data-[side=left]:-right-1 data-[side=right]:-left-1 data-[side=top]:-bottom-1" })
170
353
  ]
171
354
  })
172
355
  ) }) });
173
356
  }
174
357
 
175
358
  // src/components/ui/sidebar-nav.tsx
176
- var import_jsx_runtime3 = require("react/jsx-runtime");
359
+ var import_jsx_runtime5 = require("react/jsx-runtime");
177
360
  function getInitials(name) {
178
361
  return name.split(" ").filter(Boolean).map((word) => word[0]).join("").toUpperCase().slice(0, 2);
179
362
  }
180
- function formatCurrency(value, isNetItem = false) {
181
- const abs = Math.abs(value);
182
- const formatted = new Intl.NumberFormat("en-AU", {
183
- style: "currency",
184
- currency: "AUD",
185
- minimumFractionDigits: 0,
186
- maximumFractionDigits: 0
187
- }).format(abs);
188
- if (!isNetItem) return formatted;
189
- if (value > 0) return `+${formatted}`;
190
- if (value < 0) return `-${formatted}`;
191
- return formatted;
192
- }
193
363
  function navIconCn(isActive) {
194
364
  return cn(
195
365
  "shrink-0 transition-colors",
@@ -198,19 +368,19 @@ function navIconCn(isActive) {
198
368
  }
199
369
  function NavTooltip({ label, collapsed, children }) {
200
370
  if (!collapsed) return children;
201
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Tooltip, { children: [
202
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TooltipTrigger, { render: children }),
203
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TooltipContent, { side: "right", children: label })
371
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Tooltip, { children: [
372
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TooltipTrigger, { render: children }),
373
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TooltipContent, { side: "right", children: label })
204
374
  ] });
205
375
  }
206
376
  function MetricsGroup({ group }) {
207
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "border-b border-white/15 py-4 px-5 flex flex-col gap-1.5", children: group.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
377
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "border-b border-white/15 py-4 px-5 flex flex-col gap-1.5", children: group.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
208
378
  "div",
209
379
  {
210
380
  className: "flex items-center justify-between gap-2",
211
381
  children: [
212
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-1 min-w-0", children: [
213
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
382
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-1 min-w-0", children: [
383
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
214
384
  "span",
215
385
  {
216
386
  className: cn(
@@ -220,8 +390,8 @@ function MetricsGroup({ group }) {
220
390
  children: item.name
221
391
  }
222
392
  ),
223
- item.info && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
224
- import_lucide_react.Info,
393
+ item.info && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
394
+ import_lucide_react3.Info,
225
395
  {
226
396
  size: 11,
227
397
  strokeWidth: 2,
@@ -229,14 +399,14 @@ function MetricsGroup({ group }) {
229
399
  }
230
400
  )
231
401
  ] }),
232
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
402
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
233
403
  "span",
234
404
  {
235
405
  className: cn(
236
406
  "text-sm font-semibold tabular-nums shrink-0 text-brand-secondary-foreground",
237
407
  item.isNetItem && item.value < 0 && "text-destructive"
238
408
  ),
239
- children: formatCurrency(item.value, item.isNetItem)
409
+ children: formatCurrency(item.value, { showSign: item.isNetItem })
240
410
  }
241
411
  )
242
412
  ]
@@ -251,29 +421,30 @@ function SidebarNavItemView({
251
421
  }) {
252
422
  var _a;
253
423
  const Icon = item.icon;
254
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NavTooltip, { label: item.title, collapsed, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
255
- "button",
424
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(NavTooltip, { label: item.title, collapsed, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
425
+ Button,
256
426
  {
257
427
  type: "button",
428
+ variant: "ghost",
258
429
  onClick: () => onNavigate == null ? void 0 : onNavigate(item.href),
259
430
  className: cn(
260
- "group flex w-full items-center gap-3 py-2.5 text-base font-medium transition-colors",
431
+ "group h-auto w-full items-center gap-3 py-2.5 text-base font-medium transition-colors",
261
432
  "text-brand-secondary-foreground/70 hover:bg-white/10 hover:text-brand-secondary-foreground",
262
433
  collapsed ? "justify-center px-2" : cn(
263
- "px-3 border-l-4",
434
+ "justify-start px-3 border-l-4",
264
435
  item.isActive ? "bg-white/15 text-brand-secondary-foreground border-primary" : "border-transparent"
265
436
  )
266
437
  ),
267
438
  children: [
268
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
439
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
269
440
  Icon,
270
441
  {
271
442
  className: navIconCn((_a = item.isActive) != null ? _a : false),
272
- size: 18,
443
+ size: 24,
273
444
  strokeWidth: 1.75
274
445
  }
275
446
  ),
276
- !collapsed && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "truncate", children: item.title })
447
+ !collapsed && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "truncate", children: item.title })
277
448
  ]
278
449
  }
279
450
  ) });
@@ -286,96 +457,103 @@ function CollapsibleNavItem({
286
457
  var _a, _b;
287
458
  const Icon = item.icon;
288
459
  const hasActiveChild = (_b = (_a = item.subItems) == null ? void 0 : _a.some((sub) => sub.isActive)) != null ? _b : false;
289
- const [open, setOpen] = React2.useState(hasActiveChild);
290
- React2.useEffect(() => {
460
+ const [open, setOpen] = React3.useState(hasActiveChild);
461
+ React3.useEffect(() => {
291
462
  if (hasActiveChild) setOpen(true);
292
463
  }, [hasActiveChild]);
293
464
  if (collapsed) {
294
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NavTooltip, { label: item.title, collapsed, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
295
- "button",
465
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(NavTooltip, { label: item.title, collapsed, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
466
+ Button,
296
467
  {
297
468
  type: "button",
469
+ variant: "ghost",
298
470
  onClick: () => onNavigate == null ? void 0 : onNavigate(item.href),
299
471
  className: cn(
300
- "group flex w-full items-center justify-center px-2 py-2.5 transition-colors",
472
+ "group h-auto w-full justify-center px-2 py-2.5 transition-colors",
301
473
  "text-brand-secondary-foreground/70 hover:bg-white/10 hover:text-brand-secondary-foreground",
302
474
  hasActiveChild && "bg-white/15 text-brand-secondary-foreground"
303
475
  ),
304
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
476
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
305
477
  Icon,
306
478
  {
307
479
  className: navIconCn(hasActiveChild),
308
- size: 18,
480
+ size: 24,
309
481
  strokeWidth: 1.75
310
482
  }
311
483
  )
312
484
  }
313
485
  ) });
314
486
  }
315
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
316
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
317
- "button",
318
- {
319
- type: "button",
320
- onClick: () => setOpen((prev) => !prev),
321
- className: cn(
322
- "group flex w-full items-center gap-3 px-3 py-2.5 text-base font-medium transition-colors",
323
- "text-brand-secondary-foreground/70 hover:bg-white/10 hover:text-brand-secondary-foreground",
324
- "border-l-4 border-transparent",
325
- hasActiveChild && "bg-white/15 text-brand-secondary-foreground border-primary"
326
- ),
327
- children: [
328
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
329
- Icon,
330
- {
331
- className: navIconCn(hasActiveChild),
332
- size: 18,
333
- strokeWidth: 1.75
334
- }
335
- ),
336
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "flex-1 truncate text-left", children: item.title }),
337
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
338
- import_lucide_react.ChevronDown,
339
- {
340
- className: cn(
341
- "ml-auto shrink-0 text-brand-secondary-foreground/40 transition-transform duration-200",
342
- open && "rotate-180"
487
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
488
+ Accordion,
489
+ {
490
+ value: open ? [item.href] : [],
491
+ onValueChange: (values) => setOpen(values.length > 0),
492
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(AccordionItem, { className: "border-none", value: item.href, children: [
493
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_accordion2.Accordion.Header, { className: "flex", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
494
+ import_accordion2.Accordion.Trigger,
495
+ {
496
+ className: cn(
497
+ "group flex h-auto w-full items-center justify-start gap-3 px-3 py-2.5 text-base font-medium transition-colors",
498
+ "text-brand-secondary-foreground/70 hover:bg-white/10 hover:text-brand-secondary-foreground",
499
+ "border-l-4 border-transparent",
500
+ hasActiveChild && "bg-white/15 text-brand-secondary-foreground border-primary"
501
+ ),
502
+ children: [
503
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
504
+ Icon,
505
+ {
506
+ className: navIconCn(hasActiveChild),
507
+ size: 24,
508
+ strokeWidth: 1.75
509
+ }
343
510
  ),
344
- size: 14,
345
- strokeWidth: 2
346
- }
347
- )
348
- ]
349
- }
350
- ),
351
- open && item.subItems && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "ml-9 border-l border-white/15 pl-3", children: item.subItems.map((sub) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
352
- "button",
353
- {
354
- type: "button",
355
- onClick: () => onNavigate == null ? void 0 : onNavigate(sub.href),
356
- className: cn(
357
- "flex w-full items-center gap-2 py-1.5 pl-1 text-sm transition-colors",
358
- "text-brand-secondary-foreground/50 hover:text-brand-secondary-foreground",
359
- sub.isActive && "text-primary font-medium"
360
- ),
361
- children: [
362
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
363
- import_lucide_react.ChevronRight,
364
- {
365
- size: 11,
366
- strokeWidth: 2,
367
- className: cn(
368
- "shrink-0",
369
- sub.isActive ? "text-primary" : "text-brand-secondary-foreground/30"
511
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "flex-1 truncate text-left", children: item.title }),
512
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
513
+ import_lucide_react3.ChevronDown,
514
+ {
515
+ className: cn(
516
+ "ml-auto shrink-0 text-brand-secondary-foreground/40 transition-transform duration-200",
517
+ "group-data-[panel-open]:rotate-180"
518
+ ),
519
+ size: 14,
520
+ strokeWidth: 2
521
+ }
370
522
  )
371
- }
372
- ),
373
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "truncate", children: sub.title })
374
- ]
375
- },
376
- sub.href
377
- )) })
378
- ] });
523
+ ]
524
+ }
525
+ ) }),
526
+ item.subItems && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AccordionContent, { className: "p-0 text-inherit", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "ml-9 border-l border-white/15 pl-3", children: item.subItems.map((sub) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
527
+ Button,
528
+ {
529
+ type: "button",
530
+ variant: "ghost",
531
+ onClick: () => onNavigate == null ? void 0 : onNavigate(sub.href),
532
+ className: cn(
533
+ "h-auto w-full justify-start gap-2 py-1.5 pl-1 text-sm transition-colors",
534
+ "text-brand-secondary-foreground/50 hover:text-brand-secondary-foreground",
535
+ sub.isActive && "text-primary font-medium"
536
+ ),
537
+ children: [
538
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
539
+ import_lucide_react3.ChevronRight,
540
+ {
541
+ size: 11,
542
+ strokeWidth: 2,
543
+ className: cn(
544
+ "shrink-0",
545
+ sub.isActive ? "text-primary" : "text-brand-secondary-foreground/30"
546
+ )
547
+ }
548
+ ),
549
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "truncate", children: sub.title })
550
+ ]
551
+ },
552
+ sub.href
553
+ )) }) })
554
+ ] })
555
+ }
556
+ );
379
557
  }
380
558
  function SidebarNav({
381
559
  items,
@@ -389,93 +567,149 @@ function SidebarNav({
389
567
  onCollapsedChange,
390
568
  className
391
569
  }) {
392
- const [userMenuOpen, setUserMenuOpen] = React2.useState(false);
393
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
570
+ const [userMenuOpen, setUserMenuOpen] = React3.useState(false);
571
+ const navScrollRef = React3.useRef(null);
572
+ const expandedScrollRef = React3.useRef(0);
573
+ React3.useEffect(() => {
574
+ if (collapsed) setUserMenuOpen(false);
575
+ }, [collapsed]);
576
+ React3.useLayoutEffect(() => {
577
+ const nav = navScrollRef.current;
578
+ if (!nav) return;
579
+ if (!collapsed) {
580
+ nav.scrollTop = expandedScrollRef.current;
581
+ }
582
+ return () => {
583
+ if (!collapsed && nav) {
584
+ expandedScrollRef.current = nav.scrollTop;
585
+ }
586
+ };
587
+ }, [collapsed]);
588
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
394
589
  "nav",
395
590
  {
396
591
  "data-slot": "sidebar-nav",
397
592
  "data-collapsed": collapsed,
398
593
  className: cn(
399
- "flex h-full flex-col bg-brand-secondary text-brand-secondary-foreground",
594
+ // Force dark-mode CSS variable resolution — sidebar is always dark-backgrounded
595
+ // regardless of system theme, so semantic tokens (destructive, success, etc.)
596
+ // must use their dark-mode values to maintain WCAG contrast.
597
+ "dark flex h-full flex-col bg-brand-secondary text-brand-secondary-foreground",
400
598
  "transition-all duration-200 ease-in-out",
401
599
  collapsed ? "w-14" : "w-[279px]",
402
600
  className
403
601
  ),
404
602
  children: [
405
- !collapsed && logo && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex items-center border-b border-white/15 px-5 py-4", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
406
- "img",
407
- {
408
- src: logo,
409
- alt: "Logo",
410
- className: "h-8 w-auto object-contain object-left",
411
- style: { filter: "brightness(0) invert(1)" }
412
- }
413
- ) }),
414
- collapsed && logoCollapsed && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex items-center justify-center border-b border-white/15 py-4", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
415
- "img",
416
- {
417
- src: logoCollapsed,
418
- alt: "Logo",
419
- className: "h-8 w-8 object-contain",
420
- style: { filter: "brightness(0) invert(1)" }
421
- }
422
- ) }),
423
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "border-b border-white/15", children: [
424
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NavTooltip, { label: userName, collapsed, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
425
- "button",
603
+ (logo || logoCollapsed) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "relative flex items-center border-b border-white/15 py-4 overflow-hidden", children: [
604
+ logo && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
605
+ "img",
426
606
  {
427
- type: "button",
428
- onClick: () => !collapsed && setUserMenuOpen((prev) => !prev),
607
+ src: logo,
608
+ alt: "Logo",
429
609
  className: cn(
430
- "group flex w-full items-center gap-3 px-5 py-5 text-base transition-colors",
431
- "text-brand-secondary-foreground hover:bg-white/10",
432
- collapsed && "justify-center px-2 py-4"
610
+ "h-8 w-auto object-contain object-left px-5 transition-opacity duration-200",
611
+ collapsed ? "opacity-0" : "opacity-100"
433
612
  ),
434
- children: [
435
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center font-semibold text-xs bg-primary text-primary-foreground", children: getInitials(userName) }),
436
- !collapsed && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
437
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "flex-1 truncate text-left font-medium text-brand-secondary-foreground", children: userName }),
438
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
439
- import_lucide_react.ChevronDown,
440
- {
441
- className: cn(
442
- "shrink-0 text-brand-secondary-foreground/50 transition-transform duration-200",
443
- userMenuOpen && "rotate-180"
444
- ),
445
- size: 16,
446
- strokeWidth: 2
447
- }
448
- )
449
- ] })
450
- ]
613
+ style: { filter: "brightness(0) invert(1)" }
451
614
  }
452
- ) }),
453
- !collapsed && userMenuOpen && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "border-t border-white/15 bg-black/20", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
454
- "button",
615
+ ),
616
+ logoCollapsed && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
617
+ "img",
455
618
  {
456
- type: "button",
457
- onClick: onLogout,
619
+ src: logoCollapsed,
620
+ alt: "Logo",
458
621
  className: cn(
459
- "flex w-full items-center gap-3 px-5 py-3 text-base",
460
- "text-brand-secondary-foreground/70 hover:bg-white/10 hover:text-brand-secondary-foreground transition-colors"
622
+ "absolute inset-y-0 left-0 right-0 m-auto h-8 w-8 object-contain transition-opacity duration-200",
623
+ collapsed ? "opacity-100" : "opacity-0"
461
624
  ),
462
- children: [
463
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
464
- import_lucide_react.LogOut,
465
- {
466
- size: 16,
467
- strokeWidth: 1.75,
468
- className: "shrink-0 text-destructive"
469
- }
470
- ),
471
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Logout" })
472
- ]
625
+ style: { filter: "brightness(0) invert(1)" }
626
+ }
627
+ )
628
+ ] }),
629
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "relative border-b border-white/15", children: [
630
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
631
+ "div",
632
+ {
633
+ className: cn(
634
+ collapsed ? "opacity-0 pointer-events-none" : "opacity-100"
635
+ ),
636
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
637
+ Accordion,
638
+ {
639
+ value: userMenuOpen ? ["user-menu"] : [],
640
+ onValueChange: (values) => setUserMenuOpen(values.length > 0),
641
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(AccordionItem, { className: "border-none", value: "user-menu", children: [
642
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_accordion2.Accordion.Header, { className: "flex", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
643
+ import_accordion2.Accordion.Trigger,
644
+ {
645
+ className: cn(
646
+ "group flex h-auto w-full items-center justify-start gap-3 px-5 py-5 text-base transition-colors",
647
+ "text-brand-secondary-foreground hover:bg-white/10"
648
+ ),
649
+ children: [
650
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center font-semibold text-xs bg-primary text-primary-foreground", children: getInitials(userName) }),
651
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "flex-1 truncate text-left font-medium text-brand-secondary-foreground", children: userName }),
652
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
653
+ import_lucide_react3.ChevronDown,
654
+ {
655
+ className: "ml-auto shrink-0 text-brand-secondary-foreground/50 transition-transform duration-200 group-data-[panel-open]:rotate-180",
656
+ size: 16,
657
+ strokeWidth: 2
658
+ }
659
+ )
660
+ ]
661
+ }
662
+ ) }),
663
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AccordionContent, { className: "p-0 text-inherit", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "border-t border-white/15 bg-black/20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
664
+ Button,
665
+ {
666
+ type: "button",
667
+ variant: "ghost",
668
+ onClick: onLogout,
669
+ className: cn(
670
+ "h-auto w-full justify-start gap-3 px-5 py-3 text-base",
671
+ "text-brand-secondary-foreground/70 hover:bg-white/10 hover:text-brand-secondary-foreground transition-colors"
672
+ ),
673
+ children: [
674
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
675
+ import_lucide_react3.LogOut,
676
+ {
677
+ size: 16,
678
+ strokeWidth: 1.75,
679
+ className: "shrink-0 text-destructive"
680
+ }
681
+ ),
682
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Logout" })
683
+ ]
684
+ }
685
+ ) }) })
686
+ ] })
687
+ }
688
+ )
689
+ }
690
+ ),
691
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(NavTooltip, { label: userName, collapsed, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
692
+ "div",
693
+ {
694
+ className: cn(
695
+ "absolute inset-0 flex items-center justify-center transition-opacity duration-200",
696
+ collapsed ? "opacity-100" : "opacity-0 pointer-events-none"
697
+ ),
698
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center font-semibold text-xs bg-primary text-primary-foreground", children: getInitials(userName) })
473
699
  }
474
700
  ) })
475
701
  ] }),
476
- !collapsed && !!(metricsGroups == null ? void 0 : metricsGroups.length) && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: metricsGroups.map((group, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MetricsGroup, { group }, i)) }),
477
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex flex-col overflow-y-auto py-3", children: items.map(
478
- (item) => item.isCollapsible ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
702
+ !!(metricsGroups == null ? void 0 : metricsGroups.length) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
703
+ Accordion,
704
+ {
705
+ value: !collapsed ? ["metrics"] : [],
706
+ onValueChange: () => {
707
+ },
708
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AccordionItem, { className: "border-none", value: "metrics", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AccordionContent, { className: "p-0 text-inherit", children: metricsGroups.map((group, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MetricsGroup, { group }, i)) }) })
709
+ }
710
+ ),
711
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: navScrollRef, className: "flex flex-col overflow-y-auto py-3", children: items.map(
712
+ (item) => item.isCollapsible ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
479
713
  CollapsibleNavItem,
480
714
  {
481
715
  item,
@@ -483,7 +717,7 @@ function SidebarNav({
483
717
  onNavigate
484
718
  },
485
719
  item.href
486
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
720
+ ) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
487
721
  SidebarNavItemView,
488
722
  {
489
723
  item,
@@ -493,38 +727,39 @@ function SidebarNav({
493
727
  item.href
494
728
  )
495
729
  ) }),
496
- onCollapsedChange && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mt-auto border-t border-white/15 bg-white/8", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
730
+ onCollapsedChange && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mt-auto border-t border-white/15 bg-white/8", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
497
731
  NavTooltip,
498
732
  {
499
733
  label: collapsed ? "Expand" : "Collapse",
500
734
  collapsed,
501
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
502
- "button",
735
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
736
+ Button,
503
737
  {
504
738
  type: "button",
739
+ variant: "ghost",
505
740
  onClick: () => onCollapsedChange(!collapsed),
506
741
  className: cn(
507
- "flex w-full items-center gap-3 px-3 py-3 transition-colors",
742
+ "h-12 w-full justify-start gap-3 px-3 py-3 transition-colors",
508
743
  "text-brand-secondary-foreground/80 hover:bg-white/10 hover:text-brand-secondary-foreground",
509
744
  collapsed && "justify-center px-2"
510
745
  ),
511
746
  children: [
512
- collapsed ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
513
- import_lucide_react.PanelLeftOpen,
747
+ collapsed ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
748
+ import_lucide_react3.PanelLeftOpen,
514
749
  {
515
- size: 18,
750
+ size: 24,
516
751
  strokeWidth: 1.75,
517
752
  className: "shrink-0"
518
753
  }
519
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
520
- import_lucide_react.PanelLeftClose,
754
+ ) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
755
+ import_lucide_react3.PanelLeftClose,
521
756
  {
522
- size: 18,
757
+ size: 24,
523
758
  strokeWidth: 1.75,
524
759
  className: "shrink-0"
525
760
  }
526
761
  ),
527
- !collapsed && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-sm", children: "Collapse" })
762
+ !collapsed && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-sm", children: "Collapse" })
528
763
  ]
529
764
  }
530
765
  )