@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.
package/dist/index.mjs CHANGED
@@ -5,7 +5,10 @@ import mongoose from 'mongoose';
5
5
  import jwt from 'jsonwebtoken';
6
6
  import { existsSync, readFileSync } from 'fs';
7
7
  import axios from 'axios';
8
- import { useState, useCallback, useMemo, useRef, useEffect } from 'react';
8
+ import { createContext, useState, useCallback, useMemo, useRef, useEffect, useContext } from 'react';
9
+ import { jsx, jsxs } from 'react/jsx-runtime';
10
+ import * as Yup from 'yup';
11
+ import { Formik, Form, Field, ErrorMessage } from 'formik';
9
12
  import { subYears, subWeeks, subMonths, subMinutes, subHours, subDays, startOfYear, startOfWeek, startOfMonth, startOfDay as startOfDay$1, setSeconds, setMinutes, setHours, parseISO, isYesterday, isValid, isTomorrow, isToday as isToday$1, isThisYear, isThisWeek, isThisMonth, isSameYear, isSameWeek, isSameMonth, isSameDay, isPast as isPast$1, isFuture as isFuture$1, isEqual, isBefore, isAfter, intervalToDuration, getYear, getSeconds, getMonth, getMinutes, getHours, getDay, getDate, formatRelative, formatDuration, formatDistanceToNow, formatDistance, format, endOfYear, endOfWeek, endOfMonth, endOfDay as endOfDay$1, eachWeekOfInterval, eachMonthOfInterval, eachDayOfInterval, differenceInYears, differenceInWeeks, differenceInSeconds, differenceInMonths, differenceInMinutes, differenceInHours, differenceInDays, addYears, addWeeks, addMonths, addMinutes, addHours, addDays as addDays$1 } from 'date-fns';
10
13
  import { toZonedTime, fromZonedTime, formatInTimeZone } from 'date-fns-tz';
11
14
 
@@ -772,14 +775,24 @@ var client_exports = {};
772
775
  __export(client_exports, {
773
776
  ApiUrlBuilder: () => ApiUrlBuilder,
774
777
  ClientLogger: () => ClientLogger,
778
+ ContactForm: () => ContactForm,
775
779
  EventEmitter: () => EventEmitter,
780
+ LoginForm: () => LoginForm,
781
+ NewsletterForm: () => NewsletterForm,
782
+ RegisterForm: () => RegisterForm,
783
+ ThemeContext: () => ThemeContext,
784
+ ThemeProvider: () => ThemeProvider,
785
+ ThemeToggle: () => ThemeToggle,
786
+ VALIDATION_MESSAGES: () => VALIDATION_MESSAGES,
776
787
  addDays: () => addDays,
788
+ adjustColor: () => adjustColor,
777
789
  appEvents: () => appEvents,
778
790
  camelToKebab: () => camelToKebab,
779
791
  capitalize: () => capitalize,
780
792
  capitalizeWords: () => capitalizeWords,
781
793
  checkPackage: () => checkPackage,
782
794
  clientLogger: () => clientLogger,
795
+ contactFormSchema: () => contactFormSchema,
783
796
  copyToClipboard: () => copyToClipboard,
784
797
  createApiEndpoints: () => createApiEndpoints,
785
798
  createApiUrlBuilder: () => createApiUrlBuilder,
@@ -788,21 +801,42 @@ __export(client_exports, {
788
801
  createErrorResponse: () => createErrorResponse,
789
802
  createEventEmitter: () => createEventEmitter,
790
803
  createHttpClient: () => createHttpClient,
804
+ createRegisterFormSchema: () => createRegisterFormSchema,
791
805
  createSuccessResponse: () => createSuccessResponse,
806
+ createTheme: () => createTheme,
807
+ createThemeFromBrand: () => createThemeFromBrand,
808
+ cssVar: () => cssVar,
809
+ deepMerge: () => deepMerge,
810
+ defaultDarkTheme: () => defaultDarkTheme,
811
+ defaultLightTheme: () => defaultLightTheme,
812
+ dummyBannerData: () => dummyBannerData,
813
+ dummyFaqItems: () => dummyFaqItems,
814
+ dummyFeatures: () => dummyFeatures,
815
+ dummyFooterData: () => dummyFooterData,
816
+ dummyHeaderData: () => dummyHeaderData,
817
+ dummyImage: () => dummyImage,
818
+ dummyPricingPlans: () => dummyPricingPlans,
819
+ dummyTestimonials: () => dummyTestimonials,
792
820
  endOfDay: () => endOfDay,
821
+ flattenToCssVars: () => flattenToCssVars,
793
822
  formatDate: () => formatDate,
794
823
  formatDateForInput: () => formatDateForInput,
795
824
  formatDateTime: () => formatDateTime,
796
825
  formatDateTimeForInput: () => formatDateTimeForInput,
797
826
  formatPackageCheckResult: () => formatPackageCheckResult2,
798
827
  formatRelativeTime: () => formatRelativeTime,
828
+ generateCssVars: () => generateCssVars,
799
829
  generateNcuCommand: () => generateNcuCommand2,
830
+ getContrastColor: () => getContrastColor,
800
831
  getErrorMessage: () => getErrorMessage,
801
832
  getNextPage: () => getNextPage,
802
833
  getPrevPage: () => getPrevPage,
803
834
  getResponseData: () => getResponseData,
835
+ getSystemColorScheme: () => getSystemColorScheme,
804
836
  hasData: () => hasData,
805
837
  hasMorePages: () => hasMorePages,
838
+ hexToRgba: () => hexToRgba,
839
+ injectCssVars: () => injectCssVars,
806
840
  isClipboardAvailable: () => isClipboardAvailable,
807
841
  isErrorResponse: () => isErrorResponse,
808
842
  isForbidden: () => isForbidden,
@@ -816,11 +850,20 @@ __export(client_exports, {
816
850
  isToday: () => isToday,
817
851
  isUnauthorized: () => isUnauthorized,
818
852
  kebabToCamel: () => kebabToCamel,
853
+ loadThemeFromUrl: () => loadThemeFromUrl,
854
+ loadThemeMode: () => loadThemeMode,
855
+ loginFormSchema: () => loginFormSchema,
856
+ loremIpsum: () => loremIpsum,
857
+ newsletterFormSchema: () => newsletterFormSchema,
819
858
  packageCheck: () => packageCheck,
820
859
  parseError: () => parseError,
821
860
  parseFullResponse: () => parseFullResponse,
822
861
  parseResponse: () => parseResponse,
823
862
  readFromClipboard: () => readFromClipboard,
863
+ registerFormSchema: () => registerFormSchema,
864
+ removeCssVars: () => removeCssVars,
865
+ resolveThemeMode: () => resolveThemeMode,
866
+ saveThemeMode: () => saveThemeMode,
824
867
  slugify: () => slugify,
825
868
  slugifyUnique: () => slugifyUnique,
826
869
  startOfDay: () => startOfDay,
@@ -878,7 +921,9 @@ __export(client_exports, {
878
921
  useSessionStorage: () => useSessionStorage_default,
879
922
  useSet: () => useSet_default,
880
923
  useSnackbar: () => useSnackbar_default,
924
+ useTheme: () => useTheme,
881
925
  useThemeDetector: () => useThemeDetector_default,
926
+ useThemeValue: () => useThemeValue,
882
927
  useThrottle: () => useThrottle_default,
883
928
  useTimeout: () => useTimeout_default,
884
929
  useToggle: () => useToggle_default,
@@ -1717,11 +1762,11 @@ function useDefault(initialValue, defaultValue) {
1717
1762
  }
1718
1763
  var useDefault_default = useDefault;
1719
1764
  function usePrevious(value, initialValue) {
1720
- const ref = useRef(initialValue);
1765
+ const ref2 = useRef(initialValue);
1721
1766
  useEffect(() => {
1722
- ref.current = value;
1767
+ ref2.current = value;
1723
1768
  }, [value]);
1724
- return ref.current;
1769
+ return ref2.current;
1725
1770
  }
1726
1771
  var usePrevious_default = usePrevious;
1727
1772
  function useObjectState(initialState) {
@@ -2647,7 +2692,7 @@ function useKeyPress(targetKey, callback, options = {}) {
2647
2692
  var useKeyPress_default = useKeyPress;
2648
2693
  function useHover(onHoverChange) {
2649
2694
  const [isHovered, setIsHovered] = useState(false);
2650
- const ref = useRef(null);
2695
+ const ref2 = useRef(null);
2651
2696
  const onMouseEnter = useCallback(() => {
2652
2697
  setIsHovered(true);
2653
2698
  onHoverChange?.(true);
@@ -2657,7 +2702,7 @@ function useHover(onHoverChange) {
2657
2702
  onHoverChange?.(false);
2658
2703
  }, [onHoverChange]);
2659
2704
  return {
2660
- ref,
2705
+ ref: ref2,
2661
2706
  isHovered,
2662
2707
  bind: {
2663
2708
  onMouseEnter,
@@ -2667,13 +2712,13 @@ function useHover(onHoverChange) {
2667
2712
  }
2668
2713
  var useHover_default = useHover;
2669
2714
  function useClickAway(callback, events = ["mousedown", "touchstart"]) {
2670
- const ref = useRef(null);
2715
+ const ref2 = useRef(null);
2671
2716
  const savedCallback = useRef(callback);
2672
2717
  useEffect(() => {
2673
2718
  savedCallback.current = callback;
2674
2719
  }, [callback]);
2675
2720
  const handleClickAway = useCallback((event) => {
2676
- const el = ref.current;
2721
+ const el = ref2.current;
2677
2722
  if (!el || el.contains(event.target)) {
2678
2723
  return;
2679
2724
  }
@@ -2690,14 +2735,14 @@ function useClickAway(callback, events = ["mousedown", "touchstart"]) {
2690
2735
  });
2691
2736
  };
2692
2737
  }, [events, handleClickAway]);
2693
- return ref;
2738
+ return ref2;
2694
2739
  }
2695
2740
  var useClickAway_default = useClickAway;
2696
- function useOnClickOutside(ref, handler, enabled = true) {
2741
+ function useOnClickOutside(ref2, handler, enabled = true) {
2697
2742
  useEffect(() => {
2698
2743
  if (!enabled) return;
2699
2744
  const listener = (event) => {
2700
- const el = ref?.current;
2745
+ const el = ref2?.current;
2701
2746
  if (!el || el.contains(event.target)) {
2702
2747
  return;
2703
2748
  }
@@ -2709,7 +2754,7 @@ function useOnClickOutside(ref, handler, enabled = true) {
2709
2754
  document.removeEventListener("mousedown", listener);
2710
2755
  document.removeEventListener("touchstart", listener);
2711
2756
  };
2712
- }, [ref, handler, enabled]);
2757
+ }, [ref2, handler, enabled]);
2713
2758
  }
2714
2759
  var useOnClickOutside_default = useOnClickOutside;
2715
2760
  function useLongPress(options = {}) {
@@ -2782,7 +2827,7 @@ function useLongPress(options = {}) {
2782
2827
  var useLongPress_default = useLongPress;
2783
2828
  function useMouse(options = {}) {
2784
2829
  const { enabled = true } = options;
2785
- const ref = useRef(null);
2830
+ const ref2 = useRef(null);
2786
2831
  const [position, setPosition] = useState({
2787
2832
  x: 0,
2788
2833
  y: 0,
@@ -2796,8 +2841,8 @@ function useMouse(options = {}) {
2796
2841
  let elementX = 0;
2797
2842
  let elementY = 0;
2798
2843
  let isInElement = false;
2799
- if (ref.current) {
2800
- const rect = ref.current.getBoundingClientRect();
2844
+ if (ref2.current) {
2845
+ const rect = ref2.current.getBoundingClientRect();
2801
2846
  elementX = event.clientX - rect.left;
2802
2847
  elementY = event.clientY - rect.top;
2803
2848
  isInElement = elementX >= 0 && elementX <= rect.width && elementY >= 0 && elementY <= rect.height;
@@ -2820,7 +2865,7 @@ function useMouse(options = {}) {
2820
2865
  };
2821
2866
  }, [enabled, handleMouseMove]);
2822
2867
  return {
2823
- ref,
2868
+ ref: ref2,
2824
2869
  ...position
2825
2870
  };
2826
2871
  }
@@ -3732,7 +3777,7 @@ function useMeasure() {
3732
3777
  y: rect.y
3733
3778
  });
3734
3779
  }, []);
3735
- const ref = useCallback((node) => {
3780
+ const ref2 = useCallback((node) => {
3736
3781
  if (observerRef.current) {
3737
3782
  observerRef.current.disconnect();
3738
3783
  observerRef.current = null;
@@ -3779,7 +3824,7 @@ function useMeasure() {
3779
3824
  }
3780
3825
  };
3781
3826
  }, []);
3782
- return { ref, dimensions, measure };
3827
+ return { ref: ref2, dimensions, measure };
3783
3828
  }
3784
3829
  var useMeasure_default = useMeasure;
3785
3830
  function useIntersectionObserver(options = {}) {
@@ -3796,7 +3841,7 @@ function useIntersectionObserver(options = {}) {
3796
3841
  const elementRef = useRef(null);
3797
3842
  const observerRef = useRef(null);
3798
3843
  const frozen = useRef(false);
3799
- const ref = useCallback(
3844
+ const ref2 = useCallback(
3800
3845
  (node) => {
3801
3846
  if (observerRef.current) {
3802
3847
  observerRef.current.disconnect();
@@ -3832,7 +3877,7 @@ function useIntersectionObserver(options = {}) {
3832
3877
  }
3833
3878
  };
3834
3879
  }, []);
3835
- return { ref, isIntersecting, entry };
3880
+ return { ref: ref2, isIntersecting, entry };
3836
3881
  }
3837
3882
  var useIntersectionObserver_default = useIntersectionObserver;
3838
3883
  var DEFAULT_DURATION = 4e3;
@@ -3877,6 +3922,2616 @@ function useSnackbar(defaultDuration = DEFAULT_DURATION) {
3877
3922
  }
3878
3923
  var useSnackbar_default = useSnackbar;
3879
3924
 
3925
+ // src/client/web/theme/default-light-theme.ts
3926
+ var defaultLightTheme = {
3927
+ name: "default-light",
3928
+ mode: "light",
3929
+ colors: {
3930
+ brand: {
3931
+ primary: "#3b82f6",
3932
+ secondary: "#6366f1",
3933
+ accent: "#f59e0b",
3934
+ background: "#ffffff",
3935
+ foreground: "#111827"
3936
+ },
3937
+ semantic: {
3938
+ primary: "#3b82f6",
3939
+ primaryHover: "#2563eb",
3940
+ primaryActive: "#1d4ed8",
3941
+ primaryDisabled: "#93c5fd",
3942
+ secondary: "#6366f1",
3943
+ secondaryHover: "#4f46e5",
3944
+ secondaryActive: "#4338ca",
3945
+ secondaryDisabled: "#a5b4fc",
3946
+ accent: "#f59e0b",
3947
+ accentHover: "#d97706",
3948
+ success: "#22c55e",
3949
+ successHover: "#16a34a",
3950
+ warning: "#f59e0b",
3951
+ warningHover: "#d97706",
3952
+ error: "#ef4444",
3953
+ errorHover: "#dc2626",
3954
+ info: "#3b82f6",
3955
+ infoHover: "#2563eb"
3956
+ },
3957
+ background: {
3958
+ default: "#ffffff",
3959
+ paper: "#f9fafb",
3960
+ card: "#ffffff",
3961
+ overlay: "rgba(0, 0, 0, 0.5)",
3962
+ input: "#ffffff",
3963
+ disabled: "#f3f4f6",
3964
+ hover: "#f3f4f6",
3965
+ selected: "#eff6ff"
3966
+ },
3967
+ surface: {
3968
+ light: "#f9fafb",
3969
+ main: "#f3f4f6",
3970
+ dark: "#e5e7eb"
3971
+ },
3972
+ text: {
3973
+ primary: "#111827",
3974
+ secondary: "#6b7280",
3975
+ disabled: "#9ca3af",
3976
+ placeholder: "#9ca3af",
3977
+ link: "#3b82f6",
3978
+ linkHover: "#2563eb",
3979
+ inverse: "#ffffff",
3980
+ onPrimary: "#ffffff",
3981
+ onSecondary: "#ffffff"
3982
+ },
3983
+ border: {
3984
+ default: "#e5e7eb",
3985
+ light: "#f3f4f6",
3986
+ dark: "#d1d5db",
3987
+ focus: "#3b82f6",
3988
+ error: "#ef4444",
3989
+ success: "#22c55e",
3990
+ disabled: "#e5e7eb"
3991
+ }
3992
+ },
3993
+ shadows: {
3994
+ none: "none",
3995
+ xs: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
3996
+ sm: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
3997
+ md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
3998
+ lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
3999
+ xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)",
4000
+ "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)",
4001
+ inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)",
4002
+ button: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
4003
+ buttonHover: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
4004
+ card: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
4005
+ cardHover: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
4006
+ modal: "0 25px 50px -12px rgb(0 0 0 / 0.25)",
4007
+ dropdown: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)"
4008
+ },
4009
+ typography: {
4010
+ fontFamily: {
4011
+ sans: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
4012
+ serif: 'ui-serif, Georgia, Cambria, "Times New Roman", Times, serif',
4013
+ mono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace',
4014
+ heading: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
4015
+ body: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
4016
+ },
4017
+ fontSize: {
4018
+ xs: "0.75rem",
4019
+ sm: "0.875rem",
4020
+ base: "1rem",
4021
+ lg: "1.125rem",
4022
+ xl: "1.25rem",
4023
+ "2xl": "1.5rem",
4024
+ "3xl": "1.875rem",
4025
+ "4xl": "2.25rem",
4026
+ "5xl": "3rem",
4027
+ "6xl": "3.75rem"
4028
+ },
4029
+ fontWeight: {
4030
+ light: 300,
4031
+ normal: 400,
4032
+ medium: 500,
4033
+ semibold: 600,
4034
+ bold: 700,
4035
+ extrabold: 800
4036
+ },
4037
+ lineHeight: {
4038
+ none: 1,
4039
+ tight: 1.25,
4040
+ snug: 1.375,
4041
+ normal: 1.5,
4042
+ relaxed: 1.625,
4043
+ loose: 2
4044
+ }
4045
+ },
4046
+ spacing: {
4047
+ 0: "0",
4048
+ px: "1px",
4049
+ 0.5: "0.125rem",
4050
+ 1: "0.25rem",
4051
+ 1.5: "0.375rem",
4052
+ 2: "0.5rem",
4053
+ 2.5: "0.625rem",
4054
+ 3: "0.75rem",
4055
+ 3.5: "0.875rem",
4056
+ 4: "1rem",
4057
+ 5: "1.25rem",
4058
+ 6: "1.5rem",
4059
+ 7: "1.75rem",
4060
+ 8: "2rem",
4061
+ 9: "2.25rem",
4062
+ 10: "2.5rem",
4063
+ 11: "2.75rem",
4064
+ 12: "3rem",
4065
+ 14: "3.5rem",
4066
+ 16: "4rem",
4067
+ 20: "5rem",
4068
+ 24: "6rem",
4069
+ 28: "7rem",
4070
+ 32: "8rem",
4071
+ 36: "9rem",
4072
+ 40: "10rem",
4073
+ 44: "11rem",
4074
+ 48: "12rem",
4075
+ 52: "13rem",
4076
+ 56: "14rem",
4077
+ 60: "15rem",
4078
+ 64: "16rem",
4079
+ 72: "18rem",
4080
+ 80: "20rem",
4081
+ 96: "24rem"
4082
+ },
4083
+ borderRadius: {
4084
+ none: "0",
4085
+ sm: "0.125rem",
4086
+ default: "0.25rem",
4087
+ md: "0.375rem",
4088
+ lg: "0.5rem",
4089
+ xl: "0.75rem",
4090
+ "2xl": "1rem",
4091
+ "3xl": "1.5rem",
4092
+ full: "9999px"
4093
+ },
4094
+ breakpoints: {
4095
+ xs: "475px",
4096
+ sm: "640px",
4097
+ md: "768px",
4098
+ lg: "1024px",
4099
+ xl: "1280px",
4100
+ "2xl": "1536px"
4101
+ },
4102
+ zIndex: {
4103
+ hide: -1,
4104
+ auto: "auto",
4105
+ base: 0,
4106
+ dropdown: 1e3,
4107
+ sticky: 1020,
4108
+ fixed: 1030,
4109
+ modalBackdrop: 1040,
4110
+ modal: 1050,
4111
+ popover: 1060,
4112
+ tooltip: 1070,
4113
+ toast: 1080
4114
+ },
4115
+ transitions: {
4116
+ none: "none",
4117
+ fast: "150ms ease-in-out",
4118
+ normal: "200ms ease-in-out",
4119
+ slow: "300ms ease-in-out",
4120
+ slower: "500ms ease-in-out",
4121
+ colors: "color 200ms ease-in-out, background-color 200ms ease-in-out, border-color 200ms ease-in-out",
4122
+ transform: "transform 200ms ease-in-out",
4123
+ opacity: "opacity 200ms ease-in-out",
4124
+ shadow: "box-shadow 200ms ease-in-out",
4125
+ all: "all 200ms ease-in-out"
4126
+ },
4127
+ components: {
4128
+ button: {
4129
+ bg: "#3b82f6",
4130
+ bgHover: "#2563eb",
4131
+ bgActive: "#1d4ed8",
4132
+ bgDisabled: "#93c5fd",
4133
+ color: "#ffffff",
4134
+ colorHover: "#ffffff",
4135
+ colorDisabled: "#ffffff",
4136
+ border: "transparent",
4137
+ borderHover: "transparent",
4138
+ borderWidth: "1px",
4139
+ borderRadius: "0.375rem",
4140
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
4141
+ shadowHover: "0 4px 6px -1px rgb(0 0 0 / 0.1)",
4142
+ paddingX: "1rem",
4143
+ paddingY: "0.5rem",
4144
+ fontSize: "0.875rem",
4145
+ fontWeight: 500,
4146
+ variants: {
4147
+ primary: {
4148
+ bg: "#3b82f6",
4149
+ bgHover: "#2563eb",
4150
+ color: "#ffffff"
4151
+ },
4152
+ secondary: {
4153
+ bg: "#6366f1",
4154
+ bgHover: "#4f46e5",
4155
+ color: "#ffffff"
4156
+ },
4157
+ outline: {
4158
+ bg: "transparent",
4159
+ bgHover: "#f3f4f6",
4160
+ color: "#374151",
4161
+ border: "#d1d5db",
4162
+ borderHover: "#9ca3af"
4163
+ },
4164
+ ghost: {
4165
+ bg: "transparent",
4166
+ bgHover: "#f3f4f6",
4167
+ color: "#374151",
4168
+ shadow: "none",
4169
+ shadowHover: "none"
4170
+ },
4171
+ link: {
4172
+ bg: "transparent",
4173
+ bgHover: "transparent",
4174
+ color: "#3b82f6",
4175
+ colorHover: "#2563eb",
4176
+ shadow: "none",
4177
+ shadowHover: "none",
4178
+ paddingX: "0",
4179
+ paddingY: "0"
4180
+ },
4181
+ danger: {
4182
+ bg: "#ef4444",
4183
+ bgHover: "#dc2626",
4184
+ color: "#ffffff"
4185
+ },
4186
+ success: {
4187
+ bg: "#22c55e",
4188
+ bgHover: "#16a34a",
4189
+ color: "#ffffff"
4190
+ }
4191
+ },
4192
+ sizes: {
4193
+ xs: {
4194
+ paddingX: "0.5rem",
4195
+ paddingY: "0.25rem",
4196
+ fontSize: "0.75rem"
4197
+ },
4198
+ sm: {
4199
+ paddingX: "0.75rem",
4200
+ paddingY: "0.375rem",
4201
+ fontSize: "0.875rem"
4202
+ },
4203
+ md: {
4204
+ paddingX: "1rem",
4205
+ paddingY: "0.5rem",
4206
+ fontSize: "0.875rem"
4207
+ },
4208
+ lg: {
4209
+ paddingX: "1.25rem",
4210
+ paddingY: "0.625rem",
4211
+ fontSize: "1rem"
4212
+ },
4213
+ xl: {
4214
+ paddingX: "1.5rem",
4215
+ paddingY: "0.75rem",
4216
+ fontSize: "1.125rem"
4217
+ }
4218
+ }
4219
+ },
4220
+ input: {
4221
+ bg: "#ffffff",
4222
+ bgFocus: "#ffffff",
4223
+ bgDisabled: "#f3f4f6",
4224
+ bgError: "#fef2f2",
4225
+ color: "#111827",
4226
+ colorPlaceholder: "#9ca3af",
4227
+ colorDisabled: "#9ca3af",
4228
+ border: "#d1d5db",
4229
+ borderFocus: "#3b82f6",
4230
+ borderError: "#ef4444",
4231
+ borderWidth: "1px",
4232
+ borderRadius: "0.375rem",
4233
+ shadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
4234
+ shadowFocus: "0 0 0 3px rgb(59 130 246 / 0.1)",
4235
+ paddingX: "0.75rem",
4236
+ paddingY: "0.5rem",
4237
+ fontSize: "0.875rem",
4238
+ labelColor: "#374151",
4239
+ labelFontSize: "0.875rem",
4240
+ labelFontWeight: 500,
4241
+ helperColor: "#6b7280",
4242
+ errorColor: "#ef4444",
4243
+ sizes: {
4244
+ sm: {
4245
+ paddingX: "0.5rem",
4246
+ paddingY: "0.375rem",
4247
+ fontSize: "0.75rem"
4248
+ },
4249
+ md: {
4250
+ paddingX: "0.75rem",
4251
+ paddingY: "0.5rem",
4252
+ fontSize: "0.875rem"
4253
+ },
4254
+ lg: {
4255
+ paddingX: "1rem",
4256
+ paddingY: "0.625rem",
4257
+ fontSize: "1rem"
4258
+ }
4259
+ }
4260
+ },
4261
+ card: {
4262
+ bg: "#ffffff",
4263
+ bgHover: "#ffffff",
4264
+ border: "#e5e7eb",
4265
+ borderWidth: "1px",
4266
+ borderRadius: "0.5rem",
4267
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
4268
+ shadowHover: "0 10px 15px -3px rgb(0 0 0 / 0.1)",
4269
+ padding: "1.5rem",
4270
+ headerBg: "#f9fafb",
4271
+ headerBorder: "#e5e7eb",
4272
+ headerPadding: "1rem 1.5rem",
4273
+ footerBg: "#f9fafb",
4274
+ footerBorder: "#e5e7eb",
4275
+ footerPadding: "1rem 1.5rem"
4276
+ },
4277
+ header: {
4278
+ bg: "#ffffff",
4279
+ bgScrolled: "rgba(255, 255, 255, 0.95)",
4280
+ color: "#111827",
4281
+ border: "#e5e7eb",
4282
+ shadow: "none",
4283
+ shadowScrolled: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
4284
+ height: "4rem",
4285
+ paddingX: "1.5rem",
4286
+ logoHeight: "2rem",
4287
+ navColor: "#374151",
4288
+ navColorHover: "#111827",
4289
+ navColorActive: "#3b82f6",
4290
+ navFontSize: "0.875rem",
4291
+ navFontWeight: 500,
4292
+ mobileMenuBg: "#ffffff",
4293
+ mobileMenuShadow: "0 10px 15px -3px rgb(0 0 0 / 0.1)"
4294
+ },
4295
+ footer: {
4296
+ bg: "#111827",
4297
+ color: "#d1d5db",
4298
+ colorMuted: "#9ca3af",
4299
+ border: "#374151",
4300
+ padding: "4rem 1.5rem",
4301
+ linkColor: "#d1d5db",
4302
+ linkColorHover: "#ffffff",
4303
+ headingColor: "#ffffff",
4304
+ headingFontSize: "1rem",
4305
+ headingFontWeight: 600,
4306
+ copyrightBg: "#0f172a",
4307
+ copyrightColor: "#9ca3af"
4308
+ },
4309
+ banner: {
4310
+ bg: "#eff6ff",
4311
+ color: "#1e40af",
4312
+ border: "#bfdbfe",
4313
+ borderRadius: "0.5rem",
4314
+ padding: "1rem 1.5rem",
4315
+ shadow: "none",
4316
+ closeBg: "transparent",
4317
+ closeColor: "#1e40af",
4318
+ variants: {
4319
+ info: {
4320
+ bg: "#eff6ff",
4321
+ color: "#1e40af",
4322
+ border: "#bfdbfe"
4323
+ },
4324
+ success: {
4325
+ bg: "#f0fdf4",
4326
+ color: "#166534",
4327
+ border: "#bbf7d0"
4328
+ },
4329
+ warning: {
4330
+ bg: "#fffbeb",
4331
+ color: "#92400e",
4332
+ border: "#fde68a"
4333
+ },
4334
+ error: {
4335
+ bg: "#fef2f2",
4336
+ color: "#991b1b",
4337
+ border: "#fecaca"
4338
+ },
4339
+ promo: {
4340
+ bg: "#faf5ff",
4341
+ color: "#6b21a8",
4342
+ border: "#e9d5ff"
4343
+ }
4344
+ }
4345
+ },
4346
+ loader: {
4347
+ color: "#3b82f6",
4348
+ colorSecondary: "#e5e7eb",
4349
+ size: "2.5rem",
4350
+ borderWidth: "3px",
4351
+ overlayBg: "rgba(255, 255, 255, 0.8)",
4352
+ overlayOpacity: 1,
4353
+ sizes: {
4354
+ xs: "1rem",
4355
+ sm: "1.5rem",
4356
+ md: "2.5rem",
4357
+ lg: "3.5rem",
4358
+ xl: "5rem"
4359
+ }
4360
+ },
4361
+ modal: {
4362
+ bg: "#ffffff",
4363
+ color: "#111827",
4364
+ border: "#e5e7eb",
4365
+ borderRadius: "0.5rem",
4366
+ shadow: "0 25px 50px -12px rgb(0 0 0 / 0.25)",
4367
+ padding: "1.5rem",
4368
+ overlayBg: "rgba(0, 0, 0, 0.5)",
4369
+ overlayOpacity: 1,
4370
+ headerBg: "#ffffff",
4371
+ headerBorder: "#e5e7eb",
4372
+ headerPadding: "1rem 1.5rem",
4373
+ footerBg: "#f9fafb",
4374
+ footerBorder: "#e5e7eb",
4375
+ footerPadding: "1rem 1.5rem",
4376
+ closeBg: "transparent",
4377
+ closeColor: "#6b7280",
4378
+ closeHoverBg: "#f3f4f6",
4379
+ sizes: {
4380
+ sm: "24rem",
4381
+ md: "32rem",
4382
+ lg: "48rem",
4383
+ xl: "64rem",
4384
+ full: "100%"
4385
+ }
4386
+ },
4387
+ toast: {
4388
+ bg: "#ffffff",
4389
+ color: "#111827",
4390
+ border: "#e5e7eb",
4391
+ borderRadius: "0.5rem",
4392
+ shadow: "0 10px 15px -3px rgb(0 0 0 / 0.1)",
4393
+ padding: "1rem",
4394
+ variants: {
4395
+ success: {
4396
+ bg: "#f0fdf4",
4397
+ color: "#166534",
4398
+ border: "#bbf7d0"
4399
+ },
4400
+ error: {
4401
+ bg: "#fef2f2",
4402
+ color: "#991b1b",
4403
+ border: "#fecaca"
4404
+ },
4405
+ warning: {
4406
+ bg: "#fffbeb",
4407
+ color: "#92400e",
4408
+ border: "#fde68a"
4409
+ },
4410
+ info: {
4411
+ bg: "#eff6ff",
4412
+ color: "#1e40af",
4413
+ border: "#bfdbfe"
4414
+ }
4415
+ }
4416
+ },
4417
+ newsletter: {
4418
+ bg: "#f9fafb",
4419
+ color: "#111827",
4420
+ border: "#e5e7eb",
4421
+ borderRadius: "0.5rem",
4422
+ padding: "2rem",
4423
+ titleColor: "#111827",
4424
+ titleFontSize: "1.5rem",
4425
+ descColor: "#6b7280",
4426
+ descFontSize: "1rem",
4427
+ inputBg: "#ffffff",
4428
+ inputBorder: "#d1d5db",
4429
+ buttonBg: "#3b82f6",
4430
+ buttonColor: "#ffffff"
4431
+ }
4432
+ }
4433
+ };
4434
+
4435
+ // src/client/web/theme/default-dark-theme.ts
4436
+ var defaultDarkTheme = {
4437
+ name: "default-dark",
4438
+ mode: "dark",
4439
+ colors: {
4440
+ brand: {
4441
+ primary: "#60a5fa",
4442
+ secondary: "#818cf8",
4443
+ accent: "#fbbf24",
4444
+ background: "#0f172a",
4445
+ foreground: "#f8fafc"
4446
+ },
4447
+ semantic: {
4448
+ primary: "#60a5fa",
4449
+ primaryHover: "#3b82f6",
4450
+ primaryActive: "#2563eb",
4451
+ primaryDisabled: "#1e3a5f",
4452
+ secondary: "#818cf8",
4453
+ secondaryHover: "#6366f1",
4454
+ secondaryActive: "#4f46e5",
4455
+ secondaryDisabled: "#312e81",
4456
+ accent: "#fbbf24",
4457
+ accentHover: "#f59e0b",
4458
+ success: "#4ade80",
4459
+ successHover: "#22c55e",
4460
+ warning: "#fbbf24",
4461
+ warningHover: "#f59e0b",
4462
+ error: "#f87171",
4463
+ errorHover: "#ef4444",
4464
+ info: "#60a5fa",
4465
+ infoHover: "#3b82f6"
4466
+ },
4467
+ background: {
4468
+ default: "#0f172a",
4469
+ paper: "#1e293b",
4470
+ card: "#1e293b",
4471
+ overlay: "rgba(0, 0, 0, 0.7)",
4472
+ input: "#1e293b",
4473
+ disabled: "#334155",
4474
+ hover: "#334155",
4475
+ selected: "#1e3a5f"
4476
+ },
4477
+ surface: {
4478
+ light: "#334155",
4479
+ main: "#1e293b",
4480
+ dark: "#0f172a"
4481
+ },
4482
+ text: {
4483
+ primary: "#f8fafc",
4484
+ secondary: "#94a3b8",
4485
+ disabled: "#64748b",
4486
+ placeholder: "#64748b",
4487
+ link: "#60a5fa",
4488
+ linkHover: "#3b82f6",
4489
+ inverse: "#0f172a",
4490
+ onPrimary: "#0f172a",
4491
+ onSecondary: "#0f172a"
4492
+ },
4493
+ border: {
4494
+ default: "#334155",
4495
+ light: "#475569",
4496
+ dark: "#1e293b",
4497
+ focus: "#60a5fa",
4498
+ error: "#f87171",
4499
+ success: "#4ade80",
4500
+ disabled: "#334155"
4501
+ }
4502
+ },
4503
+ shadows: {
4504
+ none: "none",
4505
+ xs: "0 1px 2px 0 rgb(0 0 0 / 0.3)",
4506
+ sm: "0 1px 3px 0 rgb(0 0 0 / 0.4), 0 1px 2px -1px rgb(0 0 0 / 0.4)",
4507
+ md: "0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.4)",
4508
+ lg: "0 10px 15px -3px rgb(0 0 0 / 0.4), 0 4px 6px -4px rgb(0 0 0 / 0.4)",
4509
+ xl: "0 20px 25px -5px rgb(0 0 0 / 0.4), 0 8px 10px -6px rgb(0 0 0 / 0.4)",
4510
+ "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.6)",
4511
+ inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.3)",
4512
+ button: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
4513
+ buttonHover: "0 4px 6px -1px rgb(0 0 0 / 0.4)",
4514
+ card: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
4515
+ cardHover: "0 10px 15px -3px rgb(0 0 0 / 0.4)",
4516
+ modal: "0 25px 50px -12px rgb(0 0 0 / 0.6)",
4517
+ dropdown: "0 10px 15px -3px rgb(0 0 0 / 0.4)"
4518
+ },
4519
+ typography: {
4520
+ fontFamily: {
4521
+ sans: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
4522
+ serif: 'ui-serif, Georgia, Cambria, "Times New Roman", Times, serif',
4523
+ mono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace',
4524
+ heading: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
4525
+ body: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
4526
+ },
4527
+ fontSize: {
4528
+ xs: "0.75rem",
4529
+ sm: "0.875rem",
4530
+ base: "1rem",
4531
+ lg: "1.125rem",
4532
+ xl: "1.25rem",
4533
+ "2xl": "1.5rem",
4534
+ "3xl": "1.875rem",
4535
+ "4xl": "2.25rem",
4536
+ "5xl": "3rem",
4537
+ "6xl": "3.75rem"
4538
+ },
4539
+ fontWeight: {
4540
+ light: 300,
4541
+ normal: 400,
4542
+ medium: 500,
4543
+ semibold: 600,
4544
+ bold: 700,
4545
+ extrabold: 800
4546
+ },
4547
+ lineHeight: {
4548
+ none: 1,
4549
+ tight: 1.25,
4550
+ snug: 1.375,
4551
+ normal: 1.5,
4552
+ relaxed: 1.625,
4553
+ loose: 2
4554
+ }
4555
+ },
4556
+ spacing: {
4557
+ 0: "0",
4558
+ px: "1px",
4559
+ 0.5: "0.125rem",
4560
+ 1: "0.25rem",
4561
+ 1.5: "0.375rem",
4562
+ 2: "0.5rem",
4563
+ 2.5: "0.625rem",
4564
+ 3: "0.75rem",
4565
+ 3.5: "0.875rem",
4566
+ 4: "1rem",
4567
+ 5: "1.25rem",
4568
+ 6: "1.5rem",
4569
+ 7: "1.75rem",
4570
+ 8: "2rem",
4571
+ 9: "2.25rem",
4572
+ 10: "2.5rem",
4573
+ 11: "2.75rem",
4574
+ 12: "3rem",
4575
+ 14: "3.5rem",
4576
+ 16: "4rem",
4577
+ 20: "5rem",
4578
+ 24: "6rem",
4579
+ 28: "7rem",
4580
+ 32: "8rem",
4581
+ 36: "9rem",
4582
+ 40: "10rem",
4583
+ 44: "11rem",
4584
+ 48: "12rem",
4585
+ 52: "13rem",
4586
+ 56: "14rem",
4587
+ 60: "15rem",
4588
+ 64: "16rem",
4589
+ 72: "18rem",
4590
+ 80: "20rem",
4591
+ 96: "24rem"
4592
+ },
4593
+ borderRadius: {
4594
+ none: "0",
4595
+ sm: "0.125rem",
4596
+ default: "0.25rem",
4597
+ md: "0.375rem",
4598
+ lg: "0.5rem",
4599
+ xl: "0.75rem",
4600
+ "2xl": "1rem",
4601
+ "3xl": "1.5rem",
4602
+ full: "9999px"
4603
+ },
4604
+ breakpoints: {
4605
+ xs: "475px",
4606
+ sm: "640px",
4607
+ md: "768px",
4608
+ lg: "1024px",
4609
+ xl: "1280px",
4610
+ "2xl": "1536px"
4611
+ },
4612
+ zIndex: {
4613
+ hide: -1,
4614
+ auto: "auto",
4615
+ base: 0,
4616
+ dropdown: 1e3,
4617
+ sticky: 1020,
4618
+ fixed: 1030,
4619
+ modalBackdrop: 1040,
4620
+ modal: 1050,
4621
+ popover: 1060,
4622
+ tooltip: 1070,
4623
+ toast: 1080
4624
+ },
4625
+ transitions: {
4626
+ none: "none",
4627
+ fast: "150ms ease-in-out",
4628
+ normal: "200ms ease-in-out",
4629
+ slow: "300ms ease-in-out",
4630
+ slower: "500ms ease-in-out",
4631
+ colors: "color 200ms ease-in-out, background-color 200ms ease-in-out, border-color 200ms ease-in-out",
4632
+ transform: "transform 200ms ease-in-out",
4633
+ opacity: "opacity 200ms ease-in-out",
4634
+ shadow: "box-shadow 200ms ease-in-out",
4635
+ all: "all 200ms ease-in-out"
4636
+ },
4637
+ components: {
4638
+ button: {
4639
+ bg: "#60a5fa",
4640
+ bgHover: "#3b82f6",
4641
+ bgActive: "#2563eb",
4642
+ bgDisabled: "#1e3a5f",
4643
+ color: "#0f172a",
4644
+ colorHover: "#0f172a",
4645
+ colorDisabled: "#64748b",
4646
+ border: "transparent",
4647
+ borderHover: "transparent",
4648
+ borderWidth: "1px",
4649
+ borderRadius: "0.375rem",
4650
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
4651
+ shadowHover: "0 4px 6px -1px rgb(0 0 0 / 0.4)",
4652
+ paddingX: "1rem",
4653
+ paddingY: "0.5rem",
4654
+ fontSize: "0.875rem",
4655
+ fontWeight: 500,
4656
+ variants: {
4657
+ primary: {
4658
+ bg: "#60a5fa",
4659
+ bgHover: "#3b82f6",
4660
+ color: "#0f172a"
4661
+ },
4662
+ secondary: {
4663
+ bg: "#818cf8",
4664
+ bgHover: "#6366f1",
4665
+ color: "#0f172a"
4666
+ },
4667
+ outline: {
4668
+ bg: "transparent",
4669
+ bgHover: "#334155",
4670
+ color: "#f8fafc",
4671
+ border: "#475569",
4672
+ borderHover: "#64748b"
4673
+ },
4674
+ ghost: {
4675
+ bg: "transparent",
4676
+ bgHover: "#334155",
4677
+ color: "#f8fafc",
4678
+ shadow: "none",
4679
+ shadowHover: "none"
4680
+ },
4681
+ link: {
4682
+ bg: "transparent",
4683
+ bgHover: "transparent",
4684
+ color: "#60a5fa",
4685
+ colorHover: "#3b82f6",
4686
+ shadow: "none",
4687
+ shadowHover: "none",
4688
+ paddingX: "0",
4689
+ paddingY: "0"
4690
+ },
4691
+ danger: {
4692
+ bg: "#f87171",
4693
+ bgHover: "#ef4444",
4694
+ color: "#0f172a"
4695
+ },
4696
+ success: {
4697
+ bg: "#4ade80",
4698
+ bgHover: "#22c55e",
4699
+ color: "#0f172a"
4700
+ }
4701
+ },
4702
+ sizes: {
4703
+ xs: {
4704
+ paddingX: "0.5rem",
4705
+ paddingY: "0.25rem",
4706
+ fontSize: "0.75rem"
4707
+ },
4708
+ sm: {
4709
+ paddingX: "0.75rem",
4710
+ paddingY: "0.375rem",
4711
+ fontSize: "0.875rem"
4712
+ },
4713
+ md: {
4714
+ paddingX: "1rem",
4715
+ paddingY: "0.5rem",
4716
+ fontSize: "0.875rem"
4717
+ },
4718
+ lg: {
4719
+ paddingX: "1.25rem",
4720
+ paddingY: "0.625rem",
4721
+ fontSize: "1rem"
4722
+ },
4723
+ xl: {
4724
+ paddingX: "1.5rem",
4725
+ paddingY: "0.75rem",
4726
+ fontSize: "1.125rem"
4727
+ }
4728
+ }
4729
+ },
4730
+ input: {
4731
+ bg: "#1e293b",
4732
+ bgFocus: "#1e293b",
4733
+ bgDisabled: "#334155",
4734
+ bgError: "#450a0a",
4735
+ color: "#f8fafc",
4736
+ colorPlaceholder: "#64748b",
4737
+ colorDisabled: "#64748b",
4738
+ border: "#475569",
4739
+ borderFocus: "#60a5fa",
4740
+ borderError: "#f87171",
4741
+ borderWidth: "1px",
4742
+ borderRadius: "0.375rem",
4743
+ shadow: "0 1px 2px 0 rgb(0 0 0 / 0.3)",
4744
+ shadowFocus: "0 0 0 3px rgb(96 165 250 / 0.2)",
4745
+ paddingX: "0.75rem",
4746
+ paddingY: "0.5rem",
4747
+ fontSize: "0.875rem",
4748
+ labelColor: "#e2e8f0",
4749
+ labelFontSize: "0.875rem",
4750
+ labelFontWeight: 500,
4751
+ helperColor: "#94a3b8",
4752
+ errorColor: "#f87171",
4753
+ sizes: {
4754
+ sm: {
4755
+ paddingX: "0.5rem",
4756
+ paddingY: "0.375rem",
4757
+ fontSize: "0.75rem"
4758
+ },
4759
+ md: {
4760
+ paddingX: "0.75rem",
4761
+ paddingY: "0.5rem",
4762
+ fontSize: "0.875rem"
4763
+ },
4764
+ lg: {
4765
+ paddingX: "1rem",
4766
+ paddingY: "0.625rem",
4767
+ fontSize: "1rem"
4768
+ }
4769
+ }
4770
+ },
4771
+ card: {
4772
+ bg: "#1e293b",
4773
+ bgHover: "#1e293b",
4774
+ border: "#334155",
4775
+ borderWidth: "1px",
4776
+ borderRadius: "0.5rem",
4777
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
4778
+ shadowHover: "0 10px 15px -3px rgb(0 0 0 / 0.4)",
4779
+ padding: "1.5rem",
4780
+ headerBg: "#0f172a",
4781
+ headerBorder: "#334155",
4782
+ headerPadding: "1rem 1.5rem",
4783
+ footerBg: "#0f172a",
4784
+ footerBorder: "#334155",
4785
+ footerPadding: "1rem 1.5rem"
4786
+ },
4787
+ header: {
4788
+ bg: "#0f172a",
4789
+ bgScrolled: "rgba(15, 23, 42, 0.95)",
4790
+ color: "#f8fafc",
4791
+ border: "#334155",
4792
+ shadow: "none",
4793
+ shadowScrolled: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
4794
+ height: "4rem",
4795
+ paddingX: "1.5rem",
4796
+ logoHeight: "2rem",
4797
+ navColor: "#94a3b8",
4798
+ navColorHover: "#f8fafc",
4799
+ navColorActive: "#60a5fa",
4800
+ navFontSize: "0.875rem",
4801
+ navFontWeight: 500,
4802
+ mobileMenuBg: "#1e293b",
4803
+ mobileMenuShadow: "0 10px 15px -3px rgb(0 0 0 / 0.4)"
4804
+ },
4805
+ footer: {
4806
+ bg: "#020617",
4807
+ color: "#94a3b8",
4808
+ colorMuted: "#64748b",
4809
+ border: "#1e293b",
4810
+ padding: "4rem 1.5rem",
4811
+ linkColor: "#94a3b8",
4812
+ linkColorHover: "#f8fafc",
4813
+ headingColor: "#f8fafc",
4814
+ headingFontSize: "1rem",
4815
+ headingFontWeight: 600,
4816
+ copyrightBg: "#0f172a",
4817
+ copyrightColor: "#64748b"
4818
+ },
4819
+ banner: {
4820
+ bg: "#1e3a5f",
4821
+ color: "#bfdbfe",
4822
+ border: "#3b82f6",
4823
+ borderRadius: "0.5rem",
4824
+ padding: "1rem 1.5rem",
4825
+ shadow: "none",
4826
+ closeBg: "transparent",
4827
+ closeColor: "#bfdbfe",
4828
+ variants: {
4829
+ info: {
4830
+ bg: "#1e3a5f",
4831
+ color: "#bfdbfe",
4832
+ border: "#3b82f6"
4833
+ },
4834
+ success: {
4835
+ bg: "#14532d",
4836
+ color: "#bbf7d0",
4837
+ border: "#22c55e"
4838
+ },
4839
+ warning: {
4840
+ bg: "#78350f",
4841
+ color: "#fde68a",
4842
+ border: "#f59e0b"
4843
+ },
4844
+ error: {
4845
+ bg: "#7f1d1d",
4846
+ color: "#fecaca",
4847
+ border: "#ef4444"
4848
+ },
4849
+ promo: {
4850
+ bg: "#581c87",
4851
+ color: "#e9d5ff",
4852
+ border: "#a855f7"
4853
+ }
4854
+ }
4855
+ },
4856
+ loader: {
4857
+ color: "#60a5fa",
4858
+ colorSecondary: "#334155",
4859
+ size: "2.5rem",
4860
+ borderWidth: "3px",
4861
+ overlayBg: "rgba(15, 23, 42, 0.8)",
4862
+ overlayOpacity: 1,
4863
+ sizes: {
4864
+ xs: "1rem",
4865
+ sm: "1.5rem",
4866
+ md: "2.5rem",
4867
+ lg: "3.5rem",
4868
+ xl: "5rem"
4869
+ }
4870
+ },
4871
+ modal: {
4872
+ bg: "#1e293b",
4873
+ color: "#f8fafc",
4874
+ border: "#334155",
4875
+ borderRadius: "0.5rem",
4876
+ shadow: "0 25px 50px -12px rgb(0 0 0 / 0.6)",
4877
+ padding: "1.5rem",
4878
+ overlayBg: "rgba(0, 0, 0, 0.7)",
4879
+ overlayOpacity: 1,
4880
+ headerBg: "#1e293b",
4881
+ headerBorder: "#334155",
4882
+ headerPadding: "1rem 1.5rem",
4883
+ footerBg: "#0f172a",
4884
+ footerBorder: "#334155",
4885
+ footerPadding: "1rem 1.5rem",
4886
+ closeBg: "transparent",
4887
+ closeColor: "#94a3b8",
4888
+ closeHoverBg: "#334155",
4889
+ sizes: {
4890
+ sm: "24rem",
4891
+ md: "32rem",
4892
+ lg: "48rem",
4893
+ xl: "64rem",
4894
+ full: "100%"
4895
+ }
4896
+ },
4897
+ toast: {
4898
+ bg: "#1e293b",
4899
+ color: "#f8fafc",
4900
+ border: "#334155",
4901
+ borderRadius: "0.5rem",
4902
+ shadow: "0 10px 15px -3px rgb(0 0 0 / 0.4)",
4903
+ padding: "1rem",
4904
+ variants: {
4905
+ success: {
4906
+ bg: "#14532d",
4907
+ color: "#bbf7d0",
4908
+ border: "#22c55e"
4909
+ },
4910
+ error: {
4911
+ bg: "#7f1d1d",
4912
+ color: "#fecaca",
4913
+ border: "#ef4444"
4914
+ },
4915
+ warning: {
4916
+ bg: "#78350f",
4917
+ color: "#fde68a",
4918
+ border: "#f59e0b"
4919
+ },
4920
+ info: {
4921
+ bg: "#1e3a5f",
4922
+ color: "#bfdbfe",
4923
+ border: "#3b82f6"
4924
+ }
4925
+ }
4926
+ },
4927
+ newsletter: {
4928
+ bg: "#1e293b",
4929
+ color: "#f8fafc",
4930
+ border: "#334155",
4931
+ borderRadius: "0.5rem",
4932
+ padding: "2rem",
4933
+ titleColor: "#f8fafc",
4934
+ titleFontSize: "1.5rem",
4935
+ descColor: "#94a3b8",
4936
+ descFontSize: "1rem",
4937
+ inputBg: "#0f172a",
4938
+ inputBorder: "#475569",
4939
+ buttonBg: "#60a5fa",
4940
+ buttonColor: "#0f172a"
4941
+ }
4942
+ }
4943
+ };
4944
+
4945
+ // src/client/web/theme/theme-utils.ts
4946
+ function deepMerge(target, source) {
4947
+ const output = { ...target };
4948
+ for (const key in source) {
4949
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
4950
+ const sourceValue = source[key];
4951
+ const targetValue = target[key];
4952
+ if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue && typeof targetValue === "object" && !Array.isArray(targetValue)) {
4953
+ output[key] = deepMerge(
4954
+ targetValue,
4955
+ sourceValue
4956
+ );
4957
+ } else if (sourceValue !== void 0) {
4958
+ output[key] = sourceValue;
4959
+ }
4960
+ }
4961
+ }
4962
+ return output;
4963
+ }
4964
+ function createThemeFromBrand(brand, baseTheme = defaultLightTheme) {
4965
+ const { colors: colors2 } = brand;
4966
+ const brandOverrides = {
4967
+ brand,
4968
+ colors: {
4969
+ brand: {
4970
+ primary: colors2.primary,
4971
+ secondary: colors2.secondary,
4972
+ accent: colors2.accent || colors2.primary,
4973
+ background: colors2.background || baseTheme.colors.background.default,
4974
+ foreground: colors2.foreground || baseTheme.colors.text.primary
4975
+ },
4976
+ semantic: {
4977
+ primary: colors2.primary,
4978
+ primaryHover: adjustColor(colors2.primary, -10),
4979
+ primaryActive: adjustColor(colors2.primary, -20),
4980
+ primaryDisabled: adjustColor(colors2.primary, 40),
4981
+ secondary: colors2.secondary,
4982
+ secondaryHover: adjustColor(colors2.secondary, -10),
4983
+ secondaryActive: adjustColor(colors2.secondary, -20),
4984
+ secondaryDisabled: adjustColor(colors2.secondary, 40),
4985
+ accent: colors2.accent || colors2.primary,
4986
+ accentHover: adjustColor(colors2.accent || colors2.primary, -10)
4987
+ }
4988
+ },
4989
+ components: {
4990
+ button: {
4991
+ bg: colors2.primary,
4992
+ bgHover: adjustColor(colors2.primary, -10),
4993
+ bgActive: adjustColor(colors2.primary, -20),
4994
+ variants: {
4995
+ primary: {
4996
+ bg: colors2.primary,
4997
+ bgHover: adjustColor(colors2.primary, -10)
4998
+ },
4999
+ secondary: {
5000
+ bg: colors2.secondary,
5001
+ bgHover: adjustColor(colors2.secondary, -10)
5002
+ }
5003
+ }
5004
+ },
5005
+ input: {
5006
+ borderFocus: colors2.primary
5007
+ },
5008
+ header: {
5009
+ navColorActive: colors2.primary
5010
+ },
5011
+ loader: {
5012
+ color: colors2.primary
5013
+ },
5014
+ newsletter: {
5015
+ buttonBg: colors2.primary
5016
+ }
5017
+ }
5018
+ };
5019
+ return deepMerge(baseTheme, brandOverrides);
5020
+ }
5021
+ function adjustColor(hex, percent) {
5022
+ hex = hex.replace(/^#/, "");
5023
+ let r = parseInt(hex.substring(0, 2), 16);
5024
+ let g = parseInt(hex.substring(2, 4), 16);
5025
+ let b = parseInt(hex.substring(4, 6), 16);
5026
+ r = Math.min(255, Math.max(0, r + r * percent / 100));
5027
+ g = Math.min(255, Math.max(0, g + g * percent / 100));
5028
+ b = Math.min(255, Math.max(0, b + b * percent / 100));
5029
+ const toHex = (n) => Math.round(n).toString(16).padStart(2, "0");
5030
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
5031
+ }
5032
+ function hexToRgba(hex, alpha = 1) {
5033
+ hex = hex.replace(/^#/, "");
5034
+ const r = parseInt(hex.substring(0, 2), 16);
5035
+ const g = parseInt(hex.substring(2, 4), 16);
5036
+ const b = parseInt(hex.substring(4, 6), 16);
5037
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
5038
+ }
5039
+ function getContrastColor(hex) {
5040
+ hex = hex.replace(/^#/, "");
5041
+ const r = parseInt(hex.substring(0, 2), 16);
5042
+ const g = parseInt(hex.substring(2, 4), 16);
5043
+ const b = parseInt(hex.substring(4, 6), 16);
5044
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
5045
+ return luminance > 0.5 ? "#000000" : "#ffffff";
5046
+ }
5047
+ function flattenToCssVars(obj, prefix = "--ec") {
5048
+ const result = {};
5049
+ function flatten(current, path2 = []) {
5050
+ for (const key in current) {
5051
+ if (Object.prototype.hasOwnProperty.call(current, key)) {
5052
+ const value = current[key];
5053
+ const newPath = [...path2, key];
5054
+ const varName = `${prefix}-${newPath.join("-")}`;
5055
+ if (value && typeof value === "object" && !Array.isArray(value)) {
5056
+ flatten(value, newPath);
5057
+ } else if (typeof value === "string" || typeof value === "number") {
5058
+ result[varName] = String(value);
5059
+ }
5060
+ }
5061
+ }
5062
+ }
5063
+ flatten(obj);
5064
+ return result;
5065
+ }
5066
+ function generateCssVars(theme, prefix = "--ec") {
5067
+ const cssVars = flattenToCssVars(theme, prefix);
5068
+ return Object.entries(cssVars).map(([key, value]) => `${key}: ${value};`).join("\n");
5069
+ }
5070
+ function injectCssVars(theme, prefix = "--ec") {
5071
+ if (typeof document === "undefined") return;
5072
+ const cssVars = flattenToCssVars(theme, prefix);
5073
+ const root = document.documentElement;
5074
+ for (const [key, value] of Object.entries(cssVars)) {
5075
+ root.style.setProperty(key, value);
5076
+ }
5077
+ }
5078
+ function removeCssVars(prefix = "--ec") {
5079
+ if (typeof document === "undefined") return;
5080
+ const root = document.documentElement;
5081
+ const style = root.style;
5082
+ for (let i = style.length - 1; i >= 0; i--) {
5083
+ const name = style[i];
5084
+ if (name.startsWith(prefix)) {
5085
+ root.style.removeProperty(name);
5086
+ }
5087
+ }
5088
+ }
5089
+ async function loadThemeFromUrl(url) {
5090
+ try {
5091
+ const response = await fetch(url, {
5092
+ headers: {
5093
+ Accept: "application/json"
5094
+ }
5095
+ });
5096
+ if (!response.ok) {
5097
+ console.error(`Failed to load theme from ${url}: ${response.status}`);
5098
+ return null;
5099
+ }
5100
+ const themeData = await response.json();
5101
+ return themeData;
5102
+ } catch (error) {
5103
+ console.error(`Error loading theme from ${url}:`, error);
5104
+ return null;
5105
+ }
5106
+ }
5107
+ async function createTheme(config = {}) {
5108
+ let lightTheme = { ...defaultLightTheme };
5109
+ let darkTheme = { ...defaultDarkTheme };
5110
+ if (config.themeUrl) {
5111
+ const urlTheme = await loadThemeFromUrl(config.themeUrl);
5112
+ if (urlTheme) {
5113
+ lightTheme = deepMerge(lightTheme, urlTheme);
5114
+ darkTheme = deepMerge(darkTheme, urlTheme);
5115
+ }
5116
+ }
5117
+ if (config.brandIdentity) {
5118
+ lightTheme = createThemeFromBrand(config.brandIdentity, lightTheme);
5119
+ darkTheme = createThemeFromBrand(config.brandIdentity, darkTheme);
5120
+ }
5121
+ if (config.light) {
5122
+ lightTheme = deepMerge(lightTheme, config.light);
5123
+ }
5124
+ if (config.dark) {
5125
+ darkTheme = deepMerge(darkTheme, config.dark);
5126
+ }
5127
+ return { light: lightTheme, dark: darkTheme };
5128
+ }
5129
+ var DEFAULT_STORAGE_KEY = "ec-theme-mode";
5130
+ function saveThemeMode(mode, storageKey = DEFAULT_STORAGE_KEY) {
5131
+ if (typeof localStorage === "undefined") return;
5132
+ try {
5133
+ localStorage.setItem(storageKey, mode);
5134
+ } catch (error) {
5135
+ console.error("Failed to save theme mode:", error);
5136
+ }
5137
+ }
5138
+ function loadThemeMode(storageKey = DEFAULT_STORAGE_KEY) {
5139
+ if (typeof localStorage === "undefined") return null;
5140
+ try {
5141
+ const mode = localStorage.getItem(storageKey);
5142
+ if (mode === "light" || mode === "dark" || mode === "system") {
5143
+ return mode;
5144
+ }
5145
+ return null;
5146
+ } catch (error) {
5147
+ console.error("Failed to load theme mode:", error);
5148
+ return null;
5149
+ }
5150
+ }
5151
+ function getSystemColorScheme() {
5152
+ if (typeof window === "undefined") return "light";
5153
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
5154
+ }
5155
+ function resolveThemeMode(mode) {
5156
+ if (mode === "system") {
5157
+ return getSystemColorScheme();
5158
+ }
5159
+ return mode;
5160
+ }
5161
+ var ThemeContext = createContext(null);
5162
+ function useTheme() {
5163
+ const context = useContext(ThemeContext);
5164
+ if (!context) {
5165
+ throw new Error("useTheme must be used within a ThemeProvider");
5166
+ }
5167
+ return context;
5168
+ }
5169
+ function ThemeProvider({
5170
+ children,
5171
+ config = {},
5172
+ initialTheme
5173
+ }) {
5174
+ const {
5175
+ defaultMode = "system",
5176
+ themeUrl,
5177
+ light: lightOverrides,
5178
+ dark: darkOverrides,
5179
+ brandIdentity,
5180
+ enableSystemTheme = true,
5181
+ persistTheme = true,
5182
+ storageKey = "ec-theme-mode",
5183
+ cssVarPrefix = "--ec"
5184
+ } = config;
5185
+ const [mode, setModeState] = useState(() => {
5186
+ if (persistTheme && typeof window !== "undefined") {
5187
+ const savedMode = loadThemeMode(storageKey);
5188
+ if (savedMode) return savedMode;
5189
+ }
5190
+ return defaultMode;
5191
+ });
5192
+ const [lightTheme, setLightTheme] = useState(() => {
5193
+ if (initialTheme && initialTheme.mode === "light") return initialTheme;
5194
+ let theme2 = defaultLightTheme;
5195
+ if (brandIdentity) {
5196
+ theme2 = createThemeFromBrand(brandIdentity, theme2);
5197
+ }
5198
+ if (lightOverrides) {
5199
+ theme2 = deepMerge(theme2, lightOverrides);
5200
+ }
5201
+ return theme2;
5202
+ });
5203
+ const [darkTheme, setDarkTheme] = useState(() => {
5204
+ if (initialTheme && initialTheme.mode === "dark") return initialTheme;
5205
+ let theme2 = defaultDarkTheme;
5206
+ if (brandIdentity) {
5207
+ theme2 = createThemeFromBrand(brandIdentity, theme2);
5208
+ }
5209
+ if (darkOverrides) {
5210
+ theme2 = deepMerge(theme2, darkOverrides);
5211
+ }
5212
+ return theme2;
5213
+ });
5214
+ const [isLoading, setIsLoading] = useState(!!themeUrl);
5215
+ const [error, setError] = useState(null);
5216
+ const resolvedMode = useMemo(() => resolveThemeMode(mode), [mode]);
5217
+ const theme = useMemo(
5218
+ () => resolvedMode === "dark" ? darkTheme : lightTheme,
5219
+ [resolvedMode, lightTheme, darkTheme]
5220
+ );
5221
+ const isDark = resolvedMode === "dark";
5222
+ const isLight = resolvedMode === "light";
5223
+ useEffect(() => {
5224
+ if (!themeUrl) return;
5225
+ setIsLoading(true);
5226
+ setError(null);
5227
+ loadThemeFromUrl(themeUrl).then((urlTheme) => {
5228
+ if (urlTheme) {
5229
+ setLightTheme((prev) => deepMerge(prev, urlTheme));
5230
+ setDarkTheme((prev) => deepMerge(prev, urlTheme));
5231
+ }
5232
+ }).catch((err) => {
5233
+ setError(err instanceof Error ? err.message : "Failed to load theme");
5234
+ }).finally(() => {
5235
+ setIsLoading(false);
5236
+ });
5237
+ }, [themeUrl]);
5238
+ useEffect(() => {
5239
+ if (typeof window !== "undefined") {
5240
+ injectCssVars(theme, cssVarPrefix);
5241
+ }
5242
+ }, [theme, cssVarPrefix]);
5243
+ useEffect(() => {
5244
+ if (typeof document !== "undefined") {
5245
+ document.documentElement.setAttribute("data-theme", resolvedMode);
5246
+ document.documentElement.style.colorScheme = resolvedMode;
5247
+ }
5248
+ }, [resolvedMode]);
5249
+ useEffect(() => {
5250
+ if (!enableSystemTheme || typeof window === "undefined") return;
5251
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
5252
+ const handleChange = () => {
5253
+ if (mode === "system") {
5254
+ setModeState("system");
5255
+ }
5256
+ };
5257
+ mediaQuery.addEventListener("change", handleChange);
5258
+ return () => mediaQuery.removeEventListener("change", handleChange);
5259
+ }, [mode, enableSystemTheme]);
5260
+ useEffect(() => {
5261
+ if (persistTheme && typeof window !== "undefined") {
5262
+ saveThemeMode(mode, storageKey);
5263
+ }
5264
+ }, [mode, persistTheme, storageKey]);
5265
+ const setMode = useCallback((newMode) => {
5266
+ setModeState(newMode);
5267
+ }, []);
5268
+ const toggleMode = useCallback(() => {
5269
+ setModeState((prev) => {
5270
+ const current = resolveThemeMode(prev);
5271
+ return current === "dark" ? "light" : "dark";
5272
+ });
5273
+ }, []);
5274
+ const updateTheme = useCallback((updates) => {
5275
+ setLightTheme((prev) => deepMerge(prev, updates));
5276
+ setDarkTheme((prev) => deepMerge(prev, updates));
5277
+ }, []);
5278
+ const resetTheme = useCallback(() => {
5279
+ let light = defaultLightTheme;
5280
+ let dark = defaultDarkTheme;
5281
+ if (brandIdentity) {
5282
+ light = createThemeFromBrand(brandIdentity, light);
5283
+ dark = createThemeFromBrand(brandIdentity, dark);
5284
+ }
5285
+ if (lightOverrides) {
5286
+ light = deepMerge(light, lightOverrides);
5287
+ }
5288
+ if (darkOverrides) {
5289
+ dark = deepMerge(dark, darkOverrides);
5290
+ }
5291
+ setLightTheme(light);
5292
+ setDarkTheme(dark);
5293
+ }, [brandIdentity, lightOverrides, darkOverrides]);
5294
+ const contextValue = useMemo(
5295
+ () => ({
5296
+ theme,
5297
+ mode,
5298
+ setMode,
5299
+ toggleMode,
5300
+ updateTheme,
5301
+ resetTheme,
5302
+ isDark,
5303
+ isLight,
5304
+ isLoading,
5305
+ error
5306
+ }),
5307
+ [theme, mode, setMode, toggleMode, updateTheme, resetTheme, isDark, isLight, isLoading, error]
5308
+ );
5309
+ return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: contextValue, children });
5310
+ }
5311
+ function cssVar(path2, prefix = "--ec") {
5312
+ return `var(${prefix}-${path2.replace(/\./g, "-")})`;
5313
+ }
5314
+ function useThemeValue(selector) {
5315
+ const { theme } = useTheme();
5316
+ return selector(theme);
5317
+ }
5318
+ function ThemeToggle({
5319
+ className = "",
5320
+ size = 24,
5321
+ showLabel = false,
5322
+ lightLabel = "Light",
5323
+ darkLabel = "Dark"
5324
+ }) {
5325
+ const { isDark, toggleMode } = useTheme();
5326
+ return /* @__PURE__ */ jsxs(
5327
+ "button",
5328
+ {
5329
+ type: "button",
5330
+ onClick: toggleMode,
5331
+ className: `ec-theme-toggle ${className}`,
5332
+ "aria-label": isDark ? "Switch to light mode" : "Switch to dark mode",
5333
+ style: {
5334
+ background: "none",
5335
+ border: "none",
5336
+ cursor: "pointer",
5337
+ display: "inline-flex",
5338
+ alignItems: "center",
5339
+ gap: "0.5rem",
5340
+ padding: "0.5rem",
5341
+ borderRadius: "0.375rem",
5342
+ transition: "background-color 200ms ease-in-out"
5343
+ },
5344
+ children: [
5345
+ isDark ? (
5346
+ // Sun icon for dark mode (click to go light)
5347
+ /* @__PURE__ */ jsxs(
5348
+ "svg",
5349
+ {
5350
+ width: size,
5351
+ height: size,
5352
+ viewBox: "0 0 24 24",
5353
+ fill: "none",
5354
+ stroke: "currentColor",
5355
+ strokeWidth: "2",
5356
+ strokeLinecap: "round",
5357
+ strokeLinejoin: "round",
5358
+ children: [
5359
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "5" }),
5360
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "1", x2: "12", y2: "3" }),
5361
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "21", x2: "12", y2: "23" }),
5362
+ /* @__PURE__ */ jsx("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }),
5363
+ /* @__PURE__ */ jsx("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }),
5364
+ /* @__PURE__ */ jsx("line", { x1: "1", y1: "12", x2: "3", y2: "12" }),
5365
+ /* @__PURE__ */ jsx("line", { x1: "21", y1: "12", x2: "23", y2: "12" }),
5366
+ /* @__PURE__ */ jsx("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }),
5367
+ /* @__PURE__ */ jsx("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" })
5368
+ ]
5369
+ }
5370
+ )
5371
+ ) : (
5372
+ // Moon icon for light mode (click to go dark)
5373
+ /* @__PURE__ */ jsx(
5374
+ "svg",
5375
+ {
5376
+ width: size,
5377
+ height: size,
5378
+ viewBox: "0 0 24 24",
5379
+ fill: "none",
5380
+ stroke: "currentColor",
5381
+ strokeWidth: "2",
5382
+ strokeLinecap: "round",
5383
+ strokeLinejoin: "round",
5384
+ children: /* @__PURE__ */ jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" })
5385
+ }
5386
+ )
5387
+ ),
5388
+ showLabel && /* @__PURE__ */ jsx("span", { children: isDark ? darkLabel : lightLabel })
5389
+ ]
5390
+ }
5391
+ );
5392
+ }
5393
+
5394
+ // src/client/web/astro/types.ts
5395
+ function dummyImage(width, height, text, bgColor = "cccccc", textColor = "969696") {
5396
+ const label = text ? `&text=${encodeURIComponent(text)}` : "";
5397
+ return `https://dummyimage.com/${width}x${height}/${bgColor}/${textColor}${label}`;
5398
+ }
5399
+ function loremIpsum(type = "paragraph", count = 1) {
5400
+ const words = [
5401
+ "lorem",
5402
+ "ipsum",
5403
+ "dolor",
5404
+ "sit",
5405
+ "amet",
5406
+ "consectetur",
5407
+ "adipiscing",
5408
+ "elit",
5409
+ "sed",
5410
+ "do",
5411
+ "eiusmod",
5412
+ "tempor",
5413
+ "incididunt",
5414
+ "ut",
5415
+ "labore",
5416
+ "et",
5417
+ "dolore",
5418
+ "magna",
5419
+ "aliqua",
5420
+ "enim",
5421
+ "ad",
5422
+ "minim",
5423
+ "veniam",
5424
+ "quis",
5425
+ "nostrud",
5426
+ "exercitation",
5427
+ "ullamco",
5428
+ "laboris",
5429
+ "nisi",
5430
+ "aliquip",
5431
+ "ex",
5432
+ "ea",
5433
+ "commodo",
5434
+ "consequat",
5435
+ "duis",
5436
+ "aute",
5437
+ "irure",
5438
+ "in",
5439
+ "reprehenderit",
5440
+ "voluptate",
5441
+ "velit",
5442
+ "esse",
5443
+ "cillum",
5444
+ "fugiat",
5445
+ "nulla",
5446
+ "pariatur",
5447
+ "excepteur",
5448
+ "sint",
5449
+ "occaecat",
5450
+ "cupidatat",
5451
+ "non",
5452
+ "proident",
5453
+ "sunt",
5454
+ "culpa",
5455
+ "qui",
5456
+ "officia",
5457
+ "deserunt",
5458
+ "mollit",
5459
+ "anim",
5460
+ "id",
5461
+ "est",
5462
+ "laborum"
5463
+ ];
5464
+ const getWords = (n) => {
5465
+ const result = [];
5466
+ for (let i = 0; i < n; i++) {
5467
+ result.push(words[Math.floor(Math.random() * words.length)]);
5468
+ }
5469
+ return result;
5470
+ };
5471
+ const capitalize2 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
5472
+ if (type === "word") {
5473
+ return getWords(count).join(" ");
5474
+ }
5475
+ if (type === "sentence") {
5476
+ const sentences = [];
5477
+ for (let i = 0; i < count; i++) {
5478
+ const sentence = capitalize2(getWords(Math.floor(Math.random() * 10) + 5).join(" ")) + ".";
5479
+ sentences.push(sentence);
5480
+ }
5481
+ return sentences.join(" ");
5482
+ }
5483
+ const paragraphs = [];
5484
+ for (let i = 0; i < count; i++) {
5485
+ const sentences = [];
5486
+ const sentenceCount = Math.floor(Math.random() * 4) + 3;
5487
+ for (let j = 0; j < sentenceCount; j++) {
5488
+ sentences.push(capitalize2(getWords(Math.floor(Math.random() * 10) + 5).join(" ")) + ".");
5489
+ }
5490
+ paragraphs.push(sentences.join(" "));
5491
+ }
5492
+ return paragraphs.join("\n\n");
5493
+ }
5494
+ var dummyHeaderData = {
5495
+ logo: dummyImage(120, 40, "Logo"),
5496
+ logoAlt: "Company Logo",
5497
+ navLinks: [
5498
+ { text: "Home", href: "/", active: true },
5499
+ { text: "About", href: "/about" },
5500
+ { text: "Services", href: "/services" },
5501
+ { text: "Blog", href: "/blog" },
5502
+ { text: "Contact", href: "/contact" }
5503
+ ],
5504
+ cta: {
5505
+ text: "Get Started",
5506
+ href: "/signup",
5507
+ variant: "primary"
5508
+ },
5509
+ sticky: true
5510
+ };
5511
+ var dummyFooterData = {
5512
+ logo: dummyImage(120, 40, "Logo"),
5513
+ logoAlt: "Company Logo",
5514
+ description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore.",
5515
+ columns: [
5516
+ {
5517
+ title: "Product",
5518
+ links: [
5519
+ { text: "Features", href: "/features" },
5520
+ { text: "Pricing", href: "/pricing" },
5521
+ { text: "Integrations", href: "/integrations" },
5522
+ { text: "API", href: "/api" }
5523
+ ]
5524
+ },
5525
+ {
5526
+ title: "Company",
5527
+ links: [
5528
+ { text: "About", href: "/about" },
5529
+ { text: "Blog", href: "/blog" },
5530
+ { text: "Careers", href: "/careers" },
5531
+ { text: "Contact", href: "/contact" }
5532
+ ]
5533
+ },
5534
+ {
5535
+ title: "Legal",
5536
+ links: [
5537
+ { text: "Privacy Policy", href: "/privacy" },
5538
+ { text: "Terms of Service", href: "/terms" },
5539
+ { text: "Cookie Policy", href: "/cookies" }
5540
+ ]
5541
+ }
5542
+ ],
5543
+ socialLinks: [
5544
+ { platform: "twitter", href: "https://twitter.com" },
5545
+ { platform: "facebook", href: "https://facebook.com" },
5546
+ { platform: "instagram", href: "https://instagram.com" },
5547
+ { platform: "linkedin", href: "https://linkedin.com" },
5548
+ { platform: "github", href: "https://github.com" }
5549
+ ],
5550
+ copyright: `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} Company Name. All rights reserved.`
5551
+ };
5552
+ var dummyBannerData = {
5553
+ title: "Build Something Amazing Today",
5554
+ subtitle: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
5555
+ backgroundImage: dummyImage(1920, 800, "Hero+Background", "1e293b", "334155"),
5556
+ primaryCta: {
5557
+ text: "Get Started Free",
5558
+ href: "/signup",
5559
+ variant: "primary"
5560
+ },
5561
+ secondaryCta: {
5562
+ text: "Learn More",
5563
+ href: "/about",
5564
+ variant: "outline"
5565
+ },
5566
+ height: "lg",
5567
+ align: "center"
5568
+ };
5569
+ var dummyFeatures = [
5570
+ {
5571
+ title: "Lightning Fast",
5572
+ description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
5573
+ 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>'
5574
+ },
5575
+ {
5576
+ title: "Secure & Reliable",
5577
+ description: "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
5578
+ 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>'
5579
+ },
5580
+ {
5581
+ title: "Easy to Use",
5582
+ description: "Ut enim ad minim veniam, quis nostrud exercitation ullamco.",
5583
+ 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>'
5584
+ }
5585
+ ];
5586
+ var dummyTestimonials = [
5587
+ {
5588
+ name: "John Doe",
5589
+ role: "CEO",
5590
+ company: "Tech Corp",
5591
+ avatar: dummyImage(80, 80, "JD", "3b82f6", "ffffff"),
5592
+ text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
5593
+ rating: 5
5594
+ },
5595
+ {
5596
+ name: "Jane Smith",
5597
+ role: "CTO",
5598
+ company: "Startup Inc",
5599
+ avatar: dummyImage(80, 80, "JS", "10b981", "ffffff"),
5600
+ text: "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
5601
+ rating: 5
5602
+ },
5603
+ {
5604
+ name: "Bob Wilson",
5605
+ role: "Product Manager",
5606
+ company: "Enterprise Co",
5607
+ avatar: dummyImage(80, 80, "BW", "f59e0b", "ffffff"),
5608
+ text: "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
5609
+ rating: 4
5610
+ }
5611
+ ];
5612
+ var dummyPricingPlans = [
5613
+ {
5614
+ name: "Starter",
5615
+ description: "Perfect for individuals",
5616
+ price: "$9",
5617
+ period: "/month",
5618
+ features: [
5619
+ { text: "5 Projects", included: true },
5620
+ { text: "10GB Storage", included: true },
5621
+ { text: "Email Support", included: true },
5622
+ { text: "API Access", included: false },
5623
+ { text: "Custom Domain", included: false }
5624
+ ],
5625
+ ctaText: "Start Free Trial",
5626
+ ctaHref: "/signup?plan=starter"
5627
+ },
5628
+ {
5629
+ name: "Professional",
5630
+ description: "Best for growing teams",
5631
+ price: "$29",
5632
+ period: "/month",
5633
+ features: [
5634
+ { text: "Unlimited Projects", included: true },
5635
+ { text: "100GB Storage", included: true },
5636
+ { text: "Priority Support", included: true },
5637
+ { text: "API Access", included: true },
5638
+ { text: "Custom Domain", included: false }
5639
+ ],
5640
+ ctaText: "Start Free Trial",
5641
+ ctaHref: "/signup?plan=pro",
5642
+ popular: true,
5643
+ badge: "Most Popular"
5644
+ },
5645
+ {
5646
+ name: "Enterprise",
5647
+ description: "For large organizations",
5648
+ price: "$99",
5649
+ period: "/month",
5650
+ features: [
5651
+ { text: "Unlimited Projects", included: true },
5652
+ { text: "Unlimited Storage", included: true },
5653
+ { text: "24/7 Support", included: true },
5654
+ { text: "API Access", included: true },
5655
+ { text: "Custom Domain", included: true }
5656
+ ],
5657
+ ctaText: "Contact Sales",
5658
+ ctaHref: "/contact?plan=enterprise"
5659
+ }
5660
+ ];
5661
+ var dummyFaqItems = [
5662
+ {
5663
+ question: "What is your refund policy?",
5664
+ answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
5665
+ },
5666
+ {
5667
+ question: "How do I cancel my subscription?",
5668
+ answer: "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
5669
+ },
5670
+ {
5671
+ question: "Can I change my plan later?",
5672
+ answer: "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
5673
+ },
5674
+ {
5675
+ question: "Do you offer discounts for non-profits?",
5676
+ answer: "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
5677
+ }
5678
+ ];
5679
+
5680
+ // src/client/web/forms/types.ts
5681
+ var VALIDATION_MESSAGES = {
5682
+ required: "This field is required",
5683
+ email: "Please enter a valid email address",
5684
+ phone: "Please enter a valid phone number",
5685
+ minLength: (min) => `Must be at least ${min} characters`,
5686
+ maxLength: (max) => `Must be no more than ${max} characters`,
5687
+ passwordMatch: "Passwords must match",
5688
+ acceptTerms: "You must accept the terms and conditions",
5689
+ passwordUppercase: "Password must contain at least one uppercase letter",
5690
+ passwordLowercase: "Password must contain at least one lowercase letter",
5691
+ passwordNumber: "Password must contain at least one number",
5692
+ passwordSpecial: "Password must contain at least one special character"
5693
+ };
5694
+ var contactFormSchema = Yup.object().shape({
5695
+ name: Yup.string().required(VALIDATION_MESSAGES.required).min(2, VALIDATION_MESSAGES.minLength(2)).max(100, VALIDATION_MESSAGES.maxLength(100)),
5696
+ email: Yup.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
5697
+ phone: Yup.string().matches(
5698
+ /^[+]?[(]?[0-9]{1,4}[)]?[-\s./0-9]*$/,
5699
+ VALIDATION_MESSAGES.phone
5700
+ ).nullable(),
5701
+ subject: Yup.string().max(200, VALIDATION_MESSAGES.maxLength(200)).nullable(),
5702
+ message: Yup.string().required(VALIDATION_MESSAGES.required).min(10, VALIDATION_MESSAGES.minLength(10)).max(2e3, VALIDATION_MESSAGES.maxLength(2e3))
5703
+ });
5704
+ var newsletterFormSchema = Yup.object().shape({
5705
+ email: Yup.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
5706
+ firstName: Yup.string().min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)).nullable(),
5707
+ lastName: Yup.string().min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)).nullable()
5708
+ });
5709
+ var loginFormSchema = Yup.object().shape({
5710
+ email: Yup.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
5711
+ password: Yup.string().required(VALIDATION_MESSAGES.required).min(8, VALIDATION_MESSAGES.minLength(8)),
5712
+ rememberMe: Yup.boolean()
5713
+ });
5714
+ function createRegisterFormSchema(requirements = {}) {
5715
+ const {
5716
+ minLength = 8,
5717
+ requireUppercase = true,
5718
+ requireLowercase = true,
5719
+ requireNumber = true,
5720
+ requireSpecial = false
5721
+ } = requirements;
5722
+ let passwordSchema = Yup.string().required(VALIDATION_MESSAGES.required).min(minLength, VALIDATION_MESSAGES.minLength(minLength));
5723
+ if (requireUppercase) {
5724
+ passwordSchema = passwordSchema.matches(
5725
+ /[A-Z]/,
5726
+ VALIDATION_MESSAGES.passwordUppercase
5727
+ );
5728
+ }
5729
+ if (requireLowercase) {
5730
+ passwordSchema = passwordSchema.matches(
5731
+ /[a-z]/,
5732
+ VALIDATION_MESSAGES.passwordLowercase
5733
+ );
5734
+ }
5735
+ if (requireNumber) {
5736
+ passwordSchema = passwordSchema.matches(
5737
+ /[0-9]/,
5738
+ VALIDATION_MESSAGES.passwordNumber
5739
+ );
5740
+ }
5741
+ if (requireSpecial) {
5742
+ passwordSchema = passwordSchema.matches(
5743
+ /[!@#$%^&*(),.?":{}|<>]/,
5744
+ VALIDATION_MESSAGES.passwordSpecial
5745
+ );
5746
+ }
5747
+ return Yup.object().shape({
5748
+ firstName: Yup.string().required(VALIDATION_MESSAGES.required).min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)),
5749
+ lastName: Yup.string().required(VALIDATION_MESSAGES.required).min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)),
5750
+ email: Yup.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
5751
+ password: passwordSchema,
5752
+ confirmPassword: Yup.string().required(VALIDATION_MESSAGES.required).oneOf([Yup.ref("password")], VALIDATION_MESSAGES.passwordMatch),
5753
+ acceptTerms: Yup.boolean().oneOf([true], VALIDATION_MESSAGES.acceptTerms)
5754
+ });
5755
+ }
5756
+ var registerFormSchema = createRegisterFormSchema();
5757
+ var defaultInitialValues = {
5758
+ name: "",
5759
+ email: "",
5760
+ phone: "",
5761
+ subject: "",
5762
+ message: ""
5763
+ };
5764
+ var defaultSubjectOptions = [
5765
+ "General Inquiry",
5766
+ "Support Request",
5767
+ "Sales Question",
5768
+ "Partnership",
5769
+ "Feedback",
5770
+ "Other"
5771
+ ];
5772
+ function ContactForm({
5773
+ actionUrl,
5774
+ onSubmit,
5775
+ initialValues,
5776
+ showPhone = true,
5777
+ showSubject = true,
5778
+ subjectOptions = defaultSubjectOptions,
5779
+ submitText = "Send Message",
5780
+ successMessage = "Thank you! Your message has been sent successfully.",
5781
+ className = "",
5782
+ formClass = "",
5783
+ inputClass = "",
5784
+ labelClass = "",
5785
+ buttonClass = "",
5786
+ errorClass = ""
5787
+ }) {
5788
+ const [submitStatus, setSubmitStatus] = useState("idle");
5789
+ const [submitMessage, setSubmitMessage] = useState("");
5790
+ const mergedInitialValues = {
5791
+ ...defaultInitialValues,
5792
+ ...initialValues
5793
+ };
5794
+ 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";
5795
+ const baseLabelClass = "block text-sm font-medium text-gray-700 mb-1";
5796
+ const baseErrorClass = "text-sm text-red-600 mt-1";
5797
+ 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";
5798
+ const handleSubmit = async (values, { setSubmitting, resetForm }) => {
5799
+ try {
5800
+ let result;
5801
+ if (onSubmit) {
5802
+ result = await onSubmit(values);
5803
+ } else if (actionUrl) {
5804
+ const response = await fetch(actionUrl, {
5805
+ method: "POST",
5806
+ headers: { "Content-Type": "application/json" },
5807
+ body: JSON.stringify(values)
5808
+ });
5809
+ result = await response.json();
5810
+ } else {
5811
+ await new Promise((resolve2) => setTimeout(resolve2, 1e3));
5812
+ result = { success: true };
5813
+ }
5814
+ if (result.success) {
5815
+ setSubmitStatus("success");
5816
+ setSubmitMessage(result.message || successMessage);
5817
+ resetForm();
5818
+ } else {
5819
+ setSubmitStatus("error");
5820
+ setSubmitMessage(result.message || "Something went wrong. Please try again.");
5821
+ }
5822
+ } catch (error) {
5823
+ setSubmitStatus("error");
5824
+ setSubmitMessage("An error occurred. Please try again later.");
5825
+ } finally {
5826
+ setSubmitting(false);
5827
+ }
5828
+ };
5829
+ return /* @__PURE__ */ jsx("div", { className: `ec-contact-form ${className}`, children: submitStatus === "success" ? /* @__PURE__ */ jsxs("div", { className: "p-6 bg-green-50 border border-green-200 rounded-lg text-center", children: [
5830
+ /* @__PURE__ */ 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__ */ 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" }) }),
5831
+ /* @__PURE__ */ jsx("p", { className: "text-green-800 font-medium", children: submitMessage }),
5832
+ /* @__PURE__ */ jsx(
5833
+ "button",
5834
+ {
5835
+ type: "button",
5836
+ onClick: () => setSubmitStatus("idle"),
5837
+ className: "mt-4 text-green-600 hover:text-green-700 text-sm font-medium",
5838
+ children: "Send another message"
5839
+ }
5840
+ )
5841
+ ] }) : /* @__PURE__ */ jsx(
5842
+ Formik,
5843
+ {
5844
+ initialValues: mergedInitialValues,
5845
+ validationSchema: contactFormSchema,
5846
+ onSubmit: handleSubmit,
5847
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxs(Form, { className: `space-y-4 ${formClass}`, noValidate: true, children: [
5848
+ /* @__PURE__ */ jsxs("div", { children: [
5849
+ /* @__PURE__ */ jsxs("label", { htmlFor: "contact-name", className: `${baseLabelClass} ${labelClass}`, children: [
5850
+ "Name ",
5851
+ /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
5852
+ ] }),
5853
+ /* @__PURE__ */ jsx(
5854
+ Field,
5855
+ {
5856
+ type: "text",
5857
+ id: "contact-name",
5858
+ name: "name",
5859
+ placeholder: "John Doe",
5860
+ className: `${baseInputClass} ${inputClass} ${errors.name && touched.name ? "border-red-500 focus:ring-red-500" : ""}`
5861
+ }
5862
+ ),
5863
+ /* @__PURE__ */ jsx(ErrorMessage, { name: "name", component: "p", className: `${baseErrorClass} ${errorClass}` })
5864
+ ] }),
5865
+ /* @__PURE__ */ jsxs("div", { children: [
5866
+ /* @__PURE__ */ jsxs("label", { htmlFor: "contact-email", className: `${baseLabelClass} ${labelClass}`, children: [
5867
+ "Email ",
5868
+ /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
5869
+ ] }),
5870
+ /* @__PURE__ */ jsx(
5871
+ Field,
5872
+ {
5873
+ type: "email",
5874
+ id: "contact-email",
5875
+ name: "email",
5876
+ placeholder: "john@example.com",
5877
+ className: `${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500 focus:ring-red-500" : ""}`
5878
+ }
5879
+ ),
5880
+ /* @__PURE__ */ jsx(ErrorMessage, { name: "email", component: "p", className: `${baseErrorClass} ${errorClass}` })
5881
+ ] }),
5882
+ showPhone && /* @__PURE__ */ jsxs("div", { children: [
5883
+ /* @__PURE__ */ jsx("label", { htmlFor: "contact-phone", className: `${baseLabelClass} ${labelClass}`, children: "Phone" }),
5884
+ /* @__PURE__ */ jsx(
5885
+ Field,
5886
+ {
5887
+ type: "tel",
5888
+ id: "contact-phone",
5889
+ name: "phone",
5890
+ placeholder: "+1 (555) 000-0000",
5891
+ className: `${baseInputClass} ${inputClass} ${errors.phone && touched.phone ? "border-red-500 focus:ring-red-500" : ""}`
5892
+ }
5893
+ ),
5894
+ /* @__PURE__ */ jsx(ErrorMessage, { name: "phone", component: "p", className: `${baseErrorClass} ${errorClass}` })
5895
+ ] }),
5896
+ showSubject && /* @__PURE__ */ jsxs("div", { children: [
5897
+ /* @__PURE__ */ jsx("label", { htmlFor: "contact-subject", className: `${baseLabelClass} ${labelClass}`, children: "Subject" }),
5898
+ /* @__PURE__ */ jsxs(
5899
+ Field,
5900
+ {
5901
+ as: "select",
5902
+ id: "contact-subject",
5903
+ name: "subject",
5904
+ className: `${baseInputClass} ${inputClass}`,
5905
+ children: [
5906
+ /* @__PURE__ */ jsx("option", { value: "", children: "Select a subject..." }),
5907
+ subjectOptions.map((option) => /* @__PURE__ */ jsx("option", { value: option, children: option }, option))
5908
+ ]
5909
+ }
5910
+ ),
5911
+ /* @__PURE__ */ jsx(ErrorMessage, { name: "subject", component: "p", className: `${baseErrorClass} ${errorClass}` })
5912
+ ] }),
5913
+ /* @__PURE__ */ jsxs("div", { children: [
5914
+ /* @__PURE__ */ jsxs("label", { htmlFor: "contact-message", className: `${baseLabelClass} ${labelClass}`, children: [
5915
+ "Message ",
5916
+ /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
5917
+ ] }),
5918
+ /* @__PURE__ */ jsx(
5919
+ Field,
5920
+ {
5921
+ as: "textarea",
5922
+ id: "contact-message",
5923
+ name: "message",
5924
+ rows: 5,
5925
+ placeholder: "Your message...",
5926
+ className: `${baseInputClass} ${inputClass} resize-none ${errors.message && touched.message ? "border-red-500 focus:ring-red-500" : ""}`
5927
+ }
5928
+ ),
5929
+ /* @__PURE__ */ jsx(ErrorMessage, { name: "message", component: "p", className: `${baseErrorClass} ${errorClass}` })
5930
+ ] }),
5931
+ submitStatus === "error" && /* @__PURE__ */ jsx("div", { className: "p-4 bg-red-50 border border-red-200 rounded-lg", children: /* @__PURE__ */ jsx("p", { className: "text-red-800 text-sm", children: submitMessage }) }),
5932
+ /* @__PURE__ */ jsx(
5933
+ "button",
5934
+ {
5935
+ type: "submit",
5936
+ disabled: isSubmitting,
5937
+ className: `${baseButtonClass} ${buttonClass}`,
5938
+ children: isSubmitting ? /* @__PURE__ */ jsxs("span", { className: "flex items-center justify-center gap-2", children: [
5939
+ /* @__PURE__ */ jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
5940
+ /* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
5941
+ /* @__PURE__ */ 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" })
5942
+ ] }),
5943
+ "Sending..."
5944
+ ] }) : submitText
5945
+ }
5946
+ )
5947
+ ] })
5948
+ }
5949
+ ) });
5950
+ }
5951
+ var defaultInitialValues2 = {
5952
+ email: "",
5953
+ firstName: "",
5954
+ lastName: ""
5955
+ };
5956
+ function NewsletterForm({
5957
+ actionUrl,
5958
+ onSubmit,
5959
+ initialValues,
5960
+ showName = false,
5961
+ placeholder = "Enter your email",
5962
+ submitText = "Subscribe",
5963
+ successMessage = "Thank you for subscribing!",
5964
+ layout = "inline",
5965
+ className = "",
5966
+ formClass = "",
5967
+ inputClass = "",
5968
+ buttonClass = ""
5969
+ }) {
5970
+ const [submitStatus, setSubmitStatus] = useState("idle");
5971
+ const [submitMessage, setSubmitMessage] = useState("");
5972
+ const mergedInitialValues = {
5973
+ ...defaultInitialValues2,
5974
+ ...initialValues
5975
+ };
5976
+ 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";
5977
+ 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";
5978
+ const handleSubmit = async (values, { setSubmitting, resetForm }) => {
5979
+ try {
5980
+ let result;
5981
+ if (onSubmit) {
5982
+ result = await onSubmit(values);
5983
+ } else if (actionUrl) {
5984
+ const response = await fetch(actionUrl, {
5985
+ method: "POST",
5986
+ headers: { "Content-Type": "application/json" },
5987
+ body: JSON.stringify(values)
5988
+ });
5989
+ result = await response.json();
5990
+ } else {
5991
+ await new Promise((resolve2) => setTimeout(resolve2, 1e3));
5992
+ result = { success: true };
5993
+ }
5994
+ if (result.success) {
5995
+ setSubmitStatus("success");
5996
+ setSubmitMessage(result.message || successMessage);
5997
+ resetForm();
5998
+ } else {
5999
+ setSubmitStatus("error");
6000
+ setSubmitMessage(result.message || "Something went wrong. Please try again.");
6001
+ }
6002
+ } catch (error) {
6003
+ setSubmitStatus("error");
6004
+ setSubmitMessage("An error occurred. Please try again later.");
6005
+ } finally {
6006
+ setSubmitting(false);
6007
+ }
6008
+ };
6009
+ if (submitStatus === "success") {
6010
+ return /* @__PURE__ */ jsx("div", { className: `ec-newsletter-form ${className}`, children: /* @__PURE__ */ jsxs("div", { className: "p-4 bg-green-50 border border-green-200 rounded-lg text-center", children: [
6011
+ /* @__PURE__ */ jsx("p", { className: "text-green-800 font-medium", children: submitMessage }),
6012
+ /* @__PURE__ */ jsx(
6013
+ "button",
6014
+ {
6015
+ type: "button",
6016
+ onClick: () => setSubmitStatus("idle"),
6017
+ className: "mt-2 text-green-600 hover:text-green-700 text-sm",
6018
+ children: "Subscribe another email"
6019
+ }
6020
+ )
6021
+ ] }) });
6022
+ }
6023
+ return /* @__PURE__ */ jsxs("div", { className: `ec-newsletter-form ${className}`, children: [
6024
+ /* @__PURE__ */ jsx(
6025
+ Formik,
6026
+ {
6027
+ initialValues: mergedInitialValues,
6028
+ validationSchema: newsletterFormSchema,
6029
+ onSubmit: handleSubmit,
6030
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxs(
6031
+ Form,
6032
+ {
6033
+ className: `${layout === "inline" ? "flex flex-col sm:flex-row gap-3" : "space-y-4"} ${formClass}`,
6034
+ noValidate: true,
6035
+ children: [
6036
+ showName && /* @__PURE__ */ jsxs("div", { className: layout === "inline" ? "flex gap-3 flex-1" : "grid grid-cols-2 gap-4", children: [
6037
+ /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
6038
+ /* @__PURE__ */ jsx(
6039
+ Field,
6040
+ {
6041
+ type: "text",
6042
+ name: "firstName",
6043
+ placeholder: "First name",
6044
+ className: `w-full ${baseInputClass} ${inputClass} ${errors.firstName && touched.firstName ? "border-red-500" : ""}`
6045
+ }
6046
+ ),
6047
+ layout === "stacked" && /* @__PURE__ */ jsx(ErrorMessage, { name: "firstName", component: "p", className: "text-sm text-red-600 mt-1" })
6048
+ ] }),
6049
+ /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
6050
+ /* @__PURE__ */ jsx(
6051
+ Field,
6052
+ {
6053
+ type: "text",
6054
+ name: "lastName",
6055
+ placeholder: "Last name",
6056
+ className: `w-full ${baseInputClass} ${inputClass} ${errors.lastName && touched.lastName ? "border-red-500" : ""}`
6057
+ }
6058
+ ),
6059
+ layout === "stacked" && /* @__PURE__ */ jsx(ErrorMessage, { name: "lastName", component: "p", className: "text-sm text-red-600 mt-1" })
6060
+ ] })
6061
+ ] }),
6062
+ /* @__PURE__ */ jsxs("div", { className: layout === "inline" ? "flex-1" : "", children: [
6063
+ /* @__PURE__ */ jsx(
6064
+ Field,
6065
+ {
6066
+ type: "email",
6067
+ name: "email",
6068
+ placeholder,
6069
+ className: `w-full ${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500" : ""}`
6070
+ }
6071
+ ),
6072
+ layout === "stacked" && /* @__PURE__ */ jsx(ErrorMessage, { name: "email", component: "p", className: "text-sm text-red-600 mt-1" })
6073
+ ] }),
6074
+ /* @__PURE__ */ jsx(
6075
+ "button",
6076
+ {
6077
+ type: "submit",
6078
+ disabled: isSubmitting,
6079
+ className: `${baseButtonClass} ${buttonClass} ${layout === "stacked" ? "w-full" : ""}`,
6080
+ children: isSubmitting ? /* @__PURE__ */ jsxs("span", { className: "flex items-center justify-center gap-2", children: [
6081
+ /* @__PURE__ */ jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
6082
+ /* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
6083
+ /* @__PURE__ */ 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" })
6084
+ ] }),
6085
+ "Subscribing..."
6086
+ ] }) : submitText
6087
+ }
6088
+ ),
6089
+ layout === "inline" && errors.email && touched.email && /* @__PURE__ */ jsx("div", { className: "w-full sm:w-auto", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-red-600", children: errors.email }) })
6090
+ ]
6091
+ }
6092
+ )
6093
+ }
6094
+ ),
6095
+ submitStatus === "error" && /* @__PURE__ */ jsx("div", { className: "mt-4 p-4 bg-red-50 border border-red-200 rounded-lg", children: /* @__PURE__ */ jsx("p", { className: "text-red-800 text-sm", children: submitMessage }) })
6096
+ ] });
6097
+ }
6098
+ var defaultInitialValues3 = {
6099
+ email: "",
6100
+ password: "",
6101
+ rememberMe: false
6102
+ };
6103
+ function LoginForm({
6104
+ actionUrl,
6105
+ onSubmit,
6106
+ initialValues,
6107
+ showRememberMe = true,
6108
+ forgotPasswordLink = "/forgot-password",
6109
+ registerLink = "/register",
6110
+ submitText = "Sign In",
6111
+ successRedirect,
6112
+ className = "",
6113
+ formClass = "",
6114
+ inputClass = "",
6115
+ buttonClass = ""
6116
+ }) {
6117
+ const [submitStatus, setSubmitStatus] = useState("idle");
6118
+ const [submitMessage, setSubmitMessage] = useState("");
6119
+ const [showPassword, setShowPassword] = useState(false);
6120
+ const mergedInitialValues = {
6121
+ ...defaultInitialValues3,
6122
+ ...initialValues
6123
+ };
6124
+ 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";
6125
+ const baseLabelClass = "block text-sm font-medium text-gray-700 mb-1";
6126
+ const baseErrorClass = "text-sm text-red-600 mt-1";
6127
+ 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";
6128
+ const handleSubmit = async (values, { setSubmitting }) => {
6129
+ try {
6130
+ let result;
6131
+ if (onSubmit) {
6132
+ result = await onSubmit(values);
6133
+ } else if (actionUrl) {
6134
+ const response = await fetch(actionUrl, {
6135
+ method: "POST",
6136
+ headers: { "Content-Type": "application/json" },
6137
+ body: JSON.stringify(values)
6138
+ });
6139
+ result = await response.json();
6140
+ } else {
6141
+ await new Promise((resolve2) => setTimeout(resolve2, 1e3));
6142
+ result = { success: true };
6143
+ }
6144
+ if (result.success) {
6145
+ setSubmitStatus("success");
6146
+ setSubmitMessage(result.message || "Login successful!");
6147
+ if (successRedirect && typeof window !== "undefined") {
6148
+ window.location.href = successRedirect;
6149
+ }
6150
+ } else {
6151
+ setSubmitStatus("error");
6152
+ setSubmitMessage(result.message || "Invalid email or password.");
6153
+ }
6154
+ } catch (error) {
6155
+ setSubmitStatus("error");
6156
+ setSubmitMessage("An error occurred. Please try again later.");
6157
+ } finally {
6158
+ setSubmitting(false);
6159
+ }
6160
+ };
6161
+ return /* @__PURE__ */ jsx("div", { className: `ec-login-form ${className}`, children: /* @__PURE__ */ jsx(
6162
+ Formik,
6163
+ {
6164
+ initialValues: mergedInitialValues,
6165
+ validationSchema: loginFormSchema,
6166
+ onSubmit: handleSubmit,
6167
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxs(Form, { className: `space-y-4 ${formClass}`, noValidate: true, children: [
6168
+ /* @__PURE__ */ jsxs("div", { children: [
6169
+ /* @__PURE__ */ jsx("label", { htmlFor: "login-email", className: baseLabelClass, children: "Email" }),
6170
+ /* @__PURE__ */ jsx(
6171
+ Field,
6172
+ {
6173
+ type: "email",
6174
+ id: "login-email",
6175
+ name: "email",
6176
+ placeholder: "you@example.com",
6177
+ autoComplete: "email",
6178
+ className: `${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500 focus:ring-red-500" : ""}`
6179
+ }
6180
+ ),
6181
+ /* @__PURE__ */ jsx(ErrorMessage, { name: "email", component: "p", className: baseErrorClass })
6182
+ ] }),
6183
+ /* @__PURE__ */ jsxs("div", { children: [
6184
+ /* @__PURE__ */ jsx("label", { htmlFor: "login-password", className: baseLabelClass, children: "Password" }),
6185
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
6186
+ /* @__PURE__ */ jsx(
6187
+ Field,
6188
+ {
6189
+ type: showPassword ? "text" : "password",
6190
+ id: "login-password",
6191
+ name: "password",
6192
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
6193
+ autoComplete: "current-password",
6194
+ className: `${baseInputClass} ${inputClass} pr-12 ${errors.password && touched.password ? "border-red-500 focus:ring-red-500" : ""}`
6195
+ }
6196
+ ),
6197
+ /* @__PURE__ */ jsx(
6198
+ "button",
6199
+ {
6200
+ type: "button",
6201
+ onClick: () => setShowPassword(!showPassword),
6202
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700",
6203
+ tabIndex: -1,
6204
+ children: showPassword ? /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ 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__ */ jsxs("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [
6205
+ /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" }),
6206
+ /* @__PURE__ */ 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" })
6207
+ ] })
6208
+ }
6209
+ )
6210
+ ] }),
6211
+ /* @__PURE__ */ jsx(ErrorMessage, { name: "password", component: "p", className: baseErrorClass })
6212
+ ] }),
6213
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
6214
+ showRememberMe && /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [
6215
+ /* @__PURE__ */ jsx(
6216
+ Field,
6217
+ {
6218
+ type: "checkbox",
6219
+ name: "rememberMe",
6220
+ className: "w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
6221
+ }
6222
+ ),
6223
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-gray-600", children: "Remember me" })
6224
+ ] }),
6225
+ forgotPasswordLink && /* @__PURE__ */ jsx(
6226
+ "a",
6227
+ {
6228
+ href: forgotPasswordLink,
6229
+ className: "text-sm text-blue-600 hover:text-blue-700 font-medium",
6230
+ children: "Forgot password?"
6231
+ }
6232
+ )
6233
+ ] }),
6234
+ submitStatus === "error" && /* @__PURE__ */ jsx("div", { className: "p-4 bg-red-50 border border-red-200 rounded-lg", children: /* @__PURE__ */ jsx("p", { className: "text-red-800 text-sm", children: submitMessage }) }),
6235
+ /* @__PURE__ */ jsx(
6236
+ "button",
6237
+ {
6238
+ type: "submit",
6239
+ disabled: isSubmitting,
6240
+ className: `${baseButtonClass} ${buttonClass}`,
6241
+ children: isSubmitting ? /* @__PURE__ */ jsxs("span", { className: "flex items-center justify-center gap-2", children: [
6242
+ /* @__PURE__ */ jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
6243
+ /* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
6244
+ /* @__PURE__ */ 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" })
6245
+ ] }),
6246
+ "Signing in..."
6247
+ ] }) : submitText
6248
+ }
6249
+ ),
6250
+ registerLink && /* @__PURE__ */ jsxs("p", { className: "text-center text-sm text-gray-600", children: [
6251
+ "Don't have an account?",
6252
+ " ",
6253
+ /* @__PURE__ */ jsx("a", { href: registerLink, className: "text-blue-600 hover:text-blue-700 font-medium", children: "Sign up" })
6254
+ ] })
6255
+ ] })
6256
+ }
6257
+ ) });
6258
+ }
6259
+ var defaultInitialValues4 = {
6260
+ firstName: "",
6261
+ lastName: "",
6262
+ email: "",
6263
+ password: "",
6264
+ confirmPassword: "",
6265
+ acceptTerms: false
6266
+ };
6267
+ function RegisterForm({
6268
+ actionUrl,
6269
+ onSubmit,
6270
+ initialValues,
6271
+ termsLink = "/terms",
6272
+ privacyLink = "/privacy",
6273
+ loginLink = "/login",
6274
+ submitText = "Create Account",
6275
+ successRedirect,
6276
+ passwordRequirements = {
6277
+ minLength: 8,
6278
+ requireUppercase: true,
6279
+ requireLowercase: true,
6280
+ requireNumber: true,
6281
+ requireSpecial: false
6282
+ },
6283
+ className = "",
6284
+ formClass = "",
6285
+ inputClass = "",
6286
+ buttonClass = ""
6287
+ }) {
6288
+ const [submitStatus, setSubmitStatus] = useState("idle");
6289
+ const [submitMessage, setSubmitMessage] = useState("");
6290
+ const [showPassword, setShowPassword] = useState(false);
6291
+ const [showConfirmPassword, setShowConfirmPassword] = useState(false);
6292
+ const mergedInitialValues = {
6293
+ ...defaultInitialValues4,
6294
+ ...initialValues
6295
+ };
6296
+ const validationSchema = createRegisterFormSchema(passwordRequirements);
6297
+ 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";
6298
+ const baseLabelClass = "block text-sm font-medium text-gray-700 mb-1";
6299
+ const baseErrorClass = "text-sm text-red-600 mt-1";
6300
+ 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";
6301
+ const handleSubmit = async (values, { setSubmitting }) => {
6302
+ try {
6303
+ let result;
6304
+ if (onSubmit) {
6305
+ result = await onSubmit(values);
6306
+ } else if (actionUrl) {
6307
+ const response = await fetch(actionUrl, {
6308
+ method: "POST",
6309
+ headers: { "Content-Type": "application/json" },
6310
+ body: JSON.stringify(values)
6311
+ });
6312
+ result = await response.json();
6313
+ } else {
6314
+ await new Promise((resolve2) => setTimeout(resolve2, 1e3));
6315
+ result = { success: true };
6316
+ }
6317
+ if (result.success) {
6318
+ setSubmitStatus("success");
6319
+ setSubmitMessage(result.message || "Account created successfully!");
6320
+ if (successRedirect && typeof window !== "undefined") {
6321
+ window.location.href = successRedirect;
6322
+ }
6323
+ } else {
6324
+ setSubmitStatus("error");
6325
+ setSubmitMessage(result.message || "Registration failed. Please try again.");
6326
+ }
6327
+ } catch (error) {
6328
+ setSubmitStatus("error");
6329
+ setSubmitMessage("An error occurred. Please try again later.");
6330
+ } finally {
6331
+ setSubmitting(false);
6332
+ }
6333
+ };
6334
+ if (submitStatus === "success") {
6335
+ return /* @__PURE__ */ jsx("div", { className: `ec-register-form ${className}`, children: /* @__PURE__ */ jsxs("div", { className: "p-6 bg-green-50 border border-green-200 rounded-lg text-center", children: [
6336
+ /* @__PURE__ */ 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__ */ 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" }) }),
6337
+ /* @__PURE__ */ jsx("p", { className: "text-green-800 font-medium", children: submitMessage }),
6338
+ loginLink && /* @__PURE__ */ jsx(
6339
+ "a",
6340
+ {
6341
+ href: loginLink,
6342
+ className: "inline-block mt-4 text-green-600 hover:text-green-700 font-medium",
6343
+ children: "Sign in to your account"
6344
+ }
6345
+ )
6346
+ ] }) });
6347
+ }
6348
+ return /* @__PURE__ */ jsx("div", { className: `ec-register-form ${className}`, children: /* @__PURE__ */ jsx(
6349
+ Formik,
6350
+ {
6351
+ initialValues: mergedInitialValues,
6352
+ validationSchema,
6353
+ onSubmit: handleSubmit,
6354
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxs(Form, { className: `space-y-4 ${formClass}`, noValidate: true, children: [
6355
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: [
6356
+ /* @__PURE__ */ jsxs("div", { children: [
6357
+ /* @__PURE__ */ jsxs("label", { htmlFor: "register-firstName", className: baseLabelClass, children: [
6358
+ "First Name ",
6359
+ /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
6360
+ ] }),
6361
+ /* @__PURE__ */ jsx(
6362
+ Field,
6363
+ {
6364
+ type: "text",
6365
+ id: "register-firstName",
6366
+ name: "firstName",
6367
+ placeholder: "John",
6368
+ autoComplete: "given-name",
6369
+ className: `${baseInputClass} ${inputClass} ${errors.firstName && touched.firstName ? "border-red-500 focus:ring-red-500" : ""}`
6370
+ }
6371
+ ),
6372
+ /* @__PURE__ */ jsx(ErrorMessage, { name: "firstName", component: "p", className: baseErrorClass })
6373
+ ] }),
6374
+ /* @__PURE__ */ jsxs("div", { children: [
6375
+ /* @__PURE__ */ jsxs("label", { htmlFor: "register-lastName", className: baseLabelClass, children: [
6376
+ "Last Name ",
6377
+ /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
6378
+ ] }),
6379
+ /* @__PURE__ */ jsx(
6380
+ Field,
6381
+ {
6382
+ type: "text",
6383
+ id: "register-lastName",
6384
+ name: "lastName",
6385
+ placeholder: "Doe",
6386
+ autoComplete: "family-name",
6387
+ className: `${baseInputClass} ${inputClass} ${errors.lastName && touched.lastName ? "border-red-500 focus:ring-red-500" : ""}`
6388
+ }
6389
+ ),
6390
+ /* @__PURE__ */ jsx(ErrorMessage, { name: "lastName", component: "p", className: baseErrorClass })
6391
+ ] })
6392
+ ] }),
6393
+ /* @__PURE__ */ jsxs("div", { children: [
6394
+ /* @__PURE__ */ jsxs("label", { htmlFor: "register-email", className: baseLabelClass, children: [
6395
+ "Email ",
6396
+ /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
6397
+ ] }),
6398
+ /* @__PURE__ */ jsx(
6399
+ Field,
6400
+ {
6401
+ type: "email",
6402
+ id: "register-email",
6403
+ name: "email",
6404
+ placeholder: "you@example.com",
6405
+ autoComplete: "email",
6406
+ className: `${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500 focus:ring-red-500" : ""}`
6407
+ }
6408
+ ),
6409
+ /* @__PURE__ */ jsx(ErrorMessage, { name: "email", component: "p", className: baseErrorClass })
6410
+ ] }),
6411
+ /* @__PURE__ */ jsxs("div", { children: [
6412
+ /* @__PURE__ */ jsxs("label", { htmlFor: "register-password", className: baseLabelClass, children: [
6413
+ "Password ",
6414
+ /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
6415
+ ] }),
6416
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
6417
+ /* @__PURE__ */ jsx(
6418
+ Field,
6419
+ {
6420
+ type: showPassword ? "text" : "password",
6421
+ id: "register-password",
6422
+ name: "password",
6423
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
6424
+ autoComplete: "new-password",
6425
+ className: `${baseInputClass} ${inputClass} pr-12 ${errors.password && touched.password ? "border-red-500 focus:ring-red-500" : ""}`
6426
+ }
6427
+ ),
6428
+ /* @__PURE__ */ jsx(
6429
+ "button",
6430
+ {
6431
+ type: "button",
6432
+ onClick: () => setShowPassword(!showPassword),
6433
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700",
6434
+ tabIndex: -1,
6435
+ children: showPassword ? /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ 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__ */ jsxs("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [
6436
+ /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" }),
6437
+ /* @__PURE__ */ 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" })
6438
+ ] })
6439
+ }
6440
+ )
6441
+ ] }),
6442
+ /* @__PURE__ */ jsx(ErrorMessage, { name: "password", component: "p", className: baseErrorClass }),
6443
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500 mt-1", children: [
6444
+ "Min ",
6445
+ passwordRequirements.minLength,
6446
+ " characters",
6447
+ passwordRequirements.requireUppercase && ", uppercase",
6448
+ passwordRequirements.requireLowercase && ", lowercase",
6449
+ passwordRequirements.requireNumber && ", number",
6450
+ passwordRequirements.requireSpecial && ", special character"
6451
+ ] })
6452
+ ] }),
6453
+ /* @__PURE__ */ jsxs("div", { children: [
6454
+ /* @__PURE__ */ jsxs("label", { htmlFor: "register-confirmPassword", className: baseLabelClass, children: [
6455
+ "Confirm Password ",
6456
+ /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
6457
+ ] }),
6458
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
6459
+ /* @__PURE__ */ jsx(
6460
+ Field,
6461
+ {
6462
+ type: showConfirmPassword ? "text" : "password",
6463
+ id: "register-confirmPassword",
6464
+ name: "confirmPassword",
6465
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
6466
+ autoComplete: "new-password",
6467
+ className: `${baseInputClass} ${inputClass} pr-12 ${errors.confirmPassword && touched.confirmPassword ? "border-red-500 focus:ring-red-500" : ""}`
6468
+ }
6469
+ ),
6470
+ /* @__PURE__ */ jsx(
6471
+ "button",
6472
+ {
6473
+ type: "button",
6474
+ onClick: () => setShowConfirmPassword(!showConfirmPassword),
6475
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700",
6476
+ tabIndex: -1,
6477
+ children: showConfirmPassword ? /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ 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__ */ jsxs("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [
6478
+ /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" }),
6479
+ /* @__PURE__ */ 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" })
6480
+ ] })
6481
+ }
6482
+ )
6483
+ ] }),
6484
+ /* @__PURE__ */ jsx(ErrorMessage, { name: "confirmPassword", component: "p", className: baseErrorClass })
6485
+ ] }),
6486
+ /* @__PURE__ */ jsxs("div", { children: [
6487
+ /* @__PURE__ */ jsxs("label", { className: "flex items-start gap-2 cursor-pointer", children: [
6488
+ /* @__PURE__ */ jsx(
6489
+ Field,
6490
+ {
6491
+ type: "checkbox",
6492
+ name: "acceptTerms",
6493
+ className: "w-4 h-4 mt-1 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
6494
+ }
6495
+ ),
6496
+ /* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-600", children: [
6497
+ "I agree to the",
6498
+ " ",
6499
+ /* @__PURE__ */ jsx("a", { href: termsLink, className: "text-blue-600 hover:underline", target: "_blank", rel: "noopener noreferrer", children: "Terms of Service" }),
6500
+ " ",
6501
+ "and",
6502
+ " ",
6503
+ /* @__PURE__ */ jsx("a", { href: privacyLink, className: "text-blue-600 hover:underline", target: "_blank", rel: "noopener noreferrer", children: "Privacy Policy" }),
6504
+ /* @__PURE__ */ jsx("span", { className: "text-red-500", children: " *" })
6505
+ ] })
6506
+ ] }),
6507
+ /* @__PURE__ */ jsx(ErrorMessage, { name: "acceptTerms", component: "p", className: baseErrorClass })
6508
+ ] }),
6509
+ submitStatus === "error" && /* @__PURE__ */ jsx("div", { className: "p-4 bg-red-50 border border-red-200 rounded-lg", children: /* @__PURE__ */ jsx("p", { className: "text-red-800 text-sm", children: submitMessage }) }),
6510
+ /* @__PURE__ */ jsx(
6511
+ "button",
6512
+ {
6513
+ type: "submit",
6514
+ disabled: isSubmitting,
6515
+ className: `${baseButtonClass} ${buttonClass}`,
6516
+ children: isSubmitting ? /* @__PURE__ */ jsxs("span", { className: "flex items-center justify-center gap-2", children: [
6517
+ /* @__PURE__ */ jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
6518
+ /* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
6519
+ /* @__PURE__ */ 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" })
6520
+ ] }),
6521
+ "Creating account..."
6522
+ ] }) : submitText
6523
+ }
6524
+ ),
6525
+ loginLink && /* @__PURE__ */ jsxs("p", { className: "text-center text-sm text-gray-600", children: [
6526
+ "Already have an account?",
6527
+ " ",
6528
+ /* @__PURE__ */ jsx("a", { href: loginLink, className: "text-blue-600 hover:text-blue-700 font-medium", children: "Sign in" })
6529
+ ] })
6530
+ ] })
6531
+ }
6532
+ ) });
6533
+ }
6534
+
3880
6535
  // src/shared/index.ts
3881
6536
  var shared_exports = {};
3882
6537
  __export(shared_exports, {
@@ -3910,7 +6565,7 @@ __export(shared_exports, {
3910
6565
  THEME: () => THEME,
3911
6566
  TOKEN_TYPES: () => TOKEN_TYPES,
3912
6567
  USER_STATUS: () => USER_STATUS,
3913
- VALIDATION_MESSAGES: () => VALIDATION_MESSAGES,
6568
+ VALIDATION_MESSAGES: () => VALIDATION_MESSAGES2,
3914
6569
  VALIDATION_PATTERNS: () => VALIDATION_PATTERNS,
3915
6570
  VALIDATION_RULES: () => VALIDATION_RULES,
3916
6571
  VISIBILITY: () => VISIBILITY,
@@ -4833,7 +7488,7 @@ var isValidUsername = (username) => {
4833
7488
  var isValidSlug = (slug) => {
4834
7489
  return VALIDATION_PATTERNS.SLUG.test(slug);
4835
7490
  };
4836
- var VALIDATION_MESSAGES = {
7491
+ var VALIDATION_MESSAGES2 = {
4837
7492
  // Required fields
4838
7493
  REQUIRED: "This field is required",
4839
7494
  REQUIRED_FIELD: (field) => `${field} is required`,
@@ -4874,17 +7529,17 @@ var VALIDATION_MESSAGES = {
4874
7529
  var VALIDATION_RULES = {
4875
7530
  email: {
4876
7531
  pattern: VALIDATION_PATTERNS.EMAIL,
4877
- message: VALIDATION_MESSAGES.EMAIL_INVALID
7532
+ message: VALIDATION_MESSAGES2.EMAIL_INVALID
4878
7533
  },
4879
7534
  password: {
4880
7535
  minLength: 8,
4881
7536
  pattern: VALIDATION_PATTERNS.PASSWORD_MEDIUM,
4882
- message: VALIDATION_MESSAGES.PASSWORD_MEDIUM
7537
+ message: VALIDATION_MESSAGES2.PASSWORD_MEDIUM
4883
7538
  },
4884
7539
  passwordStrong: {
4885
7540
  minLength: 8,
4886
7541
  pattern: VALIDATION_PATTERNS.PASSWORD_STRONG,
4887
- message: VALIDATION_MESSAGES.PASSWORD_STRONG
7542
+ message: VALIDATION_MESSAGES2.PASSWORD_STRONG
4888
7543
  },
4889
7544
  name: {
4890
7545
  minLength: 2,
@@ -4894,15 +7549,15 @@ var VALIDATION_RULES = {
4894
7549
  minLength: 3,
4895
7550
  maxLength: 30,
4896
7551
  pattern: VALIDATION_PATTERNS.USERNAME,
4897
- message: VALIDATION_MESSAGES.USERNAME_INVALID
7552
+ message: VALIDATION_MESSAGES2.USERNAME_INVALID
4898
7553
  },
4899
7554
  phone: {
4900
7555
  pattern: VALIDATION_PATTERNS.PHONE_INTERNATIONAL,
4901
- message: VALIDATION_MESSAGES.PHONE_INVALID
7556
+ message: VALIDATION_MESSAGES2.PHONE_INVALID
4902
7557
  },
4903
7558
  url: {
4904
7559
  pattern: VALIDATION_PATTERNS.URL,
4905
- message: VALIDATION_MESSAGES.URL_INVALID
7560
+ message: VALIDATION_MESSAGES2.URL_INVALID
4906
7561
  }
4907
7562
  };
4908
7563