@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.
@@ -26820,110 +26820,6 @@ const AVATAR_PALETTE = [
26820
26820
  colors.accent2,
26821
26821
  colors.accent3
26822
26822
  ];
26823
- const ActionIcon = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(ActionIcon$1, { color: colors.primary, variant: "subtle", ...props, ref }));
26824
- ActionIcon.displayName = "ActionIcon";
26825
- function Alert(props) {
26826
- return /* @__PURE__ */ jsxRuntime.jsx(Alert$1, { ...props });
26827
- }
26828
- const Avatar = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(Avatar$1, { radius: "md", color: colors.primary, ...props, ref }));
26829
- Avatar.displayName = "Avatar";
26830
- const Badge = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { variant: "light", ...props, ref }));
26831
- Badge.displayName = "Badge";
26832
- const Button = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(Button$1, { color: colors.primary, ...props, ref }));
26833
- Button.displayName = "Button";
26834
- const Card = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(Card$1, { padding: "lg", radius: "xl", withBorder: true, ...props, ref }));
26835
- Card.displayName = "Card";
26836
- const Checkbox = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(Checkbox$1, { color: colors.primary, ...props, ref }));
26837
- Checkbox.displayName = "Checkbox";
26838
- function Drawer(props) {
26839
- return /* @__PURE__ */ jsxRuntime.jsx(Drawer$1, { position: "right", size: "lg", p: "lg", ...props });
26840
- }
26841
- function Loader(props) {
26842
- return /* @__PURE__ */ jsxRuntime.jsx(Loader$1, { ...props });
26843
- }
26844
- function MenuBase(props) {
26845
- return /* @__PURE__ */ jsxRuntime.jsx(Menu$1, { shadow: "md", ...props });
26846
- }
26847
- const Menu = Object.assign(MenuBase, {
26848
- Target: Menu$1.Target,
26849
- Dropdown: Menu$1.Dropdown,
26850
- Item: Menu$1.Item,
26851
- Label: Menu$1.Label,
26852
- Divider: Menu$1.Divider
26853
- });
26854
- function Modal(props) {
26855
- return /* @__PURE__ */ jsxRuntime.jsx(Modal$1, { centered: true, radius: "lg", ...props });
26856
- }
26857
- const PasswordInput = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(PasswordInput$1, { size: "md", ...props, ref }));
26858
- PasswordInput.displayName = "PasswordInput";
26859
- const Select = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(Select$1, { size: "md", ...props, ref }));
26860
- Select.displayName = "Select";
26861
- function Skeleton(props) {
26862
- return /* @__PURE__ */ jsxRuntime.jsx(Skeleton$1, { ...props });
26863
- }
26864
- const Switch = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(Switch$1, { color: colors.primary, ...props, ref }));
26865
- Switch.displayName = "Switch";
26866
- function TableBase(props) {
26867
- return /* @__PURE__ */ jsxRuntime.jsx(Table$1, { ...props });
26868
- }
26869
- const Table = Object.assign(TableBase, {
26870
- Thead: Table$1.Thead,
26871
- Tbody: Table$1.Tbody,
26872
- Tr: Table$1.Tr,
26873
- Th: Table$1.Th,
26874
- Td: Table$1.Td,
26875
- Tfoot: Table$1.Tfoot,
26876
- Caption: Table$1.Caption
26877
- });
26878
- function TabsBase(props) {
26879
- return /* @__PURE__ */ jsxRuntime.jsx(Tabs$1, { color: colors.primary, ...props });
26880
- }
26881
- const Tabs = Object.assign(TabsBase, {
26882
- List: Tabs$1.List,
26883
- Tab: Tabs$1.Tab,
26884
- Panel: Tabs$1.Panel
26885
- });
26886
- const TextInput = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(TextInput$1, { size: "md", ...props, ref }));
26887
- TextInput.displayName = "TextInput";
26888
- function Tooltip(props) {
26889
- return /* @__PURE__ */ jsxRuntime.jsx(Tooltip$1, { ...props });
26890
- }
26891
- function ErrorFallback({
26892
- title = "Something went wrong",
26893
- description = "We've been notified and are working on a fix.",
26894
- onAction,
26895
- actionLabel = "Reload Page",
26896
- error: error2
26897
- }) {
26898
- if (error2 !== void 0) {
26899
- console.error("[ErrorFallback]", error2);
26900
- }
26901
- const handleAction = onAction ?? (() => window.location.reload());
26902
- return /* @__PURE__ */ jsxRuntime.jsx(Container, { size: "sm", py: "xl", children: /* @__PURE__ */ jsxRuntime.jsxs(Stack, { align: "center", gap: "md", children: [
26903
- /* @__PURE__ */ jsxRuntime.jsx(Title, { order: 2, children: title }),
26904
- /* @__PURE__ */ jsxRuntime.jsx(Text, { c: "dimmed", children: description }),
26905
- /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleAction, children: actionLabel })
26906
- ] }) });
26907
- }
26908
- function FairmintLogo({
26909
- src = "https://imagedelivery.net/Lm6ChJXR4cIKKycsNMvGjA/0367be38-c9d8-4206-aaae-eba5ff830600/public",
26910
- width = 140,
26911
- height = 30,
26912
- className,
26913
- alt = "Fairmint"
26914
- }) {
26915
- return /* @__PURE__ */ jsxRuntime.jsx(
26916
- "img",
26917
- {
26918
- src,
26919
- alt,
26920
- width,
26921
- height,
26922
- className,
26923
- style: { objectFit: "contain" }
26924
- }
26925
- );
26926
- }
26927
26823
  const radii = {
26928
26824
  xs: "0.25rem",
26929
26825
  sm: "0.375rem",
@@ -27027,12 +26923,16 @@ const info = [
27027
26923
  "#155B75",
27028
26924
  "#164C63"
27029
26925
  ];
26926
+ const typography = {
26927
+ fontFamily: '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"',
26928
+ headingFontFamily: '"Plus Jakarta Sans", sans-serif'
26929
+ };
27030
26930
  const theme = createTheme({
27031
26931
  primaryColor: "indigo",
27032
26932
  colors: { indigo, gray: neutral, fairmintBlue, fairmintPurple, success, warning, error, info },
27033
- fontFamily: '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"',
26933
+ fontFamily: typography.fontFamily,
27034
26934
  headings: {
27035
- fontFamily: '"Plus Jakarta Sans", sans-serif',
26935
+ fontFamily: typography.headingFontFamily,
27036
26936
  fontWeight: "700"
27037
26937
  },
27038
26938
  radius: radii,
@@ -27082,6 +26982,49 @@ const theme = createTheme({
27082
26982
  }
27083
26983
  }
27084
26984
  });
26985
+ const fairmintCssVariables = () => ({
26986
+ variables: {
26987
+ "--fairmint-font-headings": typography.headingFontFamily,
26988
+ "--fairmint-font-body": typography.fontFamily
26989
+ },
26990
+ light: {
26991
+ /** Large decorative background text on error/empty pages. */
26992
+ "--fairmint-watermark-color": neutral[1],
26993
+ /** Supporting / muted text (subtitles, secondary labels). Replaces c="dimmed" and neutral.5 */
26994
+ "--fairmint-color-text-secondary": neutral[5],
26995
+ /** Faint metadata text (timestamps, tertiary labels). Replaces neutral.4 */
26996
+ "--fairmint-color-text-tertiary": neutral[4],
26997
+ /** Background tint for selected / active rows. Replaces primary.0 */
26998
+ "--fairmint-color-surface-selected": indigo[0]
26999
+ },
27000
+ dark: {
27001
+ "--fairmint-watermark-color": neutral[7],
27002
+ "--fairmint-color-text-secondary": neutral[4],
27003
+ "--fairmint-color-text-tertiary": neutral[5],
27004
+ "--fairmint-color-surface-selected": indigo[9]
27005
+ }
27006
+ });
27007
+ const fairmintVars = {
27008
+ /** Secondary / muted text — subtitles, supporting labels. Adapts to color scheme. */
27009
+ colorTextSecondary: `var(--fairmint-color-text-secondary, ${neutral[5]})`,
27010
+ /** Tertiary / faint text — timestamps, metadata. Adapts to color scheme. */
27011
+ colorTextTertiary: `var(--fairmint-color-text-tertiary, ${neutral[4]})`,
27012
+ /** Background tint for selected / active rows. Adapts to color scheme. */
27013
+ colorSurfaceSelected: `var(--fairmint-color-surface-selected, ${indigo[0]})`,
27014
+ /** Large decorative watermark on error/empty pages. Adapts to color scheme. */
27015
+ watermarkColor: `var(--fairmint-watermark-color, ${neutral[1]})`,
27016
+ /** Heading font family (Plus Jakarta Sans). */
27017
+ fontHeadings: `var(--fairmint-font-headings, ${typography.headingFontFamily})`,
27018
+ /** Body font family (Inter). */
27019
+ fontBody: `var(--fairmint-font-body, ${typography.fontFamily})`
27020
+ };
27021
+ function createFairmintMantineProviderProps(colorScheme = "light") {
27022
+ return {
27023
+ theme,
27024
+ cssVariablesResolver: fairmintCssVariables,
27025
+ defaultColorScheme: colorScheme
27026
+ };
27027
+ }
27085
27028
  const brandColors = {
27086
27029
  blue: "#0A4EFB",
27087
27030
  purple: "#9E03FF",
@@ -27106,15 +27049,127 @@ const semanticColors = {
27106
27049
  error: "#F04438",
27107
27050
  info: "#06AED4"
27108
27051
  };
27052
+ const ActionIcon = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(ActionIcon$1, { color: colors.primary, variant: "subtle", ...props, ref }));
27053
+ ActionIcon.displayName = "ActionIcon";
27054
+ function Alert(props) {
27055
+ return /* @__PURE__ */ jsxRuntime.jsx(Alert$1, { ...props });
27056
+ }
27057
+ const Avatar = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(Avatar$1, { radius: "md", color: colors.primary, ...props, ref }));
27058
+ Avatar.displayName = "Avatar";
27059
+ const Badge = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { variant: "light", ...props, ref }));
27060
+ Badge.displayName = "Badge";
27061
+ const Button = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(Button$1, { color: colors.primary, ...props, ref }));
27062
+ Button.displayName = "Button";
27063
+ const Card = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(Card$1, { padding: "lg", radius: "xl", withBorder: true, ...props, ref }));
27064
+ Card.displayName = "Card";
27065
+ const Checkbox = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(Checkbox$1, { color: colors.primary, ...props, ref }));
27066
+ Checkbox.displayName = "Checkbox";
27067
+ function Drawer(props) {
27068
+ return /* @__PURE__ */ jsxRuntime.jsx(Drawer$1, { position: "right", size: "lg", p: "lg", ...props });
27069
+ }
27070
+ function Loader(props) {
27071
+ return /* @__PURE__ */ jsxRuntime.jsx(Loader$1, { ...props });
27072
+ }
27073
+ function MenuBase(props) {
27074
+ return /* @__PURE__ */ jsxRuntime.jsx(Menu$1, { shadow: "md", ...props });
27075
+ }
27076
+ const Menu = Object.assign(MenuBase, {
27077
+ Target: Menu$1.Target,
27078
+ Dropdown: Menu$1.Dropdown,
27079
+ Item: Menu$1.Item,
27080
+ Label: Menu$1.Label,
27081
+ Divider: Menu$1.Divider
27082
+ });
27083
+ function Modal(props) {
27084
+ return /* @__PURE__ */ jsxRuntime.jsx(Modal$1, { centered: true, radius: "lg", ...props });
27085
+ }
27086
+ const PasswordInput = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(PasswordInput$1, { size: "md", ...props, ref }));
27087
+ PasswordInput.displayName = "PasswordInput";
27088
+ const Select = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(Select$1, { size: "md", ...props, ref }));
27089
+ Select.displayName = "Select";
27090
+ function Skeleton(props) {
27091
+ return /* @__PURE__ */ jsxRuntime.jsx(Skeleton$1, { ...props });
27092
+ }
27093
+ const Switch = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(Switch$1, { color: colors.primary, ...props, ref }));
27094
+ Switch.displayName = "Switch";
27095
+ function TableBase(props) {
27096
+ return /* @__PURE__ */ jsxRuntime.jsx(Table$1, { ...props });
27097
+ }
27098
+ const Table = Object.assign(TableBase, {
27099
+ Thead: Table$1.Thead,
27100
+ Tbody: Table$1.Tbody,
27101
+ Tr: Table$1.Tr,
27102
+ Th: Table$1.Th,
27103
+ Td: Table$1.Td,
27104
+ Tfoot: Table$1.Tfoot,
27105
+ Caption: Table$1.Caption
27106
+ });
27107
+ function TabsBase(props) {
27108
+ return /* @__PURE__ */ jsxRuntime.jsx(Tabs$1, { color: colors.primary, ...props });
27109
+ }
27110
+ const Tabs = Object.assign(TabsBase, {
27111
+ List: Tabs$1.List,
27112
+ Tab: Tabs$1.Tab,
27113
+ Panel: Tabs$1.Panel
27114
+ });
27115
+ const TextInput = React.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(TextInput$1, { size: "md", ...props, ref }));
27116
+ TextInput.displayName = "TextInput";
27117
+ function Tooltip(props) {
27118
+ return /* @__PURE__ */ jsxRuntime.jsx(Tooltip$1, { fz: "xs", ...props });
27119
+ }
27120
+ function ErrorFallback({
27121
+ title = "Something went wrong",
27122
+ description = "We've been notified and are working on a fix.",
27123
+ onAction,
27124
+ actionLabel = "Reload Page",
27125
+ error: error2
27126
+ }) {
27127
+ if (error2 !== void 0) {
27128
+ console.error("[ErrorFallback]", error2);
27129
+ }
27130
+ const handleAction = onAction ?? (() => window.location.reload());
27131
+ return /* @__PURE__ */ jsxRuntime.jsx(Container, { size: "sm", py: "xl", children: /* @__PURE__ */ jsxRuntime.jsxs(Stack, { align: "center", gap: "md", children: [
27132
+ /* @__PURE__ */ jsxRuntime.jsx(Title, { order: 2, children: title }),
27133
+ /* @__PURE__ */ jsxRuntime.jsx(Text, { c: fairmintVars.colorTextSecondary, children: description }),
27134
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleAction, children: actionLabel })
27135
+ ] }) });
27136
+ }
27137
+ function FairmintLogo({
27138
+ src = "https://imagedelivery.net/Lm6ChJXR4cIKKycsNMvGjA/0367be38-c9d8-4206-aaae-eba5ff830600/public",
27139
+ width = 140,
27140
+ height = 30,
27141
+ className,
27142
+ alt = "Fairmint"
27143
+ }) {
27144
+ return /* @__PURE__ */ jsxRuntime.jsx(
27145
+ "img",
27146
+ {
27147
+ src,
27148
+ alt,
27149
+ width,
27150
+ height,
27151
+ className,
27152
+ style: { objectFit: "contain" }
27153
+ }
27154
+ );
27155
+ }
27109
27156
  function FairmintProvider({
27110
27157
  children,
27111
27158
  colorScheme = "light",
27112
27159
  notificationPosition = "top-right"
27113
27160
  }) {
27114
- return /* @__PURE__ */ jsxRuntime.jsxs(MantineProvider, { theme, defaultColorScheme: colorScheme, children: [
27115
- /* @__PURE__ */ jsxRuntime.jsx(Notifications, { position: notificationPosition }),
27116
- children
27117
- ] });
27161
+ return /* @__PURE__ */ jsxRuntime.jsxs(
27162
+ MantineProvider,
27163
+ {
27164
+ theme,
27165
+ defaultColorScheme: colorScheme,
27166
+ cssVariablesResolver: fairmintCssVariables,
27167
+ children: [
27168
+ /* @__PURE__ */ jsxRuntime.jsx(Notifications, { position: notificationPosition }),
27169
+ children
27170
+ ]
27171
+ }
27172
+ );
27118
27173
  }
27119
27174
  const emailSchema = stringType().email("Please enter a valid email address");
27120
27175
  function EmailField({ error: error2, ...rest }) {
@@ -28229,7 +28284,7 @@ function FormField({
28229
28284
  }
28230
28285
  ),
28231
28286
  children && inputProps.error && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: "error", role: "alert", children: inputProps.error }),
28232
- children && description && !inputProps.error && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: "dimmed", children: description })
28287
+ children && description && !inputProps.error && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, children: description })
28233
28288
  ] });
28234
28289
  }
28235
28290
  const passwordSchema = stringType().min(8, "Password must be at least 8 characters");
@@ -28245,17 +28300,77 @@ function PasswordField({ error: error2, ...rest }) {
28245
28300
  }
28246
28301
  );
28247
28302
  }
28248
- const phoneSchema = stringType().regex(/^\+?[\d\s\-().]{7,20}$/, "Please enter a valid phone number");
28249
- function PhoneField({ error: error2, ...rest }) {
28303
+ const phoneSchema = stringType().refine((value) => {
28304
+ if (!/^\+?[\d\s\-().]*$/.test(value)) return false;
28305
+ const digits = value.replace(/\D/g, "");
28306
+ if (value.startsWith("+")) {
28307
+ if (digits.startsWith("1")) return digits.length === 11;
28308
+ return digits.length >= 8 && digits.length <= 15;
28309
+ }
28310
+ return digits.length === 10 || digits.length === 11 && digits.startsWith("1");
28311
+ }, "Please enter a valid phone number");
28312
+ function formatPhone(raw) {
28313
+ const hasPlus = raw.startsWith("+");
28314
+ const digits = raw.replace(/\D/g, "");
28315
+ if (!digits) return hasPlus ? "+" : "";
28316
+ if (!hasPlus && digits.length === 11 && digits.startsWith("1")) {
28317
+ return formatPhone(`+${digits}`);
28318
+ }
28319
+ if (hasPlus && digits.startsWith("1")) {
28320
+ const local = digits.slice(1);
28321
+ if (!local.length) return "+1";
28322
+ if (local.length <= 3) return `+1 (${local}`;
28323
+ if (local.length <= 6) return `+1 (${local.slice(0, 3)}) ${local.slice(3)}`;
28324
+ return `+1 (${local.slice(0, 3)}) ${local.slice(3, 6)}-${local.slice(6, 10)}`;
28325
+ }
28326
+ if (hasPlus) return `+${digits}`;
28327
+ if (digits.length <= 3) return digits;
28328
+ if (digits.length <= 6) return `(${digits.slice(0, 3)}) ${digits.slice(3)}`;
28329
+ return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6, 10)}`;
28330
+ }
28331
+ function normalizePhone(formatted) {
28332
+ const hasPlus = formatted.startsWith("+");
28333
+ const digits = formatted.replace(/\D/g, "");
28334
+ if (!digits) return "";
28335
+ if (hasPlus) return `+${digits}`;
28336
+ if (digits.length === 10) return `+1${digits}`;
28337
+ return `+${digits}`;
28338
+ }
28339
+ const formatPhoneDisplay = formatPhone;
28340
+ function PhoneField({ error: error2, onChange, value, ...rest }) {
28341
+ const inputRef = React.useRef(null);
28342
+ const handleChange = (e) => {
28343
+ const raw = e.target.value;
28344
+ const hasPlus = raw.startsWith("+");
28345
+ let digits = raw.replace(/\D/g, "");
28346
+ const shouldFormatAsUsCountryCode = digits.startsWith("1") && (hasPlus || !hasPlus && digits.length > 10);
28347
+ if (shouldFormatAsUsCountryCode) {
28348
+ digits = digits.slice(0, 11);
28349
+ } else {
28350
+ digits = digits.slice(0, hasPlus ? 15 : 10);
28351
+ }
28352
+ const formatted = formatPhone(hasPlus || shouldFormatAsUsCountryCode ? `+${digits}` : digits);
28353
+ e.target.value = formatted;
28354
+ onChange?.(e);
28355
+ };
28356
+ const displayValue = typeof value === "string" ? formatPhone(value) : value;
28357
+ React.useEffect(() => {
28358
+ if (inputRef.current && displayValue != null && inputRef.current.value !== String(displayValue)) {
28359
+ inputRef.current.value = String(displayValue);
28360
+ }
28361
+ }, [displayValue]);
28250
28362
  return /* @__PURE__ */ jsxRuntime.jsx(
28251
28363
  TextInput,
28252
28364
  {
28365
+ ref: inputRef,
28253
28366
  type: "tel",
28254
28367
  label: rest.label ?? "Phone",
28255
- placeholder: rest.placeholder ?? "+1 (555) 000-0000",
28368
+ placeholder: rest.placeholder ?? "(555) 000-0000",
28256
28369
  autoComplete: "tel",
28370
+ ...rest,
28257
28371
  error: error2,
28258
- ...rest
28372
+ value: displayValue,
28373
+ onChange: handleChange
28259
28374
  }
28260
28375
  );
28261
28376
  }
@@ -28459,9 +28574,9 @@ function EmptyState({
28459
28574
  actionColor = colors.primary
28460
28575
  }) {
28461
28576
  return /* @__PURE__ */ jsxRuntime.jsxs(Stack, { align: "center", gap: "md", py: "xl", role: "status", children: [
28462
- icon && /* @__PURE__ */ jsxRuntime.jsx(Box, { c: `${colors.neutral}.5`, fz: "2.5rem", children: icon }),
28577
+ icon && /* @__PURE__ */ jsxRuntime.jsx(Box, { c: fairmintVars.colorTextSecondary, fz: "2.5rem", children: icon }),
28463
28578
  /* @__PURE__ */ jsxRuntime.jsx(Title, { order: 4, ta: "center", children: title }),
28464
- description && /* @__PURE__ */ jsxRuntime.jsx(Text, { c: "dimmed", size: "sm", ta: "center", maw: 360, children: description }),
28579
+ description && /* @__PURE__ */ jsxRuntime.jsx(Text, { c: fairmintVars.colorTextSecondary, size: "sm", ta: "center", maw: 360, children: description }),
28465
28580
  actionLabel && onAction && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "light", color: actionColor, onClick: onAction, children: actionLabel })
28466
28581
  ] });
28467
28582
  }
@@ -28649,6 +28764,102 @@ function EditableSection({
28649
28764
  ] }) : readView
28650
28765
  ] });
28651
28766
  }
28767
+ const ERROR_CONFIGS = {
28768
+ 400: {
28769
+ title: "Bad request",
28770
+ description: "Your request could not be understood. Please check your input and try again.",
28771
+ actionLabel: "Go back"
28772
+ },
28773
+ 401: {
28774
+ title: "Authentication required",
28775
+ description: "You need to sign in to access this page. If you believe this is a mistake, please contact support.",
28776
+ actionLabel: "Go back"
28777
+ },
28778
+ 403: {
28779
+ title: "Access denied",
28780
+ description: "You don't have permission to access this page. Contact support if you believe this is a mistake.",
28781
+ actionLabel: "Go back"
28782
+ },
28783
+ 404: {
28784
+ title: "Nothing to see here",
28785
+ 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.",
28786
+ actionLabel: "Go back"
28787
+ },
28788
+ 429: {
28789
+ title: "Too many requests",
28790
+ description: "You have made too many requests in a short period. Please wait a moment before trying again.",
28791
+ actionLabel: "Try again"
28792
+ },
28793
+ 500: {
28794
+ title: "Something went wrong",
28795
+ description: "An unexpected error occurred on our end. We have been notified and are working on a fix.",
28796
+ actionLabel: "Reload page"
28797
+ },
28798
+ 503: {
28799
+ title: "Service unavailable",
28800
+ description: "We are temporarily unavailable for scheduled maintenance. Please check back shortly.",
28801
+ actionLabel: "Try again"
28802
+ }
28803
+ };
28804
+ function defaultAction(errorCode) {
28805
+ if (errorCode >= 500 || errorCode === 429) return () => window.location.reload();
28806
+ return () => {
28807
+ if (window.history.length > 1) window.history.back();
28808
+ else window.location.assign(window.location.origin);
28809
+ };
28810
+ }
28811
+ function ErrorPage({
28812
+ errorCode = 404,
28813
+ title,
28814
+ description,
28815
+ onAction,
28816
+ actionLabel
28817
+ }) {
28818
+ const config2 = ERROR_CONFIGS[errorCode] ?? ERROR_CONFIGS[500];
28819
+ const resolvedTitle = title ?? config2.title;
28820
+ const resolvedDescription = description ?? config2.description;
28821
+ const resolvedActionLabel = actionLabel ?? config2.actionLabel;
28822
+ const handleAction = onAction ?? defaultAction(errorCode);
28823
+ return /* @__PURE__ */ jsxRuntime.jsxs(
28824
+ Flex,
28825
+ {
28826
+ pos: "relative",
28827
+ align: "center",
28828
+ justify: "center",
28829
+ style: { minHeight: "100dvh", overflow: "hidden" },
28830
+ children: [
28831
+ /* @__PURE__ */ jsxRuntime.jsx(
28832
+ Box,
28833
+ {
28834
+ pos: "absolute",
28835
+ "aria-hidden": true,
28836
+ fw: 900,
28837
+ lh: 1,
28838
+ w: "100%",
28839
+ ta: "center",
28840
+ c: fairmintVars.watermarkColor,
28841
+ ff: fairmintVars.fontHeadings,
28842
+ style: {
28843
+ fontSize: "clamp(200px, 30vw, 380px)",
28844
+ userSelect: "none",
28845
+ letterSpacing: "-0.04em",
28846
+ top: "50%",
28847
+ left: "50%",
28848
+ transform: "translate(-50%, -50%)",
28849
+ pointerEvents: "none"
28850
+ },
28851
+ children: errorCode
28852
+ }
28853
+ ),
28854
+ /* @__PURE__ */ jsxRuntime.jsx(Container, { size: "sm", pos: "relative", style: { zIndex: 1 }, children: /* @__PURE__ */ jsxRuntime.jsxs(Stack, { align: "center", gap: "lg", children: [
28855
+ /* @__PURE__ */ jsxRuntime.jsx(Title, { order: 2, ta: "center", children: resolvedTitle }),
28856
+ /* @__PURE__ */ jsxRuntime.jsx(Text, { c: fairmintVars.colorTextSecondary, ta: "center", maw: 500, size: "lg", children: resolvedDescription }),
28857
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { color: colors.primary, onClick: handleAction, children: resolvedActionLabel })
28858
+ ] }) })
28859
+ ]
28860
+ }
28861
+ );
28862
+ }
28652
28863
  const DefaultChevronIcon = () => /* @__PURE__ */ jsxRuntime.jsx(
28653
28864
  "svg",
28654
28865
  {
@@ -28687,14 +28898,22 @@ function ListRow({
28687
28898
  /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: avatarSrc, alt: title, radius: "md", size: 40, color: avatarColor, children: avatarFallback ?? title.charAt(0).toUpperCase() }),
28688
28899
  /* @__PURE__ */ jsxRuntime.jsxs(Box, { flex: 1, miw: 0, children: [
28689
28900
  /* @__PURE__ */ jsxRuntime.jsx(Text, { fw: 500, size: "sm", truncate: true, children: title }),
28690
- subtitle && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: "dimmed", lh: 1.3, children: subtitle })
28901
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, lh: 1.3, children: subtitle })
28691
28902
  ] }),
28692
28903
  /* @__PURE__ */ jsxRuntime.jsxs(Group, { gap: 6, wrap: "nowrap", children: [
28693
28904
  rightSection ?? (value !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs(Stack, { gap: 2, align: "flex-end", children: [
28694
28905
  /* @__PURE__ */ jsxRuntime.jsx(Text, { fw: 500, size: "sm", style: { whiteSpace: "nowrap" }, children: value }),
28695
- valueSubtitle && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: "dimmed", style: { whiteSpace: "nowrap" }, children: valueSubtitle })
28906
+ valueSubtitle && /* @__PURE__ */ jsxRuntime.jsx(
28907
+ Text,
28908
+ {
28909
+ size: "xs",
28910
+ c: fairmintVars.colorTextSecondary,
28911
+ style: { whiteSpace: "nowrap" },
28912
+ children: valueSubtitle
28913
+ }
28914
+ )
28696
28915
  ] })),
28697
- displayChevron && (chevronIcon ?? /* @__PURE__ */ jsxRuntime.jsx(Box, { c: `${colors.neutral}.4`, style: { flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(DefaultChevronIcon, {}) }))
28916
+ displayChevron && (chevronIcon ?? /* @__PURE__ */ jsxRuntime.jsx(Box, { c: fairmintVars.colorTextTertiary, style: { flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(DefaultChevronIcon, {}) }))
28698
28917
  ] })
28699
28918
  ] });
28700
28919
  const animationStyle = animate ? {
@@ -28706,7 +28925,7 @@ function ListRow({
28706
28925
  return /* @__PURE__ */ jsxRuntime.jsx(
28707
28926
  Box,
28708
28927
  {
28709
- bg: isSelected ? `${colors.primary}.0` : void 0,
28928
+ bg: isSelected ? fairmintVars.colorSurfaceSelected : void 0,
28710
28929
  py: "sm",
28711
28930
  px: "md",
28712
28931
  style: animationStyle,
@@ -28717,7 +28936,7 @@ function ListRow({
28717
28936
  return /* @__PURE__ */ jsxRuntime.jsx(
28718
28937
  UnstyledButton,
28719
28938
  {
28720
- bg: isSelected ? `${colors.primary}.0` : void 0,
28939
+ bg: isSelected ? fairmintVars.colorSurfaceSelected : void 0,
28721
28940
  onClick,
28722
28941
  w: "100%",
28723
28942
  py: "sm",
@@ -29987,9 +30206,9 @@ function PhotoCropModal({
29987
30206
  )
29988
30207
  }
29989
30208
  ),
29990
- /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: "dimmed", ta: "center", children: "Drag to reposition · Scroll or pinch to zoom" }),
30209
+ /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, ta: "center", children: "Drag to reposition · Scroll or pinch to zoom" }),
29991
30210
  /* @__PURE__ */ jsxRuntime.jsxs(Group, { justify: "flex-end", gap: "xs", children: [
29992
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "subtle", color: "gray", onClick: onClose, disabled: isConfirming, children: "Cancel" }),
30211
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "subtle", color: colors.neutral, onClick: onClose, disabled: isConfirming, children: "Cancel" }),
29993
30212
  /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleConfirm, loading: isConfirming, disabled: !croppedAreaPixels, children: "Apply" })
29994
30213
  ] })
29995
30214
  ] }) });
@@ -30088,7 +30307,7 @@ function StatCard({
30088
30307
  }
30089
30308
  ),
30090
30309
  /* @__PURE__ */ jsxRuntime.jsx(Text, { fw: 700, size: "xl", lh: 1, children: value }),
30091
- trend && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: "dimmed", children: trend })
30310
+ trend && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, children: trend })
30092
30311
  ] }),
30093
30312
  icon && /* @__PURE__ */ jsxRuntime.jsx(Box, { c: `${color}.5`, fz: "1.5rem", children: icon })
30094
30313
  ] }) });
@@ -30183,7 +30402,7 @@ function PageHeader({ title, subtitle, action }) {
30183
30402
  return /* @__PURE__ */ jsxRuntime.jsxs(Group, { justify: "space-between", align: "flex-start", mb: "lg", children: [
30184
30403
  /* @__PURE__ */ jsxRuntime.jsxs(Stack, { gap: 4, children: [
30185
30404
  /* @__PURE__ */ jsxRuntime.jsx(Title, { order: 2, children: title }),
30186
- subtitle && /* @__PURE__ */ jsxRuntime.jsx(Text, { c: "dimmed", size: "sm", children: subtitle })
30405
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx(Text, { c: fairmintVars.colorTextSecondary, size: "sm", children: subtitle })
30187
30406
  ] }),
30188
30407
  action
30189
30408
  ] });
@@ -30373,6 +30592,8 @@ function InvestorProfileCard({
30373
30592
  subtitle,
30374
30593
  children,
30375
30594
  onEditName,
30595
+ editNameDisabled,
30596
+ editNameTooltip,
30376
30597
  onUploadPhoto,
30377
30598
  photoUploading,
30378
30599
  editNameIcon,
@@ -30461,11 +30682,25 @@ function InvestorProfileCard({
30461
30682
  /* @__PURE__ */ jsxRuntime.jsxs(Group, { gap: "xs", wrap: "nowrap", align: "center", children: [
30462
30683
  /* @__PURE__ */ jsxRuntime.jsx(Text, { fw: 600, size: "md", children: displayName }),
30463
30684
  verificationStatus && /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: verificationStatus, size: "xs" }),
30464
- onEditName && /* @__PURE__ */ jsxRuntime.jsx(ActionIcon, { variant: "subtle", size: "sm", onClick: onEditName, "aria-label": "Edit name", children: editNameIcon ?? /* @__PURE__ */ jsxRuntime.jsx(DefaultPencilIcon, {}) })
30685
+ onEditName && (editNameDisabled ? /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { label: editNameTooltip ?? "Coming soon", children: /* @__PURE__ */ jsxRuntime.jsx(
30686
+ ActionIcon,
30687
+ {
30688
+ variant: "subtle",
30689
+ size: "sm",
30690
+ "aria-label": "Edit name",
30691
+ "aria-disabled": "true",
30692
+ onClick: (event) => {
30693
+ event.preventDefault();
30694
+ event.stopPropagation();
30695
+ },
30696
+ style: { opacity: 0.5, cursor: "not-allowed" },
30697
+ children: editNameIcon ?? /* @__PURE__ */ jsxRuntime.jsx(DefaultPencilIcon, {})
30698
+ }
30699
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx(ActionIcon, { variant: "subtle", size: "sm", onClick: onEditName, "aria-label": "Edit name", children: editNameIcon ?? /* @__PURE__ */ jsxRuntime.jsx(DefaultPencilIcon, {}) }))
30465
30700
  ] }),
30466
- email && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "sm", c: `${colors.neutral}.5`, children: email }),
30467
- memberSinceText && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: `${colors.neutral}.4`, children: memberSinceText }),
30468
- subtitle && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: `${colors.neutral}.5`, children: subtitle })
30701
+ email && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "sm", c: fairmintVars.colorTextSecondary, children: email }),
30702
+ memberSinceText && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: fairmintVars.colorTextTertiary, children: memberSinceText }),
30703
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, children: subtitle })
30469
30704
  ] })
30470
30705
  ] }),
30471
30706
  children
@@ -30565,7 +30800,7 @@ function WalletList({
30565
30800
  children: [
30566
30801
  /* @__PURE__ */ jsxRuntime.jsxs(Group, { gap: "xs", children: [
30567
30802
  /* @__PURE__ */ jsxRuntime.jsx(Badge, { size: "xs", variant: "light", children: getTypeLabel(w.type, typeLabels) }),
30568
- w.label && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: `${colors.neutral}.5`, children: w.label }),
30803
+ w.label && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, children: w.label }),
30569
30804
  /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "sm", ff: "monospace", children: truncateAddress(w.address) })
30570
30805
  ] }),
30571
30806
  /* @__PURE__ */ jsxRuntime.jsxs(Group, { gap: 4, children: [
@@ -30643,7 +30878,7 @@ function WalletList({
30643
30878
  title: "Remove Wallet",
30644
30879
  message: /* @__PURE__ */ jsxRuntime.jsxs(Stack, { gap: "sm", children: [
30645
30880
  /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "sm", children: "Are you sure you want to remove this wallet address? This action cannot be undone." }),
30646
- walletToRemove && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "sm", ff: "monospace", c: `${colors.neutral}.5`, children: walletToRemove }),
30881
+ walletToRemove && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "sm", ff: "monospace", c: fairmintVars.colorTextSecondary, children: walletToRemove }),
30647
30882
  removeError && /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "sm", c: colors.error, children: removeError })
30648
30883
  ] }),
30649
30884
  opened: walletToRemove !== null,
@@ -30721,6 +30956,7 @@ exports.EmailField = EmailField;
30721
30956
  exports.EmptyState = EmptyState;
30722
30957
  exports.EquityGrantCard = EquityGrantCard;
30723
30958
  exports.ErrorFallback = ErrorFallback;
30959
+ exports.ErrorPage = ErrorPage;
30724
30960
  exports.EthereumAddressField = EthereumAddressField;
30725
30961
  exports.FairmintLogo = FairmintLogo;
30726
30962
  exports.FairmintProvider = FairmintProvider;
@@ -30779,18 +31015,24 @@ exports.ZERO_ETHEREUM_ADDRESS = ZERO_ETHEREUM_ADDRESS;
30779
31015
  exports.ZipField = ZipField;
30780
31016
  exports.brandColors = brandColors;
30781
31017
  exports.colors = colors;
31018
+ exports.createFairmintMantineProviderProps = createFairmintMantineProviderProps;
30782
31019
  exports.createZipSchema = createZipSchema;
30783
31020
  exports.emailSchema = emailSchema;
30784
31021
  exports.ethereumAddressSchema = ethereumAddressSchema;
31022
+ exports.fairmintCssVariables = fairmintCssVariables;
31023
+ exports.fairmintVars = fairmintVars;
30785
31024
  exports.formatCurrency = formatCurrency;
30786
31025
  exports.formatCurrencyPrecise = formatCurrencyPrecise;
30787
31026
  exports.formatDate = formatDate;
30788
31027
  exports.formatNumber = formatNumber;
30789
31028
  exports.formatPercent = formatPercent;
31029
+ exports.formatPhone = formatPhone;
31030
+ exports.formatPhoneDisplay = formatPhoneDisplay;
30790
31031
  exports.formatPreciseWithCurrency = formatPreciseWithCurrency;
30791
31032
  exports.getAvatarColor = getAvatarColor;
30792
31033
  exports.isEthereumAddress = isEthereumAddress;
30793
31034
  exports.neutralColors = neutralColors;
31035
+ exports.normalizePhone = normalizePhone;
30794
31036
  exports.notify = notify;
30795
31037
  exports.passwordSchema = passwordSchema;
30796
31038
  exports.phoneSchema = phoneSchema;
@@ -30798,6 +31040,7 @@ exports.radii = radii;
30798
31040
  exports.semanticColors = semanticColors;
30799
31041
  exports.theme = theme;
30800
31042
  exports.truncateAddress = truncateAddress;
31043
+ exports.typography = typography;
30801
31044
  exports.useClickOutside = useClickOutside;
30802
31045
  exports.useClipboard = useClipboard;
30803
31046
  exports.useDebouncedCallback = useDebouncedCallback;