@burdenoff/microfe-export 2026.624.1 → 2026.625.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ import { useI18n as a } from "@burdenoff/fe-libs/shared/providers/shell/I18nProv
7
7
  var o = {
8
8
  CREATED: "bg-status-info-bg-subtle text-status-info-text",
9
9
  QUEUED: "bg-status-warning-bg-subtle text-status-warning-text",
10
- RUNNING: "bg-status-info-bg-subtle text-status-info-text animate-pulse",
10
+ RUNNING: "bg-status-info-bg-subtle text-status-info-text motion-safe:animate-vc-glow-pulse",
11
11
  COMPLETED: "bg-status-success-bg-subtle text-status-success-text",
12
12
  FAILED: "bg-status-error-bg-subtle text-status-error-text",
13
13
  CANCELLED: "bg-bg-sunken text-text-secondary",
@@ -1 +1 @@
1
- {"version":3,"file":"ExportStatusBadge.js","names":[],"sources":["../../../src/export/components/ExportStatusBadge.tsx"],"sourcesContent":["import { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { cn } from \"../utils/cn\";\nimport { getStatusDisplayName } from \"../constants/enums\";\nimport type { ExportJobStatus } from \"../types\";\nimport { tWithFallback } from \"../utils/i18n\";\n\ninterface ExportStatusBadgeProps {\n status: ExportJobStatus;\n className?: string;\n}\n\nconst statusStyles: Record<ExportJobStatus, string> = {\n CREATED: \"bg-status-info-bg-subtle text-status-info-text\",\n QUEUED: \"bg-status-warning-bg-subtle text-status-warning-text\",\n RUNNING: \"bg-status-info-bg-subtle text-status-info-text animate-pulse\",\n COMPLETED: \"bg-status-success-bg-subtle text-status-success-text\",\n FAILED: \"bg-status-error-bg-subtle text-status-error-text\",\n CANCELLED: \"bg-bg-sunken text-text-secondary\",\n EXPIRED: \"bg-accent-orange-subtle text-accent-orange\",\n DELETED: \"bg-bg-sunken text-text-tertiary\",\n};\n\n/**\n * ExportStatusBadge - Renders a colored badge for export job status\n */\nexport function ExportStatusBadge({\n status,\n className,\n}: ExportStatusBadgeProps) {\n const { t } = useI18n();\n const tr = (key: string, fallback: string) => tWithFallback(t, key, fallback);\n\n const statusLabel =\n {\n CREATED: tr(\"export.shared.status.created\", \"Created\"),\n QUEUED: tr(\"export.shared.status.queued\", \"Queued\"),\n RUNNING: tr(\"export.shared.status.running\", \"Running\"),\n COMPLETED: tr(\"export.shared.status.completed\", \"Completed\"),\n FAILED: tr(\"export.shared.status.failed\", \"Failed\"),\n CANCELLED: tr(\"export.shared.status.cancelled\", \"Cancelled\"),\n EXPIRED: tr(\"export.shared.status.expired\", \"Expired\"),\n DELETED: tr(\"export.shared.status.deleted\", \"Deleted\"),\n }[status] ?? getStatusDisplayName(status);\n\n return (\n <span\n className={cn(\n \"inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium\",\n statusStyles[status],\n className,\n )}\n >\n {status === \"RUNNING\" && (\n <span className=\"relative flex size-2\">\n <span className=\"animate-ping absolute inline-flex h-full w-full rounded-full bg-accent-blue opacity-75\" />\n <span className=\"relative inline-flex rounded-full size-2 bg-accent-blue\" />\n </span>\n )}\n {statusLabel}\n </span>\n );\n}\n"],"mappings":";;;;;;AAWA,IAAM,IAAgD;CACpD,SAAS;CACT,QAAQ;CACR,SAAS;CACT,WAAW;CACX,QAAQ;CACR,WAAW;CACX,SAAS;CACT,SAAS;CACV;AAKD,SAAgB,EAAkB,EAChC,WACA,gBACyB;CACzB,IAAM,EAAE,SAAM,GAAS,EACjB,KAAM,GAAa,MAAqB,EAAc,GAAG,GAAK,EAAS,EAEvE,IACJ;EACE,SAAS,EAAG,gCAAgC,UAAU;EACtD,QAAQ,EAAG,+BAA+B,SAAS;EACnD,SAAS,EAAG,gCAAgC,UAAU;EACtD,WAAW,EAAG,kCAAkC,YAAY;EAC5D,QAAQ,EAAG,+BAA+B,SAAS;EACnD,WAAW,EAAG,kCAAkC,YAAY;EAC5D,SAAS,EAAG,gCAAgC,UAAU;EACtD,SAAS,EAAG,gCAAgC,UAAU;EACvD,CAAC,MAAW,EAAqB,EAAO;AAE3C,QACE,kBAAC,QAAD;EACE,WAAW,EACT,mFACA,EAAa,IACb,EACD;YALH,CAOG,MAAW,aACV,kBAAC,QAAD;GAAM,WAAU;aAAhB,CACE,kBAAC,QAAD,EAAM,WAAU,0FAA2F,CAAA,EAC3G,kBAAC,QAAD,EAAM,WAAU,2DAA4D,CAAA,CACvE;MAER,EACI"}
1
+ {"version":3,"file":"ExportStatusBadge.js","names":[],"sources":["../../../src/export/components/ExportStatusBadge.tsx"],"sourcesContent":["import { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { cn } from \"../utils/cn\";\nimport { getStatusDisplayName } from \"../constants/enums\";\nimport type { ExportJobStatus } from \"../types\";\nimport { tWithFallback } from \"../utils/i18n\";\n\ninterface ExportStatusBadgeProps {\n status: ExportJobStatus;\n className?: string;\n}\n\nconst statusStyles: Record<ExportJobStatus, string> = {\n CREATED: \"bg-status-info-bg-subtle text-status-info-text\",\n QUEUED: \"bg-status-warning-bg-subtle text-status-warning-text\",\n RUNNING:\n \"bg-status-info-bg-subtle text-status-info-text motion-safe:animate-vc-glow-pulse\",\n COMPLETED: \"bg-status-success-bg-subtle text-status-success-text\",\n FAILED: \"bg-status-error-bg-subtle text-status-error-text\",\n CANCELLED: \"bg-bg-sunken text-text-secondary\",\n EXPIRED: \"bg-accent-orange-subtle text-accent-orange\",\n DELETED: \"bg-bg-sunken text-text-tertiary\",\n};\n\n/**\n * ExportStatusBadge - Renders a colored badge for export job status\n */\nexport function ExportStatusBadge({\n status,\n className,\n}: ExportStatusBadgeProps) {\n const { t } = useI18n();\n const tr = (key: string, fallback: string) => tWithFallback(t, key, fallback);\n\n const statusLabel =\n {\n CREATED: tr(\"export.shared.status.created\", \"Created\"),\n QUEUED: tr(\"export.shared.status.queued\", \"Queued\"),\n RUNNING: tr(\"export.shared.status.running\", \"Running\"),\n COMPLETED: tr(\"export.shared.status.completed\", \"Completed\"),\n FAILED: tr(\"export.shared.status.failed\", \"Failed\"),\n CANCELLED: tr(\"export.shared.status.cancelled\", \"Cancelled\"),\n EXPIRED: tr(\"export.shared.status.expired\", \"Expired\"),\n DELETED: tr(\"export.shared.status.deleted\", \"Deleted\"),\n }[status] ?? getStatusDisplayName(status);\n\n return (\n <span\n className={cn(\n \"inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium\",\n statusStyles[status],\n className,\n )}\n >\n {status === \"RUNNING\" && (\n <span className=\"relative flex size-2\">\n <span className=\"animate-ping absolute inline-flex h-full w-full rounded-full bg-accent-blue opacity-75\" />\n <span className=\"relative inline-flex rounded-full size-2 bg-accent-blue\" />\n </span>\n )}\n {statusLabel}\n </span>\n );\n}\n"],"mappings":";;;;;;AAWA,IAAM,IAAgD;CACpD,SAAS;CACT,QAAQ;CACR,SACE;CACF,WAAW;CACX,QAAQ;CACR,WAAW;CACX,SAAS;CACT,SAAS;CACV;AAKD,SAAgB,EAAkB,EAChC,WACA,gBACyB;CACzB,IAAM,EAAE,SAAM,GAAS,EACjB,KAAM,GAAa,MAAqB,EAAc,GAAG,GAAK,EAAS,EAEvE,IACJ;EACE,SAAS,EAAG,gCAAgC,UAAU;EACtD,QAAQ,EAAG,+BAA+B,SAAS;EACnD,SAAS,EAAG,gCAAgC,UAAU;EACtD,WAAW,EAAG,kCAAkC,YAAY;EAC5D,QAAQ,EAAG,+BAA+B,SAAS;EACnD,WAAW,EAAG,kCAAkC,YAAY;EAC5D,SAAS,EAAG,gCAAgC,UAAU;EACtD,SAAS,EAAG,gCAAgC,UAAU;EACvD,CAAC,MAAW,EAAqB,EAAO;AAE3C,QACE,kBAAC,QAAD;EACE,WAAW,EACT,mFACA,EAAa,IACb,EACD;YALH,CAOG,MAAW,aACV,kBAAC,QAAD;GAAM,WAAU;aAAhB,CACE,kBAAC,QAAD,EAAM,WAAU,0FAA2F,CAAA,EAC3G,kBAAC,QAAD,EAAM,WAAU,2DAA4D,CAAA,CACvE;MAER,EACI"}
@@ -1,8 +1,8 @@
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 { EmptyState as r } from "@burdenoff/fe-libs/ui";
3
+ import "@burdenoff/fe-libs/ui";
4
4
  //#region src/export/components/PageLayout.tsx
5
- var i = {
5
+ var r = {
6
6
  sm: "max-w-screen-sm",
7
7
  md: "max-w-screen-md",
8
8
  lg: "max-w-screen-lg",
@@ -11,11 +11,11 @@ var i = {
11
11
  "3xl": "max-w-[1600px]",
12
12
  full: "max-w-full"
13
13
  };
14
- function a({ children: r, title: a, subtitle: o, icon: s, headerActions: c, headerContent: l, maxWidth: u = "xl", showHeader: d = !0, className: f, contentClassName: p }) {
14
+ function i({ children: i, title: a, subtitle: o, icon: s, headerActions: c, headerContent: l, maxWidth: u = "xl", showHeader: d = !0, className: f, contentClassName: p }) {
15
15
  return /* @__PURE__ */ t("div", {
16
16
  className: e("min-h-full w-full", "px-4 sm:px-6 lg:px-8 xl:px-12", "py-6 sm:py-8 lg:py-10", "animate-in fade-in-0 slide-in-from-bottom-4 duration-500", f),
17
17
  children: /* @__PURE__ */ n("div", {
18
- className: e("mx-auto w-full", i[u], p),
18
+ className: e("mx-auto w-full", r[u], p),
19
19
  children: [d && (a || c) && /* @__PURE__ */ n("header", {
20
20
  className: "mb-6 sm:mb-8",
21
21
  children: [/* @__PURE__ */ n("div", {
@@ -45,12 +45,12 @@ function a({ children: r, title: a, subtitle: o, icon: s, headerActions: c, head
45
45
  })]
46
46
  }), /* @__PURE__ */ t("div", {
47
47
  className: "space-y-6",
48
- children: r
48
+ children: i
49
49
  })]
50
50
  })
51
51
  });
52
52
  }
53
- function o({ children: r, title: i, description: a, actions: o, className: s, ...c }) {
53
+ function a({ children: r, title: i, description: a, actions: o, className: s, ...c }) {
54
54
  return /* @__PURE__ */ n("section", {
55
55
  className: e("space-y-4", s),
56
56
  ...c,
@@ -69,18 +69,7 @@ function o({ children: r, title: i, description: a, actions: o, className: s, ..
69
69
  }), r]
70
70
  });
71
71
  }
72
- function s({ icon: e, title: n, description: i, action: a, className: o }) {
73
- return /* @__PURE__ */ t("div", {
74
- className: o,
75
- children: /* @__PURE__ */ t(r, {
76
- icon: e,
77
- title: n,
78
- description: i,
79
- action: a
80
- })
81
- });
82
- }
83
72
  //#endregion
84
- export { s as EmptyState, a as PageLayout, o as PageSection };
73
+ export { i as PageLayout, a as PageSection };
85
74
 
86
75
  //# sourceMappingURL=PageLayout.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PageLayout.js","names":[],"sources":["../../../src/export/components/PageLayout.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { EmptyState as CanonicalEmptyState } from \"@burdenoff/fe-libs/ui\";\nimport { cn } from \"../utils/cn\";\n\ninterface PageLayoutProps {\n children: ReactNode;\n /** Page title */\n title?: string;\n /** Page subtitle/description */\n subtitle?: string;\n /** Icon component to display next to title */\n icon?: ReactNode;\n /** Actions to display in header (buttons, etc.) */\n headerActions?: ReactNode;\n /** Additional header content below title */\n headerContent?: ReactNode;\n /** Maximum width of content: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full' */\n maxWidth?: \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\" | \"full\";\n /** Whether to show the header section */\n showHeader?: boolean;\n /** Additional CSS classes for the container */\n className?: string;\n /** Additional CSS classes for the content area */\n contentClassName?: string;\n}\n\nconst maxWidthClasses = {\n sm: \"max-w-screen-sm\", // 640px\n md: \"max-w-screen-md\", // 768px\n lg: \"max-w-screen-lg\", // 1024px\n xl: \"max-w-screen-xl\", // 1280px\n \"2xl\": \"max-w-screen-2xl\", // 1536px\n \"3xl\": \"max-w-[1600px]\",\n full: \"max-w-full\",\n};\n\n/**\n * PageLayout - A consistent page wrapper with responsive design\n *\n * Features:\n * - Proper max-width constraints\n * - Responsive padding\n * - Animated entrance\n * - Consistent header styling\n */\nexport function PageLayout({\n children,\n title,\n subtitle,\n icon,\n headerActions,\n headerContent,\n maxWidth = \"xl\",\n showHeader = true,\n className,\n contentClassName,\n}: PageLayoutProps) {\n return (\n <div\n className={cn(\n // Base styles - full width container with padding\n \"min-h-full w-full\",\n // Responsive horizontal padding\n \"px-4 sm:px-6 lg:px-8 xl:px-12\",\n // Responsive vertical padding\n \"py-6 sm:py-8 lg:py-10\",\n // Entrance animation\n \"animate-in fade-in-0 slide-in-from-bottom-4 duration-500\",\n className,\n )}\n >\n {/* Max-width constrained content container */}\n <div\n className={cn(\n \"mx-auto w-full\",\n maxWidthClasses[maxWidth],\n contentClassName,\n )}\n >\n {/* Page Header */}\n {showHeader && (title || headerActions) && (\n <header className=\"mb-6 sm:mb-8\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n {/* Title Section */}\n <div className=\"space-y-1\">\n {(title || icon) && (\n <div className=\"flex items-center gap-3\">\n {icon && (\n <div className=\"flex-shrink-0 p-2.5 rounded-xl bg-action-primary-bg/10 text-primary\">\n {icon}\n </div>\n )}\n {title && (\n <h1 className=\"text-2xl sm:text-3xl font-bold tracking-tight text-text-primary\">\n {title}\n </h1>\n )}\n </div>\n )}\n {subtitle && (\n <p className=\"text-sm sm:text-base text-text-secondary max-w-2xl\">\n {subtitle}\n </p>\n )}\n </div>\n\n {/* Header Actions */}\n {headerActions && (\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n {headerActions}\n </div>\n )}\n </div>\n\n {/* Additional Header Content */}\n {headerContent && <div className=\"mt-4\">{headerContent}</div>}\n </header>\n )}\n\n {/* Page content — must not use a <main> landmark here because the\n host shell (AppShellLayout) already renders one; nesting <main>\n elements is invalid HTML and an a11y violation. */}\n <div className=\"space-y-6\">{children}</div>\n </div>\n </div>\n );\n}\n\n/**\n * PageSection - A section within a page with consistent spacing\n */\nexport function PageSection({\n children,\n title,\n description,\n actions,\n className,\n ...rest\n}: {\n children: ReactNode;\n title?: string;\n description?: string;\n actions?: ReactNode;\n className?: string;\n} & React.HTMLAttributes<HTMLElement>) {\n return (\n <section className={cn(\"space-y-4\", className)} {...rest}>\n {(title || actions) && (\n <div className=\"flex items-center justify-between\">\n <div>\n {title && (\n <h2 className=\"text-lg font-semibold text-text-primary\">{title}</h2>\n )}\n {description && (\n <p className=\"text-sm text-text-secondary\">{description}</p>\n )}\n </div>\n {actions && <div className=\"flex items-center gap-2\">{actions}</div>}\n </div>\n )}\n {children}\n </section>\n );\n}\n\n/**\n * Local wrapper around the canonical `EmptyState` from `@burdenoff/fe-libs/ui`.\n * Keeps the existing microfe-export call sites stable while routing all\n * empty-state rendering through the shared primitive.\n */\nexport function EmptyState({\n icon,\n title,\n description,\n action,\n className,\n}: {\n icon?: ReactNode;\n title: string;\n description?: string;\n action?: ReactNode;\n className?: string;\n}) {\n return (\n <div className={className}>\n <CanonicalEmptyState\n icon={icon}\n title={title}\n description={description}\n action={action}\n />\n </div>\n );\n}\n"],"mappings":";;;;AA0BA,IAAM,IAAkB;CACtB,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,OAAO;CACP,OAAO;CACP,MAAM;CACP;AAWD,SAAgB,EAAW,EACzB,aACA,UACA,aACA,SACA,kBACA,kBACA,cAAW,MACX,gBAAa,IACb,cACA,uBACkB;AAClB,QACE,kBAAC,OAAD;EACE,WAAW,EAET,qBAEA,iCAEA,yBAEA,4DACA,EACD;YAGD,kBAAC,OAAD;GACE,WAAW,EACT,kBACA,EAAgB,IAChB,EACD;aALH,CAQG,MAAe,KAAS,MACvB,kBAAC,UAAD;IAAQ,WAAU;cAAlB,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CAEE,kBAAC,OAAD;MAAK,WAAU;gBAAf,EACI,KAAS,MACT,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACG,KACC,kBAAC,OAAD;QAAK,WAAU;kBACZ;QACG,CAAA,EAEP,KACC,kBAAC,MAAD;QAAI,WAAU;kBACX;QACE,CAAA,CAEH;UAEP,KACC,kBAAC,KAAD;OAAG,WAAU;iBACV;OACC,CAAA,CAEF;SAGL,KACC,kBAAC,OAAD;MAAK,WAAU;gBACZ;MACG,CAAA,CAEJ;QAGL,KAAiB,kBAAC,OAAD;KAAK,WAAU;eAAQ;KAAoB,CAAA,CACtD;OAMX,kBAAC,OAAD;IAAK,WAAU;IAAa;IAAe,CAAA,CACvC;;EACF,CAAA;;AAOV,SAAgB,EAAY,EAC1B,aACA,UACA,gBACA,YACA,cACA,GAAG,KAOkC;AACrC,QACE,kBAAC,WAAD;EAAS,WAAW,EAAG,aAAa,EAAU;EAAE,GAAI;YAApD,EACI,KAAS,MACT,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACG,KACC,kBAAC,MAAD;IAAI,WAAU;cAA2C;IAAW,CAAA,EAErE,KACC,kBAAC,KAAD;IAAG,WAAU;cAA+B;IAAgB,CAAA,CAE1D,EAAA,CAAA,EACL,KAAW,kBAAC,OAAD;IAAK,WAAU;cAA2B;IAAc,CAAA,CAChE;MAEP,EACO;;;AASd,SAAgB,EAAW,EACzB,SACA,UACA,gBACA,WACA,gBAOC;AACD,QACE,kBAAC,OAAD;EAAgB;YACd,kBAAC,GAAD;GACQ;GACC;GACM;GACL;GACR,CAAA;EACE,CAAA"}
1
+ {"version":3,"file":"PageLayout.js","names":[],"sources":["../../../src/export/components/PageLayout.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { EmptyState as CanonicalEmptyState } from \"@burdenoff/fe-libs/ui\";\nimport { cn } from \"../utils/cn\";\n\ninterface PageLayoutProps {\n children: ReactNode;\n /** Page title */\n title?: string;\n /** Page subtitle/description */\n subtitle?: string;\n /** Icon component to display next to title */\n icon?: ReactNode;\n /** Actions to display in header (buttons, etc.) */\n headerActions?: ReactNode;\n /** Additional header content below title */\n headerContent?: ReactNode;\n /** Maximum width of content: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full' */\n maxWidth?: \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\" | \"full\";\n /** Whether to show the header section */\n showHeader?: boolean;\n /** Additional CSS classes for the container */\n className?: string;\n /** Additional CSS classes for the content area */\n contentClassName?: string;\n}\n\nconst maxWidthClasses = {\n sm: \"max-w-screen-sm\", // 640px\n md: \"max-w-screen-md\", // 768px\n lg: \"max-w-screen-lg\", // 1024px\n xl: \"max-w-screen-xl\", // 1280px\n \"2xl\": \"max-w-screen-2xl\", // 1536px\n \"3xl\": \"max-w-[1600px]\",\n full: \"max-w-full\",\n};\n\n/**\n * PageLayout - A consistent page wrapper with responsive design\n *\n * Features:\n * - Proper max-width constraints\n * - Responsive padding\n * - Animated entrance\n * - Consistent header styling\n */\nexport function PageLayout({\n children,\n title,\n subtitle,\n icon,\n headerActions,\n headerContent,\n maxWidth = \"xl\",\n showHeader = true,\n className,\n contentClassName,\n}: PageLayoutProps) {\n return (\n <div\n className={cn(\n // Base styles - full width container with padding\n \"min-h-full w-full\",\n // Responsive horizontal padding\n \"px-4 sm:px-6 lg:px-8 xl:px-12\",\n // Responsive vertical padding\n \"py-6 sm:py-8 lg:py-10\",\n // Entrance animation\n \"animate-in fade-in-0 slide-in-from-bottom-4 duration-500\",\n className,\n )}\n >\n {/* Max-width constrained content container */}\n <div\n className={cn(\n \"mx-auto w-full\",\n maxWidthClasses[maxWidth],\n contentClassName,\n )}\n >\n {/* Page Header */}\n {showHeader && (title || headerActions) && (\n <header className=\"mb-6 sm:mb-8\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n {/* Title Section */}\n <div className=\"space-y-1\">\n {(title || icon) && (\n <div className=\"flex items-center gap-3\">\n {icon && (\n <div className=\"flex-shrink-0 p-2.5 rounded-xl bg-action-primary-bg/10 text-primary\">\n {icon}\n </div>\n )}\n {title && (\n <h1 className=\"text-2xl sm:text-3xl font-bold tracking-tight text-text-primary\">\n {title}\n </h1>\n )}\n </div>\n )}\n {subtitle && (\n <p className=\"text-sm sm:text-base text-text-secondary max-w-2xl\">\n {subtitle}\n </p>\n )}\n </div>\n\n {/* Header Actions */}\n {headerActions && (\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n {headerActions}\n </div>\n )}\n </div>\n\n {/* Additional Header Content */}\n {headerContent && <div className=\"mt-4\">{headerContent}</div>}\n </header>\n )}\n\n {/* Page content — must not use a <main> landmark here because the\n host shell (AppShellLayout) already renders one; nesting <main>\n elements is invalid HTML and an a11y violation. */}\n <div className=\"space-y-6\">{children}</div>\n </div>\n </div>\n );\n}\n\n/**\n * PageSection - A section within a page with consistent spacing\n */\nexport function PageSection({\n children,\n title,\n description,\n actions,\n className,\n ...rest\n}: {\n children: ReactNode;\n title?: string;\n description?: string;\n actions?: ReactNode;\n className?: string;\n} & React.HTMLAttributes<HTMLElement>) {\n return (\n <section className={cn(\"space-y-4\", className)} {...rest}>\n {(title || actions) && (\n <div className=\"flex items-center justify-between\">\n <div>\n {title && (\n <h2 className=\"text-lg font-semibold text-text-primary\">{title}</h2>\n )}\n {description && (\n <p className=\"text-sm text-text-secondary\">{description}</p>\n )}\n </div>\n {actions && <div className=\"flex items-center gap-2\">{actions}</div>}\n </div>\n )}\n {children}\n </section>\n );\n}\n\n/**\n * Local wrapper around the canonical `EmptyState` from `@burdenoff/fe-libs/ui`.\n * Keeps the existing microfe-export call sites stable while routing all\n * empty-state rendering through the shared primitive.\n */\nexport function EmptyState({\n icon,\n title,\n description,\n action,\n className,\n}: {\n icon?: ReactNode;\n title: string;\n description?: string;\n action?: ReactNode;\n className?: string;\n}) {\n return (\n <div className={className}>\n <CanonicalEmptyState\n icon={icon}\n title={title}\n description={description}\n action={action}\n />\n </div>\n );\n}\n"],"mappings":";;;;AA0BA,IAAM,IAAkB;CACtB,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,OAAO;CACP,OAAO;CACP,MAAM;CACP;AAWD,SAAgB,EAAW,EACzB,aACA,UACA,aACA,SACA,kBACA,kBACA,cAAW,MACX,gBAAa,IACb,cACA,uBACkB;AAClB,QACE,kBAAC,OAAD;EACE,WAAW,EAET,qBAEA,iCAEA,yBAEA,4DACA,EACD;YAGD,kBAAC,OAAD;GACE,WAAW,EACT,kBACA,EAAgB,IAChB,EACD;aALH,CAQG,MAAe,KAAS,MACvB,kBAAC,UAAD;IAAQ,WAAU;cAAlB,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CAEE,kBAAC,OAAD;MAAK,WAAU;gBAAf,EACI,KAAS,MACT,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACG,KACC,kBAAC,OAAD;QAAK,WAAU;kBACZ;QACG,CAAA,EAEP,KACC,kBAAC,MAAD;QAAI,WAAU;kBACX;QACE,CAAA,CAEH;UAEP,KACC,kBAAC,KAAD;OAAG,WAAU;iBACV;OACC,CAAA,CAEF;SAGL,KACC,kBAAC,OAAD;MAAK,WAAU;gBACZ;MACG,CAAA,CAEJ;QAGL,KAAiB,kBAAC,OAAD;KAAK,WAAU;eAAQ;KAAoB,CAAA,CACtD;OAMX,kBAAC,OAAD;IAAK,WAAU;IAAa;IAAe,CAAA,CACvC;;EACF,CAAA;;AAOV,SAAgB,EAAY,EAC1B,aACA,UACA,gBACA,YACA,cACA,GAAG,KAOkC;AACrC,QACE,kBAAC,WAAD;EAAS,WAAW,EAAG,aAAa,EAAU;EAAE,GAAI;YAApD,EACI,KAAS,MACT,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACG,KACC,kBAAC,MAAD;IAAI,WAAU;cAA2C;IAAW,CAAA,EAErE,KACC,kBAAC,KAAD;IAAG,WAAU;cAA+B;IAAgB,CAAA,CAE1D,EAAA,CAAA,EACL,KAAW,kBAAC,OAAD;IAAK,WAAU;cAA2B;IAAc,CAAA,CAChE;MAEP,EACO"}