@exyconn/common 2.0.0 → 2.1.0

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.
@@ -2,10 +2,32 @@
2
2
 
3
3
  var axios = require('axios');
4
4
  var react = require('react');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var Yup = require('yup');
7
+ var formik = require('formik');
5
8
 
6
9
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
10
 
11
+ function _interopNamespace(e) {
12
+ if (e && e.__esModule) return e;
13
+ var n = Object.create(null);
14
+ if (e) {
15
+ Object.keys(e).forEach(function (k) {
16
+ if (k !== 'default') {
17
+ var d = Object.getOwnPropertyDescriptor(e, k);
18
+ Object.defineProperty(n, k, d.get ? d : {
19
+ enumerable: true,
20
+ get: function () { return e[k]; }
21
+ });
22
+ }
23
+ });
24
+ }
25
+ n.default = e;
26
+ return Object.freeze(n);
27
+ }
28
+
8
29
  var axios__default = /*#__PURE__*/_interopDefault(axios);
30
+ var Yup__namespace = /*#__PURE__*/_interopNamespace(Yup);
9
31
 
10
32
  // src/client/http/axios-instance.ts
11
33
  var createHttpClient = (options) => {
@@ -836,11 +858,11 @@ function useDefault(initialValue, defaultValue) {
836
858
  }
837
859
  var useDefault_default = useDefault;
838
860
  function usePrevious(value, initialValue) {
839
- const ref = react.useRef(initialValue);
861
+ const ref2 = react.useRef(initialValue);
840
862
  react.useEffect(() => {
841
- ref.current = value;
863
+ ref2.current = value;
842
864
  }, [value]);
843
- return ref.current;
865
+ return ref2.current;
844
866
  }
845
867
  var usePrevious_default = usePrevious;
846
868
  function useObjectState(initialState) {
@@ -1766,7 +1788,7 @@ function useKeyPress(targetKey, callback, options = {}) {
1766
1788
  var useKeyPress_default = useKeyPress;
1767
1789
  function useHover(onHoverChange) {
1768
1790
  const [isHovered, setIsHovered] = react.useState(false);
1769
- const ref = react.useRef(null);
1791
+ const ref2 = react.useRef(null);
1770
1792
  const onMouseEnter = react.useCallback(() => {
1771
1793
  setIsHovered(true);
1772
1794
  onHoverChange?.(true);
@@ -1776,7 +1798,7 @@ function useHover(onHoverChange) {
1776
1798
  onHoverChange?.(false);
1777
1799
  }, [onHoverChange]);
1778
1800
  return {
1779
- ref,
1801
+ ref: ref2,
1780
1802
  isHovered,
1781
1803
  bind: {
1782
1804
  onMouseEnter,
@@ -1786,13 +1808,13 @@ function useHover(onHoverChange) {
1786
1808
  }
1787
1809
  var useHover_default = useHover;
1788
1810
  function useClickAway(callback, events = ["mousedown", "touchstart"]) {
1789
- const ref = react.useRef(null);
1811
+ const ref2 = react.useRef(null);
1790
1812
  const savedCallback = react.useRef(callback);
1791
1813
  react.useEffect(() => {
1792
1814
  savedCallback.current = callback;
1793
1815
  }, [callback]);
1794
1816
  const handleClickAway = react.useCallback((event) => {
1795
- const el = ref.current;
1817
+ const el = ref2.current;
1796
1818
  if (!el || el.contains(event.target)) {
1797
1819
  return;
1798
1820
  }
@@ -1809,14 +1831,14 @@ function useClickAway(callback, events = ["mousedown", "touchstart"]) {
1809
1831
  });
1810
1832
  };
1811
1833
  }, [events, handleClickAway]);
1812
- return ref;
1834
+ return ref2;
1813
1835
  }
1814
1836
  var useClickAway_default = useClickAway;
1815
- function useOnClickOutside(ref, handler, enabled = true) {
1837
+ function useOnClickOutside(ref2, handler, enabled = true) {
1816
1838
  react.useEffect(() => {
1817
1839
  if (!enabled) return;
1818
1840
  const listener = (event) => {
1819
- const el = ref?.current;
1841
+ const el = ref2?.current;
1820
1842
  if (!el || el.contains(event.target)) {
1821
1843
  return;
1822
1844
  }
@@ -1828,7 +1850,7 @@ function useOnClickOutside(ref, handler, enabled = true) {
1828
1850
  document.removeEventListener("mousedown", listener);
1829
1851
  document.removeEventListener("touchstart", listener);
1830
1852
  };
1831
- }, [ref, handler, enabled]);
1853
+ }, [ref2, handler, enabled]);
1832
1854
  }
1833
1855
  var useOnClickOutside_default = useOnClickOutside;
1834
1856
  function useLongPress(options = {}) {
@@ -1901,7 +1923,7 @@ function useLongPress(options = {}) {
1901
1923
  var useLongPress_default = useLongPress;
1902
1924
  function useMouse(options = {}) {
1903
1925
  const { enabled = true } = options;
1904
- const ref = react.useRef(null);
1926
+ const ref2 = react.useRef(null);
1905
1927
  const [position, setPosition] = react.useState({
1906
1928
  x: 0,
1907
1929
  y: 0,
@@ -1915,8 +1937,8 @@ function useMouse(options = {}) {
1915
1937
  let elementX = 0;
1916
1938
  let elementY = 0;
1917
1939
  let isInElement = false;
1918
- if (ref.current) {
1919
- const rect = ref.current.getBoundingClientRect();
1940
+ if (ref2.current) {
1941
+ const rect = ref2.current.getBoundingClientRect();
1920
1942
  elementX = event.clientX - rect.left;
1921
1943
  elementY = event.clientY - rect.top;
1922
1944
  isInElement = elementX >= 0 && elementX <= rect.width && elementY >= 0 && elementY <= rect.height;
@@ -1939,7 +1961,7 @@ function useMouse(options = {}) {
1939
1961
  };
1940
1962
  }, [enabled, handleMouseMove]);
1941
1963
  return {
1942
- ref,
1964
+ ref: ref2,
1943
1965
  ...position
1944
1966
  };
1945
1967
  }
@@ -2851,7 +2873,7 @@ function useMeasure() {
2851
2873
  y: rect.y
2852
2874
  });
2853
2875
  }, []);
2854
- const ref = react.useCallback((node) => {
2876
+ const ref2 = react.useCallback((node) => {
2855
2877
  if (observerRef.current) {
2856
2878
  observerRef.current.disconnect();
2857
2879
  observerRef.current = null;
@@ -2898,7 +2920,7 @@ function useMeasure() {
2898
2920
  }
2899
2921
  };
2900
2922
  }, []);
2901
- return { ref, dimensions, measure };
2923
+ return { ref: ref2, dimensions, measure };
2902
2924
  }
2903
2925
  var useMeasure_default = useMeasure;
2904
2926
  function useIntersectionObserver(options = {}) {
@@ -2915,7 +2937,7 @@ function useIntersectionObserver(options = {}) {
2915
2937
  const elementRef = react.useRef(null);
2916
2938
  const observerRef = react.useRef(null);
2917
2939
  const frozen = react.useRef(false);
2918
- const ref = react.useCallback(
2940
+ const ref2 = react.useCallback(
2919
2941
  (node) => {
2920
2942
  if (observerRef.current) {
2921
2943
  observerRef.current.disconnect();
@@ -2951,7 +2973,7 @@ function useIntersectionObserver(options = {}) {
2951
2973
  }
2952
2974
  };
2953
2975
  }, []);
2954
- return { ref, isIntersecting, entry };
2976
+ return { ref: ref2, isIntersecting, entry };
2955
2977
  }
2956
2978
  var useIntersectionObserver_default = useIntersectionObserver;
2957
2979
  var DEFAULT_DURATION = 4e3;
@@ -2996,16 +3018,2636 @@ function useSnackbar(defaultDuration = DEFAULT_DURATION) {
2996
3018
  }
2997
3019
  var useSnackbar_default = useSnackbar;
2998
3020
 
3021
+ // src/client/web/theme/default-light-theme.ts
3022
+ var defaultLightTheme = {
3023
+ name: "default-light",
3024
+ mode: "light",
3025
+ colors: {
3026
+ brand: {
3027
+ primary: "#3b82f6",
3028
+ secondary: "#6366f1",
3029
+ accent: "#f59e0b",
3030
+ background: "#ffffff",
3031
+ foreground: "#111827"
3032
+ },
3033
+ semantic: {
3034
+ primary: "#3b82f6",
3035
+ primaryHover: "#2563eb",
3036
+ primaryActive: "#1d4ed8",
3037
+ primaryDisabled: "#93c5fd",
3038
+ secondary: "#6366f1",
3039
+ secondaryHover: "#4f46e5",
3040
+ secondaryActive: "#4338ca",
3041
+ secondaryDisabled: "#a5b4fc",
3042
+ accent: "#f59e0b",
3043
+ accentHover: "#d97706",
3044
+ success: "#22c55e",
3045
+ successHover: "#16a34a",
3046
+ warning: "#f59e0b",
3047
+ warningHover: "#d97706",
3048
+ error: "#ef4444",
3049
+ errorHover: "#dc2626",
3050
+ info: "#3b82f6",
3051
+ infoHover: "#2563eb"
3052
+ },
3053
+ background: {
3054
+ default: "#ffffff",
3055
+ paper: "#f9fafb",
3056
+ card: "#ffffff",
3057
+ overlay: "rgba(0, 0, 0, 0.5)",
3058
+ input: "#ffffff",
3059
+ disabled: "#f3f4f6",
3060
+ hover: "#f3f4f6",
3061
+ selected: "#eff6ff"
3062
+ },
3063
+ surface: {
3064
+ light: "#f9fafb",
3065
+ main: "#f3f4f6",
3066
+ dark: "#e5e7eb"
3067
+ },
3068
+ text: {
3069
+ primary: "#111827",
3070
+ secondary: "#6b7280",
3071
+ disabled: "#9ca3af",
3072
+ placeholder: "#9ca3af",
3073
+ link: "#3b82f6",
3074
+ linkHover: "#2563eb",
3075
+ inverse: "#ffffff",
3076
+ onPrimary: "#ffffff",
3077
+ onSecondary: "#ffffff"
3078
+ },
3079
+ border: {
3080
+ default: "#e5e7eb",
3081
+ light: "#f3f4f6",
3082
+ dark: "#d1d5db",
3083
+ focus: "#3b82f6",
3084
+ error: "#ef4444",
3085
+ success: "#22c55e",
3086
+ disabled: "#e5e7eb"
3087
+ }
3088
+ },
3089
+ shadows: {
3090
+ none: "none",
3091
+ xs: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
3092
+ sm: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
3093
+ md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
3094
+ lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
3095
+ xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)",
3096
+ "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)",
3097
+ inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)",
3098
+ button: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
3099
+ buttonHover: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
3100
+ card: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
3101
+ cardHover: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
3102
+ modal: "0 25px 50px -12px rgb(0 0 0 / 0.25)",
3103
+ dropdown: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)"
3104
+ },
3105
+ typography: {
3106
+ fontFamily: {
3107
+ sans: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
3108
+ serif: 'ui-serif, Georgia, Cambria, "Times New Roman", Times, serif',
3109
+ mono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace',
3110
+ heading: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
3111
+ body: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
3112
+ },
3113
+ fontSize: {
3114
+ xs: "0.75rem",
3115
+ sm: "0.875rem",
3116
+ base: "1rem",
3117
+ lg: "1.125rem",
3118
+ xl: "1.25rem",
3119
+ "2xl": "1.5rem",
3120
+ "3xl": "1.875rem",
3121
+ "4xl": "2.25rem",
3122
+ "5xl": "3rem",
3123
+ "6xl": "3.75rem"
3124
+ },
3125
+ fontWeight: {
3126
+ light: 300,
3127
+ normal: 400,
3128
+ medium: 500,
3129
+ semibold: 600,
3130
+ bold: 700,
3131
+ extrabold: 800
3132
+ },
3133
+ lineHeight: {
3134
+ none: 1,
3135
+ tight: 1.25,
3136
+ snug: 1.375,
3137
+ normal: 1.5,
3138
+ relaxed: 1.625,
3139
+ loose: 2
3140
+ }
3141
+ },
3142
+ spacing: {
3143
+ 0: "0",
3144
+ px: "1px",
3145
+ 0.5: "0.125rem",
3146
+ 1: "0.25rem",
3147
+ 1.5: "0.375rem",
3148
+ 2: "0.5rem",
3149
+ 2.5: "0.625rem",
3150
+ 3: "0.75rem",
3151
+ 3.5: "0.875rem",
3152
+ 4: "1rem",
3153
+ 5: "1.25rem",
3154
+ 6: "1.5rem",
3155
+ 7: "1.75rem",
3156
+ 8: "2rem",
3157
+ 9: "2.25rem",
3158
+ 10: "2.5rem",
3159
+ 11: "2.75rem",
3160
+ 12: "3rem",
3161
+ 14: "3.5rem",
3162
+ 16: "4rem",
3163
+ 20: "5rem",
3164
+ 24: "6rem",
3165
+ 28: "7rem",
3166
+ 32: "8rem",
3167
+ 36: "9rem",
3168
+ 40: "10rem",
3169
+ 44: "11rem",
3170
+ 48: "12rem",
3171
+ 52: "13rem",
3172
+ 56: "14rem",
3173
+ 60: "15rem",
3174
+ 64: "16rem",
3175
+ 72: "18rem",
3176
+ 80: "20rem",
3177
+ 96: "24rem"
3178
+ },
3179
+ borderRadius: {
3180
+ none: "0",
3181
+ sm: "0.125rem",
3182
+ default: "0.25rem",
3183
+ md: "0.375rem",
3184
+ lg: "0.5rem",
3185
+ xl: "0.75rem",
3186
+ "2xl": "1rem",
3187
+ "3xl": "1.5rem",
3188
+ full: "9999px"
3189
+ },
3190
+ breakpoints: {
3191
+ xs: "475px",
3192
+ sm: "640px",
3193
+ md: "768px",
3194
+ lg: "1024px",
3195
+ xl: "1280px",
3196
+ "2xl": "1536px"
3197
+ },
3198
+ zIndex: {
3199
+ hide: -1,
3200
+ auto: "auto",
3201
+ base: 0,
3202
+ dropdown: 1e3,
3203
+ sticky: 1020,
3204
+ fixed: 1030,
3205
+ modalBackdrop: 1040,
3206
+ modal: 1050,
3207
+ popover: 1060,
3208
+ tooltip: 1070,
3209
+ toast: 1080
3210
+ },
3211
+ transitions: {
3212
+ none: "none",
3213
+ fast: "150ms ease-in-out",
3214
+ normal: "200ms ease-in-out",
3215
+ slow: "300ms ease-in-out",
3216
+ slower: "500ms ease-in-out",
3217
+ colors: "color 200ms ease-in-out, background-color 200ms ease-in-out, border-color 200ms ease-in-out",
3218
+ transform: "transform 200ms ease-in-out",
3219
+ opacity: "opacity 200ms ease-in-out",
3220
+ shadow: "box-shadow 200ms ease-in-out",
3221
+ all: "all 200ms ease-in-out"
3222
+ },
3223
+ components: {
3224
+ button: {
3225
+ bg: "#3b82f6",
3226
+ bgHover: "#2563eb",
3227
+ bgActive: "#1d4ed8",
3228
+ bgDisabled: "#93c5fd",
3229
+ color: "#ffffff",
3230
+ colorHover: "#ffffff",
3231
+ colorDisabled: "#ffffff",
3232
+ border: "transparent",
3233
+ borderHover: "transparent",
3234
+ borderWidth: "1px",
3235
+ borderRadius: "0.375rem",
3236
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
3237
+ shadowHover: "0 4px 6px -1px rgb(0 0 0 / 0.1)",
3238
+ paddingX: "1rem",
3239
+ paddingY: "0.5rem",
3240
+ fontSize: "0.875rem",
3241
+ fontWeight: 500,
3242
+ variants: {
3243
+ primary: {
3244
+ bg: "#3b82f6",
3245
+ bgHover: "#2563eb",
3246
+ color: "#ffffff"
3247
+ },
3248
+ secondary: {
3249
+ bg: "#6366f1",
3250
+ bgHover: "#4f46e5",
3251
+ color: "#ffffff"
3252
+ },
3253
+ outline: {
3254
+ bg: "transparent",
3255
+ bgHover: "#f3f4f6",
3256
+ color: "#374151",
3257
+ border: "#d1d5db",
3258
+ borderHover: "#9ca3af"
3259
+ },
3260
+ ghost: {
3261
+ bg: "transparent",
3262
+ bgHover: "#f3f4f6",
3263
+ color: "#374151",
3264
+ shadow: "none",
3265
+ shadowHover: "none"
3266
+ },
3267
+ link: {
3268
+ bg: "transparent",
3269
+ bgHover: "transparent",
3270
+ color: "#3b82f6",
3271
+ colorHover: "#2563eb",
3272
+ shadow: "none",
3273
+ shadowHover: "none",
3274
+ paddingX: "0",
3275
+ paddingY: "0"
3276
+ },
3277
+ danger: {
3278
+ bg: "#ef4444",
3279
+ bgHover: "#dc2626",
3280
+ color: "#ffffff"
3281
+ },
3282
+ success: {
3283
+ bg: "#22c55e",
3284
+ bgHover: "#16a34a",
3285
+ color: "#ffffff"
3286
+ }
3287
+ },
3288
+ sizes: {
3289
+ xs: {
3290
+ paddingX: "0.5rem",
3291
+ paddingY: "0.25rem",
3292
+ fontSize: "0.75rem"
3293
+ },
3294
+ sm: {
3295
+ paddingX: "0.75rem",
3296
+ paddingY: "0.375rem",
3297
+ fontSize: "0.875rem"
3298
+ },
3299
+ md: {
3300
+ paddingX: "1rem",
3301
+ paddingY: "0.5rem",
3302
+ fontSize: "0.875rem"
3303
+ },
3304
+ lg: {
3305
+ paddingX: "1.25rem",
3306
+ paddingY: "0.625rem",
3307
+ fontSize: "1rem"
3308
+ },
3309
+ xl: {
3310
+ paddingX: "1.5rem",
3311
+ paddingY: "0.75rem",
3312
+ fontSize: "1.125rem"
3313
+ }
3314
+ }
3315
+ },
3316
+ input: {
3317
+ bg: "#ffffff",
3318
+ bgFocus: "#ffffff",
3319
+ bgDisabled: "#f3f4f6",
3320
+ bgError: "#fef2f2",
3321
+ color: "#111827",
3322
+ colorPlaceholder: "#9ca3af",
3323
+ colorDisabled: "#9ca3af",
3324
+ border: "#d1d5db",
3325
+ borderFocus: "#3b82f6",
3326
+ borderError: "#ef4444",
3327
+ borderWidth: "1px",
3328
+ borderRadius: "0.375rem",
3329
+ shadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
3330
+ shadowFocus: "0 0 0 3px rgb(59 130 246 / 0.1)",
3331
+ paddingX: "0.75rem",
3332
+ paddingY: "0.5rem",
3333
+ fontSize: "0.875rem",
3334
+ labelColor: "#374151",
3335
+ labelFontSize: "0.875rem",
3336
+ labelFontWeight: 500,
3337
+ helperColor: "#6b7280",
3338
+ errorColor: "#ef4444",
3339
+ sizes: {
3340
+ sm: {
3341
+ paddingX: "0.5rem",
3342
+ paddingY: "0.375rem",
3343
+ fontSize: "0.75rem"
3344
+ },
3345
+ md: {
3346
+ paddingX: "0.75rem",
3347
+ paddingY: "0.5rem",
3348
+ fontSize: "0.875rem"
3349
+ },
3350
+ lg: {
3351
+ paddingX: "1rem",
3352
+ paddingY: "0.625rem",
3353
+ fontSize: "1rem"
3354
+ }
3355
+ }
3356
+ },
3357
+ card: {
3358
+ bg: "#ffffff",
3359
+ bgHover: "#ffffff",
3360
+ border: "#e5e7eb",
3361
+ borderWidth: "1px",
3362
+ borderRadius: "0.5rem",
3363
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
3364
+ shadowHover: "0 10px 15px -3px rgb(0 0 0 / 0.1)",
3365
+ padding: "1.5rem",
3366
+ headerBg: "#f9fafb",
3367
+ headerBorder: "#e5e7eb",
3368
+ headerPadding: "1rem 1.5rem",
3369
+ footerBg: "#f9fafb",
3370
+ footerBorder: "#e5e7eb",
3371
+ footerPadding: "1rem 1.5rem"
3372
+ },
3373
+ header: {
3374
+ bg: "#ffffff",
3375
+ bgScrolled: "rgba(255, 255, 255, 0.95)",
3376
+ color: "#111827",
3377
+ border: "#e5e7eb",
3378
+ shadow: "none",
3379
+ shadowScrolled: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
3380
+ height: "4rem",
3381
+ paddingX: "1.5rem",
3382
+ logoHeight: "2rem",
3383
+ navColor: "#374151",
3384
+ navColorHover: "#111827",
3385
+ navColorActive: "#3b82f6",
3386
+ navFontSize: "0.875rem",
3387
+ navFontWeight: 500,
3388
+ mobileMenuBg: "#ffffff",
3389
+ mobileMenuShadow: "0 10px 15px -3px rgb(0 0 0 / 0.1)"
3390
+ },
3391
+ footer: {
3392
+ bg: "#111827",
3393
+ color: "#d1d5db",
3394
+ colorMuted: "#9ca3af",
3395
+ border: "#374151",
3396
+ padding: "4rem 1.5rem",
3397
+ linkColor: "#d1d5db",
3398
+ linkColorHover: "#ffffff",
3399
+ headingColor: "#ffffff",
3400
+ headingFontSize: "1rem",
3401
+ headingFontWeight: 600,
3402
+ copyrightBg: "#0f172a",
3403
+ copyrightColor: "#9ca3af"
3404
+ },
3405
+ banner: {
3406
+ bg: "#eff6ff",
3407
+ color: "#1e40af",
3408
+ border: "#bfdbfe",
3409
+ borderRadius: "0.5rem",
3410
+ padding: "1rem 1.5rem",
3411
+ shadow: "none",
3412
+ closeBg: "transparent",
3413
+ closeColor: "#1e40af",
3414
+ variants: {
3415
+ info: {
3416
+ bg: "#eff6ff",
3417
+ color: "#1e40af",
3418
+ border: "#bfdbfe"
3419
+ },
3420
+ success: {
3421
+ bg: "#f0fdf4",
3422
+ color: "#166534",
3423
+ border: "#bbf7d0"
3424
+ },
3425
+ warning: {
3426
+ bg: "#fffbeb",
3427
+ color: "#92400e",
3428
+ border: "#fde68a"
3429
+ },
3430
+ error: {
3431
+ bg: "#fef2f2",
3432
+ color: "#991b1b",
3433
+ border: "#fecaca"
3434
+ },
3435
+ promo: {
3436
+ bg: "#faf5ff",
3437
+ color: "#6b21a8",
3438
+ border: "#e9d5ff"
3439
+ }
3440
+ }
3441
+ },
3442
+ loader: {
3443
+ color: "#3b82f6",
3444
+ colorSecondary: "#e5e7eb",
3445
+ size: "2.5rem",
3446
+ borderWidth: "3px",
3447
+ overlayBg: "rgba(255, 255, 255, 0.8)",
3448
+ overlayOpacity: 1,
3449
+ sizes: {
3450
+ xs: "1rem",
3451
+ sm: "1.5rem",
3452
+ md: "2.5rem",
3453
+ lg: "3.5rem",
3454
+ xl: "5rem"
3455
+ }
3456
+ },
3457
+ modal: {
3458
+ bg: "#ffffff",
3459
+ color: "#111827",
3460
+ border: "#e5e7eb",
3461
+ borderRadius: "0.5rem",
3462
+ shadow: "0 25px 50px -12px rgb(0 0 0 / 0.25)",
3463
+ padding: "1.5rem",
3464
+ overlayBg: "rgba(0, 0, 0, 0.5)",
3465
+ overlayOpacity: 1,
3466
+ headerBg: "#ffffff",
3467
+ headerBorder: "#e5e7eb",
3468
+ headerPadding: "1rem 1.5rem",
3469
+ footerBg: "#f9fafb",
3470
+ footerBorder: "#e5e7eb",
3471
+ footerPadding: "1rem 1.5rem",
3472
+ closeBg: "transparent",
3473
+ closeColor: "#6b7280",
3474
+ closeHoverBg: "#f3f4f6",
3475
+ sizes: {
3476
+ sm: "24rem",
3477
+ md: "32rem",
3478
+ lg: "48rem",
3479
+ xl: "64rem",
3480
+ full: "100%"
3481
+ }
3482
+ },
3483
+ toast: {
3484
+ bg: "#ffffff",
3485
+ color: "#111827",
3486
+ border: "#e5e7eb",
3487
+ borderRadius: "0.5rem",
3488
+ shadow: "0 10px 15px -3px rgb(0 0 0 / 0.1)",
3489
+ padding: "1rem",
3490
+ variants: {
3491
+ success: {
3492
+ bg: "#f0fdf4",
3493
+ color: "#166534",
3494
+ border: "#bbf7d0"
3495
+ },
3496
+ error: {
3497
+ bg: "#fef2f2",
3498
+ color: "#991b1b",
3499
+ border: "#fecaca"
3500
+ },
3501
+ warning: {
3502
+ bg: "#fffbeb",
3503
+ color: "#92400e",
3504
+ border: "#fde68a"
3505
+ },
3506
+ info: {
3507
+ bg: "#eff6ff",
3508
+ color: "#1e40af",
3509
+ border: "#bfdbfe"
3510
+ }
3511
+ }
3512
+ },
3513
+ newsletter: {
3514
+ bg: "#f9fafb",
3515
+ color: "#111827",
3516
+ border: "#e5e7eb",
3517
+ borderRadius: "0.5rem",
3518
+ padding: "2rem",
3519
+ titleColor: "#111827",
3520
+ titleFontSize: "1.5rem",
3521
+ descColor: "#6b7280",
3522
+ descFontSize: "1rem",
3523
+ inputBg: "#ffffff",
3524
+ inputBorder: "#d1d5db",
3525
+ buttonBg: "#3b82f6",
3526
+ buttonColor: "#ffffff"
3527
+ }
3528
+ }
3529
+ };
3530
+
3531
+ // src/client/web/theme/default-dark-theme.ts
3532
+ var defaultDarkTheme = {
3533
+ name: "default-dark",
3534
+ mode: "dark",
3535
+ colors: {
3536
+ brand: {
3537
+ primary: "#60a5fa",
3538
+ secondary: "#818cf8",
3539
+ accent: "#fbbf24",
3540
+ background: "#0f172a",
3541
+ foreground: "#f8fafc"
3542
+ },
3543
+ semantic: {
3544
+ primary: "#60a5fa",
3545
+ primaryHover: "#3b82f6",
3546
+ primaryActive: "#2563eb",
3547
+ primaryDisabled: "#1e3a5f",
3548
+ secondary: "#818cf8",
3549
+ secondaryHover: "#6366f1",
3550
+ secondaryActive: "#4f46e5",
3551
+ secondaryDisabled: "#312e81",
3552
+ accent: "#fbbf24",
3553
+ accentHover: "#f59e0b",
3554
+ success: "#4ade80",
3555
+ successHover: "#22c55e",
3556
+ warning: "#fbbf24",
3557
+ warningHover: "#f59e0b",
3558
+ error: "#f87171",
3559
+ errorHover: "#ef4444",
3560
+ info: "#60a5fa",
3561
+ infoHover: "#3b82f6"
3562
+ },
3563
+ background: {
3564
+ default: "#0f172a",
3565
+ paper: "#1e293b",
3566
+ card: "#1e293b",
3567
+ overlay: "rgba(0, 0, 0, 0.7)",
3568
+ input: "#1e293b",
3569
+ disabled: "#334155",
3570
+ hover: "#334155",
3571
+ selected: "#1e3a5f"
3572
+ },
3573
+ surface: {
3574
+ light: "#334155",
3575
+ main: "#1e293b",
3576
+ dark: "#0f172a"
3577
+ },
3578
+ text: {
3579
+ primary: "#f8fafc",
3580
+ secondary: "#94a3b8",
3581
+ disabled: "#64748b",
3582
+ placeholder: "#64748b",
3583
+ link: "#60a5fa",
3584
+ linkHover: "#3b82f6",
3585
+ inverse: "#0f172a",
3586
+ onPrimary: "#0f172a",
3587
+ onSecondary: "#0f172a"
3588
+ },
3589
+ border: {
3590
+ default: "#334155",
3591
+ light: "#475569",
3592
+ dark: "#1e293b",
3593
+ focus: "#60a5fa",
3594
+ error: "#f87171",
3595
+ success: "#4ade80",
3596
+ disabled: "#334155"
3597
+ }
3598
+ },
3599
+ shadows: {
3600
+ none: "none",
3601
+ xs: "0 1px 2px 0 rgb(0 0 0 / 0.3)",
3602
+ sm: "0 1px 3px 0 rgb(0 0 0 / 0.4), 0 1px 2px -1px rgb(0 0 0 / 0.4)",
3603
+ md: "0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.4)",
3604
+ lg: "0 10px 15px -3px rgb(0 0 0 / 0.4), 0 4px 6px -4px rgb(0 0 0 / 0.4)",
3605
+ xl: "0 20px 25px -5px rgb(0 0 0 / 0.4), 0 8px 10px -6px rgb(0 0 0 / 0.4)",
3606
+ "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.6)",
3607
+ inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.3)",
3608
+ button: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
3609
+ buttonHover: "0 4px 6px -1px rgb(0 0 0 / 0.4)",
3610
+ card: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
3611
+ cardHover: "0 10px 15px -3px rgb(0 0 0 / 0.4)",
3612
+ modal: "0 25px 50px -12px rgb(0 0 0 / 0.6)",
3613
+ dropdown: "0 10px 15px -3px rgb(0 0 0 / 0.4)"
3614
+ },
3615
+ typography: {
3616
+ fontFamily: {
3617
+ sans: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
3618
+ serif: 'ui-serif, Georgia, Cambria, "Times New Roman", Times, serif',
3619
+ mono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace',
3620
+ heading: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
3621
+ body: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
3622
+ },
3623
+ fontSize: {
3624
+ xs: "0.75rem",
3625
+ sm: "0.875rem",
3626
+ base: "1rem",
3627
+ lg: "1.125rem",
3628
+ xl: "1.25rem",
3629
+ "2xl": "1.5rem",
3630
+ "3xl": "1.875rem",
3631
+ "4xl": "2.25rem",
3632
+ "5xl": "3rem",
3633
+ "6xl": "3.75rem"
3634
+ },
3635
+ fontWeight: {
3636
+ light: 300,
3637
+ normal: 400,
3638
+ medium: 500,
3639
+ semibold: 600,
3640
+ bold: 700,
3641
+ extrabold: 800
3642
+ },
3643
+ lineHeight: {
3644
+ none: 1,
3645
+ tight: 1.25,
3646
+ snug: 1.375,
3647
+ normal: 1.5,
3648
+ relaxed: 1.625,
3649
+ loose: 2
3650
+ }
3651
+ },
3652
+ spacing: {
3653
+ 0: "0",
3654
+ px: "1px",
3655
+ 0.5: "0.125rem",
3656
+ 1: "0.25rem",
3657
+ 1.5: "0.375rem",
3658
+ 2: "0.5rem",
3659
+ 2.5: "0.625rem",
3660
+ 3: "0.75rem",
3661
+ 3.5: "0.875rem",
3662
+ 4: "1rem",
3663
+ 5: "1.25rem",
3664
+ 6: "1.5rem",
3665
+ 7: "1.75rem",
3666
+ 8: "2rem",
3667
+ 9: "2.25rem",
3668
+ 10: "2.5rem",
3669
+ 11: "2.75rem",
3670
+ 12: "3rem",
3671
+ 14: "3.5rem",
3672
+ 16: "4rem",
3673
+ 20: "5rem",
3674
+ 24: "6rem",
3675
+ 28: "7rem",
3676
+ 32: "8rem",
3677
+ 36: "9rem",
3678
+ 40: "10rem",
3679
+ 44: "11rem",
3680
+ 48: "12rem",
3681
+ 52: "13rem",
3682
+ 56: "14rem",
3683
+ 60: "15rem",
3684
+ 64: "16rem",
3685
+ 72: "18rem",
3686
+ 80: "20rem",
3687
+ 96: "24rem"
3688
+ },
3689
+ borderRadius: {
3690
+ none: "0",
3691
+ sm: "0.125rem",
3692
+ default: "0.25rem",
3693
+ md: "0.375rem",
3694
+ lg: "0.5rem",
3695
+ xl: "0.75rem",
3696
+ "2xl": "1rem",
3697
+ "3xl": "1.5rem",
3698
+ full: "9999px"
3699
+ },
3700
+ breakpoints: {
3701
+ xs: "475px",
3702
+ sm: "640px",
3703
+ md: "768px",
3704
+ lg: "1024px",
3705
+ xl: "1280px",
3706
+ "2xl": "1536px"
3707
+ },
3708
+ zIndex: {
3709
+ hide: -1,
3710
+ auto: "auto",
3711
+ base: 0,
3712
+ dropdown: 1e3,
3713
+ sticky: 1020,
3714
+ fixed: 1030,
3715
+ modalBackdrop: 1040,
3716
+ modal: 1050,
3717
+ popover: 1060,
3718
+ tooltip: 1070,
3719
+ toast: 1080
3720
+ },
3721
+ transitions: {
3722
+ none: "none",
3723
+ fast: "150ms ease-in-out",
3724
+ normal: "200ms ease-in-out",
3725
+ slow: "300ms ease-in-out",
3726
+ slower: "500ms ease-in-out",
3727
+ colors: "color 200ms ease-in-out, background-color 200ms ease-in-out, border-color 200ms ease-in-out",
3728
+ transform: "transform 200ms ease-in-out",
3729
+ opacity: "opacity 200ms ease-in-out",
3730
+ shadow: "box-shadow 200ms ease-in-out",
3731
+ all: "all 200ms ease-in-out"
3732
+ },
3733
+ components: {
3734
+ button: {
3735
+ bg: "#60a5fa",
3736
+ bgHover: "#3b82f6",
3737
+ bgActive: "#2563eb",
3738
+ bgDisabled: "#1e3a5f",
3739
+ color: "#0f172a",
3740
+ colorHover: "#0f172a",
3741
+ colorDisabled: "#64748b",
3742
+ border: "transparent",
3743
+ borderHover: "transparent",
3744
+ borderWidth: "1px",
3745
+ borderRadius: "0.375rem",
3746
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
3747
+ shadowHover: "0 4px 6px -1px rgb(0 0 0 / 0.4)",
3748
+ paddingX: "1rem",
3749
+ paddingY: "0.5rem",
3750
+ fontSize: "0.875rem",
3751
+ fontWeight: 500,
3752
+ variants: {
3753
+ primary: {
3754
+ bg: "#60a5fa",
3755
+ bgHover: "#3b82f6",
3756
+ color: "#0f172a"
3757
+ },
3758
+ secondary: {
3759
+ bg: "#818cf8",
3760
+ bgHover: "#6366f1",
3761
+ color: "#0f172a"
3762
+ },
3763
+ outline: {
3764
+ bg: "transparent",
3765
+ bgHover: "#334155",
3766
+ color: "#f8fafc",
3767
+ border: "#475569",
3768
+ borderHover: "#64748b"
3769
+ },
3770
+ ghost: {
3771
+ bg: "transparent",
3772
+ bgHover: "#334155",
3773
+ color: "#f8fafc",
3774
+ shadow: "none",
3775
+ shadowHover: "none"
3776
+ },
3777
+ link: {
3778
+ bg: "transparent",
3779
+ bgHover: "transparent",
3780
+ color: "#60a5fa",
3781
+ colorHover: "#3b82f6",
3782
+ shadow: "none",
3783
+ shadowHover: "none",
3784
+ paddingX: "0",
3785
+ paddingY: "0"
3786
+ },
3787
+ danger: {
3788
+ bg: "#f87171",
3789
+ bgHover: "#ef4444",
3790
+ color: "#0f172a"
3791
+ },
3792
+ success: {
3793
+ bg: "#4ade80",
3794
+ bgHover: "#22c55e",
3795
+ color: "#0f172a"
3796
+ }
3797
+ },
3798
+ sizes: {
3799
+ xs: {
3800
+ paddingX: "0.5rem",
3801
+ paddingY: "0.25rem",
3802
+ fontSize: "0.75rem"
3803
+ },
3804
+ sm: {
3805
+ paddingX: "0.75rem",
3806
+ paddingY: "0.375rem",
3807
+ fontSize: "0.875rem"
3808
+ },
3809
+ md: {
3810
+ paddingX: "1rem",
3811
+ paddingY: "0.5rem",
3812
+ fontSize: "0.875rem"
3813
+ },
3814
+ lg: {
3815
+ paddingX: "1.25rem",
3816
+ paddingY: "0.625rem",
3817
+ fontSize: "1rem"
3818
+ },
3819
+ xl: {
3820
+ paddingX: "1.5rem",
3821
+ paddingY: "0.75rem",
3822
+ fontSize: "1.125rem"
3823
+ }
3824
+ }
3825
+ },
3826
+ input: {
3827
+ bg: "#1e293b",
3828
+ bgFocus: "#1e293b",
3829
+ bgDisabled: "#334155",
3830
+ bgError: "#450a0a",
3831
+ color: "#f8fafc",
3832
+ colorPlaceholder: "#64748b",
3833
+ colorDisabled: "#64748b",
3834
+ border: "#475569",
3835
+ borderFocus: "#60a5fa",
3836
+ borderError: "#f87171",
3837
+ borderWidth: "1px",
3838
+ borderRadius: "0.375rem",
3839
+ shadow: "0 1px 2px 0 rgb(0 0 0 / 0.3)",
3840
+ shadowFocus: "0 0 0 3px rgb(96 165 250 / 0.2)",
3841
+ paddingX: "0.75rem",
3842
+ paddingY: "0.5rem",
3843
+ fontSize: "0.875rem",
3844
+ labelColor: "#e2e8f0",
3845
+ labelFontSize: "0.875rem",
3846
+ labelFontWeight: 500,
3847
+ helperColor: "#94a3b8",
3848
+ errorColor: "#f87171",
3849
+ sizes: {
3850
+ sm: {
3851
+ paddingX: "0.5rem",
3852
+ paddingY: "0.375rem",
3853
+ fontSize: "0.75rem"
3854
+ },
3855
+ md: {
3856
+ paddingX: "0.75rem",
3857
+ paddingY: "0.5rem",
3858
+ fontSize: "0.875rem"
3859
+ },
3860
+ lg: {
3861
+ paddingX: "1rem",
3862
+ paddingY: "0.625rem",
3863
+ fontSize: "1rem"
3864
+ }
3865
+ }
3866
+ },
3867
+ card: {
3868
+ bg: "#1e293b",
3869
+ bgHover: "#1e293b",
3870
+ border: "#334155",
3871
+ borderWidth: "1px",
3872
+ borderRadius: "0.5rem",
3873
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
3874
+ shadowHover: "0 10px 15px -3px rgb(0 0 0 / 0.4)",
3875
+ padding: "1.5rem",
3876
+ headerBg: "#0f172a",
3877
+ headerBorder: "#334155",
3878
+ headerPadding: "1rem 1.5rem",
3879
+ footerBg: "#0f172a",
3880
+ footerBorder: "#334155",
3881
+ footerPadding: "1rem 1.5rem"
3882
+ },
3883
+ header: {
3884
+ bg: "#0f172a",
3885
+ bgScrolled: "rgba(15, 23, 42, 0.95)",
3886
+ color: "#f8fafc",
3887
+ border: "#334155",
3888
+ shadow: "none",
3889
+ shadowScrolled: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
3890
+ height: "4rem",
3891
+ paddingX: "1.5rem",
3892
+ logoHeight: "2rem",
3893
+ navColor: "#94a3b8",
3894
+ navColorHover: "#f8fafc",
3895
+ navColorActive: "#60a5fa",
3896
+ navFontSize: "0.875rem",
3897
+ navFontWeight: 500,
3898
+ mobileMenuBg: "#1e293b",
3899
+ mobileMenuShadow: "0 10px 15px -3px rgb(0 0 0 / 0.4)"
3900
+ },
3901
+ footer: {
3902
+ bg: "#020617",
3903
+ color: "#94a3b8",
3904
+ colorMuted: "#64748b",
3905
+ border: "#1e293b",
3906
+ padding: "4rem 1.5rem",
3907
+ linkColor: "#94a3b8",
3908
+ linkColorHover: "#f8fafc",
3909
+ headingColor: "#f8fafc",
3910
+ headingFontSize: "1rem",
3911
+ headingFontWeight: 600,
3912
+ copyrightBg: "#0f172a",
3913
+ copyrightColor: "#64748b"
3914
+ },
3915
+ banner: {
3916
+ bg: "#1e3a5f",
3917
+ color: "#bfdbfe",
3918
+ border: "#3b82f6",
3919
+ borderRadius: "0.5rem",
3920
+ padding: "1rem 1.5rem",
3921
+ shadow: "none",
3922
+ closeBg: "transparent",
3923
+ closeColor: "#bfdbfe",
3924
+ variants: {
3925
+ info: {
3926
+ bg: "#1e3a5f",
3927
+ color: "#bfdbfe",
3928
+ border: "#3b82f6"
3929
+ },
3930
+ success: {
3931
+ bg: "#14532d",
3932
+ color: "#bbf7d0",
3933
+ border: "#22c55e"
3934
+ },
3935
+ warning: {
3936
+ bg: "#78350f",
3937
+ color: "#fde68a",
3938
+ border: "#f59e0b"
3939
+ },
3940
+ error: {
3941
+ bg: "#7f1d1d",
3942
+ color: "#fecaca",
3943
+ border: "#ef4444"
3944
+ },
3945
+ promo: {
3946
+ bg: "#581c87",
3947
+ color: "#e9d5ff",
3948
+ border: "#a855f7"
3949
+ }
3950
+ }
3951
+ },
3952
+ loader: {
3953
+ color: "#60a5fa",
3954
+ colorSecondary: "#334155",
3955
+ size: "2.5rem",
3956
+ borderWidth: "3px",
3957
+ overlayBg: "rgba(15, 23, 42, 0.8)",
3958
+ overlayOpacity: 1,
3959
+ sizes: {
3960
+ xs: "1rem",
3961
+ sm: "1.5rem",
3962
+ md: "2.5rem",
3963
+ lg: "3.5rem",
3964
+ xl: "5rem"
3965
+ }
3966
+ },
3967
+ modal: {
3968
+ bg: "#1e293b",
3969
+ color: "#f8fafc",
3970
+ border: "#334155",
3971
+ borderRadius: "0.5rem",
3972
+ shadow: "0 25px 50px -12px rgb(0 0 0 / 0.6)",
3973
+ padding: "1.5rem",
3974
+ overlayBg: "rgba(0, 0, 0, 0.7)",
3975
+ overlayOpacity: 1,
3976
+ headerBg: "#1e293b",
3977
+ headerBorder: "#334155",
3978
+ headerPadding: "1rem 1.5rem",
3979
+ footerBg: "#0f172a",
3980
+ footerBorder: "#334155",
3981
+ footerPadding: "1rem 1.5rem",
3982
+ closeBg: "transparent",
3983
+ closeColor: "#94a3b8",
3984
+ closeHoverBg: "#334155",
3985
+ sizes: {
3986
+ sm: "24rem",
3987
+ md: "32rem",
3988
+ lg: "48rem",
3989
+ xl: "64rem",
3990
+ full: "100%"
3991
+ }
3992
+ },
3993
+ toast: {
3994
+ bg: "#1e293b",
3995
+ color: "#f8fafc",
3996
+ border: "#334155",
3997
+ borderRadius: "0.5rem",
3998
+ shadow: "0 10px 15px -3px rgb(0 0 0 / 0.4)",
3999
+ padding: "1rem",
4000
+ variants: {
4001
+ success: {
4002
+ bg: "#14532d",
4003
+ color: "#bbf7d0",
4004
+ border: "#22c55e"
4005
+ },
4006
+ error: {
4007
+ bg: "#7f1d1d",
4008
+ color: "#fecaca",
4009
+ border: "#ef4444"
4010
+ },
4011
+ warning: {
4012
+ bg: "#78350f",
4013
+ color: "#fde68a",
4014
+ border: "#f59e0b"
4015
+ },
4016
+ info: {
4017
+ bg: "#1e3a5f",
4018
+ color: "#bfdbfe",
4019
+ border: "#3b82f6"
4020
+ }
4021
+ }
4022
+ },
4023
+ newsletter: {
4024
+ bg: "#1e293b",
4025
+ color: "#f8fafc",
4026
+ border: "#334155",
4027
+ borderRadius: "0.5rem",
4028
+ padding: "2rem",
4029
+ titleColor: "#f8fafc",
4030
+ titleFontSize: "1.5rem",
4031
+ descColor: "#94a3b8",
4032
+ descFontSize: "1rem",
4033
+ inputBg: "#0f172a",
4034
+ inputBorder: "#475569",
4035
+ buttonBg: "#60a5fa",
4036
+ buttonColor: "#0f172a"
4037
+ }
4038
+ }
4039
+ };
4040
+
4041
+ // src/client/web/theme/theme-utils.ts
4042
+ function deepMerge(target, source) {
4043
+ const output = { ...target };
4044
+ for (const key in source) {
4045
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
4046
+ const sourceValue = source[key];
4047
+ const targetValue = target[key];
4048
+ if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue && typeof targetValue === "object" && !Array.isArray(targetValue)) {
4049
+ output[key] = deepMerge(
4050
+ targetValue,
4051
+ sourceValue
4052
+ );
4053
+ } else if (sourceValue !== void 0) {
4054
+ output[key] = sourceValue;
4055
+ }
4056
+ }
4057
+ }
4058
+ return output;
4059
+ }
4060
+ function createThemeFromBrand(brand, baseTheme = defaultLightTheme) {
4061
+ const { colors } = brand;
4062
+ const brandOverrides = {
4063
+ brand,
4064
+ colors: {
4065
+ brand: {
4066
+ primary: colors.primary,
4067
+ secondary: colors.secondary,
4068
+ accent: colors.accent || colors.primary,
4069
+ background: colors.background || baseTheme.colors.background.default,
4070
+ foreground: colors.foreground || baseTheme.colors.text.primary
4071
+ },
4072
+ semantic: {
4073
+ primary: colors.primary,
4074
+ primaryHover: adjustColor(colors.primary, -10),
4075
+ primaryActive: adjustColor(colors.primary, -20),
4076
+ primaryDisabled: adjustColor(colors.primary, 40),
4077
+ secondary: colors.secondary,
4078
+ secondaryHover: adjustColor(colors.secondary, -10),
4079
+ secondaryActive: adjustColor(colors.secondary, -20),
4080
+ secondaryDisabled: adjustColor(colors.secondary, 40),
4081
+ accent: colors.accent || colors.primary,
4082
+ accentHover: adjustColor(colors.accent || colors.primary, -10)
4083
+ }
4084
+ },
4085
+ components: {
4086
+ button: {
4087
+ bg: colors.primary,
4088
+ bgHover: adjustColor(colors.primary, -10),
4089
+ bgActive: adjustColor(colors.primary, -20),
4090
+ variants: {
4091
+ primary: {
4092
+ bg: colors.primary,
4093
+ bgHover: adjustColor(colors.primary, -10)
4094
+ },
4095
+ secondary: {
4096
+ bg: colors.secondary,
4097
+ bgHover: adjustColor(colors.secondary, -10)
4098
+ }
4099
+ }
4100
+ },
4101
+ input: {
4102
+ borderFocus: colors.primary
4103
+ },
4104
+ header: {
4105
+ navColorActive: colors.primary
4106
+ },
4107
+ loader: {
4108
+ color: colors.primary
4109
+ },
4110
+ newsletter: {
4111
+ buttonBg: colors.primary
4112
+ }
4113
+ }
4114
+ };
4115
+ return deepMerge(baseTheme, brandOverrides);
4116
+ }
4117
+ function adjustColor(hex, percent) {
4118
+ hex = hex.replace(/^#/, "");
4119
+ let r = parseInt(hex.substring(0, 2), 16);
4120
+ let g = parseInt(hex.substring(2, 4), 16);
4121
+ let b = parseInt(hex.substring(4, 6), 16);
4122
+ r = Math.min(255, Math.max(0, r + r * percent / 100));
4123
+ g = Math.min(255, Math.max(0, g + g * percent / 100));
4124
+ b = Math.min(255, Math.max(0, b + b * percent / 100));
4125
+ const toHex = (n) => Math.round(n).toString(16).padStart(2, "0");
4126
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
4127
+ }
4128
+ function hexToRgba(hex, alpha = 1) {
4129
+ hex = hex.replace(/^#/, "");
4130
+ const r = parseInt(hex.substring(0, 2), 16);
4131
+ const g = parseInt(hex.substring(2, 4), 16);
4132
+ const b = parseInt(hex.substring(4, 6), 16);
4133
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
4134
+ }
4135
+ function getContrastColor(hex) {
4136
+ hex = hex.replace(/^#/, "");
4137
+ const r = parseInt(hex.substring(0, 2), 16);
4138
+ const g = parseInt(hex.substring(2, 4), 16);
4139
+ const b = parseInt(hex.substring(4, 6), 16);
4140
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
4141
+ return luminance > 0.5 ? "#000000" : "#ffffff";
4142
+ }
4143
+ function flattenToCssVars(obj, prefix = "--ec") {
4144
+ const result = {};
4145
+ function flatten(current, path = []) {
4146
+ for (const key in current) {
4147
+ if (Object.prototype.hasOwnProperty.call(current, key)) {
4148
+ const value = current[key];
4149
+ const newPath = [...path, key];
4150
+ const varName = `${prefix}-${newPath.join("-")}`;
4151
+ if (value && typeof value === "object" && !Array.isArray(value)) {
4152
+ flatten(value, newPath);
4153
+ } else if (typeof value === "string" || typeof value === "number") {
4154
+ result[varName] = String(value);
4155
+ }
4156
+ }
4157
+ }
4158
+ }
4159
+ flatten(obj);
4160
+ return result;
4161
+ }
4162
+ function generateCssVars(theme, prefix = "--ec") {
4163
+ const cssVars = flattenToCssVars(theme, prefix);
4164
+ return Object.entries(cssVars).map(([key, value]) => `${key}: ${value};`).join("\n");
4165
+ }
4166
+ function injectCssVars(theme, prefix = "--ec") {
4167
+ if (typeof document === "undefined") return;
4168
+ const cssVars = flattenToCssVars(theme, prefix);
4169
+ const root = document.documentElement;
4170
+ for (const [key, value] of Object.entries(cssVars)) {
4171
+ root.style.setProperty(key, value);
4172
+ }
4173
+ }
4174
+ function removeCssVars(prefix = "--ec") {
4175
+ if (typeof document === "undefined") return;
4176
+ const root = document.documentElement;
4177
+ const style = root.style;
4178
+ for (let i = style.length - 1; i >= 0; i--) {
4179
+ const name = style[i];
4180
+ if (name.startsWith(prefix)) {
4181
+ root.style.removeProperty(name);
4182
+ }
4183
+ }
4184
+ }
4185
+ async function loadThemeFromUrl(url) {
4186
+ try {
4187
+ const response = await fetch(url, {
4188
+ headers: {
4189
+ Accept: "application/json"
4190
+ }
4191
+ });
4192
+ if (!response.ok) {
4193
+ console.error(`Failed to load theme from ${url}: ${response.status}`);
4194
+ return null;
4195
+ }
4196
+ const themeData = await response.json();
4197
+ return themeData;
4198
+ } catch (error) {
4199
+ console.error(`Error loading theme from ${url}:`, error);
4200
+ return null;
4201
+ }
4202
+ }
4203
+ async function createTheme(config = {}) {
4204
+ let lightTheme = { ...defaultLightTheme };
4205
+ let darkTheme = { ...defaultDarkTheme };
4206
+ if (config.themeUrl) {
4207
+ const urlTheme = await loadThemeFromUrl(config.themeUrl);
4208
+ if (urlTheme) {
4209
+ lightTheme = deepMerge(lightTheme, urlTheme);
4210
+ darkTheme = deepMerge(darkTheme, urlTheme);
4211
+ }
4212
+ }
4213
+ if (config.brandIdentity) {
4214
+ lightTheme = createThemeFromBrand(config.brandIdentity, lightTheme);
4215
+ darkTheme = createThemeFromBrand(config.brandIdentity, darkTheme);
4216
+ }
4217
+ if (config.light) {
4218
+ lightTheme = deepMerge(lightTheme, config.light);
4219
+ }
4220
+ if (config.dark) {
4221
+ darkTheme = deepMerge(darkTheme, config.dark);
4222
+ }
4223
+ return { light: lightTheme, dark: darkTheme };
4224
+ }
4225
+ var DEFAULT_STORAGE_KEY = "ec-theme-mode";
4226
+ function saveThemeMode(mode, storageKey = DEFAULT_STORAGE_KEY) {
4227
+ if (typeof localStorage === "undefined") return;
4228
+ try {
4229
+ localStorage.setItem(storageKey, mode);
4230
+ } catch (error) {
4231
+ console.error("Failed to save theme mode:", error);
4232
+ }
4233
+ }
4234
+ function loadThemeMode(storageKey = DEFAULT_STORAGE_KEY) {
4235
+ if (typeof localStorage === "undefined") return null;
4236
+ try {
4237
+ const mode = localStorage.getItem(storageKey);
4238
+ if (mode === "light" || mode === "dark" || mode === "system") {
4239
+ return mode;
4240
+ }
4241
+ return null;
4242
+ } catch (error) {
4243
+ console.error("Failed to load theme mode:", error);
4244
+ return null;
4245
+ }
4246
+ }
4247
+ function getSystemColorScheme() {
4248
+ if (typeof window === "undefined") return "light";
4249
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
4250
+ }
4251
+ function resolveThemeMode(mode) {
4252
+ if (mode === "system") {
4253
+ return getSystemColorScheme();
4254
+ }
4255
+ return mode;
4256
+ }
4257
+ var ThemeContext = react.createContext(null);
4258
+ function useTheme() {
4259
+ const context = react.useContext(ThemeContext);
4260
+ if (!context) {
4261
+ throw new Error("useTheme must be used within a ThemeProvider");
4262
+ }
4263
+ return context;
4264
+ }
4265
+ function ThemeProvider({
4266
+ children,
4267
+ config = {},
4268
+ initialTheme
4269
+ }) {
4270
+ const {
4271
+ defaultMode = "system",
4272
+ themeUrl,
4273
+ light: lightOverrides,
4274
+ dark: darkOverrides,
4275
+ brandIdentity,
4276
+ enableSystemTheme = true,
4277
+ persistTheme = true,
4278
+ storageKey = "ec-theme-mode",
4279
+ cssVarPrefix = "--ec"
4280
+ } = config;
4281
+ const [mode, setModeState] = react.useState(() => {
4282
+ if (persistTheme && typeof window !== "undefined") {
4283
+ const savedMode = loadThemeMode(storageKey);
4284
+ if (savedMode) return savedMode;
4285
+ }
4286
+ return defaultMode;
4287
+ });
4288
+ const [lightTheme, setLightTheme] = react.useState(() => {
4289
+ if (initialTheme && initialTheme.mode === "light") return initialTheme;
4290
+ let theme2 = defaultLightTheme;
4291
+ if (brandIdentity) {
4292
+ theme2 = createThemeFromBrand(brandIdentity, theme2);
4293
+ }
4294
+ if (lightOverrides) {
4295
+ theme2 = deepMerge(theme2, lightOverrides);
4296
+ }
4297
+ return theme2;
4298
+ });
4299
+ const [darkTheme, setDarkTheme] = react.useState(() => {
4300
+ if (initialTheme && initialTheme.mode === "dark") return initialTheme;
4301
+ let theme2 = defaultDarkTheme;
4302
+ if (brandIdentity) {
4303
+ theme2 = createThemeFromBrand(brandIdentity, theme2);
4304
+ }
4305
+ if (darkOverrides) {
4306
+ theme2 = deepMerge(theme2, darkOverrides);
4307
+ }
4308
+ return theme2;
4309
+ });
4310
+ const [isLoading, setIsLoading] = react.useState(!!themeUrl);
4311
+ const [error, setError] = react.useState(null);
4312
+ const resolvedMode = react.useMemo(() => resolveThemeMode(mode), [mode]);
4313
+ const theme = react.useMemo(
4314
+ () => resolvedMode === "dark" ? darkTheme : lightTheme,
4315
+ [resolvedMode, lightTheme, darkTheme]
4316
+ );
4317
+ const isDark = resolvedMode === "dark";
4318
+ const isLight = resolvedMode === "light";
4319
+ react.useEffect(() => {
4320
+ if (!themeUrl) return;
4321
+ setIsLoading(true);
4322
+ setError(null);
4323
+ loadThemeFromUrl(themeUrl).then((urlTheme) => {
4324
+ if (urlTheme) {
4325
+ setLightTheme((prev) => deepMerge(prev, urlTheme));
4326
+ setDarkTheme((prev) => deepMerge(prev, urlTheme));
4327
+ }
4328
+ }).catch((err) => {
4329
+ setError(err instanceof Error ? err.message : "Failed to load theme");
4330
+ }).finally(() => {
4331
+ setIsLoading(false);
4332
+ });
4333
+ }, [themeUrl]);
4334
+ react.useEffect(() => {
4335
+ if (typeof window !== "undefined") {
4336
+ injectCssVars(theme, cssVarPrefix);
4337
+ }
4338
+ }, [theme, cssVarPrefix]);
4339
+ react.useEffect(() => {
4340
+ if (typeof document !== "undefined") {
4341
+ document.documentElement.setAttribute("data-theme", resolvedMode);
4342
+ document.documentElement.style.colorScheme = resolvedMode;
4343
+ }
4344
+ }, [resolvedMode]);
4345
+ react.useEffect(() => {
4346
+ if (!enableSystemTheme || typeof window === "undefined") return;
4347
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
4348
+ const handleChange = () => {
4349
+ if (mode === "system") {
4350
+ setModeState("system");
4351
+ }
4352
+ };
4353
+ mediaQuery.addEventListener("change", handleChange);
4354
+ return () => mediaQuery.removeEventListener("change", handleChange);
4355
+ }, [mode, enableSystemTheme]);
4356
+ react.useEffect(() => {
4357
+ if (persistTheme && typeof window !== "undefined") {
4358
+ saveThemeMode(mode, storageKey);
4359
+ }
4360
+ }, [mode, persistTheme, storageKey]);
4361
+ const setMode = react.useCallback((newMode) => {
4362
+ setModeState(newMode);
4363
+ }, []);
4364
+ const toggleMode = react.useCallback(() => {
4365
+ setModeState((prev) => {
4366
+ const current = resolveThemeMode(prev);
4367
+ return current === "dark" ? "light" : "dark";
4368
+ });
4369
+ }, []);
4370
+ const updateTheme = react.useCallback((updates) => {
4371
+ setLightTheme((prev) => deepMerge(prev, updates));
4372
+ setDarkTheme((prev) => deepMerge(prev, updates));
4373
+ }, []);
4374
+ const resetTheme = react.useCallback(() => {
4375
+ let light = defaultLightTheme;
4376
+ let dark = defaultDarkTheme;
4377
+ if (brandIdentity) {
4378
+ light = createThemeFromBrand(brandIdentity, light);
4379
+ dark = createThemeFromBrand(brandIdentity, dark);
4380
+ }
4381
+ if (lightOverrides) {
4382
+ light = deepMerge(light, lightOverrides);
4383
+ }
4384
+ if (darkOverrides) {
4385
+ dark = deepMerge(dark, darkOverrides);
4386
+ }
4387
+ setLightTheme(light);
4388
+ setDarkTheme(dark);
4389
+ }, [brandIdentity, lightOverrides, darkOverrides]);
4390
+ const contextValue = react.useMemo(
4391
+ () => ({
4392
+ theme,
4393
+ mode,
4394
+ setMode,
4395
+ toggleMode,
4396
+ updateTheme,
4397
+ resetTheme,
4398
+ isDark,
4399
+ isLight,
4400
+ isLoading,
4401
+ error
4402
+ }),
4403
+ [theme, mode, setMode, toggleMode, updateTheme, resetTheme, isDark, isLight, isLoading, error]
4404
+ );
4405
+ return /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value: contextValue, children });
4406
+ }
4407
+ function cssVar(path, prefix = "--ec") {
4408
+ return `var(${prefix}-${path.replace(/\./g, "-")})`;
4409
+ }
4410
+ function useThemeValue(selector) {
4411
+ const { theme } = useTheme();
4412
+ return selector(theme);
4413
+ }
4414
+ function ThemeToggle({
4415
+ className = "",
4416
+ size = 24,
4417
+ showLabel = false,
4418
+ lightLabel = "Light",
4419
+ darkLabel = "Dark"
4420
+ }) {
4421
+ const { isDark, toggleMode } = useTheme();
4422
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4423
+ "button",
4424
+ {
4425
+ type: "button",
4426
+ onClick: toggleMode,
4427
+ className: `ec-theme-toggle ${className}`,
4428
+ "aria-label": isDark ? "Switch to light mode" : "Switch to dark mode",
4429
+ style: {
4430
+ background: "none",
4431
+ border: "none",
4432
+ cursor: "pointer",
4433
+ display: "inline-flex",
4434
+ alignItems: "center",
4435
+ gap: "0.5rem",
4436
+ padding: "0.5rem",
4437
+ borderRadius: "0.375rem",
4438
+ transition: "background-color 200ms ease-in-out"
4439
+ },
4440
+ children: [
4441
+ isDark ? (
4442
+ // Sun icon for dark mode (click to go light)
4443
+ /* @__PURE__ */ jsxRuntime.jsxs(
4444
+ "svg",
4445
+ {
4446
+ width: size,
4447
+ height: size,
4448
+ viewBox: "0 0 24 24",
4449
+ fill: "none",
4450
+ stroke: "currentColor",
4451
+ strokeWidth: "2",
4452
+ strokeLinecap: "round",
4453
+ strokeLinejoin: "round",
4454
+ children: [
4455
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "5" }),
4456
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "1", x2: "12", y2: "3" }),
4457
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "21", x2: "12", y2: "23" }),
4458
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }),
4459
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }),
4460
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "1", y1: "12", x2: "3", y2: "12" }),
4461
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "21", y1: "12", x2: "23", y2: "12" }),
4462
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }),
4463
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" })
4464
+ ]
4465
+ }
4466
+ )
4467
+ ) : (
4468
+ // Moon icon for light mode (click to go dark)
4469
+ /* @__PURE__ */ jsxRuntime.jsx(
4470
+ "svg",
4471
+ {
4472
+ width: size,
4473
+ height: size,
4474
+ viewBox: "0 0 24 24",
4475
+ fill: "none",
4476
+ stroke: "currentColor",
4477
+ strokeWidth: "2",
4478
+ strokeLinecap: "round",
4479
+ strokeLinejoin: "round",
4480
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" })
4481
+ }
4482
+ )
4483
+ ),
4484
+ showLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { children: isDark ? darkLabel : lightLabel })
4485
+ ]
4486
+ }
4487
+ );
4488
+ }
4489
+
4490
+ // src/client/web/astro/types.ts
4491
+ function dummyImage(width, height, text, bgColor = "cccccc", textColor = "969696") {
4492
+ const label = text ? `&text=${encodeURIComponent(text)}` : "";
4493
+ return `https://dummyimage.com/${width}x${height}/${bgColor}/${textColor}${label}`;
4494
+ }
4495
+ function loremIpsum(type = "paragraph", count = 1) {
4496
+ const words = [
4497
+ "lorem",
4498
+ "ipsum",
4499
+ "dolor",
4500
+ "sit",
4501
+ "amet",
4502
+ "consectetur",
4503
+ "adipiscing",
4504
+ "elit",
4505
+ "sed",
4506
+ "do",
4507
+ "eiusmod",
4508
+ "tempor",
4509
+ "incididunt",
4510
+ "ut",
4511
+ "labore",
4512
+ "et",
4513
+ "dolore",
4514
+ "magna",
4515
+ "aliqua",
4516
+ "enim",
4517
+ "ad",
4518
+ "minim",
4519
+ "veniam",
4520
+ "quis",
4521
+ "nostrud",
4522
+ "exercitation",
4523
+ "ullamco",
4524
+ "laboris",
4525
+ "nisi",
4526
+ "aliquip",
4527
+ "ex",
4528
+ "ea",
4529
+ "commodo",
4530
+ "consequat",
4531
+ "duis",
4532
+ "aute",
4533
+ "irure",
4534
+ "in",
4535
+ "reprehenderit",
4536
+ "voluptate",
4537
+ "velit",
4538
+ "esse",
4539
+ "cillum",
4540
+ "fugiat",
4541
+ "nulla",
4542
+ "pariatur",
4543
+ "excepteur",
4544
+ "sint",
4545
+ "occaecat",
4546
+ "cupidatat",
4547
+ "non",
4548
+ "proident",
4549
+ "sunt",
4550
+ "culpa",
4551
+ "qui",
4552
+ "officia",
4553
+ "deserunt",
4554
+ "mollit",
4555
+ "anim",
4556
+ "id",
4557
+ "est",
4558
+ "laborum"
4559
+ ];
4560
+ const getWords = (n) => {
4561
+ const result = [];
4562
+ for (let i = 0; i < n; i++) {
4563
+ result.push(words[Math.floor(Math.random() * words.length)]);
4564
+ }
4565
+ return result;
4566
+ };
4567
+ const capitalize2 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
4568
+ if (type === "word") {
4569
+ return getWords(count).join(" ");
4570
+ }
4571
+ if (type === "sentence") {
4572
+ const sentences = [];
4573
+ for (let i = 0; i < count; i++) {
4574
+ const sentence = capitalize2(getWords(Math.floor(Math.random() * 10) + 5).join(" ")) + ".";
4575
+ sentences.push(sentence);
4576
+ }
4577
+ return sentences.join(" ");
4578
+ }
4579
+ const paragraphs = [];
4580
+ for (let i = 0; i < count; i++) {
4581
+ const sentences = [];
4582
+ const sentenceCount = Math.floor(Math.random() * 4) + 3;
4583
+ for (let j = 0; j < sentenceCount; j++) {
4584
+ sentences.push(capitalize2(getWords(Math.floor(Math.random() * 10) + 5).join(" ")) + ".");
4585
+ }
4586
+ paragraphs.push(sentences.join(" "));
4587
+ }
4588
+ return paragraphs.join("\n\n");
4589
+ }
4590
+ var dummyHeaderData = {
4591
+ logo: dummyImage(120, 40, "Logo"),
4592
+ logoAlt: "Company Logo",
4593
+ navLinks: [
4594
+ { text: "Home", href: "/", active: true },
4595
+ { text: "About", href: "/about" },
4596
+ { text: "Services", href: "/services" },
4597
+ { text: "Blog", href: "/blog" },
4598
+ { text: "Contact", href: "/contact" }
4599
+ ],
4600
+ cta: {
4601
+ text: "Get Started",
4602
+ href: "/signup",
4603
+ variant: "primary"
4604
+ },
4605
+ sticky: true
4606
+ };
4607
+ var dummyFooterData = {
4608
+ logo: dummyImage(120, 40, "Logo"),
4609
+ logoAlt: "Company Logo",
4610
+ description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore.",
4611
+ columns: [
4612
+ {
4613
+ title: "Product",
4614
+ links: [
4615
+ { text: "Features", href: "/features" },
4616
+ { text: "Pricing", href: "/pricing" },
4617
+ { text: "Integrations", href: "/integrations" },
4618
+ { text: "API", href: "/api" }
4619
+ ]
4620
+ },
4621
+ {
4622
+ title: "Company",
4623
+ links: [
4624
+ { text: "About", href: "/about" },
4625
+ { text: "Blog", href: "/blog" },
4626
+ { text: "Careers", href: "/careers" },
4627
+ { text: "Contact", href: "/contact" }
4628
+ ]
4629
+ },
4630
+ {
4631
+ title: "Legal",
4632
+ links: [
4633
+ { text: "Privacy Policy", href: "/privacy" },
4634
+ { text: "Terms of Service", href: "/terms" },
4635
+ { text: "Cookie Policy", href: "/cookies" }
4636
+ ]
4637
+ }
4638
+ ],
4639
+ socialLinks: [
4640
+ { platform: "twitter", href: "https://twitter.com" },
4641
+ { platform: "facebook", href: "https://facebook.com" },
4642
+ { platform: "instagram", href: "https://instagram.com" },
4643
+ { platform: "linkedin", href: "https://linkedin.com" },
4644
+ { platform: "github", href: "https://github.com" }
4645
+ ],
4646
+ copyright: `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} Company Name. All rights reserved.`
4647
+ };
4648
+ var dummyBannerData = {
4649
+ title: "Build Something Amazing Today",
4650
+ subtitle: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
4651
+ backgroundImage: dummyImage(1920, 800, "Hero+Background", "1e293b", "334155"),
4652
+ primaryCta: {
4653
+ text: "Get Started Free",
4654
+ href: "/signup",
4655
+ variant: "primary"
4656
+ },
4657
+ secondaryCta: {
4658
+ text: "Learn More",
4659
+ href: "/about",
4660
+ variant: "outline"
4661
+ },
4662
+ height: "lg",
4663
+ align: "center"
4664
+ };
4665
+ var dummyFeatures = [
4666
+ {
4667
+ title: "Lightning Fast",
4668
+ description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
4669
+ icon: '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" /></svg>'
4670
+ },
4671
+ {
4672
+ title: "Secure & Reliable",
4673
+ description: "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
4674
+ icon: '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" /></svg>'
4675
+ },
4676
+ {
4677
+ title: "Easy to Use",
4678
+ description: "Ut enim ad minim veniam, quis nostrud exercitation ullamco.",
4679
+ icon: '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" /></svg>'
4680
+ }
4681
+ ];
4682
+ var dummyTestimonials = [
4683
+ {
4684
+ name: "John Doe",
4685
+ role: "CEO",
4686
+ company: "Tech Corp",
4687
+ avatar: dummyImage(80, 80, "JD", "3b82f6", "ffffff"),
4688
+ text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
4689
+ rating: 5
4690
+ },
4691
+ {
4692
+ name: "Jane Smith",
4693
+ role: "CTO",
4694
+ company: "Startup Inc",
4695
+ avatar: dummyImage(80, 80, "JS", "10b981", "ffffff"),
4696
+ text: "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
4697
+ rating: 5
4698
+ },
4699
+ {
4700
+ name: "Bob Wilson",
4701
+ role: "Product Manager",
4702
+ company: "Enterprise Co",
4703
+ avatar: dummyImage(80, 80, "BW", "f59e0b", "ffffff"),
4704
+ text: "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
4705
+ rating: 4
4706
+ }
4707
+ ];
4708
+ var dummyPricingPlans = [
4709
+ {
4710
+ name: "Starter",
4711
+ description: "Perfect for individuals",
4712
+ price: "$9",
4713
+ period: "/month",
4714
+ features: [
4715
+ { text: "5 Projects", included: true },
4716
+ { text: "10GB Storage", included: true },
4717
+ { text: "Email Support", included: true },
4718
+ { text: "API Access", included: false },
4719
+ { text: "Custom Domain", included: false }
4720
+ ],
4721
+ ctaText: "Start Free Trial",
4722
+ ctaHref: "/signup?plan=starter"
4723
+ },
4724
+ {
4725
+ name: "Professional",
4726
+ description: "Best for growing teams",
4727
+ price: "$29",
4728
+ period: "/month",
4729
+ features: [
4730
+ { text: "Unlimited Projects", included: true },
4731
+ { text: "100GB Storage", included: true },
4732
+ { text: "Priority Support", included: true },
4733
+ { text: "API Access", included: true },
4734
+ { text: "Custom Domain", included: false }
4735
+ ],
4736
+ ctaText: "Start Free Trial",
4737
+ ctaHref: "/signup?plan=pro",
4738
+ popular: true,
4739
+ badge: "Most Popular"
4740
+ },
4741
+ {
4742
+ name: "Enterprise",
4743
+ description: "For large organizations",
4744
+ price: "$99",
4745
+ period: "/month",
4746
+ features: [
4747
+ { text: "Unlimited Projects", included: true },
4748
+ { text: "Unlimited Storage", included: true },
4749
+ { text: "24/7 Support", included: true },
4750
+ { text: "API Access", included: true },
4751
+ { text: "Custom Domain", included: true }
4752
+ ],
4753
+ ctaText: "Contact Sales",
4754
+ ctaHref: "/contact?plan=enterprise"
4755
+ }
4756
+ ];
4757
+ var dummyFaqItems = [
4758
+ {
4759
+ question: "What is your refund policy?",
4760
+ answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
4761
+ },
4762
+ {
4763
+ question: "How do I cancel my subscription?",
4764
+ answer: "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
4765
+ },
4766
+ {
4767
+ question: "Can I change my plan later?",
4768
+ answer: "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
4769
+ },
4770
+ {
4771
+ question: "Do you offer discounts for non-profits?",
4772
+ answer: "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
4773
+ }
4774
+ ];
4775
+
4776
+ // src/client/web/forms/types.ts
4777
+ var VALIDATION_MESSAGES = {
4778
+ required: "This field is required",
4779
+ email: "Please enter a valid email address",
4780
+ phone: "Please enter a valid phone number",
4781
+ minLength: (min) => `Must be at least ${min} characters`,
4782
+ maxLength: (max) => `Must be no more than ${max} characters`,
4783
+ passwordMatch: "Passwords must match",
4784
+ acceptTerms: "You must accept the terms and conditions",
4785
+ passwordUppercase: "Password must contain at least one uppercase letter",
4786
+ passwordLowercase: "Password must contain at least one lowercase letter",
4787
+ passwordNumber: "Password must contain at least one number",
4788
+ passwordSpecial: "Password must contain at least one special character"
4789
+ };
4790
+ var contactFormSchema = Yup__namespace.object().shape({
4791
+ name: Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(2, VALIDATION_MESSAGES.minLength(2)).max(100, VALIDATION_MESSAGES.maxLength(100)),
4792
+ email: Yup__namespace.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
4793
+ phone: Yup__namespace.string().matches(
4794
+ /^[+]?[(]?[0-9]{1,4}[)]?[-\s./0-9]*$/,
4795
+ VALIDATION_MESSAGES.phone
4796
+ ).nullable(),
4797
+ subject: Yup__namespace.string().max(200, VALIDATION_MESSAGES.maxLength(200)).nullable(),
4798
+ message: Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(10, VALIDATION_MESSAGES.minLength(10)).max(2e3, VALIDATION_MESSAGES.maxLength(2e3))
4799
+ });
4800
+ var newsletterFormSchema = Yup__namespace.object().shape({
4801
+ email: Yup__namespace.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
4802
+ firstName: Yup__namespace.string().min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)).nullable(),
4803
+ lastName: Yup__namespace.string().min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)).nullable()
4804
+ });
4805
+ var loginFormSchema = Yup__namespace.object().shape({
4806
+ email: Yup__namespace.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
4807
+ password: Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(8, VALIDATION_MESSAGES.minLength(8)),
4808
+ rememberMe: Yup__namespace.boolean()
4809
+ });
4810
+ function createRegisterFormSchema(requirements = {}) {
4811
+ const {
4812
+ minLength = 8,
4813
+ requireUppercase = true,
4814
+ requireLowercase = true,
4815
+ requireNumber = true,
4816
+ requireSpecial = false
4817
+ } = requirements;
4818
+ let passwordSchema = Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(minLength, VALIDATION_MESSAGES.minLength(minLength));
4819
+ if (requireUppercase) {
4820
+ passwordSchema = passwordSchema.matches(
4821
+ /[A-Z]/,
4822
+ VALIDATION_MESSAGES.passwordUppercase
4823
+ );
4824
+ }
4825
+ if (requireLowercase) {
4826
+ passwordSchema = passwordSchema.matches(
4827
+ /[a-z]/,
4828
+ VALIDATION_MESSAGES.passwordLowercase
4829
+ );
4830
+ }
4831
+ if (requireNumber) {
4832
+ passwordSchema = passwordSchema.matches(
4833
+ /[0-9]/,
4834
+ VALIDATION_MESSAGES.passwordNumber
4835
+ );
4836
+ }
4837
+ if (requireSpecial) {
4838
+ passwordSchema = passwordSchema.matches(
4839
+ /[!@#$%^&*(),.?":{}|<>]/,
4840
+ VALIDATION_MESSAGES.passwordSpecial
4841
+ );
4842
+ }
4843
+ return Yup__namespace.object().shape({
4844
+ firstName: Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)),
4845
+ lastName: Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)),
4846
+ email: Yup__namespace.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
4847
+ password: passwordSchema,
4848
+ confirmPassword: Yup__namespace.string().required(VALIDATION_MESSAGES.required).oneOf([Yup__namespace.ref("password")], VALIDATION_MESSAGES.passwordMatch),
4849
+ acceptTerms: Yup__namespace.boolean().oneOf([true], VALIDATION_MESSAGES.acceptTerms)
4850
+ });
4851
+ }
4852
+ var registerFormSchema = createRegisterFormSchema();
4853
+ var defaultInitialValues = {
4854
+ name: "",
4855
+ email: "",
4856
+ phone: "",
4857
+ subject: "",
4858
+ message: ""
4859
+ };
4860
+ var defaultSubjectOptions = [
4861
+ "General Inquiry",
4862
+ "Support Request",
4863
+ "Sales Question",
4864
+ "Partnership",
4865
+ "Feedback",
4866
+ "Other"
4867
+ ];
4868
+ function ContactForm({
4869
+ actionUrl,
4870
+ onSubmit,
4871
+ initialValues,
4872
+ showPhone = true,
4873
+ showSubject = true,
4874
+ subjectOptions = defaultSubjectOptions,
4875
+ submitText = "Send Message",
4876
+ successMessage = "Thank you! Your message has been sent successfully.",
4877
+ className = "",
4878
+ formClass = "",
4879
+ inputClass = "",
4880
+ labelClass = "",
4881
+ buttonClass = "",
4882
+ errorClass = ""
4883
+ }) {
4884
+ const [submitStatus, setSubmitStatus] = react.useState("idle");
4885
+ const [submitMessage, setSubmitMessage] = react.useState("");
4886
+ const mergedInitialValues = {
4887
+ ...defaultInitialValues,
4888
+ ...initialValues
4889
+ };
4890
+ const baseInputClass = "w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors";
4891
+ const baseLabelClass = "block text-sm font-medium text-gray-700 mb-1";
4892
+ const baseErrorClass = "text-sm text-red-600 mt-1";
4893
+ const baseButtonClass = "w-full px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed";
4894
+ const handleSubmit = async (values, { setSubmitting, resetForm }) => {
4895
+ try {
4896
+ let result;
4897
+ if (onSubmit) {
4898
+ result = await onSubmit(values);
4899
+ } else if (actionUrl) {
4900
+ const response = await fetch(actionUrl, {
4901
+ method: "POST",
4902
+ headers: { "Content-Type": "application/json" },
4903
+ body: JSON.stringify(values)
4904
+ });
4905
+ result = await response.json();
4906
+ } else {
4907
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
4908
+ result = { success: true };
4909
+ }
4910
+ if (result.success) {
4911
+ setSubmitStatus("success");
4912
+ setSubmitMessage(result.message || successMessage);
4913
+ resetForm();
4914
+ } else {
4915
+ setSubmitStatus("error");
4916
+ setSubmitMessage(result.message || "Something went wrong. Please try again.");
4917
+ }
4918
+ } catch (error) {
4919
+ setSubmitStatus("error");
4920
+ setSubmitMessage("An error occurred. Please try again later.");
4921
+ } finally {
4922
+ setSubmitting(false);
4923
+ }
4924
+ };
4925
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `ec-contact-form ${className}`, children: submitStatus === "success" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 bg-green-50 border border-green-200 rounded-lg text-center", children: [
4926
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-12 h-12 text-green-500 mx-auto mb-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
4927
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-green-800 font-medium", children: submitMessage }),
4928
+ /* @__PURE__ */ jsxRuntime.jsx(
4929
+ "button",
4930
+ {
4931
+ type: "button",
4932
+ onClick: () => setSubmitStatus("idle"),
4933
+ className: "mt-4 text-green-600 hover:text-green-700 text-sm font-medium",
4934
+ children: "Send another message"
4935
+ }
4936
+ )
4937
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
4938
+ formik.Formik,
4939
+ {
4940
+ initialValues: mergedInitialValues,
4941
+ validationSchema: contactFormSchema,
4942
+ onSubmit: handleSubmit,
4943
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { className: `space-y-4 ${formClass}`, noValidate: true, children: [
4944
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4945
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "contact-name", className: `${baseLabelClass} ${labelClass}`, children: [
4946
+ "Name ",
4947
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
4948
+ ] }),
4949
+ /* @__PURE__ */ jsxRuntime.jsx(
4950
+ formik.Field,
4951
+ {
4952
+ type: "text",
4953
+ id: "contact-name",
4954
+ name: "name",
4955
+ placeholder: "John Doe",
4956
+ className: `${baseInputClass} ${inputClass} ${errors.name && touched.name ? "border-red-500 focus:ring-red-500" : ""}`
4957
+ }
4958
+ ),
4959
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "name", component: "p", className: `${baseErrorClass} ${errorClass}` })
4960
+ ] }),
4961
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4962
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "contact-email", className: `${baseLabelClass} ${labelClass}`, children: [
4963
+ "Email ",
4964
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
4965
+ ] }),
4966
+ /* @__PURE__ */ jsxRuntime.jsx(
4967
+ formik.Field,
4968
+ {
4969
+ type: "email",
4970
+ id: "contact-email",
4971
+ name: "email",
4972
+ placeholder: "john@example.com",
4973
+ className: `${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500 focus:ring-red-500" : ""}`
4974
+ }
4975
+ ),
4976
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "email", component: "p", className: `${baseErrorClass} ${errorClass}` })
4977
+ ] }),
4978
+ showPhone && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4979
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "contact-phone", className: `${baseLabelClass} ${labelClass}`, children: "Phone" }),
4980
+ /* @__PURE__ */ jsxRuntime.jsx(
4981
+ formik.Field,
4982
+ {
4983
+ type: "tel",
4984
+ id: "contact-phone",
4985
+ name: "phone",
4986
+ placeholder: "+1 (555) 000-0000",
4987
+ className: `${baseInputClass} ${inputClass} ${errors.phone && touched.phone ? "border-red-500 focus:ring-red-500" : ""}`
4988
+ }
4989
+ ),
4990
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "phone", component: "p", className: `${baseErrorClass} ${errorClass}` })
4991
+ ] }),
4992
+ showSubject && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4993
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "contact-subject", className: `${baseLabelClass} ${labelClass}`, children: "Subject" }),
4994
+ /* @__PURE__ */ jsxRuntime.jsxs(
4995
+ formik.Field,
4996
+ {
4997
+ as: "select",
4998
+ id: "contact-subject",
4999
+ name: "subject",
5000
+ className: `${baseInputClass} ${inputClass}`,
5001
+ children: [
5002
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select a subject..." }),
5003
+ subjectOptions.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option, children: option }, option))
5004
+ ]
5005
+ }
5006
+ ),
5007
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "subject", component: "p", className: `${baseErrorClass} ${errorClass}` })
5008
+ ] }),
5009
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5010
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "contact-message", className: `${baseLabelClass} ${labelClass}`, children: [
5011
+ "Message ",
5012
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
5013
+ ] }),
5014
+ /* @__PURE__ */ jsxRuntime.jsx(
5015
+ formik.Field,
5016
+ {
5017
+ as: "textarea",
5018
+ id: "contact-message",
5019
+ name: "message",
5020
+ rows: 5,
5021
+ placeholder: "Your message...",
5022
+ className: `${baseInputClass} ${inputClass} resize-none ${errors.message && touched.message ? "border-red-500 focus:ring-red-500" : ""}`
5023
+ }
5024
+ ),
5025
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "message", component: "p", className: `${baseErrorClass} ${errorClass}` })
5026
+ ] }),
5027
+ submitStatus === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 bg-red-50 border border-red-200 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-red-800 text-sm", children: submitMessage }) }),
5028
+ /* @__PURE__ */ jsxRuntime.jsx(
5029
+ "button",
5030
+ {
5031
+ type: "submit",
5032
+ disabled: isSubmitting,
5033
+ className: `${baseButtonClass} ${buttonClass}`,
5034
+ children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
5035
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
5036
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
5037
+ /* @__PURE__ */ jsxRuntime.jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
5038
+ ] }),
5039
+ "Sending..."
5040
+ ] }) : submitText
5041
+ }
5042
+ )
5043
+ ] })
5044
+ }
5045
+ ) });
5046
+ }
5047
+ var defaultInitialValues2 = {
5048
+ email: "",
5049
+ firstName: "",
5050
+ lastName: ""
5051
+ };
5052
+ function NewsletterForm({
5053
+ actionUrl,
5054
+ onSubmit,
5055
+ initialValues,
5056
+ showName = false,
5057
+ placeholder = "Enter your email",
5058
+ submitText = "Subscribe",
5059
+ successMessage = "Thank you for subscribing!",
5060
+ layout = "inline",
5061
+ className = "",
5062
+ formClass = "",
5063
+ inputClass = "",
5064
+ buttonClass = ""
5065
+ }) {
5066
+ const [submitStatus, setSubmitStatus] = react.useState("idle");
5067
+ const [submitMessage, setSubmitMessage] = react.useState("");
5068
+ const mergedInitialValues = {
5069
+ ...defaultInitialValues2,
5070
+ ...initialValues
5071
+ };
5072
+ const baseInputClass = "px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors";
5073
+ const baseButtonClass = "px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed";
5074
+ const handleSubmit = async (values, { setSubmitting, resetForm }) => {
5075
+ try {
5076
+ let result;
5077
+ if (onSubmit) {
5078
+ result = await onSubmit(values);
5079
+ } else if (actionUrl) {
5080
+ const response = await fetch(actionUrl, {
5081
+ method: "POST",
5082
+ headers: { "Content-Type": "application/json" },
5083
+ body: JSON.stringify(values)
5084
+ });
5085
+ result = await response.json();
5086
+ } else {
5087
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
5088
+ result = { success: true };
5089
+ }
5090
+ if (result.success) {
5091
+ setSubmitStatus("success");
5092
+ setSubmitMessage(result.message || successMessage);
5093
+ resetForm();
5094
+ } else {
5095
+ setSubmitStatus("error");
5096
+ setSubmitMessage(result.message || "Something went wrong. Please try again.");
5097
+ }
5098
+ } catch (error) {
5099
+ setSubmitStatus("error");
5100
+ setSubmitMessage("An error occurred. Please try again later.");
5101
+ } finally {
5102
+ setSubmitting(false);
5103
+ }
5104
+ };
5105
+ if (submitStatus === "success") {
5106
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `ec-newsletter-form ${className}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 bg-green-50 border border-green-200 rounded-lg text-center", children: [
5107
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-green-800 font-medium", children: submitMessage }),
5108
+ /* @__PURE__ */ jsxRuntime.jsx(
5109
+ "button",
5110
+ {
5111
+ type: "button",
5112
+ onClick: () => setSubmitStatus("idle"),
5113
+ className: "mt-2 text-green-600 hover:text-green-700 text-sm",
5114
+ children: "Subscribe another email"
5115
+ }
5116
+ )
5117
+ ] }) });
5118
+ }
5119
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `ec-newsletter-form ${className}`, children: [
5120
+ /* @__PURE__ */ jsxRuntime.jsx(
5121
+ formik.Formik,
5122
+ {
5123
+ initialValues: mergedInitialValues,
5124
+ validationSchema: newsletterFormSchema,
5125
+ onSubmit: handleSubmit,
5126
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxRuntime.jsxs(
5127
+ formik.Form,
5128
+ {
5129
+ className: `${layout === "inline" ? "flex flex-col sm:flex-row gap-3" : "space-y-4"} ${formClass}`,
5130
+ noValidate: true,
5131
+ children: [
5132
+ showName && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: layout === "inline" ? "flex gap-3 flex-1" : "grid grid-cols-2 gap-4", children: [
5133
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
5134
+ /* @__PURE__ */ jsxRuntime.jsx(
5135
+ formik.Field,
5136
+ {
5137
+ type: "text",
5138
+ name: "firstName",
5139
+ placeholder: "First name",
5140
+ className: `w-full ${baseInputClass} ${inputClass} ${errors.firstName && touched.firstName ? "border-red-500" : ""}`
5141
+ }
5142
+ ),
5143
+ layout === "stacked" && /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "firstName", component: "p", className: "text-sm text-red-600 mt-1" })
5144
+ ] }),
5145
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
5146
+ /* @__PURE__ */ jsxRuntime.jsx(
5147
+ formik.Field,
5148
+ {
5149
+ type: "text",
5150
+ name: "lastName",
5151
+ placeholder: "Last name",
5152
+ className: `w-full ${baseInputClass} ${inputClass} ${errors.lastName && touched.lastName ? "border-red-500" : ""}`
5153
+ }
5154
+ ),
5155
+ layout === "stacked" && /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "lastName", component: "p", className: "text-sm text-red-600 mt-1" })
5156
+ ] })
5157
+ ] }),
5158
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: layout === "inline" ? "flex-1" : "", children: [
5159
+ /* @__PURE__ */ jsxRuntime.jsx(
5160
+ formik.Field,
5161
+ {
5162
+ type: "email",
5163
+ name: "email",
5164
+ placeholder,
5165
+ className: `w-full ${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500" : ""}`
5166
+ }
5167
+ ),
5168
+ layout === "stacked" && /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "email", component: "p", className: "text-sm text-red-600 mt-1" })
5169
+ ] }),
5170
+ /* @__PURE__ */ jsxRuntime.jsx(
5171
+ "button",
5172
+ {
5173
+ type: "submit",
5174
+ disabled: isSubmitting,
5175
+ className: `${baseButtonClass} ${buttonClass} ${layout === "stacked" ? "w-full" : ""}`,
5176
+ children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
5177
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
5178
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
5179
+ /* @__PURE__ */ jsxRuntime.jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
5180
+ ] }),
5181
+ "Subscribing..."
5182
+ ] }) : submitText
5183
+ }
5184
+ ),
5185
+ layout === "inline" && errors.email && touched.email && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full sm:w-auto", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-red-600", children: errors.email }) })
5186
+ ]
5187
+ }
5188
+ )
5189
+ }
5190
+ ),
5191
+ submitStatus === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 p-4 bg-red-50 border border-red-200 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-red-800 text-sm", children: submitMessage }) })
5192
+ ] });
5193
+ }
5194
+ var defaultInitialValues3 = {
5195
+ email: "",
5196
+ password: "",
5197
+ rememberMe: false
5198
+ };
5199
+ function LoginForm({
5200
+ actionUrl,
5201
+ onSubmit,
5202
+ initialValues,
5203
+ showRememberMe = true,
5204
+ forgotPasswordLink = "/forgot-password",
5205
+ registerLink = "/register",
5206
+ submitText = "Sign In",
5207
+ successRedirect,
5208
+ className = "",
5209
+ formClass = "",
5210
+ inputClass = "",
5211
+ buttonClass = ""
5212
+ }) {
5213
+ const [submitStatus, setSubmitStatus] = react.useState("idle");
5214
+ const [submitMessage, setSubmitMessage] = react.useState("");
5215
+ const [showPassword, setShowPassword] = react.useState(false);
5216
+ const mergedInitialValues = {
5217
+ ...defaultInitialValues3,
5218
+ ...initialValues
5219
+ };
5220
+ const baseInputClass = "w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors";
5221
+ const baseLabelClass = "block text-sm font-medium text-gray-700 mb-1";
5222
+ const baseErrorClass = "text-sm text-red-600 mt-1";
5223
+ const baseButtonClass = "w-full px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed";
5224
+ const handleSubmit = async (values, { setSubmitting }) => {
5225
+ try {
5226
+ let result;
5227
+ if (onSubmit) {
5228
+ result = await onSubmit(values);
5229
+ } else if (actionUrl) {
5230
+ const response = await fetch(actionUrl, {
5231
+ method: "POST",
5232
+ headers: { "Content-Type": "application/json" },
5233
+ body: JSON.stringify(values)
5234
+ });
5235
+ result = await response.json();
5236
+ } else {
5237
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
5238
+ result = { success: true };
5239
+ }
5240
+ if (result.success) {
5241
+ setSubmitStatus("success");
5242
+ setSubmitMessage(result.message || "Login successful!");
5243
+ if (successRedirect && typeof window !== "undefined") {
5244
+ window.location.href = successRedirect;
5245
+ }
5246
+ } else {
5247
+ setSubmitStatus("error");
5248
+ setSubmitMessage(result.message || "Invalid email or password.");
5249
+ }
5250
+ } catch (error) {
5251
+ setSubmitStatus("error");
5252
+ setSubmitMessage("An error occurred. Please try again later.");
5253
+ } finally {
5254
+ setSubmitting(false);
5255
+ }
5256
+ };
5257
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `ec-login-form ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx(
5258
+ formik.Formik,
5259
+ {
5260
+ initialValues: mergedInitialValues,
5261
+ validationSchema: loginFormSchema,
5262
+ onSubmit: handleSubmit,
5263
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { className: `space-y-4 ${formClass}`, noValidate: true, children: [
5264
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5265
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "login-email", className: baseLabelClass, children: "Email" }),
5266
+ /* @__PURE__ */ jsxRuntime.jsx(
5267
+ formik.Field,
5268
+ {
5269
+ type: "email",
5270
+ id: "login-email",
5271
+ name: "email",
5272
+ placeholder: "you@example.com",
5273
+ autoComplete: "email",
5274
+ className: `${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500 focus:ring-red-500" : ""}`
5275
+ }
5276
+ ),
5277
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "email", component: "p", className: baseErrorClass })
5278
+ ] }),
5279
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5280
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "login-password", className: baseLabelClass, children: "Password" }),
5281
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
5282
+ /* @__PURE__ */ jsxRuntime.jsx(
5283
+ formik.Field,
5284
+ {
5285
+ type: showPassword ? "text" : "password",
5286
+ id: "login-password",
5287
+ name: "password",
5288
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
5289
+ autoComplete: "current-password",
5290
+ className: `${baseInputClass} ${inputClass} pr-12 ${errors.password && touched.password ? "border-red-500 focus:ring-red-500" : ""}`
5291
+ }
5292
+ ),
5293
+ /* @__PURE__ */ jsxRuntime.jsx(
5294
+ "button",
5295
+ {
5296
+ type: "button",
5297
+ onClick: () => setShowPassword(!showPassword),
5298
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700",
5299
+ tabIndex: -1,
5300
+ children: showPassword ? /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [
5301
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" }),
5302
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" })
5303
+ ] })
5304
+ }
5305
+ )
5306
+ ] }),
5307
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "password", component: "p", className: baseErrorClass })
5308
+ ] }),
5309
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
5310
+ showRememberMe && /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [
5311
+ /* @__PURE__ */ jsxRuntime.jsx(
5312
+ formik.Field,
5313
+ {
5314
+ type: "checkbox",
5315
+ name: "rememberMe",
5316
+ className: "w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
5317
+ }
5318
+ ),
5319
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-gray-600", children: "Remember me" })
5320
+ ] }),
5321
+ forgotPasswordLink && /* @__PURE__ */ jsxRuntime.jsx(
5322
+ "a",
5323
+ {
5324
+ href: forgotPasswordLink,
5325
+ className: "text-sm text-blue-600 hover:text-blue-700 font-medium",
5326
+ children: "Forgot password?"
5327
+ }
5328
+ )
5329
+ ] }),
5330
+ submitStatus === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 bg-red-50 border border-red-200 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-red-800 text-sm", children: submitMessage }) }),
5331
+ /* @__PURE__ */ jsxRuntime.jsx(
5332
+ "button",
5333
+ {
5334
+ type: "submit",
5335
+ disabled: isSubmitting,
5336
+ className: `${baseButtonClass} ${buttonClass}`,
5337
+ children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
5338
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
5339
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
5340
+ /* @__PURE__ */ jsxRuntime.jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
5341
+ ] }),
5342
+ "Signing in..."
5343
+ ] }) : submitText
5344
+ }
5345
+ ),
5346
+ registerLink && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-center text-sm text-gray-600", children: [
5347
+ "Don't have an account?",
5348
+ " ",
5349
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: registerLink, className: "text-blue-600 hover:text-blue-700 font-medium", children: "Sign up" })
5350
+ ] })
5351
+ ] })
5352
+ }
5353
+ ) });
5354
+ }
5355
+ var defaultInitialValues4 = {
5356
+ firstName: "",
5357
+ lastName: "",
5358
+ email: "",
5359
+ password: "",
5360
+ confirmPassword: "",
5361
+ acceptTerms: false
5362
+ };
5363
+ function RegisterForm({
5364
+ actionUrl,
5365
+ onSubmit,
5366
+ initialValues,
5367
+ termsLink = "/terms",
5368
+ privacyLink = "/privacy",
5369
+ loginLink = "/login",
5370
+ submitText = "Create Account",
5371
+ successRedirect,
5372
+ passwordRequirements = {
5373
+ minLength: 8,
5374
+ requireUppercase: true,
5375
+ requireLowercase: true,
5376
+ requireNumber: true,
5377
+ requireSpecial: false
5378
+ },
5379
+ className = "",
5380
+ formClass = "",
5381
+ inputClass = "",
5382
+ buttonClass = ""
5383
+ }) {
5384
+ const [submitStatus, setSubmitStatus] = react.useState("idle");
5385
+ const [submitMessage, setSubmitMessage] = react.useState("");
5386
+ const [showPassword, setShowPassword] = react.useState(false);
5387
+ const [showConfirmPassword, setShowConfirmPassword] = react.useState(false);
5388
+ const mergedInitialValues = {
5389
+ ...defaultInitialValues4,
5390
+ ...initialValues
5391
+ };
5392
+ const validationSchema = createRegisterFormSchema(passwordRequirements);
5393
+ const baseInputClass = "w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors";
5394
+ const baseLabelClass = "block text-sm font-medium text-gray-700 mb-1";
5395
+ const baseErrorClass = "text-sm text-red-600 mt-1";
5396
+ const baseButtonClass = "w-full px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed";
5397
+ const handleSubmit = async (values, { setSubmitting }) => {
5398
+ try {
5399
+ let result;
5400
+ if (onSubmit) {
5401
+ result = await onSubmit(values);
5402
+ } else if (actionUrl) {
5403
+ const response = await fetch(actionUrl, {
5404
+ method: "POST",
5405
+ headers: { "Content-Type": "application/json" },
5406
+ body: JSON.stringify(values)
5407
+ });
5408
+ result = await response.json();
5409
+ } else {
5410
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
5411
+ result = { success: true };
5412
+ }
5413
+ if (result.success) {
5414
+ setSubmitStatus("success");
5415
+ setSubmitMessage(result.message || "Account created successfully!");
5416
+ if (successRedirect && typeof window !== "undefined") {
5417
+ window.location.href = successRedirect;
5418
+ }
5419
+ } else {
5420
+ setSubmitStatus("error");
5421
+ setSubmitMessage(result.message || "Registration failed. Please try again.");
5422
+ }
5423
+ } catch (error) {
5424
+ setSubmitStatus("error");
5425
+ setSubmitMessage("An error occurred. Please try again later.");
5426
+ } finally {
5427
+ setSubmitting(false);
5428
+ }
5429
+ };
5430
+ if (submitStatus === "success") {
5431
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `ec-register-form ${className}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 bg-green-50 border border-green-200 rounded-lg text-center", children: [
5432
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-12 h-12 text-green-500 mx-auto mb-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
5433
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-green-800 font-medium", children: submitMessage }),
5434
+ loginLink && /* @__PURE__ */ jsxRuntime.jsx(
5435
+ "a",
5436
+ {
5437
+ href: loginLink,
5438
+ className: "inline-block mt-4 text-green-600 hover:text-green-700 font-medium",
5439
+ children: "Sign in to your account"
5440
+ }
5441
+ )
5442
+ ] }) });
5443
+ }
5444
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `ec-register-form ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx(
5445
+ formik.Formik,
5446
+ {
5447
+ initialValues: mergedInitialValues,
5448
+ validationSchema,
5449
+ onSubmit: handleSubmit,
5450
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { className: `space-y-4 ${formClass}`, noValidate: true, children: [
5451
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: [
5452
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5453
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "register-firstName", className: baseLabelClass, children: [
5454
+ "First Name ",
5455
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
5456
+ ] }),
5457
+ /* @__PURE__ */ jsxRuntime.jsx(
5458
+ formik.Field,
5459
+ {
5460
+ type: "text",
5461
+ id: "register-firstName",
5462
+ name: "firstName",
5463
+ placeholder: "John",
5464
+ autoComplete: "given-name",
5465
+ className: `${baseInputClass} ${inputClass} ${errors.firstName && touched.firstName ? "border-red-500 focus:ring-red-500" : ""}`
5466
+ }
5467
+ ),
5468
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "firstName", component: "p", className: baseErrorClass })
5469
+ ] }),
5470
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5471
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "register-lastName", className: baseLabelClass, children: [
5472
+ "Last Name ",
5473
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
5474
+ ] }),
5475
+ /* @__PURE__ */ jsxRuntime.jsx(
5476
+ formik.Field,
5477
+ {
5478
+ type: "text",
5479
+ id: "register-lastName",
5480
+ name: "lastName",
5481
+ placeholder: "Doe",
5482
+ autoComplete: "family-name",
5483
+ className: `${baseInputClass} ${inputClass} ${errors.lastName && touched.lastName ? "border-red-500 focus:ring-red-500" : ""}`
5484
+ }
5485
+ ),
5486
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "lastName", component: "p", className: baseErrorClass })
5487
+ ] })
5488
+ ] }),
5489
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5490
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "register-email", className: baseLabelClass, children: [
5491
+ "Email ",
5492
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
5493
+ ] }),
5494
+ /* @__PURE__ */ jsxRuntime.jsx(
5495
+ formik.Field,
5496
+ {
5497
+ type: "email",
5498
+ id: "register-email",
5499
+ name: "email",
5500
+ placeholder: "you@example.com",
5501
+ autoComplete: "email",
5502
+ className: `${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500 focus:ring-red-500" : ""}`
5503
+ }
5504
+ ),
5505
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "email", component: "p", className: baseErrorClass })
5506
+ ] }),
5507
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5508
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "register-password", className: baseLabelClass, children: [
5509
+ "Password ",
5510
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
5511
+ ] }),
5512
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
5513
+ /* @__PURE__ */ jsxRuntime.jsx(
5514
+ formik.Field,
5515
+ {
5516
+ type: showPassword ? "text" : "password",
5517
+ id: "register-password",
5518
+ name: "password",
5519
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
5520
+ autoComplete: "new-password",
5521
+ className: `${baseInputClass} ${inputClass} pr-12 ${errors.password && touched.password ? "border-red-500 focus:ring-red-500" : ""}`
5522
+ }
5523
+ ),
5524
+ /* @__PURE__ */ jsxRuntime.jsx(
5525
+ "button",
5526
+ {
5527
+ type: "button",
5528
+ onClick: () => setShowPassword(!showPassword),
5529
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700",
5530
+ tabIndex: -1,
5531
+ children: showPassword ? /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [
5532
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" }),
5533
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" })
5534
+ ] })
5535
+ }
5536
+ )
5537
+ ] }),
5538
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "password", component: "p", className: baseErrorClass }),
5539
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-gray-500 mt-1", children: [
5540
+ "Min ",
5541
+ passwordRequirements.minLength,
5542
+ " characters",
5543
+ passwordRequirements.requireUppercase && ", uppercase",
5544
+ passwordRequirements.requireLowercase && ", lowercase",
5545
+ passwordRequirements.requireNumber && ", number",
5546
+ passwordRequirements.requireSpecial && ", special character"
5547
+ ] })
5548
+ ] }),
5549
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5550
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "register-confirmPassword", className: baseLabelClass, children: [
5551
+ "Confirm Password ",
5552
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
5553
+ ] }),
5554
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
5555
+ /* @__PURE__ */ jsxRuntime.jsx(
5556
+ formik.Field,
5557
+ {
5558
+ type: showConfirmPassword ? "text" : "password",
5559
+ id: "register-confirmPassword",
5560
+ name: "confirmPassword",
5561
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
5562
+ autoComplete: "new-password",
5563
+ className: `${baseInputClass} ${inputClass} pr-12 ${errors.confirmPassword && touched.confirmPassword ? "border-red-500 focus:ring-red-500" : ""}`
5564
+ }
5565
+ ),
5566
+ /* @__PURE__ */ jsxRuntime.jsx(
5567
+ "button",
5568
+ {
5569
+ type: "button",
5570
+ onClick: () => setShowConfirmPassword(!showConfirmPassword),
5571
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700",
5572
+ tabIndex: -1,
5573
+ children: showConfirmPassword ? /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [
5574
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" }),
5575
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" })
5576
+ ] })
5577
+ }
5578
+ )
5579
+ ] }),
5580
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "confirmPassword", component: "p", className: baseErrorClass })
5581
+ ] }),
5582
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5583
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-start gap-2 cursor-pointer", children: [
5584
+ /* @__PURE__ */ jsxRuntime.jsx(
5585
+ formik.Field,
5586
+ {
5587
+ type: "checkbox",
5588
+ name: "acceptTerms",
5589
+ className: "w-4 h-4 mt-1 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
5590
+ }
5591
+ ),
5592
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-gray-600", children: [
5593
+ "I agree to the",
5594
+ " ",
5595
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: termsLink, className: "text-blue-600 hover:underline", target: "_blank", rel: "noopener noreferrer", children: "Terms of Service" }),
5596
+ " ",
5597
+ "and",
5598
+ " ",
5599
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: privacyLink, className: "text-blue-600 hover:underline", target: "_blank", rel: "noopener noreferrer", children: "Privacy Policy" }),
5600
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: " *" })
5601
+ ] })
5602
+ ] }),
5603
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "acceptTerms", component: "p", className: baseErrorClass })
5604
+ ] }),
5605
+ submitStatus === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 bg-red-50 border border-red-200 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-red-800 text-sm", children: submitMessage }) }),
5606
+ /* @__PURE__ */ jsxRuntime.jsx(
5607
+ "button",
5608
+ {
5609
+ type: "submit",
5610
+ disabled: isSubmitting,
5611
+ className: `${baseButtonClass} ${buttonClass}`,
5612
+ children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
5613
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
5614
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
5615
+ /* @__PURE__ */ jsxRuntime.jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
5616
+ ] }),
5617
+ "Creating account..."
5618
+ ] }) : submitText
5619
+ }
5620
+ ),
5621
+ loginLink && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-center text-sm text-gray-600", children: [
5622
+ "Already have an account?",
5623
+ " ",
5624
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: loginLink, className: "text-blue-600 hover:text-blue-700 font-medium", children: "Sign in" })
5625
+ ] })
5626
+ ] })
5627
+ }
5628
+ ) });
5629
+ }
5630
+
2999
5631
  exports.ApiUrlBuilder = ApiUrlBuilder;
3000
5632
  exports.ClientLogger = ClientLogger;
5633
+ exports.ContactForm = ContactForm;
3001
5634
  exports.EventEmitter = EventEmitter;
5635
+ exports.LoginForm = LoginForm;
5636
+ exports.NewsletterForm = NewsletterForm;
5637
+ exports.RegisterForm = RegisterForm;
5638
+ exports.ThemeContext = ThemeContext;
5639
+ exports.ThemeProvider = ThemeProvider;
5640
+ exports.ThemeToggle = ThemeToggle;
5641
+ exports.VALIDATION_MESSAGES = VALIDATION_MESSAGES;
3002
5642
  exports.addDays = addDays;
5643
+ exports.adjustColor = adjustColor;
3003
5644
  exports.appEvents = appEvents;
3004
5645
  exports.camelToKebab = camelToKebab;
3005
5646
  exports.capitalize = capitalize;
3006
5647
  exports.capitalizeWords = capitalizeWords;
3007
5648
  exports.checkPackage = checkPackage;
3008
5649
  exports.clientLogger = clientLogger;
5650
+ exports.contactFormSchema = contactFormSchema;
3009
5651
  exports.copyToClipboard = copyToClipboard;
3010
5652
  exports.createApiEndpoints = createApiEndpoints;
3011
5653
  exports.createApiUrlBuilder = createApiUrlBuilder;
@@ -3014,21 +5656,42 @@ exports.createEmptyPaginationMeta = createEmptyPaginationMeta;
3014
5656
  exports.createErrorResponse = createErrorResponse;
3015
5657
  exports.createEventEmitter = createEventEmitter;
3016
5658
  exports.createHttpClient = createHttpClient;
5659
+ exports.createRegisterFormSchema = createRegisterFormSchema;
3017
5660
  exports.createSuccessResponse = createSuccessResponse;
5661
+ exports.createTheme = createTheme;
5662
+ exports.createThemeFromBrand = createThemeFromBrand;
5663
+ exports.cssVar = cssVar;
5664
+ exports.deepMerge = deepMerge;
5665
+ exports.defaultDarkTheme = defaultDarkTheme;
5666
+ exports.defaultLightTheme = defaultLightTheme;
5667
+ exports.dummyBannerData = dummyBannerData;
5668
+ exports.dummyFaqItems = dummyFaqItems;
5669
+ exports.dummyFeatures = dummyFeatures;
5670
+ exports.dummyFooterData = dummyFooterData;
5671
+ exports.dummyHeaderData = dummyHeaderData;
5672
+ exports.dummyImage = dummyImage;
5673
+ exports.dummyPricingPlans = dummyPricingPlans;
5674
+ exports.dummyTestimonials = dummyTestimonials;
3018
5675
  exports.endOfDay = endOfDay;
5676
+ exports.flattenToCssVars = flattenToCssVars;
3019
5677
  exports.formatDate = formatDate;
3020
5678
  exports.formatDateForInput = formatDateForInput;
3021
5679
  exports.formatDateTime = formatDateTime;
3022
5680
  exports.formatDateTimeForInput = formatDateTimeForInput;
3023
5681
  exports.formatPackageCheckResult = formatPackageCheckResult;
3024
5682
  exports.formatRelativeTime = formatRelativeTime;
5683
+ exports.generateCssVars = generateCssVars;
3025
5684
  exports.generateNcuCommand = generateNcuCommand;
5685
+ exports.getContrastColor = getContrastColor;
3026
5686
  exports.getErrorMessage = getErrorMessage;
3027
5687
  exports.getNextPage = getNextPage;
3028
5688
  exports.getPrevPage = getPrevPage;
3029
5689
  exports.getResponseData = getResponseData;
5690
+ exports.getSystemColorScheme = getSystemColorScheme;
3030
5691
  exports.hasData = hasData;
3031
5692
  exports.hasMorePages = hasMorePages;
5693
+ exports.hexToRgba = hexToRgba;
5694
+ exports.injectCssVars = injectCssVars;
3032
5695
  exports.isClipboardAvailable = isClipboardAvailable;
3033
5696
  exports.isErrorResponse = isErrorResponse;
3034
5697
  exports.isForbidden = isForbidden;
@@ -3042,11 +5705,20 @@ exports.isSuccessResponse = isSuccessResponse;
3042
5705
  exports.isToday = isToday;
3043
5706
  exports.isUnauthorized = isUnauthorized;
3044
5707
  exports.kebabToCamel = kebabToCamel;
5708
+ exports.loadThemeFromUrl = loadThemeFromUrl;
5709
+ exports.loadThemeMode = loadThemeMode;
5710
+ exports.loginFormSchema = loginFormSchema;
5711
+ exports.loremIpsum = loremIpsum;
5712
+ exports.newsletterFormSchema = newsletterFormSchema;
3045
5713
  exports.packageCheck = packageCheck;
3046
5714
  exports.parseError = parseError;
3047
5715
  exports.parseFullResponse = parseFullResponse;
3048
5716
  exports.parseResponse = parseResponse;
3049
5717
  exports.readFromClipboard = readFromClipboard;
5718
+ exports.registerFormSchema = registerFormSchema;
5719
+ exports.removeCssVars = removeCssVars;
5720
+ exports.resolveThemeMode = resolveThemeMode;
5721
+ exports.saveThemeMode = saveThemeMode;
3050
5722
  exports.slugify = slugify;
3051
5723
  exports.slugifyUnique = slugifyUnique;
3052
5724
  exports.startOfDay = startOfDay;
@@ -3104,7 +5776,9 @@ exports.useScript = useScript_default;
3104
5776
  exports.useSessionStorage = useSessionStorage_default;
3105
5777
  exports.useSet = useSet_default;
3106
5778
  exports.useSnackbar = useSnackbar_default;
5779
+ exports.useTheme = useTheme;
3107
5780
  exports.useThemeDetector = useThemeDetector_default;
5781
+ exports.useThemeValue = useThemeValue;
3108
5782
  exports.useThrottle = useThrottle_default;
3109
5783
  exports.useTimeout = useTimeout_default;
3110
5784
  exports.useToggle = useToggle_default;