@insforge/react 0.2.9 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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-400:oklch(70.4% .191 22.216);--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-red-400{color:var(--color-red-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,126 @@ function AuthVerificationCodeInput({
1109
1059
  )) })
1110
1060
  ] });
1111
1061
  }
1062
+ function AuthEmailVerificationStep({
1063
+ email,
1064
+ title = "Verify Your Email",
1065
+ description,
1066
+ method = "code",
1067
+ onVerifyCode
1068
+ }) {
1069
+ const { baseUrl } = useInsforge();
1070
+ const [insforge] = react.useState(() => sdk.createClient({ baseUrl }));
1071
+ const [resendDisabled, setResendDisabled] = react.useState(true);
1072
+ const [resendCountdown, setResendCountdown] = react.useState(60);
1073
+ const [isSending, setIsSending] = react.useState(false);
1074
+ const [verificationCode, setVerificationCode] = react.useState("");
1075
+ const [isVerifying, setIsVerifying] = react.useState(false);
1076
+ const [verificationError, setVerificationError] = react.useState("");
1077
+ 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.";
1078
+ react.useEffect(() => {
1079
+ const sendInitialEmail = async () => {
1080
+ try {
1081
+ if (method === "code") {
1082
+ await insforge.auth.sendVerificationCode({ email });
1083
+ } else {
1084
+ await insforge.auth.sendVerificationLink({ email });
1085
+ }
1086
+ } catch {
1087
+ }
1088
+ };
1089
+ void sendInitialEmail();
1090
+ }, [email, method, insforge.auth]);
1091
+ react.useEffect(() => {
1092
+ if (resendCountdown > 0) {
1093
+ const timer = setInterval(() => {
1094
+ setResendCountdown((prev) => {
1095
+ if (prev <= 1) {
1096
+ setResendDisabled(false);
1097
+ return 0;
1098
+ }
1099
+ return prev - 1;
1100
+ });
1101
+ }, 1e3);
1102
+ return () => clearInterval(timer);
1103
+ }
1104
+ }, [resendCountdown]);
1105
+ const handleResend = async () => {
1106
+ setResendDisabled(true);
1107
+ setResendCountdown(60);
1108
+ setIsSending(true);
1109
+ setVerificationError("");
1110
+ try {
1111
+ if (method === "code") {
1112
+ await insforge.auth.sendVerificationCode({ email });
1113
+ } else {
1114
+ await insforge.auth.sendVerificationLink({ email });
1115
+ }
1116
+ } catch {
1117
+ setResendDisabled(false);
1118
+ setResendCountdown(0);
1119
+ } finally {
1120
+ setIsSending(false);
1121
+ }
1122
+ };
1123
+ const handleVerifyCode = async (code) => {
1124
+ if (!onVerifyCode) {
1125
+ return;
1126
+ }
1127
+ setIsVerifying(true);
1128
+ setVerificationError("");
1129
+ try {
1130
+ await onVerifyCode(code);
1131
+ } catch (error) {
1132
+ setVerificationError(
1133
+ error instanceof Error ? error.message : "Invalid verification code. Please try again."
1134
+ );
1135
+ setVerificationCode("");
1136
+ } finally {
1137
+ setIsVerifying(false);
1138
+ }
1139
+ };
1140
+ const displayDescription = description || defaultDescription;
1141
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex flex-col gap-6 items-center", children: [
1142
+ /* @__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: [
1143
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-black dark:text-white", children: title }),
1144
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-neutral-600 dark:text-neutral-400 text-sm leading-relaxed", children: displayDescription.split("{email}").map((part, index, array) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1145
+ part,
1146
+ index < array.length - 1 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-black dark:text-white", children: email })
1147
+ ] }, index)) }),
1148
+ method === "code" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 mt-2", children: [
1149
+ /* @__PURE__ */ jsxRuntime.jsx(
1150
+ AuthVerificationCodeInput,
1151
+ {
1152
+ value: verificationCode,
1153
+ onChange: setVerificationCode,
1154
+ email,
1155
+ disabled: isVerifying,
1156
+ onComplete: (code) => {
1157
+ void handleVerifyCode(code);
1158
+ }
1159
+ }
1160
+ ),
1161
+ verificationError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-red-600 dark:text-red-400 text-center", children: verificationError }),
1162
+ isVerifying && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 text-center", children: "Verifying..." })
1163
+ ] })
1164
+ ] }),
1165
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full text-sm text-center text-neutral-600 dark:text-neutral-400", children: [
1166
+ "Didn't receive the email?",
1167
+ " ",
1168
+ /* @__PURE__ */ jsxRuntime.jsx(
1169
+ "button",
1170
+ {
1171
+ onClick: () => {
1172
+ void handleResend();
1173
+ },
1174
+ disabled: resendDisabled || isSending,
1175
+ className: "text-black dark:text-white font-medium transition-colors disabled:cursor-not-allowed cursor-pointer hover:underline disabled:no-underline disabled:opacity-50",
1176
+ children: isSending ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
1177
+ }
1178
+ )
1179
+ ] })
1180
+ ] });
1181
+ }
1112
1182
  function SignInForm({
1113
1183
  email,
1114
1184
  password,
@@ -1273,6 +1343,7 @@ function SignIn({
1273
1343
  const [password, setPassword] = react.useState("");
1274
1344
  const [error, setError] = react.useState("");
1275
1345
  const [loading, setLoading] = react.useState(false);
1346
+ const [step, setStep] = react.useState("form");
1276
1347
  const [oauthLoading, setOauthLoading] = react.useState(
1277
1348
  null
1278
1349
  );
@@ -1284,6 +1355,11 @@ function SignIn({
1284
1355
  try {
1285
1356
  const result = await signIn(email, password);
1286
1357
  if ("error" in result) {
1358
+ if (result.statusCode === 403) {
1359
+ setStep("awaiting-verification");
1360
+ setLoading(false);
1361
+ return;
1362
+ }
1287
1363
  throw new Error(result.error);
1288
1364
  }
1289
1365
  const { user, accessToken } = result;
@@ -1298,6 +1374,21 @@ function SignIn({
1298
1374
  setLoading(false);
1299
1375
  }
1300
1376
  }
1377
+ async function handleVerifyCode(code) {
1378
+ try {
1379
+ const result = await insforge.auth.verifyEmail({ email, otp: code });
1380
+ if (result.error) {
1381
+ throw new Error(result.error.message || "Verification failed");
1382
+ }
1383
+ if (result.data?.accessToken) {
1384
+ if (onSuccess && result.data.user) {
1385
+ onSuccess(result.data.user, result.data.accessToken);
1386
+ }
1387
+ }
1388
+ } catch (err) {
1389
+ throw new Error(err.message || "Invalid verification code");
1390
+ }
1391
+ }
1301
1392
  async function handleOAuth(provider) {
1302
1393
  try {
1303
1394
  setOauthLoading(provider);
@@ -1316,7 +1407,7 @@ function SignIn({
1316
1407
  if (!emailConfig) {
1317
1408
  return null;
1318
1409
  }
1319
- return /* @__PURE__ */ jsxRuntime.jsx(
1410
+ return step === "form" ? /* @__PURE__ */ jsxRuntime.jsx(
1320
1411
  SignInForm,
1321
1412
  {
1322
1413
  email,
@@ -1332,6 +1423,12 @@ function SignIn({
1332
1423
  emailAuthConfig: emailConfig,
1333
1424
  ...uiProps
1334
1425
  }
1426
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1427
+ AuthEmailVerificationStep,
1428
+ {
1429
+ email,
1430
+ onVerifyCode: handleVerifyCode
1431
+ }
1335
1432
  );
1336
1433
  }
1337
1434
  function SignUpForm({
@@ -1482,6 +1579,77 @@ function SignUpForm({
1482
1579
  }
1483
1580
  );
1484
1581
  }
1582
+ var emailSchema = zod.z.string().min(1, "Email is required").email("Invalid email address");
1583
+ function createPasswordSchema(options) {
1584
+ const {
1585
+ minLength = 6,
1586
+ requireUppercase = false,
1587
+ requireLowercase = false,
1588
+ requireNumber = false,
1589
+ requireSpecialChar = false
1590
+ } = options || {};
1591
+ let schema = zod.z.string().min(minLength, `Password must be at least ${minLength} characters`);
1592
+ if (requireUppercase) {
1593
+ schema = schema.regex(/[A-Z]/, "Password must contain at least one uppercase letter");
1594
+ }
1595
+ if (requireLowercase) {
1596
+ schema = schema.regex(/[a-z]/, "Password must contain at least one lowercase letter");
1597
+ }
1598
+ if (requireNumber) {
1599
+ schema = schema.regex(/\d/, "Password must contain at least one number");
1600
+ }
1601
+ if (requireSpecialChar) {
1602
+ schema = schema.regex(
1603
+ /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/,
1604
+ "Password must contain at least one special character"
1605
+ );
1606
+ }
1607
+ return schema;
1608
+ }
1609
+ var passwordSchema = createPasswordSchema();
1610
+ function validateEmail(email) {
1611
+ const result = emailSchema.safeParse(email);
1612
+ if (result.success) {
1613
+ return { valid: true };
1614
+ }
1615
+ return { valid: false, error: result.error.message };
1616
+ }
1617
+ function validatePassword(password, options) {
1618
+ const schema = createPasswordSchema(options);
1619
+ const result = schema.safeParse(password);
1620
+ if (result.success) {
1621
+ return { valid: true };
1622
+ }
1623
+ return { valid: false, error: result.error.message };
1624
+ }
1625
+ function checkPasswordStrength(password) {
1626
+ const feedback = [];
1627
+ let score = 0;
1628
+ if (password.length >= 8) {
1629
+ score += 1;
1630
+ } else {
1631
+ feedback.push("Use at least 8 characters");
1632
+ }
1633
+ if (password.length >= 12) {
1634
+ score += 1;
1635
+ }
1636
+ if (/[a-z]/.test(password) && /[A-Z]/.test(password)) {
1637
+ score += 1;
1638
+ } else {
1639
+ feedback.push("Use both uppercase and lowercase letters");
1640
+ }
1641
+ if (/\d/.test(password)) {
1642
+ score += 1;
1643
+ } else {
1644
+ feedback.push("Include at least one number");
1645
+ }
1646
+ if (/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(password)) {
1647
+ score += 1;
1648
+ } else {
1649
+ feedback.push("Include at least one special character");
1650
+ }
1651
+ return { score, feedback };
1652
+ }
1485
1653
  function SignUp({
1486
1654
  afterSignUpUrl,
1487
1655
  onSuccess,
@@ -1494,6 +1662,7 @@ function SignUp({
1494
1662
  const [password, setPassword] = react.useState("");
1495
1663
  const [error, setError] = react.useState("");
1496
1664
  const [loading, setLoading] = react.useState(false);
1665
+ const [step, setStep] = react.useState("form");
1497
1666
  const [oauthLoading, setOauthLoading] = react.useState(
1498
1667
  null
1499
1668
  );
@@ -1502,19 +1671,46 @@ function SignUp({
1502
1671
  e.preventDefault();
1503
1672
  setLoading(true);
1504
1673
  setError("");
1505
- if (emailConfig && !validatePasswordStrength(password, emailConfig)) {
1506
- setError("Password does not meet all requirements");
1674
+ if (!emailConfig) {
1675
+ setError("Configuration not loaded. Please refresh the page.");
1676
+ setLoading(false);
1677
+ return;
1678
+ }
1679
+ const emailValidation = emailSchema.safeParse(email);
1680
+ if (!emailValidation.success) {
1681
+ const firstError = emailValidation.error.issues[0];
1682
+ setError(firstError.message);
1683
+ setLoading(false);
1684
+ return;
1685
+ }
1686
+ const passwordZodSchema = createPasswordSchema({
1687
+ minLength: emailConfig.passwordMinLength,
1688
+ requireUppercase: emailConfig.requireUppercase,
1689
+ requireLowercase: emailConfig.requireLowercase,
1690
+ requireNumber: emailConfig.requireNumber,
1691
+ requireSpecialChar: emailConfig.requireSpecialChar
1692
+ });
1693
+ const passwordValidation = passwordZodSchema.safeParse(password);
1694
+ if (!passwordValidation.success) {
1695
+ const firstError = passwordValidation.error.issues[0];
1696
+ setError(firstError.message);
1507
1697
  setLoading(false);
1508
1698
  return;
1509
1699
  }
1510
1700
  try {
1511
- const result = await signUp(email, password);
1701
+ const result = await signUp(emailValidation.data, password);
1512
1702
  if ("error" in result) {
1513
1703
  throw new Error(result.error);
1514
1704
  }
1515
- const { user, accessToken } = result;
1516
- if (onSuccess) {
1517
- if (user) onSuccess(user, accessToken || "");
1705
+ if (result.requiresEmailVerification && !result.accessToken) {
1706
+ setStep("awaiting-verification");
1707
+ setLoading(false);
1708
+ return;
1709
+ }
1710
+ if (result.accessToken && result.user) {
1711
+ if (onSuccess) {
1712
+ onSuccess(result.user, result.accessToken);
1713
+ }
1518
1714
  }
1519
1715
  } catch (err) {
1520
1716
  const errorMessage = err.message || "Sign up failed";
@@ -1524,6 +1720,21 @@ function SignUp({
1524
1720
  setLoading(false);
1525
1721
  }
1526
1722
  }
1723
+ async function handleVerifyCode(code) {
1724
+ try {
1725
+ const result = await insforge.auth.verifyEmail({ email, otp: code });
1726
+ if (result.error) {
1727
+ throw new Error(result.error.message || "Verification failed");
1728
+ }
1729
+ if (result.data?.accessToken) {
1730
+ if (onSuccess && result.data.user) {
1731
+ onSuccess(result.data.user, result.data.accessToken);
1732
+ }
1733
+ }
1734
+ } catch (err) {
1735
+ throw new Error(err.message || "Invalid verification code");
1736
+ }
1737
+ }
1527
1738
  async function handleOAuth(provider) {
1528
1739
  try {
1529
1740
  setOauthLoading(provider);
@@ -1542,7 +1753,7 @@ function SignUp({
1542
1753
  if (!emailConfig) {
1543
1754
  return null;
1544
1755
  }
1545
- return /* @__PURE__ */ jsxRuntime.jsx(
1756
+ return step === "form" ? /* @__PURE__ */ jsxRuntime.jsx(
1546
1757
  SignUpForm,
1547
1758
  {
1548
1759
  email,
@@ -1558,283 +1769,32 @@ function SignUp({
1558
1769
  emailAuthConfig: emailConfig,
1559
1770
  ...uiProps
1560
1771
  }
1772
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1773
+ AuthEmailVerificationStep,
1774
+ {
1775
+ email,
1776
+ onVerifyCode: handleVerifyCode
1777
+ }
1561
1778
  );
1562
1779
  }
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 { handleAuthCallback } = useInsforge();
1748
- react.useEffect(() => {
1749
- const processCallback = async () => {
1750
- if (isProcessingRef.current) return;
1751
- isProcessingRef.current = true;
1752
- const searchParams = new URLSearchParams(window.location.search);
1753
- const error = searchParams.get("error");
1754
- if (error) {
1755
- if (onError) {
1756
- onError(error);
1757
- } else {
1758
- const errorUrl = "/?error=" + encodeURIComponent(error);
1759
- if (onRedirect) {
1760
- onRedirect(errorUrl);
1761
- } else {
1762
- window.location.href = errorUrl;
1763
- }
1764
- }
1765
- return;
1766
- }
1767
- const accessToken = searchParams.get("access_token");
1768
- if (!accessToken) {
1769
- const errorMsg = "no_token";
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
- const result = await handleAuthCallback({
1783
- accessToken
1784
- });
1785
- if (!result.success) {
1786
- const errorMsg = result.error || "authentication_failed";
1787
- if (onError) {
1788
- onError(errorMsg);
1789
- } else {
1790
- const errorUrl = "/?error=" + encodeURIComponent(errorMsg);
1791
- if (onRedirect) {
1792
- onRedirect(errorUrl);
1793
- } else {
1794
- window.location.href = errorUrl;
1795
- }
1796
- }
1797
- return;
1798
- }
1799
- window.history.replaceState({}, "", window.location.pathname);
1800
- if (onSuccess) {
1801
- onSuccess();
1802
- }
1803
- const destination = redirectTo || sessionStorage.getItem("auth_destination") || sessionStorage.getItem("oauth_final_destination") || "/";
1804
- sessionStorage.removeItem("auth_destination");
1805
- sessionStorage.removeItem("oauth_final_destination");
1806
- if (onRedirect) {
1807
- onRedirect(destination);
1808
- } else {
1809
- window.location.href = destination;
1810
- }
1811
- };
1812
- processCallback();
1813
- }, [handleAuthCallback, redirectTo, onSuccess, onError, onRedirect]);
1814
- const defaultLoading = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
1815
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold mb-4", children: "Completing authentication..." }),
1816
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto" })
1817
- ] }) });
1818
- return loadingComponent || defaultLoading;
1819
- }
1820
- function ForgotPasswordForm({
1821
- email,
1822
- onEmailChange,
1823
- onSubmit,
1824
- error,
1825
- loading = false,
1826
- success = false,
1827
- appearance = {},
1828
- title = "Forgot Password?",
1829
- subtitle = "Enter your email address and we'll send you a code to reset your password.",
1830
- emailLabel = "Email",
1831
- emailPlaceholder = "example@email.com",
1832
- submitButtonText = "Send Reset Code",
1833
- loadingButtonText = "Sending...",
1834
- backToSignInText = "Remember your password?",
1835
- backToSignInUrl = "/sign-in",
1836
- successTitle = "Check Your Email",
1837
- successMessage
1780
+ function ForgotPasswordForm({
1781
+ email,
1782
+ onEmailChange,
1783
+ onSubmit,
1784
+ error,
1785
+ loading = false,
1786
+ success = false,
1787
+ appearance = {},
1788
+ title = "Forgot Password?",
1789
+ subtitle = "Enter your email address and we'll send you a code to reset your password.",
1790
+ emailLabel = "Email",
1791
+ emailPlaceholder = "example@email.com",
1792
+ submitButtonText = "Send Reset Code",
1793
+ loadingButtonText = "Sending...",
1794
+ backToSignInText = "Remember your password?",
1795
+ backToSignInUrl = "/sign-in",
1796
+ successTitle = "Check Your Email",
1797
+ successMessage
1838
1798
  }) {
1839
1799
  if (success) {
1840
1800
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -2048,118 +2008,626 @@ function ResetPasswordForm({
2048
2008
  }
2049
2009
  );
2050
2010
  }
2051
- function VerifyEmailStatus({
2052
- status,
2053
- error,
2054
- appearance = {},
2055
- verifyingTitle = "Verifying your email...",
2056
- successTitle = "Email Verified!",
2057
- successMessage = "Your email has been verified successfully. You can close this page and return to your app.",
2058
- errorTitle = "Verification Failed"
2011
+ function ResetPassword({
2012
+ token,
2013
+ backToSignInUrl = "/sign-in",
2014
+ onSuccess,
2015
+ onError,
2016
+ ...uiProps
2059
2017
  }) {
2060
- if (status === "verifying") {
2061
- return /* @__PURE__ */ jsxRuntime.jsx(AuthContainer, { appearance, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex flex-col items-center justify-center gap-6", children: [
2062
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold text-black dark:text-white", children: verifyingTitle }),
2063
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-black dark:border-white" })
2064
- ] }) });
2065
- }
2066
- if (status === "error") {
2067
- return /* @__PURE__ */ jsxRuntime.jsx(AuthContainer, { appearance, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex flex-col items-stretch justify-center gap-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start justify-center gap-2", children: [
2068
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-semibold text-black dark:text-white", children: errorTitle }),
2069
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 leading-relaxed", children: [
2070
- error || "The verification link is invalid or has expired.",
2071
- " Please try again or contact support if the problem persists. You can close this page and return to your app."
2072
- ] })
2073
- ] }) }) });
2074
- }
2075
- return /* @__PURE__ */ jsxRuntime.jsx(AuthContainer, { appearance, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex flex-col items-stretch justify-center gap-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-4", children: [
2076
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-16 rounded-full bg-green-100 dark:bg-green-900 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-8 h-8 text-green-600 dark:text-green-400", fill: "none", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 13l4 4L19 7" }) }) }),
2077
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold text-black dark:text-white text-center", children: successTitle }),
2078
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 text-center", children: successMessage })
2079
- ] }) }) });
2080
- }
2081
-
2082
- // src/hooks/useAuth.ts
2083
- function useAuth() {
2084
- const { signIn, signUp, signOut, isLoaded, isSignedIn } = useInsforge();
2085
- return { signIn, signUp, signOut, isLoaded, isSignedIn };
2086
- }
2087
-
2088
- // src/hooks/useUser.ts
2089
- function useUser() {
2090
- const { user, isLoaded, updateUser, setUser } = useInsforge();
2091
- return { user, isLoaded, updateUser, setUser };
2018
+ const { resetPassword } = useInsforge();
2019
+ const { emailConfig } = usePublicAuthConfig();
2020
+ const [newPassword, setNewPassword] = react.useState("");
2021
+ const [confirmPassword, setConfirmPassword] = react.useState("");
2022
+ const [error, setError] = react.useState("");
2023
+ const [loading, setLoading] = react.useState(false);
2024
+ async function handleSubmit(e) {
2025
+ e.preventDefault();
2026
+ setLoading(true);
2027
+ setError("");
2028
+ if (!emailConfig) {
2029
+ setError("Configuration not loaded. Please refresh the page.");
2030
+ setLoading(false);
2031
+ return;
2032
+ }
2033
+ if (newPassword !== confirmPassword) {
2034
+ setError("Passwords do not match");
2035
+ setLoading(false);
2036
+ return;
2037
+ }
2038
+ if (!token) {
2039
+ setError("Reset token is missing");
2040
+ setLoading(false);
2041
+ return;
2042
+ }
2043
+ const passwordZodSchema = createPasswordSchema({
2044
+ minLength: emailConfig.passwordMinLength,
2045
+ requireUppercase: emailConfig.requireUppercase,
2046
+ requireLowercase: emailConfig.requireLowercase,
2047
+ requireNumber: emailConfig.requireNumber,
2048
+ requireSpecialChar: emailConfig.requireSpecialChar
2049
+ });
2050
+ const passwordValidation = passwordZodSchema.safeParse(newPassword);
2051
+ if (!passwordValidation.success) {
2052
+ const firstError = passwordValidation.error.issues[0];
2053
+ setError(firstError.message);
2054
+ setLoading(false);
2055
+ return;
2056
+ }
2057
+ try {
2058
+ const result = await resetPassword(token, newPassword);
2059
+ if (result?.message) {
2060
+ if (onSuccess) {
2061
+ onSuccess(result.redirectTo);
2062
+ }
2063
+ } else {
2064
+ const errorMessage = "Failed to reset password";
2065
+ setError(errorMessage);
2066
+ if (onError) {
2067
+ onError(new Error(errorMessage));
2068
+ }
2069
+ }
2070
+ } catch (err) {
2071
+ const errorMessage = err.message || "Failed to reset password";
2072
+ setError(errorMessage);
2073
+ if (onError) {
2074
+ onError(new Error(errorMessage));
2075
+ }
2076
+ } finally {
2077
+ setLoading(false);
2078
+ }
2079
+ }
2080
+ if (!emailConfig) {
2081
+ return null;
2082
+ }
2083
+ return /* @__PURE__ */ jsxRuntime.jsx(
2084
+ ResetPasswordForm,
2085
+ {
2086
+ newPassword,
2087
+ confirmPassword,
2088
+ onNewPasswordChange: setNewPassword,
2089
+ onConfirmPasswordChange: setConfirmPassword,
2090
+ onSubmit: handleSubmit,
2091
+ error,
2092
+ loading,
2093
+ emailAuthConfig: emailConfig,
2094
+ backToSignInUrl,
2095
+ ...uiProps
2096
+ }
2097
+ );
2092
2098
  }
2093
- var emailSchema = zod.z.string().min(1, "Email is required").email("Invalid email address");
2094
- function createPasswordSchema(options) {
2095
- const {
2096
- minLength = 6,
2097
- requireUppercase = false,
2098
- requireLowercase = false,
2099
- requireNumber = false,
2100
- requireSpecialChar = false
2101
- } = options || {};
2102
- let schema = zod.z.string().min(minLength, `Password must be at least ${minLength} characters`);
2103
- if (requireUppercase) {
2104
- schema = schema.regex(/[A-Z]/, "Password must contain at least one uppercase letter");
2099
+ function ForgotPassword({
2100
+ backToSignInUrl = "/sign-in",
2101
+ onSuccess,
2102
+ onError,
2103
+ ...uiProps
2104
+ }) {
2105
+ const { sendPasswordResetCode, baseUrl } = useInsforge();
2106
+ const { emailConfig } = usePublicAuthConfig();
2107
+ const [insforge] = react.useState(() => sdk.createClient({ baseUrl }));
2108
+ const [step, setStep] = react.useState("email");
2109
+ const [email, setEmail] = react.useState("");
2110
+ const [verificationCode, setVerificationCode] = react.useState("");
2111
+ const [resetToken, setResetToken] = react.useState("");
2112
+ const [error, setError] = react.useState("");
2113
+ const [loading, setLoading] = react.useState(false);
2114
+ const [success, setSuccess] = react.useState(false);
2115
+ const [resendDisabled, setResendDisabled] = react.useState(true);
2116
+ const [resendCountdown, setResendCountdown] = react.useState(60);
2117
+ const [isSendingCode, setIsSendingCode] = react.useState(false);
2118
+ const [isVerifyingCode, setIsVerifyingCode] = react.useState(false);
2119
+ react.useEffect(() => {
2120
+ if (resendCountdown > 0 && step === "code") {
2121
+ const timer = setInterval(() => {
2122
+ setResendCountdown((prev) => {
2123
+ if (prev <= 1) {
2124
+ setResendDisabled(false);
2125
+ return 0;
2126
+ }
2127
+ return prev - 1;
2128
+ });
2129
+ }, 1e3);
2130
+ return () => clearInterval(timer);
2131
+ }
2132
+ }, [resendCountdown, step]);
2133
+ async function handleEmailSubmit(e) {
2134
+ e.preventDefault();
2135
+ setLoading(true);
2136
+ setError("");
2137
+ const emailValidation = emailSchema.safeParse(email);
2138
+ if (!emailValidation.success) {
2139
+ const firstError = emailValidation.error.issues[0];
2140
+ setError(firstError.message);
2141
+ setLoading(false);
2142
+ return;
2143
+ }
2144
+ try {
2145
+ const result = await sendPasswordResetCode(emailValidation.data);
2146
+ if (result?.success) {
2147
+ if (emailConfig?.resetPasswordMethod === "link") {
2148
+ setSuccess(true);
2149
+ if (onSuccess) {
2150
+ onSuccess();
2151
+ }
2152
+ } else {
2153
+ setStep("code");
2154
+ setResendDisabled(true);
2155
+ setResendCountdown(60);
2156
+ }
2157
+ } else {
2158
+ const errorMessage = result?.message || "Failed to send reset code";
2159
+ setError(errorMessage);
2160
+ if (onError) {
2161
+ onError(new Error(errorMessage));
2162
+ }
2163
+ }
2164
+ } catch (err) {
2165
+ const errorMessage = err.message || "Failed to send reset code";
2166
+ setError(errorMessage);
2167
+ if (onError) {
2168
+ onError(new Error(errorMessage));
2169
+ }
2170
+ } finally {
2171
+ setLoading(false);
2172
+ }
2105
2173
  }
2106
- if (requireLowercase) {
2107
- schema = schema.regex(/[a-z]/, "Password must contain at least one lowercase letter");
2174
+ async function handleVerifyCode(code) {
2175
+ setIsVerifyingCode(true);
2176
+ setError("");
2177
+ setVerificationCode(code);
2178
+ try {
2179
+ const result = await insforge.auth.verifyResetPasswordCode({ email, code });
2180
+ if (result.error) {
2181
+ throw new Error(result.error.message || "Failed to verify code");
2182
+ }
2183
+ if (result.data) {
2184
+ setResetToken(result.data.resetToken);
2185
+ setStep("password");
2186
+ }
2187
+ } catch (err) {
2188
+ setError(err.message || "Invalid verification code");
2189
+ setVerificationCode("");
2190
+ } finally {
2191
+ setIsVerifyingCode(false);
2192
+ }
2108
2193
  }
2109
- if (requireNumber) {
2110
- schema = schema.regex(/\d/, "Password must contain at least one number");
2194
+ const handleResendCode = react.useCallback(async () => {
2195
+ setResendDisabled(true);
2196
+ setResendCountdown(60);
2197
+ setIsSendingCode(true);
2198
+ setError("");
2199
+ try {
2200
+ await sendPasswordResetCode(email);
2201
+ } catch (err) {
2202
+ setError(err.message || "Failed to resend code");
2203
+ setResendDisabled(false);
2204
+ setResendCountdown(0);
2205
+ } finally {
2206
+ setIsSendingCode(false);
2207
+ }
2208
+ }, [email, sendPasswordResetCode]);
2209
+ function handlePasswordResetSuccess() {
2210
+ if (onSuccess) {
2211
+ onSuccess();
2212
+ }
2111
2213
  }
2112
- if (requireSpecialChar) {
2113
- schema = schema.regex(
2114
- /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/,
2115
- "Password must contain at least one special character"
2214
+ if (!emailConfig) {
2215
+ return null;
2216
+ }
2217
+ if (step === "email") {
2218
+ return /* @__PURE__ */ jsxRuntime.jsx(
2219
+ ForgotPasswordForm,
2220
+ {
2221
+ email,
2222
+ onEmailChange: setEmail,
2223
+ onSubmit: handleEmailSubmit,
2224
+ error,
2225
+ loading,
2226
+ success,
2227
+ backToSignInUrl,
2228
+ ...uiProps
2229
+ }
2116
2230
  );
2117
2231
  }
2118
- return schema;
2119
- }
2120
- var passwordSchema = createPasswordSchema();
2121
- function validateEmail(email) {
2122
- const result = emailSchema.safeParse(email);
2123
- if (result.success) {
2124
- return { valid: true };
2232
+ if (step === "code") {
2233
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2234
+ AuthContainer,
2235
+ {
2236
+ appearance: {
2237
+ containerClassName: uiProps.appearance?.container,
2238
+ cardClassName: uiProps.appearance?.card
2239
+ },
2240
+ children: [
2241
+ /* @__PURE__ */ jsxRuntime.jsx(
2242
+ AuthHeader,
2243
+ {
2244
+ title: "Enter Reset Code",
2245
+ 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.`,
2246
+ appearance: {
2247
+ containerClassName: uiProps.appearance?.header?.container,
2248
+ titleClassName: uiProps.appearance?.header?.title,
2249
+ subtitleClassName: uiProps.appearance?.header?.subtitle
2250
+ }
2251
+ }
2252
+ ),
2253
+ /* @__PURE__ */ jsxRuntime.jsx(AuthErrorBanner, { error, className: uiProps.appearance?.errorBanner }),
2254
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex flex-col gap-6 items-center", children: [
2255
+ /* @__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: [
2256
+ /* @__PURE__ */ jsxRuntime.jsx(
2257
+ AuthVerificationCodeInput,
2258
+ {
2259
+ value: verificationCode,
2260
+ onChange: setVerificationCode,
2261
+ email,
2262
+ disabled: isVerifyingCode,
2263
+ onComplete: (code) => {
2264
+ void handleVerifyCode(code);
2265
+ }
2266
+ }
2267
+ ),
2268
+ isVerifyingCode && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 text-center", children: "Verifying..." })
2269
+ ] }) }),
2270
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full text-sm text-center text-neutral-600 dark:text-neutral-400", children: [
2271
+ "Didn't receive the email?",
2272
+ " ",
2273
+ /* @__PURE__ */ jsxRuntime.jsx(
2274
+ "button",
2275
+ {
2276
+ onClick: () => {
2277
+ void handleResendCode();
2278
+ },
2279
+ disabled: resendDisabled || isSendingCode,
2280
+ className: "text-black dark:text-white font-medium transition-colors disabled:cursor-not-allowed cursor-pointer hover:underline disabled:no-underline disabled:opacity-50",
2281
+ children: isSendingCode ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
2282
+ }
2283
+ )
2284
+ ] })
2285
+ ] }),
2286
+ /* @__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" }) })
2287
+ ]
2288
+ }
2289
+ );
2125
2290
  }
2126
- return { valid: false, error: result.error.message };
2291
+ return /* @__PURE__ */ jsxRuntime.jsx(
2292
+ ResetPassword,
2293
+ {
2294
+ token: resetToken,
2295
+ backToSignInUrl,
2296
+ onSuccess: handlePasswordResetSuccess,
2297
+ onError,
2298
+ appearance: uiProps.appearance
2299
+ }
2300
+ );
2127
2301
  }
2128
- function validatePassword(password, options) {
2129
- const schema = createPasswordSchema(options);
2130
- const result = schema.safeParse(password);
2131
- if (result.success) {
2132
- return { valid: true };
2302
+ function VerifyEmailStatus({
2303
+ status,
2304
+ error,
2305
+ appearance = {},
2306
+ verifyingTitle = "Verifying your email...",
2307
+ successTitle = "Email Verified!",
2308
+ successMessage = "Your email has been verified successfully. You can close this page and return to your app.",
2309
+ errorTitle = "Verification Failed"
2310
+ }) {
2311
+ if (status === "verifying") {
2312
+ return /* @__PURE__ */ jsxRuntime.jsx(AuthContainer, { appearance, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex flex-col items-center justify-center gap-6", children: [
2313
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold text-black dark:text-white", children: verifyingTitle }),
2314
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-black dark:border-white" })
2315
+ ] }) });
2133
2316
  }
2134
- return { valid: false, error: result.error.message };
2135
- }
2136
- function checkPasswordStrength(password) {
2137
- const feedback = [];
2138
- let score = 0;
2139
- if (password.length >= 8) {
2140
- score += 1;
2141
- } else {
2142
- feedback.push("Use at least 8 characters");
2317
+ if (status === "error") {
2318
+ return /* @__PURE__ */ jsxRuntime.jsx(AuthContainer, { appearance, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex flex-col items-stretch justify-center gap-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start justify-center gap-2", children: [
2319
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-semibold text-black dark:text-white", children: errorTitle }),
2320
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 leading-relaxed", children: [
2321
+ error || "The verification link is invalid or has expired.",
2322
+ " Please try again or contact support if the problem persists. You can close this page and return to your app."
2323
+ ] })
2324
+ ] }) }) });
2143
2325
  }
2144
- if (password.length >= 12) {
2145
- score += 1;
2326
+ return /* @__PURE__ */ jsxRuntime.jsx(AuthContainer, { appearance, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex flex-col items-stretch justify-center gap-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-4", children: [
2327
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-16 rounded-full bg-green-100 dark:bg-green-900 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-8 h-8 text-green-600 dark:text-green-400", fill: "none", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 13l4 4L19 7" }) }) }),
2328
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold text-black dark:text-white text-center", children: successTitle }),
2329
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 text-center", children: successMessage })
2330
+ ] }) }) });
2331
+ }
2332
+ function VerifyEmail({
2333
+ token,
2334
+ onSuccess,
2335
+ onError,
2336
+ ...uiProps
2337
+ }) {
2338
+ const { verifyEmail } = useInsforge();
2339
+ const [status, setStatus] = react.useState("verifying");
2340
+ const [error, setError] = react.useState("");
2341
+ react.useEffect(() => {
2342
+ const verifyEmailFn = async () => {
2343
+ if (!token) {
2344
+ const errorMessage = "Invalid verification link. Missing required token.";
2345
+ setError(errorMessage);
2346
+ setStatus("error");
2347
+ if (onError) {
2348
+ onError(new Error(errorMessage));
2349
+ }
2350
+ return;
2351
+ }
2352
+ try {
2353
+ const result = await verifyEmail(token);
2354
+ if (!result?.accessToken) {
2355
+ const errorMessage = result ? "Verification succeeded but no access token received" : "Email verification failed";
2356
+ setError(errorMessage);
2357
+ setStatus("error");
2358
+ if (onError) {
2359
+ onError(new Error(errorMessage));
2360
+ }
2361
+ return;
2362
+ }
2363
+ setStatus("success");
2364
+ if (onSuccess) {
2365
+ onSuccess({
2366
+ accessToken: result.accessToken,
2367
+ user: result.user
2368
+ });
2369
+ }
2370
+ } catch (err) {
2371
+ const errorMessage = err.message || "Email verification failed";
2372
+ setError(errorMessage);
2373
+ setStatus("error");
2374
+ if (onError) {
2375
+ onError(new Error(errorMessage));
2376
+ }
2377
+ }
2378
+ };
2379
+ void verifyEmailFn();
2380
+ }, [token, verifyEmail, onSuccess, onError]);
2381
+ return /* @__PURE__ */ jsxRuntime.jsx(VerifyEmailStatus, { status, error, ...uiProps });
2382
+ }
2383
+ function UserButton({
2384
+ afterSignOutUrl = "/",
2385
+ mode = "detailed",
2386
+ appearance = {}
2387
+ }) {
2388
+ const { user, signOut } = useInsforge();
2389
+ const [isOpen, setIsOpen] = react.useState(false);
2390
+ const [imageError, setImageError] = react.useState(false);
2391
+ const dropdownRef = react.useRef(null);
2392
+ react.useEffect(() => {
2393
+ setImageError(false);
2394
+ const avatarUrl = user?.avatarUrl;
2395
+ if (!avatarUrl) return;
2396
+ const checkImageUrl = async () => {
2397
+ try {
2398
+ const response = await fetch(avatarUrl, {
2399
+ method: "HEAD",
2400
+ cache: "no-cache"
2401
+ });
2402
+ if (!response.ok) {
2403
+ setImageError(true);
2404
+ }
2405
+ } catch (error) {
2406
+ setImageError(true);
2407
+ }
2408
+ };
2409
+ checkImageUrl();
2410
+ }, [user?.avatarUrl]);
2411
+ react.useEffect(() => {
2412
+ function handleClickOutside(event) {
2413
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
2414
+ setIsOpen(false);
2415
+ }
2416
+ }
2417
+ if (isOpen) {
2418
+ document.addEventListener("mousedown", handleClickOutside);
2419
+ }
2420
+ return () => {
2421
+ document.removeEventListener("mousedown", handleClickOutside);
2422
+ };
2423
+ }, [isOpen]);
2424
+ async function handleSignOut() {
2425
+ await signOut();
2426
+ setIsOpen(false);
2427
+ window.location.href = afterSignOutUrl;
2146
2428
  }
2147
- if (/[a-z]/.test(password) && /[A-Z]/.test(password)) {
2148
- score += 1;
2149
- } else {
2150
- feedback.push("Use both uppercase and lowercase letters");
2429
+ if (!user) return null;
2430
+ const initials = user.name ? user.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
2431
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2432
+ "div",
2433
+ {
2434
+ className: cn("relative inline-block", appearance.containerClassName),
2435
+ ref: dropdownRef,
2436
+ children: [
2437
+ /* @__PURE__ */ jsxRuntime.jsxs(
2438
+ "button",
2439
+ {
2440
+ className: cn(
2441
+ "p-1 bg-transparent border-0 rounded-full cursor-pointer transition-all duration-200",
2442
+ "flex items-center justify-center gap-2",
2443
+ "hover:bg-black/5",
2444
+ mode === "detailed" && "rounded-lg p-2",
2445
+ appearance.buttonClassName
2446
+ ),
2447
+ onClick: () => setIsOpen(!isOpen),
2448
+ "aria-expanded": isOpen,
2449
+ "aria-haspopup": "true",
2450
+ children: [
2451
+ /* @__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(
2452
+ "img",
2453
+ {
2454
+ src: user.avatarUrl,
2455
+ alt: user.email,
2456
+ onError: () => setImageError(true),
2457
+ className: "rounded-full object-cover w-full h-full"
2458
+ }
2459
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-white font-semibold text-sm", children: initials }) }),
2460
+ mode === "detailed" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-0.5", children: [
2461
+ user.name && /* @__PURE__ */ jsxRuntime.jsx(
2462
+ "div",
2463
+ {
2464
+ className: cn(
2465
+ "text-sm font-semibold text-gray-900 leading-5 text-left",
2466
+ appearance.nameClassName
2467
+ ),
2468
+ children: user.name
2469
+ }
2470
+ ),
2471
+ /* @__PURE__ */ jsxRuntime.jsx(
2472
+ "div",
2473
+ {
2474
+ className: cn(
2475
+ "text-xs text-gray-500 leading-4 text-left",
2476
+ appearance.emailClassName
2477
+ ),
2478
+ children: user.email
2479
+ }
2480
+ )
2481
+ ] })
2482
+ ]
2483
+ }
2484
+ ),
2485
+ isOpen && /* @__PURE__ */ jsxRuntime.jsx(
2486
+ "div",
2487
+ {
2488
+ className: cn(
2489
+ "absolute top-full right-0 mt-2 min-w-40",
2490
+ "bg-white border border-gray-200 rounded-lg",
2491
+ "shadow-lg z-50 overflow-hidden p-1",
2492
+ appearance.dropdownClassName
2493
+ ),
2494
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
2495
+ "button",
2496
+ {
2497
+ onClick: handleSignOut,
2498
+ 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",
2499
+ children: [
2500
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LogOut, { className: "w-5 h-5" }),
2501
+ "Sign out"
2502
+ ]
2503
+ }
2504
+ )
2505
+ }
2506
+ )
2507
+ ]
2508
+ }
2509
+ );
2510
+ }
2511
+ function Protect({
2512
+ children,
2513
+ fallback,
2514
+ redirectTo = "/sign-in",
2515
+ condition,
2516
+ onRedirect
2517
+ }) {
2518
+ const { isSignedIn, isLoaded, user } = useInsforge();
2519
+ react.useEffect(() => {
2520
+ if (isLoaded && !isSignedIn) {
2521
+ if (onRedirect) {
2522
+ onRedirect(redirectTo);
2523
+ } else {
2524
+ window.location.href = redirectTo;
2525
+ }
2526
+ } else if (isLoaded && isSignedIn && condition && user) {
2527
+ if (!condition(user)) {
2528
+ if (onRedirect) {
2529
+ onRedirect(redirectTo);
2530
+ } else {
2531
+ window.location.href = redirectTo;
2532
+ }
2533
+ }
2534
+ }
2535
+ }, [isLoaded, isSignedIn, redirectTo, condition, user, onRedirect]);
2536
+ if (!isLoaded) {
2537
+ return fallback || /* @__PURE__ */ jsxRuntime.jsx("div", { className: "insforge-loading", children: "Loading..." });
2151
2538
  }
2152
- if (/\d/.test(password)) {
2153
- score += 1;
2154
- } else {
2155
- feedback.push("Include at least one number");
2539
+ if (!isSignedIn) {
2540
+ return fallback || null;
2156
2541
  }
2157
- if (/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(password)) {
2158
- score += 1;
2159
- } else {
2160
- feedback.push("Include at least one special character");
2542
+ if (condition && user && !condition(user)) {
2543
+ return fallback || null;
2161
2544
  }
2162
- return { score, feedback };
2545
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
2546
+ }
2547
+ function SignedIn({ children }) {
2548
+ const { isSignedIn, isLoaded } = useInsforge();
2549
+ if (!isLoaded) return null;
2550
+ if (!isSignedIn) return null;
2551
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
2552
+ }
2553
+ function SignedOut({ children }) {
2554
+ const { isSignedIn, isLoaded } = useInsforge();
2555
+ if (!isLoaded) return null;
2556
+ if (isSignedIn) return null;
2557
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
2558
+ }
2559
+ function InsforgeCallback({
2560
+ redirectTo = "/",
2561
+ onSuccess,
2562
+ onError,
2563
+ loadingComponent,
2564
+ onRedirect
2565
+ }) {
2566
+ const isProcessingRef = react.useRef(false);
2567
+ const { isLoaded, isSignedIn } = useInsforge();
2568
+ react.useEffect(() => {
2569
+ if (!isLoaded) return;
2570
+ if (isProcessingRef.current) return;
2571
+ isProcessingRef.current = true;
2572
+ const processCallback = async () => {
2573
+ const searchParams = new URLSearchParams(window.location.search);
2574
+ const error = searchParams.get("error");
2575
+ if (error) {
2576
+ if (onError) {
2577
+ onError(error);
2578
+ } else {
2579
+ const errorUrl = "/?error=" + encodeURIComponent(error);
2580
+ if (onRedirect) {
2581
+ onRedirect(errorUrl);
2582
+ } else {
2583
+ window.location.href = errorUrl;
2584
+ }
2585
+ }
2586
+ return;
2587
+ }
2588
+ if (!isSignedIn) {
2589
+ const errorMsg = "authentication_failed";
2590
+ if (onError) {
2591
+ onError(errorMsg);
2592
+ } else {
2593
+ const errorUrl = "/?error=" + encodeURIComponent(errorMsg);
2594
+ if (onRedirect) {
2595
+ onRedirect(errorUrl);
2596
+ } else {
2597
+ window.location.href = errorUrl;
2598
+ }
2599
+ }
2600
+ return;
2601
+ }
2602
+ window.history.replaceState({}, "", window.location.pathname);
2603
+ if (onSuccess) {
2604
+ onSuccess();
2605
+ }
2606
+ if (onRedirect) {
2607
+ onRedirect(redirectTo);
2608
+ } else {
2609
+ window.location.href = redirectTo;
2610
+ }
2611
+ };
2612
+ processCallback();
2613
+ }, [isLoaded, isSignedIn, redirectTo, onSuccess, onError, onRedirect]);
2614
+ const defaultLoading = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
2615
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold mb-4", children: "Completing authentication..." }),
2616
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto" })
2617
+ ] }) });
2618
+ return loadingComponent || defaultLoading;
2619
+ }
2620
+
2621
+ // src/hooks/useAuth.ts
2622
+ function useAuth() {
2623
+ const { signIn, signUp, signOut, isLoaded, isSignedIn } = useInsforge();
2624
+ return { signIn, signUp, signOut, isLoaded, isSignedIn };
2625
+ }
2626
+
2627
+ // src/hooks/useUser.ts
2628
+ function useUser() {
2629
+ const { user, isLoaded, updateUser, setUser } = useInsforge();
2630
+ return { user, isLoaded, updateUser, setUser };
2163
2631
  }
2164
2632
  function RedirectToAuth({ baseUrl, path }) {
2165
2633
  react.useEffect(() => {
@@ -2214,6 +2682,7 @@ function getInsforgeRoutes(config) {
2214
2682
  exports.AuthBranding = AuthBranding;
2215
2683
  exports.AuthContainer = AuthContainer;
2216
2684
  exports.AuthDivider = AuthDivider;
2685
+ exports.AuthEmailVerificationStep = AuthEmailVerificationStep;
2217
2686
  exports.AuthErrorBanner = AuthErrorBanner;
2218
2687
  exports.AuthFormField = AuthFormField;
2219
2688
  exports.AuthHeader = AuthHeader;
@@ -2224,11 +2693,13 @@ exports.AuthPasswordField = AuthPasswordField;
2224
2693
  exports.AuthPasswordStrengthIndicator = AuthPasswordStrengthIndicator;
2225
2694
  exports.AuthSubmitButton = AuthSubmitButton;
2226
2695
  exports.AuthVerificationCodeInput = AuthVerificationCodeInput;
2696
+ exports.ForgotPassword = ForgotPassword;
2227
2697
  exports.ForgotPasswordForm = ForgotPasswordForm;
2228
2698
  exports.InsforgeCallback = InsforgeCallback;
2229
2699
  exports.InsforgeProvider = InsforgeProvider;
2230
2700
  exports.OAUTH_PROVIDER_CONFIG = OAUTH_PROVIDER_CONFIG;
2231
2701
  exports.Protect = Protect;
2702
+ exports.ResetPassword = ResetPassword;
2232
2703
  exports.ResetPasswordForm = ResetPasswordForm;
2233
2704
  exports.SignIn = SignIn;
2234
2705
  exports.SignInForm = SignInForm;
@@ -2237,6 +2708,7 @@ exports.SignUpForm = SignUpForm;
2237
2708
  exports.SignedIn = SignedIn;
2238
2709
  exports.SignedOut = SignedOut;
2239
2710
  exports.UserButton = UserButton;
2711
+ exports.VerifyEmail = VerifyEmail;
2240
2712
  exports.VerifyEmailStatus = VerifyEmailStatus;
2241
2713
  exports.checkPasswordStrength = checkPasswordStrength;
2242
2714
  exports.cn = cn;