@insforge/nextjs 0.7.2 → 0.7.4

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
@@ -6,7 +6,7 @@ if (typeof document !== 'undefined' && typeof window !== 'undefined') {
6
6
  if (!document.getElementById(styleId)) {
7
7
  const style = document.createElement('style');
8
8
  style.id = styleId;
9
- style.textContent = "/**\n * InsForge Next.js Component Library Styles\n * A standalone CSS file for auth components - no Tailwind required!\n */\n\n/* Font Face Declaration */\n@font-face {\n font-family: 'Manrope';\n src: url('./fonts/Manrope-VariableFont_wght.ttf') format('truetype');\n font-weight: 100 900;\n font-style: normal;\n font-display: swap;\n}\n\n/* CSS Variables */\n:root {\n --font-manrope: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n}\n\n/* Reset and Base Styles */\n.insforge-auth-container * {\n box-sizing: border-box;\n}\n\n/* Main Container - App handles layout, we just provide the card */\n.insforge-auth-container {\n width: 100%;\n max-width: 400px;\n background: white;\n}\n\n.insforge-branding {\n background: #FAFAFA;\n padding: 8px 8px 16px 8px;\n display: flex;\n flex-direction: row;\n justify-content: center;\n align-items: center;\n gap: 4px;\n}\n\n.insforge-branding-text {\n color: #000;\n font-family: var(--font-manrope);\n font-size: 12px;\n font-style: normal;\n font-weight: 400;\n line-height: normal;\n}\n\n/* Form Card */\n.insforge-auth-card {\n width: 100%;\n border-radius: 12px;\n overflow: hidden;\n box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.25);\n}\n\n.insforge-auth-content {\n padding: 24px;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: stretch;\n gap: 24px;\n}\n\n/* Header */\n.insforge-auth-header {\n display: flex;\n flex-direction: column;\n justify-content: start;\n align-items: start;\n gap: 8px;\n}\n\n.insforge-auth-title {\n color: #000;\n font-family: Inter;\n font-size: 24px;\n font-style: normal;\n font-weight: 600;\n line-height: 32px; /* 133.333% */\n}\n\n.insforge-auth-subtitle {\n color: #828282;\n font-family: Inter;\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 24px; /* 171.429% */\n}\n\n/* Error Banner */\n.insforge-error-banner {\n display: flex;\n padding: 8px 8px 8px 12px;\n margin-bottom: 16px;\n align-items: center;\n gap: 8px;\n align-self: stretch;\n border-radius: 4px;\n border: 2px solid #DC2626;\n background: #FEF2F2;\n color: #DC2626;\n font-family: Inter;\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 20px; /* 142.857% */\n}\n\n.insforge-error-icon {\n color: #EF4444;\n flex-shrink: 0;\n width: 24px;\n height: 24px;\n}\n\n/* Form Elements */\n.insforge-form {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: stretch;\n gap: 24px;\n}\n\n.insforge-form-group {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: stretch;\n gap: 4px;\n}\n\n.insforge-form-label-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.insforge-form-label {\n color: #000;\n font-family: Inter;\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 24px;\n}\n\n.insforge-form-link {\n color: #828282;\n text-align: right;\n font-family: Inter;\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 24px;\n}\n\n.insforge-form-link:hover {\n color: #828282;\n text-decoration: underline;\n}\n\n/* Input Container for Password (with icon) */\n.insforge-input-wrapper {\n position: relative;\n}\n\n.insforge-input {\n width: 100%;\n display: flex;\n padding: 8px 8px 10px 12px;\n align-items: center;\n gap: 8px;\n align-self: stretch;\n border-radius: 4px;\n border: 1px solid #BCBCBC;\n background: #FFF;\n font-family: Inter;\n font-size: 16px;\n font-style: normal;\n font-weight: 400;\n line-height: 20px;\n}\n\n.insforge-input::placeholder {\n color: #A6A6A6;\n}\n\n.insforge-input:focus {\n outline: none;\n}\n\n.insforge-input-with-icon {\n padding-right: 3rem;\n}\n\n.insforge-input-icon-btn {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n background: transparent;\n border: none;\n color: #A6A6A6;\n cursor: pointer;\n transition: color 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.insforge-input-icon-btn:hover {\n color: #6b7280;\n}\n\n/* Primary Button */\n.insforge-btn-primary {\n border-radius: 4px;\n background: #000;\n width: 100%;\n display: flex;\n margin: 16px 0 0 0;\n padding: 8px 16px;\n justify-content: center;\n align-items: center;\n gap: 10px;\n align-self: stretch;\n color: #FFF;\n font-family: Manrope;\n font-size: 16px;\n font-style: normal;\n font-weight: 600;\n line-height: normal;\n border: none;\n cursor: pointer;\n}\n\n.insforge-btn-primary:hover {\n background: #303030;\n}\n\n.insforge-btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.insforge-btn-primary .insforge-btn-loader {\n display: none;\n animation: insforge-spin 1s linear infinite;\n}\n\n.insforge-btn-primary[data-loading] .insforge-btn-loader {\n display: block;\n}\n\n.insforge-btn-primary .insforge-btn-check {\n display: none;\n}\n\n.insforge-btn-primary[data-confirmed] .insforge-btn-check {\n display: block;\n}\n\n/* Text Link Section */\n.insforge-text-center {\n text-align: center;\n color: #828282;\n font-family: Inter;\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 24px;\n}\n\n.insforge-link-primary {\n color: #000;\n font-family: Inter;\n font-size: 14px;\n font-style: normal;\n font-weight: 500;\n line-height: 24px;\n}\n\n/* Divider */\n.insforge-divider {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 24px;\n align-self: stretch;\n}\n\n.insforge-divider::before,\n.insforge-divider::after {\n content: '';\n flex: 1;\n height: 1px;\n background: #C6C6C6;\n}\n\n.insforge-divider-text {\n color: #C6C6C6;\n font-family: Manrope;\n font-size: 14px;\n font-style: normal;\n font-weight: 600;\n line-height: normal;\n}\n\n/* OAuth Section */\n.insforge-oauth-container {\n display: grid;\n gap: 12px;\n width: 100%;\n}\n\n/* ============================================================================\n SMART OAUTH GRID LAYOUT SYSTEM\n Pattern: 1→1x1, 2→1x2, 3→1x3, 4→2x2, 5+→auto (3 per row, last row centered)\n ============================================================================ */\n\n/* 1 provider: single column, full width - displays \"Continue with Provider\" */\n.insforge-oauth-container[data-provider-count=\"1\"] {\n grid-template-columns: 1fr;\n}\n\n/* 2 providers: two columns - displays \"Provider\" */\n.insforge-oauth-container[data-provider-count=\"2\"] {\n grid-template-columns: repeat(2, 1fr);\n}\n\n/* 3 providers: three columns - icon only */\n.insforge-oauth-container[data-provider-count=\"3\"] {\n grid-template-columns: repeat(3, 1fr);\n}\n\n/* 4 providers: 2x2 grid - displays \"Provider\" */\n.insforge-oauth-container[data-provider-count=\"4\"] {\n grid-template-columns: repeat(2, 1fr);\n}\n\n/* 5+ providers: Universal 6-column grid system\n - Grid columns managed by OAuthProviderList component via inline styles\n - This provides precise control over button positioning */\n.insforge-oauth-container:not([data-provider-count=\"1\"]):not([data-provider-count=\"2\"]):not([data-provider-count=\"3\"]):not([data-provider-count=\"4\"]) {\n grid-template-columns: repeat(6, 1fr);\n}\n\n/* OAuth Button */\n.insforge-oauth-btn {\n display: flex;\n width: 100%;\n height: 36px;\n padding: 8px 12px;\n flex-direction: row;\n justify-content: center;\n align-items: center;\n gap: 12px;\n border-radius: 6px;\n border: 1px solid #E4E4E7;\n background: #FFF;\n box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.10);\n color: #09090B;\n text-align: center;\n font-family: Inter;\n font-size: 14px;\n font-style: normal;\n font-weight: 500;\n line-height: 20px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n/* Full mode: show icon + \"Continue with Provider\" */\n.insforge-oauth-btn[data-display-mode=\"full\"] {\n justify-content: center;\n}\n\n/* Short mode: show icon + \"Provider\" */\n.insforge-oauth-btn[data-display-mode=\"short\"] {\n justify-content: center;\n padding: 8px;\n gap: 8px;\n}\n\n/* Icon only mode: show only icon */\n.insforge-oauth-btn[data-display-mode=\"icon\"] {\n justify-content: center;\n gap: 0;\n}\n\n.insforge-oauth-btn[data-display-mode=\"icon\"] .insforge-oauth-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.insforge-oauth-btn:hover {\n background: #f9fafb;\n border-color: #9ca3af;\n}\n\n.insforge-oauth-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.insforge-oauth-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.insforge-oauth-loader {\n display: none;\n animation: insforge-spin 1s linear infinite;\n}\n\n.insforge-oauth-btn[data-loading] .insforge-oauth-icon {\n display: none;\n}\n\n.insforge-oauth-btn[data-loading] .insforge-oauth-loader {\n display: block;\n}\n\n/* Spin Animation */\n@keyframes insforge-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n/* UserButton Styles */\n.insforge-user-button-container {\n position: relative;\n display: inline-block;\n}\n\n.insforge-user-button {\n padding: 0.25rem;\n background: transparent;\n border: none;\n border-radius: 9999px;\n cursor: pointer;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n}\n\n.insforge-user-button:hover {\n background: rgba(0, 0, 0, 0.05);\n}\n\n.insforge-user-button-detailed {\n border-radius: 0.5rem;\n padding: 0.5rem;\n}\n\n.insforge-user-button-info {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 0.125rem;\n}\n\n.insforge-user-button-name {\n font-size: 0.875rem;\n font-weight: 600;\n color: #111827;\n line-height: 1.25rem;\n text-align: left;\n}\n\n.insforge-user-button-email {\n font-size: 0.75rem;\n color: #6b7280;\n line-height: 1rem;\n text-align: left;\n}\n\n.insforge-user-avatar {\n width: 2.5rem;\n height: 2.5rem;\n border-radius: 9999px;\n object-fit: cover;\n}\n\n.insforge-user-avatar-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2.5rem;\n height: 2.5rem;\n background: #3b82f6;\n color: white;\n font-weight: 600;\n font-size: 0.875rem;\n border-radius: 9999px;\n}\n\n.insforge-user-dropdown {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 0.5rem;\n min-width: 10rem;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 0.5rem;\n box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n z-index: 50;\n overflow: hidden;\n padding: 0.25rem;\n}\n\n.insforge-sign-out-button {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n gap: 0.5rem;\n width: 100%;\n padding: 0.5rem 0.75rem;\n font-size: 0.875rem;\n font-family: inherit;\n color: #dc2626;\n background: transparent;\n border: none;\n border-radius: 0.375rem;\n cursor: pointer;\n transition: background 0.2s;\n text-align: left;\n}\n\n.insforge-sign-out-button:hover {\n background: #fef2f2;\n}\n\n/* Loading State */\n.insforge-loading {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 2rem;\n color: #6b7280;\n font-size: 0.875rem;\n}\n\n/* Password Strength Indicator */\n.insforge-password-strength {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n margin-top: 0.5rem;\n}\n\n.insforge-password-requirement {\n height: 1.5rem;\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.insforge-password-check {\n width: 1.25rem;\n height: 1.25rem;\n border-radius: 9999px;\n display: flex;\n border-width: 2px;\n border-style: solid;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease-in-out;\n background-color: transparent;\n border-color: #a3a3a3;\n flex-shrink: 0;\n}\n\n.insforge-password-check-valid {\n background-color: #22c55e;\n border-color: transparent;\n}\n\n.insforge-password-check-icon {\n color: #fff;\n stroke-width: 3;\n}\n\n.insforge-password-requirement-label {\n color:#000;\n font-family: Inter;\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 24px;\n}\n\n/* Verification Code Input */\n.insforge-verification-code-container {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n gap: 24px;\n}\n\n.insforge-verification-instructions {\n color: #525252;\n font-family: Inter;\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 20px;\n}\n\n.insforge-verification-instructions > span {\n color: #000;\n font-family: Inter;\n font-size: 14px;\n font-style: normal;\n font-weight: 600;\n line-height: 20px;\n}\n\n.insforge-verification-code-inputs {\n display: flex;\n flex-direction: row;\n gap: 12px;\n justify-content: center;\n align-items: center;\n}\n\n.insforge-verification-code-input {\n width: 100%;\n height: 48px;\n padding: 8px 12px;\n border-radius: 4px;\n border: 1px solid #E0E0E0;\n background: #FFF;\n text-align: center;\n font-size: 16px;\n font-style: normal;\n line-height: 20px;\n font-weight: 600;\n font-family: var(--font-manrope);\n color: #000;\n transition: all 0.2s ease-in-out;\n outline: none;\n}\n\n.insforge-verification-code-input:focus {\n border-color: #000;\n box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1);\n}\n\n.insforge-verification-code-input:disabled {\n background-color: #F5F5F5;\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n/* Verification Instructions */\n.insforge-verification-instructions {\n color: #4F4F4F;\n font-family: Inter;\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 24px;\n margin-bottom: 8px;\n}\n\n.insforge-verification-email {\n color: #000;\n font-weight: 600;\n}\n\n.insforge-resend-code {\n color: #525252;\n font-family: Inter;\n font-size: 14px;\n font-style: normal;\n font-weight: 400;\n line-height: 24px;\n text-align: center;\n}\n\n.insforge-resend-link {\n color: #000;\n font-family: Inter;\n font-size: 14px;\n font-style: normal;\n font-weight: 500;\n line-height: 24px;\n}\n\n.insforge-resend-link:hover {\n text-decoration: underline;\n}\n\n.insforge-resend-link:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Responsive adjustments */\n@media (max-width: 640px) {\n .insforge-auth-card {\n padding: 2rem 1.5rem;\n }\n\n .insforge-auth-title {\n font-size: 1.75rem;\n }\n\n .insforge-verification-code-container {\n gap: 8px;\n }\n\n .insforge-verification-code-input {\n width: 40px;\n height: 48px;\n font-size: 20px;\n }\n}\n\n";
9
+ 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-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-500:oklch(72.3% .219 149.579);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-gray-200:oklch(92.8% .006 264.531);--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-black:#000;--color-white:#fff;--spacing:.25rem;--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-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--leading-normal:1.5;--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-4{margin-top:calc(var(--spacing)*4)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.flex{display:flex}.grid{display:grid}.inline-block{display:inline-block}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-12{height:calc(var(--spacing)*12)}.h-\\[18px\\]{height:18px}.min-h-screen{min-height:100vh}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-10{width:calc(var(--spacing)*10)}.w-12{width:calc(var(--spacing)*12)}.w-\\[18px\\]{width:18px}.w-full{width:100%}.max-w-\\[400px\\]{max-width:400px}.min-w-40{min-width:calc(var(--spacing)*40)}.flex-1{flex:1}.flex-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-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.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-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-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-red-600{border-color:var(--color-red-600)}.border-transparent{border-color:#0000}.bg-\\[\\#FAFAFA\\]{background-color:#fafafa}.bg-black{background-color:var(--color-black)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-green-500{background-color:var(--color-green-500)}.bg-red-50{background-color:var(--color-red-50)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.stroke-\\[3\\]{stroke-width:3px}.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-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--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)}.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-gray-500{color:var(--color-gray-500)}.text-gray-900{color:var(--color-gray-900)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.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-gray-800:hover{background-color:var(--color-gray-800)}.hover\\:bg-red-50:hover{background-color:var(--color-red-50)}.hover\\:text-gray-600:hover{color:var(--color-gray-600)}}.focus\\:border-black:focus{border-color:var(--color-black)}.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\\: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}}@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-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)}}";
10
10
  if (document.head) {
11
11
  document.head.appendChild(style);
12
12
  }
@@ -67,6 +67,7 @@ __export(src_exports, {
67
67
  SignedIn: () => SignedIn,
68
68
  SignedOut: () => SignedOut,
69
69
  UserButton: () => UserButton,
70
+ cn: () => cn,
70
71
  getProviderConfig: () => getProviderConfig,
71
72
  getProviderName: () => getProviderName,
72
73
  isProviderSupported: () => isProviderSupported,
@@ -166,7 +167,7 @@ function InsforgeProvider({
166
167
  id: userResult.data.user.id,
167
168
  email: userResult.data.user.email,
168
169
  name: userResult.data.profile?.nickname || "",
169
- avatarUrl: userResult.data.profile?.avatar_url || ""
170
+ avatarUrl: userResult.data.profile?.avatarUrl || ""
170
171
  };
171
172
  setUser(userData);
172
173
  setSession({
@@ -225,7 +226,7 @@ function InsforgeProvider({
225
226
  id: userResult.data.user.id,
226
227
  email: userResult.data.user.email,
227
228
  name: userResult.data.profile?.nickname || "",
228
- avatarUrl: userResult.data.profile?.avatar_url || ""
229
+ avatarUrl: userResult.data.profile?.avatarUrl || ""
229
230
  };
230
231
  const sessionData = {
231
232
  userId: userResult.data.user.id,
@@ -321,7 +322,7 @@ function InsforgeProvider({
321
322
  if (!user) throw new Error("No user signed in");
322
323
  const result = await insforge.auth.setProfile({
323
324
  nickname: data.name || "",
324
- avatar_url: data.avatarUrl || ""
325
+ avatarUrl: data.avatarUrl || ""
325
326
  });
326
327
  if (result.data) {
327
328
  const updatedUser = { ...user, ...result.data };
@@ -465,12 +466,22 @@ function useEmailAuthConfig() {
465
466
  return { config, isLoaded };
466
467
  }
467
468
 
469
+ // src/lib/utils.ts
470
+ var import_clsx = require("clsx");
471
+ var import_tailwind_merge = require("tailwind-merge");
472
+ function cn(...inputs) {
473
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
474
+ }
475
+
468
476
  // src/components/auth/AuthBranding.tsx
469
477
  var import_link = __toESM(require("next/link"));
470
478
  var import_jsx_runtime2 = require("react/jsx-runtime");
471
- function AuthBranding({ text = "Secured by", href = "https://insforge.dev" }) {
472
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "insforge-branding", children: [
473
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "insforge-branding-text", children: text }),
479
+ function AuthBranding({ text = "Secured by", href = "https://insforge.dev", className }) {
480
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: cn(
481
+ "bg-[#FAFAFA] px-2 py-4 flex flex-row justify-center items-center gap-1",
482
+ className
483
+ ), children: [
484
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xs font-medium text-black font-manrope", children: text }),
474
485
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_link.default, { href, target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { width: "83", height: "20", viewBox: "0 0 83 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
475
486
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
476
487
  "path",
@@ -531,43 +542,98 @@ function AuthBranding({ text = "Secured by", href = "https://insforge.dev" }) {
531
542
 
532
543
  // src/components/auth/AuthContainer.tsx
533
544
  var import_jsx_runtime3 = require("react/jsx-runtime");
534
- function AuthContainer({ children, style }) {
535
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "insforge-auth-container", style, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "insforge-auth-card", children: [
536
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "insforge-auth-content", children }),
545
+ function AuthContainer({
546
+ children,
547
+ style,
548
+ className
549
+ }) {
550
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: cn("w-full max-w-[400px]", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "w-full rounded-xl overflow-hidden shadow-lg", children: [
551
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "bg-white p-6 flex flex-col justify-center items-stretch gap-6", children }),
537
552
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AuthBranding, {})
538
553
  ] }) });
539
554
  }
540
555
 
541
556
  // src/components/auth/AuthHeader.tsx
542
557
  var import_jsx_runtime4 = require("react/jsx-runtime");
543
- function AuthHeader({ title, subtitle }) {
544
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "insforge-auth-header", children: [
545
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { className: "insforge-auth-title", children: title }),
546
- subtitle && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "insforge-auth-subtitle", children: subtitle })
558
+ function AuthHeader({
559
+ title,
560
+ subtitle,
561
+ className,
562
+ titleClassName,
563
+ subtitleClassName
564
+ }) {
565
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: cn(
566
+ "flex flex-col justify-start items-start gap-2",
567
+ className
568
+ ), children: [
569
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { className: cn(
570
+ "text-2xl font-semibold text-black leading-8",
571
+ titleClassName
572
+ ), children: title }),
573
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: cn(
574
+ "text-sm font-normal text-[#828282] leading-6",
575
+ subtitleClassName
576
+ ), children: subtitle })
547
577
  ] });
548
578
  }
549
579
 
550
580
  // src/components/auth/AuthErrorBanner.tsx
551
581
  var import_lucide_react = require("lucide-react");
552
582
  var import_jsx_runtime5 = require("react/jsx-runtime");
553
- function AuthErrorBanner({ error }) {
583
+ function AuthErrorBanner({ error, className }) {
554
584
  if (!error) return null;
555
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "insforge-error-banner", children: [
556
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.AlertTriangle, { className: "insforge-error-icon" }),
557
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: error })
558
- ] });
585
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
586
+ "div",
587
+ {
588
+ className: cn(
589
+ "flex items-center gap-2 mb-4 pl-3 py-2 pr-2 bg-red-50 border-2 border-red-600 rounded",
590
+ className
591
+ ),
592
+ children: [
593
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.AlertTriangle, { className: "w-6 h-6 text-red-500 flex-shrink-0" }),
594
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-sm text-red-600 flex-1", children: error })
595
+ ]
596
+ }
597
+ );
559
598
  }
560
599
 
561
600
  // src/components/auth/AuthFormField.tsx
562
601
  var import_jsx_runtime6 = require("react/jsx-runtime");
563
- function AuthFormField({ label, id, className = "", ...props }) {
564
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "insforge-form-group", children: [
565
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("label", { htmlFor: id, className: "insforge-form-label", children: label }),
602
+ function AuthFormField({
603
+ label,
604
+ id,
605
+ className = "",
606
+ labelClassName,
607
+ inputClassName,
608
+ ...props
609
+ }) {
610
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: cn(
611
+ "flex flex-col justify-center items-stretch gap-1",
612
+ className
613
+ ), children: [
614
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
615
+ "label",
616
+ {
617
+ htmlFor: id,
618
+ className: cn(
619
+ "text-sm font-normal text-black leading-6",
620
+ labelClassName
621
+ ),
622
+ children: label
623
+ }
624
+ ),
566
625
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
567
626
  "input",
568
627
  {
569
628
  id,
570
- className: `insforge-input ${className}`,
629
+ className: cn(
630
+ "w-full flex items-center gap-2 self-stretch",
631
+ "pl-3 pr-2 py-2 rounded-sm border border-[#D4D4D4] bg-white",
632
+ "text-sm font-normal leading-5",
633
+ "placeholder:text-[#A3A3A3] placeholder:font-sm placeholder:font-normal",
634
+ "focus:outline-none focus:border-black",
635
+ inputClassName
636
+ ),
571
637
  ...props
572
638
  }
573
639
  )
@@ -625,20 +691,25 @@ function validatePasswordStrength(password, config) {
625
691
  }
626
692
  function AuthPasswordStrengthIndicator({
627
693
  password,
628
- config
694
+ config,
695
+ className
629
696
  }) {
630
697
  const requirements = createRequirements(config);
631
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "insforge-password-strength", children: requirements.map((requirement, index) => {
698
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: cn("flex flex-col gap-1 mt-2", className), children: requirements.map((requirement, index) => {
632
699
  const isValid = requirement.test(password);
633
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "insforge-password-requirement", children: [
700
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "h-6 flex items-center gap-1", children: [
634
701
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
635
702
  "div",
636
703
  {
637
- className: `insforge-password-check ${isValid ? "insforge-password-check-valid" : ""}`,
638
- children: isValid && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react2.Check, { className: "insforge-password-check-icon", size: 12 })
704
+ className: cn(
705
+ "w-5 h-5 rounded-full flex items-center justify-center transition-all duration-200",
706
+ "border-2 flex-shrink-0",
707
+ isValid ? "bg-green-500 border-transparent" : "bg-transparent border-neutral-400"
708
+ ),
709
+ children: isValid && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react2.Check, { className: "text-white stroke-[3]", size: 12 })
639
710
  }
640
711
  ),
641
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "insforge-password-requirement-label", children: requirement.label })
712
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-sm font-normal text-black leading-6", children: requirement.label })
642
713
  ] }, index);
643
714
  }) });
644
715
  }
@@ -653,6 +724,8 @@ function AuthPasswordField({
653
724
  forgotPasswordLink,
654
725
  value,
655
726
  className = "",
727
+ labelClassName,
728
+ inputClassName,
656
729
  onFocus,
657
730
  ...props
658
731
  }) {
@@ -664,42 +737,75 @@ function AuthPasswordField({
664
737
  }
665
738
  onFocus?.(e);
666
739
  };
667
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "insforge-form-group", children: [
668
- (label || forgotPasswordLink) && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "insforge-form-label-row", children: [
669
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { htmlFor: id, className: "insforge-form-label", style: { margin: 0 }, children: label }),
670
- forgotPasswordLink && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("a", { href: forgotPasswordLink.href, className: "insforge-form-link", children: forgotPasswordLink.text || "Forget Password?" })
671
- ] }),
672
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "insforge-input-wrapper", children: [
673
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
674
- "input",
675
- {
676
- id,
677
- type: showPassword ? "text" : "password",
678
- className: `insforge-input insforge-input-with-icon ${className}`,
679
- value,
680
- onFocus: handleFocus,
681
- ...props
682
- }
740
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
741
+ "div",
742
+ {
743
+ className: cn(
744
+ "flex flex-col justify-center items-stretch gap-1",
745
+ className
683
746
  ),
684
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
685
- "button",
686
- {
687
- type: "button",
688
- onClick: () => setShowPassword(!showPassword),
689
- className: "insforge-input-icon-btn",
690
- "aria-label": showPassword ? "Hide password" : "Show password",
691
- children: showPassword ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react3.EyeOff, { size: 20 }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react3.Eye, { size: 20 })
692
- }
693
- )
694
- ] }),
695
- showStrengthIndicator && showStrength && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
696
- AuthPasswordStrengthIndicator,
697
- {
698
- password: String(value || ""),
699
- config: emailAuthConfig
700
- }
701
- )
702
- ] });
747
+ children: [
748
+ (label || forgotPasswordLink) && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex justify-between items-center", children: [
749
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
750
+ "label",
751
+ {
752
+ htmlFor: id,
753
+ className: cn(
754
+ "text-sm font-normal text-black leading-6",
755
+ labelClassName
756
+ ),
757
+ children: label
758
+ }
759
+ ),
760
+ forgotPasswordLink && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
761
+ "a",
762
+ {
763
+ href: forgotPasswordLink.href,
764
+ className: "text-right text-sm font-normal text-[#737373] leading-6",
765
+ children: forgotPasswordLink.text || "Forget Password?"
766
+ }
767
+ )
768
+ ] }),
769
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "relative", children: [
770
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
771
+ "input",
772
+ {
773
+ id,
774
+ type: showPassword ? "text" : "password",
775
+ className: cn(
776
+ "w-full flex items-center gap-2 self-stretch",
777
+ "pl-3 py-2 pr-8 rounded border border-[#D4D4D4] bg-white",
778
+ "text-sm font-normal leading-5",
779
+ "placeholder:text-[#A3A3A3] placeholder:font-sm placeholder:font-normal",
780
+ "focus:outline-none focus:border-black",
781
+ inputClassName
782
+ ),
783
+ value,
784
+ onFocus: handleFocus,
785
+ ...props
786
+ }
787
+ ),
788
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
789
+ "button",
790
+ {
791
+ type: "button",
792
+ onClick: () => setShowPassword(!showPassword),
793
+ className: "absolute right-2 top-1/2 -translate-y-1/2 bg-transparent border-none text-[#A6A6A6] cursor-pointer transition-colors hover:text-gray-600 flex items-center justify-center",
794
+ "aria-label": showPassword ? "Hide password" : "Show password",
795
+ children: showPassword ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react3.EyeOff, { size: 20 }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react3.Eye, { size: 20 })
796
+ }
797
+ )
798
+ ] }),
799
+ showStrengthIndicator && showStrength && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
800
+ AuthPasswordStrengthIndicator,
801
+ {
802
+ password: String(value || ""),
803
+ config: emailAuthConfig
804
+ }
805
+ )
806
+ ]
807
+ }
808
+ );
703
809
  }
704
810
 
705
811
  // src/components/auth/AuthSubmitButton.tsx
@@ -710,20 +816,27 @@ function AuthSubmitButton({
710
816
  isLoading = false,
711
817
  confirmed = false,
712
818
  disabled = false,
713
- style
819
+ style,
820
+ className
714
821
  }) {
715
822
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
716
823
  "button",
717
824
  {
718
825
  type: "submit",
719
- className: "insforge-btn-primary",
826
+ className: cn(
827
+ "rounded-sm bg-black w-full flex mt-4 px-4 py-2",
828
+ "justify-center items-center gap-2.5 self-stretch",
829
+ "text-white font-semibold font-manrope text-base leading-normal",
830
+ "border-none cursor-pointer transition-colors",
831
+ "hover:bg-gray-800",
832
+ "disabled:opacity-50 disabled:cursor-not-allowed",
833
+ className
834
+ ),
720
835
  style,
721
836
  disabled: disabled || isLoading || confirmed,
722
- "data-loading": isLoading || void 0,
723
- "data-confirmed": confirmed || void 0,
724
837
  children: [
725
- isLoading && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.Loader2, { className: "insforge-btn-loader", size: 20 }),
726
- confirmed && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.CircleCheck, { className: "insforge-btn-check", size: 20 }),
838
+ isLoading && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.Loader2, { className: "w-5 h-5 animate-spin", size: 20 }),
839
+ confirmed && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.CircleCheck, { className: "w-5 h-5", size: 20 }),
727
840
  children
728
841
  ]
729
842
  }
@@ -732,17 +845,35 @@ function AuthSubmitButton({
732
845
 
733
846
  // src/components/auth/AuthDivider.tsx
734
847
  var import_jsx_runtime10 = require("react/jsx-runtime");
735
- function AuthDivider({ text = "or" }) {
736
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "insforge-divider", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "insforge-divider-text", children: text }) });
848
+ function AuthDivider({ text = "or", className }) {
849
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: cn(
850
+ "flex justify-center items-center gap-6 self-stretch",
851
+ "before:content-[''] before:flex-1 before:h-px before:bg-[#E5E5E5]",
852
+ "after:content-[''] after:flex-1 after:h-px after:bg-[#E5E5E5]",
853
+ className
854
+ ), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-sm font-semibold font-manrope text-[#A3A3A3] leading-normal", children: text }) });
737
855
  }
738
856
 
739
857
  // src/components/auth/AuthLink.tsx
740
858
  var import_jsx_runtime11 = require("react/jsx-runtime");
741
- function AuthLink({ text, linkText, href }) {
742
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: "insforge-text-center", children: [
859
+ function AuthLink({ text, linkText, href, className, linkClassName }) {
860
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: cn(
861
+ "text-center text-sm font-normal text-[#828282] leading-6",
862
+ className
863
+ ), children: [
743
864
  text,
744
865
  " ",
745
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("a", { href, className: "insforge-link-primary", children: linkText })
866
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
867
+ "a",
868
+ {
869
+ href,
870
+ className: cn(
871
+ "text-sm font-medium text-black leading-6",
872
+ linkClassName
873
+ ),
874
+ children: linkText
875
+ }
876
+ )
746
877
  ] });
747
878
  }
748
879
 
@@ -903,7 +1034,8 @@ function AuthOAuthButton({
903
1034
  disabled,
904
1035
  loading,
905
1036
  displayMode = "full",
906
- style
1037
+ style,
1038
+ className
907
1039
  }) {
908
1040
  const config = getProviderConfig(provider);
909
1041
  if (!config) {
@@ -920,15 +1052,25 @@ function AuthOAuthButton({
920
1052
  {
921
1053
  type: "button",
922
1054
  onClick: () => onClick(provider),
923
- className: "insforge-oauth-btn",
1055
+ className: cn(
1056
+ "flex w-full h-9 px-3 py-2",
1057
+ "flex-row justify-center items-center gap-3",
1058
+ "rounded-md border border-[#E4E4E7] bg-white",
1059
+ "shadow-[0_1px_2px_0_rgba(0,0,0,0.10)]",
1060
+ "text-[#09090B] text-center text-sm font-medium leading-5",
1061
+ "cursor-pointer transition-all duration-200",
1062
+ "hover:bg-[#f9fafb] hover:border-[#9ca3af]",
1063
+ "disabled:opacity-60 disabled:cursor-not-allowed",
1064
+ displayMode === "full" && "justify-center",
1065
+ displayMode === "short" && "justify-center px-2 gap-2",
1066
+ displayMode === "icon" && "justify-center gap-0",
1067
+ className
1068
+ ),
924
1069
  disabled: disabled || loading,
925
- "data-loading": loading || void 0,
926
- "data-display-mode": displayMode,
927
1070
  style,
928
1071
  children: [
929
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react5.Loader2, { className: "insforge-oauth-loader", size: 18 }),
930
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "insforge-oauth-icon", children: config.svg }),
931
- getButtonText() && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "insforge-oauth-text", children: getButtonText() })
1072
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react5.Loader2, { className: "w-[18px] h-[18px] animate-spin", size: 18 }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "flex items-center justify-center flex-shrink-0", children: config.svg }),
1073
+ getButtonText() && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: getButtonText() })
932
1074
  ]
933
1075
  }
934
1076
  );
@@ -940,7 +1082,8 @@ function AuthOAuthProviders({
940
1082
  providers,
941
1083
  onClick,
942
1084
  disabled,
943
- loading
1085
+ loading,
1086
+ className
944
1087
  }) {
945
1088
  if (!providers || providers.length === 0) {
946
1089
  return null;
@@ -975,7 +1118,18 @@ function AuthOAuthProviders({
975
1118
  return { gridColumn: "span 2" };
976
1119
  }
977
1120
  };
978
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "insforge-oauth-container", "data-provider-count": count, children: providers.map((provider, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1121
+ const getGridClass = () => {
1122
+ if (count === 1) return "grid-cols-1";
1123
+ if (count === 2) return "grid-cols-2";
1124
+ if (count === 3) return "grid-cols-3";
1125
+ if (count === 4) return "grid-cols-2";
1126
+ return "grid-cols-6";
1127
+ };
1128
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: cn(
1129
+ "grid gap-3 w-full",
1130
+ getGridClass(),
1131
+ className
1132
+ ), children: providers.map((provider, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
979
1133
  AuthOAuthButton,
980
1134
  {
981
1135
  provider,
@@ -997,7 +1151,9 @@ function AuthVerificationCodeInput({
997
1151
  value,
998
1152
  email,
999
1153
  onChange,
1000
- disabled = false
1154
+ disabled = false,
1155
+ className,
1156
+ inputClassName
1001
1157
  }) {
1002
1158
  const inputRefs = (0, import_react5.useRef)([]);
1003
1159
  const handleChange = (index, digit) => {
@@ -1032,13 +1188,17 @@ function AuthVerificationCodeInput({
1032
1188
  inputRefs.current[length - 1]?.focus();
1033
1189
  }
1034
1190
  };
1035
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "insforge-verification-code-container", children: [
1036
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("p", { className: "insforge-verification-instructions", children: [
1037
- "We've sent a verification code to your inbox at ",
1038
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: email }),
1191
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cn(
1192
+ "flex flex-col justify-center items-center gap-6",
1193
+ className
1194
+ ), children: [
1195
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("p", { className: "text-sm font-normal text-[#525252] leading-5", children: [
1196
+ "We've sent a verification code to your inbox at",
1197
+ " ",
1198
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-sm font-semibold text-black leading-5", children: email }),
1039
1199
  ". Enter it below to proceed."
1040
1200
  ] }),
1041
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "insforge-verification-code-inputs", children: Array.from({ length }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1201
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex flex-row gap-3 justify-center items-center", children: Array.from({ length }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1042
1202
  "input",
1043
1203
  {
1044
1204
  ref: (el) => {
@@ -1052,7 +1212,14 @@ function AuthVerificationCodeInput({
1052
1212
  onKeyDown: (e) => handleKeyDown(index, e),
1053
1213
  onPaste: handlePaste,
1054
1214
  disabled,
1055
- className: "insforge-verification-code-input",
1215
+ className: cn(
1216
+ "w-full h-12 px-3 py-2 rounded border border-[#E0E0E0] bg-white",
1217
+ "text-center text-base font-semibold leading-5 text-black",
1218
+ "transition-all duration-200 outline-none",
1219
+ "focus:border-black focus:shadow-[0_0_0_2px_rgba(0,0,0,0.1)]",
1220
+ "disabled:bg-[#F5F5F5] disabled:cursor-not-allowed disabled:opacity-60",
1221
+ inputClassName
1222
+ ),
1056
1223
  autoComplete: "one-time-code"
1057
1224
  },
1058
1225
  index
@@ -1088,7 +1255,9 @@ function SignIn({
1088
1255
  const [password, setPassword] = (0, import_react6.useState)("");
1089
1256
  const [error, setError] = (0, import_react6.useState)("");
1090
1257
  const [loading, setLoading] = (0, import_react6.useState)(false);
1091
- const [oauthLoading, setOauthLoading] = (0, import_react6.useState)(null);
1258
+ const [oauthLoading, setOauthLoading] = (0, import_react6.useState)(
1259
+ null
1260
+ );
1092
1261
  const insforge = (0, import_react6.useState)(() => (0, import_sdk4.createClient)({ baseUrl }))[0];
1093
1262
  async function handleSubmit(e) {
1094
1263
  e.preventDefault();
@@ -1128,50 +1297,58 @@ function SignIn({
1128
1297
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(AuthContainer, { style: appearance.container, children: [
1129
1298
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AuthHeader, { title, subtitle }),
1130
1299
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AuthErrorBanner, { error }),
1131
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("form", { onSubmit: handleSubmit, className: "insforge-form", children: [
1132
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1133
- AuthFormField,
1134
- {
1135
- id: "email",
1136
- type: "email",
1137
- label: emailLabel,
1138
- placeholder: emailPlaceholder,
1139
- value: email,
1140
- onChange: (e) => setEmail(e.target.value),
1141
- required: true,
1142
- autoComplete: "email"
1143
- }
1144
- ),
1145
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1146
- AuthPasswordField,
1147
- {
1148
- id: "password",
1149
- label: passwordLabel,
1150
- placeholder: passwordPlaceholder,
1151
- value: password,
1152
- onChange: (e) => setPassword(e.target.value),
1153
- required: true,
1154
- autoComplete: "current-password",
1155
- emailAuthConfig: emailAuthConfig || {
1156
- requireEmailVerification: false,
1157
- passwordMinLength: 6,
1158
- requireNumber: false,
1159
- requireLowercase: false,
1160
- requireUppercase: false,
1161
- requireSpecialChar: false
1162
- }
1163
- }
1164
- ),
1165
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1166
- AuthSubmitButton,
1167
- {
1168
- isLoading: loading,
1169
- disabled: loading || oauthLoading !== null,
1170
- style: appearance.button,
1171
- children: loading ? loadingButtonText : submitButtonText
1172
- }
1173
- )
1174
- ] }),
1300
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1301
+ "form",
1302
+ {
1303
+ onSubmit: handleSubmit,
1304
+ noValidate: true,
1305
+ className: "flex flex-col items-stretch justify-center gap-6",
1306
+ children: [
1307
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1308
+ AuthFormField,
1309
+ {
1310
+ id: "email",
1311
+ type: "email",
1312
+ label: emailLabel,
1313
+ placeholder: emailPlaceholder,
1314
+ value: email,
1315
+ onChange: (e) => setEmail(e.target.value),
1316
+ required: true,
1317
+ autoComplete: "email"
1318
+ }
1319
+ ),
1320
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1321
+ AuthPasswordField,
1322
+ {
1323
+ id: "password",
1324
+ label: passwordLabel,
1325
+ placeholder: passwordPlaceholder,
1326
+ value: password,
1327
+ onChange: (e) => setPassword(e.target.value),
1328
+ required: true,
1329
+ autoComplete: "current-password",
1330
+ emailAuthConfig: emailAuthConfig || {
1331
+ requireEmailVerification: false,
1332
+ passwordMinLength: 6,
1333
+ requireNumber: false,
1334
+ requireLowercase: false,
1335
+ requireUppercase: false,
1336
+ requireSpecialChar: false
1337
+ }
1338
+ }
1339
+ ),
1340
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1341
+ AuthSubmitButton,
1342
+ {
1343
+ isLoading: loading,
1344
+ disabled: loading || oauthLoading !== null,
1345
+ style: appearance.button,
1346
+ children: loading ? loadingButtonText : submitButtonText
1347
+ }
1348
+ )
1349
+ ]
1350
+ }
1351
+ ),
1175
1352
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AuthLink, { text: signUpText, linkText: signUpLinkText, href: signUpUrl }),
1176
1353
  oauthProviders.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
1177
1354
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AuthDivider, { text: dividerText }),
@@ -1220,7 +1397,9 @@ function SignUp({
1220
1397
  const [password, setPassword] = (0, import_react7.useState)("");
1221
1398
  const [error, setError] = (0, import_react7.useState)("");
1222
1399
  const [loading, setLoading] = (0, import_react7.useState)(false);
1223
- const [oauthLoading, setOauthLoading] = (0, import_react7.useState)(null);
1400
+ const [oauthLoading, setOauthLoading] = (0, import_react7.useState)(
1401
+ null
1402
+ );
1224
1403
  const insforge = (0, import_react7.useState)(() => (0, import_sdk5.createClient)({ baseUrl }))[0];
1225
1404
  async function handleCredentialsSubmit(e) {
1226
1405
  e.preventDefault();
@@ -1268,60 +1447,61 @@ function SignUp({
1268
1447
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(AuthContainer, { style: appearance.container, children: [
1269
1448
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(AuthHeader, { title, subtitle }),
1270
1449
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(AuthErrorBanner, { error }),
1271
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("form", { onSubmit: handleCredentialsSubmit, className: "insforge-form", children: [
1272
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1273
- AuthFormField,
1274
- {
1275
- id: "email",
1276
- type: "email",
1277
- label: emailLabel,
1278
- placeholder: emailPlaceholder,
1279
- value: email,
1280
- onChange: (e) => setEmail(e.target.value),
1281
- required: true,
1282
- autoComplete: "email"
1283
- }
1284
- ),
1285
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1286
- AuthPasswordField,
1287
- {
1288
- id: "password",
1289
- label: passwordLabel,
1290
- placeholder: passwordPlaceholder,
1291
- value: password,
1292
- onChange: (e) => setPassword(e.target.value),
1293
- required: true,
1294
- minLength: emailAuthConfig?.passwordMinLength ?? 8,
1295
- autoComplete: "new-password",
1296
- showStrengthIndicator: true,
1297
- emailAuthConfig: emailAuthConfig || {
1298
- requireEmailVerification: false,
1299
- passwordMinLength: 6,
1300
- requireNumber: false,
1301
- requireLowercase: false,
1302
- requireUppercase: false,
1303
- requireSpecialChar: false
1304
- }
1305
- }
1306
- ),
1307
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1308
- AuthSubmitButton,
1309
- {
1310
- isLoading: loading,
1311
- disabled: loading || oauthLoading !== null,
1312
- style: appearance.button,
1313
- children: loading ? loadingButtonText : submitButtonText
1314
- }
1315
- )
1316
- ] }),
1317
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1318
- AuthLink,
1450
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1451
+ "form",
1319
1452
  {
1320
- text: signInText,
1321
- linkText: signInLinkText,
1322
- href: signInUrl
1453
+ onSubmit: handleCredentialsSubmit,
1454
+ noValidate: true,
1455
+ className: "flex flex-col items-stretch justify-center gap-6",
1456
+ children: [
1457
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1458
+ AuthFormField,
1459
+ {
1460
+ id: "email",
1461
+ type: "email",
1462
+ label: emailLabel,
1463
+ placeholder: emailPlaceholder,
1464
+ value: email,
1465
+ onChange: (e) => setEmail(e.target.value),
1466
+ required: true,
1467
+ autoComplete: "email"
1468
+ }
1469
+ ),
1470
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1471
+ AuthPasswordField,
1472
+ {
1473
+ id: "password",
1474
+ label: passwordLabel,
1475
+ placeholder: passwordPlaceholder,
1476
+ value: password,
1477
+ onChange: (e) => setPassword(e.target.value),
1478
+ required: true,
1479
+ minLength: emailAuthConfig?.passwordMinLength ?? 8,
1480
+ autoComplete: "new-password",
1481
+ showStrengthIndicator: true,
1482
+ emailAuthConfig: emailAuthConfig || {
1483
+ requireEmailVerification: false,
1484
+ passwordMinLength: 6,
1485
+ requireNumber: false,
1486
+ requireLowercase: false,
1487
+ requireUppercase: false,
1488
+ requireSpecialChar: false
1489
+ }
1490
+ }
1491
+ ),
1492
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1493
+ AuthSubmitButton,
1494
+ {
1495
+ isLoading: loading,
1496
+ disabled: loading || oauthLoading !== null,
1497
+ style: appearance.button,
1498
+ children: loading ? loadingButtonText : submitButtonText
1499
+ }
1500
+ )
1501
+ ]
1323
1502
  }
1324
1503
  ),
1504
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(AuthLink, { text: signInText, linkText: signInLinkText, href: signInUrl }),
1325
1505
  oauthProviders.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1326
1506
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(AuthDivider, { text: dividerText }),
1327
1507
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
@@ -1344,7 +1524,8 @@ var import_jsx_runtime18 = require("react/jsx-runtime");
1344
1524
  function UserButton({
1345
1525
  afterSignOutUrl = "/",
1346
1526
  mode = "detailed",
1347
- appearance = {}
1527
+ appearance = {},
1528
+ className
1348
1529
  }) {
1349
1530
  const { user, signOut } = useInsforge();
1350
1531
  const [isOpen, setIsOpen] = (0, import_react8.useState)(false);
@@ -1369,29 +1550,69 @@ function UserButton({
1369
1550
  }
1370
1551
  if (!user) return null;
1371
1552
  const initials = user.nickname ? user.nickname.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
1372
- const avatarUrl = user.avatar_url;
1373
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "insforge-user-button-container", ref: dropdownRef, children: [
1553
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: cn("relative inline-block", className), ref: dropdownRef, children: [
1374
1554
  /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1375
1555
  "button",
1376
1556
  {
1377
- className: `insforge-user-button ${mode === "detailed" ? "insforge-user-button-detailed" : ""}`,
1557
+ className: cn(
1558
+ // Base styles
1559
+ "p-1 bg-transparent border-0 rounded-full cursor-pointer transition-all duration-200",
1560
+ "flex items-center justify-center gap-2",
1561
+ "hover:bg-black/5",
1562
+ // Detailed mode styles
1563
+ mode === "detailed" && "rounded-lg p-2",
1564
+ // User override
1565
+ appearance.buttonClassName
1566
+ ),
1378
1567
  onClick: () => setIsOpen(!isOpen),
1379
1568
  style: appearance.button,
1380
1569
  "aria-expanded": isOpen,
1381
1570
  "aria-haspopup": "true",
1382
1571
  children: [
1383
- avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("img", { src: avatarUrl, alt: user.email, className: "insforge-user-avatar" }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "insforge-user-avatar-placeholder", children: initials }),
1384
- mode === "detailed" && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "insforge-user-button-info", children: [
1385
- user.nickname && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "insforge-user-button-name", children: user.nickname }),
1386
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "insforge-user-button-email", children: user.email })
1572
+ user.avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1573
+ "img",
1574
+ {
1575
+ src: user.avatarUrl,
1576
+ alt: user.email,
1577
+ className: "w-10 h-10 rounded-full object-cover"
1578
+ }
1579
+ ) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex items-center justify-center w-10 h-10 bg-blue-500 text-white font-semibold text-sm rounded-full", children: initials }),
1580
+ mode === "detailed" && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col items-start gap-0.5", children: [
1581
+ user.nickname && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: cn(
1582
+ "text-sm font-semibold text-gray-900 leading-5 text-left",
1583
+ appearance.nameClassName
1584
+ ), children: user.nickname }),
1585
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: cn(
1586
+ "text-xs text-gray-500 leading-4 text-left",
1587
+ appearance.emailClassName
1588
+ ), children: user.email })
1387
1589
  ] })
1388
1590
  ]
1389
1591
  }
1390
1592
  ),
1391
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "insforge-user-dropdown", style: appearance.dropdown, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("button", { onClick: handleSignOut, className: "insforge-sign-out-button", children: [
1392
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react6.LogOut, { className: "w-5 h-5" }),
1393
- "Sign out"
1394
- ] }) })
1593
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1594
+ "div",
1595
+ {
1596
+ className: cn(
1597
+ "absolute top-full right-0 mt-2 min-w-40",
1598
+ "bg-white border border-gray-200 rounded-lg",
1599
+ "shadow-lg z-50 overflow-hidden p-1",
1600
+ appearance.dropdownClassName
1601
+ ),
1602
+ style: appearance.dropdown,
1603
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1604
+ "button",
1605
+ {
1606
+ onClick: handleSignOut,
1607
+ 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",
1608
+ children: [
1609
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react6.LogOut, { className: "w-5 h-5" }),
1610
+ "Sign out"
1611
+ ]
1612
+ }
1613
+ )
1614
+ }
1615
+ )
1395
1616
  ] });
1396
1617
  }
1397
1618
 
@@ -1468,6 +1689,7 @@ function Protect({
1468
1689
  SignedIn,
1469
1690
  SignedOut,
1470
1691
  UserButton,
1692
+ cn,
1471
1693
  getProviderConfig,
1472
1694
  getProviderName,
1473
1695
  isProviderSupported,