@burdenoff/microfe-atheletebridge 2026.624.1 → 2026.625.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 (43) hide show
  1. package/dist/atheletebridge/components/EmptyState.js +18 -11
  2. package/dist/atheletebridge/components/EmptyState.js.map +1 -1
  3. package/dist/atheletebridge/components/InvestmentCard.js +7 -7
  4. package/dist/atheletebridge/components/InvestmentCard.js.map +1 -1
  5. package/dist/atheletebridge/components/MetricsCard.js +20 -14
  6. package/dist/atheletebridge/components/MetricsCard.js.map +1 -1
  7. package/dist/atheletebridge/components/PageLayout.js +30 -19
  8. package/dist/atheletebridge/components/PageLayout.js.map +1 -1
  9. package/dist/atheletebridge/pages/HomePage.js +218 -207
  10. package/dist/atheletebridge/pages/HomePage.js.map +1 -1
  11. package/dist/atheletebridge/pages/common/NotificationCenterPage.js +1 -0
  12. package/dist/atheletebridge/pages/common/NotificationCenterPage.js.map +1 -1
  13. package/dist/atheletebridge/pages/customer/BookingDetailsPage.js +1 -0
  14. package/dist/atheletebridge/pages/customer/BookingDetailsPage.js.map +1 -1
  15. package/dist/atheletebridge/pages/customer/CartDetailPage.js +1 -0
  16. package/dist/atheletebridge/pages/customer/CartDetailPage.js.map +1 -1
  17. package/dist/atheletebridge/pages/customer/CartDiscoveryPage.js +1 -0
  18. package/dist/atheletebridge/pages/customer/CartDiscoveryPage.js.map +1 -1
  19. package/dist/atheletebridge/pages/customer/DirectServiceBookingPage.js +1 -0
  20. package/dist/atheletebridge/pages/customer/DirectServiceBookingPage.js.map +1 -1
  21. package/dist/atheletebridge/pages/customer/FavoritesPage.js +1 -0
  22. package/dist/atheletebridge/pages/customer/FavoritesPage.js.map +1 -1
  23. package/dist/atheletebridge/pages/customer/OrderHistoryPage.js +1 -0
  24. package/dist/atheletebridge/pages/customer/OrderHistoryPage.js.map +1 -1
  25. package/dist/atheletebridge/pages/customer/OrderTrackingPage.js +1 -0
  26. package/dist/atheletebridge/pages/customer/OrderTrackingPage.js.map +1 -1
  27. package/dist/atheletebridge/pages/customer/PaymentMethodsPage.js +1 -0
  28. package/dist/atheletebridge/pages/customer/PaymentMethodsPage.js.map +1 -1
  29. package/dist/atheletebridge/pages/customer/ReviewsPage.js +1 -0
  30. package/dist/atheletebridge/pages/customer/ReviewsPage.js.map +1 -1
  31. package/dist/atheletebridge/pages/customer/SavedAddressesPage.js +1 -0
  32. package/dist/atheletebridge/pages/customer/SavedAddressesPage.js.map +1 -1
  33. package/dist/atheletebridge/pages/investor/InvestmentOpportunitiesPage.js +1 -0
  34. package/dist/atheletebridge/pages/investor/InvestmentOpportunitiesPage.js.map +1 -1
  35. package/dist/atheletebridge/pages/investor/InvestorInvestmentsPage.js +1 -0
  36. package/dist/atheletebridge/pages/investor/InvestorInvestmentsPage.js.map +1 -1
  37. package/dist/atheletebridge/pages/worker/TaskDetailsPage.js +1 -0
  38. package/dist/atheletebridge/pages/worker/TaskDetailsPage.js.map +1 -1
  39. package/dist/atheletebridge/pages/worker/WorkerOrdersPage.js +1 -0
  40. package/dist/atheletebridge/pages/worker/WorkerOrdersPage.js.map +1 -1
  41. package/dist/atheletebridge/pages/worker/WorkerSchedulePage.js +2 -0
  42. package/dist/atheletebridge/pages/worker/WorkerSchedulePage.js.map +1 -1
  43. package/package.json +3 -3
@@ -1,28 +1,35 @@
1
1
  import { cn as e } from "../utils/cn.js";
2
2
  import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
+ import { IllustratedEmptyState as r } from "@burdenoff/fe-libs/ui";
3
4
  //#region src/atheletebridge/components/EmptyState.tsx
4
- var r = ({ icon: r, title: i, description: a, action: o, className: s }) => /* @__PURE__ */ n("div", {
5
- className: e("flex flex-col items-center justify-center py-12 px-4 text-center", s),
5
+ var i = ({ icon: i, illustration: a, title: o, description: s, action: c, className: l }) => a ? /* @__PURE__ */ t(r, {
6
+ illustration: a,
7
+ title: o,
8
+ description: s,
9
+ action: c,
10
+ className: l
11
+ }) : /* @__PURE__ */ n("div", {
12
+ className: e("flex flex-col items-center justify-center py-12 px-4 text-center", l),
6
13
  children: [
7
- r && /* @__PURE__ */ t("div", {
14
+ i && /* @__PURE__ */ t("div", {
8
15
  className: "mb-4 text-text-secondary opacity-50",
9
- children: r
16
+ children: i
10
17
  }),
11
18
  /* @__PURE__ */ t("h3", {
12
- className: "text-lg font-medium text-text-primary",
13
- children: i
19
+ className: "text-lg font-semibold tracking-tight text-text-primary",
20
+ children: o
14
21
  }),
15
- a && /* @__PURE__ */ t("p", {
22
+ s && /* @__PURE__ */ t("p", {
16
23
  className: "mt-2 text-sm text-text-secondary max-w-sm",
17
- children: a
24
+ children: s
18
25
  }),
19
- o && /* @__PURE__ */ t("div", {
26
+ c && /* @__PURE__ */ t("div", {
20
27
  className: "mt-6",
21
- children: o
28
+ children: c
22
29
  })
23
30
  ]
24
31
  });
25
32
  //#endregion
26
- export { r as EmptyState };
33
+ export { i as EmptyState };
27
34
 
28
35
  //# sourceMappingURL=EmptyState.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EmptyState.js","names":[],"sources":["../../../src/atheletebridge/components/EmptyState.tsx"],"sourcesContent":["/**\n * Empty State Component\n * @module atheletebridge/components\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { cn } from '../utils/cn';\n\ninterface EmptyStateProps {\n icon?: ReactNode;\n title: string;\n description?: string;\n action?: ReactNode;\n className?: string;\n}\n\nexport const EmptyState: FC<EmptyStateProps> = ({\n icon,\n title,\n description,\n action,\n className,\n}) => {\n return (\n <div\n className={cn('flex flex-col items-center justify-center py-12 px-4 text-center', className)}\n >\n {icon && <div className=\"mb-4 text-text-secondary opacity-50\">{icon}</div>}\n <h3 className=\"text-lg font-medium text-text-primary\">{title}</h3>\n {description && <p className=\"mt-2 text-sm text-text-secondary max-w-sm\">{description}</p>}\n {action && <div className=\"mt-6\">{action}</div>}\n </div>\n );\n};\n"],"mappings":";;;AAgBA,IAAa,KAAmC,EAC9C,SACA,UACA,gBACA,WACA,mBAGE,kBAAC,OAAD;CACE,WAAW,EAAG,oEAAoE,EAAU;WAD9F;EAGG,KAAQ,kBAAC,OAAD;GAAK,WAAU;aAAuC;GAAW,CAAA;EAC1E,kBAAC,MAAD;GAAI,WAAU;aAAyC;GAAW,CAAA;EACjE,KAAe,kBAAC,KAAD;GAAG,WAAU;aAA6C;GAAgB,CAAA;EACzF,KAAU,kBAAC,OAAD;GAAK,WAAU;aAAQ;GAAa,CAAA;EAC3C"}
1
+ {"version":3,"file":"EmptyState.js","names":[],"sources":["../../../src/atheletebridge/components/EmptyState.tsx"],"sourcesContent":["/**\n * Empty State Component\n * @module atheletebridge/components\n *\n * Boff UI 2.0: when an `illustration` name is provided, renders the on-brand\n * `IllustratedEmptyState` (host serves /illustrations/<name>.webp). Falls back\n * to the calm icon-based layout for callers that pass an `icon`.\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\n\ninterface EmptyStateProps {\n icon?: ReactNode;\n /** On-brand illustration name → /illustrations/<name>.webp (preferred). */\n illustration?: string;\n title: string;\n description?: string;\n action?: ReactNode;\n className?: string;\n}\n\nexport const EmptyState: FC<EmptyStateProps> = ({\n icon,\n illustration,\n title,\n description,\n action,\n className,\n}) => {\n if (illustration) {\n return (\n <IllustratedEmptyState\n illustration={illustration}\n title={title}\n description={description}\n action={action}\n className={className}\n />\n );\n }\n\n return (\n <div\n className={cn('flex flex-col items-center justify-center py-12 px-4 text-center', className)}\n >\n {icon && <div className=\"mb-4 text-text-secondary opacity-50\">{icon}</div>}\n <h3 className=\"text-lg font-semibold tracking-tight text-text-primary\">{title}</h3>\n {description && <p className=\"mt-2 text-sm text-text-secondary max-w-sm\">{description}</p>}\n {action && <div className=\"mt-6\">{action}</div>}\n </div>\n );\n};\n"],"mappings":";;;;AAuBA,IAAa,KAAmC,EAC9C,SACA,iBACA,UACA,gBACA,WACA,mBAEI,IAEA,kBAAC,GAAD;CACgB;CACP;CACM;CACL;CACG;CACX,CAAA,GAKJ,kBAAC,OAAD;CACE,WAAW,EAAG,oEAAoE,EAAU;WAD9F;EAGG,KAAQ,kBAAC,OAAD;GAAK,WAAU;aAAuC;GAAW,CAAA;EAC1E,kBAAC,MAAD;GAAI,WAAU;aAA0D;GAAW,CAAA;EAClF,KAAe,kBAAC,KAAD;GAAG,WAAU;aAA6C;GAAgB,CAAA;EACzF,KAAU,kBAAC,OAAD;GAAK,WAAU;aAAQ;GAAa,CAAA;EAC3C"}
@@ -7,17 +7,17 @@ var s = {
7
7
  low: {
8
8
  label: "Low Risk",
9
9
  icon: r,
10
- color: "text-green-600 dark:text-green-400"
10
+ color: "text-status-success-text"
11
11
  },
12
12
  medium: {
13
13
  label: "Medium Risk",
14
14
  icon: n,
15
- color: "text-yellow-600 dark:text-yellow-400"
15
+ color: "text-status-warning-text"
16
16
  },
17
17
  high: {
18
18
  label: "High Risk",
19
19
  icon: n,
20
- color: "text-red-600 dark:text-red-400"
20
+ color: "text-status-error-text"
21
21
  }
22
22
  }, c = ({ id: n, cartName: r, targetAmount: c, raisedAmount: l, currency: u = "INR", expectedReturns: d, riskLevel: f, status: p, onClick: m, className: h }) => {
23
23
  let g = c > 0 ? Math.min(l / c * 100, 100) : 0, _ = s[f], v = _.icon, y = (e) => new Intl.NumberFormat(void 0, {
@@ -32,7 +32,7 @@ var s = {
32
32
  onKeyDown: (e) => {
33
33
  (e.key === "Enter" || e.key === " ") && (e.preventDefault(), m?.(n));
34
34
  },
35
- className: e("rounded-lg border border-border-subtle bg-bg-surface p-4 shadow-sm transition-colors", "hover:border-accent-foreground/20 hover:shadow-md cursor-pointer", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]", h),
35
+ className: e("rounded-card border border-border-seam bg-bg-surface p-4 shadow-elevation-1", "transition-[box-shadow,border-color] duration-200", "hover:border-border-strong hover:shadow-pop cursor-pointer", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-canvas", h),
36
36
  children: [
37
37
  /* @__PURE__ */ o("div", {
38
38
  className: "flex items-start justify-between",
@@ -50,7 +50,7 @@ var s = {
50
50
  className: "text-text-secondary",
51
51
  children: "Raised"
52
52
  }), /* @__PURE__ */ o("span", {
53
- className: "font-medium text-text-primary",
53
+ className: "font-medium tabular-nums text-text-primary",
54
54
  children: [Math.round(g), "%"]
55
55
  })]
56
56
  }),
@@ -62,7 +62,7 @@ var s = {
62
62
  })
63
63
  }),
64
64
  /* @__PURE__ */ o("div", {
65
- className: "mt-1.5 flex items-center justify-between text-xs text-text-secondary",
65
+ className: "mt-1.5 flex items-center justify-between text-xs tabular-nums text-text-secondary",
66
66
  children: [/* @__PURE__ */ a("span", { children: y(l) }), /* @__PURE__ */ a("span", { children: y(c) })]
67
67
  })
68
68
  ]
@@ -72,7 +72,7 @@ var s = {
72
72
  children: [/* @__PURE__ */ o("div", {
73
73
  className: "flex items-center gap-1.5 text-sm",
74
74
  children: [
75
- /* @__PURE__ */ a(i, { className: "h-3.5 w-3.5 text-green-600 dark:text-green-400" }),
75
+ /* @__PURE__ */ a(i, { className: "h-3.5 w-3.5 text-status-success-text" }),
76
76
  /* @__PURE__ */ a("span", {
77
77
  className: "font-medium text-text-primary",
78
78
  children: d
@@ -1 +1 @@
1
- {"version":3,"file":"InvestmentCard.js","names":[],"sources":["../../../src/atheletebridge/components/InvestmentCard.tsx"],"sourcesContent":["/**\n * Investment Card Component\n * @module atheletebridge/components\n *\n * Displays an investment opportunity with cart name, target/raised amounts,\n * progress bar, expected returns, risk level, and status.\n */\n\nimport type { FC } from 'react';\nimport { TrendingUp, AlertTriangle, Shield } from 'lucide-react';\nimport { cn } from '../utils/cn';\nimport { StatusBadge } from './StatusBadge';\nimport type { InvestmentStatus, RiskLevel } from '../types';\n\ninterface InvestmentCardProps {\n id: string;\n cartName: string;\n targetAmount: number;\n raisedAmount: number;\n currency?: string;\n expectedReturns: string;\n riskLevel: RiskLevel;\n status: InvestmentStatus;\n onClick?: (id: string) => void;\n className?: string;\n}\n\nconst riskConfig: Record<RiskLevel, { label: string; icon: typeof Shield; color: string }> = {\n low: {\n label: 'Low Risk',\n icon: Shield,\n color: 'text-green-600 dark:text-green-400',\n },\n medium: {\n label: 'Medium Risk',\n icon: AlertTriangle,\n color: 'text-yellow-600 dark:text-yellow-400',\n },\n high: {\n label: 'High Risk',\n icon: AlertTriangle,\n color: 'text-red-600 dark:text-red-400',\n },\n};\n\nexport const InvestmentCard: FC<InvestmentCardProps> = ({\n id,\n cartName,\n targetAmount,\n raisedAmount,\n currency = 'INR',\n expectedReturns,\n riskLevel,\n status,\n onClick,\n className,\n}) => {\n const progress = targetAmount > 0 ? Math.min((raisedAmount / targetAmount) * 100, 100) : 0;\n const risk = riskConfig[riskLevel];\n const RiskIcon = risk.icon;\n\n const formatAmount = (amount: number) =>\n new Intl.NumberFormat(undefined, {\n style: 'currency',\n currency,\n maximumFractionDigits: 0,\n }).format(amount);\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => onClick?.(id)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onClick?.(id);\n }\n }}\n className={cn(\n 'rounded-lg border border-border-subtle bg-bg-surface p-4 shadow-sm transition-colors',\n 'hover:border-accent-foreground/20 hover:shadow-md cursor-pointer',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]',\n className\n )}\n >\n {/* Header */}\n <div className=\"flex items-start justify-between\">\n <h3 className=\"text-base font-semibold text-text-primary truncate\">{cartName}</h3>\n <StatusBadge status={status} />\n </div>\n\n {/* Progress Bar */}\n <div className=\"mt-4\">\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-text-secondary\">Raised</span>\n <span className=\"font-medium text-text-primary\">{Math.round(progress)}%</span>\n </div>\n <div className=\"mt-1.5 h-2 w-full rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className=\"h-full rounded-full bg-action-primary-bg transition-all duration-300\"\n style={{ width: `${progress}%` }}\n />\n </div>\n <div className=\"mt-1.5 flex items-center justify-between text-xs text-text-secondary\">\n <span>{formatAmount(raisedAmount)}</span>\n <span>{formatAmount(targetAmount)}</span>\n </div>\n </div>\n\n {/* Details */}\n <div className=\"mt-4 flex items-center justify-between\">\n <div className=\"flex items-center gap-1.5 text-sm\">\n <TrendingUp className=\"h-3.5 w-3.5 text-green-600 dark:text-green-400\" />\n <span className=\"font-medium text-text-primary\">{expectedReturns}</span>\n <span className=\"text-text-secondary\">returns</span>\n </div>\n <div className={cn('flex items-center gap-1 text-xs font-medium', risk.color)}>\n <RiskIcon className=\"h-3.5 w-3.5\" />\n <span>{risk.label}</span>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;AA2BA,IAAM,IAAuF;CAC3F,KAAK;EACH,OAAO;EACP,MAAM;EACN,OAAO;EACR;CACD,QAAQ;EACN,OAAO;EACP,MAAM;EACN,OAAO;EACR;CACD,MAAM;EACJ,OAAO;EACP,MAAM;EACN,OAAO;EACR;CACF,EAEY,KAA2C,EACtD,OACA,aACA,iBACA,iBACA,cAAW,OACX,oBACA,cACA,WACA,YACA,mBACI;CACJ,IAAM,IAAW,IAAe,IAAI,KAAK,IAAK,IAAe,IAAgB,KAAK,IAAI,GAAG,GACnF,IAAO,EAAW,IAClB,IAAW,EAAK,MAEhB,KAAgB,MACpB,IAAI,KAAK,aAAa,KAAA,GAAW;EAC/B,OAAO;EACP;EACA,uBAAuB;EACxB,CAAC,CAAC,OAAO,EAAO;AAEnB,QACE,kBAAC,OAAD;EACE,MAAK;EACL,UAAU;EACV,eAAe,IAAU,EAAG;EAC5B,YAAY,MAAM;AAChB,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,gBAAgB,EAClB,IAAU,EAAG;;EAGjB,WAAW,EACT,wFACA,oEACA,gGACA,EACD;YAfH;GAkBE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAAsD;KAAc,CAAA,EAClF,kBAAC,GAAD,EAAqB,WAAU,CAAA,CAC3B;;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD;OAAM,WAAU;iBAAsB;OAAa,CAAA,EACnD,kBAAC,QAAD;OAAM,WAAU;iBAAhB,CAAiD,KAAK,MAAM,EAAS,EAAC,IAAQ;SAC1E;;KACN,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,OAAD;OACE,WAAU;OACV,OAAO,EAAE,OAAO,GAAG,EAAS,IAAI;OAChC,CAAA;MACE,CAAA;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD,EAAA,UAAO,EAAa,EAAa,EAAQ,CAAA,EACzC,kBAAC,QAAD,EAAA,UAAO,EAAa,EAAa,EAAQ,CAAA,CACrC;;KACF;;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD,EAAY,WAAU,kDAAmD,CAAA;MACzE,kBAAC,QAAD;OAAM,WAAU;iBAAiC;OAAuB,CAAA;MACxE,kBAAC,QAAD;OAAM,WAAU;iBAAsB;OAAc,CAAA;MAChD;QACN,kBAAC,OAAD;KAAK,WAAW,EAAG,+CAA+C,EAAK,MAAM;eAA7E,CACE,kBAAC,GAAD,EAAU,WAAU,eAAgB,CAAA,EACpC,kBAAC,QAAD,EAAA,UAAO,EAAK,OAAa,CAAA,CACrB;OACF;;GACF"}
1
+ {"version":3,"file":"InvestmentCard.js","names":[],"sources":["../../../src/atheletebridge/components/InvestmentCard.tsx"],"sourcesContent":["/**\n * Investment Card Component\n * @module atheletebridge/components\n *\n * Displays an investment opportunity with cart name, target/raised amounts,\n * progress bar, expected returns, risk level, and status.\n */\n\nimport type { FC } from 'react';\nimport { TrendingUp, AlertTriangle, Shield } from 'lucide-react';\nimport { cn } from '../utils/cn';\nimport { StatusBadge } from './StatusBadge';\nimport type { InvestmentStatus, RiskLevel } from '../types';\n\ninterface InvestmentCardProps {\n id: string;\n cartName: string;\n targetAmount: number;\n raisedAmount: number;\n currency?: string;\n expectedReturns: string;\n riskLevel: RiskLevel;\n status: InvestmentStatus;\n onClick?: (id: string) => void;\n className?: string;\n}\n\nconst riskConfig: Record<RiskLevel, { label: string; icon: typeof Shield; color: string }> = {\n low: {\n label: 'Low Risk',\n icon: Shield,\n color: 'text-status-success-text',\n },\n medium: {\n label: 'Medium Risk',\n icon: AlertTriangle,\n color: 'text-status-warning-text',\n },\n high: {\n label: 'High Risk',\n icon: AlertTriangle,\n color: 'text-status-error-text',\n },\n};\n\nexport const InvestmentCard: FC<InvestmentCardProps> = ({\n id,\n cartName,\n targetAmount,\n raisedAmount,\n currency = 'INR',\n expectedReturns,\n riskLevel,\n status,\n onClick,\n className,\n}) => {\n const progress = targetAmount > 0 ? Math.min((raisedAmount / targetAmount) * 100, 100) : 0;\n const risk = riskConfig[riskLevel];\n const RiskIcon = risk.icon;\n\n const formatAmount = (amount: number) =>\n new Intl.NumberFormat(undefined, {\n style: 'currency',\n currency,\n maximumFractionDigits: 0,\n }).format(amount);\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => onClick?.(id)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onClick?.(id);\n }\n }}\n className={cn(\n 'rounded-card border border-border-seam bg-bg-surface p-4 shadow-elevation-1',\n 'transition-[box-shadow,border-color] duration-200',\n 'hover:border-border-strong hover:shadow-pop cursor-pointer',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-canvas',\n className\n )}\n >\n {/* Header */}\n <div className=\"flex items-start justify-between\">\n <h3 className=\"text-base font-semibold text-text-primary truncate\">{cartName}</h3>\n <StatusBadge status={status} />\n </div>\n\n {/* Progress Bar */}\n <div className=\"mt-4\">\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-text-secondary\">Raised</span>\n <span className=\"font-medium tabular-nums text-text-primary\">\n {Math.round(progress)}%\n </span>\n </div>\n <div className=\"mt-1.5 h-2 w-full rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className=\"h-full rounded-full bg-action-primary-bg transition-all duration-300\"\n style={{ width: `${progress}%` }}\n />\n </div>\n <div className=\"mt-1.5 flex items-center justify-between text-xs tabular-nums text-text-secondary\">\n <span>{formatAmount(raisedAmount)}</span>\n <span>{formatAmount(targetAmount)}</span>\n </div>\n </div>\n\n {/* Details */}\n <div className=\"mt-4 flex items-center justify-between\">\n <div className=\"flex items-center gap-1.5 text-sm\">\n <TrendingUp className=\"h-3.5 w-3.5 text-status-success-text\" />\n <span className=\"font-medium text-text-primary\">{expectedReturns}</span>\n <span className=\"text-text-secondary\">returns</span>\n </div>\n <div className={cn('flex items-center gap-1 text-xs font-medium', risk.color)}>\n <RiskIcon className=\"h-3.5 w-3.5\" />\n <span>{risk.label}</span>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;AA2BA,IAAM,IAAuF;CAC3F,KAAK;EACH,OAAO;EACP,MAAM;EACN,OAAO;EACR;CACD,QAAQ;EACN,OAAO;EACP,MAAM;EACN,OAAO;EACR;CACD,MAAM;EACJ,OAAO;EACP,MAAM;EACN,OAAO;EACR;CACF,EAEY,KAA2C,EACtD,OACA,aACA,iBACA,iBACA,cAAW,OACX,oBACA,cACA,WACA,YACA,mBACI;CACJ,IAAM,IAAW,IAAe,IAAI,KAAK,IAAK,IAAe,IAAgB,KAAK,IAAI,GAAG,GACnF,IAAO,EAAW,IAClB,IAAW,EAAK,MAEhB,KAAgB,MACpB,IAAI,KAAK,aAAa,KAAA,GAAW;EAC/B,OAAO;EACP;EACA,uBAAuB;EACxB,CAAC,CAAC,OAAO,EAAO;AAEnB,QACE,kBAAC,OAAD;EACE,MAAK;EACL,UAAU;EACV,eAAe,IAAU,EAAG;EAC5B,YAAY,MAAM;AAChB,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,gBAAgB,EAClB,IAAU,EAAG;;EAGjB,WAAW,EACT,+EACA,qDACA,8DACA,mJACA,EACD;YAhBH;GAmBE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAAsD;KAAc,CAAA,EAClF,kBAAC,GAAD,EAAqB,WAAU,CAAA,CAC3B;;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD;OAAM,WAAU;iBAAsB;OAAa,CAAA,EACnD,kBAAC,QAAD;OAAM,WAAU;iBAAhB,CACG,KAAK,MAAM,EAAS,EAAC,IACjB;SACH;;KACN,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,OAAD;OACE,WAAU;OACV,OAAO,EAAE,OAAO,GAAG,EAAS,IAAI;OAChC,CAAA;MACE,CAAA;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD,EAAA,UAAO,EAAa,EAAa,EAAQ,CAAA,EACzC,kBAAC,QAAD,EAAA,UAAO,EAAa,EAAa,EAAQ,CAAA,CACrC;;KACF;;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD,EAAY,WAAU,wCAAyC,CAAA;MAC/D,kBAAC,QAAD;OAAM,WAAU;iBAAiC;OAAuB,CAAA;MACxE,kBAAC,QAAD;OAAM,WAAU;iBAAsB;OAAc,CAAA;MAChD;QACN,kBAAC,OAAD;KAAK,WAAW,EAAG,+CAA+C,EAAK,MAAM;eAA7E,CACE,kBAAC,GAAD,EAAU,WAAU,eAAgB,CAAA,EACpC,kBAAC,QAAD,EAAA,UAAO,EAAK,OAAa,CAAA,CACrB;OACF;;GACF"}
@@ -1,37 +1,43 @@
1
1
  import { cn as e } from "../utils/cn.js";
2
2
  import { Minus as t, TrendingDown as n, TrendingUp as r } from "lucide-react";
3
3
  import { jsx as i, jsxs as a } from "react/jsx-runtime";
4
+ import { GlassCard as o } from "@burdenoff/fe-libs/ui";
4
5
  //#region src/atheletebridge/components/MetricsCard.tsx
5
- var o = {
6
+ var s = {
6
7
  up: {
7
8
  icon: r,
8
- color: "text-green-600 dark:text-green-400"
9
+ color: "text-status-success-text"
9
10
  },
10
11
  down: {
11
12
  icon: n,
12
- color: "text-red-600 dark:text-red-400"
13
+ color: "text-status-error-text"
13
14
  },
14
15
  neutral: {
15
16
  icon: t,
16
17
  color: "text-text-secondary"
17
18
  }
18
- }, s = ({ icon: t, value: n, label: r, trend: s, trendValue: c, className: l }) => {
19
- let u = s ? o[s] : null, d = u?.icon;
20
- return /* @__PURE__ */ a("div", {
21
- className: e("rounded-lg border border-border-subtle bg-bg-surface p-6 shadow-sm", l),
19
+ }, c = ({ icon: t, value: n, label: r, trend: c, trendValue: l, featured: u = !1, className: d }) => {
20
+ let f = c ? s[c] : null, p = f?.icon;
21
+ return /* @__PURE__ */ a(o, {
22
+ treatment: u ? "glass" : "metric",
23
+ glow: u,
24
+ className: e("p-6", d),
22
25
  children: [/* @__PURE__ */ a("div", {
23
- className: "flex items-center justify-between",
26
+ className: "relative flex items-center justify-between",
24
27
  children: [/* @__PURE__ */ i("div", {
25
28
  className: "text-text-secondary",
26
29
  children: t
27
- }), s && u && d && /* @__PURE__ */ a("div", {
28
- className: e("flex items-center gap-1 text-xs font-medium", u.color),
29
- children: [/* @__PURE__ */ i(d, { className: "h-3.5 w-3.5" }), c && /* @__PURE__ */ i("span", { children: c })]
30
+ }), c && f && p && /* @__PURE__ */ a("div", {
31
+ className: e("flex items-center gap-1 text-xs font-medium", f.color),
32
+ children: [/* @__PURE__ */ i(p, { className: "h-3.5 w-3.5" }), l && /* @__PURE__ */ i("span", {
33
+ className: "tabular-nums",
34
+ children: l
35
+ })]
30
36
  })]
31
37
  }), /* @__PURE__ */ a("div", {
32
- className: "mt-3",
38
+ className: "relative mt-3",
33
39
  children: [/* @__PURE__ */ i("p", {
34
- className: "text-2xl font-bold text-text-primary",
40
+ className: "text-2xl font-bold tabular-nums text-text-primary",
35
41
  children: n
36
42
  }), /* @__PURE__ */ i("p", {
37
43
  className: "mt-1 text-sm text-text-secondary",
@@ -41,6 +47,6 @@ var o = {
41
47
  });
42
48
  };
43
49
  //#endregion
44
- export { s as MetricsCard };
50
+ export { c as MetricsCard };
45
51
 
46
52
  //# sourceMappingURL=MetricsCard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MetricsCard.js","names":[],"sources":["../../../src/atheletebridge/components/MetricsCard.tsx"],"sourcesContent":["/**\n * Metrics Card Component\n * @module atheletebridge/components\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { TrendingUp, TrendingDown, Minus } from 'lucide-react';\nimport { cn } from '../utils/cn';\nimport type { TrendDirection } from '../types';\n\ninterface MetricsCardProps {\n icon: ReactNode;\n value: string | number;\n label: string;\n trend?: TrendDirection;\n trendValue?: string;\n className?: string;\n}\n\nconst trendConfig: Record<TrendDirection, { icon: typeof TrendingUp; color: string }> = {\n up: { icon: TrendingUp, color: 'text-green-600 dark:text-green-400' },\n down: { icon: TrendingDown, color: 'text-red-600 dark:text-red-400' },\n neutral: { icon: Minus, color: 'text-text-secondary' },\n};\n\nexport const MetricsCard: FC<MetricsCardProps> = ({\n icon,\n value,\n label,\n trend,\n trendValue,\n className,\n}) => {\n const trendInfo = trend ? trendConfig[trend] : null;\n const TrendIcon = trendInfo?.icon;\n\n return (\n <div className={cn('rounded-lg border border-border-subtle bg-bg-surface p-6 shadow-sm', className)}>\n <div className=\"flex items-center justify-between\">\n <div className=\"text-text-secondary\">{icon}</div>\n {trend && trendInfo && TrendIcon && (\n <div className={cn('flex items-center gap-1 text-xs font-medium', trendInfo.color)}>\n <TrendIcon className=\"h-3.5 w-3.5\" />\n {trendValue && <span>{trendValue}</span>}\n </div>\n )}\n </div>\n <div className=\"mt-3\">\n <p className=\"text-2xl font-bold text-text-primary\">{value}</p>\n <p className=\"mt-1 text-sm text-text-secondary\">{label}</p>\n </div>\n </div>\n );\n};\n"],"mappings":";;;;AAmBA,IAAM,IAAkF;CACtF,IAAI;EAAE,MAAM;EAAY,OAAO;EAAsC;CACrE,MAAM;EAAE,MAAM;EAAc,OAAO;EAAkC;CACrE,SAAS;EAAE,MAAM;EAAO,OAAO;EAAuB;CACvD,EAEY,KAAqC,EAChD,SACA,UACA,UACA,UACA,eACA,mBACI;CACJ,IAAM,IAAY,IAAQ,EAAY,KAAS,MACzC,IAAY,GAAW;AAE7B,QACE,kBAAC,OAAD;EAAK,WAAW,EAAG,sEAAsE,EAAU;YAAnG,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAuB;IAAW,CAAA,EAChD,KAAS,KAAa,KACrB,kBAAC,OAAD;IAAK,WAAW,EAAG,+CAA+C,EAAU,MAAM;cAAlF,CACE,kBAAC,GAAD,EAAW,WAAU,eAAgB,CAAA,EACpC,KAAc,kBAAC,QAAD,EAAA,UAAO,GAAkB,CAAA,CACpC;MAEJ;MACN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD;IAAG,WAAU;cAAwC;IAAU,CAAA,EAC/D,kBAAC,KAAD;IAAG,WAAU;cAAoC;IAAU,CAAA,CACvD;KACF"}
1
+ {"version":3,"file":"MetricsCard.js","names":[],"sources":["../../../src/atheletebridge/components/MetricsCard.tsx"],"sourcesContent":["/**\n * Metrics Card Component\n * @module atheletebridge/components\n *\n * Boff UI 2.0: KPI tiles use the glassmorphic `GlassCard` \"metric\" treatment\n * (accent wash + seam border + soft pop-lift). The hero metric per page can\n * opt into the brighter `glass` treatment with an accent glow via `featured`.\n * Numerals are tabular for clean alignment. No hover movement.\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { TrendingUp, TrendingDown, Minus } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\nimport type { TrendDirection } from '../types';\n\ninterface MetricsCardProps {\n icon: ReactNode;\n value: string | number;\n label: string;\n trend?: TrendDirection;\n trendValue?: string;\n /** Render as the single featured hero metric (glass treatment + glow). */\n featured?: boolean;\n className?: string;\n}\n\nconst trendConfig: Record<TrendDirection, { icon: typeof TrendingUp; color: string }> = {\n up: { icon: TrendingUp, color: 'text-status-success-text' },\n down: { icon: TrendingDown, color: 'text-status-error-text' },\n neutral: { icon: Minus, color: 'text-text-secondary' },\n};\n\nexport const MetricsCard: FC<MetricsCardProps> = ({\n icon,\n value,\n label,\n trend,\n trendValue,\n featured = false,\n className,\n}) => {\n const trendInfo = trend ? trendConfig[trend] : null;\n const TrendIcon = trendInfo?.icon;\n\n return (\n <GlassCard\n treatment={featured ? 'glass' : 'metric'}\n glow={featured}\n className={cn('p-6', className)}\n >\n <div className=\"relative flex items-center justify-between\">\n <div className=\"text-text-secondary\">{icon}</div>\n {trend && trendInfo && TrendIcon && (\n <div className={cn('flex items-center gap-1 text-xs font-medium', trendInfo.color)}>\n <TrendIcon className=\"h-3.5 w-3.5\" />\n {trendValue && <span className=\"tabular-nums\">{trendValue}</span>}\n </div>\n )}\n </div>\n <div className=\"relative mt-3\">\n <p className=\"text-2xl font-bold tabular-nums text-text-primary\">{value}</p>\n <p className=\"mt-1 text-sm text-text-secondary\">{label}</p>\n </div>\n </GlassCard>\n );\n};\n"],"mappings":";;;;;AA2BA,IAAM,IAAkF;CACtF,IAAI;EAAE,MAAM;EAAY,OAAO;EAA4B;CAC3D,MAAM;EAAE,MAAM;EAAc,OAAO;EAA0B;CAC7D,SAAS;EAAE,MAAM;EAAO,OAAO;EAAuB;CACvD,EAEY,KAAqC,EAChD,SACA,UACA,UACA,UACA,eACA,cAAW,IACX,mBACI;CACJ,IAAM,IAAY,IAAQ,EAAY,KAAS,MACzC,IAAY,GAAW;AAE7B,QACE,kBAAC,GAAD;EACE,WAAW,IAAW,UAAU;EAChC,MAAM;EACN,WAAW,EAAG,OAAO,EAAU;YAHjC,CAKE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAuB;IAAW,CAAA,EAChD,KAAS,KAAa,KACrB,kBAAC,OAAD;IAAK,WAAW,EAAG,+CAA+C,EAAU,MAAM;cAAlF,CACE,kBAAC,GAAD,EAAW,WAAU,eAAgB,CAAA,EACpC,KAAc,kBAAC,QAAD;KAAM,WAAU;eAAgB;KAAkB,CAAA,CAC7D;MAEJ;MACN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD;IAAG,WAAU;cAAqD;IAAU,CAAA,EAC5E,kBAAC,KAAD;IAAG,WAAU;cAAoC;IAAU,CAAA,CACvD;KACI"}
@@ -1,26 +1,37 @@
1
1
  import { cn as e } from "../utils/cn.js";
2
2
  import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
+ import { AuroraBackground as r, GradientText as i } from "@burdenoff/fe-libs/ui";
3
4
  //#region src/atheletebridge/components/PageLayout.tsx
4
- var r = ({ title: r, description: i, actions: a, children: o, className: s }) => /* @__PURE__ */ n("div", {
5
- className: e("flex flex-col h-full", s),
6
- children: [/* @__PURE__ */ n("div", {
7
- className: "flex items-center justify-between px-6 py-4 border-b border-border-subtle bg-bg-surface",
8
- children: [/* @__PURE__ */ n("div", { children: [/* @__PURE__ */ t("h1", {
9
- className: "text-2xl font-semibold text-text-primary",
10
- children: r
11
- }), i && /* @__PURE__ */ t("p", {
12
- className: "mt-1 text-sm text-text-secondary",
13
- children: i
14
- })] }), a && /* @__PURE__ */ t("div", {
15
- className: "flex items-center gap-3",
16
- children: a
5
+ var a = ({ title: a, description: o, actions: s, children: c, className: l, hero: u = !1, gradientTitle: d = !1 }) => {
6
+ let f = d && typeof a == "string" ? /* @__PURE__ */ t(i, { children: a }) : a;
7
+ return /* @__PURE__ */ n("div", {
8
+ className: e("flex flex-col h-full", l),
9
+ children: [/* @__PURE__ */ n("div", {
10
+ className: e("relative overflow-hidden flex items-center justify-between gap-4 px-6 py-4", "border-b border-border-seam bg-bg-surface"),
11
+ children: [
12
+ u && /* @__PURE__ */ t(r, { intensity: "subtle" }),
13
+ /* @__PURE__ */ n("div", {
14
+ className: "min-w-0",
15
+ children: [/* @__PURE__ */ t("h1", {
16
+ className: "text-2xl font-semibold tracking-tight text-text-primary truncate",
17
+ children: f
18
+ }), o && /* @__PURE__ */ t("p", {
19
+ className: "mt-1 text-sm text-text-secondary",
20
+ children: o
21
+ })]
22
+ }),
23
+ s && /* @__PURE__ */ t("div", {
24
+ className: "flex items-center gap-2 shrink-0",
25
+ children: s
26
+ })
27
+ ]
28
+ }), /* @__PURE__ */ t("div", {
29
+ className: "flex-1 overflow-auto p-6",
30
+ children: c
17
31
  })]
18
- }), /* @__PURE__ */ t("div", {
19
- className: "flex-1 overflow-auto p-6",
20
- children: o
21
- })]
22
- });
32
+ });
33
+ };
23
34
  //#endregion
24
- export { r as PageLayout };
35
+ export { a as PageLayout };
25
36
 
26
37
  //# sourceMappingURL=PageLayout.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PageLayout.js","names":[],"sources":["../../../src/atheletebridge/components/PageLayout.tsx"],"sourcesContent":["/**\n * Page Layout Component\n * @module atheletebridge/components\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { cn } from '../utils/cn';\n\ninterface PageLayoutProps {\n title: ReactNode;\n description?: string;\n actions?: ReactNode;\n children: ReactNode;\n className?: string;\n}\n\nexport const PageLayout: FC<PageLayoutProps> = ({\n title,\n description,\n actions,\n children,\n className,\n}) => {\n return (\n <div className={cn('flex flex-col h-full', className)}>\n {/* Page Header */}\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-border-subtle bg-bg-surface\">\n <div>\n <h1 className=\"text-2xl font-semibold text-text-primary\">{title}</h1>\n {description && <p className=\"mt-1 text-sm text-text-secondary\">{description}</p>}\n </div>\n {actions && <div className=\"flex items-center gap-3\">{actions}</div>}\n </div>\n\n {/* Page Content */}\n <div className=\"flex-1 overflow-auto p-6\">{children}</div>\n </div>\n );\n};\n"],"mappings":";;;AAgBA,IAAa,KAAmC,EAC9C,UACA,gBACA,YACA,aACA,mBAGE,kBAAC,OAAD;CAAK,WAAW,EAAG,wBAAwB,EAAU;WAArD,CAEE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;GAAI,WAAU;aAA4C;GAAW,CAAA,EACpE,KAAe,kBAAC,KAAD;GAAG,WAAU;aAAoC;GAAgB,CAAA,CAC7E,EAAA,CAAA,EACL,KAAW,kBAAC,OAAD;GAAK,WAAU;aAA2B;GAAc,CAAA,CAChE;KAGN,kBAAC,OAAD;EAAK,WAAU;EAA4B;EAAe,CAAA,CACtD"}
1
+ {"version":3,"file":"PageLayout.js","names":[],"sources":["../../../src/atheletebridge/components/PageLayout.tsx"],"sourcesContent":["/**\n * Page Layout Component\n * @module atheletebridge/components\n *\n * Boff UI 2.0: glassmorphic seam-bordered page header with an optional\n * living aurora backdrop (one per MFE — opt in via `hero`) and a gradient\n * hero title (`gradientTitle`). The backdrop is decorative, sits behind\n * content (-z-10) and never moves layout. Reduced-motion safe.\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { AuroraBackground, GradientText } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\n\ninterface PageLayoutProps {\n title: ReactNode;\n description?: string;\n actions?: ReactNode;\n children: ReactNode;\n className?: string;\n /**\n * Render the living aurora backdrop behind the header. Use on exactly ONE\n * primary page per MFE (the root dashboard).\n */\n hero?: boolean;\n /**\n * When `title` is a string, wrap it in a subtle brand gradient (the ONE\n * hero heading per page). Ignored when `title` is a node.\n */\n gradientTitle?: boolean;\n}\n\nexport const PageLayout: FC<PageLayoutProps> = ({\n title,\n description,\n actions,\n children,\n className,\n hero = false,\n gradientTitle = false,\n}) => {\n const renderedTitle =\n gradientTitle && typeof title === 'string' ? <GradientText>{title}</GradientText> : title;\n\n return (\n <div className={cn('flex flex-col h-full', className)}>\n {/* Page Header */}\n <div\n className={cn(\n 'relative overflow-hidden flex items-center justify-between gap-4 px-6 py-4',\n 'border-b border-border-seam bg-bg-surface'\n )}\n >\n {hero && <AuroraBackground intensity=\"subtle\" />}\n <div className=\"min-w-0\">\n <h1 className=\"text-2xl font-semibold tracking-tight text-text-primary truncate\">\n {renderedTitle}\n </h1>\n {description && <p className=\"mt-1 text-sm text-text-secondary\">{description}</p>}\n </div>\n {actions && <div className=\"flex items-center gap-2 shrink-0\">{actions}</div>}\n </div>\n\n {/* Page Content */}\n <div className=\"flex-1 overflow-auto p-6\">{children}</div>\n </div>\n );\n};\n"],"mappings":";;;;AAgCA,IAAa,KAAmC,EAC9C,UACA,gBACA,YACA,aACA,cACA,UAAO,IACP,mBAAgB,SACZ;CACJ,IAAM,IACJ,KAAiB,OAAO,KAAU,WAAW,kBAAC,GAAD,EAAA,UAAe,GAAqB,CAAA,GAAG;AAEtF,QACE,kBAAC,OAAD;EAAK,WAAW,EAAG,wBAAwB,EAAU;YAArD,CAEE,kBAAC,OAAD;GACE,WAAW,EACT,8EACA,4CACD;aAJH;IAMG,KAAQ,kBAAC,GAAD,EAAkB,WAAU,UAAW,CAAA;IAChD,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBACX;MACE,CAAA,EACJ,KAAe,kBAAC,KAAD;MAAG,WAAU;gBAAoC;MAAgB,CAAA,CAC7E;;IACL,KAAW,kBAAC,OAAD;KAAK,WAAU;eAAoC;KAAc,CAAA;IACzE;MAGN,kBAAC,OAAD;GAAK,WAAU;GAA4B;GAAe,CAAA,CACtD"}