@fairmint/ui 0.2.12 → 0.2.14

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.
@@ -26802,110 +26802,6 @@ const AVATAR_PALETTE = [
26802
26802
  colors.accent2,
26803
26803
  colors.accent3
26804
26804
  ];
26805
- const ActionIcon = forwardRef((props, ref) => /* @__PURE__ */ jsx(ActionIcon$1, { color: colors.primary, variant: "subtle", ...props, ref }));
26806
- ActionIcon.displayName = "ActionIcon";
26807
- function Alert(props) {
26808
- return /* @__PURE__ */ jsx(Alert$1, { ...props });
26809
- }
26810
- const Avatar = forwardRef((props, ref) => /* @__PURE__ */ jsx(Avatar$1, { radius: "md", color: colors.primary, ...props, ref }));
26811
- Avatar.displayName = "Avatar";
26812
- const Badge = forwardRef((props, ref) => /* @__PURE__ */ jsx(Badge$1, { variant: "light", ...props, ref }));
26813
- Badge.displayName = "Badge";
26814
- const Button = forwardRef((props, ref) => /* @__PURE__ */ jsx(Button$1, { color: colors.primary, ...props, ref }));
26815
- Button.displayName = "Button";
26816
- const Card = forwardRef((props, ref) => /* @__PURE__ */ jsx(Card$1, { padding: "lg", radius: "xl", withBorder: true, ...props, ref }));
26817
- Card.displayName = "Card";
26818
- const Checkbox = forwardRef((props, ref) => /* @__PURE__ */ jsx(Checkbox$1, { color: colors.primary, ...props, ref }));
26819
- Checkbox.displayName = "Checkbox";
26820
- function Drawer(props) {
26821
- return /* @__PURE__ */ jsx(Drawer$1, { position: "right", size: "lg", p: "lg", ...props });
26822
- }
26823
- function Loader(props) {
26824
- return /* @__PURE__ */ jsx(Loader$1, { ...props });
26825
- }
26826
- function MenuBase(props) {
26827
- return /* @__PURE__ */ jsx(Menu$1, { shadow: "md", ...props });
26828
- }
26829
- const Menu = Object.assign(MenuBase, {
26830
- Target: Menu$1.Target,
26831
- Dropdown: Menu$1.Dropdown,
26832
- Item: Menu$1.Item,
26833
- Label: Menu$1.Label,
26834
- Divider: Menu$1.Divider
26835
- });
26836
- function Modal(props) {
26837
- return /* @__PURE__ */ jsx(Modal$1, { centered: true, radius: "lg", ...props });
26838
- }
26839
- const PasswordInput = forwardRef((props, ref) => /* @__PURE__ */ jsx(PasswordInput$1, { size: "md", ...props, ref }));
26840
- PasswordInput.displayName = "PasswordInput";
26841
- const Select = forwardRef((props, ref) => /* @__PURE__ */ jsx(Select$1, { size: "md", ...props, ref }));
26842
- Select.displayName = "Select";
26843
- function Skeleton(props) {
26844
- return /* @__PURE__ */ jsx(Skeleton$1, { ...props });
26845
- }
26846
- const Switch = forwardRef((props, ref) => /* @__PURE__ */ jsx(Switch$1, { color: colors.primary, ...props, ref }));
26847
- Switch.displayName = "Switch";
26848
- function TableBase(props) {
26849
- return /* @__PURE__ */ jsx(Table$1, { ...props });
26850
- }
26851
- const Table = Object.assign(TableBase, {
26852
- Thead: Table$1.Thead,
26853
- Tbody: Table$1.Tbody,
26854
- Tr: Table$1.Tr,
26855
- Th: Table$1.Th,
26856
- Td: Table$1.Td,
26857
- Tfoot: Table$1.Tfoot,
26858
- Caption: Table$1.Caption
26859
- });
26860
- function TabsBase(props) {
26861
- return /* @__PURE__ */ jsx(Tabs$1, { color: colors.primary, ...props });
26862
- }
26863
- const Tabs = Object.assign(TabsBase, {
26864
- List: Tabs$1.List,
26865
- Tab: Tabs$1.Tab,
26866
- Panel: Tabs$1.Panel
26867
- });
26868
- const TextInput = forwardRef((props, ref) => /* @__PURE__ */ jsx(TextInput$1, { size: "md", ...props, ref }));
26869
- TextInput.displayName = "TextInput";
26870
- function Tooltip(props) {
26871
- return /* @__PURE__ */ jsx(Tooltip$1, { ...props });
26872
- }
26873
- function ErrorFallback({
26874
- title = "Something went wrong",
26875
- description = "We've been notified and are working on a fix.",
26876
- onAction,
26877
- actionLabel = "Reload Page",
26878
- error: error2
26879
- }) {
26880
- if (error2 !== void 0) {
26881
- console.error("[ErrorFallback]", error2);
26882
- }
26883
- const handleAction = onAction ?? (() => window.location.reload());
26884
- return /* @__PURE__ */ jsx(Container, { size: "sm", py: "xl", children: /* @__PURE__ */ jsxs(Stack, { align: "center", gap: "md", children: [
26885
- /* @__PURE__ */ jsx(Title, { order: 2, children: title }),
26886
- /* @__PURE__ */ jsx(Text, { c: "dimmed", children: description }),
26887
- /* @__PURE__ */ jsx(Button, { onClick: handleAction, children: actionLabel })
26888
- ] }) });
26889
- }
26890
- function FairmintLogo({
26891
- src = "https://imagedelivery.net/Lm6ChJXR4cIKKycsNMvGjA/0367be38-c9d8-4206-aaae-eba5ff830600/public",
26892
- width = 140,
26893
- height = 30,
26894
- className,
26895
- alt = "Fairmint"
26896
- }) {
26897
- return /* @__PURE__ */ jsx(
26898
- "img",
26899
- {
26900
- src,
26901
- alt,
26902
- width,
26903
- height,
26904
- className,
26905
- style: { objectFit: "contain" }
26906
- }
26907
- );
26908
- }
26909
26805
  const radii = {
26910
26806
  xs: "0.25rem",
26911
26807
  sm: "0.375rem",
@@ -27009,12 +26905,16 @@ const info = [
27009
26905
  "#155B75",
27010
26906
  "#164C63"
27011
26907
  ];
26908
+ const typography = {
26909
+ fontFamily: '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"',
26910
+ headingFontFamily: '"Plus Jakarta Sans", sans-serif'
26911
+ };
27012
26912
  const theme = createTheme({
27013
26913
  primaryColor: "indigo",
27014
26914
  colors: { indigo, gray: neutral, fairmintBlue, fairmintPurple, success, warning, error, info },
27015
- fontFamily: '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"',
26915
+ fontFamily: typography.fontFamily,
27016
26916
  headings: {
27017
- fontFamily: '"Plus Jakarta Sans", sans-serif',
26917
+ fontFamily: typography.headingFontFamily,
27018
26918
  fontWeight: "700"
27019
26919
  },
27020
26920
  radius: radii,
@@ -27064,6 +26964,49 @@ const theme = createTheme({
27064
26964
  }
27065
26965
  }
27066
26966
  });
26967
+ const fairmintCssVariables = () => ({
26968
+ variables: {
26969
+ "--fairmint-font-headings": typography.headingFontFamily,
26970
+ "--fairmint-font-body": typography.fontFamily
26971
+ },
26972
+ light: {
26973
+ /** Large decorative background text on error/empty pages. */
26974
+ "--fairmint-watermark-color": neutral[1],
26975
+ /** Supporting / muted text (subtitles, secondary labels). Replaces c="dimmed" and neutral.5 */
26976
+ "--fairmint-color-text-secondary": neutral[5],
26977
+ /** Faint metadata text (timestamps, tertiary labels). Replaces neutral.4 */
26978
+ "--fairmint-color-text-tertiary": neutral[4],
26979
+ /** Background tint for selected / active rows. Replaces primary.0 */
26980
+ "--fairmint-color-surface-selected": indigo[0]
26981
+ },
26982
+ dark: {
26983
+ "--fairmint-watermark-color": neutral[7],
26984
+ "--fairmint-color-text-secondary": neutral[4],
26985
+ "--fairmint-color-text-tertiary": neutral[5],
26986
+ "--fairmint-color-surface-selected": indigo[9]
26987
+ }
26988
+ });
26989
+ const fairmintVars = {
26990
+ /** Secondary / muted text — subtitles, supporting labels. Adapts to color scheme. */
26991
+ colorTextSecondary: `var(--fairmint-color-text-secondary, ${neutral[5]})`,
26992
+ /** Tertiary / faint text — timestamps, metadata. Adapts to color scheme. */
26993
+ colorTextTertiary: `var(--fairmint-color-text-tertiary, ${neutral[4]})`,
26994
+ /** Background tint for selected / active rows. Adapts to color scheme. */
26995
+ colorSurfaceSelected: `var(--fairmint-color-surface-selected, ${indigo[0]})`,
26996
+ /** Large decorative watermark on error/empty pages. Adapts to color scheme. */
26997
+ watermarkColor: `var(--fairmint-watermark-color, ${neutral[1]})`,
26998
+ /** Heading font family (Plus Jakarta Sans). */
26999
+ fontHeadings: `var(--fairmint-font-headings, ${typography.headingFontFamily})`,
27000
+ /** Body font family (Inter). */
27001
+ fontBody: `var(--fairmint-font-body, ${typography.fontFamily})`
27002
+ };
27003
+ function createFairmintMantineProviderProps(colorScheme = "light") {
27004
+ return {
27005
+ theme,
27006
+ cssVariablesResolver: fairmintCssVariables,
27007
+ defaultColorScheme: colorScheme
27008
+ };
27009
+ }
27067
27010
  const brandColors = {
27068
27011
  blue: "#0A4EFB",
27069
27012
  purple: "#9E03FF",
@@ -27088,15 +27031,127 @@ const semanticColors = {
27088
27031
  error: "#F04438",
27089
27032
  info: "#06AED4"
27090
27033
  };
27034
+ const ActionIcon = forwardRef((props, ref) => /* @__PURE__ */ jsx(ActionIcon$1, { color: colors.primary, variant: "subtle", ...props, ref }));
27035
+ ActionIcon.displayName = "ActionIcon";
27036
+ function Alert(props) {
27037
+ return /* @__PURE__ */ jsx(Alert$1, { ...props });
27038
+ }
27039
+ const Avatar = forwardRef((props, ref) => /* @__PURE__ */ jsx(Avatar$1, { radius: "md", color: colors.primary, ...props, ref }));
27040
+ Avatar.displayName = "Avatar";
27041
+ const Badge = forwardRef((props, ref) => /* @__PURE__ */ jsx(Badge$1, { variant: "light", ...props, ref }));
27042
+ Badge.displayName = "Badge";
27043
+ const Button = forwardRef((props, ref) => /* @__PURE__ */ jsx(Button$1, { color: colors.primary, ...props, ref }));
27044
+ Button.displayName = "Button";
27045
+ const Card = forwardRef((props, ref) => /* @__PURE__ */ jsx(Card$1, { padding: "lg", radius: "xl", withBorder: true, ...props, ref }));
27046
+ Card.displayName = "Card";
27047
+ const Checkbox = forwardRef((props, ref) => /* @__PURE__ */ jsx(Checkbox$1, { color: colors.primary, ...props, ref }));
27048
+ Checkbox.displayName = "Checkbox";
27049
+ function Drawer(props) {
27050
+ return /* @__PURE__ */ jsx(Drawer$1, { position: "right", size: "lg", p: "lg", ...props });
27051
+ }
27052
+ function Loader(props) {
27053
+ return /* @__PURE__ */ jsx(Loader$1, { ...props });
27054
+ }
27055
+ function MenuBase(props) {
27056
+ return /* @__PURE__ */ jsx(Menu$1, { shadow: "md", ...props });
27057
+ }
27058
+ const Menu = Object.assign(MenuBase, {
27059
+ Target: Menu$1.Target,
27060
+ Dropdown: Menu$1.Dropdown,
27061
+ Item: Menu$1.Item,
27062
+ Label: Menu$1.Label,
27063
+ Divider: Menu$1.Divider
27064
+ });
27065
+ function Modal(props) {
27066
+ return /* @__PURE__ */ jsx(Modal$1, { centered: true, radius: "lg", ...props });
27067
+ }
27068
+ const PasswordInput = forwardRef((props, ref) => /* @__PURE__ */ jsx(PasswordInput$1, { size: "md", ...props, ref }));
27069
+ PasswordInput.displayName = "PasswordInput";
27070
+ const Select = forwardRef((props, ref) => /* @__PURE__ */ jsx(Select$1, { size: "md", ...props, ref }));
27071
+ Select.displayName = "Select";
27072
+ function Skeleton(props) {
27073
+ return /* @__PURE__ */ jsx(Skeleton$1, { ...props });
27074
+ }
27075
+ const Switch = forwardRef((props, ref) => /* @__PURE__ */ jsx(Switch$1, { color: colors.primary, ...props, ref }));
27076
+ Switch.displayName = "Switch";
27077
+ function TableBase(props) {
27078
+ return /* @__PURE__ */ jsx(Table$1, { ...props });
27079
+ }
27080
+ const Table = Object.assign(TableBase, {
27081
+ Thead: Table$1.Thead,
27082
+ Tbody: Table$1.Tbody,
27083
+ Tr: Table$1.Tr,
27084
+ Th: Table$1.Th,
27085
+ Td: Table$1.Td,
27086
+ Tfoot: Table$1.Tfoot,
27087
+ Caption: Table$1.Caption
27088
+ });
27089
+ function TabsBase(props) {
27090
+ return /* @__PURE__ */ jsx(Tabs$1, { color: colors.primary, ...props });
27091
+ }
27092
+ const Tabs = Object.assign(TabsBase, {
27093
+ List: Tabs$1.List,
27094
+ Tab: Tabs$1.Tab,
27095
+ Panel: Tabs$1.Panel
27096
+ });
27097
+ const TextInput = forwardRef((props, ref) => /* @__PURE__ */ jsx(TextInput$1, { size: "md", ...props, ref }));
27098
+ TextInput.displayName = "TextInput";
27099
+ function Tooltip(props) {
27100
+ return /* @__PURE__ */ jsx(Tooltip$1, { fz: "xs", ...props });
27101
+ }
27102
+ function ErrorFallback({
27103
+ title = "Something went wrong",
27104
+ description = "We've been notified and are working on a fix.",
27105
+ onAction,
27106
+ actionLabel = "Reload Page",
27107
+ error: error2
27108
+ }) {
27109
+ if (error2 !== void 0) {
27110
+ console.error("[ErrorFallback]", error2);
27111
+ }
27112
+ const handleAction = onAction ?? (() => window.location.reload());
27113
+ return /* @__PURE__ */ jsx(Container, { size: "sm", py: "xl", children: /* @__PURE__ */ jsxs(Stack, { align: "center", gap: "md", children: [
27114
+ /* @__PURE__ */ jsx(Title, { order: 2, children: title }),
27115
+ /* @__PURE__ */ jsx(Text, { c: fairmintVars.colorTextSecondary, children: description }),
27116
+ /* @__PURE__ */ jsx(Button, { onClick: handleAction, children: actionLabel })
27117
+ ] }) });
27118
+ }
27119
+ function FairmintLogo({
27120
+ src = "https://imagedelivery.net/Lm6ChJXR4cIKKycsNMvGjA/0367be38-c9d8-4206-aaae-eba5ff830600/public",
27121
+ width = 140,
27122
+ height = 30,
27123
+ className,
27124
+ alt = "Fairmint"
27125
+ }) {
27126
+ return /* @__PURE__ */ jsx(
27127
+ "img",
27128
+ {
27129
+ src,
27130
+ alt,
27131
+ width,
27132
+ height,
27133
+ className,
27134
+ style: { objectFit: "contain" }
27135
+ }
27136
+ );
27137
+ }
27091
27138
  function FairmintProvider({
27092
27139
  children,
27093
27140
  colorScheme = "light",
27094
27141
  notificationPosition = "top-right"
27095
27142
  }) {
27096
- return /* @__PURE__ */ jsxs(MantineProvider, { theme, defaultColorScheme: colorScheme, children: [
27097
- /* @__PURE__ */ jsx(Notifications, { position: notificationPosition }),
27098
- children
27099
- ] });
27143
+ return /* @__PURE__ */ jsxs(
27144
+ MantineProvider,
27145
+ {
27146
+ theme,
27147
+ defaultColorScheme: colorScheme,
27148
+ cssVariablesResolver: fairmintCssVariables,
27149
+ children: [
27150
+ /* @__PURE__ */ jsx(Notifications, { position: notificationPosition }),
27151
+ children
27152
+ ]
27153
+ }
27154
+ );
27100
27155
  }
27101
27156
  const emailSchema = stringType().email("Please enter a valid email address");
27102
27157
  function EmailField({ error: error2, ...rest }) {
@@ -28211,7 +28266,7 @@ function FormField({
28211
28266
  }
28212
28267
  ),
28213
28268
  children && inputProps.error && /* @__PURE__ */ jsx(Text, { size: "xs", c: "error", role: "alert", children: inputProps.error }),
28214
- children && description && !inputProps.error && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: description })
28269
+ children && description && !inputProps.error && /* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, children: description })
28215
28270
  ] });
28216
28271
  }
28217
28272
  const passwordSchema = stringType().min(8, "Password must be at least 8 characters");
@@ -28227,17 +28282,77 @@ function PasswordField({ error: error2, ...rest }) {
28227
28282
  }
28228
28283
  );
28229
28284
  }
28230
- const phoneSchema = stringType().regex(/^\+?[\d\s\-().]{7,20}$/, "Please enter a valid phone number");
28231
- function PhoneField({ error: error2, ...rest }) {
28285
+ const phoneSchema = stringType().refine((value) => {
28286
+ if (!/^\+?[\d\s\-().]*$/.test(value)) return false;
28287
+ const digits = value.replace(/\D/g, "");
28288
+ if (value.startsWith("+")) {
28289
+ if (digits.startsWith("1")) return digits.length === 11;
28290
+ return digits.length >= 8 && digits.length <= 15;
28291
+ }
28292
+ return digits.length === 10 || digits.length === 11 && digits.startsWith("1");
28293
+ }, "Please enter a valid phone number");
28294
+ function formatPhone(raw) {
28295
+ const hasPlus = raw.startsWith("+");
28296
+ const digits = raw.replace(/\D/g, "");
28297
+ if (!digits) return hasPlus ? "+" : "";
28298
+ if (!hasPlus && digits.length === 11 && digits.startsWith("1")) {
28299
+ return formatPhone(`+${digits}`);
28300
+ }
28301
+ if (hasPlus && digits.startsWith("1")) {
28302
+ const local = digits.slice(1);
28303
+ if (!local.length) return "+1";
28304
+ if (local.length <= 3) return `+1 (${local}`;
28305
+ if (local.length <= 6) return `+1 (${local.slice(0, 3)}) ${local.slice(3)}`;
28306
+ return `+1 (${local.slice(0, 3)}) ${local.slice(3, 6)}-${local.slice(6, 10)}`;
28307
+ }
28308
+ if (hasPlus) return `+${digits}`;
28309
+ if (digits.length <= 3) return digits;
28310
+ if (digits.length <= 6) return `(${digits.slice(0, 3)}) ${digits.slice(3)}`;
28311
+ return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6, 10)}`;
28312
+ }
28313
+ function normalizePhone(formatted) {
28314
+ const hasPlus = formatted.startsWith("+");
28315
+ const digits = formatted.replace(/\D/g, "");
28316
+ if (!digits) return "";
28317
+ if (hasPlus) return `+${digits}`;
28318
+ if (digits.length === 10) return `+1${digits}`;
28319
+ return `+${digits}`;
28320
+ }
28321
+ const formatPhoneDisplay = formatPhone;
28322
+ function PhoneField({ error: error2, onChange, value, ...rest }) {
28323
+ const inputRef = React__default.useRef(null);
28324
+ const handleChange = (e) => {
28325
+ const raw = e.target.value;
28326
+ const hasPlus = raw.startsWith("+");
28327
+ let digits = raw.replace(/\D/g, "");
28328
+ const shouldFormatAsUsCountryCode = digits.startsWith("1") && (hasPlus || !hasPlus && digits.length > 10);
28329
+ if (shouldFormatAsUsCountryCode) {
28330
+ digits = digits.slice(0, 11);
28331
+ } else {
28332
+ digits = digits.slice(0, hasPlus ? 15 : 10);
28333
+ }
28334
+ const formatted = formatPhone(hasPlus || shouldFormatAsUsCountryCode ? `+${digits}` : digits);
28335
+ e.target.value = formatted;
28336
+ onChange?.(e);
28337
+ };
28338
+ const displayValue = typeof value === "string" ? formatPhone(value) : value;
28339
+ React__default.useEffect(() => {
28340
+ if (inputRef.current && displayValue != null && inputRef.current.value !== String(displayValue)) {
28341
+ inputRef.current.value = String(displayValue);
28342
+ }
28343
+ }, [displayValue]);
28232
28344
  return /* @__PURE__ */ jsx(
28233
28345
  TextInput,
28234
28346
  {
28347
+ ref: inputRef,
28235
28348
  type: "tel",
28236
28349
  label: rest.label ?? "Phone",
28237
- placeholder: rest.placeholder ?? "+1 (555) 000-0000",
28350
+ placeholder: rest.placeholder ?? "(555) 000-0000",
28238
28351
  autoComplete: "tel",
28352
+ ...rest,
28239
28353
  error: error2,
28240
- ...rest
28354
+ value: displayValue,
28355
+ onChange: handleChange
28241
28356
  }
28242
28357
  );
28243
28358
  }
@@ -28441,9 +28556,9 @@ function EmptyState({
28441
28556
  actionColor = colors.primary
28442
28557
  }) {
28443
28558
  return /* @__PURE__ */ jsxs(Stack, { align: "center", gap: "md", py: "xl", role: "status", children: [
28444
- icon && /* @__PURE__ */ jsx(Box, { c: `${colors.neutral}.5`, fz: "2.5rem", children: icon }),
28559
+ icon && /* @__PURE__ */ jsx(Box, { c: fairmintVars.colorTextSecondary, fz: "2.5rem", children: icon }),
28445
28560
  /* @__PURE__ */ jsx(Title, { order: 4, ta: "center", children: title }),
28446
- description && /* @__PURE__ */ jsx(Text, { c: "dimmed", size: "sm", ta: "center", maw: 360, children: description }),
28561
+ description && /* @__PURE__ */ jsx(Text, { c: fairmintVars.colorTextSecondary, size: "sm", ta: "center", maw: 360, children: description }),
28447
28562
  actionLabel && onAction && /* @__PURE__ */ jsx(Button, { variant: "light", color: actionColor, onClick: onAction, children: actionLabel })
28448
28563
  ] });
28449
28564
  }
@@ -28631,6 +28746,102 @@ function EditableSection({
28631
28746
  ] }) : readView
28632
28747
  ] });
28633
28748
  }
28749
+ const ERROR_CONFIGS = {
28750
+ 400: {
28751
+ title: "Bad request",
28752
+ description: "Your request could not be understood. Please check your input and try again.",
28753
+ actionLabel: "Go back"
28754
+ },
28755
+ 401: {
28756
+ title: "Authentication required",
28757
+ description: "You need to sign in to access this page. If you believe this is a mistake, please contact support.",
28758
+ actionLabel: "Go back"
28759
+ },
28760
+ 403: {
28761
+ title: "Access denied",
28762
+ description: "You don't have permission to access this page. Contact support if you believe this is a mistake.",
28763
+ actionLabel: "Go back"
28764
+ },
28765
+ 404: {
28766
+ title: "Nothing to see here",
28767
+ description: "The page you are trying to open does not exist. You may have mistyped the address, or the page has been moved to another URL.",
28768
+ actionLabel: "Go back"
28769
+ },
28770
+ 429: {
28771
+ title: "Too many requests",
28772
+ description: "You have made too many requests in a short period. Please wait a moment before trying again.",
28773
+ actionLabel: "Try again"
28774
+ },
28775
+ 500: {
28776
+ title: "Something went wrong",
28777
+ description: "An unexpected error occurred on our end. We have been notified and are working on a fix.",
28778
+ actionLabel: "Reload page"
28779
+ },
28780
+ 503: {
28781
+ title: "Service unavailable",
28782
+ description: "We are temporarily unavailable for scheduled maintenance. Please check back shortly.",
28783
+ actionLabel: "Try again"
28784
+ }
28785
+ };
28786
+ function defaultAction(errorCode) {
28787
+ if (errorCode >= 500 || errorCode === 429) return () => window.location.reload();
28788
+ return () => {
28789
+ if (window.history.length > 1) window.history.back();
28790
+ else window.location.assign(window.location.origin);
28791
+ };
28792
+ }
28793
+ function ErrorPage({
28794
+ errorCode = 404,
28795
+ title,
28796
+ description,
28797
+ onAction,
28798
+ actionLabel
28799
+ }) {
28800
+ const config2 = ERROR_CONFIGS[errorCode] ?? ERROR_CONFIGS[500];
28801
+ const resolvedTitle = title ?? config2.title;
28802
+ const resolvedDescription = description ?? config2.description;
28803
+ const resolvedActionLabel = actionLabel ?? config2.actionLabel;
28804
+ const handleAction = onAction ?? defaultAction(errorCode);
28805
+ return /* @__PURE__ */ jsxs(
28806
+ Flex,
28807
+ {
28808
+ pos: "relative",
28809
+ align: "center",
28810
+ justify: "center",
28811
+ style: { minHeight: "100dvh", overflow: "hidden" },
28812
+ children: [
28813
+ /* @__PURE__ */ jsx(
28814
+ Box,
28815
+ {
28816
+ pos: "absolute",
28817
+ "aria-hidden": true,
28818
+ fw: 900,
28819
+ lh: 1,
28820
+ w: "100%",
28821
+ ta: "center",
28822
+ c: fairmintVars.watermarkColor,
28823
+ ff: fairmintVars.fontHeadings,
28824
+ style: {
28825
+ fontSize: "clamp(200px, 30vw, 380px)",
28826
+ userSelect: "none",
28827
+ letterSpacing: "-0.04em",
28828
+ top: "50%",
28829
+ left: "50%",
28830
+ transform: "translate(-50%, -50%)",
28831
+ pointerEvents: "none"
28832
+ },
28833
+ children: errorCode
28834
+ }
28835
+ ),
28836
+ /* @__PURE__ */ jsx(Container, { size: "sm", pos: "relative", style: { zIndex: 1 }, children: /* @__PURE__ */ jsxs(Stack, { align: "center", gap: "lg", children: [
28837
+ /* @__PURE__ */ jsx(Title, { order: 2, ta: "center", children: resolvedTitle }),
28838
+ /* @__PURE__ */ jsx(Text, { c: fairmintVars.colorTextSecondary, ta: "center", maw: 500, size: "lg", children: resolvedDescription }),
28839
+ /* @__PURE__ */ jsx(Button, { color: colors.primary, onClick: handleAction, children: resolvedActionLabel })
28840
+ ] }) })
28841
+ ]
28842
+ }
28843
+ );
28844
+ }
28634
28845
  const DefaultChevronIcon = () => /* @__PURE__ */ jsx(
28635
28846
  "svg",
28636
28847
  {
@@ -28669,14 +28880,22 @@ function ListRow({
28669
28880
  /* @__PURE__ */ jsx(Avatar, { src: avatarSrc, alt: title, radius: "md", size: 40, color: avatarColor, children: avatarFallback ?? title.charAt(0).toUpperCase() }),
28670
28881
  /* @__PURE__ */ jsxs(Box, { flex: 1, miw: 0, children: [
28671
28882
  /* @__PURE__ */ jsx(Text, { fw: 500, size: "sm", truncate: true, children: title }),
28672
- subtitle && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lh: 1.3, children: subtitle })
28883
+ subtitle && /* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, lh: 1.3, children: subtitle })
28673
28884
  ] }),
28674
28885
  /* @__PURE__ */ jsxs(Group, { gap: 6, wrap: "nowrap", children: [
28675
28886
  rightSection ?? (value !== void 0 && /* @__PURE__ */ jsxs(Stack, { gap: 2, align: "flex-end", children: [
28676
28887
  /* @__PURE__ */ jsx(Text, { fw: 500, size: "sm", style: { whiteSpace: "nowrap" }, children: value }),
28677
- valueSubtitle && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", style: { whiteSpace: "nowrap" }, children: valueSubtitle })
28888
+ valueSubtitle && /* @__PURE__ */ jsx(
28889
+ Text,
28890
+ {
28891
+ size: "xs",
28892
+ c: fairmintVars.colorTextSecondary,
28893
+ style: { whiteSpace: "nowrap" },
28894
+ children: valueSubtitle
28895
+ }
28896
+ )
28678
28897
  ] })),
28679
- displayChevron && (chevronIcon ?? /* @__PURE__ */ jsx(Box, { c: `${colors.neutral}.4`, style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx(DefaultChevronIcon, {}) }))
28898
+ displayChevron && (chevronIcon ?? /* @__PURE__ */ jsx(Box, { c: fairmintVars.colorTextTertiary, style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx(DefaultChevronIcon, {}) }))
28680
28899
  ] })
28681
28900
  ] });
28682
28901
  const animationStyle = animate ? {
@@ -28688,7 +28907,7 @@ function ListRow({
28688
28907
  return /* @__PURE__ */ jsx(
28689
28908
  Box,
28690
28909
  {
28691
- bg: isSelected ? `${colors.primary}.0` : void 0,
28910
+ bg: isSelected ? fairmintVars.colorSurfaceSelected : void 0,
28692
28911
  py: "sm",
28693
28912
  px: "md",
28694
28913
  style: animationStyle,
@@ -28699,7 +28918,7 @@ function ListRow({
28699
28918
  return /* @__PURE__ */ jsx(
28700
28919
  UnstyledButton,
28701
28920
  {
28702
- bg: isSelected ? `${colors.primary}.0` : void 0,
28921
+ bg: isSelected ? fairmintVars.colorSurfaceSelected : void 0,
28703
28922
  onClick,
28704
28923
  w: "100%",
28705
28924
  py: "sm",
@@ -29969,9 +30188,9 @@ function PhotoCropModal({
29969
30188
  )
29970
30189
  }
29971
30190
  ),
29972
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", ta: "center", children: "Drag to reposition · Scroll or pinch to zoom" }),
30191
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, ta: "center", children: "Drag to reposition · Scroll or pinch to zoom" }),
29973
30192
  /* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "xs", children: [
29974
- /* @__PURE__ */ jsx(Button, { variant: "subtle", color: "gray", onClick: onClose, disabled: isConfirming, children: "Cancel" }),
30193
+ /* @__PURE__ */ jsx(Button, { variant: "subtle", color: colors.neutral, onClick: onClose, disabled: isConfirming, children: "Cancel" }),
29975
30194
  /* @__PURE__ */ jsx(Button, { onClick: handleConfirm, loading: isConfirming, disabled: !croppedAreaPixels, children: "Apply" })
29976
30195
  ] })
29977
30196
  ] }) });
@@ -30070,7 +30289,7 @@ function StatCard({
30070
30289
  }
30071
30290
  ),
30072
30291
  /* @__PURE__ */ jsx(Text, { fw: 700, size: "xl", lh: 1, children: value }),
30073
- trend && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: trend })
30292
+ trend && /* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, children: trend })
30074
30293
  ] }),
30075
30294
  icon && /* @__PURE__ */ jsx(Box, { c: `${color}.5`, fz: "1.5rem", children: icon })
30076
30295
  ] }) });
@@ -30165,7 +30384,7 @@ function PageHeader({ title, subtitle, action }) {
30165
30384
  return /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", mb: "lg", children: [
30166
30385
  /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
30167
30386
  /* @__PURE__ */ jsx(Title, { order: 2, children: title }),
30168
- subtitle && /* @__PURE__ */ jsx(Text, { c: "dimmed", size: "sm", children: subtitle })
30387
+ subtitle && /* @__PURE__ */ jsx(Text, { c: fairmintVars.colorTextSecondary, size: "sm", children: subtitle })
30169
30388
  ] }),
30170
30389
  action
30171
30390
  ] });
@@ -30355,6 +30574,8 @@ function InvestorProfileCard({
30355
30574
  subtitle,
30356
30575
  children,
30357
30576
  onEditName,
30577
+ editNameDisabled,
30578
+ editNameTooltip,
30358
30579
  onUploadPhoto,
30359
30580
  photoUploading,
30360
30581
  editNameIcon,
@@ -30443,11 +30664,25 @@ function InvestorProfileCard({
30443
30664
  /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", align: "center", children: [
30444
30665
  /* @__PURE__ */ jsx(Text, { fw: 600, size: "md", children: displayName }),
30445
30666
  verificationStatus && /* @__PURE__ */ jsx(StatusBadge, { status: verificationStatus, size: "xs" }),
30446
- onEditName && /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", onClick: onEditName, "aria-label": "Edit name", children: editNameIcon ?? /* @__PURE__ */ jsx(DefaultPencilIcon, {}) })
30667
+ onEditName && (editNameDisabled ? /* @__PURE__ */ jsx(Tooltip, { label: editNameTooltip ?? "Coming soon", children: /* @__PURE__ */ jsx(
30668
+ ActionIcon,
30669
+ {
30670
+ variant: "subtle",
30671
+ size: "sm",
30672
+ "aria-label": "Edit name",
30673
+ "aria-disabled": "true",
30674
+ onClick: (event) => {
30675
+ event.preventDefault();
30676
+ event.stopPropagation();
30677
+ },
30678
+ style: { opacity: 0.5, cursor: "not-allowed" },
30679
+ children: editNameIcon ?? /* @__PURE__ */ jsx(DefaultPencilIcon, {})
30680
+ }
30681
+ ) }) : /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", onClick: onEditName, "aria-label": "Edit name", children: editNameIcon ?? /* @__PURE__ */ jsx(DefaultPencilIcon, {}) }))
30447
30682
  ] }),
30448
- email && /* @__PURE__ */ jsx(Text, { size: "sm", c: `${colors.neutral}.5`, children: email }),
30449
- memberSinceText && /* @__PURE__ */ jsx(Text, { size: "xs", c: `${colors.neutral}.4`, children: memberSinceText }),
30450
- subtitle && /* @__PURE__ */ jsx(Text, { size: "xs", c: `${colors.neutral}.5`, children: subtitle })
30683
+ email && /* @__PURE__ */ jsx(Text, { size: "sm", c: fairmintVars.colorTextSecondary, children: email }),
30684
+ memberSinceText && /* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextTertiary, children: memberSinceText }),
30685
+ subtitle && /* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, children: subtitle })
30451
30686
  ] })
30452
30687
  ] }),
30453
30688
  children
@@ -30547,7 +30782,7 @@ function WalletList({
30547
30782
  children: [
30548
30783
  /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
30549
30784
  /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", children: getTypeLabel(w.type, typeLabels) }),
30550
- w.label && /* @__PURE__ */ jsx(Text, { size: "xs", c: `${colors.neutral}.5`, children: w.label }),
30785
+ w.label && /* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, children: w.label }),
30551
30786
  /* @__PURE__ */ jsx(Text, { size: "sm", ff: "monospace", children: truncateAddress(w.address) })
30552
30787
  ] }),
30553
30788
  /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
@@ -30625,7 +30860,7 @@ function WalletList({
30625
30860
  title: "Remove Wallet",
30626
30861
  message: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
30627
30862
  /* @__PURE__ */ jsx(Text, { size: "sm", children: "Are you sure you want to remove this wallet address? This action cannot be undone." }),
30628
- walletToRemove && /* @__PURE__ */ jsx(Text, { size: "sm", ff: "monospace", c: `${colors.neutral}.5`, children: walletToRemove }),
30863
+ walletToRemove && /* @__PURE__ */ jsx(Text, { size: "sm", ff: "monospace", c: fairmintVars.colorTextSecondary, children: walletToRemove }),
30629
30864
  removeError && /* @__PURE__ */ jsx(Text, { size: "sm", c: colors.error, children: removeError })
30630
30865
  ] }),
30631
30866
  opened: walletToRemove !== null,
@@ -30704,6 +30939,7 @@ export {
30704
30939
  EmptyState,
30705
30940
  EquityGrantCard,
30706
30941
  ErrorFallback,
30942
+ ErrorPage,
30707
30943
  EthereumAddressField,
30708
30944
  FairmintLogo,
30709
30945
  FairmintProvider,
@@ -30762,18 +30998,24 @@ export {
30762
30998
  ZipField,
30763
30999
  brandColors,
30764
31000
  colors,
31001
+ createFairmintMantineProviderProps,
30765
31002
  createZipSchema,
30766
31003
  emailSchema,
30767
31004
  ethereumAddressSchema,
31005
+ fairmintCssVariables,
31006
+ fairmintVars,
30768
31007
  formatCurrency,
30769
31008
  formatCurrencyPrecise,
30770
31009
  formatDate,
30771
31010
  formatNumber,
30772
31011
  formatPercent,
31012
+ formatPhone,
31013
+ formatPhoneDisplay,
30773
31014
  formatPreciseWithCurrency,
30774
31015
  getAvatarColor,
30775
31016
  isEthereumAddress,
30776
31017
  neutralColors,
31018
+ normalizePhone,
30777
31019
  notify,
30778
31020
  passwordSchema,
30779
31021
  phoneSchema,
@@ -30781,6 +31023,7 @@ export {
30781
31023
  semanticColors,
30782
31024
  theme,
30783
31025
  truncateAddress,
31026
+ typography,
30784
31027
  useClickOutside,
30785
31028
  useClipboard,
30786
31029
  useDebouncedCallback,