@doneisbetter/gds-core 2.6.7 → 3.0.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.
package/dist/client.js CHANGED
@@ -24,13 +24,22 @@ __export(client_exports, {
24
24
  AccessRecoveryPanel: () => AccessRecoveryPanel,
25
25
  AccessSummary: () => AccessSummary,
26
26
  ActionBar: () => ActionBar,
27
+ ActiveFilterChips: () => ActiveFilterChips,
28
+ AdvancedDataTable: () => AdvancedDataTable,
27
29
  ArticleShell: () => ArticleShell,
30
+ AsyncSurface: () => AsyncSurface,
28
31
  AuthShell: () => AuthShell,
32
+ BannerNotice: () => BannerNotice,
29
33
  BrowseSurface: () => BrowseSurface,
34
+ BulkActionsBar: () => BulkActionsBar,
35
+ ChartTokenPanel: () => ChartTokenPanel,
30
36
  ChoiceChip: () => ChoiceChip,
37
+ CommandPalette: () => CommandPalette,
38
+ CommandRegistryProvider: () => CommandRegistryProvider,
31
39
  ConfirmDialog: () => ConfirmDialog,
32
40
  ConsumerDashboardGrid: () => ConsumerDashboardGrid,
33
41
  ConsumerSection: () => ConsumerSection,
42
+ CountBadge: () => CountBadge,
34
43
  CtaButtonGroup: () => CtaButtonGroup,
35
44
  DataToolbar: () => DataToolbar,
36
45
  DetailProfileShell: () => DetailProfileShell,
@@ -41,20 +50,33 @@ __export(client_exports, {
41
50
  EditorialCard: () => EditorialCard,
42
51
  EditorialHero: () => EditorialHero,
43
52
  EmptyState: () => EmptyState,
53
+ EvidencePanel: () => EvidencePanel,
44
54
  FeatureBand: () => FeatureBand,
45
55
  FilterDrawer: () => FilterDrawer,
46
56
  FoodMenuSection: () => FoodMenuSection,
57
+ FormErrorSummary: () => FormErrorSummary,
47
58
  FormField: () => FormField,
48
59
  GameBoardTile: () => GameBoardTile,
60
+ GdsChart: () => GdsChart,
61
+ GdsFormProvider: () => GdsFormProvider,
49
62
  GdsIcons: () => GdsIcons,
63
+ GdsNotificationProvider: () => GdsNotificationProvider,
64
+ GdsTelemetryProvider: () => GdsTelemetryProvider,
50
65
  GdsVocabulary: () => GdsVocabulary,
66
+ InlineAlert: () => InlineAlert,
67
+ LabelTag: () => LabelTag,
51
68
  ListingCard: () => ListingCard,
69
+ ListingProvider: () => ListingProvider,
52
70
  MapPanel: () => MapPanel,
53
71
  MediaCard: () => MediaCard,
54
72
  MediaField: () => MediaField,
55
73
  MetricCard: () => MetricCard,
74
+ NotificationCenter: () => NotificationCenter,
75
+ NotificationCenterView: () => NotificationCenterView,
76
+ OverlayManagerProvider: () => OverlayManagerProvider,
56
77
  PROVIDER_IDENTITY_REGISTRY: () => PROVIDER_IDENTITY_REGISTRY,
57
78
  PageHeader: () => PageHeader,
79
+ PeriodSelector: () => PeriodSelector,
58
80
  PlaceholderPanel: () => PlaceholderPanel,
59
81
  PlaybackSurface: () => PlaybackSurface,
60
82
  ProductCard: () => ProductCard,
@@ -72,6 +94,8 @@ __export(client_exports, {
72
94
  ReferenceLocaleNotice: () => ReferenceLocaleNotice,
73
95
  ReferenceSection: () => ReferenceSection,
74
96
  ReferenceThemeExplorer: () => ReferenceThemeExplorer,
97
+ ReportingSection: () => ReportingSection,
98
+ ResultSummary: () => ResultSummary,
75
99
  SectionPanel: () => SectionPanel,
76
100
  SemanticButton: () => SemanticButton,
77
101
  ShareButtonGroup: () => ShareButtonGroup,
@@ -80,31 +104,48 @@ __export(client_exports, {
80
104
  SidebarNavSection: () => SidebarNavSection,
81
105
  SimpleDataTable: () => SimpleDataTable,
82
106
  SocialAuthButtons: () => SocialAuthButtons,
107
+ SortMenu: () => SortMenu,
83
108
  StateBlock: () => StateBlock,
84
109
  StatsSection: () => StatsSection,
85
110
  StatusBadge: () => StatusBadge,
86
111
  ThemeToggle: () => ThemeToggle,
87
112
  UploadDropzone: () => UploadDropzone,
113
+ ValidatedFieldMessage: () => ValidatedFieldMessage,
88
114
  ar: () => ar,
89
115
  createGdsVocabularyPack: () => createGdsVocabularyPack,
90
116
  de: () => de,
91
117
  en: () => en,
92
118
  es: () => es,
93
119
  fr: () => fr,
120
+ gdsCardSizePaddingMap: () => gdsCardSizePaddingMap,
121
+ gdsCardTitleOrderMap: () => gdsCardTitleOrderMap,
122
+ gdsFormReducer: () => gdsFormReducer,
94
123
  gdsLocales: () => gdsLocales,
95
124
  getGdsMessages: () => getGdsMessages,
96
125
  getProviderIdentityLabel: () => getProviderIdentityLabel,
126
+ getProviderIdentityPolicy: () => getProviderIdentityPolicy,
97
127
  getSemanticActionConfig: () => getSemanticActionConfig,
98
128
  getSemanticActionLabel: () => getSemanticActionLabel,
129
+ getSupportedProviderIdentityIds: () => getSupportedProviderIdentityIds,
99
130
  he: () => he,
100
131
  hu: () => hu,
101
132
  isPresentationMode: () => isPresentationMode,
102
133
  it: () => it,
134
+ listingQueryReducer: () => listingQueryReducer,
103
135
  mergeGdsVocabularyPacks: () => mergeGdsVocabularyPacks,
136
+ renderGdsLayout: () => renderGdsLayout,
104
137
  resolveAccentPanelStyles: () => resolveAccentPanelStyles,
105
138
  resolveSemanticActionConfig: () => resolveSemanticActionConfig,
106
139
  resolveSurfacePresentationStyles: () => resolveSurfacePresentationStyles,
107
- ru: () => ru
140
+ ru: () => ru,
141
+ useCommandLauncher: () => useCommandLauncher,
142
+ useDiscoveryShellState: () => useDiscoveryShellState,
143
+ useGdsForm: () => useGdsForm,
144
+ useGdsFormSnapshot: () => useGdsFormSnapshot,
145
+ useGdsNotifications: () => useGdsNotifications,
146
+ useGdsTelemetry: () => useGdsTelemetry,
147
+ useListingState: () => useListingState,
148
+ useOverlayManager: () => useOverlayManager
108
149
  });
109
150
  module.exports = __toCommonJS(client_exports);
110
151
 
@@ -118,9 +159,24 @@ var statusColorMap = {
118
159
  info: "blue",
119
160
  neutral: "gray"
120
161
  };
162
+ var labelTagColorMap = {
163
+ neutral: "gray",
164
+ info: "blue",
165
+ warning: "yellow",
166
+ success: "green"
167
+ };
121
168
  function StatusBadge({ status, children, ...props }) {
122
169
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Badge, { color: statusColorMap[status], variant: "light", ...props, children });
123
170
  }
171
+ function LabelTag({ tone = "neutral", label, ...props }) {
172
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Badge, { color: labelTagColorMap[tone], variant: "outline", ...props, children: label });
173
+ }
174
+ function CountBadge({ value, cap = 99, srLabel, ...props }) {
175
+ const normalizedValue = Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;
176
+ const normalizedCap = Math.max(1, Math.floor(cap));
177
+ const displayValue = normalizedValue > normalizedCap ? `${normalizedCap}+` : String(normalizedValue);
178
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Badge, { color: "violet", variant: "filled", "aria-label": srLabel, ...props, children: displayValue });
179
+ }
124
180
 
125
181
  // src/EmptyState.tsx
126
182
  var import_core2 = require("@mantine/core");
@@ -463,12 +519,14 @@ function ConfirmDialog({
463
519
  var import_core5 = require("@mantine/core");
464
520
  var import_gds_theme2 = require("@doneisbetter/gds-theme");
465
521
  var import_jsx_runtime5 = require("react/jsx-runtime");
466
- function ThemeToggle({ size = "md" }) {
522
+ function ThemeToggle({ size = "md", onColorSchemeChange }) {
467
523
  const { setColorScheme } = (0, import_core5.useMantineColorScheme)();
468
524
  const computedColorScheme = (0, import_core5.useComputedColorScheme)("light", { getInitialValueInEffect: true });
469
525
  const { t } = (0, import_gds_theme2.useGdsTranslation)();
470
526
  const toggleColorScheme = () => {
471
- setColorScheme(computedColorScheme === "dark" ? "light" : "dark");
527
+ const nextScheme = computedColorScheme === "dark" ? "light" : "dark";
528
+ setColorScheme(nextScheme);
529
+ onColorSchemeChange?.(nextScheme);
472
530
  };
473
531
  const isDark = computedColorScheme === "dark";
474
532
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
@@ -773,6 +831,24 @@ function FormField({ label, description, error, children }) {
773
831
 
774
832
  // src/ListingCard.tsx
775
833
  var import_core12 = require("@mantine/core");
834
+
835
+ // src/CardContracts.ts
836
+ var gdsCardSizePaddingMap = {
837
+ xs: "xs",
838
+ sm: "sm",
839
+ md: "md",
840
+ lg: "lg",
841
+ xl: "xl"
842
+ };
843
+ var gdsCardTitleOrderMap = {
844
+ xs: 6,
845
+ sm: 5,
846
+ md: 4,
847
+ lg: 4,
848
+ xl: 3
849
+ };
850
+
851
+ // src/ListingCard.tsx
776
852
  var import_jsx_runtime13 = require("react/jsx-runtime");
777
853
  var ratioMap = {
778
854
  "1:1": 1,
@@ -841,17 +917,27 @@ function ListingCard({
841
917
  primaryAction,
842
918
  saveAction,
843
919
  shareAction,
844
- compact = false
920
+ compact = false,
921
+ size = "md",
922
+ interactiveMode = "none",
923
+ revealContent,
924
+ onSurfaceActivate,
925
+ defaultFlipped = false
845
926
  }) {
927
+ const cardPadding = compact ? "md" : gdsCardSizePaddingMap[size];
846
928
  const titleContent = href && typeof title === "string" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core12.Text, { component: "a", href, inherit: true, td: "none", children: title }) : title;
847
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core12.Card, { withBorder: true, radius: "lg", padding: compact ? "md" : "lg", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_core12.Stack, { gap: compact ? "sm" : "md", children: [
929
+ const interactiveProps = interactiveMode === "surface-link" && href ? { component: "a", href } : interactiveMode === "surface-button" ? { component: "button", type: "button", onClick: onSurfaceActivate } : {};
930
+ if (interactiveMode === "flip" && defaultFlipped && revealContent) {
931
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core12.Card, { withBorder: true, radius: "lg", padding: cardPadding, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core12.Stack, { gap: "sm", children: revealContent }) });
932
+ }
933
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core12.Card, { withBorder: true, radius: "lg", padding: cardPadding, ...interactiveProps, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_core12.Stack, { gap: compact ? "sm" : "md", children: [
848
934
  image ?? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ListingImageFallback, { mediaRatio }),
849
935
  featured || sponsoredDisclosure ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_core12.Group, { justify: "space-between", gap: "sm", wrap: "wrap", children: [
850
936
  featured ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core12.Badge, { variant: "light", color: "violet", children: "Featured" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", {}),
851
937
  sponsoredDisclosure ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core12.Text, { size: "xs", c: "dimmed", children: sponsoredDisclosure }) : null
852
938
  ] }) : null,
853
939
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_core12.Stack, { gap: 4, children: [
854
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core12.Title, { order: compact ? 5 : 4, lineClamp: 2, children: titleContent }),
940
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core12.Title, { order: compact ? 5 : gdsCardTitleOrderMap[size], lineClamp: 2, children: titleContent }),
855
941
  description ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core12.Text, { size: "sm", c: "dimmed", lineClamp: compact ? 2 : 3, children: description }) : null
856
942
  ] }),
857
943
  metadata.length ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core12.Stack, { gap: "xs", children: metadata.map((item) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_core12.Group, { justify: "space-between", align: "flex-start", gap: "sm", wrap: "nowrap", children: [
@@ -866,7 +952,8 @@ function ListingCard({
866
952
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_core12.Group, { gap: "xs", wrap: "nowrap", justify: "flex-end", style: { marginInlineStart: "auto" }, children: [
867
953
  saveAction ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ListingAffordance, { affordance: saveAction }) : null,
868
954
  shareAction ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ListingAffordance, { affordance: shareAction }) : null,
869
- primaryAction
955
+ primaryAction,
956
+ interactiveMode === "flip" && revealContent ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core12.Text, { size: "xs", c: "dimmed", children: "Flip mode supports reveal surfaces." }) : null
870
957
  ] })
871
958
  ] })
872
959
  ] }) });
@@ -932,53 +1019,42 @@ function StateBlock({
932
1019
  var import_gds_theme3 = require("@doneisbetter/gds-theme");
933
1020
  var import_jsx_runtime15 = require("react/jsx-runtime");
934
1021
  function resolvePreviewColorScheme(presetId, requestedScheme) {
935
- if (presetId === "dark-public") {
1022
+ if (presetId === "dark-public" || presetId === "neon-night") {
936
1023
  return "dark";
937
1024
  }
938
1025
  return requestedScheme;
939
1026
  }
940
- var themePresetCatalog = {
941
- default: {
942
- label: "Default runtime theme",
943
- bestFor: "Balanced multi-surface products that need the baseline GDS system.",
944
- summary: "The default shared runtime lane for most adopters.",
945
- themeKey: "gdsTheme",
946
- supportedUse: "Starter products, hybrid public/admin apps, and teams adopting all canonical contracts.",
947
- avoidFor: "Avoid for products requiring a distinct editorial voice or guaranteed dark-first brand contrast."
948
- },
949
- "dark-public": {
950
- label: "Dark public theme",
951
- bestFor: "Dark-first public experiences and campaign-style landing surfaces.",
952
- summary: "A darker public presentation lane with the shipped runtime rhythm intact.",
953
- themeKey: "gdsDarkPublicTheme",
954
- supportedUse: "Products with a deliberate dark visual baseline, low-light UX, or premium media-first surfaces.",
955
- avoidFor: "Avoid when mixed mode and editorial readability are core requirements."
956
- },
957
- "flat-surface": {
958
- label: "Flat surface theme",
959
- bestFor: "Operational products that prefer quieter elevation and flatter surface contrast.",
960
- summary: "Removes some visual weight without creating a second token authority.",
961
- themeKey: "gdsFlatSurfaceTheme",
962
- supportedUse: "Dashboards, admin surfaces, and dense content where elevation becomes distracting.",
963
- avoidFor: "Avoid for brand-first storytelling or high-expressiveness hero-first pages."
1027
+ var presetCatalog = (0, import_gds_theme3.getGdsThemePresets)();
1028
+ var themePresetCatalog = Object.fromEntries(
1029
+ presetCatalog.map((preset) => [
1030
+ preset.id,
1031
+ {
1032
+ label: preset.label,
1033
+ bestFor: `Apps aligned with ${preset.label.toLowerCase()}.`,
1034
+ summary: preset.description,
1035
+ themeKey: preset.runtimeLane,
1036
+ supportedUse: `General product adoption with ${preset.label}.`,
1037
+ avoidFor: "Avoid creating a local non-canonical theme authority."
1038
+ }
1039
+ ])
1040
+ );
1041
+ var colorSchemeProof = [
1042
+ {
1043
+ id: "light",
1044
+ label: "Light",
1045
+ description: "Validates readable default surfaces, controls, badges, and focus states against light backgrounds."
964
1046
  },
965
- editorial: {
966
- label: "Editorial serif theme",
967
- bestFor: "Documentation, editorial, and content-led experiences.",
968
- summary: "Adds a more expressive public reading tone while staying inside GDS contracts.",
969
- themeKey: "gdsEditorialPublicTheme",
970
- supportedUse: "Guides, docs, and catalog content where reading comfort matters more than impact.",
971
- avoidFor: "Avoid for dense transactional or data-first workflows with strict minimal contrast."
1047
+ {
1048
+ id: "dark",
1049
+ label: "Dark",
1050
+ description: "Validates contrast for public, operational, and feedback surfaces when dark mode is active."
972
1051
  },
973
- brand: {
974
- label: "Brand theme generator",
975
- bestFor: "Consumer teams that need controlled brand expression without forking the system.",
976
- summary: "Composes the shipped helpers into a governed product-authored theme lane.",
977
- themeKey: "createPublicBrandTheme(...)",
978
- supportedUse: "Whitelisted public branding programs with narrow product-authored intent and policy guardrails.",
979
- avoidFor: "Avoid for local style experiments or temporary visual fixes without compliance approval."
1052
+ {
1053
+ id: "auto",
1054
+ label: "Auto",
1055
+ description: "Documents the adopter path for OS-controlled schemes while keeping the provider contract unchanged."
980
1056
  }
981
- };
1057
+ ];
982
1058
  function ThemePreviewSurface({
983
1059
  preset,
984
1060
  colorScheme,
@@ -1000,6 +1076,10 @@ function ThemePreviewSurface({
1000
1076
  " ",
1001
1077
  colorScheme
1002
1078
  ] }),
1079
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Text, { size: "sm", children: [
1080
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { children: "Accessibility proof:" }),
1081
+ " status uses text, badge label, and placement, not color alone."
1082
+ ] }),
1003
1083
  forcedScheme ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { size: "sm", c: "dimmed", children: "This lane always previews in dark mode so the runtime stays inside its sanctioned contrast contract." }) : null
1004
1084
  ] }),
1005
1085
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ThemeToggle, {})
@@ -1029,7 +1109,8 @@ function ThemePreviewSurface({
1029
1109
  description: "This preview uses the real shipped design-system runtime rather than a docs-only styling lane.",
1030
1110
  metadata: [
1031
1111
  { id: "runtime", label: "Runtime lane", value: preset.themeKey },
1032
- { id: "scheme", label: "Color scheme", value: colorScheme }
1112
+ { id: "scheme", label: "Color scheme", value: colorScheme },
1113
+ { id: "focus", label: "A11y proof", value: "Keyboard + readable states" }
1033
1114
  ],
1034
1115
  primaryAction: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Button, { size: "sm", children: "Inspect route" })
1035
1116
  }
@@ -1037,40 +1118,50 @@ function ThemePreviewSurface({
1037
1118
  ] })
1038
1119
  ] }) });
1039
1120
  }
1040
- function ReferenceThemeExplorer() {
1041
- const [preset, setPreset] = (0, import_react2.useState)("default");
1042
- const [colorScheme, setColorScheme] = (0, import_react2.useState)("light");
1043
- const [brandPrimary, setBrandPrimary] = (0, import_react2.useState)("blue");
1044
- const [brandFlatSurfaces, setBrandFlatSurfaces] = (0, import_react2.useState)(true);
1045
- const [brandEditorialSerif, setBrandEditorialSerif] = (0, import_react2.useState)(false);
1121
+ function ReferenceThemeExplorer({
1122
+ initialSelection,
1123
+ onSelectionChange
1124
+ }) {
1125
+ const [preset, setPreset] = (0, import_react2.useState)(initialSelection?.preset ?? "default");
1126
+ const [colorScheme, setColorScheme] = (0, import_react2.useState)(initialSelection?.colorScheme ?? "light");
1127
+ const [brandPrimary, setBrandPrimary] = (0, import_react2.useState)(initialSelection?.brandPrimary ?? "blue");
1128
+ const [brandFlatSurfaces, setBrandFlatSurfaces] = (0, import_react2.useState)(initialSelection?.brandFlatSurfaces ?? true);
1129
+ const [brandEditorialSerif, setBrandEditorialSerif] = (0, import_react2.useState)(initialSelection?.brandEditorialSerif ?? false);
1130
+ const [fontLane, setFontLane] = (0, import_react2.useState)(initialSelection?.fontLane ?? "inter");
1046
1131
  const [comparisonEnabled, setComparisonEnabled] = (0, import_react2.useState)(false);
1047
1132
  const [comparisonPreset, setComparisonPreset] = (0, import_react2.useState)("editorial");
1048
- const resolveTheme = (presetId) => {
1049
- switch (presetId) {
1050
- case "dark-public":
1051
- return import_gds_theme3.gdsDarkPublicTheme;
1052
- case "flat-surface":
1053
- return import_gds_theme3.gdsFlatSurfaceTheme;
1054
- case "editorial":
1055
- return import_gds_theme3.gdsEditorialPublicTheme;
1056
- case "brand":
1057
- return (0, import_gds_theme3.createPublicBrandTheme)({
1058
- flatSurfaces: brandFlatSurfaces,
1059
- editorialSerif: brandEditorialSerif,
1060
- overrides: { primaryColor: brandPrimary }
1061
- });
1062
- default:
1063
- return import_gds_theme3.gdsTheme;
1064
- }
1065
- };
1133
+ const availableComparisonPresets = presetCatalog.filter((item) => item.id !== preset).map((item) => item.id);
1134
+ const resolveTheme = (presetId) => (0, import_gds_theme3.applyGdsFontLane)((0, import_gds_theme3.resolveGdsThemePreset)(presetId, {
1135
+ brandPrimary,
1136
+ brandFlatSurfaces,
1137
+ brandEditorialSerif
1138
+ }), fontLane);
1066
1139
  const selectionSummary = themePresetCatalog[preset];
1067
1140
  const comparisonSummary = themePresetCatalog[comparisonPreset];
1068
- const selectedTheme = (0, import_react2.useMemo)(() => resolveTheme(preset), [preset, brandPrimary, brandFlatSurfaces, brandEditorialSerif]);
1069
- const comparedTheme = (0, import_react2.useMemo)(() => resolveTheme(comparisonPreset), [comparisonPreset, brandPrimary, brandFlatSurfaces, brandEditorialSerif]);
1141
+ const selectedTheme = (0, import_react2.useMemo)(() => resolveTheme(preset), [preset, brandPrimary, brandFlatSurfaces, brandEditorialSerif, fontLane]);
1142
+ const comparedTheme = (0, import_react2.useMemo)(() => resolveTheme(comparisonPreset), [comparisonPreset, brandPrimary, brandFlatSurfaces, brandEditorialSerif, fontLane]);
1070
1143
  const effectiveColorScheme = resolvePreviewColorScheme(preset, colorScheme);
1071
1144
  const effectiveComparisonScheme = resolvePreviewColorScheme(comparisonPreset, colorScheme);
1072
- const previewKey = `${preset}-${effectiveColorScheme}-${brandPrimary}-${brandFlatSurfaces}-${brandEditorialSerif}`;
1073
- const comparisonPreviewKey = `${comparisonPreset}-${effectiveComparisonScheme}-${brandPrimary}-${brandFlatSurfaces}-${brandEditorialSerif}`;
1145
+ const previewKey = `${preset}-${effectiveColorScheme}-${brandPrimary}-${brandFlatSurfaces}-${brandEditorialSerif}-${fontLane}`;
1146
+ const comparisonPreviewKey = `${comparisonPreset}-${effectiveComparisonScheme}-${brandPrimary}-${brandFlatSurfaces}-${brandEditorialSerif}-${fontLane}`;
1147
+ (0, import_react2.useEffect)(() => {
1148
+ onSelectionChange?.({
1149
+ preset,
1150
+ colorScheme: effectiveColorScheme,
1151
+ theme: selectedTheme,
1152
+ fontLane,
1153
+ runtimeKey: previewKey,
1154
+ brandPrimary,
1155
+ brandFlatSurfaces,
1156
+ brandEditorialSerif
1157
+ });
1158
+ }, [onSelectionChange, preset, effectiveColorScheme, selectedTheme, fontLane, previewKey, brandPrimary, brandFlatSurfaces, brandEditorialSerif]);
1159
+ (0, import_react2.useEffect)(() => {
1160
+ if (comparisonPreset !== preset) {
1161
+ return;
1162
+ }
1163
+ setComparisonPreset(availableComparisonPresets[0] ?? "editorial");
1164
+ }, [comparisonPreset, preset, availableComparisonPresets]);
1074
1165
  const reset = () => {
1075
1166
  setPreset("default");
1076
1167
  setColorScheme("light");
@@ -1079,6 +1170,7 @@ function ReferenceThemeExplorer() {
1079
1170
  setBrandEditorialSerif(false);
1080
1171
  setComparisonEnabled(false);
1081
1172
  setComparisonPreset("editorial");
1173
+ setFontLane("inter");
1082
1174
  };
1083
1175
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Stack, { gap: "xl", children: [
1084
1176
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
@@ -1111,8 +1203,17 @@ function ReferenceThemeExplorer() {
1111
1203
  ]
1112
1204
  }
1113
1205
  ) }),
1206
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(FormField, { label: "Webfont lane", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1207
+ import_core14.NativeSelect,
1208
+ {
1209
+ "aria-label": "Webfont lane",
1210
+ value: fontLane,
1211
+ onChange: (event) => setFontLane(event.currentTarget.value || "inter"),
1212
+ data: (0, import_gds_theme3.getGdsFontLanes)().map((lane) => ({ value: lane.id, label: lane.label }))
1213
+ }
1214
+ ) }),
1114
1215
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Button, { variant: "default", size: "sm", onClick: reset, children: "Reset theme lab" }),
1115
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { size: "sm", c: "dimmed", children: "The reference site remounts an isolated provider here so visitors can test shipped presets without changing the whole docs shell." })
1216
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { size: "sm", c: "dimmed", children: "Theme changes apply to the official site shell so visitors can validate real whole-page runtime behavior." })
1116
1217
  ] }) }),
1117
1218
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Stack, { gap: "md", children: [
1118
1219
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Title, { order: 4, children: "Brand builder options" }),
@@ -1146,7 +1247,7 @@ function ReferenceThemeExplorer() {
1146
1247
  ),
1147
1248
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { size: "sm", c: "dimmed", children: "The generator composes shipped helpers instead of creating a second theme authority inside the website." })
1148
1249
  ] }) }),
1149
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Stack, { gap: "md", children: [
1250
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Stack, { gap: "md", role: "status", "aria-live": "polite", children: [
1150
1251
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Title, { order: 4, children: "Current selection summary" }),
1151
1252
  /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Stack, { gap: 6, children: [
1152
1253
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { fw: 700, children: selectionSummary.label }),
@@ -1166,7 +1267,7 @@ function ReferenceThemeExplorer() {
1166
1267
  " ",
1167
1268
  colorScheme
1168
1269
  ] }),
1169
- preset === "dark-public" && colorScheme !== effectiveColorScheme ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { size: "sm", c: "dimmed", children: "gdsDarkPublicTheme always renders in dark mode inside the live preview." }) : null
1270
+ (preset === "dark-public" || preset === "neon-night") && colorScheme !== effectiveColorScheme ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { size: "sm", c: "dimmed", children: "This dark-forward preset always renders in dark mode inside the live preview." }) : null
1170
1271
  ] }),
1171
1272
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1172
1273
  import_core14.Checkbox,
@@ -1184,7 +1285,7 @@ function ReferenceThemeExplorer() {
1184
1285
  value: comparisonPreset,
1185
1286
  onChange: (event) => setComparisonPreset(event.currentTarget.value || "editorial"),
1186
1287
  disabled: !comparisonEnabled,
1187
- data: Object.entries(themePresetCatalog).filter(([value]) => value !== preset).map(([value, item]) => ({ value, label: item.label }))
1288
+ data: availableComparisonPresets.map((value) => ({ value, label: themePresetCatalog[value].label }))
1188
1289
  }
1189
1290
  ) })
1190
1291
  ] }) })
@@ -1213,6 +1314,18 @@ function ReferenceThemeExplorer() {
1213
1314
  ] }) }, lane.themeKey)) })
1214
1315
  }
1215
1316
  ),
1317
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1318
+ ReferenceSection,
1319
+ {
1320
+ title: "Light, dark, and auto proof",
1321
+ description: "Every official lane must remain usable across explicit light, explicit dark, and OS-controlled auto modes. The dark-public lane is intentionally forced to dark in preview to preserve its contrast contract.",
1322
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.SimpleGrid, { cols: { base: 1, md: 3 }, spacing: "md", children: colorSchemeProof.map((item) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Paper, { withBorder: true, radius: "lg", p: "md", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Stack, { gap: 6, children: [
1323
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Badge, { variant: "light", color: item.id === "dark" ? "violet" : item.id === "auto" ? "teal" : "blue", w: "fit-content", children: item.label }),
1324
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { size: "sm", children: item.description }),
1325
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { size: "xs", c: "dimmed", children: "Required proof: semantic text, visible focus, and contrast-safe state treatment." })
1326
+ ] }) }, item.id)) })
1327
+ }
1328
+ ),
1216
1329
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1217
1330
  ReferenceSection,
1218
1331
  {
@@ -1250,18 +1363,34 @@ function ReferenceThemeExplorer() {
1250
1363
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1251
1364
  ReferenceSection,
1252
1365
  {
1253
- title: "Creator-Authored Experience Boundary",
1254
- description: "Creator-authored expression is allowed only through the sanctioned theme helpers and narrow exception process.",
1366
+ title: "Unsupported lane boundary",
1367
+ description: "Unsupported local theme lanes are blocked by policy and compliance because they create parallel design-system authority.",
1255
1368
  tone: "supporting",
1256
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1257
- StateBlock,
1258
- {
1259
- variant: "info",
1260
- title: "Shipped first, custom second",
1261
- description: "The official site uses shipped presets and the public brand generator first. Product-authored overrides must stay reviewable, testable, and scoped.",
1262
- compact: true
1263
- }
1264
- )
1369
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Stack, { gap: "md", children: [
1370
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1371
+ StateBlock,
1372
+ {
1373
+ variant: "permission",
1374
+ title: "Do not create local branding-layer helpers",
1375
+ description: "If a consumer needs brand expression, use createPublicBrandTheme(...). If a lane is missing, request it for GDS instead of building extendGdsTheme(...), createTheme(...), or mergeMantineTheme(...) ownership locally.",
1376
+ compact: true
1377
+ }
1378
+ ),
1379
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.SimpleGrid, { cols: { base: 1, md: 2 }, spacing: "md", children: [
1380
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Paper, { withBorder: true, radius: "lg", p: "md", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Stack, { gap: 6, children: [
1381
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { fw: 700, size: "sm", children: "Approved remediation" }),
1382
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Code, { block: true, children: [
1383
+ "createPublicBrandTheme(",
1384
+ `{ flatSurfaces: true, overrides: { primaryColor: 'blue' } }`,
1385
+ ")"
1386
+ ] })
1387
+ ] }) }),
1388
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Paper, { withBorder: true, radius: "lg", p: "md", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Stack, { gap: 6, children: [
1389
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { fw: 700, size: "sm", children: "Prohibited ownership" }),
1390
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Code, { block: true, children: "extendGdsTheme(...) / createTheme(...) / mergeMantineTheme(...)" })
1391
+ ] }) })
1392
+ ] })
1393
+ ] })
1265
1394
  }
1266
1395
  )
1267
1396
  ] });
@@ -1544,16 +1673,17 @@ function ProductCard({
1544
1673
  metadata = [],
1545
1674
  primaryAction,
1546
1675
  secondaryActions = [],
1547
- footer
1676
+ footer,
1677
+ size = "md"
1548
1678
  }) {
1549
1679
  const MoreIcon = GdsIcons.Menu;
1550
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_core21.Card, { withBorder: true, radius: "lg", padding: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_core21.Stack, { gap: "md", children: [
1680
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_core21.Card, { withBorder: true, radius: "lg", padding: gdsCardSizePaddingMap[size], children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_core21.Stack, { gap: "md", children: [
1551
1681
  media,
1552
1682
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_core21.Group, { justify: "space-between", align: "flex-start", wrap: "nowrap", children: [
1553
1683
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_core21.Group, { align: "flex-start", gap: "sm", wrap: "nowrap", children: [
1554
1684
  icon ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_core21.ThemeIcon, { variant: "light", size: "xl", radius: "xl", "aria-hidden": true, children: icon }) : null,
1555
1685
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_core21.Stack, { gap: 4, children: [
1556
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_core21.Title, { order: 4, children: title }),
1686
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_core21.Title, { order: gdsCardTitleOrderMap[size], children: title }),
1557
1687
  description ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_core21.Text, { size: "sm", c: "dimmed", lineClamp: 3, children: description }) : null
1558
1688
  ] })
1559
1689
  ] }),
@@ -1637,8 +1767,11 @@ function PublicProductCard({
1637
1767
  secondaryAction,
1638
1768
  metadata = [],
1639
1769
  compact = false,
1770
+ size = "md",
1640
1771
  loading = false,
1641
- disabled = false
1772
+ disabled = false,
1773
+ interactiveMode = "none",
1774
+ onSurfaceActivate
1642
1775
  }) {
1643
1776
  if (loading) {
1644
1777
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(LoadingCard, { compact });
@@ -1654,11 +1787,12 @@ function PublicProductCard({
1654
1787
  const pickupHelper = helperKind === "pickup" ? helperText : pickupNote;
1655
1788
  const inventoryHelper = helperKind === "inventory" ? helperText : inventoryNote;
1656
1789
  const hasSupportingRegion = Boolean(price || supportingHelper || pickupHelper || inventoryHelper);
1657
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_core22.Card, { withBorder: true, radius: "lg", padding: compact ? "md" : "lg", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_core22.Stack, { gap: compact ? "sm" : "md", children: [
1790
+ const interactiveProps = interactiveMode === "surface-button" ? { component: "button", type: "button", onClick: onSurfaceActivate } : {};
1791
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_core22.Card, { withBorder: true, radius: "lg", padding: compact ? "md" : gdsCardSizePaddingMap[size], ...interactiveProps, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_core22.Stack, { gap: compact ? "sm" : "md", children: [
1658
1792
  image ?? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ImageFallback, { compact }),
1659
1793
  /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_core22.Group, { justify: "space-between", align: "flex-start", wrap: "nowrap", gap: "sm", children: [
1660
1794
  /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_core22.Stack, { gap: 4, style: { minWidth: 0, flex: 1 }, children: [
1661
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_core22.Title, { order: compact ? 5 : 4, lineClamp: 2, children: title }),
1795
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_core22.Title, { order: compact ? 5 : gdsCardTitleOrderMap[size], lineClamp: 2, children: title }),
1662
1796
  description ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_core22.Text, { size: "sm", c: "dimmed", lineClamp: compact ? 2 : 3, children: description }) : null
1663
1797
  ] }),
1664
1798
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_core22.Badge, { variant: "light", color: stateBadge.color, children: stateBadge.label })
@@ -2032,20 +2166,277 @@ function DetailProfileShell({
2032
2166
  ] }) });
2033
2167
  }
2034
2168
 
2169
+ // src/AsyncSurface.tsx
2170
+ var import_jsx_runtime30 = require("react/jsx-runtime");
2171
+ function getRetryAction(onRetry) {
2172
+ if (!onRetry) {
2173
+ return void 0;
2174
+ }
2175
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "button", onClick: onRetry, children: "Retry" });
2176
+ }
2177
+ function renderStateBlock({
2178
+ variant,
2179
+ title,
2180
+ description,
2181
+ compact,
2182
+ presentation,
2183
+ minHeight,
2184
+ contentAlign,
2185
+ contentJustify,
2186
+ action
2187
+ }) {
2188
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
2189
+ StateBlock,
2190
+ {
2191
+ variant,
2192
+ title,
2193
+ description,
2194
+ action,
2195
+ compact,
2196
+ presentation,
2197
+ minHeight,
2198
+ contentAlign,
2199
+ contentJustify
2200
+ }
2201
+ );
2202
+ }
2203
+ function AsyncSurface({
2204
+ state,
2205
+ successContent,
2206
+ idleContent,
2207
+ loadingTitle = "Loading",
2208
+ loadingDescription = "This surface is still synchronizing.",
2209
+ emptyTitle = "No results",
2210
+ emptyDescription = "No data is available for this surface yet.",
2211
+ errorTitle = "Unable to load",
2212
+ errorDescription = "Something went wrong while preparing this surface.",
2213
+ refreshingTitle = "Refreshing",
2214
+ refreshingDescription = "The latest data is being fetched.",
2215
+ onRetry,
2216
+ retryAction,
2217
+ compact = false,
2218
+ presentation = "inline",
2219
+ minHeight,
2220
+ contentAlign,
2221
+ contentJustify
2222
+ }) {
2223
+ const fallbackRetryAction = retryAction ?? getRetryAction(onRetry);
2224
+ if (state === "success") {
2225
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_jsx_runtime30.Fragment, { children: successContent });
2226
+ }
2227
+ if (state === "idle") {
2228
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_jsx_runtime30.Fragment, { children: idleContent ?? successContent ?? null });
2229
+ }
2230
+ if (state === "loading") {
2231
+ return renderStateBlock({
2232
+ variant: "loading",
2233
+ title: loadingTitle,
2234
+ description: loadingDescription,
2235
+ compact,
2236
+ presentation,
2237
+ minHeight,
2238
+ contentAlign,
2239
+ contentJustify
2240
+ });
2241
+ }
2242
+ if (state === "empty") {
2243
+ return renderStateBlock({
2244
+ variant: "empty",
2245
+ title: emptyTitle,
2246
+ description: emptyDescription,
2247
+ compact,
2248
+ presentation,
2249
+ minHeight,
2250
+ contentAlign,
2251
+ contentJustify,
2252
+ action: fallbackRetryAction
2253
+ });
2254
+ }
2255
+ if (state === "error") {
2256
+ return renderStateBlock({
2257
+ variant: "error",
2258
+ title: errorTitle,
2259
+ description: errorDescription,
2260
+ compact,
2261
+ presentation,
2262
+ minHeight,
2263
+ contentAlign,
2264
+ contentJustify,
2265
+ action: fallbackRetryAction
2266
+ });
2267
+ }
2268
+ return renderStateBlock({
2269
+ variant: "info",
2270
+ title: refreshingTitle,
2271
+ description: refreshingDescription,
2272
+ compact,
2273
+ presentation,
2274
+ minHeight,
2275
+ contentAlign,
2276
+ contentJustify
2277
+ });
2278
+ }
2279
+
2280
+ // src/ListingPrimitives.tsx
2281
+ var import_core28 = require("@mantine/core");
2282
+ var import_jsx_runtime31 = require("react/jsx-runtime");
2283
+ function ActiveFilterChips({
2284
+ filters,
2285
+ emptyLabel = "No active filters."
2286
+ }) {
2287
+ if (!filters.length) {
2288
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core28.Text, { size: "sm", c: "dimmed", children: emptyLabel });
2289
+ }
2290
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core28.Group, { gap: "xs", children: filters.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2291
+ import_core28.Badge,
2292
+ {
2293
+ variant: "light",
2294
+ rightSection: filter.onRemove ? "\xD7" : void 0,
2295
+ style: filter.onRemove ? { cursor: "pointer" } : void 0,
2296
+ onClick: filter.onRemove,
2297
+ children: filter.label
2298
+ },
2299
+ filter.id
2300
+ )) });
2301
+ }
2302
+ function ResultSummary({
2303
+ resultCount,
2304
+ noun = "results",
2305
+ description
2306
+ }) {
2307
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_core28.Stack, { gap: 2, children: [
2308
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_core28.Text, { size: "sm", fw: 600, children: [
2309
+ resultCount,
2310
+ " ",
2311
+ noun
2312
+ ] }),
2313
+ description ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core28.Text, { size: "xs", c: "dimmed", children: description }) : null
2314
+ ] });
2315
+ }
2316
+ function SortMenu({
2317
+ value,
2318
+ options,
2319
+ onChange,
2320
+ label = "Sort"
2321
+ }) {
2322
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2323
+ import_core28.Select,
2324
+ {
2325
+ "aria-label": label,
2326
+ label,
2327
+ value,
2328
+ data: options,
2329
+ onChange: (next) => {
2330
+ if (next) {
2331
+ onChange?.(next);
2332
+ }
2333
+ },
2334
+ w: 220
2335
+ }
2336
+ );
2337
+ }
2338
+ function BulkActionsBar({
2339
+ selectedCount,
2340
+ actions,
2341
+ clearAction
2342
+ }) {
2343
+ if (selectedCount <= 0) {
2344
+ return null;
2345
+ }
2346
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_core28.Group, { justify: "space-between", align: "center", children: [
2347
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_core28.Text, { size: "sm", fw: 600, children: [
2348
+ selectedCount,
2349
+ " selected"
2350
+ ] }),
2351
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_core28.Group, { gap: "xs", children: [
2352
+ actions,
2353
+ clearAction ?? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core28.Button, { variant: "subtle", size: "xs", children: "Clear selection" })
2354
+ ] })
2355
+ ] });
2356
+ }
2357
+
2358
+ // src/ListingState.client.tsx
2359
+ var import_react5 = require("react");
2360
+ var import_jsx_runtime32 = require("react/jsx-runtime");
2361
+ function createInitialState(config = {}) {
2362
+ return {
2363
+ search: "",
2364
+ sort: config.defaultSort ?? "newest",
2365
+ filters: [],
2366
+ page: 1,
2367
+ pageSize: config.defaultPageSize ?? 25,
2368
+ selection: []
2369
+ };
2370
+ }
2371
+ function listingQueryReducer(state, action) {
2372
+ if (action.type === "set-search") {
2373
+ return { ...state, search: action.value, page: 1, selection: [] };
2374
+ }
2375
+ if (action.type === "set-sort") {
2376
+ return { ...state, sort: action.value, page: 1, selection: [] };
2377
+ }
2378
+ if (action.type === "toggle-filter") {
2379
+ const exists = state.filters.includes(action.value);
2380
+ return {
2381
+ ...state,
2382
+ filters: exists ? state.filters.filter((item) => item !== action.value) : [...state.filters, action.value],
2383
+ page: 1,
2384
+ selection: []
2385
+ };
2386
+ }
2387
+ if (action.type === "clear-filters") {
2388
+ return { ...state, filters: [], page: 1, selection: [] };
2389
+ }
2390
+ if (action.type === "set-page") {
2391
+ return { ...state, page: Math.max(1, Math.floor(action.value)) };
2392
+ }
2393
+ if (action.type === "set-page-size") {
2394
+ const nextPageSize = Math.max(1, Math.floor(action.value));
2395
+ return { ...state, pageSize: nextPageSize, page: 1, selection: [] };
2396
+ }
2397
+ if (action.type === "toggle-selection") {
2398
+ const exists = state.selection.includes(action.value);
2399
+ return {
2400
+ ...state,
2401
+ selection: exists ? state.selection.filter((item) => item !== action.value) : [...state.selection, action.value]
2402
+ };
2403
+ }
2404
+ if (action.type === "clear-selection") {
2405
+ return { ...state, selection: [] };
2406
+ }
2407
+ return createInitialState({ defaultSort: state.sort, defaultPageSize: state.pageSize });
2408
+ }
2409
+ var ListingStateContext = (0, import_react5.createContext)(null);
2410
+ function ListingProvider({
2411
+ children,
2412
+ config
2413
+ }) {
2414
+ const [state, dispatch] = (0, import_react5.useReducer)(listingQueryReducer, config, createInitialState);
2415
+ const value = (0, import_react5.useMemo)(() => ({ state, dispatch }), [state]);
2416
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ListingStateContext.Provider, { value, children });
2417
+ }
2418
+ function useListingState() {
2419
+ const context = (0, import_react5.useContext)(ListingStateContext);
2420
+ if (!context) {
2421
+ throw new Error("useListingState must be used within ListingProvider.");
2422
+ }
2423
+ return context;
2424
+ }
2425
+
2035
2426
  // src/PublicShell.tsx
2036
- var import_core29 = require("@mantine/core");
2427
+ var import_core30 = require("@mantine/core");
2037
2428
 
2038
2429
  // src/PublicNav.tsx
2039
- var import_core28 = require("@mantine/core");
2040
- var import_jsx_runtime30 = require("react/jsx-runtime");
2430
+ var import_core29 = require("@mantine/core");
2431
+ var import_jsx_runtime33 = require("react/jsx-runtime");
2041
2432
  function PublicNav({ items, activeId, renderLink }) {
2042
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_core28.Group, { component: "nav", "aria-label": "Primary", gap: "lg", wrap: "nowrap", children: items.map((item) => {
2433
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core29.Group, { component: "nav", "aria-label": "Primary", gap: "lg", wrap: "nowrap", children: items.map((item) => {
2043
2434
  const active = item.id === activeId;
2044
2435
  if (renderLink) {
2045
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: renderLink(item, active) }, item.id);
2436
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { children: renderLink(item, active) }, item.id);
2046
2437
  }
2047
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
2048
- import_core28.Anchor,
2438
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2439
+ import_core29.Anchor,
2049
2440
  {
2050
2441
  href: item.href,
2051
2442
  "aria-current": active ? "page" : void 0,
@@ -2062,15 +2453,15 @@ function PublicNav({ items, activeId, renderLink }) {
2062
2453
  }
2063
2454
 
2064
2455
  // src/PublicShell.tsx
2065
- var import_jsx_runtime31 = require("react/jsx-runtime");
2456
+ var import_jsx_runtime34 = require("react/jsx-runtime");
2066
2457
  function InlineMobileNavigation({
2067
2458
  mobileNavigation,
2068
2459
  className,
2069
2460
  mode
2070
2461
  }) {
2071
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_core29.Box, { component: "details", hiddenFrom: "sm", className, children: [
2072
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
2073
- import_core29.Box,
2462
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_core30.Box, { component: "details", hiddenFrom: "sm", className, children: [
2463
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
2464
+ import_core30.Box,
2074
2465
  {
2075
2466
  component: "summary",
2076
2467
  "aria-label": mode === "drawer" ? "Open site navigation drawer" : "Open site navigation",
@@ -2082,13 +2473,13 @@ function InlineMobileNavigation({
2082
2473
  gap: "0.5rem"
2083
2474
  },
2084
2475
  children: [
2085
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.Burger, { opened: false, "aria-hidden": true }),
2086
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.Text, { size: "sm", fw: 600, children: "Menu" })
2476
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.Burger, { opened: false, "aria-hidden": true }),
2477
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.Text, { size: "sm", fw: 600, children: "Menu" })
2087
2478
  ]
2088
2479
  }
2089
2480
  ),
2090
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2091
- import_core29.Box,
2481
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2482
+ import_core30.Box,
2092
2483
  {
2093
2484
  mt: "sm",
2094
2485
  p: "sm",
@@ -2097,7 +2488,7 @@ function InlineMobileNavigation({
2097
2488
  border: "1px solid var(--mantine-color-default-border)",
2098
2489
  background: mode === "drawer" ? "light-dark(var(--mantine-color-white), color-mix(in srgb, var(--mantine-color-dark-7) 92%, black))" : "var(--mantine-color-body)"
2099
2490
  },
2100
- children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.Stack, { gap: "sm", children: mobileNavigation })
2491
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.Stack, { gap: "sm", children: mobileNavigation })
2101
2492
  }
2102
2493
  )
2103
2494
  ] });
@@ -2118,30 +2509,30 @@ function PublicShell({
2118
2509
  mobileNavigationMode = "sheet",
2119
2510
  classNames
2120
2511
  }) {
2121
- const resolvedNavigation = navigation ?? (navItems ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(PublicNav, { items: navItems, activeId: activeNavId }) : null);
2512
+ const resolvedNavigation = navigation ?? (navItems ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(PublicNav, { items: navItems, activeId: activeNavId }) : null);
2122
2513
  const containerSize = maxContentWidth ?? (compact ? "md" : "lg");
2123
2514
  const headerHeight = headerVariant === "compact" ? 64 : headerVariant === "branded-quiet" ? 88 : 72;
2124
2515
  const mainPadding = headerVariant === "compact" ? "lg" : "xl";
2125
2516
  const usesInlineMobileNavigation = Boolean(mobileNavigation) && mobileNavigationMode !== "sheet";
2126
2517
  const usesSheetMobileNavigation = Boolean(mobileNavigation) && mobileNavigationMode === "sheet";
2127
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
2128
- import_core29.AppShell,
2518
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
2519
+ import_core30.AppShell,
2129
2520
  {
2130
2521
  className: classNames?.root,
2131
2522
  header: { height: headerHeight },
2132
2523
  footer: usesSheetMobileNavigation ? { height: 68 } : void 0,
2133
2524
  padding: 0,
2134
2525
  children: [
2135
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.AppShell.Header, { withBorder: headerBordered, className: classNames?.header, "data-header-variant": headerVariant, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.Container, { size: containerSize, h: "100%", py: headerVariant === "branded-quiet" ? "sm" : 0, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
2136
- import_core29.Group,
2526
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.AppShell.Header, { withBorder: headerBordered, className: classNames?.header, "data-header-variant": headerVariant, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.Container, { size: containerSize, h: "100%", py: headerVariant === "branded-quiet" ? "sm" : 0, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
2527
+ import_core30.Group,
2137
2528
  {
2138
2529
  h: "100%",
2139
2530
  justify: "space-between",
2140
2531
  wrap: "nowrap",
2141
2532
  gap: headerVariant === "compact" ? "sm" : "lg",
2142
2533
  children: [
2143
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_core29.Group, { wrap: "nowrap", gap: headerVariant === "compact" ? "xs" : "sm", className: classNames?.brand, children: [
2144
- usesInlineMobileNavigation ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2534
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_core30.Group, { wrap: "nowrap", gap: headerVariant === "compact" ? "xs" : "sm", className: classNames?.brand, children: [
2535
+ usesInlineMobileNavigation ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2145
2536
  InlineMobileNavigation,
2146
2537
  {
2147
2538
  mobileNavigation,
@@ -2149,17 +2540,17 @@ function PublicShell({
2149
2540
  mode: mobileNavigationMode
2150
2541
  }
2151
2542
  ) : null,
2152
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.Box, { children: brand })
2543
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.Box, { children: brand })
2153
2544
  ] }),
2154
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.Group, { visibleFrom: "sm", gap: headerVariant === "compact" ? "md" : "lg", className: classNames?.navigation, children: resolvedNavigation }),
2155
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.Group, { gap: "sm", className: classNames?.actions, children: actions })
2545
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.Group, { visibleFrom: "sm", gap: headerVariant === "compact" ? "md" : "lg", className: classNames?.navigation, children: resolvedNavigation }),
2546
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.Group, { gap: "sm", className: classNames?.actions, children: actions })
2156
2547
  ]
2157
2548
  }
2158
2549
  ) }) }),
2159
- usesSheetMobileNavigation ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.AppShell.Footer, { withBorder: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.Container, { size: containerSize, h: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.Group, { h: "100%", justify: "space-around", wrap: "nowrap", children: mobileNavigation }) }) }) : null,
2160
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_core29.AppShell.Main, { children: [
2161
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.Container, { size: containerSize, py: mainPadding, className: classNames?.content, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.Stack, { gap: "xl", children }) }),
2162
- footer ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.Box, { component: typeof footer === "string" ? "footer" : "div", py: "xl", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.Container, { size: containerSize, children: typeof footer === "string" ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core29.Text, { size: "sm", c: "dimmed", children: footer }) : footer }) }) : null
2550
+ usesSheetMobileNavigation ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.AppShell.Footer, { withBorder: true, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.Container, { size: containerSize, h: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.Group, { h: "100%", justify: "space-around", wrap: "nowrap", children: mobileNavigation }) }) }) : null,
2551
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_core30.AppShell.Main, { children: [
2552
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.Container, { size: containerSize, py: mainPadding, className: classNames?.content, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.Stack, { gap: "xl", children }) }),
2553
+ footer ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.Box, { component: typeof footer === "string" ? "footer" : "div", py: "xl", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.Container, { size: containerSize, children: typeof footer === "string" ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core30.Text, { size: "sm", c: "dimmed", children: footer }) : footer }) }) : null
2163
2554
  ] })
2164
2555
  ]
2165
2556
  }
@@ -2167,9 +2558,49 @@ function PublicShell({
2167
2558
  }
2168
2559
 
2169
2560
  // src/DiscoveryShell.tsx
2170
- var import_core30 = require("@mantine/core");
2561
+ var import_react6 = require("react");
2562
+ var import_core31 = require("@mantine/core");
2171
2563
  var import_hooks2 = require("@mantine/hooks");
2172
- var import_jsx_runtime32 = require("react/jsx-runtime");
2564
+ var import_jsx_runtime35 = require("react/jsx-runtime");
2565
+ function useDiscoveryShellState({
2566
+ defaultSidebarOpen = false,
2567
+ sidebarStorageKey,
2568
+ onSidebarOpenedChange
2569
+ } = {}) {
2570
+ const [opened, setOpenedState] = (0, import_react6.useState)(defaultSidebarOpen);
2571
+ (0, import_react6.useEffect)(() => {
2572
+ if (!sidebarStorageKey || typeof window === "undefined") {
2573
+ return;
2574
+ }
2575
+ const stored = window.localStorage.getItem(sidebarStorageKey);
2576
+ if (stored === "open") {
2577
+ setOpenedState(true);
2578
+ }
2579
+ if (stored === "closed") {
2580
+ setOpenedState(false);
2581
+ }
2582
+ }, [sidebarStorageKey]);
2583
+ const persistAndNotify = (next) => {
2584
+ if (sidebarStorageKey && typeof window !== "undefined") {
2585
+ window.localStorage.setItem(sidebarStorageKey, next ? "open" : "closed");
2586
+ }
2587
+ onSidebarOpenedChange?.(next);
2588
+ };
2589
+ const setOpened = (next) => {
2590
+ setOpenedState(next);
2591
+ persistAndNotify(next);
2592
+ };
2593
+ const open = () => setOpened(true);
2594
+ const close = () => setOpened(false);
2595
+ const toggle = () => {
2596
+ setOpenedState((current) => {
2597
+ const next = !current;
2598
+ persistAndNotify(next);
2599
+ return next;
2600
+ });
2601
+ };
2602
+ return { opened, open, close, toggle, setOpened };
2603
+ }
2173
2604
  function DiscoveryShell({
2174
2605
  header,
2175
2606
  sidebar,
@@ -2177,28 +2608,47 @@ function DiscoveryShell({
2177
2608
  children,
2178
2609
  mobileNavigationLabel = "Toggle navigation",
2179
2610
  defaultSidebarOpen = false,
2611
+ sidebarStorageKey,
2612
+ sidebarOpened,
2613
+ onSidebarOpenedChange,
2180
2614
  stickySidebar = true,
2615
+ desktopCollapsible = false,
2616
+ desktopNavigationLabel = "Toggle sidebar",
2181
2617
  sidebarWidth = 280,
2182
2618
  headerHeight = 60,
2183
2619
  shellPadding = "md",
2184
2620
  collapseBreakpoint = "sm"
2185
2621
  }) {
2186
- const [opened, { toggle, close }] = (0, import_hooks2.useDisclosure)(defaultSidebarOpen);
2187
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
2188
- import_core30.AppShell,
2622
+ const breakpointByAlias = {
2623
+ xs: "36em",
2624
+ sm: "48em",
2625
+ md: "62em",
2626
+ lg: "75em",
2627
+ xl: "88em"
2628
+ };
2629
+ const isMobile = (0, import_hooks2.useMediaQuery)(`(max-width: ${breakpointByAlias[collapseBreakpoint]})`);
2630
+ const shellState = useDiscoveryShellState({ defaultSidebarOpen, sidebarStorageKey, onSidebarOpenedChange });
2631
+ const opened = sidebarOpened ?? shellState.opened;
2632
+ const close = onSidebarOpenedChange ? () => onSidebarOpenedChange(false) : shellState.close;
2633
+ const toggle = onSidebarOpenedChange ? () => onSidebarOpenedChange(!opened) : shellState.toggle;
2634
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
2635
+ import_core31.AppShell,
2189
2636
  {
2190
2637
  header: { height: headerHeight },
2191
2638
  footer: footer ? { height: 68 } : void 0,
2192
2639
  navbar: {
2193
2640
  width: sidebarWidth,
2194
2641
  breakpoint: collapseBreakpoint,
2195
- collapsed: { mobile: !opened }
2642
+ collapsed: {
2643
+ mobile: !opened,
2644
+ desktop: desktopCollapsible ? !opened : false
2645
+ }
2196
2646
  },
2197
2647
  padding: shellPadding,
2198
2648
  children: [
2199
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core30.AppShell.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_core30.Group, { h: "100%", px: "md", gap: "sm", wrap: "nowrap", children: [
2200
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2201
- import_core30.Burger,
2649
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_core31.AppShell.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_core31.Group, { h: "100%", px: "md", gap: "sm", wrap: "nowrap", children: [
2650
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
2651
+ import_core31.Burger,
2202
2652
  {
2203
2653
  opened,
2204
2654
  onClick: toggle,
@@ -2207,10 +2657,20 @@ function DiscoveryShell({
2207
2657
  "aria-label": mobileNavigationLabel
2208
2658
  }
2209
2659
  ),
2210
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core30.Box, { style: { flex: 1, minWidth: 0 }, children: header })
2660
+ desktopCollapsible ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
2661
+ import_core31.Burger,
2662
+ {
2663
+ opened,
2664
+ onClick: toggle,
2665
+ visibleFrom: collapseBreakpoint,
2666
+ size: "sm",
2667
+ "aria-label": desktopNavigationLabel
2668
+ }
2669
+ ) : null,
2670
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_core31.Box, { style: { flex: 1, minWidth: 0 }, children: header })
2211
2671
  ] }) }),
2212
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core30.AppShell.Navbar, { p: "md", "data-sticky-sidebar": stickySidebar || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core30.ScrollArea, { h: "100%", type: "auto", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2213
- import_core30.Box,
2672
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_core31.AppShell.Navbar, { p: "md", "data-sticky-sidebar": stickySidebar || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_core31.ScrollArea, { h: "100%", type: "auto", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
2673
+ import_core31.Box,
2214
2674
  {
2215
2675
  h: "100%",
2216
2676
  style: stickySidebar ? {
@@ -2220,27 +2680,37 @@ function DiscoveryShell({
2220
2680
  children: sidebar
2221
2681
  }
2222
2682
  ) }) }),
2223
- footer ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core30.AppShell.Footer, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core30.Group, { h: "100%", px: "md", justify: "space-around", wrap: "nowrap", children: footer }) }) : null,
2224
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core30.AppShell.Main, { onClick: () => close(), children })
2683
+ footer ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_core31.AppShell.Footer, { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_core31.Group, { h: "100%", px: "md", justify: "space-around", wrap: "nowrap", children: footer }) }) : null,
2684
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
2685
+ import_core31.AppShell.Main,
2686
+ {
2687
+ onClick: () => {
2688
+ if (isMobile) {
2689
+ close();
2690
+ }
2691
+ },
2692
+ children
2693
+ }
2694
+ )
2225
2695
  ]
2226
2696
  }
2227
2697
  );
2228
2698
  }
2229
2699
 
2230
2700
  // src/DocsShell.tsx
2231
- var import_react5 = require("react");
2232
- var import_core31 = require("@mantine/core");
2233
- var import_jsx_runtime33 = require("react/jsx-runtime");
2701
+ var import_react7 = require("react");
2702
+ var import_core32 = require("@mantine/core");
2703
+ var import_jsx_runtime36 = require("react/jsx-runtime");
2234
2704
  function DocsShellSidebar({ primaryNavigation, secondaryNavigation }) {
2235
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_core31.Stack, { gap: "md", h: "100%", children: [
2236
- primaryNavigation ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_core31.Stack, { gap: "xs", children: [
2237
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core31.Text, { size: "xs", fw: 700, c: "dimmed", children: "Primary" }),
2705
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_core32.Stack, { gap: "md", h: "100%", children: [
2706
+ primaryNavigation ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_core32.Stack, { gap: "xs", children: [
2707
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core32.Text, { size: "xs", fw: 700, c: "dimmed", children: "Primary" }),
2238
2708
  primaryNavigation
2239
2709
  ] }) : null,
2240
- secondaryNavigation ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
2241
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core31.Divider, {}),
2242
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_core31.Stack, { gap: "xs", children: [
2243
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core31.Text, { size: "xs", fw: 700, c: "dimmed", children: "More" }),
2710
+ secondaryNavigation ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
2711
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core32.Divider, {}),
2712
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_core32.Stack, { gap: "xs", children: [
2713
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core32.Text, { size: "xs", fw: 700, c: "dimmed", children: "More" }),
2244
2714
  secondaryNavigation
2245
2715
  ] })
2246
2716
  ] }) : null
@@ -2264,15 +2734,15 @@ function DocsShell({
2264
2734
  children,
2265
2735
  contentWidth = "full"
2266
2736
  }) {
2267
- const [mobileNavOpen, setMobileNavOpen] = (0, import_react5.useState)(false);
2268
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2737
+ const [mobileNavOpen, setMobileNavOpen] = (0, import_react7.useState)(false);
2738
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2269
2739
  DiscoveryShell,
2270
2740
  {
2271
- header: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_core31.Group, { h: "100%", justify: "space-between", align: "center", wrap: "nowrap", gap: "md", children: [
2272
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_core31.Group, { gap: "sm", align: "center", wrap: "nowrap", style: { minWidth: 0 }, children: [
2273
- mobileNavigationMode === "inline-collapse" && mobileNavigation ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
2274
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2275
- import_core31.Burger,
2741
+ header: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_core32.Group, { h: "100%", justify: "space-between", align: "center", wrap: "nowrap", gap: "md", children: [
2742
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_core32.Group, { gap: "sm", align: "center", wrap: "nowrap", style: { minWidth: 0 }, children: [
2743
+ mobileNavigationMode === "inline-collapse" && mobileNavigation ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
2744
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2745
+ import_core32.Burger,
2276
2746
  {
2277
2747
  opened: mobileNavOpen,
2278
2748
  onClick: () => setMobileNavOpen((value) => !value),
@@ -2281,14 +2751,14 @@ function DocsShell({
2281
2751
  "aria-label": "Toggle docs navigation"
2282
2752
  }
2283
2753
  ),
2284
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core31.Transition, { mounted: mobileNavOpen, transition: "pop", duration: 120, children: (styles) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core31.Box, { style: styles, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core31.Box, { mt: "xs", p: "sm", style: { borderRadius: 8, border: "1px solid var(--mantine-color-default-border)" }, children: mobileNavigation }) }) })
2754
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core32.Transition, { mounted: mobileNavOpen, transition: "pop", duration: 120, children: (styles) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core32.Box, { style: styles, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core32.Box, { mt: "xs", p: "sm", style: { borderRadius: 8, border: "1px solid var(--mantine-color-default-border)" }, children: mobileNavigation }) }) })
2285
2755
  ] }) : null,
2286
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core31.Box, { style: { minWidth: 0 }, children: brand }),
2287
- headerContext ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core31.Text, { size: "sm", c: "dimmed", lineClamp: 1, children: headerContext }) : null
2756
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core32.Box, { style: { minWidth: 0 }, children: brand }),
2757
+ headerContext ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core32.Text, { size: "sm", c: "dimmed", lineClamp: 1, children: headerContext }) : null
2288
2758
  ] }),
2289
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core31.Group, { gap: "sm", wrap: "nowrap", style: { minWidth: 0 }, children: actions })
2759
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core32.Group, { gap: "sm", wrap: "nowrap", style: { minWidth: 0 }, children: actions })
2290
2760
  ] }),
2291
- sidebar: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2761
+ sidebar: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2292
2762
  DocsShellSidebar,
2293
2763
  {
2294
2764
  primaryNavigation,
@@ -2298,26 +2768,26 @@ function DocsShell({
2298
2768
  footer,
2299
2769
  mobileNavigationLabel: "Open docs navigation",
2300
2770
  headerHeight: 72,
2301
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core31.Container, { size: resolveContentContainerSize(contentWidth), px: "md", py: "lg", w: "100%", children })
2771
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core32.Container, { size: resolveContentContainerSize(contentWidth), px: "md", py: "lg", w: "100%", children })
2302
2772
  }
2303
2773
  );
2304
2774
  }
2305
2775
 
2306
2776
  // src/SidebarNav.tsx
2307
- var import_react6 = require("react");
2308
- var import_core32 = require("@mantine/core");
2777
+ var import_react8 = require("react");
2778
+ var import_core33 = require("@mantine/core");
2309
2779
  var import_gds_theme4 = require("@doneisbetter/gds-theme");
2310
- var import_jsx_runtime34 = require("react/jsx-runtime");
2780
+ var import_jsx_runtime37 = require("react/jsx-runtime");
2311
2781
  function SidebarNav({ children, ariaLabel = "Primary navigation", gap = "md" }) {
2312
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core32.Stack, { component: "nav", "aria-label": ariaLabel, gap, h: "100%", children });
2782
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core33.Stack, { component: "nav", "aria-label": ariaLabel, gap, h: "100%", children });
2313
2783
  }
2314
2784
  function SidebarNavSection({ label, children, pushToBottom = false }) {
2315
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_core32.Stack, { gap: "xs", mt: pushToBottom ? "auto" : void 0, children: [
2316
- label ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core32.Text, { size: "xs", fw: 700, c: "dimmed", children: label }) : null,
2317
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core32.Stack, { gap: 4, children })
2785
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_core33.Stack, { gap: "xs", mt: pushToBottom ? "auto" : void 0, children: [
2786
+ label ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core33.Text, { size: "xs", fw: 700, c: "dimmed", children: label }) : null,
2787
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core33.Stack, { gap: 4, children })
2318
2788
  ] });
2319
2789
  }
2320
- var _SidebarNavItem = (0, import_react6.forwardRef)(
2790
+ var _SidebarNavItem = (0, import_react8.forwardRef)(
2321
2791
  ({
2322
2792
  action,
2323
2793
  label,
@@ -2333,14 +2803,14 @@ var _SidebarNavItem = (0, import_react6.forwardRef)(
2333
2803
  const config = action ? resolveSemanticActionConfig(action, vocabularyPacks) : null;
2334
2804
  const Icon = config?.icon;
2335
2805
  const resolvedLabel = label ?? (action ? getSemanticActionLabel(action, t, vocabularyPacks) : void 0);
2336
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2337
- import_core32.NavLink,
2806
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2807
+ import_core33.NavLink,
2338
2808
  {
2339
2809
  ref,
2340
2810
  label: resolvedLabel,
2341
2811
  description,
2342
- leftSection: icon ?? (Icon ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Icon, { size: "1rem", stroke: 1.5 }) : void 0),
2343
- rightSection: badge ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_core32.Box, { children: badge }) : props.rightSection,
2812
+ leftSection: icon ?? (Icon ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Icon, { size: "1rem", stroke: 1.5 }) : void 0),
2813
+ rightSection: badge ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core33.Box, { children: badge }) : props.rightSection,
2344
2814
  "aria-label": ariaLabel ?? (typeof resolvedLabel === "string" ? resolvedLabel : void 0),
2345
2815
  "aria-current": props.active ? "page" : ariaCurrent,
2346
2816
  ...props
@@ -2348,21 +2818,21 @@ var _SidebarNavItem = (0, import_react6.forwardRef)(
2348
2818
  );
2349
2819
  }
2350
2820
  );
2351
- var SidebarNavItem = (0, import_core32.createPolymorphicComponent)(_SidebarNavItem);
2821
+ var SidebarNavItem = (0, import_core33.createPolymorphicComponent)(_SidebarNavItem);
2352
2822
 
2353
2823
  // src/PublicSiteFooter.tsx
2354
- var import_core33 = require("@mantine/core");
2355
- var import_jsx_runtime35 = require("react/jsx-runtime");
2824
+ var import_core34 = require("@mantine/core");
2825
+ var import_jsx_runtime38 = require("react/jsx-runtime");
2356
2826
  function PublicSiteFooter({ children, meta }) {
2357
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_core33.Stack, { component: "footer", gap: "xs", children: [
2358
- children ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_core33.Text, { size: "sm", children }) : null,
2359
- meta ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_core33.Group, { gap: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_core33.Text, { size: "xs", c: "dimmed", children: meta }) }) : null
2827
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_core34.Stack, { component: "footer", gap: "xs", children: [
2828
+ children ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core34.Text, { size: "sm", children }) : null,
2829
+ meta ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core34.Group, { gap: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core34.Text, { size: "xs", c: "dimmed", children: meta }) }) : null
2360
2830
  ] });
2361
2831
  }
2362
2832
 
2363
2833
  // src/PublicBrandFooter.tsx
2364
- var import_core34 = require("@mantine/core");
2365
- var import_jsx_runtime36 = require("react/jsx-runtime");
2834
+ var import_core35 = require("@mantine/core");
2835
+ var import_jsx_runtime39 = require("react/jsx-runtime");
2366
2836
  function PublicBrandFooter({
2367
2837
  media,
2368
2838
  brandTitle,
@@ -2377,8 +2847,8 @@ function PublicBrandFooter({
2377
2847
  const mediaSpan = layoutVariant === "immersive-media" ? 5 : 4;
2378
2848
  const primarySpan = media ? layoutVariant === "balanced-quote" ? 4 : 4 : secondary ? 6 : 12;
2379
2849
  const secondarySpan = media ? Math.max(3, 12 - mediaSpan - primarySpan) : Math.max(4, 12 - primarySpan);
2380
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2381
- import_core34.Paper,
2850
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2851
+ import_core35.Paper,
2382
2852
  {
2383
2853
  component: "footer",
2384
2854
  withBorder: true,
@@ -2386,19 +2856,19 @@ function PublicBrandFooter({
2386
2856
  p: compact ? "lg" : "xl",
2387
2857
  className: classNames?.root,
2388
2858
  "data-layout-variant": layoutVariant,
2389
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_core34.Stack, { gap: "lg", children: [
2390
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_core34.Grid, { gutter: compact ? "lg" : "xl", align: "flex-start", children: [
2391
- media ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core34.Grid.Col, { span: { base: 12, md: mediaSpan }, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core34.Box, { className: classNames?.media, children: media }) }) : null,
2392
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core34.Grid.Col, { span: { base: 12, md: primarySpan }, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_core34.Stack, { gap: compact ? "xs" : "sm", className: classNames?.primary, children: [
2393
- brandTitle ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core34.Title, { order: 4, children: brandTitle }) : null,
2394
- description ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core34.Text, { c: "dimmed", children: description }) : null,
2395
- actions ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core34.Box, { children: actions }) : null
2859
+ children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_core35.Stack, { gap: "lg", children: [
2860
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_core35.Grid, { gutter: compact ? "lg" : "xl", align: "flex-start", children: [
2861
+ media ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core35.Grid.Col, { span: { base: 12, md: mediaSpan }, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core35.Box, { className: classNames?.media, children: media }) }) : null,
2862
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core35.Grid.Col, { span: { base: 12, md: primarySpan }, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_core35.Stack, { gap: compact ? "xs" : "sm", className: classNames?.primary, children: [
2863
+ brandTitle ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core35.Title, { order: 4, children: brandTitle }) : null,
2864
+ description ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core35.Text, { c: "dimmed", children: description }) : null,
2865
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core35.Box, { children: actions }) : null
2396
2866
  ] }) }),
2397
- secondary ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core34.Grid.Col, { span: { base: 12, md: secondarySpan }, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core34.Stack, { gap: compact ? "xs" : "sm", className: classNames?.secondary, children: secondary }) }) : null
2867
+ secondary ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core35.Grid.Col, { span: { base: 12, md: secondarySpan }, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core35.Stack, { gap: compact ? "xs" : "sm", className: classNames?.secondary, children: secondary }) }) : null
2398
2868
  ] }),
2399
- legal ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
2400
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core34.Divider, {}),
2401
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core34.Group, { justify: "space-between", gap: "sm", wrap: "wrap", className: classNames?.legal, children: typeof legal === "string" ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_core34.Text, { size: "sm", c: "dimmed", children: legal }) : legal })
2869
+ legal ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
2870
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core35.Divider, {}),
2871
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core35.Group, { justify: "space-between", gap: "sm", wrap: "wrap", className: classNames?.legal, children: typeof legal === "string" ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core35.Text, { size: "sm", c: "dimmed", children: legal }) : legal })
2402
2872
  ] }) : null
2403
2873
  ] })
2404
2874
  }
@@ -2406,44 +2876,54 @@ function PublicBrandFooter({
2406
2876
  }
2407
2877
 
2408
2878
  // src/AuthShell.tsx
2409
- var import_core35 = require("@mantine/core");
2410
- var import_jsx_runtime37 = require("react/jsx-runtime");
2879
+ var import_core36 = require("@mantine/core");
2880
+ var import_jsx_runtime40 = require("react/jsx-runtime");
2411
2881
  function AuthShell({
2412
2882
  title,
2413
2883
  description,
2884
+ intent = "sign-in",
2414
2885
  brand,
2415
2886
  headerActions,
2416
2887
  footer,
2417
2888
  helper,
2889
+ error,
2890
+ guestAction,
2891
+ supportAction,
2418
2892
  socialAuth,
2419
2893
  dividerLabel = "Or continue with your account",
2420
2894
  children
2421
2895
  }) {
2422
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core35.Box, { py: { base: "xl", md: "4rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core35.Container, { size: "xs", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_core35.Stack, { gap: "xl", children: [
2423
- brand || headerActions ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_core35.Group, { justify: brand && headerActions ? "space-between" : "center", align: "center", children: [
2424
- brand ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core35.Box, { children: brand }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core35.Box, {}),
2425
- headerActions ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core35.Group, { gap: "sm", children: headerActions }) : null
2896
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core36.Box, { py: { base: "xl", md: "4rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core36.Container, { size: "xs", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_core36.Stack, { gap: "xl", children: [
2897
+ brand || headerActions ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_core36.Group, { justify: brand && headerActions ? "space-between" : "center", align: "center", children: [
2898
+ brand ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core36.Box, { children: brand }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core36.Box, {}),
2899
+ headerActions ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core36.Group, { gap: "sm", children: headerActions }) : null
2426
2900
  ] }) : null,
2427
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core35.Card, { withBorder: true, radius: "lg", padding: "xl", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_core35.Stack, { gap: "lg", children: [
2428
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_core35.Stack, { gap: "xs", ta: "center", children: [
2429
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core35.Title, { order: 2, children: title }),
2430
- description ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core35.Text, { c: "dimmed", size: "sm", children: description }) : null
2901
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core36.Card, { withBorder: true, radius: "lg", padding: "xl", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_core36.Stack, { gap: "lg", children: [
2902
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_core36.Stack, { gap: "xs", ta: "center", children: [
2903
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core36.Group, { justify: "center", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core36.Badge, { variant: "light", color: intent === "account-linking" ? "blue" : intent === "guest-entry" ? "gray" : "teal", children: intent.replace("-", " ") }) }),
2904
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core36.Title, { order: 2, children: title }),
2905
+ description ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core36.Text, { c: "dimmed", size: "sm", children: description }) : null
2431
2906
  ] }),
2432
- socialAuth ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core35.Box, { children: socialAuth }) : null,
2433
- socialAuth ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core35.Divider, { label: dividerLabel, labelPosition: "center" }) : null,
2907
+ error ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core36.Alert, { color: "red", variant: "light", role: "alert", children: error }) : null,
2908
+ socialAuth ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core36.Box, { children: socialAuth }) : null,
2909
+ socialAuth ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core36.Divider, { label: dividerLabel, labelPosition: "center" }) : null,
2434
2910
  children,
2435
- helper ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core35.Text, { size: "sm", c: "dimmed", ta: "center", children: helper }) : null
2911
+ guestAction || supportAction ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_core36.Group, { justify: "center", gap: "sm", children: [
2912
+ guestAction,
2913
+ supportAction
2914
+ ] }) : null,
2915
+ helper ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core36.Text, { size: "sm", c: "dimmed", ta: "center", children: helper }) : null
2436
2916
  ] }) }),
2437
- footer ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core35.Text, { size: "sm", c: "dimmed", ta: "center", children: footer }) : null
2917
+ footer ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core36.Text, { size: "sm", c: "dimmed", ta: "center", children: footer }) : null
2438
2918
  ] }) }) });
2439
2919
  }
2440
2920
 
2441
2921
  // src/SocialAuthButtons.tsx
2442
- var import_core37 = require("@mantine/core");
2922
+ var import_core38 = require("@mantine/core");
2443
2923
 
2444
2924
  // src/ProviderIdentityButtons.tsx
2445
- var import_core36 = require("@mantine/core");
2446
- var import_jsx_runtime38 = require("react/jsx-runtime");
2925
+ var import_core37 = require("@mantine/core");
2926
+ var import_jsx_runtime41 = require("react/jsx-runtime");
2447
2927
  var PROVIDER_IDENTITY_REGISTRY = {
2448
2928
  google: {
2449
2929
  providerLabel: "Google",
@@ -2533,17 +3013,31 @@ function mapVariant(variant = "neutral") {
2533
3013
  function getProviderIdentityLabel(provider, fallbackOverride) {
2534
3014
  return resolveProviderLabel(provider, fallbackOverride);
2535
3015
  }
3016
+ function getSupportedProviderIdentityIds() {
3017
+ return Object.keys(PROVIDER_IDENTITY_REGISTRY);
3018
+ }
3019
+ function getProviderIdentityPolicy(provider) {
3020
+ const meta = getProviderIdentityMeta(provider);
3021
+ return {
3022
+ id: meta.id,
3023
+ supported: meta.supported,
3024
+ providerLabel: meta.providerLabel,
3025
+ colorAuthority: meta.supported ? "provider" : "gds-neutral",
3026
+ minTouchTargetPx: 44,
3027
+ allowedVariants: ["solid", "outline", "neutral"]
3028
+ };
3029
+ }
2536
3030
  function ProviderIdentityMark({ provider }) {
2537
3031
  const meta = getProviderIdentityMeta(provider);
2538
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2539
- import_core36.ThemeIcon,
3032
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3033
+ import_core37.ThemeIcon,
2540
3034
  {
2541
3035
  variant: "light",
2542
3036
  color: meta.brandColor,
2543
3037
  radius: "xl",
2544
3038
  size: "md",
2545
3039
  "aria-hidden": "true",
2546
- children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core36.Text, { size: "xs", fw: 700, c: "inherit", children: meta.markLabel })
3040
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core37.Text, { size: "xs", fw: 700, c: "inherit", children: meta.markLabel })
2547
3041
  }
2548
3042
  );
2549
3043
  }
@@ -2551,10 +3045,13 @@ function ProviderIdentityButton({
2551
3045
  provider,
2552
3046
  label,
2553
3047
  description,
3048
+ policyNote,
3049
+ error,
2554
3050
  href,
2555
3051
  onClick,
2556
3052
  disabled,
2557
3053
  loading,
3054
+ tenantDisabledReason,
2558
3055
  fullWidth = true,
2559
3056
  size = "md",
2560
3057
  variant = "neutral",
@@ -2564,14 +3061,15 @@ function ProviderIdentityButton({
2564
3061
  }) {
2565
3062
  const meta = getProviderIdentityMeta(provider);
2566
3063
  const buttonLabel = resolveProviderLabel(provider, label);
3064
+ const resolvedDisabled = disabled || Boolean(tenantDisabledReason);
2567
3065
  const buttonProps = href ? {
2568
3066
  component: "a",
2569
3067
  href
2570
3068
  } : {
2571
3069
  onClick
2572
3070
  };
2573
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2574
- import_core36.Button,
3071
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3072
+ import_core37.Button,
2575
3073
  {
2576
3074
  variant: mapVariant(variant),
2577
3075
  color: variant === "solid" ? meta.brandColor : void 0,
@@ -2580,14 +3078,17 @@ function ProviderIdentityButton({
2580
3078
  size,
2581
3079
  "aria-label": ariaLabel ?? (typeof buttonLabel === "string" ? buttonLabel : void 0),
2582
3080
  "aria-describedby": describedBy,
2583
- leftSection: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ProviderIdentityMark, { provider }),
2584
- disabled,
3081
+ leftSection: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(ProviderIdentityMark, { provider }),
3082
+ disabled: resolvedDisabled,
2585
3083
  loading,
2586
3084
  styles: { root: { minHeight: minTouchTargetPx } },
2587
3085
  ...buttonProps,
2588
- children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_core36.Stack, { gap: 0, align: "flex-start", children: [
2589
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core36.Text, { inherit: true, children: buttonLabel }),
2590
- description ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core36.Text, { size: "xs", c: "dimmed", lh: 1.2, children: description }) : null
3086
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_core37.Stack, { gap: 0, align: "flex-start", children: [
3087
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core37.Text, { inherit: true, children: buttonLabel }),
3088
+ description ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core37.Text, { size: "xs", c: "dimmed", lh: 1.2, children: description }) : null,
3089
+ policyNote ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core37.Text, { size: "xs", c: "dimmed", lh: 1.2, children: policyNote }) : null,
3090
+ tenantDisabledReason ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core37.Text, { size: "xs", c: "orange.7", lh: 1.2, children: tenantDisabledReason }) : null,
3091
+ error ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core37.Text, { size: "xs", c: "red.7", lh: 1.2, role: "alert", children: error }) : null
2591
3092
  ] })
2592
3093
  }
2593
3094
  );
@@ -2598,16 +3099,16 @@ function ProviderIdentityButtonGroup({ providers, layout = "stack" }) {
2598
3099
  }
2599
3100
  const content = providers.map((entry, index) => {
2600
3101
  const key = `${normalizeProviderId(String(entry.provider)) || "provider"}-${index}`;
2601
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ProviderIdentityButton, { ...entry }, key);
3102
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(ProviderIdentityButton, { ...entry }, key);
2602
3103
  });
2603
3104
  if (layout === "grid") {
2604
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core36.SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: content });
3105
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core37.SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: content });
2605
3106
  }
2606
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core36.Stack, { gap: "sm", children: content });
3107
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core37.Stack, { gap: "sm", children: content });
2607
3108
  }
2608
3109
 
2609
3110
  // src/SocialAuthButtons.tsx
2610
- var import_jsx_runtime39 = require("react/jsx-runtime");
3111
+ var import_jsx_runtime42 = require("react/jsx-runtime");
2611
3112
  function SocialAuthButtons({
2612
3113
  providers,
2613
3114
  title = "Continue with a trusted provider",
@@ -2622,50 +3123,53 @@ function SocialAuthButtons({
2622
3123
  provider: provider.id,
2623
3124
  label: provider.label,
2624
3125
  description: provider.description,
3126
+ policyNote: provider.policyNote,
3127
+ error: provider.error,
2625
3128
  href: provider.href,
2626
3129
  onClick: provider.onClick,
2627
3130
  disabled: provider.disabled,
2628
3131
  loading: provider.loading,
3132
+ tenantDisabledReason: provider.tenantDisabledReason,
2629
3133
  size: provider.size ?? (compact ? "sm" : "md"),
2630
3134
  variant: provider.variant
2631
3135
  }));
2632
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_core37.Stack, { gap: "md", children: [
2633
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_core37.Stack, { gap: 4, ta: "center", children: [
2634
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_core37.Group, { justify: "center", gap: "xs", children: [
2635
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(GdsIcons.Login, { size: "1rem" }),
2636
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core37.Text, { fw: 600, children: title })
3136
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_core38.Stack, { gap: "md", children: [
3137
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_core38.Stack, { gap: 4, ta: "center", children: [
3138
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_core38.Group, { justify: "center", gap: "xs", children: [
3139
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(GdsIcons.Login, { size: "1rem" }),
3140
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_core38.Text, { fw: 600, children: title })
2637
3141
  ] }),
2638
- description ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core37.Text, { size: "sm", c: "dimmed", children: description }) : null
3142
+ description ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_core38.Text, { size: "sm", c: "dimmed", children: description }) : null
2639
3143
  ] }),
2640
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core37.Divider, {}),
2641
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ProviderIdentityButtonGroup, { providers: buttons, layout })
3144
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_core38.Divider, {}),
3145
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ProviderIdentityButtonGroup, { providers: buttons, layout })
2642
3146
  ] });
2643
3147
  }
2644
3148
 
2645
3149
  // src/ArticleShell.tsx
2646
- var import_core38 = require("@mantine/core");
2647
- var import_jsx_runtime40 = require("react/jsx-runtime");
3150
+ var import_core39 = require("@mantine/core");
3151
+ var import_jsx_runtime43 = require("react/jsx-runtime");
2648
3152
  function ArticleShell({ eyebrow, title, lead, meta, sideRail, children }) {
2649
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Container, { size: "lg", py: "xl", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_core38.Group, { align: "flex-start", gap: "xl", wrap: "nowrap", children: [
2650
- /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_core38.Stack, { gap: "lg", maw: 760, flex: 1, children: [
2651
- /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_core38.Stack, { gap: "sm", children: [
2652
- eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Text, { size: "sm", fw: 700, c: "dimmed", tt: "uppercase", children: eyebrow }) : null,
2653
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Title, { order: 1, children: title }),
2654
- lead ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Text, { size: "lg", c: "dimmed", children: lead }) : null,
2655
- meta ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Group, { gap: "md", children: meta }) : null
3153
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core39.Container, { size: "lg", py: "xl", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_core39.Group, { align: "flex-start", gap: "xl", wrap: "nowrap", children: [
3154
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_core39.Stack, { gap: "lg", maw: 760, flex: 1, children: [
3155
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_core39.Stack, { gap: "sm", children: [
3156
+ eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core39.Text, { size: "sm", fw: 700, c: "dimmed", tt: "uppercase", children: eyebrow }) : null,
3157
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core39.Title, { order: 1, children: title }),
3158
+ lead ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core39.Text, { size: "lg", c: "dimmed", children: lead }) : null,
3159
+ meta ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core39.Group, { gap: "md", children: meta }) : null
2656
3160
  ] }),
2657
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Stack, { gap: "md", children })
3161
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core39.Stack, { gap: "md", children })
2658
3162
  ] }),
2659
- sideRail ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Stack, { visibleFrom: "lg", gap: "md", w: 240, children: sideRail }) : null
3163
+ sideRail ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core39.Stack, { visibleFrom: "lg", gap: "md", w: 240, children: sideRail }) : null
2660
3164
  ] }) });
2661
3165
  }
2662
3166
 
2663
3167
  // src/DocsCodeBlock.tsx
2664
- var import_react7 = require("react");
2665
- var import_core39 = require("@mantine/core");
2666
- var import_jsx_runtime41 = require("react/jsx-runtime");
3168
+ var import_react9 = require("react");
3169
+ var import_core40 = require("@mantine/core");
3170
+ var import_jsx_runtime44 = require("react/jsx-runtime");
2667
3171
  function DocsCodeBlock({ code, language, title, withCopy = true }) {
2668
- const [copied, setCopied] = (0, import_react7.useState)(false);
3172
+ const [copied, setCopied] = (0, import_react9.useState)(false);
2669
3173
  const handleCopy = async () => {
2670
3174
  if (!navigator?.clipboard) {
2671
3175
  return;
@@ -2674,44 +3178,44 @@ function DocsCodeBlock({ code, language, title, withCopy = true }) {
2674
3178
  setCopied(true);
2675
3179
  window.setTimeout(() => setCopied(false), 1200);
2676
3180
  };
2677
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core39.Paper, { withBorder: true, radius: "lg", p: "md", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_core39.Stack, { gap: "sm", children: [
2678
- title || withCopy ? /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_core39.Group, { justify: "space-between", align: "center", children: [
2679
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_core39.Stack, { gap: 0, children: [
2680
- title ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core39.Text, { fw: 600, children: title }) : null,
2681
- language ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core39.Text, { size: "xs", c: "dimmed", children: language }) : null
3181
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core40.Paper, { withBorder: true, radius: "lg", p: "md", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_core40.Stack, { gap: "sm", children: [
3182
+ title || withCopy ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_core40.Group, { justify: "space-between", align: "center", children: [
3183
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_core40.Stack, { gap: 0, children: [
3184
+ title ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core40.Text, { fw: 600, children: title }) : null,
3185
+ language ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core40.Text, { size: "xs", c: "dimmed", children: language }) : null
2682
3186
  ] }),
2683
- withCopy ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2684
- import_core39.ActionIcon,
3187
+ withCopy ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3188
+ import_core40.ActionIcon,
2685
3189
  {
2686
3190
  variant: "subtle",
2687
3191
  "aria-label": copied ? "Copied code block" : "Copy code block",
2688
3192
  onClick: () => {
2689
3193
  void handleCopy();
2690
3194
  },
2691
- children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(GdsIcons.Copy, { size: "1rem" })
3195
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(GdsIcons.Copy, { size: "1rem" })
2692
3196
  }
2693
3197
  ) : null
2694
3198
  ] }) : null,
2695
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core39.Code, { block: true, children: code })
3199
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core40.Code, { block: true, children: code })
2696
3200
  ] }) });
2697
3201
  }
2698
3202
 
2699
3203
  // src/CtaButtonGroup.tsx
2700
- var import_core40 = require("@mantine/core");
2701
- var import_jsx_runtime42 = require("react/jsx-runtime");
3204
+ var import_core41 = require("@mantine/core");
3205
+ var import_jsx_runtime45 = require("react/jsx-runtime");
2702
3206
  function CtaButtonGroup({ primary, secondary, tertiary }) {
2703
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_core40.Stack, { gap: "sm", children: [
2704
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_core40.Group, { gap: "sm", align: "stretch", children: [
2705
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { children: primary }),
2706
- secondary ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { children: secondary }) : null
3207
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_core41.Stack, { gap: "sm", children: [
3208
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_core41.Group, { gap: "sm", align: "stretch", children: [
3209
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { children: primary }),
3210
+ secondary ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { children: secondary }) : null
2707
3211
  ] }),
2708
- tertiary ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { children: tertiary }) : null
3212
+ tertiary ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { children: tertiary }) : null
2709
3213
  ] });
2710
3214
  }
2711
3215
 
2712
3216
  // src/DocsPageShell.tsx
2713
- var import_core41 = require("@mantine/core");
2714
- var import_jsx_runtime43 = require("react/jsx-runtime");
3217
+ var import_core42 = require("@mantine/core");
3218
+ var import_jsx_runtime46 = require("react/jsx-runtime");
2715
3219
  function DocsPageShell({
2716
3220
  breadcrumbs = [],
2717
3221
  title,
@@ -2722,27 +3226,27 @@ function DocsPageShell({
2722
3226
  footerNext,
2723
3227
  children
2724
3228
  }) {
2725
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core41.Container, { fluid: true, py: "xl", px: { base: "md", md: "lg", lg: "xl" }, w: "100%", maw: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_core41.Group, { align: "flex-start", gap: "xl", wrap: "nowrap", children: [
2726
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_core41.Stack, { component: "article", gap: "lg", flex: 1, miw: 0, children: [
2727
- breadcrumbs.length ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core41.Breadcrumbs, { children: breadcrumbs.map(
2728
- (crumb) => crumb.href ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core41.Anchor, { href: crumb.href, children: crumb.label }, `${crumb.label}-${crumb.href}`) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core41.Text, { children: crumb.label }, crumb.label)
3229
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core42.Container, { fluid: true, py: "xl", px: { base: "md", md: "lg", lg: "xl" }, w: "100%", maw: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_core42.Group, { align: "flex-start", gap: "xl", wrap: "nowrap", children: [
3230
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_core42.Stack, { component: "article", gap: "lg", flex: 1, miw: 0, children: [
3231
+ breadcrumbs.length ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core42.Breadcrumbs, { children: breadcrumbs.map(
3232
+ (crumb) => crumb.href ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core42.Anchor, { href: crumb.href, children: crumb.label }, `${crumb.label}-${crumb.href}`) : /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core42.Text, { children: crumb.label }, crumb.label)
2729
3233
  ) }) : null,
2730
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_core41.Stack, { gap: "sm", children: [
2731
- eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core41.Text, { size: "sm", fw: 700, c: "dimmed", children: eyebrow }) : null,
2732
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core41.Title, { order: 1, children: title }),
2733
- lead ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core41.Text, { size: "lg", c: "dimmed", children: lead }) : null,
2734
- meta ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core41.Group, { gap: "md", children: meta }) : null
3234
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_core42.Stack, { gap: "sm", children: [
3235
+ eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core42.Text, { size: "sm", fw: 700, c: "dimmed", children: eyebrow }) : null,
3236
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core42.Title, { order: 1, children: title }),
3237
+ lead ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core42.Text, { size: "lg", c: "dimmed", children: lead }) : null,
3238
+ meta ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core42.Group, { gap: "md", children: meta }) : null
2735
3239
  ] }),
2736
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core41.Stack, { gap: "md", children }),
2737
- footerNext ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core41.Anchor, { href: footerNext.href, fw: 600, children: footerNext.label }) : null
3240
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core42.Stack, { gap: "md", children }),
3241
+ footerNext ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core42.Anchor, { href: footerNext.href, fw: 600, children: footerNext.label }) : null
2738
3242
  ] }),
2739
- sideRail ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_core41.Stack, { visibleFrom: "lg", gap: "md", w: 240, children: sideRail }) : null
3243
+ sideRail ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core42.Stack, { visibleFrom: "lg", gap: "md", w: 240, children: sideRail }) : null
2740
3244
  ] }) });
2741
3245
  }
2742
3246
 
2743
3247
  // src/EditorialHero.tsx
2744
- var import_core42 = require("@mantine/core");
2745
- var import_jsx_runtime44 = require("react/jsx-runtime");
3248
+ var import_core43 = require("@mantine/core");
3249
+ var import_jsx_runtime47 = require("react/jsx-runtime");
2746
3250
  function resolveActionVariant(action, index, seenPrimary) {
2747
3251
  const requested = action.variant ?? (index === 0 ? "primary" : "secondary");
2748
3252
  if (requested === "primary" && !seenPrimary) {
@@ -2754,8 +3258,8 @@ function resolveActionVariant(action, index, seenPrimary) {
2754
3258
  return { variant: "default", seenPrimary };
2755
3259
  }
2756
3260
  function HeroAction({ action, variant }) {
2757
- const content = /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2758
- import_core42.Anchor,
3261
+ const content = /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3262
+ import_core43.Anchor,
2759
3263
  {
2760
3264
  href: action.href,
2761
3265
  onClick: action.onClick,
@@ -2779,8 +3283,8 @@ function HeroAction({ action, variant }) {
2779
3283
  }
2780
3284
  );
2781
3285
  if (!action.href) {
2782
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2783
- import_core42.Box,
3286
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3287
+ import_core43.Box,
2784
3288
  {
2785
3289
  component: "button",
2786
3290
  type: "button",
@@ -2807,30 +3311,30 @@ function HeroAction({ action, variant }) {
2807
3311
  return content;
2808
3312
  }
2809
3313
  function LoadingHero({ compact }) {
2810
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Paper, { withBorder: true, radius: "xl", p: compact ? "lg" : "xl", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_core42.Grid, { gutter: compact ? "lg" : "xl", align: "center", children: [
2811
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Grid.Col, { span: { base: 12, md: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_core42.Stack, { gap: "md", children: [
2812
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Skeleton, { height: 16, width: 96, radius: "xl" }),
2813
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Skeleton, { height: 48, width: "90%", radius: "md" }),
2814
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Skeleton, { height: 18, width: "100%", radius: "md" }),
2815
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Skeleton, { height: 18, width: "82%", radius: "md" }),
2816
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_core42.Group, { children: [
2817
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Skeleton, { height: 40, width: 140, radius: "md" }),
2818
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Skeleton, { height: 40, width: 140, radius: "md" })
3314
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Paper, { withBorder: true, radius: "xl", p: compact ? "lg" : "xl", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_core43.Grid, { gutter: compact ? "lg" : "xl", align: "center", children: [
3315
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Grid.Col, { span: { base: 12, md: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_core43.Stack, { gap: "md", children: [
3316
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Skeleton, { height: 16, width: 96, radius: "xl" }),
3317
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Skeleton, { height: 48, width: "90%", radius: "md" }),
3318
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Skeleton, { height: 18, width: "100%", radius: "md" }),
3319
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Skeleton, { height: 18, width: "82%", radius: "md" }),
3320
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_core43.Group, { children: [
3321
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Skeleton, { height: 40, width: 140, radius: "md" }),
3322
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Skeleton, { height: 40, width: 140, radius: "md" })
2819
3323
  ] })
2820
3324
  ] }) }),
2821
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Grid.Col, { span: { base: 12, md: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.AspectRatio, { ratio: 16 / 11, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Skeleton, { radius: "lg" }) }) })
3325
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Grid.Col, { span: { base: 12, md: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.AspectRatio, { ratio: 16 / 11, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Skeleton, { radius: "lg" }) }) })
2822
3326
  ] }) });
2823
3327
  }
2824
3328
  function MediaFallback() {
2825
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.AspectRatio, { ratio: 16 / 11, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2826
- import_core42.ThemeIcon,
3329
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.AspectRatio, { ratio: 16 / 11, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3330
+ import_core43.ThemeIcon,
2827
3331
  {
2828
3332
  size: "100%",
2829
3333
  radius: "lg",
2830
3334
  color: "gray",
2831
3335
  variant: "light",
2832
3336
  "aria-label": "Hero media is unavailable",
2833
- children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(GdsIcons.Gallery, { size: "2.5rem" })
3337
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(GdsIcons.Gallery, { size: "2.5rem" })
2834
3338
  }
2835
3339
  ) });
2836
3340
  }
@@ -2850,8 +3354,8 @@ function MediaFrame({
2850
3354
  } else if (mediaFade === "soft-start") {
2851
3355
  overlayBackground = "linear-gradient(90deg, light-dark(rgba(255,255,255,0.9), rgba(17,24,39,0.72)) 0%, rgba(255,255,255,0) 28%)";
2852
3356
  }
2853
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
2854
- import_core42.Box,
3357
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
3358
+ import_core43.Box,
2855
3359
  {
2856
3360
  component: "figure",
2857
3361
  m: 0,
@@ -2864,9 +3368,9 @@ function MediaFrame({
2864
3368
  },
2865
3369
  "aria-label": mediaAlt,
2866
3370
  children: [
2867
- media ?? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(MediaFallback, {}),
2868
- media && overlayBackground ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2869
- import_core42.Box,
3371
+ media ?? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(MediaFallback, {}),
3372
+ media && overlayBackground ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3373
+ import_core43.Box,
2870
3374
  {
2871
3375
  "aria-hidden": true,
2872
3376
  style: {
@@ -2899,7 +3403,7 @@ function EditorialHero({
2899
3403
  classNames
2900
3404
  }) {
2901
3405
  if (loading) {
2902
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(LoadingHero, { compact });
3406
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(LoadingHero, { compact });
2903
3407
  }
2904
3408
  const stackAlign = align === "center" ? "center" : "flex-start";
2905
3409
  const textAlign = align === "center" ? "center" : "left";
@@ -2907,15 +3411,15 @@ function EditorialHero({
2907
3411
  const renderedActions = actions.slice(0, 3).map((action, index) => {
2908
3412
  const resolved = resolveActionVariant(action, index, seenPrimary);
2909
3413
  seenPrimary = resolved.seenPrimary;
2910
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(HeroAction, { action, variant: resolved.variant }, `${action.label}-${index}`);
3414
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(HeroAction, { action, variant: resolved.variant }, `${action.label}-${index}`);
2911
3415
  });
2912
- const textSlot = /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_core42.Stack, { gap: compact ? "md" : "lg", justify: "center", h: "100%", className: classNames?.content, children: [
2913
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_core42.Stack, { gap: "sm", align: stackAlign, children: [
2914
- eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Text, { size: "sm", fw: 700, c: "dimmed", ta: textAlign, children: eyebrow }) : null,
2915
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Title, { order: 1, maw: 760, ta: textAlign, children: title }),
2916
- description ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Text, { size: compact ? "md" : "lg", c: "dimmed", maw: 720, ta: textAlign, children: description }) : null
3416
+ const textSlot = /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_core43.Stack, { gap: compact ? "md" : "lg", justify: "center", h: "100%", className: classNames?.content, children: [
3417
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_core43.Stack, { gap: "sm", align: stackAlign, children: [
3418
+ eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Text, { size: "sm", fw: 700, c: "dimmed", ta: textAlign, children: eyebrow }) : null,
3419
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Title, { order: 1, maw: 760, ta: textAlign, children: title }),
3420
+ description ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Text, { size: compact ? "md" : "lg", c: "dimmed", maw: 720, ta: textAlign, children: description }) : null
2917
3421
  ] }),
2918
- renderedActions.length ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Box, { className: classNames?.actions, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3422
+ renderedActions.length ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Box, { className: classNames?.actions, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
2919
3423
  CtaButtonGroup,
2920
3424
  {
2921
3425
  primary: renderedActions[0],
@@ -2923,8 +3427,8 @@ function EditorialHero({
2923
3427
  tertiary: renderedActions[2]
2924
3428
  }
2925
3429
  ) }) : null,
2926
- meta.length ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Group, { gap: "sm", wrap: "wrap", "aria-label": "Supporting details", className: classNames?.meta, children: meta.map((item) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
2927
- import_core42.Group,
3430
+ meta.length ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Group, { gap: "sm", wrap: "wrap", "aria-label": "Supporting details", className: classNames?.meta, children: meta.map((item) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
3431
+ import_core43.Group,
2928
3432
  {
2929
3433
  gap: 6,
2930
3434
  px: "sm",
@@ -2935,17 +3439,17 @@ function EditorialHero({
2935
3439
  },
2936
3440
  children: [
2937
3441
  item.icon,
2938
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Text, { size: "sm", c: "dimmed", children: item.label })
3442
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Text, { size: "sm", c: "dimmed", children: item.label })
2939
3443
  ]
2940
3444
  },
2941
3445
  item.id
2942
3446
  )) }) : null
2943
3447
  ] });
2944
- const mediaSlot = error ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(AccentPanel, { tone: "red", variant: "soft-outline", title: "Media unavailable", children: error }) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(MediaFrame, { media, mediaAlt, mediaFade, className: classNames?.media });
2945
- const textCol = /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Grid.Col, { span: { base: 12, md: 6 }, order: { base: 1, md: mediaPosition === "left" ? 2 : 1 }, children: textSlot });
2946
- const mediaCol = /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_core42.Grid.Col, { span: { base: 12, md: 6 }, order: { base: 2, md: mediaPosition === "left" ? 1 : 2 }, children: mediaSlot });
2947
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2948
- import_core42.Paper,
3448
+ const mediaSlot = error ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(AccentPanel, { tone: "red", variant: "soft-outline", title: "Media unavailable", children: error }) : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(MediaFrame, { media, mediaAlt, mediaFade, className: classNames?.media });
3449
+ const textCol = /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Grid.Col, { span: { base: 12, md: 6 }, order: { base: 1, md: mediaPosition === "left" ? 2 : 1 }, children: textSlot });
3450
+ const mediaCol = /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core43.Grid.Col, { span: { base: 12, md: 6 }, order: { base: 2, md: mediaPosition === "left" ? 1 : 2 }, children: mediaSlot });
3451
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3452
+ import_core43.Paper,
2949
3453
  {
2950
3454
  component: "section",
2951
3455
  withBorder: true,
@@ -2953,7 +3457,7 @@ function EditorialHero({
2953
3457
  p: compact ? "lg" : "xl",
2954
3458
  className: classNames?.root,
2955
3459
  style: surfaceVariant === "flat-public" ? { boxShadow: "none" } : void 0,
2956
- children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_core42.Grid, { gutter: compact ? "lg" : "xl", align: "center", children: [
3460
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_core43.Grid, { gutter: compact ? "lg" : "xl", align: "center", children: [
2957
3461
  textCol,
2958
3462
  mediaCol
2959
3463
  ] })
@@ -2962,19 +3466,19 @@ function EditorialHero({
2962
3466
  }
2963
3467
 
2964
3468
  // src/FeatureBand.tsx
2965
- var import_core43 = require("@mantine/core");
2966
- var import_jsx_runtime45 = require("react/jsx-runtime");
3469
+ var import_core44 = require("@mantine/core");
3470
+ var import_jsx_runtime48 = require("react/jsx-runtime");
2967
3471
  function FeatureBandSkeleton({
2968
3472
  columns = 3,
2969
3473
  bordered = true,
2970
3474
  variant = "default"
2971
3475
  }) {
2972
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.SimpleGrid, { cols: { base: 1, sm: Math.min(columns, 2), lg: columns }, spacing: "lg", children: Array.from({ length: columns }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.Paper, { withBorder: bordered, radius: "lg", p: variant === "compact" ? "md" : "lg", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_core43.Stack, { gap: "md", children: [
2973
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.Skeleton, { height: variant === "process" ? 28 : 42, width: variant === "process" ? 72 : 42, radius: "xl" }),
2974
- /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_core43.Stack, { gap: "xs", children: [
2975
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.Skeleton, { height: 20, width: "75%", radius: "md" }),
2976
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.Skeleton, { height: 14, width: "100%", radius: "md" }),
2977
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.Skeleton, { height: 14, width: "82%", radius: "md" })
3476
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.SimpleGrid, { cols: { base: 1, sm: Math.min(columns, 2), lg: columns }, spacing: "lg", children: Array.from({ length: columns }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.Paper, { withBorder: bordered, radius: "lg", p: variant === "compact" ? "md" : "lg", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_core44.Stack, { gap: "md", children: [
3477
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.Skeleton, { height: variant === "process" ? 28 : 42, width: variant === "process" ? 72 : 42, radius: "xl" }),
3478
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_core44.Stack, { gap: "xs", children: [
3479
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.Skeleton, { height: 20, width: "75%", radius: "md" }),
3480
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.Skeleton, { height: 14, width: "100%", radius: "md" }),
3481
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.Skeleton, { height: 14, width: "82%", radius: "md" })
2978
3482
  ] })
2979
3483
  ] }) }, index)) });
2980
3484
  }
@@ -2987,10 +3491,10 @@ function FeatureBand({
2987
3491
  variant = "default"
2988
3492
  }) {
2989
3493
  if (loading) {
2990
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(FeatureBandSkeleton, { columns, bordered, variant });
3494
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(FeatureBandSkeleton, { columns, bordered, variant });
2991
3495
  }
2992
3496
  if (!items.length) {
2993
- return emptyState ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_jsx_runtime45.Fragment, { children: emptyState }) : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3497
+ return emptyState ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_jsx_runtime48.Fragment, { children: emptyState }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
2994
3498
  EmptyState,
2995
3499
  {
2996
3500
  title: "No supporting details available",
@@ -2998,9 +3502,9 @@ function FeatureBand({
2998
3502
  }
2999
3503
  );
3000
3504
  }
3001
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.Box, { component: "section", "aria-label": "Supporting features", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.SimpleGrid, { cols: { base: 1, sm: Math.min(columns, 2), lg: columns }, spacing: "lg", children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.Paper, { withBorder: bordered, radius: "lg", p: variant === "compact" ? "md" : "lg", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_core43.Stack, { gap: "md", children: [
3002
- variant === "process" ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.Group, { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3003
- import_core43.Text,
3505
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.Box, { component: "section", "aria-label": "Supporting features", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.SimpleGrid, { cols: { base: 1, sm: Math.min(columns, 2), lg: columns }, spacing: "lg", children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.Paper, { withBorder: bordered, radius: "lg", p: variant === "compact" ? "md" : "lg", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_core44.Stack, { gap: "md", children: [
3506
+ variant === "process" ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.Group, { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3507
+ import_core44.Text,
3004
3508
  {
3005
3509
  fw: 800,
3006
3510
  size: "sm",
@@ -3012,18 +3516,18 @@ function FeatureBand({
3012
3516
  },
3013
3517
  children: item.stepLabel ?? `Step ${index + 1}`
3014
3518
  }
3015
- ) }) : item.media ? item.media : item.icon ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.Group, { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.ThemeIcon, { size: "xl", radius: "xl", variant: "light", color: "violet", children: item.icon }) }) : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.Group, { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.ThemeIcon, { size: "xl", radius: "xl", variant: "light", color: "gray", "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(GdsIcons.Info, { size: "1.25rem" }) }) }),
3016
- /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_core43.Stack, { gap: "xs", children: [
3017
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.Title, { order: 4, children: item.title }),
3018
- item.description ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.Text, { c: "dimmed", children: item.description }) : null,
3019
- item.meta ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core43.Text, { size: "sm", c: "dimmed", children: item.meta }) : null
3519
+ ) }) : item.media ? item.media : item.icon ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.Group, { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.ThemeIcon, { size: "xl", radius: "xl", variant: "light", color: "violet", children: item.icon }) }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.Group, { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.ThemeIcon, { size: "xl", radius: "xl", variant: "light", color: "gray", "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(GdsIcons.Info, { size: "1.25rem" }) }) }),
3520
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_core44.Stack, { gap: "xs", children: [
3521
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.Title, { order: 4, children: item.title }),
3522
+ item.description ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.Text, { c: "dimmed", children: item.description }) : null,
3523
+ item.meta ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core44.Text, { size: "sm", c: "dimmed", children: item.meta }) : null
3020
3524
  ] })
3021
3525
  ] }) }, item.id)) }) });
3022
3526
  }
3023
3527
 
3024
3528
  // src/MapPanel.tsx
3025
- var import_core44 = require("@mantine/core");
3026
- var import_jsx_runtime46 = require("react/jsx-runtime");
3529
+ var import_core45 = require("@mantine/core");
3530
+ var import_jsx_runtime49 = require("react/jsx-runtime");
3027
3531
  function MapPanel({
3028
3532
  title,
3029
3533
  description,
@@ -3039,7 +3543,7 @@ function MapPanel({
3039
3543
  }) {
3040
3544
  let body;
3041
3545
  if (loading) {
3042
- body = /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3546
+ body = /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3043
3547
  StateBlock,
3044
3548
  {
3045
3549
  variant: "loading",
@@ -3049,9 +3553,9 @@ function MapPanel({
3049
3553
  }
3050
3554
  );
3051
3555
  } else if (error) {
3052
- body = /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(StateBlock, { variant: "error", title: "Map unavailable", description: error, compact: true });
3556
+ body = /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(StateBlock, { variant: "error", title: "Map unavailable", description: error, compact: true });
3053
3557
  } else if (!iframeSrc && !renderMap) {
3054
- body = /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3558
+ body = /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3055
3559
  StateBlock,
3056
3560
  {
3057
3561
  variant: "empty",
@@ -3061,9 +3565,9 @@ function MapPanel({
3061
3565
  }
3062
3566
  );
3063
3567
  } else if (renderMap) {
3064
- body = /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core44.Box, { style: { minHeight }, children: renderMap() });
3568
+ body = /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core45.Box, { style: { minHeight }, children: renderMap() });
3065
3569
  } else {
3066
- body = /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core44.AspectRatio, { ratio: 16 / 9, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3570
+ body = /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core45.AspectRatio, { ratio: 16 / 9, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3067
3571
  "iframe",
3068
3572
  {
3069
3573
  src: iframeSrc,
@@ -3075,21 +3579,21 @@ function MapPanel({
3075
3579
  }
3076
3580
  ) });
3077
3581
  }
3078
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core44.Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_core44.Stack, { gap: "md", children: [
3079
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_core44.Group, { justify: "space-between", align: "flex-start", gap: "md", wrap: "wrap", children: [
3080
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_core44.Stack, { gap: 4, children: [
3081
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core44.Title, { order: 3, children: title }),
3082
- description ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_core44.Text, { size: "sm", c: "dimmed", children: description }) : null
3582
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core45.Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_core45.Stack, { gap: "md", children: [
3583
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_core45.Group, { justify: "space-between", align: "flex-start", gap: "md", wrap: "wrap", children: [
3584
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_core45.Stack, { gap: 4, children: [
3585
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core45.Title, { order: 3, children: title }),
3586
+ description ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core45.Text, { size: "sm", c: "dimmed", children: description }) : null
3083
3587
  ] }),
3084
- actions ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ActionBar, { ...actions }) : null
3588
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ActionBar, { ...actions }) : null
3085
3589
  ] }),
3086
3590
  body
3087
3591
  ] }) });
3088
3592
  }
3089
3593
 
3090
3594
  // src/PublicFlowShell.tsx
3091
- var import_core45 = require("@mantine/core");
3092
- var import_jsx_runtime47 = require("react/jsx-runtime");
3595
+ var import_core46 = require("@mantine/core");
3596
+ var import_jsx_runtime50 = require("react/jsx-runtime");
3093
3597
  var stageTone = {
3094
3598
  idle: { label: "Idle", color: "gray" },
3095
3599
  loading: { label: "Loading", color: "blue" },
@@ -3141,7 +3645,7 @@ function PublicFlowShell({
3141
3645
  const actionBar = toActionBar(stage.actions);
3142
3646
  let body = stage.body;
3143
3647
  if (stage.status === "loading") {
3144
- body = /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3648
+ body = /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3145
3649
  StateBlock,
3146
3650
  {
3147
3651
  variant: "loading",
@@ -3150,7 +3654,7 @@ function PublicFlowShell({
3150
3654
  }
3151
3655
  );
3152
3656
  } else if (stage.status === "error") {
3153
- body = errorState ?? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3657
+ body = errorState ?? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3154
3658
  StateBlock,
3155
3659
  {
3156
3660
  variant: "error",
@@ -3159,7 +3663,7 @@ function PublicFlowShell({
3159
3663
  }
3160
3664
  );
3161
3665
  } else if (!stage.body && !hardwareSurface) {
3162
- body = emptyState ?? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3666
+ body = emptyState ?? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3163
3667
  EmptyState,
3164
3668
  {
3165
3669
  title: "No stage content available",
@@ -3167,29 +3671,29 @@ function PublicFlowShell({
3167
3671
  }
3168
3672
  );
3169
3673
  }
3170
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core45.Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_core45.Stack, { gap: "lg", children: [
3171
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_core45.Group, { justify: "space-between", align: "flex-start", gap: "md", wrap: "wrap", children: [
3172
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_core45.Stack, { gap: 4, children: [
3173
- eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core45.Text, { size: "xs", fw: 700, c: "dimmed", tt: "uppercase", children: eyebrow }) : null,
3174
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_core45.Group, { gap: "sm", wrap: "wrap", children: [
3175
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core45.Title, { order: 2, children: stage.title }),
3176
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core45.Badge, { variant: "light", color: tone.color, children: tone.label })
3674
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core46.Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_core46.Stack, { gap: "lg", children: [
3675
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_core46.Group, { justify: "space-between", align: "flex-start", gap: "md", wrap: "wrap", children: [
3676
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_core46.Stack, { gap: 4, children: [
3677
+ eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core46.Text, { size: "xs", fw: 700, c: "dimmed", tt: "uppercase", children: eyebrow }) : null,
3678
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_core46.Group, { gap: "sm", wrap: "wrap", children: [
3679
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core46.Title, { order: 2, children: stage.title }),
3680
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core46.Badge, { variant: "light", color: tone.color, children: tone.label })
3177
3681
  ] }),
3178
- stage.description ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core45.Text, { size: "sm", c: "dimmed", children: stage.description }) : null
3682
+ stage.description ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core46.Text, { size: "sm", c: "dimmed", children: stage.description }) : null
3179
3683
  ] }),
3180
3684
  exitAction
3181
3685
  ] }),
3182
- stage.notice ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_core45.Text, { size: "sm", c: "dimmed", children: stage.notice }) : null,
3686
+ stage.notice ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core46.Text, { size: "sm", c: "dimmed", children: stage.notice }) : null,
3183
3687
  body,
3184
3688
  hardwareSurface,
3185
3689
  stage.aside,
3186
- actionBar ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ActionBar, { ...actionBar }) : null
3690
+ actionBar ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ActionBar, { ...actionBar }) : null
3187
3691
  ] }) });
3188
3692
  }
3189
3693
 
3190
3694
  // src/PlaybackSurface.tsx
3191
- var import_core46 = require("@mantine/core");
3192
- var import_jsx_runtime48 = require("react/jsx-runtime");
3695
+ var import_core47 = require("@mantine/core");
3696
+ var import_jsx_runtime51 = require("react/jsx-runtime");
3193
3697
  var stateTone = {
3194
3698
  loading: { label: "Loading", color: "blue" },
3195
3699
  ready: { label: "Ready", color: "teal" },
@@ -3212,7 +3716,7 @@ function PlaybackSurface({
3212
3716
  const tone = stateTone[state];
3213
3717
  let content;
3214
3718
  if (state === "loading") {
3215
- content = /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3719
+ content = /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3216
3720
  StateBlock,
3217
3721
  {
3218
3722
  variant: "loading",
@@ -3221,7 +3725,7 @@ function PlaybackSurface({
3221
3725
  }
3222
3726
  );
3223
3727
  } else if (state === "empty") {
3224
- content = emptyState ?? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3728
+ content = emptyState ?? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3225
3729
  EmptyState,
3226
3730
  {
3227
3731
  title: "No playback content available",
@@ -3229,7 +3733,7 @@ function PlaybackSurface({
3229
3733
  }
3230
3734
  );
3231
3735
  } else if (state === "error") {
3232
- content = errorState ?? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3736
+ content = errorState ?? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3233
3737
  StateBlock,
3234
3738
  {
3235
3739
  variant: "error",
@@ -3238,23 +3742,23 @@ function PlaybackSurface({
3238
3742
  }
3239
3743
  );
3240
3744
  } else {
3241
- content = /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_core46.Stack, { gap: "md", children: [
3745
+ content = /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_core47.Stack, { gap: "md", children: [
3242
3746
  media,
3243
3747
  overlays
3244
3748
  ] });
3245
3749
  }
3246
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core46.Paper, { withBorder: true, radius: "xl", p: "lg", "data-playback-mode": mode, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_core46.Stack, { gap: "md", children: [
3247
- title || statusMessage || controls ? /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_core46.Group, { justify: "space-between", align: "flex-start", gap: "md", wrap: "wrap", children: [
3248
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_core46.Stack, { gap: 4, children: [
3249
- title ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core46.Title, { order: 3, children: title }) : null,
3250
- statusMessage ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core46.Text, { size: "sm", c: "dimmed", children: statusMessage }) : null
3750
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core47.Paper, { withBorder: true, radius: "xl", p: "lg", "data-playback-mode": mode, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_core47.Stack, { gap: "md", children: [
3751
+ title || statusMessage || controls ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_core47.Group, { justify: "space-between", align: "flex-start", gap: "md", wrap: "wrap", children: [
3752
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_core47.Stack, { gap: 4, children: [
3753
+ title ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core47.Title, { order: 3, children: title }) : null,
3754
+ statusMessage ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core47.Text, { size: "sm", c: "dimmed", children: statusMessage }) : null
3251
3755
  ] }),
3252
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_core46.Group, { gap: "sm", align: "center", wrap: "wrap", children: [
3253
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core46.Badge, { variant: "light", color: tone.color, children: tone.label }),
3756
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_core47.Group, { gap: "sm", align: "center", wrap: "wrap", children: [
3757
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core47.Badge, { variant: "light", color: tone.color, children: tone.label }),
3254
3758
  controls
3255
3759
  ] })
3256
3760
  ] }) : null,
3257
- state === "degraded" ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3761
+ state === "degraded" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3258
3762
  StateBlock,
3259
3763
  {
3260
3764
  variant: "info",
@@ -3268,9 +3772,9 @@ function PlaybackSurface({
3268
3772
  }
3269
3773
 
3270
3774
  // src/ShareButtonGroup.tsx
3271
- var import_react8 = require("react");
3272
- var import_core47 = require("@mantine/core");
3273
- var import_jsx_runtime49 = require("react/jsx-runtime");
3775
+ var import_react10 = require("react");
3776
+ var import_core48 = require("@mantine/core");
3777
+ var import_jsx_runtime52 = require("react/jsx-runtime");
3274
3778
  var channelLabels = {
3275
3779
  native: "Share",
3276
3780
  copy: "Copy link",
@@ -3305,9 +3809,9 @@ function ShareAction({
3305
3809
  const label = channelLabels[channel];
3306
3810
  const Icon = channel === "copy" ? GdsIcons.Copy : channel === "mail" ? GdsIcons.Mail : channel === "message" ? GdsIcons.Message : GdsIcons.Refer;
3307
3811
  if (compact) {
3308
- return href ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core47.ActionIcon, { component: "a", href, target: "_blank", rel: "noreferrer", variant: "subtle", size: "lg", "aria-label": label, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Icon, { size: "1rem", stroke: 1.75 }) }) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core47.ActionIcon, { variant: "subtle", size: "lg", "aria-label": label, onClick, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Icon, { size: "1rem", stroke: 1.75 }) });
3812
+ return href ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_core48.ActionIcon, { component: "a", href, target: "_blank", rel: "noreferrer", variant: "subtle", size: "lg", "aria-label": label, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Icon, { size: "1rem", stroke: 1.75 }) }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_core48.ActionIcon, { variant: "subtle", size: "lg", "aria-label": label, onClick, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Icon, { size: "1rem", stroke: 1.75 }) });
3309
3813
  }
3310
- return href ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core47.Button, { component: "a", href, target: "_blank", rel: "noreferrer", variant: "default", leftSection: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Icon, { size: "1rem", stroke: 1.75 }), children: label }) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core47.Button, { variant: "default", leftSection: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Icon, { size: "1rem", stroke: 1.75 }), onClick, children: label });
3814
+ return href ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_core48.Button, { component: "a", href, target: "_blank", rel: "noreferrer", variant: "default", leftSection: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Icon, { size: "1rem", stroke: 1.75 }), children: label }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_core48.Button, { variant: "default", leftSection: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Icon, { size: "1rem", stroke: 1.75 }), onClick, children: label });
3311
3815
  }
3312
3816
  function ShareButtonGroup({
3313
3817
  url,
@@ -3318,8 +3822,8 @@ function ShareButtonGroup({
3318
3822
  label = "Share this",
3319
3823
  description
3320
3824
  }) {
3321
- const [copied, setCopied] = (0, import_react8.useState)(false);
3322
- const [shared, setShared] = (0, import_react8.useState)(false);
3825
+ const [copied, setCopied] = (0, import_react10.useState)(false);
3826
+ const [shared, setShared] = (0, import_react10.useState)(false);
3323
3827
  const hrefs = encodeShare(url, title, text);
3324
3828
  async function handleCopy() {
3325
3829
  await navigator.clipboard?.writeText?.(url);
@@ -3335,52 +3839,67 @@ function ShareButtonGroup({
3335
3839
  }
3336
3840
  await handleCopy();
3337
3841
  }
3338
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_core47.Stack, { gap: "sm", children: [
3339
- /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_core47.Stack, { gap: 2, children: [
3340
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core47.Text, { fw: 600, children: label }),
3341
- description ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core47.Text, { size: "sm", c: "dimmed", children: description }) : null
3842
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_core48.Stack, { gap: "sm", children: [
3843
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_core48.Stack, { gap: 2, children: [
3844
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_core48.Text, { fw: 600, children: label }),
3845
+ description ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_core48.Text, { size: "sm", c: "dimmed", children: description }) : null
3342
3846
  ] }),
3343
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core47.Group, { gap: "sm", wrap: "wrap", children: channels.map((channel) => {
3847
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_core48.Group, { gap: "sm", wrap: "wrap", children: channels.map((channel) => {
3344
3848
  if (channel === "copy") {
3345
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ShareAction, { channel, compact, onClick: () => void handleCopy() }, channel);
3849
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ShareAction, { channel, compact, onClick: () => void handleCopy() }, channel);
3346
3850
  }
3347
3851
  if (channel === "native") {
3348
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ShareAction, { channel, compact, onClick: () => void handleNativeShare() }, channel);
3852
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ShareAction, { channel, compact, onClick: () => void handleNativeShare() }, channel);
3349
3853
  }
3350
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ShareAction, { channel, compact, href: hrefs[channel] }, channel);
3854
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ShareAction, { channel, compact, href: hrefs[channel] }, channel);
3351
3855
  }) }),
3352
- copied ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core47.Text, { size: "sm", c: "teal", children: "Link copied." }) : null,
3353
- shared ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core47.Text, { size: "sm", c: "teal", children: "Share sheet opened." }) : null
3856
+ copied ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_core48.Text, { size: "sm", c: "teal", children: "Link copied." }) : null,
3857
+ shared ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_core48.Text, { size: "sm", c: "teal", children: "Share sheet opened." }) : null
3354
3858
  ] });
3355
3859
  }
3356
3860
 
3357
3861
  // src/UploadDropzone.tsx
3358
- var import_react9 = require("react");
3359
- var import_core48 = require("@mantine/core");
3360
- var import_jsx_runtime50 = require("react/jsx-runtime");
3862
+ var import_react11 = require("react");
3863
+ var import_core49 = require("@mantine/core");
3864
+ var import_jsx_runtime53 = require("react/jsx-runtime");
3361
3865
  function UploadDropzone({
3362
3866
  title,
3363
3867
  description,
3364
3868
  onFilesSelected,
3365
3869
  accept,
3870
+ acceptedTypesLabel,
3871
+ maxSizeLabel,
3366
3872
  multiple = true,
3367
3873
  actionLabel = "Choose files",
3368
- mode = "panel"
3874
+ mode = "panel",
3875
+ state = "idle",
3876
+ selectedFiles = [],
3877
+ error,
3878
+ policyText,
3879
+ retryAction,
3880
+ removeAction,
3881
+ readonly = false
3369
3882
  }) {
3370
- const inputRef = (0, import_react9.useRef)(null);
3371
- const [dragging, setDragging] = (0, import_react9.useState)(false);
3883
+ const inputRef = (0, import_react11.useRef)(null);
3884
+ const [dragging, setDragging] = (0, import_react11.useState)(false);
3372
3885
  const UploadIcon = GdsIcons.Upload;
3886
+ const effectiveState = readonly ? "readonly" : dragging ? "drag-active" : state;
3887
+ const isDisabled = readonly || effectiveState === "upload-pending";
3888
+ const isError = ["upload-failed", "unsupported-type", "too-large"].includes(effectiveState);
3373
3889
  const forwardFiles = (files) => {
3374
- if (!files?.length || !onFilesSelected) {
3890
+ if (isDisabled || !files?.length || !onFilesSelected) {
3375
3891
  return;
3376
3892
  }
3377
3893
  onFilesSelected(Array.from(files));
3378
3894
  };
3379
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
3380
- import_core48.Box,
3895
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
3896
+ import_core49.Box,
3381
3897
  {
3382
3898
  onDragOver: (event) => {
3383
3899
  event.preventDefault();
3900
+ if (isDisabled) {
3901
+ return;
3902
+ }
3384
3903
  setDragging(true);
3385
3904
  },
3386
3905
  onDragLeave: () => setDragging(false),
@@ -3391,12 +3910,13 @@ function UploadDropzone({
3391
3910
  },
3392
3911
  p: mode === "inline" ? "md" : "xl",
3393
3912
  style: {
3394
- border: `1px dashed var(${dragging ? "--mantine-color-violet-6" : "--mantine-color-default-border"})`,
3913
+ border: `1px dashed var(${effectiveState === "drag-active" ? "--mantine-color-violet-6" : isError ? "--mantine-color-red-6" : "--mantine-color-default-border"})`,
3395
3914
  borderRadius: "var(--mantine-radius-lg)",
3396
- background: dragging ? "var(--mantine-color-violet-light)" : "transparent"
3915
+ background: effectiveState === "drag-active" ? "var(--mantine-color-violet-light)" : "transparent"
3397
3916
  },
3917
+ "aria-invalid": isError || void 0,
3398
3918
  children: [
3399
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3919
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
3400
3920
  "input",
3401
3921
  {
3402
3922
  ref: inputRef,
@@ -3404,14 +3924,30 @@ function UploadDropzone({
3404
3924
  hidden: true,
3405
3925
  accept,
3406
3926
  multiple,
3927
+ disabled: isDisabled,
3407
3928
  onChange: (event) => forwardFiles(event.currentTarget.files)
3408
3929
  }
3409
3930
  ),
3410
- /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_core48.Stack, { align: mode === "inline" ? "flex-start" : "center", ta: mode === "inline" ? "left" : "center", gap: "sm", children: [
3411
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(UploadIcon, { size: "1.5rem" }),
3412
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core48.Text, { fw: 600, children: title }),
3413
- description ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core48.Text, { size: "sm", c: "dimmed", children: description }) : null,
3414
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core48.Group, { children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core48.Button, { variant: "light", onClick: () => inputRef.current?.click(), children: actionLabel }) })
3931
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_core49.Stack, { align: mode === "inline" ? "flex-start" : "center", ta: mode === "inline" ? "left" : "center", gap: "sm", children: [
3932
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(UploadIcon, { size: "1.5rem" }),
3933
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_core49.Badge, { variant: "light", color: isError ? "red" : effectiveState === "selected" ? "blue" : effectiveState === "upload-pending" ? "violet" : "gray", children: effectiveState.replace("-", " ") }),
3934
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_core49.Text, { fw: 600, children: title }),
3935
+ description ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_core49.Text, { size: "sm", c: "dimmed", children: description }) : null,
3936
+ acceptedTypesLabel || maxSizeLabel ? /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_core49.Group, { gap: "xs", justify: mode === "inline" ? "flex-start" : "center", children: [
3937
+ acceptedTypesLabel ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_core49.Badge, { variant: "outline", color: "gray", children: acceptedTypesLabel }) : null,
3938
+ maxSizeLabel ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_core49.Badge, { variant: "outline", color: "gray", children: maxSizeLabel }) : null
3939
+ ] }) : null,
3940
+ selectedFiles.length ? /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_core49.Text, { size: "sm", children: [
3941
+ "Selected: ",
3942
+ selectedFiles.join(", ")
3943
+ ] }) : null,
3944
+ policyText ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_core49.Text, { size: "sm", c: isError ? "red.7" : "dimmed", children: policyText }) : null,
3945
+ error ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_core49.Text, { size: "sm", c: "red.7", role: "alert", children: error }) : null,
3946
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_core49.Group, { children: [
3947
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_core49.Button, { variant: "light", onClick: () => inputRef.current?.click(), disabled: isDisabled, children: actionLabel }),
3948
+ retryAction,
3949
+ removeAction
3950
+ ] })
3415
3951
  ] })
3416
3952
  ]
3417
3953
  }
@@ -3419,14 +3955,21 @@ function UploadDropzone({
3419
3955
  }
3420
3956
 
3421
3957
  // src/MediaField.tsx
3422
- var import_core49 = require("@mantine/core");
3423
- var import_jsx_runtime51 = require("react/jsx-runtime");
3958
+ var import_core50 = require("@mantine/core");
3959
+ var import_jsx_runtime54 = require("react/jsx-runtime");
3424
3960
  var stateLabels = {
3425
3961
  empty: { label: "Empty", color: "gray" },
3962
+ "drag-active": { label: "Drop to select", color: "violet" },
3426
3963
  selected: { label: "Selected", color: "blue" },
3964
+ "preview-loading": { label: "Preview loading", color: "violet" },
3427
3965
  saved: { label: "Saved", color: "teal" },
3428
3966
  invalid: { label: "Needs attention", color: "red" },
3429
- uploading: { label: "Uploading", color: "violet" }
3967
+ uploading: { label: "Uploading", color: "violet" },
3968
+ "upload-failed": { label: "Upload failed", color: "red" },
3969
+ "unsupported-type": { label: "Unsupported type", color: "red" },
3970
+ "too-large": { label: "Too large", color: "red" },
3971
+ removed: { label: "Removed", color: "gray" },
3972
+ readonly: { label: "Read only", color: "gray" }
3430
3973
  };
3431
3974
  function MediaField({
3432
3975
  label,
@@ -3439,41 +3982,60 @@ function MediaField({
3439
3982
  policyText,
3440
3983
  error,
3441
3984
  retryAction,
3985
+ replaceAction,
3442
3986
  onRemove,
3443
3987
  onReset,
3444
3988
  removeAction,
3445
3989
  resetAction,
3446
3990
  statusAction,
3991
+ acceptedTypes,
3992
+ maxSize,
3993
+ progress,
3994
+ readonly = false,
3447
3995
  state = "empty",
3448
3996
  mode = "stacked"
3449
3997
  }) {
3450
- const stateBadge = stateLabels[state];
3451
- const resolvedRemoveAction = removeAction ?? (onRemove ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core49.Button, { type: "button", variant: "light", color: "red", onClick: onRemove, children: "Remove" }) : null);
3452
- const resolvedResetAction = resetAction ?? (onReset ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core49.Button, { type: "button", variant: "default", onClick: onReset, children: "Reset" }) : null);
3453
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3998
+ const resolvedState = readonly ? "readonly" : state;
3999
+ const stateBadge = stateLabels[resolvedState];
4000
+ const resolvedRemoveAction = removeAction ?? (!readonly && onRemove ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_core50.Button, { type: "button", variant: "light", color: "red", onClick: onRemove, children: "Remove" }) : null);
4001
+ const resolvedResetAction = resetAction ?? (!readonly && onReset ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_core50.Button, { type: "button", variant: "default", onClick: onReset, children: "Reset" }) : null);
4002
+ const boundedProgress = typeof progress === "number" ? Math.max(0, Math.min(100, progress)) : void 0;
4003
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
3454
4004
  FormField,
3455
4005
  {
3456
4006
  label,
3457
4007
  description,
3458
4008
  error,
3459
- children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core49.Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_core49.Stack, { gap: "md", children: [
3460
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core49.Group, { justify: "flex-end", align: "center", gap: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_core49.Group, { gap: "xs", justify: "flex-end", children: [
3461
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core49.Badge, { variant: "light", color: stateBadge.color, children: stateBadge.label }),
4009
+ children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_core50.Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_core50.Stack, { gap: "md", children: [
4010
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_core50.Group, { justify: "flex-end", align: "center", gap: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_core50.Group, { gap: "xs", justify: "flex-end", children: [
4011
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_core50.Badge, { variant: "light", color: stateBadge.color, children: stateBadge.label }),
3462
4012
  statusAction
3463
4013
  ] }) }),
3464
4014
  preview ? preview : null,
3465
- uploadControl || urlInput ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [
3466
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core49.Divider, {}),
3467
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_core49.Stack, { gap: "sm", style: mode === "split" ? { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))" } : void 0, children: [
4015
+ typeof boundedProgress === "number" ? /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_core50.Stack, { gap: 4, children: [
4016
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_core50.Progress, { value: boundedProgress, "aria-label": "Upload progress" }),
4017
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_core50.Text, { size: "xs", c: "dimmed", children: [
4018
+ boundedProgress,
4019
+ "% complete"
4020
+ ] })
4021
+ ] }) : null,
4022
+ (uploadControl || urlInput) && !readonly ? /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_jsx_runtime54.Fragment, { children: [
4023
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_core50.Divider, {}),
4024
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_core50.Stack, { gap: "sm", style: mode === "split" ? { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))" } : void 0, children: [
3468
4025
  uploadControl,
3469
4026
  urlInput
3470
4027
  ] })
3471
4028
  ] }) : null,
3472
- value ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core49.Text, { size: "sm", c: "dimmed", style: { wordBreak: "break-all" }, children: value }) : null,
3473
- helpText ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core49.Text, { size: "sm", c: "dimmed", children: helpText }) : null,
3474
- policyText ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core49.Text, { size: "sm", c: error ? "red.7" : "dimmed", children: policyText }) : null,
4029
+ value ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_core50.Text, { size: "sm", c: "dimmed", style: { wordBreak: "break-all" }, children: value }) : null,
4030
+ helpText ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_core50.Text, { size: "sm", c: "dimmed", children: helpText }) : null,
4031
+ acceptedTypes || maxSize ? /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_core50.Group, { gap: "xs", wrap: "wrap", children: [
4032
+ acceptedTypes ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_core50.Badge, { variant: "outline", color: "gray", children: acceptedTypes }) : null,
4033
+ maxSize ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_core50.Badge, { variant: "outline", color: "gray", children: maxSize }) : null
4034
+ ] }) : null,
4035
+ policyText ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_core50.Text, { size: "sm", c: error ? "red.7" : "dimmed", children: policyText }) : null,
3475
4036
  typeof error !== "string" && error ? error : null,
3476
- resolvedRemoveAction || resolvedResetAction ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_core49.Group, { gap: "sm", children: [
4037
+ replaceAction || resolvedRemoveAction || resolvedResetAction || retryAction ? /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_core50.Group, { gap: "sm", children: [
4038
+ replaceAction,
3477
4039
  resolvedResetAction,
3478
4040
  retryAction,
3479
4041
  resolvedRemoveAction
@@ -3484,53 +4046,68 @@ function MediaField({
3484
4046
  }
3485
4047
 
3486
4048
  // src/MediaCard.tsx
3487
- var import_core50 = require("@mantine/core");
3488
- var import_jsx_runtime52 = require("react/jsx-runtime");
4049
+ var import_core51 = require("@mantine/core");
4050
+ var import_jsx_runtime55 = require("react/jsx-runtime");
3489
4051
  function MediaCard({ title, image, description, status, overlay, actions = [] }) {
3490
4052
  const EyeIcon = GdsIcons.Eye;
3491
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_core50.Card, { withBorder: true, radius: "lg", padding: "md", children: [
3492
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_core50.Card.Section, { pos: "relative", children: [
4053
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_core51.Card, { withBorder: true, radius: "lg", padding: "md", children: [
4054
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_core51.Card.Section, { pos: "relative", children: [
3493
4055
  image,
3494
- overlay ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { style: { position: "absolute", inset: 12, display: "flex", justifyContent: "flex-end", alignItems: "flex-start" }, children: overlay }) : null
4056
+ overlay ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { style: { position: "absolute", inset: 12, display: "flex", justifyContent: "flex-end", alignItems: "flex-start" }, children: overlay }) : null
3495
4057
  ] }),
3496
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_core50.Stack, { gap: "sm", mt: "md", children: [
3497
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_core50.Group, { justify: "space-between", align: "flex-start", children: [
3498
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_core50.Stack, { gap: 4, children: [
3499
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_core50.Title, { order: 4, children: title }),
3500
- description ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_core50.Text, { size: "sm", c: "dimmed", lineClamp: 2, children: description }) : null
4058
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_core51.Stack, { gap: "sm", mt: "md", children: [
4059
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_core51.Group, { justify: "space-between", align: "flex-start", children: [
4060
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_core51.Stack, { gap: 4, children: [
4061
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_core51.Title, { order: 4, children: title }),
4062
+ description ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_core51.Text, { size: "sm", c: "dimmed", lineClamp: 2, children: description }) : null
3501
4063
  ] }),
3502
- status ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_core50.Badge, { variant: "light", children: status }) : null
4064
+ status ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_core51.Badge, { variant: "light", children: status }) : null
3503
4065
  ] }),
3504
- actions.length ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_core50.Group, { justify: "flex-end", gap: "xs", children: actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_core50.ActionIcon, { variant: "light", "aria-label": action.label, onClick: action.onClick, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(EyeIcon, { size: "1rem" }) }, action.label)) }) : null
4066
+ actions.length ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_core51.Group, { justify: "flex-end", gap: "xs", children: actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_core51.ActionIcon, { variant: "light", "aria-label": action.label, onClick: action.onClick, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(EyeIcon, { size: "1rem" }) }, action.label)) }) : null
3505
4067
  ] })
3506
4068
  ] });
3507
4069
  }
3508
4070
 
3509
4071
  // src/AccessSummary.tsx
3510
- var import_core51 = require("@mantine/core");
3511
- var import_jsx_runtime53 = require("react/jsx-runtime");
3512
- function AccessSummary({ title, roles, scope, blocked = false, description }) {
3513
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_core51.Card, { withBorder: true, radius: "lg", padding: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_core51.Stack, { gap: "sm", children: [
3514
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_core51.Group, { justify: "space-between", align: "center", children: [
3515
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_core51.Title, { order: 4, children: title }),
3516
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_core51.Badge, { color: blocked ? "red" : "teal", variant: "light", children: blocked ? "Blocked" : "Allowed" })
4072
+ var import_core52 = require("@mantine/core");
4073
+ var import_jsx_runtime56 = require("react/jsx-runtime");
4074
+ var accessStateMeta = {
4075
+ allowed: { label: "Allowed", color: "teal" },
4076
+ blocked: { label: "Blocked", color: "red" },
4077
+ forbidden: { label: "Forbidden", color: "red" },
4078
+ expired: { label: "Expired", color: "orange" },
4079
+ "permission-limited": { label: "Permission limited", color: "grape" }
4080
+ };
4081
+ function AccessSummary({ title, roles, scope, blocked = false, state, owner, recoveryHint, description }) {
4082
+ const resolvedState = state ?? (blocked ? "blocked" : "allowed");
4083
+ const meta = accessStateMeta[resolvedState];
4084
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_core52.Card, { withBorder: true, radius: "lg", padding: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_core52.Stack, { gap: "sm", children: [
4085
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_core52.Group, { justify: "space-between", align: "center", children: [
4086
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_core52.Title, { order: 4, children: title }),
4087
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_core52.Badge, { color: meta.color, variant: "light", children: meta.label })
3517
4088
  ] }),
3518
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_core51.Group, { gap: "xs", children: roles.map((role) => /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_core51.Badge, { variant: "outline", children: role }, role)) }),
3519
- scope ? /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_core51.Text, { size: "sm", c: "dimmed", children: [
4089
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_core52.Group, { gap: "xs", children: roles.map((role) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_core52.Badge, { variant: "outline", children: role }, role)) }),
4090
+ scope ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_core52.Text, { size: "sm", c: "dimmed", children: [
3520
4091
  "Scope: ",
3521
4092
  scope
3522
4093
  ] }) : null,
3523
- description ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_core51.Text, { size: "sm", children: description }) : null
4094
+ owner ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_core52.Text, { size: "sm", c: "dimmed", children: [
4095
+ "Owner: ",
4096
+ owner
4097
+ ] }) : null,
4098
+ recoveryHint ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_core52.Text, { size: "sm", c: resolvedState === "allowed" ? "dimmed" : "red.7", children: recoveryHint }) : null,
4099
+ description ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_core52.Text, { size: "sm", children: description }) : null
3524
4100
  ] }) });
3525
4101
  }
3526
4102
 
3527
4103
  // src/AccessRecoveryPanel.tsx
3528
- var import_core52 = require("@mantine/core");
4104
+ var import_core53 = require("@mantine/core");
3529
4105
  var import_gds_theme5 = require("@doneisbetter/gds-theme");
3530
- var import_jsx_runtime54 = require("react/jsx-runtime");
4106
+ var import_jsx_runtime57 = require("react/jsx-runtime");
3531
4107
  var stateBlockVariantByState = {
3532
4108
  unauthenticated: "permission",
3533
4109
  "expired-session": "info",
4110
+ timeout: "error",
3534
4111
  forbidden: "permission",
3535
4112
  missing: "error",
3536
4113
  unavailable: "error"
@@ -3544,6 +4121,10 @@ var defaultCopyByState = {
3544
4121
  title: "Session expired",
3545
4122
  description: "Sign in again or retry to continue where you left off."
3546
4123
  },
4124
+ timeout: {
4125
+ title: "Request timed out",
4126
+ description: "The recovery action took too long. Retry or choose a safe destination."
4127
+ },
3547
4128
  forbidden: {
3548
4129
  title: "You do not have access",
3549
4130
  description: "This content is outside your current permissions or scope."
@@ -3575,6 +4156,12 @@ function defaultActionsForState(state, {
3575
4156
  secondary: retryAction && signInAction ? retryAction : backAction,
3576
4157
  tertiary: supportAction ?? null
3577
4158
  };
4159
+ case "timeout":
4160
+ return {
4161
+ primary: retryAction ?? backAction,
4162
+ secondary: retryAction && backAction ? backAction : supportAction ?? null,
4163
+ tertiary: retryAction && backAction ? supportAction ?? null : null
4164
+ };
3578
4165
  case "forbidden":
3579
4166
  return { primary: backAction, secondary: supportAction ?? null, tertiary: null };
3580
4167
  case "missing":
@@ -3596,7 +4183,7 @@ function ActionGroup({
3596
4183
  if (actions.length === 0) {
3597
4184
  return null;
3598
4185
  }
3599
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_core52.Group, { gap: "sm", justify: "center", wrap: "wrap", children: actions.map((actionConfig, index) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
4186
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_core53.Group, { gap: "sm", justify: "center", wrap: "wrap", children: actions.map((actionConfig, index) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
3600
4187
  SemanticButton,
3601
4188
  {
3602
4189
  action: actionConfig.action,
@@ -3630,14 +4217,14 @@ function AccessRecoveryPanel({
3630
4217
  onBack,
3631
4218
  supportAction
3632
4219
  });
3633
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
4220
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
3634
4221
  StateBlock,
3635
4222
  {
3636
4223
  variant: stateBlockVariantByState[state],
3637
4224
  compact,
3638
4225
  title: title ?? t(`gds.accessRecovery.${state}.title`, defaultCopy.title),
3639
4226
  description: description ?? t(`gds.accessRecovery.${state}.description`, defaultCopy.description),
3640
- action: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
4227
+ action: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
3641
4228
  ActionGroup,
3642
4229
  {
3643
4230
  primaryAction: primaryAction ?? defaults.primary,
@@ -3649,9 +4236,141 @@ function AccessRecoveryPanel({
3649
4236
  );
3650
4237
  }
3651
4238
 
4239
+ // src/GdsForm.client.tsx
4240
+ var import_react12 = require("react");
4241
+ var import_core54 = require("@mantine/core");
4242
+ var import_jsx_runtime58 = require("react/jsx-runtime");
4243
+ function createFieldState(value) {
4244
+ return { value, touched: false, dirty: false };
4245
+ }
4246
+ function createSnapshot(values) {
4247
+ const fields = Object.entries(values).reduce((acc, [field, value]) => {
4248
+ acc[field] = createFieldState(value);
4249
+ return acc;
4250
+ }, {});
4251
+ return { fields, issues: [], submitState: "idle" };
4252
+ }
4253
+ function gdsFormReducer(state, action) {
4254
+ switch (action.type) {
4255
+ case "set-field": {
4256
+ const current = state.fields[action.field] ?? createFieldState("");
4257
+ return {
4258
+ ...state,
4259
+ fields: {
4260
+ ...state.fields,
4261
+ [action.field]: {
4262
+ value: action.value,
4263
+ touched: current.touched,
4264
+ dirty: true
4265
+ }
4266
+ }
4267
+ };
4268
+ }
4269
+ case "touch-field": {
4270
+ const current = state.fields[action.field] ?? createFieldState("");
4271
+ return {
4272
+ ...state,
4273
+ fields: {
4274
+ ...state.fields,
4275
+ [action.field]: { ...current, touched: true }
4276
+ }
4277
+ };
4278
+ }
4279
+ case "set-issues":
4280
+ return { ...state, issues: [...action.issues] };
4281
+ case "set-submit-state":
4282
+ return { ...state, submitState: action.submitState, submitError: action.submitError };
4283
+ case "reset":
4284
+ return createSnapshot(action.values ?? {});
4285
+ default:
4286
+ return state;
4287
+ }
4288
+ }
4289
+ function sortIssues(issues) {
4290
+ const weight = { blocking: 0, warning: 1, info: 2 };
4291
+ return [...issues].sort((a, b) => weight[a.severity] - weight[b.severity]);
4292
+ }
4293
+ function useGdsForm({
4294
+ initialValues,
4295
+ validate,
4296
+ validateAsync,
4297
+ onSubmit
4298
+ }) {
4299
+ const [snapshot, dispatch] = (0, import_react12.useReducer)(gdsFormReducer, initialValues, createSnapshot);
4300
+ const submit = async () => {
4301
+ dispatch({ type: "set-submit-state", submitState: "validating" });
4302
+ const syncIssues = sortIssues(validate ? validate(snapshot) : []);
4303
+ let mergedIssues = syncIssues;
4304
+ if (syncIssues.filter((issue) => issue.severity === "blocking").length === 0 && validateAsync) {
4305
+ const asyncIssues = sortIssues(await validateAsync(snapshot));
4306
+ mergedIssues = sortIssues([...syncIssues, ...asyncIssues]);
4307
+ }
4308
+ dispatch({ type: "set-issues", issues: mergedIssues });
4309
+ if (mergedIssues.some((issue) => issue.severity === "blocking")) {
4310
+ dispatch({ type: "set-submit-state", submitState: "error", submitError: "Please resolve blocking validation issues." });
4311
+ return false;
4312
+ }
4313
+ dispatch({ type: "set-submit-state", submitState: "submitting" });
4314
+ try {
4315
+ await onSubmit(
4316
+ Object.entries(snapshot.fields).reduce((acc, [field, state]) => {
4317
+ acc[field] = state.value;
4318
+ return acc;
4319
+ }, {})
4320
+ );
4321
+ dispatch({ type: "set-submit-state", submitState: "success" });
4322
+ return true;
4323
+ } catch (error) {
4324
+ dispatch({
4325
+ type: "set-submit-state",
4326
+ submitState: "error",
4327
+ submitError: error instanceof Error ? error.message : "Submission failed."
4328
+ });
4329
+ return false;
4330
+ }
4331
+ };
4332
+ return (0, import_react12.useMemo)(
4333
+ () => ({
4334
+ snapshot,
4335
+ setFieldValue: (field, value) => dispatch({ type: "set-field", field, value }),
4336
+ touchField: (field) => dispatch({ type: "touch-field", field }),
4337
+ submit,
4338
+ retrySubmit: submit
4339
+ }),
4340
+ [snapshot]
4341
+ );
4342
+ }
4343
+ var GdsFormContext = (0, import_react12.createContext)(null);
4344
+ function GdsFormProvider({ snapshot, children }) {
4345
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(GdsFormContext.Provider, { value: { snapshot }, children });
4346
+ }
4347
+ function useGdsFormSnapshot() {
4348
+ const context = (0, import_react12.useContext)(GdsFormContext);
4349
+ if (!context) {
4350
+ throw new Error("useGdsFormSnapshot must be used within GdsFormProvider.");
4351
+ }
4352
+ return context.snapshot;
4353
+ }
4354
+ function FormErrorSummary({ title = "Please review the following issues." }) {
4355
+ const snapshot = useGdsFormSnapshot();
4356
+ const blocking = snapshot.issues.filter((issue) => issue.severity === "blocking");
4357
+ if (blocking.length === 0) {
4358
+ return null;
4359
+ }
4360
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_core54.Alert, { color: "red", title, children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_core54.Stack, { gap: 4, children: blocking.map((issue) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_core54.Anchor, { href: `#${issue.field}`, children: issue.message }, `${issue.field}-${issue.message}`)) }) });
4361
+ }
4362
+ function ValidatedFieldMessage({ field }) {
4363
+ const snapshot = useGdsFormSnapshot();
4364
+ const issue = snapshot.issues.find((item) => item.field === field && item.severity === "blocking");
4365
+ if (!issue) {
4366
+ return null;
4367
+ }
4368
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_core54.Text, { size: "xs", c: "red.7", id: `${field}-error`, children: issue.message });
4369
+ }
4370
+
3652
4371
  // src/PageHeader.tsx
3653
- var import_core53 = require("@mantine/core");
3654
- var import_jsx_runtime55 = require("react/jsx-runtime");
4372
+ var import_core55 = require("@mantine/core");
4373
+ var import_jsx_runtime59 = require("react/jsx-runtime");
3655
4374
  function PageHeader({
3656
4375
  title,
3657
4376
  description,
@@ -3662,19 +4381,19 @@ function PageHeader({
3662
4381
  }) {
3663
4382
  const resolvedDescription = description ?? subtitle;
3664
4383
  const eyebrowProps = eyebrowVariant === "ornamental" ? { tt: "uppercase", style: { letterSpacing: "0.12em" } } : {};
3665
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_core53.Group, { justify: "space-between", align: "flex-start", gap: "lg", wrap: "wrap", children: [
3666
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_core53.Stack, { gap: "xs", children: [
3667
- eyebrow && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_core53.Text, { size: "xs", fw: 700, c: "dimmed", ...eyebrowProps, children: eyebrow }),
3668
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_core53.Title, { order: 1, children: title }),
3669
- resolvedDescription && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_core53.Text, { c: "dimmed", maw: 720, children: resolvedDescription })
4384
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_core55.Group, { justify: "space-between", align: "flex-start", gap: "lg", wrap: "wrap", children: [
4385
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_core55.Stack, { gap: "xs", children: [
4386
+ eyebrow && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_core55.Text, { size: "xs", fw: 700, c: "dimmed", ...eyebrowProps, children: eyebrow }),
4387
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_core55.Title, { order: 1, children: title }),
4388
+ resolvedDescription && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_core55.Text, { c: "dimmed", maw: 720, children: resolvedDescription })
3670
4389
  ] }),
3671
- actions ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_core53.Box, { children: actions }) : null
4390
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_core55.Box, { children: actions }) : null
3672
4391
  ] });
3673
4392
  }
3674
4393
 
3675
4394
  // src/FilterDrawer.tsx
3676
- var import_core54 = require("@mantine/core");
3677
- var import_jsx_runtime56 = require("react/jsx-runtime");
4395
+ var import_core56 = require("@mantine/core");
4396
+ var import_jsx_runtime60 = require("react/jsx-runtime");
3678
4397
  function FilterDrawer({
3679
4398
  opened,
3680
4399
  onClose,
@@ -3690,8 +4409,8 @@ function FilterDrawer({
3690
4409
  }) {
3691
4410
  const resolvedPrimaryAction = applyAction ?? primaryAction;
3692
4411
  const resolvedSecondaryAction = resetAction ?? secondaryAction;
3693
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
3694
- import_core54.Drawer,
4412
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
4413
+ import_core56.Drawer,
3695
4414
  {
3696
4415
  opened,
3697
4416
  onClose,
@@ -3699,11 +4418,11 @@ function FilterDrawer({
3699
4418
  position: mode === "bottom-sheet" ? "bottom" : "right",
3700
4419
  size: mode === "bottom-sheet" ? "auto" : "md",
3701
4420
  radius: mode === "bottom-sheet" ? "xl" : void 0,
3702
- children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_core54.Stack, { gap: "md", children: [
3703
- description ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_core54.Text, { size: "sm", c: "dimmed", children: description }) : null,
4421
+ children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_core56.Stack, { gap: "md", children: [
4422
+ description ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_core56.Text, { size: "sm", c: "dimmed", children: description }) : null,
3704
4423
  children,
3705
- resolvedPrimaryAction || resolvedSecondaryAction || closeAction ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_core54.Group, { justify: "space-between", mt: "md", children: [
3706
- /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_core54.Group, { gap: "sm", children: [
4424
+ resolvedPrimaryAction || resolvedSecondaryAction || closeAction ? /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_core56.Group, { justify: "space-between", mt: "md", children: [
4425
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_core56.Group, { gap: "sm", children: [
3707
4426
  closeAction,
3708
4427
  resolvedSecondaryAction
3709
4428
  ] }),
@@ -3715,8 +4434,8 @@ function FilterDrawer({
3715
4434
  }
3716
4435
 
3717
4436
  // src/PlaceholderPanel.tsx
3718
- var import_core55 = require("@mantine/core");
3719
- var import_jsx_runtime57 = require("react/jsx-runtime");
4437
+ var import_core57 = require("@mantine/core");
4438
+ var import_jsx_runtime61 = require("react/jsx-runtime");
3720
4439
  function PlaceholderPanel({
3721
4440
  title,
3722
4441
  description,
@@ -3726,16 +4445,16 @@ function PlaceholderPanel({
3726
4445
  mode
3727
4446
  }) {
3728
4447
  if (mode === "live" && children) {
3729
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_jsx_runtime57.Fragment, { children });
4448
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_jsx_runtime61.Fragment, { children });
3730
4449
  }
3731
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_core55.Card, { children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_core55.Stack, { gap: "md", children: [
3732
- badge ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_core55.Badge, { variant: "light", color: "blue", w: "fit-content", children: badge }) : null,
3733
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_core55.Stack, { gap: "xs", children: [
3734
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_core55.Title, { order: 4, children: title }),
3735
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_core55.Text, { c: "dimmed", children: description })
4450
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_core57.Card, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_core57.Stack, { gap: "md", children: [
4451
+ badge ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_core57.Badge, { variant: "light", color: "blue", w: "fit-content", children: badge }) : null,
4452
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_core57.Stack, { gap: "xs", children: [
4453
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_core57.Title, { order: 4, children: title }),
4454
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_core57.Text, { c: "dimmed", children: description })
3736
4455
  ] }),
3737
- footer ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_core55.Text, { size: "sm", children: footer }) : null,
3738
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
4456
+ footer ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_core57.Text, { size: "sm", children: footer }) : null,
4457
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
3739
4458
  StateBlock,
3740
4459
  {
3741
4460
  variant: "not-enough-data",
@@ -3748,8 +4467,8 @@ function PlaceholderPanel({
3748
4467
  }
3749
4468
 
3750
4469
  // src/SimpleDataTable.tsx
3751
- var import_core56 = require("@mantine/core");
3752
- var import_jsx_runtime58 = require("react/jsx-runtime");
4470
+ var import_core58 = require("@mantine/core");
4471
+ var import_jsx_runtime62 = require("react/jsx-runtime");
3753
4472
  function SimpleDataTable({
3754
4473
  columns,
3755
4474
  rows,
@@ -3760,23 +4479,331 @@ function SimpleDataTable({
3760
4479
  getRowKey
3761
4480
  }) {
3762
4481
  if (error) {
3763
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(StateBlock, { variant: "error", title: "Unable to load data", description: error, compact: true });
4482
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(StateBlock, { variant: "error", title: "Unable to load data", description: error, compact: true });
3764
4483
  }
3765
4484
  if (loading) {
3766
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(StateBlock, { variant: "loading", title: "Loading data", description: "Please wait while the shared dataset is prepared.", compact: true });
4485
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(StateBlock, { variant: "loading", title: "Loading data", description: "Please wait while the shared dataset is prepared.", compact: true });
3767
4486
  }
3768
4487
  if (!rows.length) {
3769
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(StateBlock, { variant: "empty", title: emptyTitle, description: emptyDescription, compact: true });
4488
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(StateBlock, { variant: "empty", title: emptyTitle, description: emptyDescription, compact: true });
3770
4489
  }
3771
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_core56.ScrollArea, { children: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_core56.Table, { striped: true, highlightOnHover: true, withTableBorder: true, withColumnBorders: true, children: [
3772
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_core56.Table.Thead, { children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_core56.Table.Tr, { children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_core56.Table.Th, { children: column.header }, String(column.key))) }) }),
3773
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_core56.Table.Tbody, { children: rows.map((row, index) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_core56.Table.Tr, { children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_core56.Table.Td, { children: column.render ? column.render(row) : String(row[column.key] ?? "") }, String(column.key))) }, getRowKey ? getRowKey(row, index) : index)) })
4490
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_core58.ScrollArea, { children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_core58.Table, { striped: true, highlightOnHover: true, withTableBorder: true, withColumnBorders: true, children: [
4491
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_core58.Table.Thead, { children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_core58.Table.Tr, { children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_core58.Table.Th, { children: column.header }, String(column.key))) }) }),
4492
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_core58.Table.Tbody, { children: rows.map((row, index) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_core58.Table.Tr, { children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_core58.Table.Td, { children: column.render ? column.render(row) : String(row[column.key] ?? "") }, String(column.key))) }, getRowKey ? getRowKey(row, index) : index)) })
4493
+ ] }) });
4494
+ }
4495
+
4496
+ // src/AdvancedDataTable.client.tsx
4497
+ var import_react13 = require("react");
4498
+ var import_core59 = require("@mantine/core");
4499
+ var import_jsx_runtime63 = require("react/jsx-runtime");
4500
+ function compareValues(a, b) {
4501
+ if (typeof a === "number" && typeof b === "number") {
4502
+ return a - b;
4503
+ }
4504
+ return String(a).localeCompare(String(b), void 0, { numeric: true, sensitivity: "base" });
4505
+ }
4506
+ function AdvancedDataTable({
4507
+ rows,
4508
+ columns,
4509
+ rowId,
4510
+ loading = false,
4511
+ error = null,
4512
+ density: densityProp,
4513
+ stickyHeader = true,
4514
+ stickyHeaderOffset = 0,
4515
+ selectedRowIds,
4516
+ onSelectedRowIdsChange,
4517
+ sortBy: sortByProp,
4518
+ sortDirection: sortDirectionProp,
4519
+ onSortChange,
4520
+ responsiveFallback = "stacked-cards"
4521
+ }) {
4522
+ const [densityState, setDensityState] = (0, import_react13.useState)(densityProp ?? "comfortable");
4523
+ const [sortState, setSortState] = (0, import_react13.useState)({ key: sortByProp ?? null, direction: sortDirectionProp ?? "asc" });
4524
+ const [selectionState, setSelectionState] = (0, import_react13.useState)([]);
4525
+ const density = densityProp ?? densityState;
4526
+ const sortBy = sortByProp ?? sortState.key;
4527
+ const sortDirection = sortDirectionProp ?? sortState.direction;
4528
+ const selection = selectedRowIds ?? selectionState;
4529
+ const sortedRows = (0, import_react13.useMemo)(() => {
4530
+ if (!sortBy) {
4531
+ return rows;
4532
+ }
4533
+ const column = columns.find((item) => item.key === sortBy);
4534
+ if (!column) {
4535
+ return rows;
4536
+ }
4537
+ const next = [...rows].sort((left, right) => {
4538
+ const leftValue = column.sortAccessor ? column.sortAccessor(left) : String(left[column.key] ?? "");
4539
+ const rightValue = column.sortAccessor ? column.sortAccessor(right) : String(right[column.key] ?? "");
4540
+ const result = compareValues(leftValue, rightValue);
4541
+ return sortDirection === "asc" ? result : -result;
4542
+ });
4543
+ return next;
4544
+ }, [rows, columns, sortBy, sortDirection]);
4545
+ const allIds = (0, import_react13.useMemo)(() => sortedRows.map((row, index) => rowId(row, index)), [sortedRows, rowId]);
4546
+ const allSelected = allIds.length > 0 && allIds.every((id) => selection.includes(id));
4547
+ if (error) {
4548
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(StateBlock, { variant: "error", title: "Unable to load table", description: error, compact: true });
4549
+ }
4550
+ if (loading) {
4551
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(StateBlock, { variant: "loading", title: "Loading table", description: "Preparing enterprise data grid.", compact: true });
4552
+ }
4553
+ if (!rows.length) {
4554
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
4555
+ StateBlock,
4556
+ {
4557
+ variant: "empty",
4558
+ title: "No rows available",
4559
+ description: "Adjust filters or broaden scope to populate this table.",
4560
+ compact: true
4561
+ }
4562
+ );
4563
+ }
4564
+ const horizontalSpacing = density === "compact" ? "xs" : "md";
4565
+ const verticalSpacing = density === "compact" ? 6 : 10;
4566
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_core59.Stack, { gap: "sm", children: [
4567
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_core59.Group, { justify: "space-between", align: "center", children: [
4568
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_core59.Text, { size: "sm", fw: 600, children: [
4569
+ rows.length,
4570
+ " rows"
4571
+ ] }),
4572
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
4573
+ import_core59.SegmentedControl,
4574
+ {
4575
+ size: "xs",
4576
+ value: density,
4577
+ onChange: (value) => setDensityState(value),
4578
+ data: [
4579
+ { label: "Compact", value: "compact" },
4580
+ { label: "Comfortable", value: "comfortable" }
4581
+ ]
4582
+ }
4583
+ )
4584
+ ] }),
4585
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_core59.ScrollArea, { children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
4586
+ import_core59.Table,
4587
+ {
4588
+ stickyHeader,
4589
+ stickyHeaderOffset,
4590
+ withTableBorder: true,
4591
+ highlightOnHover: true,
4592
+ striped: true,
4593
+ horizontalSpacing,
4594
+ verticalSpacing,
4595
+ children: [
4596
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_core59.Table.Thead, { children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_core59.Table.Tr, { children: [
4597
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_core59.Table.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
4598
+ import_core59.Checkbox,
4599
+ {
4600
+ "aria-label": "Select all rows",
4601
+ checked: allSelected,
4602
+ indeterminate: !allSelected && selection.length > 0,
4603
+ onChange: (event) => {
4604
+ const next = event.currentTarget.checked ? allIds : [];
4605
+ if (onSelectedRowIdsChange) {
4606
+ onSelectedRowIdsChange(next);
4607
+ } else {
4608
+ setSelectionState(next);
4609
+ }
4610
+ }
4611
+ }
4612
+ ) }),
4613
+ columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_core59.Table.Th, { style: column.width ? { width: column.width } : void 0, children: column.sortable ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
4614
+ "button",
4615
+ {
4616
+ type: "button",
4617
+ "aria-label": `Sort by ${column.label}`,
4618
+ onClick: () => {
4619
+ const nextDirection = sortBy === column.key && sortDirection === "asc" ? "desc" : "asc";
4620
+ if (onSortChange) {
4621
+ onSortChange(column.key, nextDirection);
4622
+ } else {
4623
+ setSortState({ key: column.key, direction: nextDirection });
4624
+ }
4625
+ },
4626
+ children: column.label
4627
+ }
4628
+ ) : column.label }, column.key))
4629
+ ] }) }),
4630
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_core59.Table.Tbody, { children: sortedRows.map((row, index) => {
4631
+ const id = rowId(row, index);
4632
+ const checked = selection.includes(id);
4633
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_core59.Table.Tr, { children: [
4634
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_core59.Table.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
4635
+ import_core59.Checkbox,
4636
+ {
4637
+ "aria-label": `Select row ${id}`,
4638
+ checked,
4639
+ onChange: () => {
4640
+ const next = checked ? selection.filter((item) => item !== id) : [...selection, id];
4641
+ if (onSelectedRowIdsChange) {
4642
+ onSelectedRowIdsChange(next);
4643
+ } else {
4644
+ setSelectionState(next);
4645
+ }
4646
+ }
4647
+ }
4648
+ ) }),
4649
+ columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_core59.Table.Td, { children: column.render ? column.render(row) : String(row[column.key] ?? "") }, column.key))
4650
+ ] }, id);
4651
+ }) })
4652
+ ]
4653
+ }
4654
+ ) }),
4655
+ responsiveFallback === "stacked-cards" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_core59.Stack, { gap: "xs", children: sortedRows.slice(0, 3).map((row, index) => {
4656
+ const id = rowId(row, index);
4657
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
4658
+ StateBlock,
4659
+ {
4660
+ variant: "info",
4661
+ compact: true,
4662
+ title: String(row[columns[0]?.key] ?? id),
4663
+ description: columns.slice(1, 3).map((column) => `${column.label}: ${String(row[column.key] ?? "")}`).join(" | ")
4664
+ },
4665
+ `card-${id}`
4666
+ );
4667
+ }) }) : null
4668
+ ] });
4669
+ }
4670
+
4671
+ // src/OverlayManager.client.tsx
4672
+ var import_react14 = require("react");
4673
+ var import_jsx_runtime64 = require("react/jsx-runtime");
4674
+ var OverlayManagerContext = (0, import_react14.createContext)(null);
4675
+ function OverlayManagerProvider({ children }) {
4676
+ const [stack, setStack] = (0, import_react14.useState)([]);
4677
+ const value = (0, import_react14.useMemo)(() => ({
4678
+ stack,
4679
+ registerOverlay: (overlay) => {
4680
+ setStack((current) => {
4681
+ const without = current.filter((item) => item.id !== overlay.id);
4682
+ return [...without, overlay];
4683
+ });
4684
+ },
4685
+ unregisterOverlay: (id) => {
4686
+ setStack((current) => current.filter((item) => item.id !== id));
4687
+ },
4688
+ isTopMost: (id) => stack.length > 0 && stack[stack.length - 1]?.id === id,
4689
+ requestClose: (id, reason) => {
4690
+ if (stack.length === 0 || stack[stack.length - 1]?.id !== id) {
4691
+ return null;
4692
+ }
4693
+ return reason;
4694
+ }
4695
+ }), [stack]);
4696
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(OverlayManagerContext.Provider, { value, children });
4697
+ }
4698
+ function useOverlayManager() {
4699
+ const context = (0, import_react14.useContext)(OverlayManagerContext);
4700
+ if (!context) {
4701
+ throw new Error("useOverlayManager must be used within OverlayManagerProvider.");
4702
+ }
4703
+ return context;
4704
+ }
4705
+
4706
+ // src/CommandPalette.client.tsx
4707
+ var import_react15 = require("react");
4708
+ var import_core60 = require("@mantine/core");
4709
+ var import_jsx_runtime65 = require("react/jsx-runtime");
4710
+ var CommandPaletteContext = (0, import_react15.createContext)(null);
4711
+ function normalize(text) {
4712
+ return text.trim().toLowerCase();
4713
+ }
4714
+ function scoreCommand(command, query, recentUse) {
4715
+ const q = normalize(query);
4716
+ if (!q) {
4717
+ return 0;
4718
+ }
4719
+ const label = normalize(command.label);
4720
+ const keywords = command.keywords?.map(normalize) ?? [];
4721
+ const prefix = label.startsWith(q) ? 1 : 0;
4722
+ const keyword = keywords.some((item) => item.includes(q)) ? 1 : 0;
4723
+ const recent = recentUse[command.id] ? 1 : 0;
4724
+ return 0.6 * prefix + 0.3 * keyword + 0.1 * recent;
4725
+ }
4726
+ function CommandRegistryProvider({ children }) {
4727
+ const [commands, setCommands] = (0, import_react15.useState)([]);
4728
+ const [opened, setOpened] = (0, import_react15.useState)(false);
4729
+ const value = (0, import_react15.useMemo)(() => ({
4730
+ commands,
4731
+ registerCommands: (next) => setCommands(next),
4732
+ open: () => setOpened(true),
4733
+ close: () => setOpened(false)
4734
+ }), [commands]);
4735
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(CommandPaletteContext.Provider, { value, children: [
4736
+ children,
4737
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(CommandPalette, { opened, onClose: () => setOpened(false) })
4738
+ ] });
4739
+ }
4740
+ function useCommandLauncher() {
4741
+ const context = (0, import_react15.useContext)(CommandPaletteContext);
4742
+ if (!context) {
4743
+ throw new Error("useCommandLauncher must be used within CommandRegistryProvider.");
4744
+ }
4745
+ return {
4746
+ open: context.open,
4747
+ close: context.close,
4748
+ registerCommands: context.registerCommands
4749
+ };
4750
+ }
4751
+ function CommandPalette({ opened, onClose }) {
4752
+ const contextValue = (0, import_react15.useContext)(CommandPaletteContext);
4753
+ if (!contextValue) {
4754
+ throw new Error("CommandPalette must be used within CommandRegistryProvider.");
4755
+ }
4756
+ const registry = contextValue;
4757
+ const [query, setQuery] = (0, import_react15.useState)("");
4758
+ const [recentUse, setRecentUse] = (0, import_react15.useState)({});
4759
+ const enabledCommands = registry.commands.filter((command) => command.enabledWhen ? command.enabledWhen() : true);
4760
+ const filteredCommands = [...enabledCommands].map((command) => ({ command, score: scoreCommand(command, query, recentUse) })).filter(({ command, score }) => normalize(query) === "" || score > 0 || normalize(command.label).includes(normalize(query))).sort((a, b) => b.score - a.score).map((item) => item.command);
4761
+ (0, import_react15.useEffect)(() => {
4762
+ function onKeyDown(event) {
4763
+ if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
4764
+ event.preventDefault();
4765
+ registry.open();
4766
+ }
4767
+ if (event.key === "Escape" && opened) {
4768
+ onClose();
4769
+ }
4770
+ }
4771
+ window.addEventListener("keydown", onKeyDown);
4772
+ return () => window.removeEventListener("keydown", onKeyDown);
4773
+ }, [registry, opened, onClose]);
4774
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_core60.Modal, { opened, onClose, title: "Quick actions", centered: true, children: /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(import_core60.Stack, { gap: "sm", children: [
4775
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
4776
+ import_core60.TextInput,
4777
+ {
4778
+ "aria-label": "Command search",
4779
+ placeholder: "Search commands",
4780
+ value: query,
4781
+ onChange: (event) => setQuery(event.currentTarget.value)
4782
+ }
4783
+ ),
4784
+ filteredCommands.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_core60.Text, { size: "sm", c: "dimmed", children: "No matching commands." }) : filteredCommands.map((command) => /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(import_core60.Group, { justify: "space-between", wrap: "nowrap", children: [
4785
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
4786
+ "button",
4787
+ {
4788
+ type: "button",
4789
+ onClick: async () => {
4790
+ await command.run();
4791
+ setRecentUse((current) => ({ ...current, [command.id]: Date.now() }));
4792
+ onClose();
4793
+ },
4794
+ "aria-label": command.label,
4795
+ children: command.label
4796
+ }
4797
+ ),
4798
+ command.shortcut ? /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_core60.Text, { size: "xs", c: "dimmed", children: command.shortcut }) : null
4799
+ ] }, command.id)),
4800
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_core60.Group, { justify: "flex-end", children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_core60.ActionIcon, { variant: "subtle", "aria-label": "Close command palette", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(GdsIcons.Close, { size: "1rem" }) }) })
3774
4801
  ] }) });
3775
4802
  }
3776
4803
 
3777
4804
  // src/StatsSection.tsx
3778
- var import_core57 = require("@mantine/core");
3779
- var import_jsx_runtime59 = require("react/jsx-runtime");
4805
+ var import_core61 = require("@mantine/core");
4806
+ var import_jsx_runtime66 = require("react/jsx-runtime");
3780
4807
  function StatsSection({
3781
4808
  title,
3782
4809
  loading = false,
@@ -3788,11 +4815,11 @@ function StatsSection({
3788
4815
  }) {
3789
4816
  let content = children;
3790
4817
  if (error) {
3791
- content = /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(StateBlock, { variant: "error", title: "Unable to load statistics", description: error, compact: true });
4818
+ content = /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(StateBlock, { variant: "error", title: "Unable to load statistics", description: error, compact: true });
3792
4819
  } else if (loading) {
3793
- content = /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(StateBlock, { variant: "loading", title: "Loading statistics", description: "This shared data surface is still synchronizing.", compact: true });
4820
+ content = /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(StateBlock, { variant: "loading", title: "Loading statistics", description: "This shared data surface is still synchronizing.", compact: true });
3794
4821
  } else if (belowThreshold) {
3795
- content = /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
4822
+ content = /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
3796
4823
  StateBlock,
3797
4824
  {
3798
4825
  variant: "not-enough-data",
@@ -3802,14 +4829,479 @@ function StatsSection({
3802
4829
  }
3803
4830
  );
3804
4831
  } else if (placeholder) {
3805
- content = /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(PlaceholderPanel, { ...placeholder, mode: "placeholder" });
4832
+ content = /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(PlaceholderPanel, { ...placeholder, mode: "placeholder" });
3806
4833
  }
3807
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_core57.Stack, { gap: "md", children: [
3808
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_core57.Title, { order: 3, children: title }),
4834
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(import_core61.Stack, { gap: "md", children: [
4835
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_core61.Title, { order: 3, children: title }),
3809
4836
  content
3810
4837
  ] });
3811
4838
  }
3812
4839
 
4840
+ // src/PeriodSelector.tsx
4841
+ var import_core62 = require("@mantine/core");
4842
+ var import_jsx_runtime67 = require("react/jsx-runtime");
4843
+ function PeriodSelector({
4844
+ label,
4845
+ description,
4846
+ value,
4847
+ options,
4848
+ onChange,
4849
+ timezone,
4850
+ scope,
4851
+ helperText,
4852
+ error,
4853
+ stale = false,
4854
+ filtered = false,
4855
+ disabled = false
4856
+ }) {
4857
+ const selectedOption = options.find((option) => option.value === value);
4858
+ return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(FormField, { label, description, error, children: /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(import_core62.Stack, { gap: "sm", children: [
4859
+ /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
4860
+ "select",
4861
+ {
4862
+ "aria-label": typeof label === "string" ? label : "Reporting period",
4863
+ value,
4864
+ disabled,
4865
+ onChange: (event) => onChange?.(event.currentTarget.value),
4866
+ children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("option", { value: option.value, children: option.label }, option.value))
4867
+ }
4868
+ ),
4869
+ /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(import_core62.Group, { gap: "xs", wrap: "wrap", children: [
4870
+ timezone ? /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(import_core62.Badge, { variant: "outline", color: "gray", children: [
4871
+ "Timezone: ",
4872
+ timezone
4873
+ ] }) : null,
4874
+ filtered ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_core62.Badge, { variant: "light", color: "blue", children: "Filtered" }) : null,
4875
+ stale ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_core62.Badge, { variant: "light", color: "orange", children: "Stale data" }) : null,
4876
+ scope ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_core62.Badge, { variant: "outline", color: "gray", children: scope }) : null
4877
+ ] }),
4878
+ selectedOption?.description ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_core62.Text, { size: "sm", c: "dimmed", children: selectedOption.description }) : null,
4879
+ helperText ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_core62.Text, { size: "sm", c: "dimmed", children: helperText }) : null
4880
+ ] }) });
4881
+ }
4882
+
4883
+ // src/EvidencePanel.tsx
4884
+ var import_core63 = require("@mantine/core");
4885
+ var import_jsx_runtime68 = require("react/jsx-runtime");
4886
+ var stateTone2 = {
4887
+ current: { label: "Current", color: "teal" },
4888
+ stale: { label: "Stale", color: "orange" },
4889
+ partial: { label: "Partial data", color: "yellow" },
4890
+ "permission-limited": { label: "Permission limited", color: "grape" },
4891
+ loading: { label: "Loading", color: "blue" },
4892
+ empty: { label: "No evidence", color: "gray" },
4893
+ error: { label: "Needs attention", color: "red" }
4894
+ };
4895
+ function EvidencePanel({
4896
+ title,
4897
+ description,
4898
+ source,
4899
+ freshness,
4900
+ confidence,
4901
+ state = "current",
4902
+ evidenceCount,
4903
+ permissionNote,
4904
+ retryAction,
4905
+ details,
4906
+ children
4907
+ }) {
4908
+ const tone = stateTone2[state];
4909
+ const isProblem = state === "error" || state === "permission-limited" || state === "stale" || state === "partial";
4910
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_core63.Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_core63.Stack, { gap: "md", children: [
4911
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_core63.Group, { justify: "space-between", align: "flex-start", gap: "sm", children: [
4912
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_core63.Stack, { gap: 4, children: [
4913
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_core63.Title, { order: 4, children: title }),
4914
+ description ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_core63.Text, { size: "sm", c: "dimmed", children: description }) : null
4915
+ ] }),
4916
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_core63.Badge, { variant: "light", color: tone.color, children: tone.label })
4917
+ ] }),
4918
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_core63.Group, { gap: "xs", wrap: "wrap", children: [
4919
+ source ? /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_core63.Badge, { variant: "outline", color: "gray", children: [
4920
+ "Source: ",
4921
+ source
4922
+ ] }) : null,
4923
+ freshness ? /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_core63.Badge, { variant: "outline", color: "gray", children: [
4924
+ "Freshness: ",
4925
+ freshness
4926
+ ] }) : null,
4927
+ confidence ? /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_core63.Badge, { variant: "outline", color: "gray", children: [
4928
+ "Confidence: ",
4929
+ confidence
4930
+ ] }) : null,
4931
+ typeof evidenceCount === "number" ? /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_core63.Badge, { variant: "outline", color: "gray", children: [
4932
+ "Evidence: ",
4933
+ evidenceCount
4934
+ ] }) : null
4935
+ ] }),
4936
+ permissionNote ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_core63.Alert, { color: isProblem ? tone.color : "gray", variant: "light", children: permissionNote }) : null,
4937
+ details,
4938
+ children,
4939
+ retryAction
4940
+ ] }) });
4941
+ }
4942
+
4943
+ // src/ChartTokenPanel.tsx
4944
+ var import_core64 = require("@mantine/core");
4945
+ var import_jsx_runtime69 = require("react/jsx-runtime");
4946
+ function ChartTokenPanel({
4947
+ title,
4948
+ description,
4949
+ summary,
4950
+ state = "ready",
4951
+ legend = [],
4952
+ children,
4953
+ tableFallback,
4954
+ retryAction
4955
+ }) {
4956
+ if (state === "loading") {
4957
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(StateBlock, { variant: "loading", title: "Loading chart", description: summary, compact: true, action: retryAction });
4958
+ }
4959
+ if (state === "empty") {
4960
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(StateBlock, { variant: "empty", title: "No chart data", description: summary, compact: true, action: retryAction });
4961
+ }
4962
+ if (state === "below-threshold") {
4963
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(StateBlock, { variant: "not-enough-data", title: "Not enough data for chart", description: summary, compact: true, action: retryAction });
4964
+ }
4965
+ if (state === "error") {
4966
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(StateBlock, { variant: "error", title: "Unable to load chart", description: summary, compact: true, action: retryAction });
4967
+ }
4968
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_core64.Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_core64.Stack, { gap: "md", children: [
4969
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_core64.Group, { justify: "space-between", align: "flex-start", gap: "sm", children: [
4970
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_core64.Stack, { gap: 4, children: [
4971
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_core64.Title, { order: 4, children: title }),
4972
+ description ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_core64.Text, { size: "sm", c: "dimmed", children: description }) : null
4973
+ ] }),
4974
+ state !== "ready" ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_core64.Badge, { variant: "light", color: state === "permission-limited" ? "grape" : "yellow", children: state.replace("-", " ") }) : null
4975
+ ] }),
4976
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_core64.Text, { size: "sm", children: summary }),
4977
+ legend.length ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_core64.Group, { gap: "xs", wrap: "wrap", "aria-label": "Chart legend", children: legend.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_core64.Badge, { variant: "outline", color: "gray", title: typeof item.description === "string" ? item.description : void 0, children: [
4978
+ item.label,
4979
+ ": ",
4980
+ item.token
4981
+ ] }, `${String(item.label)}-${index}`)) }) : null,
4982
+ children,
4983
+ tableFallback ? /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_core64.Stack, { gap: "xs", children: [
4984
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_core64.Text, { size: "sm", fw: 600, children: "Accessible data fallback" }),
4985
+ tableFallback
4986
+ ] }) : null
4987
+ ] }) });
4988
+ }
4989
+
4990
+ // src/GdsChart.tsx
4991
+ var import_core65 = require("@mantine/core");
4992
+ var import_jsx_runtime70 = require("react/jsx-runtime");
4993
+ function GdsChart({ type, title, summary, data, state = "ready", retryAction }) {
4994
+ const tableRows = data.map((item) => ({ label: item.label, value: String(item.value), group: item.group ?? "-" }));
4995
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
4996
+ ChartTokenPanel,
4997
+ {
4998
+ title,
4999
+ summary,
5000
+ state,
5001
+ retryAction,
5002
+ legend: [
5003
+ { label: "Primary", token: "var(--mantine-color-blue-6)" },
5004
+ { label: "Secondary", token: "var(--mantine-color-teal-6)" }
5005
+ ],
5006
+ tableFallback: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
5007
+ SimpleDataTable,
5008
+ {
5009
+ columns: [
5010
+ { key: "label", header: "Label" },
5011
+ { key: "value", header: "Value" },
5012
+ { key: "group", header: "Group" }
5013
+ ],
5014
+ rows: tableRows
5015
+ }
5016
+ ),
5017
+ children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(import_core65.Paper, { withBorder: true, radius: "md", p: "md", children: /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_core65.Stack, { gap: "sm", children: [
5018
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_core65.Group, { justify: "space-between", children: [
5019
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(import_core65.Text, { fw: 700, children: title }),
5020
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(import_core65.Badge, { variant: "light", children: type })
5021
+ ] }),
5022
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(import_core65.Text, { size: "sm", c: "dimmed", children: summary }),
5023
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_core65.Text, { size: "xs", c: "dimmed", children: [
5024
+ "Type lane: ",
5025
+ type
5026
+ ] })
5027
+ ] }) })
5028
+ }
5029
+ );
5030
+ }
5031
+
5032
+ // src/LayoutBlocks.tsx
5033
+ var import_core66 = require("@mantine/core");
5034
+ var import_jsx_runtime71 = require("react/jsx-runtime");
5035
+ function renderBlock(block) {
5036
+ switch (block.type) {
5037
+ case "hero":
5038
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(SectionPanel, { title: String(block.props.title ?? "Hero"), description: String(block.props.description ?? "Hero block"), children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_core66.Text, { children: String(block.props.body ?? "Composable hero content") }) });
5039
+ case "stats":
5040
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_core66.SimpleGrid, { cols: { base: 1, md: 3 }, children: block.props.items?.map((item) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_core66.Card, { withBorder: true, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(import_core66.Stack, { gap: 2, children: [
5041
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_core66.Text, { size: "sm", c: "dimmed", children: item.label }),
5042
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_core66.Title, { order: 4, children: item.value })
5043
+ ] }) }, `${block.id}-${item.label}`)) ?? null });
5044
+ case "cards-grid":
5045
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_core66.SimpleGrid, { cols: { base: 1, md: 2 }, children: block.props.items?.map((item) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ListingCard, { title: item.title, description: item.description, size: "sm" }, `${block.id}-${item.title}`)) ?? null });
5046
+ case "chart":
5047
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
5048
+ GdsChart,
5049
+ {
5050
+ type: block.props.chartType ?? "bar",
5051
+ title: String(block.props.title ?? "Chart block"),
5052
+ summary: String(block.props.summary ?? "Block-composed chart summary"),
5053
+ data: block.props.data ?? [{ label: "A", value: 10 }]
5054
+ }
5055
+ );
5056
+ case "cta":
5057
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
5058
+ ActionBar,
5059
+ {
5060
+ primary: { action: "save" },
5061
+ secondary: [{ action: "cancel" }],
5062
+ tertiary: [{ action: "preview" }]
5063
+ }
5064
+ );
5065
+ case "footer":
5066
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_core66.Text, { size: "sm", c: "dimmed", children: String(block.props.text ?? "Footer block") });
5067
+ default:
5068
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_core66.Alert, { color: "red", children: "Unsupported block type." });
5069
+ }
5070
+ }
5071
+ function renderGdsLayout(schema) {
5072
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_core66.Stack, { gap: "lg", children: schema.blocks.map((block) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { children: renderBlock(block) }, block.id)) });
5073
+ }
5074
+
5075
+ // src/ReportingSection.tsx
5076
+ var import_core67 = require("@mantine/core");
5077
+ var import_jsx_runtime72 = require("react/jsx-runtime");
5078
+ function ReportingSection({
5079
+ title,
5080
+ description,
5081
+ state = "ready",
5082
+ periodControl,
5083
+ evidence,
5084
+ metrics,
5085
+ chart,
5086
+ table,
5087
+ action,
5088
+ stateMessage,
5089
+ retryAction
5090
+ }) {
5091
+ let stateBlock = null;
5092
+ if (state === "loading") {
5093
+ stateBlock = /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(StateBlock, { variant: "loading", title: "Loading report", description: stateMessage ?? "The reporting surface is synchronizing.", compact: true });
5094
+ } else if (state === "empty") {
5095
+ stateBlock = /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(StateBlock, { variant: "empty", title: "No report data", description: stateMessage ?? "No records match this reporting scope yet.", compact: true });
5096
+ } else if (state === "error") {
5097
+ stateBlock = /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(StateBlock, { variant: "error", title: "Unable to load report", description: stateMessage ?? "The report could not be prepared.", compact: true, action: retryAction });
5098
+ } else if (state === "below-threshold") {
5099
+ stateBlock = /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(StateBlock, { variant: "not-enough-data", title: "Not enough data", description: stateMessage ?? "This report is hidden until the threshold is met.", compact: true });
5100
+ } else if (state === "permission-limited") {
5101
+ stateBlock = /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(StateBlock, { variant: "permission", title: "Permission-limited report", description: stateMessage ?? "Some evidence is hidden by access rules.", compact: true, action: retryAction });
5102
+ }
5103
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(import_core67.Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_core67.Stack, { gap: "lg", children: [
5104
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_core67.Group, { justify: "space-between", align: "flex-start", gap: "md", children: [
5105
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_core67.Stack, { gap: 4, children: [
5106
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(import_core67.Title, { order: 3, children: title }),
5107
+ description ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(import_core67.Text, { size: "sm", c: "dimmed", children: description }) : null
5108
+ ] }),
5109
+ action
5110
+ ] }),
5111
+ periodControl,
5112
+ (state === "partial" || state === "stale" || state === "filtered") && stateMessage ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(StateBlock, { variant: "info", title: state === "partial" ? "Partial report" : state === "stale" ? "Stale report" : "Filtered report", description: stateMessage, compact: true }) : null,
5113
+ stateBlock,
5114
+ metrics,
5115
+ chart,
5116
+ table,
5117
+ evidence
5118
+ ] }) });
5119
+ }
5120
+
5121
+ // src/Notifications.tsx
5122
+ var import_core68 = require("@mantine/core");
5123
+ var import_jsx_runtime73 = require("react/jsx-runtime");
5124
+ var notificationColorMap = {
5125
+ success: "teal",
5126
+ error: "red",
5127
+ warning: "yellow",
5128
+ info: "blue",
5129
+ neutral: "gray"
5130
+ };
5131
+ function severityToStateVariant(severity) {
5132
+ if (severity === "success") return "success";
5133
+ if (severity === "error") return "error";
5134
+ if (severity === "warning") return "not-enough-data";
5135
+ if (severity === "neutral") return "disabled";
5136
+ return "info";
5137
+ }
5138
+ function InlineAlert({
5139
+ title,
5140
+ message,
5141
+ severity = "info",
5142
+ action
5143
+ }) {
5144
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
5145
+ import_core68.Alert,
5146
+ {
5147
+ variant: "light",
5148
+ color: notificationColorMap[severity],
5149
+ title,
5150
+ icon: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(GdsIcons.Info, { size: "1rem" }),
5151
+ role: severity === "error" ? "alert" : "status",
5152
+ children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(import_core68.Stack, { gap: "xs", children: [
5153
+ message ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(import_core68.Text, { size: "sm", children: message }) : null,
5154
+ action
5155
+ ] })
5156
+ }
5157
+ );
5158
+ }
5159
+ function BannerNotice({
5160
+ eyebrow,
5161
+ title,
5162
+ message,
5163
+ severity = "info",
5164
+ action
5165
+ }) {
5166
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(import_core68.Paper, { withBorder: true, radius: "lg", p: "md", children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(import_core68.Stack, { gap: "xs", children: [
5167
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(import_core68.Group, { justify: "space-between", align: "center", children: [
5168
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(import_core68.Group, { gap: "xs", children: [
5169
+ eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(import_core68.Badge, { variant: "light", children: eyebrow }) : null,
5170
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(import_core68.Badge, { variant: "light", color: notificationColorMap[severity], children: severityToStateVariant(severity).replace("-", " ") })
5171
+ ] }),
5172
+ action
5173
+ ] }),
5174
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(import_core68.Title, { order: 4, children: title }),
5175
+ message ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(import_core68.Text, { size: "sm", c: "dimmed", children: message }) : null
5176
+ ] }) });
5177
+ }
5178
+ function NotificationCenterView({
5179
+ notifications,
5180
+ onDismiss,
5181
+ onClear,
5182
+ title = "Notifications",
5183
+ emptyMessage = "No active notifications."
5184
+ }) {
5185
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(import_core68.Paper, { withBorder: true, radius: "lg", p: "md", children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(import_core68.Stack, { gap: "md", children: [
5186
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(import_core68.Group, { justify: "space-between", align: "center", children: [
5187
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(import_core68.Title, { order: 4, children: title }),
5188
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(import_core68.Button, { size: "xs", variant: "subtle", onClick: onClear, disabled: notifications.length === 0 || !onClear, children: "Clear all" })
5189
+ ] }),
5190
+ notifications.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(import_core68.Text, { size: "sm", c: "dimmed", children: emptyMessage }) : /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(import_core68.Stack, { gap: "sm", children: notifications.map((item) => /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
5191
+ InlineAlert,
5192
+ {
5193
+ severity: item.severity,
5194
+ title: item.title,
5195
+ message: item.message,
5196
+ action: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(import_core68.Group, { gap: "xs", children: [
5197
+ item.actions?.map((action) => /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(import_core68.Button, { size: "xs", variant: "default", onClick: action.onClick, children: action.label }, action.id)),
5198
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(import_core68.Button, { size: "xs", variant: "subtle", onClick: () => onDismiss?.(item.id), disabled: !onDismiss, children: "Dismiss" })
5199
+ ] })
5200
+ },
5201
+ item.id
5202
+ )) })
5203
+ ] }) });
5204
+ }
5205
+
5206
+ // src/Notifications.client.tsx
5207
+ var import_react16 = require("react");
5208
+ var import_jsx_runtime74 = require("react/jsx-runtime");
5209
+ var GdsNotificationContext = (0, import_react16.createContext)(null);
5210
+ function GdsNotificationProvider({ children }) {
5211
+ const [notifications, setNotifications] = (0, import_react16.useState)([]);
5212
+ const value = (0, import_react16.useMemo)(() => ({
5213
+ notifications,
5214
+ notify: (message) => {
5215
+ setNotifications((current) => {
5216
+ const rest = current.filter((item) => item.id !== message.id);
5217
+ return [...rest, message];
5218
+ });
5219
+ if (typeof message.autoCloseMs === "number" && message.autoCloseMs > 0) {
5220
+ window.setTimeout(() => {
5221
+ setNotifications((current) => current.filter((item) => item.id !== message.id));
5222
+ }, message.autoCloseMs);
5223
+ }
5224
+ },
5225
+ dismiss: (id) => {
5226
+ setNotifications((current) => current.filter((item) => item.id !== id));
5227
+ },
5228
+ clear: () => {
5229
+ setNotifications([]);
5230
+ }
5231
+ }), [notifications]);
5232
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(GdsNotificationContext.Provider, { value, children });
5233
+ }
5234
+ function useGdsNotifications() {
5235
+ const context = (0, import_react16.useContext)(GdsNotificationContext);
5236
+ if (!context) {
5237
+ throw new Error("useGdsNotifications must be used within GdsNotificationProvider.");
5238
+ }
5239
+ return context;
5240
+ }
5241
+ function NotificationCenter({
5242
+ title = "Notifications",
5243
+ emptyMessage = "No active notifications."
5244
+ }) {
5245
+ const { notifications, dismiss, clear } = useGdsNotifications();
5246
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
5247
+ NotificationCenterView,
5248
+ {
5249
+ title,
5250
+ emptyMessage,
5251
+ notifications,
5252
+ onDismiss: dismiss,
5253
+ onClear: clear
5254
+ }
5255
+ );
5256
+ }
5257
+
5258
+ // src/Telemetry.client.tsx
5259
+ var import_react17 = require("react");
5260
+ var import_jsx_runtime75 = require("react/jsx-runtime");
5261
+ var GdsTelemetryContext = (0, import_react17.createContext)(null);
5262
+ function hashToUnit(value) {
5263
+ let hash = 0;
5264
+ for (let index = 0; index < value.length; index += 1) {
5265
+ hash = (hash << 5) - hash + value.charCodeAt(index);
5266
+ hash |= 0;
5267
+ }
5268
+ return Math.abs(hash % 1e3) / 1e3;
5269
+ }
5270
+ function redactContext(context) {
5271
+ if (!context) {
5272
+ return context;
5273
+ }
5274
+ return Object.entries(context).reduce((acc, [key, value]) => {
5275
+ if (key.toLowerCase().includes("email") || key.toLowerCase().includes("name") || key.toLowerCase().includes("phone")) {
5276
+ return acc;
5277
+ }
5278
+ acc[key] = value;
5279
+ return acc;
5280
+ }, {});
5281
+ }
5282
+ function GdsTelemetryProvider({ children, sink, sampleRate = 1 }) {
5283
+ const value = (0, import_react17.useMemo)(() => ({
5284
+ emit: (event) => {
5285
+ if (hashToUnit(event.correlationId) > sampleRate) {
5286
+ return;
5287
+ }
5288
+ sink?.({
5289
+ ...event,
5290
+ context: redactContext(event.context),
5291
+ ts: Date.now()
5292
+ });
5293
+ }
5294
+ }), [sampleRate, sink]);
5295
+ return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(GdsTelemetryContext.Provider, { value, children });
5296
+ }
5297
+ function useGdsTelemetry() {
5298
+ const context = (0, import_react17.useContext)(GdsTelemetryContext);
5299
+ if (!context) {
5300
+ throw new Error("useGdsTelemetry must be used within GdsTelemetryProvider.");
5301
+ }
5302
+ return context;
5303
+ }
5304
+
3813
5305
  // src/locales/ar.ts
3814
5306
  var ar = {
3815
5307
  "gds.action.settings": "\u0627\u0644\u0625\u0639\u062F\u0627\u062F\u0627\u062A",
@@ -5118,13 +6610,22 @@ function getGdsMessages(locale) {
5118
6610
  AccessRecoveryPanel,
5119
6611
  AccessSummary,
5120
6612
  ActionBar,
6613
+ ActiveFilterChips,
6614
+ AdvancedDataTable,
5121
6615
  ArticleShell,
6616
+ AsyncSurface,
5122
6617
  AuthShell,
6618
+ BannerNotice,
5123
6619
  BrowseSurface,
6620
+ BulkActionsBar,
6621
+ ChartTokenPanel,
5124
6622
  ChoiceChip,
6623
+ CommandPalette,
6624
+ CommandRegistryProvider,
5125
6625
  ConfirmDialog,
5126
6626
  ConsumerDashboardGrid,
5127
6627
  ConsumerSection,
6628
+ CountBadge,
5128
6629
  CtaButtonGroup,
5129
6630
  DataToolbar,
5130
6631
  DetailProfileShell,
@@ -5135,20 +6636,33 @@ function getGdsMessages(locale) {
5135
6636
  EditorialCard,
5136
6637
  EditorialHero,
5137
6638
  EmptyState,
6639
+ EvidencePanel,
5138
6640
  FeatureBand,
5139
6641
  FilterDrawer,
5140
6642
  FoodMenuSection,
6643
+ FormErrorSummary,
5141
6644
  FormField,
5142
6645
  GameBoardTile,
6646
+ GdsChart,
6647
+ GdsFormProvider,
5143
6648
  GdsIcons,
6649
+ GdsNotificationProvider,
6650
+ GdsTelemetryProvider,
5144
6651
  GdsVocabulary,
6652
+ InlineAlert,
6653
+ LabelTag,
5145
6654
  ListingCard,
6655
+ ListingProvider,
5146
6656
  MapPanel,
5147
6657
  MediaCard,
5148
6658
  MediaField,
5149
6659
  MetricCard,
6660
+ NotificationCenter,
6661
+ NotificationCenterView,
6662
+ OverlayManagerProvider,
5150
6663
  PROVIDER_IDENTITY_REGISTRY,
5151
6664
  PageHeader,
6665
+ PeriodSelector,
5152
6666
  PlaceholderPanel,
5153
6667
  PlaybackSurface,
5154
6668
  ProductCard,
@@ -5166,6 +6680,8 @@ function getGdsMessages(locale) {
5166
6680
  ReferenceLocaleNotice,
5167
6681
  ReferenceSection,
5168
6682
  ReferenceThemeExplorer,
6683
+ ReportingSection,
6684
+ ResultSummary,
5169
6685
  SectionPanel,
5170
6686
  SemanticButton,
5171
6687
  ShareButtonGroup,
@@ -5174,29 +6690,46 @@ function getGdsMessages(locale) {
5174
6690
  SidebarNavSection,
5175
6691
  SimpleDataTable,
5176
6692
  SocialAuthButtons,
6693
+ SortMenu,
5177
6694
  StateBlock,
5178
6695
  StatsSection,
5179
6696
  StatusBadge,
5180
6697
  ThemeToggle,
5181
6698
  UploadDropzone,
6699
+ ValidatedFieldMessage,
5182
6700
  ar,
5183
6701
  createGdsVocabularyPack,
5184
6702
  de,
5185
6703
  en,
5186
6704
  es,
5187
6705
  fr,
6706
+ gdsCardSizePaddingMap,
6707
+ gdsCardTitleOrderMap,
6708
+ gdsFormReducer,
5188
6709
  gdsLocales,
5189
6710
  getGdsMessages,
5190
6711
  getProviderIdentityLabel,
6712
+ getProviderIdentityPolicy,
5191
6713
  getSemanticActionConfig,
5192
6714
  getSemanticActionLabel,
6715
+ getSupportedProviderIdentityIds,
5193
6716
  he,
5194
6717
  hu,
5195
6718
  isPresentationMode,
5196
6719
  it,
6720
+ listingQueryReducer,
5197
6721
  mergeGdsVocabularyPacks,
6722
+ renderGdsLayout,
5198
6723
  resolveAccentPanelStyles,
5199
6724
  resolveSemanticActionConfig,
5200
6725
  resolveSurfacePresentationStyles,
5201
- ru
6726
+ ru,
6727
+ useCommandLauncher,
6728
+ useDiscoveryShellState,
6729
+ useGdsForm,
6730
+ useGdsFormSnapshot,
6731
+ useGdsNotifications,
6732
+ useGdsTelemetry,
6733
+ useListingState,
6734
+ useOverlayManager
5202
6735
  });