@insforge/react 0.2.10 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ if (typeof document !== 'undefined' && typeof window !== 'undefined') {
5
5
  if (!document.getElementById(styleId)) {
6
6
  const style = document.createElement('style');
7
7
  style.id = styleId;
8
- style.textContent = "/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n@import \"https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap\";@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-content:\"\"}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-green-100:oklch(96.2% .044 156.743);--color-green-400:oklch(79.2% .209 151.711);--color-green-600:oklch(62.7% .194 149.214);--color-green-900:oklch(39.3% .095 152.535);--color-blue-50:oklch(97% .014 254.604);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-900:oklch(37.9% .146 265.522);--color-purple-300:oklch(82.7% .119 306.383);--color-purple-500:oklch(62.7% .265 303.9);--color-purple-600:oklch(55.8% .288 302.321);--color-purple-700:oklch(49.6% .265 301.924);--color-purple-800:oklch(43.8% .218 303.724);--color-purple-900:oklch(38.1% .176 304.987);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-neutral-400:oklch(70.8% 0 0);--color-neutral-600:oklch(43.9% 0 0);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-lg:32rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25/1.875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--leading-normal:1.5;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-manrope:\"Manrope\",sans-serif}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.absolute{position:absolute}.relative{position:relative}.top-1\\/2{top:50%}.top-full{top:100%}.right-0{right:calc(var(--spacing)*0)}.right-2{right:calc(var(--spacing)*2)}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.h-3{height:calc(var(--spacing)*3)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-12{height:calc(var(--spacing)*12)}.h-16{height:calc(var(--spacing)*16)}.h-\\[18px\\]{height:18px}.h-full{height:100%}.min-h-screen{min-height:100vh}.w-3{width:calc(var(--spacing)*3)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-8{width:calc(var(--spacing)*8)}.w-10{width:calc(var(--spacing)*10)}.w-12{width:calc(var(--spacing)*12)}.w-16{width:calc(var(--spacing)*16)}.w-\\[18px\\]{width:18px}.w-full{width:100%}.max-w-\\[400px\\]{max-width:400px}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.min-w-40{min-width:calc(var(--spacing)*40)}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-y-1\\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.items-center{align-items:center}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-start{justify-content:flex-start}.gap-0{gap:calc(var(--spacing)*0)}.gap-0\\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.self-stretch{align-self:stretch}.overflow-hidden{overflow:hidden}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-none{--tw-border-style:none;border-style:none}.border-\\[\\#D4D4D4\\]{border-color:#d4d4d4}.border-\\[\\#E0E0E0\\]{border-color:#e0e0e0}.border-\\[\\#E4E4E7\\]{border-color:#e4e4e7}.border-black{border-color:var(--color-black)}.border-blue-500{border-color:var(--color-blue-500)}.border-blue-600{border-color:var(--color-blue-600)}.border-gray-200{border-color:var(--color-gray-200)}.border-neutral-400{border-color:var(--color-neutral-400)}.border-purple-300{border-color:var(--color-purple-300)}.border-red-600{border-color:var(--color-red-600)}.border-transparent{border-color:#0000}.bg-\\[\\#059669\\]{background-color:#059669}.bg-\\[\\#FAFAFA\\]{background-color:#fafafa}.bg-black{background-color:var(--color-black)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-green-100{background-color:var(--color-green-100)}.bg-purple-600{background-color:var(--color-purple-600)}.bg-red-50{background-color:var(--color-red-50)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-blue-50{--tw-gradient-from:var(--color-blue-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-white{--tw-gradient-to:var(--color-white);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.object-cover{object-fit:cover}.p-1{padding:calc(var(--spacing)*1)}.p-2{padding:calc(var(--spacing)*2)}.p-6{padding:calc(var(--spacing)*6)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.py-2{padding-block:calc(var(--spacing)*2)}.py-4{padding-block:calc(var(--spacing)*4)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-8{padding-right:calc(var(--spacing)*8)}.pl-3{padding-left:calc(var(--spacing)*3)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-manrope{font-family:var(--font-manrope)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-4{--tw-leading:calc(var(--spacing)*4);line-height:calc(var(--spacing)*4)}.leading-5{--tw-leading:calc(var(--spacing)*5);line-height:calc(var(--spacing)*5)}.leading-6{--tw-leading:calc(var(--spacing)*6);line-height:calc(var(--spacing)*6)}.leading-8{--tw-leading:calc(var(--spacing)*8);line-height:calc(var(--spacing)*8)}.leading-normal{--tw-leading:var(--leading-normal);line-height:var(--leading-normal)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-\\[\\#09090B\\]{color:#09090b}.text-\\[\\#525252\\]{color:#525252}.text-\\[\\#737373\\]{color:#737373}.text-\\[\\#828282\\]{color:#828282}.text-\\[\\#A3A3A3\\]{color:#a3a3a3}.text-\\[\\#A6A6A6\\]{color:#a6a6a6}.text-black{color:var(--color-black)}.text-blue-500{color:var(--color-blue-500)}.text-blue-900{color:var(--color-blue-900)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-green-600{color:var(--color-green-600)}.text-neutral-600{color:var(--color-neutral-600)}.text-purple-600{color:var(--color-purple-600)}.text-purple-700{color:var(--color-purple-700)}.text-purple-900{color:var(--color-purple-900)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_1px_2px_0_rgba\\(0\\,0\\,0\\,0\\.10\\)\\]{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.outline-none{--tw-outline-style:none;outline-style:none}.placeholder\\:font-normal::placeholder{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.placeholder\\:text-\\[\\#A3A3A3\\]::placeholder{color:#a3a3a3}.before\\:h-px:before{content:var(--tw-content);height:1px}.before\\:flex-1:before{content:var(--tw-content);flex:1}.before\\:bg-\\[\\#E5E5E5\\]:before{content:var(--tw-content);background-color:#e5e5e5}.before\\:content-\\[\\'\\'\\]:before{--tw-content:\"\";content:var(--tw-content)}.after\\:h-px:after{content:var(--tw-content);height:1px}.after\\:flex-1:after{content:var(--tw-content);flex:1}.after\\:bg-\\[\\#E5E5E5\\]:after{content:var(--tw-content);background-color:#e5e5e5}.after\\:content-\\[\\'\\'\\]:after{--tw-content:\"\";content:var(--tw-content)}@media (hover:hover){.hover\\:border-\\[\\#9ca3af\\]:hover{border-color:#9ca3af}.hover\\:bg-\\[\\#f9fafb\\]:hover{background-color:#f9fafb}.hover\\:bg-black\\/5:hover{background-color:#0000000d}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-black\\/5:hover{background-color:color-mix(in oklab,var(--color-black)5%,transparent)}}.hover\\:bg-blue-50:hover{background-color:var(--color-blue-50)}.hover\\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\\:bg-gray-800:hover{background-color:var(--color-gray-800)}.hover\\:bg-purple-700:hover{background-color:var(--color-purple-700)}.hover\\:bg-red-50:hover{background-color:var(--color-red-50)}.hover\\:bg-white\\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-white\\/10:hover{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.hover\\:text-gray-600:hover{color:var(--color-gray-600)}.hover\\:text-purple-800:hover{color:var(--color-purple-800)}}.focus\\:border-black:focus{border-color:var(--color-black)}.focus\\:border-purple-500:focus{border-color:var(--color-purple-500)}.focus\\:shadow-\\[0_0_0_2px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]:focus{--tw-shadow:0 0 0 2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.focus\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:bg-\\[\\#F5F5F5\\]:disabled{background-color:#f5f5f5}.disabled\\:opacity-50:disabled{opacity:.5}.disabled\\:opacity-60:disabled{opacity:.6}@media (prefers-color-scheme:dark){.dark\\:border-white{border-color:var(--color-white)}.dark\\:bg-green-900{background-color:var(--color-green-900)}.dark\\:text-gray-400{color:var(--color-gray-400)}.dark\\:text-green-400{color:var(--color-green-400)}.dark\\:text-neutral-400{color:var(--color-neutral-400)}.dark\\:text-white{color:var(--color-white)}}}@property --tw-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-translate-y{syntax:\"*\";inherits:false;initial-value:0}@property --tw-translate-z{syntax:\"*\";inherits:false;initial-value:0}@property --tw-border-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:\"*\";inherits:false}@property --tw-gradient-from{syntax:\"<color>\";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:\"<color>\";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:\"<color>\";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:\"*\";inherits:false}@property --tw-gradient-via-stops{syntax:\"*\";inherits:false}@property --tw-gradient-from-position{syntax:\"<length-percentage>\";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:\"<length-percentage>\";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:\"<length-percentage>\";inherits:false;initial-value:100%}@property --tw-leading{syntax:\"*\";inherits:false}@property --tw-font-weight{syntax:\"*\";inherits:false}@property --tw-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\"*\";inherits:false}@property --tw-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\"*\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\"*\";inherits:false}@property --tw-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\"*\";inherits:false}@property --tw-inset-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\"*\";inherits:false}@property --tw-ring-offset-width{syntax:\"<length>\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\"*\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:\"*\";inherits:false}@property --tw-content{syntax:\"*\";inherits:false;initial-value:\"\"}@keyframes spin{to{transform:rotate(360deg)}}";
8
+ style.textContent = "/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n@import \"https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap\";@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-content:\"\"}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-green-100:oklch(96.2% .044 156.743);--color-green-400:oklch(79.2% .209 151.711);--color-green-600:oklch(62.7% .194 149.214);--color-green-900:oklch(39.3% .095 152.535);--color-blue-50:oklch(97% .014 254.604);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-900:oklch(37.9% .146 265.522);--color-indigo-50:oklch(96.2% .018 272.314);--color-indigo-600:oklch(51.1% .262 276.966);--color-indigo-700:oklch(45.7% .24 277.023);--color-purple-300:oklch(82.7% .119 306.383);--color-purple-500:oklch(62.7% .265 303.9);--color-purple-600:oklch(55.8% .288 302.321);--color-purple-700:oklch(49.6% .265 301.924);--color-purple-800:oklch(43.8% .218 303.724);--color-purple-900:oklch(38.1% .176 304.987);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-neutral-100:oklch(97% 0 0);--color-neutral-400:oklch(70.8% 0 0);--color-neutral-600:oklch(43.9% 0 0);--color-neutral-800:oklch(26.9% 0 0);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-lg:32rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25/1.875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--leading-normal:1.5;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-manrope:\"Manrope\",sans-serif}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.absolute{position:absolute}.relative{position:relative}.top-1\\/2{top:50%}.top-full{top:100%}.right-0{right:calc(var(--spacing)*0)}.right-2{right:calc(var(--spacing)*2)}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.h-3{height:calc(var(--spacing)*3)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-12{height:calc(var(--spacing)*12)}.h-16{height:calc(var(--spacing)*16)}.h-\\[18px\\]{height:18px}.h-full{height:100%}.min-h-screen{min-height:100vh}.w-3{width:calc(var(--spacing)*3)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-8{width:calc(var(--spacing)*8)}.w-10{width:calc(var(--spacing)*10)}.w-12{width:calc(var(--spacing)*12)}.w-16{width:calc(var(--spacing)*16)}.w-\\[18px\\]{width:18px}.w-full{width:100%}.max-w-\\[400px\\]{max-width:400px}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.min-w-40{min-width:calc(var(--spacing)*40)}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-y-1\\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.items-center{align-items:center}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-start{justify-content:flex-start}.gap-0{gap:calc(var(--spacing)*0)}.gap-0\\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.self-stretch{align-self:stretch}.overflow-hidden{overflow:hidden}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-none{--tw-border-style:none;border-style:none}.border-\\[\\#D4D4D4\\]{border-color:#d4d4d4}.border-\\[\\#E0E0E0\\]{border-color:#e0e0e0}.border-\\[\\#E4E4E7\\]{border-color:#e4e4e7}.border-black{border-color:var(--color-black)}.border-blue-500{border-color:var(--color-blue-500)}.border-blue-600{border-color:var(--color-blue-600)}.border-gray-200{border-color:var(--color-gray-200)}.border-neutral-400{border-color:var(--color-neutral-400)}.border-purple-300{border-color:var(--color-purple-300)}.border-red-600{border-color:var(--color-red-600)}.border-transparent{border-color:#0000}.bg-\\[\\#059669\\]{background-color:#059669}.bg-\\[\\#FAFAFA\\]{background-color:#fafafa}.bg-black{background-color:var(--color-black)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-green-100{background-color:var(--color-green-100)}.bg-indigo-600{background-color:var(--color-indigo-600)}.bg-neutral-100{background-color:var(--color-neutral-100)}.bg-purple-600{background-color:var(--color-purple-600)}.bg-red-50{background-color:var(--color-red-50)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-blue-50{--tw-gradient-from:var(--color-blue-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-indigo-50{--tw-gradient-from:var(--color-indigo-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-white{--tw-gradient-to:var(--color-white);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.object-cover{object-fit:cover}.p-1{padding:calc(var(--spacing)*1)}.p-2{padding:calc(var(--spacing)*2)}.p-6{padding:calc(var(--spacing)*6)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.py-2{padding-block:calc(var(--spacing)*2)}.py-4{padding-block:calc(var(--spacing)*4)}.pt-4{padding-top:calc(var(--spacing)*4)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-8{padding-right:calc(var(--spacing)*8)}.pb-6{padding-bottom:calc(var(--spacing)*6)}.pl-3{padding-left:calc(var(--spacing)*3)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-manrope{font-family:var(--font-manrope)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-4{--tw-leading:calc(var(--spacing)*4);line-height:calc(var(--spacing)*4)}.leading-5{--tw-leading:calc(var(--spacing)*5);line-height:calc(var(--spacing)*5)}.leading-6{--tw-leading:calc(var(--spacing)*6);line-height:calc(var(--spacing)*6)}.leading-8{--tw-leading:calc(var(--spacing)*8);line-height:calc(var(--spacing)*8)}.leading-normal{--tw-leading:var(--leading-normal);line-height:var(--leading-normal)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-\\[\\#09090B\\]{color:#09090b}.text-\\[\\#525252\\]{color:#525252}.text-\\[\\#737373\\]{color:#737373}.text-\\[\\#828282\\]{color:#828282}.text-\\[\\#A3A3A3\\]{color:#a3a3a3}.text-\\[\\#A6A6A6\\]{color:#a6a6a6}.text-black{color:var(--color-black)}.text-blue-500{color:var(--color-blue-500)}.text-blue-900{color:var(--color-blue-900)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-green-600{color:var(--color-green-600)}.text-neutral-600{color:var(--color-neutral-600)}.text-purple-600{color:var(--color-purple-600)}.text-purple-700{color:var(--color-purple-700)}.text-purple-900{color:var(--color-purple-900)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_1px_2px_0_rgba\\(0\\,0\\,0\\,0\\.10\\)\\]{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.outline-none{--tw-outline-style:none;outline-style:none}.placeholder\\:font-normal::placeholder{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.placeholder\\:text-\\[\\#A3A3A3\\]::placeholder{color:#a3a3a3}.before\\:h-px:before{content:var(--tw-content);height:1px}.before\\:flex-1:before{content:var(--tw-content);flex:1}.before\\:bg-\\[\\#E5E5E5\\]:before{content:var(--tw-content);background-color:#e5e5e5}.before\\:content-\\[\\'\\'\\]:before{--tw-content:\"\";content:var(--tw-content)}.after\\:h-px:after{content:var(--tw-content);height:1px}.after\\:flex-1:after{content:var(--tw-content);flex:1}.after\\:bg-\\[\\#E5E5E5\\]:after{content:var(--tw-content);background-color:#e5e5e5}.after\\:content-\\[\\'\\'\\]:after{--tw-content:\"\";content:var(--tw-content)}@media (hover:hover){.hover\\:border-\\[\\#9ca3af\\]:hover{border-color:#9ca3af}.hover\\:bg-\\[\\#f9fafb\\]:hover{background-color:#f9fafb}.hover\\:bg-black\\/5:hover{background-color:#0000000d}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-black\\/5:hover{background-color:color-mix(in oklab,var(--color-black)5%,transparent)}}.hover\\:bg-blue-50:hover{background-color:var(--color-blue-50)}.hover\\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\\:bg-gray-800:hover{background-color:var(--color-gray-800)}.hover\\:bg-indigo-700:hover{background-color:var(--color-indigo-700)}.hover\\:bg-purple-700:hover{background-color:var(--color-purple-700)}.hover\\:bg-red-50:hover{background-color:var(--color-red-50)}.hover\\:bg-white\\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-white\\/10:hover{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.hover\\:text-gray-600:hover{color:var(--color-gray-600)}.hover\\:text-purple-800:hover{color:var(--color-purple-800)}.hover\\:underline:hover{text-decoration-line:underline}}.focus\\:border-black:focus{border-color:var(--color-black)}.focus\\:border-purple-500:focus{border-color:var(--color-purple-500)}.focus\\:shadow-\\[0_0_0_2px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]:focus{--tw-shadow:0 0 0 2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.focus\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:bg-\\[\\#F5F5F5\\]:disabled{background-color:#f5f5f5}.disabled\\:no-underline:disabled{text-decoration-line:none}.disabled\\:opacity-50:disabled{opacity:.5}.disabled\\:opacity-60:disabled{opacity:.6}@media (prefers-color-scheme:dark){.dark\\:border-white{border-color:var(--color-white)}.dark\\:bg-green-900{background-color:var(--color-green-900)}.dark\\:bg-neutral-800{background-color:var(--color-neutral-800)}.dark\\:text-gray-400{color:var(--color-gray-400)}.dark\\:text-green-400{color:var(--color-green-400)}.dark\\:text-neutral-400{color:var(--color-neutral-400)}.dark\\:text-white{color:var(--color-white)}}}@property --tw-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-translate-y{syntax:\"*\";inherits:false;initial-value:0}@property --tw-translate-z{syntax:\"*\";inherits:false;initial-value:0}@property --tw-border-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:\"*\";inherits:false}@property --tw-gradient-from{syntax:\"<color>\";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:\"<color>\";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:\"<color>\";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:\"*\";inherits:false}@property --tw-gradient-via-stops{syntax:\"*\";inherits:false}@property --tw-gradient-from-position{syntax:\"<length-percentage>\";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:\"<length-percentage>\";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:\"<length-percentage>\";inherits:false;initial-value:100%}@property --tw-leading{syntax:\"*\";inherits:false}@property --tw-font-weight{syntax:\"*\";inherits:false}@property --tw-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\"*\";inherits:false}@property --tw-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\"*\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\"*\";inherits:false}@property --tw-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\"*\";inherits:false}@property --tw-inset-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\"*\";inherits:false}@property --tw-ring-offset-width{syntax:\"<length>\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\"*\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:\"*\";inherits:false}@property --tw-content{syntax:\"*\";inherits:false;initial-value:\"\"}@keyframes spin{to{transform:rotate(360deg)}}";
9
9
  if (document.head) {
10
10
  document.head.appendChild(style);
11
11
  }
@@ -160,70 +160,6 @@ function InsforgeProvider({
160
160
  },
161
161
  [insforge, onAuthChange, syncTokenToCookie]
162
162
  );
163
- const handleAuthCallback = react.useCallback(
164
- async (params) => {
165
- try {
166
- await insforge.auth.setSession({
167
- accessToken: params.accessToken,
168
- user: {
169
- id: params.userId || "",
170
- email: params.email || "",
171
- name: params.name || "",
172
- emailVerified: false,
173
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
174
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
175
- }
176
- });
177
- const userResult = await insforge.auth.getCurrentUser();
178
- if (!userResult.data) {
179
- await insforge.auth.signOut();
180
- if (clearCookie) {
181
- try {
182
- await clearCookie();
183
- } catch (error) {
184
- }
185
- }
186
- return { success: false, error: "invalid_token" };
187
- }
188
- const profile = userResult.data.profile;
189
- const userData = {
190
- id: userResult.data.user.id,
191
- email: userResult.data.user.email,
192
- name: profile?.nickname || params.name || "",
193
- avatarUrl: profile?.avatarUrl || ""
194
- };
195
- setUser(userData);
196
- if (onAuthChange) {
197
- onAuthChange(userData);
198
- }
199
- if (syncTokenToCookie) {
200
- try {
201
- await syncTokenToCookie(params.accessToken);
202
- } catch (error) {
203
- }
204
- }
205
- return { success: true };
206
- } catch (error) {
207
- console.error("[InsforgeProvider] Auth callback failed:", error);
208
- await insforge.auth.signOut();
209
- if (clearCookie) {
210
- try {
211
- await clearCookie();
212
- } catch (error2) {
213
- }
214
- }
215
- setUser(null);
216
- if (onAuthChange) {
217
- onAuthChange(null);
218
- }
219
- return {
220
- success: false,
221
- error: error instanceof Error ? error.message : "authentication_failed"
222
- };
223
- }
224
- },
225
- [insforge, onAuthChange, syncTokenToCookie, clearCookie]
226
- );
227
163
  const signIn = react.useCallback(
228
164
  async (email, password) => {
229
165
  const sdkResult = await insforge.auth.signInWithPassword({
@@ -241,8 +177,11 @@ function InsforgeProvider({
241
177
  );
242
178
  return sdkResult.data;
243
179
  } else {
244
- const errorMessage = sdkResult.error?.message || "Invalid email or password";
245
- return { error: errorMessage };
180
+ return {
181
+ error: sdkResult.error?.message || "Invalid email or password",
182
+ statusCode: sdkResult.error?.statusCode,
183
+ errorCode: sdkResult.error?.error
184
+ };
246
185
  }
247
186
  },
248
187
  [insforge, handleAuthSuccess]
@@ -251,18 +190,23 @@ function InsforgeProvider({
251
190
  async (email, password) => {
252
191
  const sdkResult = await insforge.auth.signUp({ email, password });
253
192
  if (sdkResult.data) {
254
- await handleAuthSuccess(
255
- sdkResult.data.accessToken || "",
256
- sdkResult.data.user ? {
257
- id: sdkResult.data.user.id,
258
- email: sdkResult.data.user.email,
259
- name: sdkResult.data.user.name
260
- } : void 0
261
- );
193
+ if (sdkResult.data.accessToken) {
194
+ await handleAuthSuccess(
195
+ sdkResult.data.accessToken,
196
+ sdkResult.data.user ? {
197
+ id: sdkResult.data.user.id,
198
+ email: sdkResult.data.user.email,
199
+ name: sdkResult.data.user.name
200
+ } : void 0
201
+ );
202
+ }
262
203
  return sdkResult.data;
263
204
  } else {
264
- const errorMessage = sdkResult.error?.message || "Sign up failed";
265
- return { error: errorMessage };
205
+ return {
206
+ error: sdkResult.error?.message || "Sign up failed",
207
+ statusCode: sdkResult.error?.statusCode,
208
+ errorCode: sdkResult.error?.error
209
+ };
266
210
  }
267
211
  },
268
212
  [insforge, handleAuthSuccess]
@@ -347,7 +291,6 @@ function InsforgeProvider({
347
291
  signOut,
348
292
  updateUser,
349
293
  reloadAuth: loadAuthState,
350
- handleAuthCallback,
351
294
  baseUrl,
352
295
  sendPasswordResetCode,
353
296
  resetPassword,
@@ -1036,6 +979,7 @@ function AuthVerificationCodeInput({
1036
979
  email,
1037
980
  onChange,
1038
981
  disabled = false,
982
+ onComplete,
1039
983
  appearance = {}
1040
984
  }) {
1041
985
  const inputRefs = react.useRef([]);
@@ -1049,6 +993,9 @@ function AuthVerificationCodeInput({
1049
993
  if (digit && index < length - 1) {
1050
994
  inputRefs.current[index + 1]?.focus();
1051
995
  }
996
+ if (digit && index === length - 1 && updatedValue.length === length && onComplete) {
997
+ onComplete(updatedValue);
998
+ }
1052
999
  };
1053
1000
  const handleKeyDown = (index, e) => {
1054
1001
  if (e.key === "Backspace") {
@@ -1069,6 +1016,9 @@ function AuthVerificationCodeInput({
1069
1016
  if (/^\d+$/.test(pastedData) && pastedData.length === length) {
1070
1017
  onChange(pastedData);
1071
1018
  inputRefs.current[length - 1]?.focus();
1019
+ if (onComplete) {
1020
+ onComplete(pastedData);
1021
+ }
1072
1022
  }
1073
1023
  };
1074
1024
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(
@@ -1109,6 +1059,125 @@ function AuthVerificationCodeInput({
1109
1059
  )) })
1110
1060
  ] });
1111
1061
  }
1062
+ function AuthEmailVerificationStep({
1063
+ email,
1064
+ description,
1065
+ method = "code",
1066
+ onVerifyCode
1067
+ }) {
1068
+ const { baseUrl } = useInsforge();
1069
+ const [insforge] = react.useState(() => sdk.createClient({ baseUrl }));
1070
+ const [resendDisabled, setResendDisabled] = react.useState(true);
1071
+ const [resendCountdown, setResendCountdown] = react.useState(60);
1072
+ const [isSending, setIsSending] = react.useState(false);
1073
+ const [verificationCode, setVerificationCode] = react.useState("");
1074
+ const [isVerifying, setIsVerifying] = react.useState(false);
1075
+ const [verificationError, setVerificationError] = react.useState("");
1076
+ const defaultDescription = method === "code" ? "We've sent a 6-digit verification code to {email}. Please enter it below to verify your account. The code will expire in 10 minutes." : "We've sent a verification link to {email}. Please check your email and click the link to verify your account. The link will expire in 10 minutes.";
1077
+ react.useEffect(() => {
1078
+ const sendInitialEmail = async () => {
1079
+ try {
1080
+ if (method === "code") {
1081
+ await insforge.auth.sendVerificationCode({ email });
1082
+ } else {
1083
+ await insforge.auth.sendVerificationLink({ email });
1084
+ }
1085
+ } catch {
1086
+ }
1087
+ };
1088
+ void sendInitialEmail();
1089
+ }, [email, method, insforge.auth]);
1090
+ react.useEffect(() => {
1091
+ if (resendCountdown > 0) {
1092
+ const timer = setInterval(() => {
1093
+ setResendCountdown((prev) => {
1094
+ if (prev <= 1) {
1095
+ setResendDisabled(false);
1096
+ return 0;
1097
+ }
1098
+ return prev - 1;
1099
+ });
1100
+ }, 1e3);
1101
+ return () => clearInterval(timer);
1102
+ }
1103
+ }, [resendCountdown]);
1104
+ const handleResend = async () => {
1105
+ setResendDisabled(true);
1106
+ setResendCountdown(60);
1107
+ setIsSending(true);
1108
+ setVerificationError("");
1109
+ try {
1110
+ if (method === "code") {
1111
+ await insforge.auth.sendVerificationCode({ email });
1112
+ } else {
1113
+ await insforge.auth.sendVerificationLink({ email });
1114
+ }
1115
+ } catch {
1116
+ setResendDisabled(false);
1117
+ setResendCountdown(0);
1118
+ } finally {
1119
+ setIsSending(false);
1120
+ }
1121
+ };
1122
+ const handleVerifyCode = async (code) => {
1123
+ if (!onVerifyCode) {
1124
+ return;
1125
+ }
1126
+ setIsVerifying(true);
1127
+ setVerificationError("");
1128
+ try {
1129
+ await onVerifyCode(code);
1130
+ } catch (error) {
1131
+ setVerificationError(
1132
+ error instanceof Error ? error.message : "Invalid verification code. Please try again."
1133
+ );
1134
+ setVerificationCode("");
1135
+ } finally {
1136
+ setIsVerifying(false);
1137
+ }
1138
+ };
1139
+ const displayDescription = description || defaultDescription;
1140
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6 items-stretch", children: [
1141
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 leading-relaxed", children: displayDescription.split("{email}").map((part, index, array) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1142
+ part,
1143
+ index < array.length - 1 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-black dark:text-white", children: email })
1144
+ ] }, index)) }),
1145
+ verificationError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pl-3 py-2 pr-2 bg-red-50 border-2 border-red-600 rounded", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1146
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-6 h-6 text-red-500 shrink-0", fill: "none", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }),
1147
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-red-600 flex-1", children: verificationError })
1148
+ ] }) }),
1149
+ method === "code" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full bg-neutral-100 dark:bg-neutral-800 rounded-lg px-4 pt-4 pb-6 flex flex-col gap-4", children: [
1150
+ /* @__PURE__ */ jsxRuntime.jsx(
1151
+ AuthVerificationCodeInput,
1152
+ {
1153
+ value: verificationCode,
1154
+ onChange: setVerificationCode,
1155
+ email,
1156
+ disabled: isVerifying,
1157
+ onComplete: (code) => {
1158
+ void handleVerifyCode(code);
1159
+ }
1160
+ }
1161
+ ),
1162
+ isVerifying && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 text-center", children: "Verifying..." })
1163
+ ] }),
1164
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full text-sm text-center text-neutral-600 dark:text-neutral-400", children: [
1165
+ "Didn't receive the email?",
1166
+ " ",
1167
+ /* @__PURE__ */ jsxRuntime.jsx(
1168
+ "button",
1169
+ {
1170
+ onClick: () => {
1171
+ void handleResend();
1172
+ },
1173
+ disabled: resendDisabled || isSending,
1174
+ className: "text-black dark:text-white font-medium transition-colors disabled:cursor-not-allowed cursor-pointer hover:underline disabled:no-underline disabled:opacity-50",
1175
+ children: isSending ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
1176
+ }
1177
+ )
1178
+ ] })
1179
+ ] });
1180
+ }
1112
1181
  function SignInForm({
1113
1182
  email,
1114
1183
  password,
@@ -1135,7 +1204,11 @@ function SignInForm({
1135
1204
  signUpText = "Don't have an account?",
1136
1205
  signUpLinkText = "Sign Up Now",
1137
1206
  signUpUrl = "/sign-up",
1138
- dividerText = "or"
1207
+ dividerText = "or",
1208
+ // Email verification step props
1209
+ showVerificationStep = false,
1210
+ onVerifyCode,
1211
+ verificationDescription
1139
1212
  }) {
1140
1213
  return /* @__PURE__ */ jsxRuntime.jsxs(
1141
1214
  AuthContainer,
@@ -1148,8 +1221,8 @@ function SignInForm({
1148
1221
  /* @__PURE__ */ jsxRuntime.jsx(
1149
1222
  AuthHeader,
1150
1223
  {
1151
- title,
1152
- subtitle,
1224
+ title: showVerificationStep ? "Verify Your Email" : title,
1225
+ subtitle: showVerificationStep ? "" : subtitle,
1153
1226
  appearance: {
1154
1227
  containerClassName: appearance.header?.container,
1155
1228
  titleClassName: appearance.header?.title,
@@ -1164,7 +1237,14 @@ function SignInForm({
1164
1237
  className: appearance.errorBanner
1165
1238
  }
1166
1239
  ),
1167
- /* @__PURE__ */ jsxRuntime.jsxs(
1240
+ showVerificationStep ? /* @__PURE__ */ jsxRuntime.jsx(
1241
+ AuthEmailVerificationStep,
1242
+ {
1243
+ email,
1244
+ description: verificationDescription,
1245
+ onVerifyCode
1246
+ }
1247
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(
1168
1248
  "form",
1169
1249
  {
1170
1250
  onSubmit,
@@ -1223,39 +1303,41 @@ function SignInForm({
1223
1303
  ]
1224
1304
  }
1225
1305
  ),
1226
- /* @__PURE__ */ jsxRuntime.jsx(
1227
- AuthLink,
1228
- {
1229
- text: signUpText,
1230
- linkText: signUpLinkText,
1231
- href: signUpUrl,
1232
- appearance: {
1233
- containerClassName: appearance.link?.container,
1234
- linkClassName: appearance.link?.link
1235
- }
1236
- }
1237
- ),
1238
- availableProviders.length > 0 && onOAuthClick && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1239
- /* @__PURE__ */ jsxRuntime.jsx(
1240
- AuthDivider,
1241
- {
1242
- text: dividerText,
1243
- className: appearance.divider
1244
- }
1245
- ),
1306
+ !showVerificationStep && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1246
1307
  /* @__PURE__ */ jsxRuntime.jsx(
1247
- AuthOAuthProviders,
1308
+ AuthLink,
1248
1309
  {
1249
- providers: availableProviders,
1250
- onClick: onOAuthClick,
1251
- disabled: loading || oauthLoading !== null,
1252
- loading: oauthLoading,
1310
+ text: signUpText,
1311
+ linkText: signUpLinkText,
1312
+ href: signUpUrl,
1253
1313
  appearance: {
1254
- containerClassName: appearance.oauth?.container,
1255
- buttonClassName: appearance.oauth?.button
1314
+ containerClassName: appearance.link?.container,
1315
+ linkClassName: appearance.link?.link
1256
1316
  }
1257
1317
  }
1258
- )
1318
+ ),
1319
+ availableProviders.length > 0 && onOAuthClick && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1320
+ /* @__PURE__ */ jsxRuntime.jsx(
1321
+ AuthDivider,
1322
+ {
1323
+ text: dividerText,
1324
+ className: appearance.divider
1325
+ }
1326
+ ),
1327
+ /* @__PURE__ */ jsxRuntime.jsx(
1328
+ AuthOAuthProviders,
1329
+ {
1330
+ providers: availableProviders,
1331
+ onClick: onOAuthClick,
1332
+ disabled: loading || oauthLoading !== null,
1333
+ loading: oauthLoading,
1334
+ appearance: {
1335
+ containerClassName: appearance.oauth?.container,
1336
+ buttonClassName: appearance.oauth?.button
1337
+ }
1338
+ }
1339
+ )
1340
+ ] })
1259
1341
  ] })
1260
1342
  ]
1261
1343
  }
@@ -1273,6 +1355,7 @@ function SignIn({
1273
1355
  const [password, setPassword] = react.useState("");
1274
1356
  const [error, setError] = react.useState("");
1275
1357
  const [loading, setLoading] = react.useState(false);
1358
+ const [step, setStep] = react.useState("form");
1276
1359
  const [oauthLoading, setOauthLoading] = react.useState(
1277
1360
  null
1278
1361
  );
@@ -1284,6 +1367,11 @@ function SignIn({
1284
1367
  try {
1285
1368
  const result = await signIn(email, password);
1286
1369
  if ("error" in result) {
1370
+ if (result.statusCode === 403) {
1371
+ setStep("awaiting-verification");
1372
+ setLoading(false);
1373
+ return;
1374
+ }
1287
1375
  throw new Error(result.error);
1288
1376
  }
1289
1377
  const { user, accessToken } = result;
@@ -1298,6 +1386,21 @@ function SignIn({
1298
1386
  setLoading(false);
1299
1387
  }
1300
1388
  }
1389
+ async function handleVerifyCode(code) {
1390
+ try {
1391
+ const result = await insforge.auth.verifyEmail({ email, otp: code });
1392
+ if (result.error) {
1393
+ throw new Error(result.error.message || "Verification failed");
1394
+ }
1395
+ if (result.data?.accessToken) {
1396
+ if (onSuccess && result.data.user) {
1397
+ onSuccess(result.data.user, result.data.accessToken);
1398
+ }
1399
+ }
1400
+ } catch (err) {
1401
+ throw new Error(err.message || "Invalid verification code");
1402
+ }
1403
+ }
1301
1404
  async function handleOAuth(provider) {
1302
1405
  try {
1303
1406
  setOauthLoading(provider);
@@ -1330,6 +1433,8 @@ function SignIn({
1330
1433
  availableProviders: emailConfig?.oAuthProviders || [],
1331
1434
  onOAuthClick: handleOAuth,
1332
1435
  emailAuthConfig: emailConfig,
1436
+ showVerificationStep: step === "awaiting-verification",
1437
+ onVerifyCode: handleVerifyCode,
1333
1438
  ...uiProps
1334
1439
  }
1335
1440
  );
@@ -1358,7 +1463,11 @@ function SignUpForm({
1358
1463
  signInText = "Already have an account?",
1359
1464
  signInLinkText = "Login Now",
1360
1465
  signInUrl = "/sign-in",
1361
- dividerText = "or"
1466
+ dividerText = "or",
1467
+ // Email verification step props
1468
+ showVerificationStep = false,
1469
+ onVerifyCode,
1470
+ verificationDescription
1362
1471
  }) {
1363
1472
  return /* @__PURE__ */ jsxRuntime.jsxs(
1364
1473
  AuthContainer,
@@ -1371,8 +1480,8 @@ function SignUpForm({
1371
1480
  /* @__PURE__ */ jsxRuntime.jsx(
1372
1481
  AuthHeader,
1373
1482
  {
1374
- title,
1375
- subtitle,
1483
+ title: showVerificationStep ? "Verify Your Email" : title,
1484
+ subtitle: showVerificationStep ? "" : subtitle,
1376
1485
  appearance: {
1377
1486
  containerClassName: appearance.header?.container,
1378
1487
  titleClassName: appearance.header?.title,
@@ -1387,7 +1496,14 @@ function SignUpForm({
1387
1496
  className: appearance.errorBanner
1388
1497
  }
1389
1498
  ),
1390
- /* @__PURE__ */ jsxRuntime.jsxs(
1499
+ showVerificationStep ? /* @__PURE__ */ jsxRuntime.jsx(
1500
+ AuthEmailVerificationStep,
1501
+ {
1502
+ email,
1503
+ description: verificationDescription,
1504
+ onVerifyCode
1505
+ }
1506
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(
1391
1507
  "form",
1392
1508
  {
1393
1509
  onSubmit,
@@ -1444,44 +1560,117 @@ function SignUpForm({
1444
1560
  ]
1445
1561
  }
1446
1562
  ),
1447
- /* @__PURE__ */ jsxRuntime.jsx(
1448
- AuthLink,
1449
- {
1450
- text: signInText,
1451
- linkText: signInLinkText,
1452
- href: signInUrl,
1453
- appearance: {
1454
- containerClassName: appearance.link?.container,
1455
- linkClassName: appearance.link?.link
1456
- }
1457
- }
1458
- ),
1459
- availableProviders.length > 0 && onOAuthClick && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1563
+ !showVerificationStep && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1460
1564
  /* @__PURE__ */ jsxRuntime.jsx(
1461
- AuthDivider,
1565
+ AuthLink,
1462
1566
  {
1463
- text: dividerText,
1464
- className: appearance.divider
1465
- }
1466
- ),
1467
- /* @__PURE__ */ jsxRuntime.jsx(
1468
- AuthOAuthProviders,
1469
- {
1470
- providers: availableProviders,
1471
- onClick: onOAuthClick,
1472
- disabled: loading || oauthLoading !== null,
1473
- loading: oauthLoading,
1567
+ text: signInText,
1568
+ linkText: signInLinkText,
1569
+ href: signInUrl,
1474
1570
  appearance: {
1475
- containerClassName: appearance.oauth?.container,
1476
- buttonClassName: appearance.oauth?.button
1571
+ containerClassName: appearance.link?.container,
1572
+ linkClassName: appearance.link?.link
1477
1573
  }
1478
1574
  }
1479
- )
1575
+ ),
1576
+ availableProviders.length > 0 && onOAuthClick && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1577
+ /* @__PURE__ */ jsxRuntime.jsx(
1578
+ AuthDivider,
1579
+ {
1580
+ text: dividerText,
1581
+ className: appearance.divider
1582
+ }
1583
+ ),
1584
+ /* @__PURE__ */ jsxRuntime.jsx(
1585
+ AuthOAuthProviders,
1586
+ {
1587
+ providers: availableProviders,
1588
+ onClick: onOAuthClick,
1589
+ disabled: loading || oauthLoading !== null,
1590
+ loading: oauthLoading,
1591
+ appearance: {
1592
+ containerClassName: appearance.oauth?.container,
1593
+ buttonClassName: appearance.oauth?.button
1594
+ }
1595
+ }
1596
+ )
1597
+ ] })
1480
1598
  ] })
1481
1599
  ]
1482
1600
  }
1483
1601
  );
1484
1602
  }
1603
+ var emailSchema = zod.z.string().min(1, "Email is required").email("Invalid email address");
1604
+ function createPasswordSchema(options) {
1605
+ const {
1606
+ minLength = 6,
1607
+ requireUppercase = false,
1608
+ requireLowercase = false,
1609
+ requireNumber = false,
1610
+ requireSpecialChar = false
1611
+ } = options || {};
1612
+ let schema = zod.z.string().min(minLength, `Password must be at least ${minLength} characters`);
1613
+ if (requireUppercase) {
1614
+ schema = schema.regex(/[A-Z]/, "Password must contain at least one uppercase letter");
1615
+ }
1616
+ if (requireLowercase) {
1617
+ schema = schema.regex(/[a-z]/, "Password must contain at least one lowercase letter");
1618
+ }
1619
+ if (requireNumber) {
1620
+ schema = schema.regex(/\d/, "Password must contain at least one number");
1621
+ }
1622
+ if (requireSpecialChar) {
1623
+ schema = schema.regex(
1624
+ /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/,
1625
+ "Password must contain at least one special character"
1626
+ );
1627
+ }
1628
+ return schema;
1629
+ }
1630
+ var passwordSchema = createPasswordSchema();
1631
+ function validateEmail(email) {
1632
+ const result = emailSchema.safeParse(email);
1633
+ if (result.success) {
1634
+ return { valid: true };
1635
+ }
1636
+ return { valid: false, error: result.error.message };
1637
+ }
1638
+ function validatePassword(password, options) {
1639
+ const schema = createPasswordSchema(options);
1640
+ const result = schema.safeParse(password);
1641
+ if (result.success) {
1642
+ return { valid: true };
1643
+ }
1644
+ return { valid: false, error: result.error.message };
1645
+ }
1646
+ function checkPasswordStrength(password) {
1647
+ const feedback = [];
1648
+ let score = 0;
1649
+ if (password.length >= 8) {
1650
+ score += 1;
1651
+ } else {
1652
+ feedback.push("Use at least 8 characters");
1653
+ }
1654
+ if (password.length >= 12) {
1655
+ score += 1;
1656
+ }
1657
+ if (/[a-z]/.test(password) && /[A-Z]/.test(password)) {
1658
+ score += 1;
1659
+ } else {
1660
+ feedback.push("Use both uppercase and lowercase letters");
1661
+ }
1662
+ if (/\d/.test(password)) {
1663
+ score += 1;
1664
+ } else {
1665
+ feedback.push("Include at least one number");
1666
+ }
1667
+ if (/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(password)) {
1668
+ score += 1;
1669
+ } else {
1670
+ feedback.push("Include at least one special character");
1671
+ }
1672
+ return { score, feedback };
1673
+ }
1485
1674
  function SignUp({
1486
1675
  afterSignUpUrl,
1487
1676
  onSuccess,
@@ -1494,6 +1683,7 @@ function SignUp({
1494
1683
  const [password, setPassword] = react.useState("");
1495
1684
  const [error, setError] = react.useState("");
1496
1685
  const [loading, setLoading] = react.useState(false);
1686
+ const [step, setStep] = react.useState("form");
1497
1687
  const [oauthLoading, setOauthLoading] = react.useState(
1498
1688
  null
1499
1689
  );
@@ -1502,19 +1692,46 @@ function SignUp({
1502
1692
  e.preventDefault();
1503
1693
  setLoading(true);
1504
1694
  setError("");
1505
- if (emailConfig && !validatePasswordStrength(password, emailConfig)) {
1506
- setError("Password does not meet all requirements");
1695
+ if (!emailConfig) {
1696
+ setError("Configuration not loaded. Please refresh the page.");
1697
+ setLoading(false);
1698
+ return;
1699
+ }
1700
+ const emailValidation = emailSchema.safeParse(email);
1701
+ if (!emailValidation.success) {
1702
+ const firstError = emailValidation.error.issues[0];
1703
+ setError(firstError.message);
1704
+ setLoading(false);
1705
+ return;
1706
+ }
1707
+ const passwordZodSchema = createPasswordSchema({
1708
+ minLength: emailConfig.passwordMinLength,
1709
+ requireUppercase: emailConfig.requireUppercase,
1710
+ requireLowercase: emailConfig.requireLowercase,
1711
+ requireNumber: emailConfig.requireNumber,
1712
+ requireSpecialChar: emailConfig.requireSpecialChar
1713
+ });
1714
+ const passwordValidation = passwordZodSchema.safeParse(password);
1715
+ if (!passwordValidation.success) {
1716
+ const firstError = passwordValidation.error.issues[0];
1717
+ setError(firstError.message);
1507
1718
  setLoading(false);
1508
1719
  return;
1509
1720
  }
1510
1721
  try {
1511
- const result = await signUp(email, password);
1722
+ const result = await signUp(emailValidation.data, password);
1512
1723
  if ("error" in result) {
1513
1724
  throw new Error(result.error);
1514
1725
  }
1515
- const { user, accessToken } = result;
1516
- if (onSuccess) {
1517
- if (user) onSuccess(user, accessToken || "");
1726
+ if (result.requiresEmailVerification && !result.accessToken) {
1727
+ setStep("awaiting-verification");
1728
+ setLoading(false);
1729
+ return;
1730
+ }
1731
+ if (result.accessToken && result.user) {
1732
+ if (onSuccess) {
1733
+ onSuccess(result.user, result.accessToken);
1734
+ }
1518
1735
  }
1519
1736
  } catch (err) {
1520
1737
  const errorMessage = err.message || "Sign up failed";
@@ -1524,6 +1741,21 @@ function SignUp({
1524
1741
  setLoading(false);
1525
1742
  }
1526
1743
  }
1744
+ async function handleVerifyCode(code) {
1745
+ try {
1746
+ const result = await insforge.auth.verifyEmail({ email, otp: code });
1747
+ if (result.error) {
1748
+ throw new Error(result.error.message || "Verification failed");
1749
+ }
1750
+ if (result.data?.accessToken) {
1751
+ if (onSuccess && result.data.user) {
1752
+ onSuccess(result.data.user, result.data.accessToken);
1753
+ }
1754
+ }
1755
+ } catch (err) {
1756
+ throw new Error(err.message || "Invalid verification code");
1757
+ }
1758
+ }
1527
1759
  async function handleOAuth(provider) {
1528
1760
  try {
1529
1761
  setOauthLoading(provider);
@@ -1556,247 +1788,12 @@ function SignUp({
1556
1788
  availableProviders: emailConfig?.oAuthProviders || [],
1557
1789
  onOAuthClick: handleOAuth,
1558
1790
  emailAuthConfig: emailConfig,
1791
+ showVerificationStep: step === "awaiting-verification",
1792
+ onVerifyCode: handleVerifyCode,
1559
1793
  ...uiProps
1560
1794
  }
1561
1795
  );
1562
1796
  }
1563
- function UserButton({
1564
- afterSignOutUrl = "/",
1565
- mode = "detailed",
1566
- appearance = {}
1567
- }) {
1568
- const { user, signOut } = useInsforge();
1569
- const [isOpen, setIsOpen] = react.useState(false);
1570
- const [imageError, setImageError] = react.useState(false);
1571
- const dropdownRef = react.useRef(null);
1572
- react.useEffect(() => {
1573
- setImageError(false);
1574
- const avatarUrl = user?.avatarUrl;
1575
- if (!avatarUrl) return;
1576
- const checkImageUrl = async () => {
1577
- try {
1578
- const response = await fetch(avatarUrl, {
1579
- method: "HEAD",
1580
- cache: "no-cache"
1581
- });
1582
- if (!response.ok) {
1583
- setImageError(true);
1584
- }
1585
- } catch (error) {
1586
- setImageError(true);
1587
- }
1588
- };
1589
- checkImageUrl();
1590
- }, [user?.avatarUrl]);
1591
- react.useEffect(() => {
1592
- function handleClickOutside(event) {
1593
- if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
1594
- setIsOpen(false);
1595
- }
1596
- }
1597
- if (isOpen) {
1598
- document.addEventListener("mousedown", handleClickOutside);
1599
- }
1600
- return () => {
1601
- document.removeEventListener("mousedown", handleClickOutside);
1602
- };
1603
- }, [isOpen]);
1604
- async function handleSignOut() {
1605
- await signOut();
1606
- setIsOpen(false);
1607
- window.location.href = afterSignOutUrl;
1608
- }
1609
- if (!user) return null;
1610
- const initials = user.name ? user.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
1611
- return /* @__PURE__ */ jsxRuntime.jsxs(
1612
- "div",
1613
- {
1614
- className: cn("relative inline-block", appearance.containerClassName),
1615
- ref: dropdownRef,
1616
- children: [
1617
- /* @__PURE__ */ jsxRuntime.jsxs(
1618
- "button",
1619
- {
1620
- className: cn(
1621
- "p-1 bg-transparent border-0 rounded-full cursor-pointer transition-all duration-200",
1622
- "flex items-center justify-center gap-2",
1623
- "hover:bg-black/5",
1624
- mode === "detailed" && "rounded-lg p-2",
1625
- appearance.buttonClassName
1626
- ),
1627
- onClick: () => setIsOpen(!isOpen),
1628
- "aria-expanded": isOpen,
1629
- "aria-haspopup": "true",
1630
- children: [
1631
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center w-10 h-10 bg-blue-500 rounded-full", children: user.avatarUrl && !imageError ? /* @__PURE__ */ jsxRuntime.jsx(
1632
- "img",
1633
- {
1634
- src: user.avatarUrl,
1635
- alt: user.email,
1636
- onError: () => setImageError(true),
1637
- className: "rounded-full object-cover w-full h-full"
1638
- }
1639
- ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-white font-semibold text-sm", children: initials }) }),
1640
- mode === "detailed" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-0.5", children: [
1641
- user.name && /* @__PURE__ */ jsxRuntime.jsx(
1642
- "div",
1643
- {
1644
- className: cn(
1645
- "text-sm font-semibold text-gray-900 leading-5 text-left",
1646
- appearance.nameClassName
1647
- ),
1648
- children: user.name
1649
- }
1650
- ),
1651
- /* @__PURE__ */ jsxRuntime.jsx(
1652
- "div",
1653
- {
1654
- className: cn(
1655
- "text-xs text-gray-500 leading-4 text-left",
1656
- appearance.emailClassName
1657
- ),
1658
- children: user.email
1659
- }
1660
- )
1661
- ] })
1662
- ]
1663
- }
1664
- ),
1665
- isOpen && /* @__PURE__ */ jsxRuntime.jsx(
1666
- "div",
1667
- {
1668
- className: cn(
1669
- "absolute top-full right-0 mt-2 min-w-40",
1670
- "bg-white border border-gray-200 rounded-lg",
1671
- "shadow-lg z-50 overflow-hidden p-1",
1672
- appearance.dropdownClassName
1673
- ),
1674
- children: /* @__PURE__ */ jsxRuntime.jsxs(
1675
- "button",
1676
- {
1677
- onClick: handleSignOut,
1678
- className: "flex items-center justify-start gap-2 w-full px-3 py-2 text-sm font-normal text-red-600 bg-transparent border-0 rounded-md cursor-pointer transition-colors hover:bg-red-50 text-left",
1679
- children: [
1680
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LogOut, { className: "w-5 h-5" }),
1681
- "Sign out"
1682
- ]
1683
- }
1684
- )
1685
- }
1686
- )
1687
- ]
1688
- }
1689
- );
1690
- }
1691
- function Protect({
1692
- children,
1693
- fallback,
1694
- redirectTo = "/sign-in",
1695
- condition,
1696
- onRedirect
1697
- }) {
1698
- const { isSignedIn, isLoaded, user } = useInsforge();
1699
- react.useEffect(() => {
1700
- if (isLoaded && !isSignedIn) {
1701
- if (onRedirect) {
1702
- onRedirect(redirectTo);
1703
- } else {
1704
- window.location.href = redirectTo;
1705
- }
1706
- } else if (isLoaded && isSignedIn && condition && user) {
1707
- if (!condition(user)) {
1708
- if (onRedirect) {
1709
- onRedirect(redirectTo);
1710
- } else {
1711
- window.location.href = redirectTo;
1712
- }
1713
- }
1714
- }
1715
- }, [isLoaded, isSignedIn, redirectTo, condition, user, onRedirect]);
1716
- if (!isLoaded) {
1717
- return fallback || /* @__PURE__ */ jsxRuntime.jsx("div", { className: "insforge-loading", children: "Loading..." });
1718
- }
1719
- if (!isSignedIn) {
1720
- return fallback || null;
1721
- }
1722
- if (condition && user && !condition(user)) {
1723
- return fallback || null;
1724
- }
1725
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
1726
- }
1727
- function SignedIn({ children }) {
1728
- const { isSignedIn, isLoaded } = useInsforge();
1729
- if (!isLoaded) return null;
1730
- if (!isSignedIn) return null;
1731
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
1732
- }
1733
- function SignedOut({ children }) {
1734
- const { isSignedIn, isLoaded } = useInsforge();
1735
- if (!isLoaded) return null;
1736
- if (isSignedIn) return null;
1737
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
1738
- }
1739
- function InsforgeCallback({
1740
- redirectTo = "/",
1741
- onSuccess,
1742
- onError,
1743
- loadingComponent,
1744
- onRedirect
1745
- }) {
1746
- const isProcessingRef = react.useRef(false);
1747
- const { isLoaded, isSignedIn } = useInsforge();
1748
- react.useEffect(() => {
1749
- if (!isLoaded) return;
1750
- if (isProcessingRef.current) return;
1751
- isProcessingRef.current = true;
1752
- const processCallback = async () => {
1753
- const searchParams = new URLSearchParams(window.location.search);
1754
- const error = searchParams.get("error");
1755
- if (error) {
1756
- if (onError) {
1757
- onError(error);
1758
- } else {
1759
- const errorUrl = "/?error=" + encodeURIComponent(error);
1760
- if (onRedirect) {
1761
- onRedirect(errorUrl);
1762
- } else {
1763
- window.location.href = errorUrl;
1764
- }
1765
- }
1766
- return;
1767
- }
1768
- if (!isSignedIn) {
1769
- const errorMsg = "authentication_failed";
1770
- if (onError) {
1771
- onError(errorMsg);
1772
- } else {
1773
- const errorUrl = "/?error=" + encodeURIComponent(errorMsg);
1774
- if (onRedirect) {
1775
- onRedirect(errorUrl);
1776
- } else {
1777
- window.location.href = errorUrl;
1778
- }
1779
- }
1780
- return;
1781
- }
1782
- window.history.replaceState({}, "", window.location.pathname);
1783
- if (onSuccess) {
1784
- onSuccess();
1785
- }
1786
- if (onRedirect) {
1787
- onRedirect(redirectTo);
1788
- } else {
1789
- window.location.href = redirectTo;
1790
- }
1791
- };
1792
- processCallback();
1793
- }, [isLoaded, isSignedIn, redirectTo, onSuccess, onError, onRedirect]);
1794
- const defaultLoading = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
1795
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold mb-4", children: "Completing authentication..." }),
1796
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto" })
1797
- ] }) });
1798
- return loadingComponent || defaultLoading;
1799
- }
1800
1797
  function ForgotPasswordForm({
1801
1798
  email,
1802
1799
  onEmailChange,
@@ -2017,27 +2014,323 @@ function ResetPasswordForm({
2017
2014
  ]
2018
2015
  }
2019
2016
  ),
2020
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: appearance.backToSignIn || "text-center text-sm text-gray-600 dark:text-gray-400", children: [
2021
- backToSignInText && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
2022
- backToSignInText,
2023
- " "
2024
- ] }),
2025
- /* @__PURE__ */ jsxRuntime.jsx("a", { href: backToSignInUrl, className: "text-black dark:text-white font-medium", children: "Back to Sign In" })
2026
- ] })
2017
+ /* @__PURE__ */ jsxRuntime.jsx(
2018
+ AuthLink,
2019
+ {
2020
+ text: backToSignInText,
2021
+ linkText: "Back to Sign In",
2022
+ href: backToSignInUrl,
2023
+ appearance: {
2024
+ containerClassName: appearance.link?.container,
2025
+ linkClassName: appearance.link?.link
2026
+ }
2027
+ }
2028
+ )
2027
2029
  ]
2028
2030
  }
2029
2031
  );
2030
2032
  }
2031
- function VerifyEmailStatus({
2032
- status,
2033
- error,
2034
- appearance = {},
2035
- verifyingTitle = "Verifying your email...",
2036
- successTitle = "Email Verified!",
2037
- successMessage = "Your email has been verified successfully. You can close this page and return to your app.",
2038
- errorTitle = "Verification Failed"
2033
+ function ResetPassword({
2034
+ token,
2035
+ backToSignInUrl = "/sign-in",
2036
+ onSuccess,
2037
+ onError,
2038
+ ...uiProps
2039
2039
  }) {
2040
- if (status === "verifying") {
2040
+ const { resetPassword } = useInsforge();
2041
+ const { emailConfig } = usePublicAuthConfig();
2042
+ const [newPassword, setNewPassword] = react.useState("");
2043
+ const [confirmPassword, setConfirmPassword] = react.useState("");
2044
+ const [error, setError] = react.useState("");
2045
+ const [loading, setLoading] = react.useState(false);
2046
+ async function handleSubmit(e) {
2047
+ e.preventDefault();
2048
+ setLoading(true);
2049
+ setError("");
2050
+ if (!emailConfig) {
2051
+ setError("Configuration not loaded. Please refresh the page.");
2052
+ setLoading(false);
2053
+ return;
2054
+ }
2055
+ if (newPassword !== confirmPassword) {
2056
+ setError("Passwords do not match");
2057
+ setLoading(false);
2058
+ return;
2059
+ }
2060
+ if (!token) {
2061
+ setError("Reset token is missing");
2062
+ setLoading(false);
2063
+ return;
2064
+ }
2065
+ const passwordZodSchema = createPasswordSchema({
2066
+ minLength: emailConfig.passwordMinLength,
2067
+ requireUppercase: emailConfig.requireUppercase,
2068
+ requireLowercase: emailConfig.requireLowercase,
2069
+ requireNumber: emailConfig.requireNumber,
2070
+ requireSpecialChar: emailConfig.requireSpecialChar
2071
+ });
2072
+ const passwordValidation = passwordZodSchema.safeParse(newPassword);
2073
+ if (!passwordValidation.success) {
2074
+ const firstError = passwordValidation.error.issues[0];
2075
+ setError(firstError.message);
2076
+ setLoading(false);
2077
+ return;
2078
+ }
2079
+ try {
2080
+ const result = await resetPassword(token, newPassword);
2081
+ if (result?.message) {
2082
+ if (onSuccess) {
2083
+ onSuccess(result.redirectTo);
2084
+ }
2085
+ } else {
2086
+ const errorMessage = "Failed to reset password";
2087
+ setError(errorMessage);
2088
+ if (onError) {
2089
+ onError(new Error(errorMessage));
2090
+ }
2091
+ }
2092
+ } catch (err) {
2093
+ const errorMessage = err.message || "Failed to reset password";
2094
+ setError(errorMessage);
2095
+ if (onError) {
2096
+ onError(new Error(errorMessage));
2097
+ }
2098
+ } finally {
2099
+ setLoading(false);
2100
+ }
2101
+ }
2102
+ if (!emailConfig) {
2103
+ return null;
2104
+ }
2105
+ return /* @__PURE__ */ jsxRuntime.jsx(
2106
+ ResetPasswordForm,
2107
+ {
2108
+ newPassword,
2109
+ confirmPassword,
2110
+ onNewPasswordChange: setNewPassword,
2111
+ onConfirmPasswordChange: setConfirmPassword,
2112
+ onSubmit: handleSubmit,
2113
+ error,
2114
+ loading,
2115
+ emailAuthConfig: emailConfig,
2116
+ backToSignInUrl,
2117
+ ...uiProps
2118
+ }
2119
+ );
2120
+ }
2121
+ function ForgotPassword({
2122
+ backToSignInUrl = "/sign-in",
2123
+ onSuccess,
2124
+ onError,
2125
+ ...uiProps
2126
+ }) {
2127
+ const { sendPasswordResetCode, baseUrl } = useInsforge();
2128
+ const { emailConfig } = usePublicAuthConfig();
2129
+ const [insforge] = react.useState(() => sdk.createClient({ baseUrl }));
2130
+ const [step, setStep] = react.useState("email");
2131
+ const [email, setEmail] = react.useState("");
2132
+ const [verificationCode, setVerificationCode] = react.useState("");
2133
+ const [resetToken, setResetToken] = react.useState("");
2134
+ const [error, setError] = react.useState("");
2135
+ const [loading, setLoading] = react.useState(false);
2136
+ const [success, setSuccess] = react.useState(false);
2137
+ const [resendDisabled, setResendDisabled] = react.useState(true);
2138
+ const [resendCountdown, setResendCountdown] = react.useState(60);
2139
+ const [isSendingCode, setIsSendingCode] = react.useState(false);
2140
+ const [isVerifyingCode, setIsVerifyingCode] = react.useState(false);
2141
+ react.useEffect(() => {
2142
+ if (resendCountdown > 0 && step === "code") {
2143
+ const timer = setInterval(() => {
2144
+ setResendCountdown((prev) => {
2145
+ if (prev <= 1) {
2146
+ setResendDisabled(false);
2147
+ return 0;
2148
+ }
2149
+ return prev - 1;
2150
+ });
2151
+ }, 1e3);
2152
+ return () => clearInterval(timer);
2153
+ }
2154
+ }, [resendCountdown, step]);
2155
+ async function handleEmailSubmit(e) {
2156
+ e.preventDefault();
2157
+ setLoading(true);
2158
+ setError("");
2159
+ const emailValidation = emailSchema.safeParse(email);
2160
+ if (!emailValidation.success) {
2161
+ const firstError = emailValidation.error.issues[0];
2162
+ setError(firstError.message);
2163
+ setLoading(false);
2164
+ return;
2165
+ }
2166
+ try {
2167
+ const result = await sendPasswordResetCode(emailValidation.data);
2168
+ if (result?.success) {
2169
+ if (emailConfig?.resetPasswordMethod === "link") {
2170
+ setSuccess(true);
2171
+ if (onSuccess) {
2172
+ onSuccess();
2173
+ }
2174
+ } else {
2175
+ setStep("code");
2176
+ setResendDisabled(true);
2177
+ setResendCountdown(60);
2178
+ }
2179
+ } else {
2180
+ const errorMessage = result?.message || "Failed to send reset code";
2181
+ setError(errorMessage);
2182
+ if (onError) {
2183
+ onError(new Error(errorMessage));
2184
+ }
2185
+ }
2186
+ } catch (err) {
2187
+ const errorMessage = err.message || "Failed to send reset code";
2188
+ setError(errorMessage);
2189
+ if (onError) {
2190
+ onError(new Error(errorMessage));
2191
+ }
2192
+ } finally {
2193
+ setLoading(false);
2194
+ }
2195
+ }
2196
+ async function handleVerifyCode(code) {
2197
+ setIsVerifyingCode(true);
2198
+ setError("");
2199
+ setVerificationCode(code);
2200
+ try {
2201
+ const result = await insforge.auth.verifyResetPasswordCode({ email, code });
2202
+ if (result.error) {
2203
+ throw new Error(result.error.message || "Failed to verify code");
2204
+ }
2205
+ if (result.data) {
2206
+ setResetToken(result.data.resetToken);
2207
+ setStep("password");
2208
+ }
2209
+ } catch (err) {
2210
+ setError(err.message || "Invalid verification code");
2211
+ setVerificationCode("");
2212
+ } finally {
2213
+ setIsVerifyingCode(false);
2214
+ }
2215
+ }
2216
+ const handleResendCode = react.useCallback(async () => {
2217
+ setResendDisabled(true);
2218
+ setResendCountdown(60);
2219
+ setIsSendingCode(true);
2220
+ setError("");
2221
+ try {
2222
+ await sendPasswordResetCode(email);
2223
+ } catch (err) {
2224
+ setError(err.message || "Failed to resend code");
2225
+ setResendDisabled(false);
2226
+ setResendCountdown(0);
2227
+ } finally {
2228
+ setIsSendingCode(false);
2229
+ }
2230
+ }, [email, sendPasswordResetCode]);
2231
+ function handlePasswordResetSuccess() {
2232
+ if (onSuccess) {
2233
+ onSuccess();
2234
+ }
2235
+ }
2236
+ if (!emailConfig) {
2237
+ return null;
2238
+ }
2239
+ if (step === "email") {
2240
+ return /* @__PURE__ */ jsxRuntime.jsx(
2241
+ ForgotPasswordForm,
2242
+ {
2243
+ email,
2244
+ onEmailChange: setEmail,
2245
+ onSubmit: handleEmailSubmit,
2246
+ error,
2247
+ loading,
2248
+ success,
2249
+ backToSignInUrl,
2250
+ ...uiProps
2251
+ }
2252
+ );
2253
+ }
2254
+ if (step === "code") {
2255
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2256
+ AuthContainer,
2257
+ {
2258
+ appearance: {
2259
+ containerClassName: uiProps.appearance?.container,
2260
+ cardClassName: uiProps.appearance?.card
2261
+ },
2262
+ children: [
2263
+ /* @__PURE__ */ jsxRuntime.jsx(
2264
+ AuthHeader,
2265
+ {
2266
+ title: "Enter Reset Code",
2267
+ subtitle: `We've sent a 6-digit verification code to ${email}. Please enter it below to reset your password. The code will expire in 10 minutes.`,
2268
+ appearance: {
2269
+ containerClassName: uiProps.appearance?.header?.container,
2270
+ titleClassName: uiProps.appearance?.header?.title,
2271
+ subtitleClassName: uiProps.appearance?.header?.subtitle
2272
+ }
2273
+ }
2274
+ ),
2275
+ /* @__PURE__ */ jsxRuntime.jsx(AuthErrorBanner, { error, className: uiProps.appearance?.errorBanner }),
2276
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex flex-col gap-6 items-center", children: [
2277
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full bg-neutral-100 dark:bg-neutral-800 rounded-lg px-4 pt-4 pb-6 flex flex-col gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 mt-2", children: [
2278
+ /* @__PURE__ */ jsxRuntime.jsx(
2279
+ AuthVerificationCodeInput,
2280
+ {
2281
+ value: verificationCode,
2282
+ onChange: setVerificationCode,
2283
+ email,
2284
+ disabled: isVerifyingCode,
2285
+ onComplete: (code) => {
2286
+ void handleVerifyCode(code);
2287
+ }
2288
+ }
2289
+ ),
2290
+ isVerifyingCode && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 text-center", children: "Verifying..." })
2291
+ ] }) }),
2292
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full text-sm text-center text-neutral-600 dark:text-neutral-400", children: [
2293
+ "Didn't receive the email?",
2294
+ " ",
2295
+ /* @__PURE__ */ jsxRuntime.jsx(
2296
+ "button",
2297
+ {
2298
+ onClick: () => {
2299
+ void handleResendCode();
2300
+ },
2301
+ disabled: resendDisabled || isSendingCode,
2302
+ className: "text-black dark:text-white font-medium transition-colors disabled:cursor-not-allowed cursor-pointer hover:underline disabled:no-underline disabled:opacity-50",
2303
+ children: isSendingCode ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
2304
+ }
2305
+ )
2306
+ ] })
2307
+ ] }),
2308
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-center text-sm text-gray-600 dark:text-gray-400", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: backToSignInUrl, className: "text-black dark:text-white font-medium", children: "Back to Sign In" }) })
2309
+ ]
2310
+ }
2311
+ );
2312
+ }
2313
+ return /* @__PURE__ */ jsxRuntime.jsx(
2314
+ ResetPassword,
2315
+ {
2316
+ token: resetToken,
2317
+ backToSignInUrl,
2318
+ onSuccess: handlePasswordResetSuccess,
2319
+ onError,
2320
+ appearance: uiProps.appearance
2321
+ }
2322
+ );
2323
+ }
2324
+ function VerifyEmailStatus({
2325
+ status,
2326
+ error,
2327
+ appearance = {},
2328
+ verifyingTitle = "Verifying your email...",
2329
+ successTitle = "Email Verified!",
2330
+ successMessage = "Your email has been verified successfully. You can close this page and return to your app.",
2331
+ errorTitle = "Verification Failed"
2332
+ }) {
2333
+ if (status === "verifying") {
2041
2334
  return /* @__PURE__ */ jsxRuntime.jsx(AuthContainer, { appearance, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex flex-col items-center justify-center gap-6", children: [
2042
2335
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold text-black dark:text-white", children: verifyingTitle }),
2043
2336
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-black dark:border-white" })
@@ -2058,6 +2351,294 @@ function VerifyEmailStatus({
2058
2351
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 text-center", children: successMessage })
2059
2352
  ] }) }) });
2060
2353
  }
2354
+ function VerifyEmail({
2355
+ token,
2356
+ onSuccess,
2357
+ onError,
2358
+ ...uiProps
2359
+ }) {
2360
+ const { verifyEmail } = useInsforge();
2361
+ const [status, setStatus] = react.useState("verifying");
2362
+ const [error, setError] = react.useState("");
2363
+ react.useEffect(() => {
2364
+ const verifyEmailFn = async () => {
2365
+ if (!token) {
2366
+ const errorMessage = "Invalid verification link. Missing required token.";
2367
+ setError(errorMessage);
2368
+ setStatus("error");
2369
+ if (onError) {
2370
+ onError(new Error(errorMessage));
2371
+ }
2372
+ return;
2373
+ }
2374
+ try {
2375
+ const result = await verifyEmail(token);
2376
+ if (!result?.accessToken) {
2377
+ const errorMessage = result ? "Verification succeeded but no access token received" : "Email verification failed";
2378
+ setError(errorMessage);
2379
+ setStatus("error");
2380
+ if (onError) {
2381
+ onError(new Error(errorMessage));
2382
+ }
2383
+ return;
2384
+ }
2385
+ setStatus("success");
2386
+ if (onSuccess) {
2387
+ onSuccess({
2388
+ accessToken: result.accessToken,
2389
+ user: result.user
2390
+ });
2391
+ }
2392
+ } catch (err) {
2393
+ const errorMessage = err.message || "Email verification failed";
2394
+ setError(errorMessage);
2395
+ setStatus("error");
2396
+ if (onError) {
2397
+ onError(new Error(errorMessage));
2398
+ }
2399
+ }
2400
+ };
2401
+ void verifyEmailFn();
2402
+ }, [token, verifyEmail, onSuccess, onError]);
2403
+ return /* @__PURE__ */ jsxRuntime.jsx(VerifyEmailStatus, { status, error, ...uiProps });
2404
+ }
2405
+ function UserButton({
2406
+ afterSignOutUrl = "/",
2407
+ mode = "detailed",
2408
+ appearance = {}
2409
+ }) {
2410
+ const { user, signOut } = useInsforge();
2411
+ const [isOpen, setIsOpen] = react.useState(false);
2412
+ const [imageError, setImageError] = react.useState(false);
2413
+ const dropdownRef = react.useRef(null);
2414
+ react.useEffect(() => {
2415
+ setImageError(false);
2416
+ const avatarUrl = user?.avatarUrl;
2417
+ if (!avatarUrl) return;
2418
+ const checkImageUrl = async () => {
2419
+ try {
2420
+ const response = await fetch(avatarUrl, {
2421
+ method: "HEAD",
2422
+ cache: "no-cache"
2423
+ });
2424
+ if (!response.ok) {
2425
+ setImageError(true);
2426
+ }
2427
+ } catch (error) {
2428
+ setImageError(true);
2429
+ }
2430
+ };
2431
+ checkImageUrl();
2432
+ }, [user?.avatarUrl]);
2433
+ react.useEffect(() => {
2434
+ function handleClickOutside(event) {
2435
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
2436
+ setIsOpen(false);
2437
+ }
2438
+ }
2439
+ if (isOpen) {
2440
+ document.addEventListener("mousedown", handleClickOutside);
2441
+ }
2442
+ return () => {
2443
+ document.removeEventListener("mousedown", handleClickOutside);
2444
+ };
2445
+ }, [isOpen]);
2446
+ async function handleSignOut() {
2447
+ await signOut();
2448
+ setIsOpen(false);
2449
+ window.location.href = afterSignOutUrl;
2450
+ }
2451
+ if (!user) return null;
2452
+ const initials = user.name ? user.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
2453
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2454
+ "div",
2455
+ {
2456
+ className: cn("relative inline-block", appearance.containerClassName),
2457
+ ref: dropdownRef,
2458
+ children: [
2459
+ /* @__PURE__ */ jsxRuntime.jsxs(
2460
+ "button",
2461
+ {
2462
+ className: cn(
2463
+ "p-1 bg-transparent border-0 rounded-full cursor-pointer transition-all duration-200",
2464
+ "flex items-center justify-center gap-2",
2465
+ "hover:bg-black/5",
2466
+ mode === "detailed" && "rounded-lg p-2",
2467
+ appearance.buttonClassName
2468
+ ),
2469
+ onClick: () => setIsOpen(!isOpen),
2470
+ "aria-expanded": isOpen,
2471
+ "aria-haspopup": "true",
2472
+ children: [
2473
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center w-10 h-10 bg-blue-500 rounded-full", children: user.avatarUrl && !imageError ? /* @__PURE__ */ jsxRuntime.jsx(
2474
+ "img",
2475
+ {
2476
+ src: user.avatarUrl,
2477
+ alt: user.email,
2478
+ onError: () => setImageError(true),
2479
+ className: "rounded-full object-cover w-full h-full"
2480
+ }
2481
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-white font-semibold text-sm", children: initials }) }),
2482
+ mode === "detailed" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-0.5", children: [
2483
+ user.name && /* @__PURE__ */ jsxRuntime.jsx(
2484
+ "div",
2485
+ {
2486
+ className: cn(
2487
+ "text-sm font-semibold text-gray-900 leading-5 text-left",
2488
+ appearance.nameClassName
2489
+ ),
2490
+ children: user.name
2491
+ }
2492
+ ),
2493
+ /* @__PURE__ */ jsxRuntime.jsx(
2494
+ "div",
2495
+ {
2496
+ className: cn(
2497
+ "text-xs text-gray-500 leading-4 text-left",
2498
+ appearance.emailClassName
2499
+ ),
2500
+ children: user.email
2501
+ }
2502
+ )
2503
+ ] })
2504
+ ]
2505
+ }
2506
+ ),
2507
+ isOpen && /* @__PURE__ */ jsxRuntime.jsx(
2508
+ "div",
2509
+ {
2510
+ className: cn(
2511
+ "absolute top-full right-0 mt-2 min-w-40",
2512
+ "bg-white border border-gray-200 rounded-lg",
2513
+ "shadow-lg z-50 overflow-hidden p-1",
2514
+ appearance.dropdownClassName
2515
+ ),
2516
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
2517
+ "button",
2518
+ {
2519
+ onClick: handleSignOut,
2520
+ className: "flex items-center justify-start gap-2 w-full px-3 py-2 text-sm font-normal text-red-600 bg-transparent border-0 rounded-md cursor-pointer transition-colors hover:bg-red-50 text-left",
2521
+ children: [
2522
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LogOut, { className: "w-5 h-5" }),
2523
+ "Sign out"
2524
+ ]
2525
+ }
2526
+ )
2527
+ }
2528
+ )
2529
+ ]
2530
+ }
2531
+ );
2532
+ }
2533
+ function Protect({
2534
+ children,
2535
+ fallback,
2536
+ redirectTo = "/sign-in",
2537
+ condition,
2538
+ onRedirect
2539
+ }) {
2540
+ const { isSignedIn, isLoaded, user } = useInsforge();
2541
+ react.useEffect(() => {
2542
+ if (isLoaded && !isSignedIn) {
2543
+ if (onRedirect) {
2544
+ onRedirect(redirectTo);
2545
+ } else {
2546
+ window.location.href = redirectTo;
2547
+ }
2548
+ } else if (isLoaded && isSignedIn && condition && user) {
2549
+ if (!condition(user)) {
2550
+ if (onRedirect) {
2551
+ onRedirect(redirectTo);
2552
+ } else {
2553
+ window.location.href = redirectTo;
2554
+ }
2555
+ }
2556
+ }
2557
+ }, [isLoaded, isSignedIn, redirectTo, condition, user, onRedirect]);
2558
+ if (!isLoaded) {
2559
+ return fallback || /* @__PURE__ */ jsxRuntime.jsx("div", { className: "insforge-loading", children: "Loading..." });
2560
+ }
2561
+ if (!isSignedIn) {
2562
+ return fallback || null;
2563
+ }
2564
+ if (condition && user && !condition(user)) {
2565
+ return fallback || null;
2566
+ }
2567
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
2568
+ }
2569
+ function SignedIn({ children }) {
2570
+ const { isSignedIn, isLoaded } = useInsforge();
2571
+ if (!isLoaded) return null;
2572
+ if (!isSignedIn) return null;
2573
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
2574
+ }
2575
+ function SignedOut({ children }) {
2576
+ const { isSignedIn, isLoaded } = useInsforge();
2577
+ if (!isLoaded) return null;
2578
+ if (isSignedIn) return null;
2579
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
2580
+ }
2581
+ function InsforgeCallback({
2582
+ redirectTo = "/",
2583
+ onSuccess,
2584
+ onError,
2585
+ loadingComponent,
2586
+ onRedirect
2587
+ }) {
2588
+ const isProcessingRef = react.useRef(false);
2589
+ const { isLoaded, isSignedIn } = useInsforge();
2590
+ react.useEffect(() => {
2591
+ if (!isLoaded) return;
2592
+ if (isProcessingRef.current) return;
2593
+ isProcessingRef.current = true;
2594
+ const processCallback = async () => {
2595
+ const searchParams = new URLSearchParams(window.location.search);
2596
+ const error = searchParams.get("error");
2597
+ if (error) {
2598
+ if (onError) {
2599
+ onError(error);
2600
+ } else {
2601
+ const errorUrl = "/?error=" + encodeURIComponent(error);
2602
+ if (onRedirect) {
2603
+ onRedirect(errorUrl);
2604
+ } else {
2605
+ window.location.href = errorUrl;
2606
+ }
2607
+ }
2608
+ return;
2609
+ }
2610
+ if (!isSignedIn) {
2611
+ const errorMsg = "authentication_failed";
2612
+ if (onError) {
2613
+ onError(errorMsg);
2614
+ } else {
2615
+ const errorUrl = "/?error=" + encodeURIComponent(errorMsg);
2616
+ if (onRedirect) {
2617
+ onRedirect(errorUrl);
2618
+ } else {
2619
+ window.location.href = errorUrl;
2620
+ }
2621
+ }
2622
+ return;
2623
+ }
2624
+ window.history.replaceState({}, "", window.location.pathname);
2625
+ if (onSuccess) {
2626
+ onSuccess();
2627
+ }
2628
+ if (onRedirect) {
2629
+ onRedirect(redirectTo);
2630
+ } else {
2631
+ window.location.href = redirectTo;
2632
+ }
2633
+ };
2634
+ processCallback();
2635
+ }, [isLoaded, isSignedIn, redirectTo, onSuccess, onError, onRedirect]);
2636
+ const defaultLoading = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
2637
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold mb-4", children: "Completing authentication..." }),
2638
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto" })
2639
+ ] }) });
2640
+ return loadingComponent || defaultLoading;
2641
+ }
2061
2642
 
2062
2643
  // src/hooks/useAuth.ts
2063
2644
  function useAuth() {
@@ -2070,77 +2651,6 @@ function useUser() {
2070
2651
  const { user, isLoaded, updateUser, setUser } = useInsforge();
2071
2652
  return { user, isLoaded, updateUser, setUser };
2072
2653
  }
2073
- var emailSchema = zod.z.string().min(1, "Email is required").email("Invalid email address");
2074
- function createPasswordSchema(options) {
2075
- const {
2076
- minLength = 6,
2077
- requireUppercase = false,
2078
- requireLowercase = false,
2079
- requireNumber = false,
2080
- requireSpecialChar = false
2081
- } = options || {};
2082
- let schema = zod.z.string().min(minLength, `Password must be at least ${minLength} characters`);
2083
- if (requireUppercase) {
2084
- schema = schema.regex(/[A-Z]/, "Password must contain at least one uppercase letter");
2085
- }
2086
- if (requireLowercase) {
2087
- schema = schema.regex(/[a-z]/, "Password must contain at least one lowercase letter");
2088
- }
2089
- if (requireNumber) {
2090
- schema = schema.regex(/\d/, "Password must contain at least one number");
2091
- }
2092
- if (requireSpecialChar) {
2093
- schema = schema.regex(
2094
- /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/,
2095
- "Password must contain at least one special character"
2096
- );
2097
- }
2098
- return schema;
2099
- }
2100
- var passwordSchema = createPasswordSchema();
2101
- function validateEmail(email) {
2102
- const result = emailSchema.safeParse(email);
2103
- if (result.success) {
2104
- return { valid: true };
2105
- }
2106
- return { valid: false, error: result.error.message };
2107
- }
2108
- function validatePassword(password, options) {
2109
- const schema = createPasswordSchema(options);
2110
- const result = schema.safeParse(password);
2111
- if (result.success) {
2112
- return { valid: true };
2113
- }
2114
- return { valid: false, error: result.error.message };
2115
- }
2116
- function checkPasswordStrength(password) {
2117
- const feedback = [];
2118
- let score = 0;
2119
- if (password.length >= 8) {
2120
- score += 1;
2121
- } else {
2122
- feedback.push("Use at least 8 characters");
2123
- }
2124
- if (password.length >= 12) {
2125
- score += 1;
2126
- }
2127
- if (/[a-z]/.test(password) && /[A-Z]/.test(password)) {
2128
- score += 1;
2129
- } else {
2130
- feedback.push("Use both uppercase and lowercase letters");
2131
- }
2132
- if (/\d/.test(password)) {
2133
- score += 1;
2134
- } else {
2135
- feedback.push("Include at least one number");
2136
- }
2137
- if (/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(password)) {
2138
- score += 1;
2139
- } else {
2140
- feedback.push("Include at least one special character");
2141
- }
2142
- return { score, feedback };
2143
- }
2144
2654
  function RedirectToAuth({ baseUrl, path }) {
2145
2655
  react.useEffect(() => {
2146
2656
  const callbackUrl = `${window.location.origin}/auth/callback`;
@@ -2194,6 +2704,7 @@ function getInsforgeRoutes(config) {
2194
2704
  exports.AuthBranding = AuthBranding;
2195
2705
  exports.AuthContainer = AuthContainer;
2196
2706
  exports.AuthDivider = AuthDivider;
2707
+ exports.AuthEmailVerificationStep = AuthEmailVerificationStep;
2197
2708
  exports.AuthErrorBanner = AuthErrorBanner;
2198
2709
  exports.AuthFormField = AuthFormField;
2199
2710
  exports.AuthHeader = AuthHeader;
@@ -2204,11 +2715,13 @@ exports.AuthPasswordField = AuthPasswordField;
2204
2715
  exports.AuthPasswordStrengthIndicator = AuthPasswordStrengthIndicator;
2205
2716
  exports.AuthSubmitButton = AuthSubmitButton;
2206
2717
  exports.AuthVerificationCodeInput = AuthVerificationCodeInput;
2718
+ exports.ForgotPassword = ForgotPassword;
2207
2719
  exports.ForgotPasswordForm = ForgotPasswordForm;
2208
2720
  exports.InsforgeCallback = InsforgeCallback;
2209
2721
  exports.InsforgeProvider = InsforgeProvider;
2210
2722
  exports.OAUTH_PROVIDER_CONFIG = OAUTH_PROVIDER_CONFIG;
2211
2723
  exports.Protect = Protect;
2724
+ exports.ResetPassword = ResetPassword;
2212
2725
  exports.ResetPasswordForm = ResetPasswordForm;
2213
2726
  exports.SignIn = SignIn;
2214
2727
  exports.SignInForm = SignInForm;
@@ -2217,6 +2730,7 @@ exports.SignUpForm = SignUpForm;
2217
2730
  exports.SignedIn = SignedIn;
2218
2731
  exports.SignedOut = SignedOut;
2219
2732
  exports.UserButton = UserButton;
2733
+ exports.VerifyEmail = VerifyEmail;
2220
2734
  exports.VerifyEmailStatus = VerifyEmailStatus;
2221
2735
  exports.checkPasswordStrength = checkPasswordStrength;
2222
2736
  exports.cn = cn;