@luminaryworks/auth-react 0.6.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- (function(){if(typeof document==="undefined")return;var id="lw-auth-react-headless-login";if(document.getElementById(id))return;var s=document.createElement("style");s.id=id;s.textContent="/* src/HeadlessLoginPanel.module.scss */\n.HeadlessLoginPanel_module_panel {\n --lw-auth-theme: #1677ff;\n --lw-auth-theme-deep: color-mix(in srgb, var(--lw-auth-theme) 72%, #000);\n width: min(100%, 400px);\n padding: 28px 28px 22px;\n border-radius: 16px;\n background: rgba(255, 255, 255, 0.96);\n color: #14212b;\n box-shadow: 0 24px 64px rgba(15, 23, 42, 0.28);\n font-family:\n \"Segoe UI\",\n \"PingFang SC\",\n \"Noto Sans SC\",\n sans-serif;\n}\n.HeadlessLoginPanel_module_brand {\n display: flex;\n gap: 14px;\n align-items: center;\n margin-bottom: 12px;\n}\n.HeadlessLoginPanel_module_logo {\n border-radius: 12px;\n display: block;\n}\n.HeadlessLoginPanel_module_product {\n margin: 0;\n font-size: 13px;\n font-weight: 650;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--lw-auth-theme);\n}\n.HeadlessLoginPanel_module_title {\n margin: 2px 0 0;\n font-size: 22px;\n font-weight: 700;\n line-height: 1.25;\n}\n.HeadlessLoginPanel_module_subtitle {\n margin: 0 0 18px;\n font-size: 14px;\n line-height: 1.5;\n color: #4b5c68;\n}\n.HeadlessLoginPanel_module_form {\n display: grid;\n gap: 10px;\n}\n.HeadlessLoginPanel_module_channelTabs {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 6px;\n margin-bottom: 2px;\n}\n.HeadlessLoginPanel_module_channelTab {\n border: 1px solid #c9d5de;\n border-radius: 10px;\n padding: 8px 10px;\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n color: #4b5c68;\n background: #f7fafc;\n}\n.HeadlessLoginPanel_module_channelTab:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_channelTabActive {\n color: var(--lw-auth-theme-deep);\n border-color: var(--lw-auth-theme);\n background: color-mix(in srgb, var(--lw-auth-theme) 10%, #fff);\n}\n.HeadlessLoginPanel_module_codeRow {\n display: grid;\n grid-template-columns: 1fr auto;\n gap: 8px;\n align-items: stretch;\n}\n.HeadlessLoginPanel_module_codeInput {\n min-width: 0;\n}\n.HeadlessLoginPanel_module_secondaryBtn {\n border: 1px solid #b7c9d4;\n border-radius: 10px;\n padding: 0 12px;\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n color: #14212b;\n background: #fff;\n white-space: nowrap;\n}\n.HeadlessLoginPanel_module_secondaryBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_socialStack {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 10px;\n font-size: 12px;\n}\n.HeadlessLoginPanel_module_input {\n width: 100%;\n box-sizing: border-box;\n border: 1px solid #c9d5de;\n border-radius: 10px;\n padding: 10px 12px;\n font-size: 14px;\n outline: none;\n background: #f7fafc;\n}\n.HeadlessLoginPanel_module_input:focus {\n border-color: var(--lw-auth-theme);\n}\n.HeadlessLoginPanel_module_input:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_passwordField {\n position: relative;\n display: flex;\n align-items: center;\n}\n.HeadlessLoginPanel_module_passwordInput {\n padding-right: 42px;\n}\n.HeadlessLoginPanel_module_passwordToggle {\n position: absolute;\n right: 4px;\n top: 50%;\n transform: translateY(-50%);\n z-index: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: 4px;\n padding: 0;\n color: #5a6b76;\n background: transparent;\n cursor: pointer;\n}\n.HeadlessLoginPanel_module_passwordToggle:hover:not(:disabled) {\n color: var(--lw-auth-theme);\n background: color-mix(in srgb, var(--lw-auth-theme) 12%, transparent);\n}\n.HeadlessLoginPanel_module_passwordToggle:focus-visible {\n outline: 2px solid var(--lw-auth-theme);\n outline-offset: 1px;\n}\n.HeadlessLoginPanel_module_passwordToggle:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_primaryBtn {\n border: none;\n border-radius: 10px;\n padding: 11px 14px;\n font-size: 14px;\n font-weight: 650;\n cursor: pointer;\n color: #fff;\n background:\n linear-gradient(\n 135deg,\n var(--lw-auth-theme) 0%,\n var(--lw-auth-theme-deep) 100%);\n}\n.HeadlessLoginPanel_module_primaryBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_socialBtn {\n width: 100%;\n min-width: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n border: 1px solid #b7c9d4;\n border-radius: 10px;\n padding: 11px 10px;\n font-size: 14px;\n font-weight: 650;\n cursor: pointer;\n color: #14212b;\n background: #fff;\n}\n.HeadlessLoginPanel_module_socialBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_socialLogo {\n flex-shrink: 0;\n display: block;\n}\n.HeadlessLoginPanel_module_logoFallback {\n width: 18px;\n height: 18px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--lw-auth-theme) 14%, #fff);\n color: var(--lw-auth-theme-deep);\n font-size: 11px;\n font-weight: 700;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n.HeadlessLoginPanel_module_cancelBtn {\n margin-top: 10px;\n width: 100%;\n border: none;\n background: transparent;\n color: #5a6b76;\n font-size: 13px;\n cursor: pointer;\n padding: 8px;\n}\n.HeadlessLoginPanel_module_cancelBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_divider {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 14px 0;\n color: #90a0ab;\n}\n.HeadlessLoginPanel_module_dividerLine {\n flex: 1;\n height: 1px;\n background: #d5e0e7;\n}\n.HeadlessLoginPanel_module_dividerText {\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n}\n.HeadlessLoginPanel_module_hint {\n margin: 10px 0 0;\n font-size: 12px;\n color: #6b7c87;\n line-height: 1.45;\n}\n.HeadlessLoginPanel_module_domainsHint {\n margin: -2px 0 0;\n font-size: 12px;\n line-height: 1.45;\n color: #4b5c68;\n word-break: break-word;\n}\n.HeadlessLoginPanel_module_switchMode {\n margin: 12px 0 0;\n text-align: center;\n}\n.HeadlessLoginPanel_module_switchModeBtn {\n border: none;\n background: transparent;\n color: var(--lw-auth-theme);\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n padding: 4px 8px;\n text-decoration: underline;\n text-underline-offset: 3px;\n}\n.HeadlessLoginPanel_module_switchModeBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_error {\n margin: 12px 0 0;\n font-size: 13px;\n color: #b42318;\n line-height: 1.4;\n}\n.HeadlessLoginPanel_module_footer {\n margin-top: 18px;\n padding-top: 12px;\n border-top: 1px solid #e4ebf0;\n font-size: 12px;\n color: #6b7c87;\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n/* src/LoginLanguageSwitcher.module.scss */\n.LoginLanguageSwitcher_module_switch {\n position: relative;\n display: inline-flex;\n}\n.LoginLanguageSwitcher_module_trigger {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 32px;\n padding: 0 10px 0 8px;\n border: 1px solid rgba(15, 23, 42, 0.12);\n border-radius: 999px;\n background: rgba(255, 255, 255, 0.86);\n color: #243044;\n font: inherit;\n font-size: 13px;\n line-height: 1;\n cursor: pointer;\n backdrop-filter: blur(8px);\n}\n.LoginLanguageSwitcher_module_trigger:hover,\n.LoginLanguageSwitcher_module_trigger[aria-expanded=true] {\n border-color: var(--lw-login-accent, #1677ff);\n color: #0f172a;\n}\n.LoginLanguageSwitcher_module_icon {\n width: 14px;\n height: 14px;\n display: block;\n}\n.LoginLanguageSwitcher_module_caret {\n width: 10px;\n height: 10px;\n opacity: 0.65;\n}\n.LoginLanguageSwitcher_module_menu {\n position: absolute;\n top: calc(100% + 6px);\n right: 0;\n z-index: 20;\n min-width: 168px;\n margin: 0;\n padding: 6px;\n list-style: none;\n border-radius: 12px;\n background: #fff;\n box-shadow: 0 12px 40px rgba(15, 23, 42, 0.16);\n}\n.LoginLanguageSwitcher_module_item {\n display: block;\n width: 100%;\n border: 0;\n border-radius: 8px;\n padding: 8px 10px;\n background: transparent;\n color: #1f2937;\n font: inherit;\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n}\n.LoginLanguageSwitcher_module_item:hover {\n background: #f3f6fb;\n}\n.LoginLanguageSwitcher_module_itemActive {\n background: color-mix(in srgb, var(--lw-login-accent, #1677ff) 14%, #fff);\n color: var(--lw-login-accent, #1677ff);\n font-weight: 650;\n}\n.LoginLanguageSwitcher_module_onDark {\n border-color: rgba(255, 255, 255, 0.22);\n background: rgba(15, 23, 42, 0.28);\n color: rgba(255, 255, 255, 0.92);\n}\n.LoginLanguageSwitcher_module_onDark:hover,\n.LoginLanguageSwitcher_module_onDark[aria-expanded=true] {\n border-color: rgba(255, 255, 255, 0.55);\n color: #fff;\n}\n\n/* src/LoginCanvas.module.scss */\n.LoginCanvas_module_canvas {\n --lw-login-accent: #1677ff;\n position: relative;\n min-height: 100dvh;\n display: grid;\n place-items: center;\n padding: 56px 20px 24px;\n overflow: hidden;\n background:\n radial-gradient(\n 900px 480px at 8% -8%,\n color-mix(in srgb, var(--lw-login-accent) 28%, transparent),\n transparent 58%),\n radial-gradient(\n 720px 420px at 100% 12%,\n color-mix(in srgb, var(--lw-login-accent) 16%, transparent),\n transparent 52%),\n linear-gradient(\n 165deg,\n var(--lw-login-bg-a, #f4f7fb) 0%,\n var(--lw-login-bg-b, #e7eef6) 100%);\n color: var(--lw-login-ink, #122033);\n}\n.LoginCanvas_module_canvas[data-tone=console] {\n --lw-login-accent: #7eb6ff;\n --lw-login-bg-a: #0e1726;\n --lw-login-bg-b: #1a2740;\n --lw-login-ink: #e8eef8;\n --lw-login-grid: rgba(255, 255, 255, 0.05);\n}\n.LoginCanvas_module_canvas[data-tone=vista] {\n --lw-login-accent: #1677ff;\n --lw-login-bg-a: #f4f7fb;\n --lw-login-bg-b: #dde7f0;\n --lw-login-grid: rgba(11, 18, 32, 0.045);\n}\n.LoginCanvas_module_canvas[data-tone=data] {\n --lw-login-accent: #5aa2ff;\n --lw-login-bg-a: #070b14;\n --lw-login-bg-b: #12203a;\n --lw-login-ink: #e8eefc;\n --lw-login-grid: rgba(255, 255, 255, 0.045);\n}\n.LoginCanvas_module_canvas[data-tone=edu] {\n --lw-login-accent: #f59e0b;\n --lw-login-bg-a: #fff7ed;\n --lw-login-bg-b: #e0e7ff;\n --lw-login-grid: rgba(67, 56, 202, 0.06);\n}\n.LoginCanvas_module_grid {\n position: absolute;\n inset: 0;\n pointer-events: none;\n background-image:\n linear-gradient(var(--lw-login-grid, rgba(15, 23, 42, 0.04)) 1px, transparent 1px),\n linear-gradient(\n 90deg,\n var(--lw-login-grid, rgba(15, 23, 42, 0.04)) 1px,\n transparent 1px);\n background-size: 48px 48px;\n mask-image:\n radial-gradient(\n ellipse at center,\n #000 18%,\n transparent 74%);\n}\n.LoginCanvas_module_lang {\n position: fixed;\n top: 14px;\n right: 16px;\n z-index: 5;\n}\n.LoginCanvas_module_decor {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 0;\n}\n.LoginCanvas_module_slot {\n position: relative;\n z-index: 1;\n width: min(440px, 100%);\n}\n.LoginCanvas_module_slotFill {\n width: min(1120px, 100%);\n}\n/*# sourceMappingURL=index.css.map */";document.head.appendChild(s);})();
1
+ (function(){if(typeof document==="undefined")return;var id="lw-auth-react-headless-login";if(document.getElementById(id))return;var s=document.createElement("style");s.id=id;s.textContent="/* src/HeadlessLoginPanel.module.scss */\n.HeadlessLoginPanel_module_panel {\n --lw-auth-theme: #1677ff;\n --lw-auth-theme-deep: color-mix(in srgb, var(--lw-auth-theme) 72%, #000);\n box-sizing: border-box;\n width: min(100%, 400px);\n max-width: 400px;\n padding: 28px 28px 22px;\n border-radius: 16px;\n background: rgba(255, 255, 255, 0.96);\n color: #14212b;\n box-shadow: 0 24px 64px rgba(15, 23, 42, 0.28);\n font-family:\n \"Segoe UI\",\n \"PingFang SC\",\n \"Noto Sans SC\",\n sans-serif;\n}\n.HeadlessLoginPanel_module_brand {\n display: flex;\n gap: 14px;\n align-items: center;\n margin-bottom: 12px;\n}\n.HeadlessLoginPanel_module_logo {\n border-radius: 12px;\n display: block;\n}\n.HeadlessLoginPanel_module_product {\n margin: 0;\n font-size: 13px;\n font-weight: 650;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--lw-auth-theme);\n}\n.HeadlessLoginPanel_module_title {\n margin: 2px 0 0;\n font-size: 22px;\n font-weight: 700;\n line-height: 1.25;\n}\n.HeadlessLoginPanel_module_subtitle {\n margin: 0 0 18px;\n font-size: 14px;\n line-height: 1.5;\n color: #4b5c68;\n}\n.HeadlessLoginPanel_module_form {\n display: grid;\n gap: 10px;\n}\n.HeadlessLoginPanel_module_channelTabs {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 6px;\n margin-bottom: 2px;\n}\n.HeadlessLoginPanel_module_channelTab {\n border: 1px solid #c9d5de;\n border-radius: 10px;\n padding: 8px 10px;\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n color: #4b5c68;\n background: #f7fafc;\n}\n.HeadlessLoginPanel_module_channelTab:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_channelTabActive {\n color: var(--lw-auth-theme-deep);\n border-color: var(--lw-auth-theme);\n background: color-mix(in srgb, var(--lw-auth-theme) 10%, #fff);\n}\n.HeadlessLoginPanel_module_codeRow {\n display: grid;\n grid-template-columns: 1fr auto;\n gap: 8px;\n align-items: stretch;\n}\n.HeadlessLoginPanel_module_codeInput {\n min-width: 0;\n}\n.HeadlessLoginPanel_module_secondaryBtn {\n border: 1px solid #b7c9d4;\n border-radius: 10px;\n padding: 0 12px;\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n color: #14212b;\n background: #fff;\n white-space: nowrap;\n}\n.HeadlessLoginPanel_module_secondaryBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_socialStack {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 10px;\n font-size: 12px;\n}\n.HeadlessLoginPanel_module_input {\n width: 100%;\n box-sizing: border-box;\n border: 1px solid #c9d5de;\n border-radius: 10px;\n padding: 10px 12px;\n font-size: 14px;\n outline: none;\n background: #f7fafc;\n}\n.HeadlessLoginPanel_module_input:focus {\n border-color: var(--lw-auth-theme);\n}\n.HeadlessLoginPanel_module_input:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_passwordField {\n position: relative;\n display: flex;\n align-items: center;\n}\n.HeadlessLoginPanel_module_passwordInput {\n padding-right: 42px;\n}\n.HeadlessLoginPanel_module_passwordToggle {\n position: absolute;\n right: 4px;\n top: 50%;\n transform: translateY(-50%);\n z-index: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: 4px;\n padding: 0;\n color: #5a6b76;\n background: transparent;\n cursor: pointer;\n}\n.HeadlessLoginPanel_module_passwordToggle:hover:not(:disabled) {\n color: var(--lw-auth-theme);\n background: color-mix(in srgb, var(--lw-auth-theme) 12%, transparent);\n}\n.HeadlessLoginPanel_module_passwordToggle:focus-visible {\n outline: 2px solid var(--lw-auth-theme);\n outline-offset: 1px;\n}\n.HeadlessLoginPanel_module_passwordToggle:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_primaryBtn {\n border: none;\n border-radius: 10px;\n padding: 11px 14px;\n font-size: 14px;\n font-weight: 650;\n cursor: pointer;\n color: #fff;\n background:\n linear-gradient(\n 135deg,\n var(--lw-auth-theme) 0%,\n var(--lw-auth-theme-deep) 100%);\n}\n.HeadlessLoginPanel_module_primaryBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_socialBtn {\n width: 100%;\n min-width: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n border: 1px solid #b7c9d4;\n border-radius: 10px;\n padding: 11px 10px;\n font-size: 14px;\n font-weight: 650;\n cursor: pointer;\n color: #14212b;\n background: #fff;\n}\n.HeadlessLoginPanel_module_socialBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_socialLogo {\n flex-shrink: 0;\n display: block;\n}\n.HeadlessLoginPanel_module_logoFallback {\n width: 18px;\n height: 18px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--lw-auth-theme) 14%, #fff);\n color: var(--lw-auth-theme-deep);\n font-size: 11px;\n font-weight: 700;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n.HeadlessLoginPanel_module_cancelBtn {\n margin-top: 10px;\n width: 100%;\n border: none;\n background: transparent;\n color: #5a6b76;\n font-size: 13px;\n cursor: pointer;\n padding: 8px;\n}\n.HeadlessLoginPanel_module_cancelBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_divider {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 14px 0;\n color: #90a0ab;\n}\n.HeadlessLoginPanel_module_dividerLine {\n flex: 1;\n height: 1px;\n background: #d5e0e7;\n}\n.HeadlessLoginPanel_module_dividerText {\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n}\n.HeadlessLoginPanel_module_hint {\n margin: 10px 0 0;\n font-size: 12px;\n color: #6b7c87;\n line-height: 1.45;\n}\n.HeadlessLoginPanel_module_domainsHint {\n margin: -2px 0 0;\n font-size: 12px;\n line-height: 1.45;\n color: #4b5c68;\n word-break: break-word;\n}\n.HeadlessLoginPanel_module_switchMode {\n margin: 12px 0 0;\n text-align: center;\n}\n.HeadlessLoginPanel_module_switchModeBtn {\n border: none;\n background: transparent;\n color: var(--lw-auth-theme);\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n padding: 4px 8px;\n text-decoration: underline;\n text-underline-offset: 3px;\n}\n.HeadlessLoginPanel_module_switchModeBtn:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n}\n.HeadlessLoginPanel_module_error {\n margin: 12px 0 0;\n font-size: 13px;\n color: #b42318;\n line-height: 1.4;\n}\n.HeadlessLoginPanel_module_consent {\n margin: 12px 0 0;\n font-size: 13px;\n line-height: 1.45;\n color: #14212b;\n}\n.HeadlessLoginPanel_module_consentInvalid {\n margin: 12px -8px 0;\n padding: 8px;\n border: 1px solid #b42318;\n border-radius: 10px;\n background: rgba(180, 35, 24, 0.06);\n}\n.HeadlessLoginPanel_module_consentError {\n margin: 8px 0 0;\n font-size: 13px;\n font-weight: 650;\n line-height: 1.4;\n color: #b42318;\n}\n.HeadlessLoginPanel_module_consentLinks {\n margin: 0;\n}\n.HeadlessLoginPanel_module_consentLinks a {\n color: var(--lw-auth-theme);\n}\n.HeadlessLoginPanel_module_footer {\n margin-top: 18px;\n padding-top: 12px;\n border-top: 1px solid #e4ebf0;\n font-size: 12px;\n color: #6b7c87;\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n@media (max-width: 420px) {\n .HeadlessLoginPanel_module_panel {\n padding: 22px 16px 18px;\n }\n}\n\n/* src/LoginLanguageSwitcher.module.scss */\n.LoginLanguageSwitcher_module_switch {\n position: relative;\n display: inline-flex;\n}\n.LoginLanguageSwitcher_module_trigger {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 32px;\n padding: 0 10px 0 8px;\n border: 1px solid rgba(15, 23, 42, 0.12);\n border-radius: 999px;\n background: rgba(255, 255, 255, 0.86);\n color: #243044;\n font: inherit;\n font-size: 13px;\n line-height: 1;\n cursor: pointer;\n backdrop-filter: blur(8px);\n}\n.LoginLanguageSwitcher_module_trigger:hover,\n.LoginLanguageSwitcher_module_trigger[aria-expanded=true] {\n border-color: var(--lw-login-accent, #1677ff);\n color: #0f172a;\n}\n.LoginLanguageSwitcher_module_icon {\n width: 14px;\n height: 14px;\n display: block;\n}\n.LoginLanguageSwitcher_module_caret {\n width: 10px;\n height: 10px;\n opacity: 0.65;\n}\n.LoginLanguageSwitcher_module_menu {\n position: absolute;\n top: calc(100% + 6px);\n right: 0;\n z-index: 20;\n min-width: 168px;\n margin: 0;\n padding: 6px;\n list-style: none;\n border-radius: 12px;\n background: #fff;\n box-shadow: 0 12px 40px rgba(15, 23, 42, 0.16);\n}\n.LoginLanguageSwitcher_module_item {\n display: block;\n width: 100%;\n border: 0;\n border-radius: 8px;\n padding: 8px 10px;\n background: transparent;\n color: #1f2937;\n font: inherit;\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n}\n.LoginLanguageSwitcher_module_item:hover {\n background: #f3f6fb;\n}\n.LoginLanguageSwitcher_module_itemActive {\n background: color-mix(in srgb, var(--lw-login-accent, #1677ff) 14%, #fff);\n color: var(--lw-login-accent, #1677ff);\n font-weight: 650;\n}\n.LoginLanguageSwitcher_module_onDark {\n border-color: rgba(255, 255, 255, 0.22);\n background: rgba(15, 23, 42, 0.28);\n color: rgba(255, 255, 255, 0.92);\n}\n.LoginLanguageSwitcher_module_onDark:hover,\n.LoginLanguageSwitcher_module_onDark[aria-expanded=true] {\n border-color: rgba(255, 255, 255, 0.55);\n color: #fff;\n}\n\n/* src/LoginCanvas.module.scss */\n.LoginCanvas_module_canvas {\n --lw-login-accent: #1677ff;\n position: relative;\n min-height: 100dvh;\n display: grid;\n place-items: center;\n padding: 56px 20px 24px;\n overflow: hidden;\n background:\n radial-gradient(\n 900px 480px at 8% -8%,\n color-mix(in srgb, var(--lw-login-accent) 28%, transparent),\n transparent 58%),\n radial-gradient(\n 720px 420px at 100% 12%,\n color-mix(in srgb, var(--lw-login-accent) 16%, transparent),\n transparent 52%),\n linear-gradient(\n 165deg,\n var(--lw-login-bg-a, #f4f7fb) 0%,\n var(--lw-login-bg-b, #e7eef6) 100%);\n color: var(--lw-login-ink, #122033);\n}\n.LoginCanvas_module_canvas[data-tone=console] {\n --lw-login-accent: #7eb6ff;\n --lw-login-bg-a: #0e1726;\n --lw-login-bg-b: #1a2740;\n --lw-login-ink: #e8eef8;\n --lw-login-grid: rgba(255, 255, 255, 0.05);\n}\n.LoginCanvas_module_canvas[data-tone=vista] {\n --lw-login-accent: #1677ff;\n --lw-login-bg-a: #f4f7fb;\n --lw-login-bg-b: #dde7f0;\n --lw-login-grid: rgba(11, 18, 32, 0.045);\n}\n.LoginCanvas_module_canvas[data-tone=data] {\n --lw-login-accent: #7c3aed;\n --lw-login-bg-a: #0a0f1e;\n --lw-login-bg-b: #0a0f1e;\n --lw-login-ink: #e8eefc;\n --lw-login-grid: rgba(255, 255, 255, 0.045);\n}\n.LoginCanvas_module_canvas[data-tone=edu] {\n --lw-login-accent: #7ec8ff;\n --lw-login-bg-a: #0a348c;\n --lw-login-bg-b: #1d7aef;\n --lw-login-ink: #f4f8ff;\n --lw-login-grid: rgba(255, 255, 255, 0.07);\n}\n.LoginCanvas_module_grid {\n position: absolute;\n inset: 0;\n pointer-events: none;\n background-image:\n linear-gradient(var(--lw-login-grid, rgba(15, 23, 42, 0.04)) 1px, transparent 1px),\n linear-gradient(\n 90deg,\n var(--lw-login-grid, rgba(15, 23, 42, 0.04)) 1px,\n transparent 1px);\n background-size: 48px 48px;\n mask-image:\n radial-gradient(\n ellipse at center,\n #000 18%,\n transparent 74%);\n}\n.LoginCanvas_module_lang {\n position: fixed;\n top: 14px;\n right: 16px;\n z-index: 5;\n}\n.LoginCanvas_module_decor {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 0;\n}\n.LoginCanvas_module_slot {\n position: relative;\n z-index: 1;\n width: min(440px, 100%);\n}\n.LoginCanvas_module_slotFill {\n width: min(1120px, 100%);\n}\n@media (max-width: 720px) {\n .LoginCanvas_module_canvas {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-start;\n overflow-x: hidden;\n overflow-y: auto;\n padding: 72px 16px 28px;\n }\n .LoginCanvas_module_lang {\n top: 12px;\n right: 12px;\n }\n}\n@media (max-width: 420px) {\n .LoginCanvas_module_canvas {\n padding: 64px 12px 20px;\n }\n}\n/*# sourceMappingURL=index.css.map */";document.head.appendChild(s);})();
2
2
  'use strict';
3
3
 
4
4
  var oidcClientTs = require('oidc-client-ts');
@@ -250,6 +250,20 @@ function isLogtoRegisterUsername(value) {
250
250
  function experienceUrl(apiBase, path) {
251
251
  return `${apiBase.replace(/\/$/, "")}/api/experience${path}`;
252
252
  }
253
+ var ExperienceApiError = class extends Error {
254
+ status;
255
+ code;
256
+ constructor(status, code, message) {
257
+ super(message);
258
+ this.name = "ExperienceApiError";
259
+ this.status = status;
260
+ this.code = code;
261
+ }
262
+ };
263
+ var MFA_REQUIRED_CODE = "session.mfa.require_mfa_verification";
264
+ function isMfaVerificationRequired(error) {
265
+ return error instanceof ExperienceApiError && error.code === MFA_REQUIRED_CODE;
266
+ }
253
267
  async function experienceFetch(apiBase, path, init) {
254
268
  const res = await fetch(experienceUrl(apiBase, path), {
255
269
  credentials: "include",
@@ -270,8 +284,10 @@ async function experienceFetch(apiBase, path, init) {
270
284
  }
271
285
  }
272
286
  if (!res.ok) {
273
- const msg = data && typeof data === "object" && data !== null && "message" in data ? String(data.message) : `Experience API ${res.status}`;
274
- throw new Error(msg);
287
+ const body = data && typeof data === "object" && data !== null ? data : null;
288
+ const code = typeof body?.code === "string" ? body.code : "";
289
+ const msg = typeof body?.message === "string" ? body.message : `Experience API ${res.status}`;
290
+ throw new ExperienceApiError(res.status, code, msg);
275
291
  }
276
292
  return data;
277
293
  }
@@ -365,21 +381,44 @@ var LogtoExperienceAdapter = class {
365
381
  method: "POST",
366
382
  body: JSON.stringify({ verificationId })
367
383
  });
368
- const submitted = await experienceFetch(
369
- apiBase,
370
- "/submit",
371
- {
372
- method: "POST",
373
- body: JSON.stringify({})
384
+ try {
385
+ const submitted = await experienceFetch(
386
+ apiBase,
387
+ "/submit",
388
+ {
389
+ method: "POST",
390
+ body: JSON.stringify({})
391
+ }
392
+ );
393
+ return { redirectTo: submitted?.redirectTo, raw: submitted };
394
+ } catch (error) {
395
+ if (isMfaVerificationRequired(error)) {
396
+ return { mfaRequired: true };
374
397
  }
375
- );
376
- return { redirectTo: submitted?.redirectTo, raw: submitted };
398
+ throw error;
399
+ }
377
400
  } catch (error) {
378
401
  lastError = error instanceof Error ? error : new Error(String(error));
379
402
  }
380
403
  }
381
404
  throw lastError ?? new Error("Experience password sign-in failed");
382
405
  }
406
+ /** Verify the user's existing authenticator code, then submit the interaction. */
407
+ async experienceVerifyTotp(input) {
408
+ const code = input.code.trim();
409
+ if (!code) {
410
+ throw new Error("Authenticator code is required");
411
+ }
412
+ await experienceFetch(input.apiBase, "/verification/totp/verify", {
413
+ method: "POST",
414
+ body: JSON.stringify({ code })
415
+ });
416
+ const submitted = await experienceFetch(input.apiBase, "/submit", {
417
+ method: "POST",
418
+ body: JSON.stringify({})
419
+ });
420
+ return { redirectTo: submitted?.redirectTo, raw: submitted };
421
+ }
383
422
  /**
384
423
  * Register with username + password via NewPasswordIdentity.
385
424
  * Email/phone self-register requires verification codes — use social or invite instead.
@@ -922,10 +961,16 @@ function useLuminaryAuth() {
922
961
 
923
962
  // src/login-labels.ts
924
963
  var DEFAULT_LOGIN_LOCALES = [
925
- { code: "en", label: "English", short: "EN" },
926
964
  { code: "zh-CN", label: "\u7B80\u4F53\u4E2D\u6587", short: "\u7B80" },
927
965
  { code: "zh-TW", label: "\u7E41\u9AD4\u4E2D\u6587", short: "\u7E41" },
928
- { code: "es", label: "Espa\xF1ol", short: "ES" }
966
+ { code: "ja", label: "\u65E5\u672C\u8A9E", short: "JA" },
967
+ { code: "ko", label: "\uD55C\uAD6D\uC5B4", short: "KO" },
968
+ { code: "en", label: "English", short: "EN" },
969
+ { code: "pt", label: "Portugu\xEAs", short: "PT" },
970
+ { code: "nl", label: "Nederlands", short: "NL" },
971
+ { code: "it", label: "Italiano", short: "IT" },
972
+ { code: "es", label: "Espa\xF1ol", short: "ES" },
973
+ { code: "fr", label: "Fran\xE7ais", short: "FR" }
929
974
  ];
930
975
  var ZH_CN = {
931
976
  title: "\u767B\u5F55",
@@ -960,7 +1005,13 @@ var ZH_CN = {
960
1005
  allowedDomainsPrefix: "\u5141\u8BB8\u7684\u90AE\u7BB1\u57DF\u540D",
961
1006
  allowedDomainsOpen: "\u5927\u591A\u6570\u90AE\u7BB1\u90FD\u53EF\u4EE5\u6CE8\u518C\u3002",
962
1007
  allowedDomainsBlocklist: "\u5927\u591A\u6570\u90AE\u7BB1\u53EF\u7528\u3002\u4E34\u65F6\u90AE\u7BB1\u4F1A\u88AB\u62D2\u7EDD\u3002",
963
- waitingExternalBrowser: "\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u5B8C\u6210\u767B\u5F55\uFF0C\u7136\u540E\u56DE\u5230\u672C\u5E94\u7528\u3002"
1008
+ waitingExternalBrowser: "\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u5B8C\u6210\u767B\u5F55\uFF0C\u7136\u540E\u56DE\u5230\u672C\u5E94\u7528\u3002",
1009
+ consentRequired: "\u8BF7\u5148\u540C\u610F\u7528\u6237\u534F\u8BAE\u540E\u518D\u7EE7\u7EED\u3002",
1010
+ mfaTitle: "\u8EAB\u4EFD\u9A8C\u8BC1\u7801",
1011
+ mfaSubtitle: "\u8F93\u5165\u9A8C\u8BC1\u5668\u5E94\u7528\u4E2D\u7684 6 \u4F4D\u6570\u5B57\u3002",
1012
+ mfaCodePlaceholder: "6 \u4F4D\u9A8C\u8BC1\u7801",
1013
+ mfaSubmit: "\u9A8C\u8BC1\u5E76\u7EE7\u7EED",
1014
+ mfaBack: "\u8FD4\u56DE"
964
1015
  };
965
1016
  var ZH_TW = {
966
1017
  title: "\u767B\u5165",
@@ -995,7 +1046,13 @@ var ZH_TW = {
995
1046
  allowedDomainsPrefix: "\u5141\u8A31\u7684\u96FB\u5B50\u90F5\u4EF6\u7DB2\u57DF",
996
1047
  allowedDomainsOpen: "\u5927\u591A\u6578\u96FB\u5B50\u90F5\u4EF6\u90FD\u53EF\u4EE5\u8A3B\u518A\u3002",
997
1048
  allowedDomainsBlocklist: "\u5927\u591A\u6578\u96FB\u5B50\u90F5\u4EF6\u53EF\u7528\u3002\u81E8\u6642\u4FE1\u7BB1\u6703\u88AB\u62D2\u7D55\u3002",
998
- waitingExternalBrowser: "\u8ACB\u5728\u700F\u89BD\u5668\u4E2D\u5B8C\u6210\u767B\u5165\uFF0C\u7136\u5F8C\u56DE\u5230\u672C\u61C9\u7528\u3002"
1049
+ waitingExternalBrowser: "\u8ACB\u5728\u700F\u89BD\u5668\u4E2D\u5B8C\u6210\u767B\u5165\uFF0C\u7136\u5F8C\u56DE\u5230\u672C\u61C9\u7528\u3002",
1050
+ consentRequired: "\u8ACB\u5148\u540C\u610F\u4F7F\u7528\u689D\u6B3E\u5F8C\u518D\u7E7C\u7E8C\u3002",
1051
+ mfaTitle: "\u8EAB\u5206\u9A57\u8B49\u78BC",
1052
+ mfaSubtitle: "\u8F38\u5165\u9A57\u8B49\u5668\u61C9\u7528\u7A0B\u5F0F\u4E2D\u7684 6 \u4F4D\u6578\u5B57\u3002",
1053
+ mfaCodePlaceholder: "6 \u4F4D\u9A57\u8B49\u78BC",
1054
+ mfaSubmit: "\u9A57\u8B49\u4E26\u7E7C\u7E8C",
1055
+ mfaBack: "\u8FD4\u56DE"
999
1056
  };
1000
1057
  var ES = {
1001
1058
  title: "Iniciar sesi\xF3n",
@@ -1030,21 +1087,257 @@ var ES = {
1030
1087
  allowedDomainsPrefix: "Dominios de correo permitidos",
1031
1088
  allowedDomainsOpen: "El registro por correo est\xE1 abierto para la mayor\xEDa de proveedores.",
1032
1089
  allowedDomainsBlocklist: "Se aceptan la mayor\xEDa de correos. Se bloquean direcciones temporales.",
1033
- waitingExternalBrowser: "Termina el inicio de sesi\xF3n en el navegador y vuelve a esta app."
1090
+ waitingExternalBrowser: "Termina el inicio de sesi\xF3n en el navegador y vuelve a esta app.",
1091
+ consentRequired: "Acepta los t\xE9rminos antes de continuar."
1092
+ };
1093
+ var JA = {
1094
+ title: "\u30ED\u30B0\u30A4\u30F3",
1095
+ subtitle: "LuminaryWorks \u7D71\u5408\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u4F7F\u7528",
1096
+ identifierPlaceholder: "\u30E1\u30FC\u30EB\u307E\u305F\u306F\u30E6\u30FC\u30B6\u30FC\u540D",
1097
+ registerIdentifierPlaceholder: "\u30E6\u30FC\u30B6\u30FC\u540D",
1098
+ passwordPlaceholder: "\u30D1\u30B9\u30EF\u30FC\u30C9",
1099
+ confirmPasswordPlaceholder: "\u30D1\u30B9\u30EF\u30FC\u30C9\u78BA\u8A8D",
1100
+ submitPassword: "\u30D1\u30B9\u30EF\u30FC\u30C9\u3067\u30ED\u30B0\u30A4\u30F3",
1101
+ submitRegister: "\u30A2\u30AB\u30A6\u30F3\u30C8\u4F5C\u6210",
1102
+ submitSso: "\u7D71\u5408\u30A2\u30AB\u30A6\u30F3\u30C8\u3067\u7D9A\u3051\u308B",
1103
+ submitGoogle: "Google",
1104
+ submitGithub: "GitHub",
1105
+ socialDivider: "\u307E\u305F\u306F",
1106
+ hint: "\u30BD\u30FC\u30B7\u30E3\u30EB\u306F\u5404\u30B5\u30FC\u30D3\u30B9\u3092\u76F4\u63A5\u958B\u304D\u307E\u3059\u3002\u30D1\u30B9\u30EF\u30FC\u30C9\u306F LuminaryWorks \u30A2\u30AB\u30A6\u30F3\u30C8\u3067\u3059\u3002",
1107
+ registerHint: "\u30E1\u30FC\u30EB\u767B\u9332\u306B\u306F\u78BA\u8A8D\u30B3\u30FC\u30C9\u304C\u5FC5\u8981\u3067\u3059\u3002\u30E6\u30FC\u30B6\u30FC\u540D\u307E\u305F\u306F\u30BD\u30FC\u30B7\u30E3\u30EB\u3082\u4F7F\u3048\u307E\u3059\u3002",
1108
+ cancel: "\u30AD\u30E3\u30F3\u30BB\u30EB",
1109
+ experienceUnavailable: "\u30D1\u30B9\u30EF\u30FC\u30C9\u30ED\u30B0\u30A4\u30F3\u306F\u4F7F\u3048\u307E\u305B\u3093\u3002\u30BD\u30FC\u30B7\u30E3\u30EB\u3092\u304A\u4F7F\u3044\u304F\u3060\u3055\u3044\u3002",
1110
+ showPassword: "\u30D1\u30B9\u30EF\u30FC\u30C9\u3092\u8868\u793A",
1111
+ hidePassword: "\u30D1\u30B9\u30EF\u30FC\u30C9\u3092\u96A0\u3059",
1112
+ registerLink: "\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u4F5C\u6210",
1113
+ loginLink: "\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u304A\u6301\u3061\u3067\u3059\u304B\uFF1F\u30ED\u30B0\u30A4\u30F3",
1114
+ passwordMismatch: "\u30D1\u30B9\u30EF\u30FC\u30C9\u304C\u4E00\u81F4\u3057\u307E\u305B\u3093",
1115
+ registerTitle: "\u30A2\u30AB\u30A6\u30F3\u30C8\u4F5C\u6210",
1116
+ registerSubtitle: "LuminaryWorks \u7D71\u5408\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u4F5C\u6210",
1117
+ registerWithEmail: "\u30E1\u30FC\u30EB",
1118
+ registerWithUsername: "\u30E6\u30FC\u30B6\u30FC\u540D",
1119
+ emailPlaceholder: "\u30E1\u30FC\u30EB",
1120
+ verificationCodePlaceholder: "\u78BA\u8A8D\u30B3\u30FC\u30C9",
1121
+ sendCode: "\u30B3\u30FC\u30C9\u3092\u9001\u4FE1",
1122
+ resendCode: "\u518D\u9001\u4FE1",
1123
+ allowedDomainsPrefix: "\u5229\u7528\u3067\u304D\u308B\u30E1\u30FC\u30EB\u30C9\u30E1\u30A4\u30F3",
1124
+ allowedDomainsOpen: "\u307B\u3068\u3093\u3069\u306E\u30E1\u30FC\u30EB\u3067\u767B\u9332\u3067\u304D\u307E\u3059\u3002",
1125
+ allowedDomainsBlocklist: "\u307B\u3068\u3093\u3069\u306E\u30E1\u30FC\u30EB\u306F\u4F7F\u3048\u307E\u3059\u3002\u4F7F\u3044\u6368\u3066\u30A2\u30C9\u30EC\u30B9\u306F\u62D2\u5426\u3055\u308C\u307E\u3059\u3002",
1126
+ waitingExternalBrowser: "\u30D6\u30E9\u30A6\u30B6\u3067\u30ED\u30B0\u30A4\u30F3\u3092\u7D42\u3048\u305F\u3089\u3001\u3053\u306E\u30A2\u30D7\u30EA\u306B\u623B\u3063\u3066\u304F\u3060\u3055\u3044\u3002",
1127
+ consentRequired: "\u7D9A\u3051\u308B\u524D\u306B\u5229\u7528\u898F\u7D04\u3078\u540C\u610F\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
1128
+ };
1129
+ var KO = {
1130
+ title: "\uB85C\uADF8\uC778",
1131
+ subtitle: "LuminaryWorks \uD1B5\uD569 \uACC4\uC815 \uC0AC\uC6A9",
1132
+ identifierPlaceholder: "\uC774\uBA54\uC77C \uB610\uB294 \uC0AC\uC6A9\uC790 \uC774\uB984",
1133
+ registerIdentifierPlaceholder: "\uC0AC\uC6A9\uC790 \uC774\uB984",
1134
+ passwordPlaceholder: "\uBE44\uBC00\uBC88\uD638",
1135
+ confirmPasswordPlaceholder: "\uBE44\uBC00\uBC88\uD638 \uD655\uC778",
1136
+ submitPassword: "\uBE44\uBC00\uBC88\uD638\uB85C \uB85C\uADF8\uC778",
1137
+ submitRegister: "\uACC4\uC815 \uB9CC\uB4E4\uAE30",
1138
+ submitSso: "\uD1B5\uD569 \uACC4\uC815\uC73C\uB85C \uACC4\uC18D",
1139
+ submitGoogle: "Google",
1140
+ submitGithub: "GitHub",
1141
+ socialDivider: "\uB610\uB294",
1142
+ hint: "\uC18C\uC15C \uB85C\uADF8\uC778\uC740 \uD574\uB2F9 \uC11C\uBE44\uC2A4\uB97C \uBC14\uB85C \uC5FD\uB2C8\uB2E4. \uBE44\uBC00\uBC88\uD638\uB294 LuminaryWorks \uACC4\uC815\uC785\uB2C8\uB2E4.",
1143
+ registerHint: "\uC774\uBA54\uC77C \uAC00\uC785\uC5D0\uB294 \uC778\uC99D \uCF54\uB4DC\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uC790 \uC774\uB984\uC774\uB098 \uC18C\uC15C\uB3C4 \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
1144
+ cancel: "\uCDE8\uC18C",
1145
+ experienceUnavailable: "\uBE44\uBC00\uBC88\uD638 \uB85C\uADF8\uC778\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uC18C\uC15C \uB85C\uADF8\uC778\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
1146
+ showPassword: "\uBE44\uBC00\uBC88\uD638 \uD45C\uC2DC",
1147
+ hidePassword: "\uBE44\uBC00\uBC88\uD638 \uC228\uAE30\uAE30",
1148
+ registerLink: "\uACC4\uC815 \uB9CC\uB4E4\uAE30",
1149
+ loginLink: "\uACC4\uC815\uC774 \uC788\uB098\uC694? \uB85C\uADF8\uC778",
1150
+ passwordMismatch: "\uBE44\uBC00\uBC88\uD638\uAC00 \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4",
1151
+ registerTitle: "\uACC4\uC815 \uB9CC\uB4E4\uAE30",
1152
+ registerSubtitle: "LuminaryWorks \uD1B5\uD569 \uACC4\uC815 \uB9CC\uB4E4\uAE30",
1153
+ registerWithEmail: "\uC774\uBA54\uC77C",
1154
+ registerWithUsername: "\uC0AC\uC6A9\uC790 \uC774\uB984",
1155
+ emailPlaceholder: "\uC774\uBA54\uC77C",
1156
+ verificationCodePlaceholder: "\uC778\uC99D \uCF54\uB4DC",
1157
+ sendCode: "\uCF54\uB4DC \uBCF4\uB0B4\uAE30",
1158
+ resendCode: "\uB2E4\uC2DC \uBCF4\uB0B4\uAE30",
1159
+ allowedDomainsPrefix: "\uD5C8\uC6A9\uB41C \uC774\uBA54\uC77C \uB3C4\uBA54\uC778",
1160
+ allowedDomainsOpen: "\uB300\uBD80\uBD84\uC758 \uC774\uBA54\uC77C\uB85C \uAC00\uC785\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
1161
+ allowedDomainsBlocklist: "\uB300\uBD80\uBD84\uC758 \uC774\uBA54\uC77C\uC744 \uD5C8\uC6A9\uD569\uB2C8\uB2E4. \uC784\uC2DC \uC8FC\uC18C\uB294 \uAC70\uBD80\uB429\uB2C8\uB2E4.",
1162
+ waitingExternalBrowser: "\uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uB85C\uADF8\uC778\uC744 \uB9C8\uCE5C \uB4A4 \uC774 \uC571\uC73C\uB85C \uB3CC\uC544\uC624\uC138\uC694.",
1163
+ consentRequired: "\uACC4\uC18D\uD558\uB824\uBA74 \uC57D\uAD00\uC5D0 \uB3D9\uC758\uD558\uC138\uC694."
1164
+ };
1165
+ var PT = {
1166
+ title: "Entrar",
1167
+ subtitle: "Use a conta unificada LuminaryWorks",
1168
+ identifierPlaceholder: "E-mail ou usu\xE1rio",
1169
+ registerIdentifierPlaceholder: "Usu\xE1rio",
1170
+ passwordPlaceholder: "Senha",
1171
+ confirmPasswordPlaceholder: "Confirmar senha",
1172
+ submitPassword: "Entrar com senha",
1173
+ submitRegister: "Criar conta",
1174
+ submitSso: "Continuar com a conta unificada",
1175
+ submitGoogle: "Google",
1176
+ submitGithub: "GitHub",
1177
+ socialDivider: "ou",
1178
+ hint: "Redes sociais abrem o provedor direto. A senha usa sua conta LuminaryWorks.",
1179
+ registerHint: "O cadastro por e-mail pede um c\xF3digo. Tamb\xE9m d\xE1 para usar usu\xE1rio ou rede social.",
1180
+ cancel: "Cancelar",
1181
+ experienceUnavailable: "Entrada por senha indispon\xEDvel. Use uma rede social.",
1182
+ showPassword: "Mostrar senha",
1183
+ hidePassword: "Ocultar senha",
1184
+ registerLink: "Criar uma conta",
1185
+ loginLink: "J\xE1 tem conta? Entrar",
1186
+ passwordMismatch: "As senhas n\xE3o coincidem",
1187
+ registerTitle: "Criar conta",
1188
+ registerSubtitle: "Crie sua conta unificada LuminaryWorks",
1189
+ registerWithEmail: "E-mail",
1190
+ registerWithUsername: "Usu\xE1rio",
1191
+ emailPlaceholder: "E-mail",
1192
+ verificationCodePlaceholder: "C\xF3digo",
1193
+ sendCode: "Enviar c\xF3digo",
1194
+ resendCode: "Reenviar",
1195
+ allowedDomainsPrefix: "Dom\xEDnios de e-mail permitidos",
1196
+ allowedDomainsOpen: "O cadastro por e-mail est\xE1 aberto para a maioria dos provedores.",
1197
+ allowedDomainsBlocklist: "A maioria dos e-mails \xE9 aceita. Endere\xE7os tempor\xE1rios s\xE3o bloqueados.",
1198
+ waitingExternalBrowser: "Conclua o login no navegador e volte a este app.",
1199
+ consentRequired: "Aceite os termos antes de continuar."
1200
+ };
1201
+ var NL = {
1202
+ title: "Inloggen",
1203
+ subtitle: "Gebruik je LuminaryWorks-account",
1204
+ identifierPlaceholder: "E-mail of gebruikersnaam",
1205
+ registerIdentifierPlaceholder: "Gebruikersnaam",
1206
+ passwordPlaceholder: "Wachtwoord",
1207
+ confirmPasswordPlaceholder: "Bevestig wachtwoord",
1208
+ submitPassword: "Inloggen met wachtwoord",
1209
+ submitRegister: "Account maken",
1210
+ submitSso: "Doorgaan met unified account",
1211
+ submitGoogle: "Google",
1212
+ submitGithub: "GitHub",
1213
+ socialDivider: "of",
1214
+ hint: "Sociale logins openen de provider direct. Het wachtwoord is je LuminaryWorks-account.",
1215
+ registerHint: "Registreren via e-mail vraagt een code. Een gebruikersnaam of sociale login kan ook.",
1216
+ cancel: "Annuleren",
1217
+ experienceUnavailable: "Inloggen met wachtwoord is niet beschikbaar. Gebruik een sociale login.",
1218
+ showPassword: "Wachtwoord tonen",
1219
+ hidePassword: "Wachtwoord verbergen",
1220
+ registerLink: "Account maken",
1221
+ loginLink: "Al een account? Inloggen",
1222
+ passwordMismatch: "Wachtwoorden komen niet overeen",
1223
+ registerTitle: "Account maken",
1224
+ registerSubtitle: "Maak je LuminaryWorks-account",
1225
+ registerWithEmail: "E-mail",
1226
+ registerWithUsername: "Gebruikersnaam",
1227
+ emailPlaceholder: "E-mail",
1228
+ verificationCodePlaceholder: "Code",
1229
+ sendCode: "Code versturen",
1230
+ resendCode: "Opnieuw",
1231
+ allowedDomainsPrefix: "Toegestane e-maildomeinen",
1232
+ allowedDomainsOpen: "Registreren kan met de meeste e-mailproviders.",
1233
+ allowedDomainsBlocklist: "De meeste adressen zijn toegestaan. Tijdelijke adressen worden geweigerd.",
1234
+ waitingExternalBrowser: "Rond het inloggen af in de browser en kom terug naar deze app.",
1235
+ consentRequired: "Ga eerst akkoord met de voorwaarden."
1236
+ };
1237
+ var IT = {
1238
+ title: "Accedi",
1239
+ subtitle: "Usa l'account unificato LuminaryWorks",
1240
+ identifierPlaceholder: "Email o nome utente",
1241
+ registerIdentifierPlaceholder: "Nome utente",
1242
+ passwordPlaceholder: "Password",
1243
+ confirmPasswordPlaceholder: "Conferma password",
1244
+ submitPassword: "Accedi con password",
1245
+ submitRegister: "Crea account",
1246
+ submitSso: "Continua con l'account unificato",
1247
+ submitGoogle: "Google",
1248
+ submitGithub: "GitHub",
1249
+ socialDivider: "oppure",
1250
+ hint: "I social aprono il provider. La password usa il tuo account LuminaryWorks.",
1251
+ registerHint: "La registrazione email chiede un codice. Puoi anche usare un nome utente o un social.",
1252
+ cancel: "Annulla",
1253
+ experienceUnavailable: "Accesso con password non disponibile. Usa un social.",
1254
+ showPassword: "Mostra password",
1255
+ hidePassword: "Nascondi password",
1256
+ registerLink: "Crea un account",
1257
+ loginLink: "Hai gi\xE0 un account? Accedi",
1258
+ passwordMismatch: "Le password non coincidono",
1259
+ registerTitle: "Crea account",
1260
+ registerSubtitle: "Crea il tuo account unificato LuminaryWorks",
1261
+ registerWithEmail: "Email",
1262
+ registerWithUsername: "Nome utente",
1263
+ emailPlaceholder: "Email",
1264
+ verificationCodePlaceholder: "Codice",
1265
+ sendCode: "Invia codice",
1266
+ resendCode: "Invia di nuovo",
1267
+ allowedDomainsPrefix: "Domini email consentiti",
1268
+ allowedDomainsOpen: "La registrazione email \xE8 aperta per la maggior parte dei provider.",
1269
+ allowedDomainsBlocklist: "La maggior parte delle email \xE8 accettata. Gli indirizzi temporanei sono bloccati.",
1270
+ waitingExternalBrowser: "Completa l'accesso nel browser e torna a questa app.",
1271
+ consentRequired: "Accetta i termini prima di continuare."
1272
+ };
1273
+ var FR = {
1274
+ title: "Connexion",
1275
+ subtitle: "Utilisez votre compte unifi\xE9 LuminaryWorks",
1276
+ identifierPlaceholder: "E-mail ou nom d'utilisateur",
1277
+ registerIdentifierPlaceholder: "Nom d'utilisateur",
1278
+ passwordPlaceholder: "Mot de passe",
1279
+ confirmPasswordPlaceholder: "Confirmer le mot de passe",
1280
+ submitPassword: "Se connecter avec mot de passe",
1281
+ submitRegister: "Cr\xE9er un compte",
1282
+ submitSso: "Continuer avec le compte unifi\xE9",
1283
+ submitGoogle: "Google",
1284
+ submitGithub: "GitHub",
1285
+ socialDivider: "ou",
1286
+ hint: "Les r\xE9seaux ouvrent le fournisseur. Le mot de passe utilise votre compte LuminaryWorks.",
1287
+ registerHint: "L'inscription par e-mail demande un code. Un nom d'utilisateur ou un r\xE9seau social convient aussi.",
1288
+ cancel: "Annuler",
1289
+ experienceUnavailable: "Connexion par mot de passe indisponible. Utilisez un r\xE9seau social.",
1290
+ showPassword: "Afficher le mot de passe",
1291
+ hidePassword: "Masquer le mot de passe",
1292
+ registerLink: "Cr\xE9er un compte",
1293
+ loginLink: "D\xE9j\xE0 un compte ? Se connecter",
1294
+ passwordMismatch: "Les mots de passe ne correspondent pas",
1295
+ registerTitle: "Cr\xE9er un compte",
1296
+ registerSubtitle: "Cr\xE9ez votre compte unifi\xE9 LuminaryWorks",
1297
+ registerWithEmail: "E-mail",
1298
+ registerWithUsername: "Nom d'utilisateur",
1299
+ emailPlaceholder: "E-mail",
1300
+ verificationCodePlaceholder: "Code",
1301
+ sendCode: "Envoyer le code",
1302
+ resendCode: "Renvoyer",
1303
+ allowedDomainsPrefix: "Domaines e-mail autoris\xE9s",
1304
+ allowedDomainsOpen: "L'inscription par e-mail est ouverte pour la plupart des fournisseurs.",
1305
+ allowedDomainsBlocklist: "La plupart des e-mails sont accept\xE9s. Les adresses jetables sont refus\xE9es.",
1306
+ waitingExternalBrowser: "Terminez la connexion dans le navigateur, puis revenez \xE0 cette application.",
1307
+ consentRequired: "Acceptez les conditions avant de continuer.",
1308
+ mfaTitle: "Code d'authentification",
1309
+ mfaSubtitle: "Saisissez le code \xE0 6 chiffres de votre application.",
1310
+ mfaCodePlaceholder: "123456",
1311
+ mfaSubmit: "V\xE9rifier et continuer",
1312
+ mfaBack: "Retour"
1034
1313
  };
1035
1314
  var BY_LOCALE = {
1036
1315
  en: void 0,
1037
1316
  "zh-CN": ZH_CN,
1038
1317
  "zh-TW": ZH_TW,
1039
- es: ES
1318
+ ja: JA,
1319
+ ko: KO,
1320
+ pt: PT,
1321
+ nl: NL,
1322
+ it: IT,
1323
+ es: ES,
1324
+ fr: FR
1040
1325
  };
1041
1326
  function normalizeLoginLocale(locale) {
1042
1327
  const raw = (locale ?? "en").trim().toLowerCase();
1043
1328
  if (raw === "zh" || raw === "zh-cn" || raw === "zh-hans" || raw.startsWith("zh-cn")) {
1044
1329
  return "zh-CN";
1045
1330
  }
1046
- if (raw === "zh-tw" || raw === "zh-hant" || raw.startsWith("zh-tw")) return "zh-TW";
1331
+ if (raw === "zh-tw" || raw === "zh-hant" || raw.startsWith("zh-tw") || raw.startsWith("zh-hk")) {
1332
+ return "zh-TW";
1333
+ }
1334
+ if (raw === "ja" || raw.startsWith("ja-")) return "ja";
1335
+ if (raw === "ko" || raw.startsWith("ko-")) return "ko";
1336
+ if (raw === "pt" || raw.startsWith("pt-")) return "pt";
1337
+ if (raw === "nl" || raw.startsWith("nl-")) return "nl";
1338
+ if (raw === "it" || raw.startsWith("it-")) return "it";
1047
1339
  if (raw === "es" || raw.startsWith("es-")) return "es";
1340
+ if (raw === "fr" || raw.startsWith("fr-")) return "fr";
1048
1341
  if (raw === "en" || raw.startsWith("en-")) return "en";
1049
1342
  return "en";
1050
1343
  }
@@ -1085,9 +1378,14 @@ var HeadlessLoginPanel_module_default = {
1085
1378
  switchMode: "HeadlessLoginPanel_module_switchMode",
1086
1379
  switchModeBtn: "HeadlessLoginPanel_module_switchModeBtn",
1087
1380
  error: "HeadlessLoginPanel_module_error",
1381
+ consent: "HeadlessLoginPanel_module_consent",
1382
+ consentInvalid: "HeadlessLoginPanel_module_consentInvalid",
1383
+ consentError: "HeadlessLoginPanel_module_consentError",
1384
+ consentLinks: "HeadlessLoginPanel_module_consentLinks",
1088
1385
  footer: "HeadlessLoginPanel_module_footer"
1089
1386
  };
1090
1387
  var DEFAULT_LOGIN_THEME_COLOR = "#1677ff";
1388
+ var LOGIN_CARD_MAX_WIDTH = 400;
1091
1389
  var defaults = {
1092
1390
  title: "Sign in",
1093
1391
  subtitle: "Use your LuminaryWorks unified account",
@@ -1121,7 +1419,13 @@ var defaults = {
1121
1419
  allowedDomainsPrefix: "Allowed email domains",
1122
1420
  allowedDomainsOpen: "Email registration is open for most providers.",
1123
1421
  allowedDomainsBlocklist: "Most email providers are accepted. Temporary / disposable addresses are blocked.",
1124
- waitingExternalBrowser: "Finish signing in with your browser, then return to this app."
1422
+ waitingExternalBrowser: "Finish signing in with your browser, then return to this app.",
1423
+ consentRequired: "Please agree to the terms before continuing.",
1424
+ mfaTitle: "Authenticator code",
1425
+ mfaSubtitle: "Enter the 6-digit code from your authenticator app.",
1426
+ mfaCodePlaceholder: "123456",
1427
+ mfaSubmit: "Verify and continue",
1428
+ mfaBack: "Back"
1125
1429
  };
1126
1430
  function resolveSieBase(config) {
1127
1431
  const explicit = config.experienceApiBase?.trim();
@@ -1162,6 +1466,12 @@ function HeadlessLoginPanel({
1162
1466
  onCancel,
1163
1467
  onOidcSession,
1164
1468
  onExperienceRedirect,
1469
+ consent,
1470
+ consentDocuments,
1471
+ consentOk = true,
1472
+ onConsentBlocked,
1473
+ initialIdentifier,
1474
+ onIdentifierChange,
1165
1475
  footer,
1166
1476
  className,
1167
1477
  style,
@@ -1210,18 +1520,30 @@ function HeadlessLoginPanel({
1210
1520
  const configured = isIdpConfigured(config);
1211
1521
  const [panelMode, setPanelMode] = react.useState("sign-in");
1212
1522
  const [registerChannel, setRegisterChannel] = react.useState("email");
1213
- const [identifier, setIdentifier] = react.useState("");
1523
+ const [identifier, setIdentifier] = react.useState(initialIdentifier ?? "");
1524
+ const hydratedIdentifier = react.useRef(false);
1525
+ react.useEffect(() => {
1526
+ if (hydratedIdentifier.current) return;
1527
+ if (!initialIdentifier) return;
1528
+ hydratedIdentifier.current = true;
1529
+ setIdentifier(initialIdentifier);
1530
+ }, [initialIdentifier]);
1214
1531
  const [password, setPassword] = react.useState("");
1215
1532
  const [confirmPassword, setConfirmPassword] = react.useState("");
1216
1533
  const [verificationCode, setVerificationCode] = react.useState("");
1217
1534
  const [emailVerificationId, setEmailVerificationId] = react.useState(null);
1218
1535
  const [passwordVisible, setPasswordVisible] = react.useState(false);
1219
1536
  const panelStyle = {
1537
+ width: `min(100%, ${LOGIN_CARD_MAX_WIDTH}px)`,
1538
+ maxWidth: LOGIN_CARD_MAX_WIDTH,
1220
1539
  ...style,
1221
1540
  ["--lw-auth-theme"]: themeColor || DEFAULT_LOGIN_THEME_COLOR
1222
1541
  };
1223
1542
  const [loading, setLoading] = react.useState(null);
1224
1543
  const [error, setError] = react.useState("");
1544
+ const [consentBlocked, setConsentBlocked] = react.useState(false);
1545
+ const [mfaPending, setMfaPending] = react.useState(false);
1546
+ const [mfaCode, setMfaCode] = react.useState("");
1225
1547
  const [awaitingExternal, setAwaitingExternal] = react.useState(false);
1226
1548
  const [connectors, setConnectors] = react.useState([]);
1227
1549
  const socialEnabled = showSocialConnectors !== false && !(Array.isArray(socialProviders) && socialProviders.length === 0) && experienceAdapter.capabilities.includes(LOGIN_EXPERIENCE_CAPABILITIES.socialConnectors) && experienceAdapter.capabilities.includes(LOGIN_EXPERIENCE_CAPABILITIES.socialDirectSignIn) && typeof experienceAdapter.fetchSocialConnectors === "function" && typeof experienceAdapter.createSocialSignInRequest === "function";
@@ -1276,6 +1598,15 @@ function HeadlessLoginPanel({
1276
1598
  socialEnabled,
1277
1599
  socialProviders
1278
1600
  ]);
1601
+ react.useEffect(() => {
1602
+ if (consentOk) setConsentBlocked(false);
1603
+ }, [consentOk]);
1604
+ const ensureConsent = () => {
1605
+ if (consentOk) return true;
1606
+ setConsentBlocked(true);
1607
+ onConsentBlocked?.();
1608
+ return false;
1609
+ };
1279
1610
  const runOidc = async (experienceRequest) => {
1280
1611
  if (!configured) throw new Error("IdP not configured");
1281
1612
  if (mode === "external") {
@@ -1302,6 +1633,7 @@ function HeadlessLoginPanel({
1302
1633
  await onOidcSession?.(session, next);
1303
1634
  };
1304
1635
  const runSocial = async (target) => {
1636
+ if (!ensureConsent()) return;
1305
1637
  setError("");
1306
1638
  setLoading(target);
1307
1639
  try {
@@ -1318,6 +1650,7 @@ function HeadlessLoginPanel({
1318
1650
  }
1319
1651
  };
1320
1652
  const runHostedOidc = async () => {
1653
+ if (!ensureConsent()) return;
1321
1654
  setError("");
1322
1655
  setLoading("sso");
1323
1656
  try {
@@ -1338,6 +1671,7 @@ function HeadlessLoginPanel({
1338
1671
  const runPassword = async (event) => {
1339
1672
  event.preventDefault();
1340
1673
  if (!configured) return;
1674
+ if (!ensureConsent()) return;
1341
1675
  setError("");
1342
1676
  setLoading("password");
1343
1677
  try {
@@ -1414,6 +1748,36 @@ function HeadlessLoginPanel({
1414
1748
  scopes: config.scopes,
1415
1749
  returnUrl
1416
1750
  });
1751
+ if (result.mfaRequired) {
1752
+ setMfaPending(true);
1753
+ setMfaCode("");
1754
+ setLoading(null);
1755
+ return;
1756
+ }
1757
+ if (result.redirectTo) {
1758
+ followExperienceRedirect(result.redirectTo);
1759
+ return;
1760
+ }
1761
+ throw new Error("Experience API did not return redirectTo");
1762
+ } catch (e) {
1763
+ setError(e instanceof Error ? e.message : String(e));
1764
+ setLoading(null);
1765
+ }
1766
+ };
1767
+ const runMfa = async (event) => {
1768
+ event.preventDefault();
1769
+ if (!configured || !ensureConsent()) return;
1770
+ setError("");
1771
+ setLoading("mfa");
1772
+ try {
1773
+ const apiBase = config.experienceApiBase?.trim();
1774
+ if (!apiBase || !experienceAdapter.experienceVerifyTotp) {
1775
+ throw new Error(labels.experienceUnavailable);
1776
+ }
1777
+ const result = await experienceAdapter.experienceVerifyTotp({
1778
+ apiBase,
1779
+ code: mfaCode
1780
+ });
1417
1781
  if (result.redirectTo) {
1418
1782
  followExperienceRedirect(result.redirectTo);
1419
1783
  return;
@@ -1426,6 +1790,7 @@ function HeadlessLoginPanel({
1426
1790
  };
1427
1791
  const runSendCode = async () => {
1428
1792
  if (!configured || !useEmailRegister) return;
1793
+ if (!ensureConsent()) return;
1429
1794
  setError("");
1430
1795
  setLoading("send-code");
1431
1796
  try {
@@ -1467,8 +1832,8 @@ function HeadlessLoginPanel({
1467
1832
  const showSocial = socialEnabled && connectors.length > 0;
1468
1833
  const showHint = Boolean(labelsProp?.hint) || showSocial || isRegister;
1469
1834
  const formReady = Boolean(identifier.trim()) && Boolean(password) && (!isRegister || Boolean(confirmPassword)) && (!useEmailRegister || Boolean(verificationCode.trim()) && Boolean(emailVerificationId));
1470
- const titleText = isRegister ? labels.registerTitle : labels.title;
1471
- const subtitleText = isRegister ? labels.registerSubtitle : labels.subtitle;
1835
+ const titleText = mfaPending ? labels.mfaTitle : isRegister ? labels.registerTitle : labels.title;
1836
+ const subtitleText = mfaPending ? labels.mfaSubtitle : isRegister ? labels.registerSubtitle : labels.subtitle;
1472
1837
  const identifierPlaceholder = isRegister ? useEmailRegister ? labels.emailPlaceholder : labels.registerIdentifierPlaceholder : labels.identifierPlaceholder;
1473
1838
  const submitLabel = isRegister ? labels.submitRegister : labels.submitPassword;
1474
1839
  const hintText = isRegister ? labels.registerHint : labels.hint;
@@ -1487,7 +1852,44 @@ function HeadlessLoginPanel({
1487
1852
  ] }),
1488
1853
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: HeadlessLoginPanel_module_default.subtitle, children: subtitleText }),
1489
1854
  configured ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1490
- passwordEnabled ? /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: (e) => void runPassword(e), className: HeadlessLoginPanel_module_default.form, children: [
1855
+ passwordEnabled && mfaPending ? /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: (e) => void runMfa(e), className: HeadlessLoginPanel_module_default.form, children: [
1856
+ /* @__PURE__ */ jsxRuntime.jsx(
1857
+ "input",
1858
+ {
1859
+ inputMode: "numeric",
1860
+ autoComplete: "one-time-code",
1861
+ name: "totp",
1862
+ placeholder: labels.mfaCodePlaceholder,
1863
+ value: mfaCode,
1864
+ onChange: (e) => setMfaCode(e.target.value),
1865
+ className: HeadlessLoginPanel_module_default.input,
1866
+ disabled: busy
1867
+ }
1868
+ ),
1869
+ /* @__PURE__ */ jsxRuntime.jsx(
1870
+ "button",
1871
+ {
1872
+ type: "submit",
1873
+ className: HeadlessLoginPanel_module_default.primaryBtn,
1874
+ disabled: busy || mfaCode.trim().length < 6,
1875
+ children: loading === "mfa" ? "\u2026" : labels.mfaSubmit
1876
+ }
1877
+ ),
1878
+ /* @__PURE__ */ jsxRuntime.jsx(
1879
+ "button",
1880
+ {
1881
+ type: "button",
1882
+ className: HeadlessLoginPanel_module_default.cancelBtn,
1883
+ disabled: busy,
1884
+ onClick: () => {
1885
+ setMfaPending(false);
1886
+ setMfaCode("");
1887
+ setError("");
1888
+ },
1889
+ children: labels.mfaBack
1890
+ }
1891
+ )
1892
+ ] }) : passwordEnabled ? /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: (e) => void runPassword(e), className: HeadlessLoginPanel_module_default.form, children: [
1491
1893
  isRegister && emailRegisterEnabled && usernameRegisterEnabled ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: HeadlessLoginPanel_module_default.channelTabs, role: "tablist", "aria-label": "Register method", children: [
1492
1894
  /* @__PURE__ */ jsxRuntime.jsx(
1493
1895
  "button",
@@ -1539,7 +1941,9 @@ function HeadlessLoginPanel({
1539
1941
  placeholder: identifierPlaceholder,
1540
1942
  value: identifier,
1541
1943
  onChange: (e) => {
1542
- setIdentifier(e.target.value);
1944
+ const next = e.target.value;
1945
+ setIdentifier(next);
1946
+ onIdentifierChange?.(next);
1543
1947
  if (useEmailRegister) {
1544
1948
  setEmailVerificationId(null);
1545
1949
  }
@@ -1626,6 +2030,13 @@ function HeadlessLoginPanel({
1626
2030
  children: loading === "sso" ? "\u2026" : labels.submitSso
1627
2031
  }
1628
2032
  ) }),
2033
+ consent || consentDocuments && consentDocuments.length > 0 || consentBlocked ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx(HeadlessLoginPanel_module_default.consent, consentBlocked && HeadlessLoginPanel_module_default.consentInvalid), children: [
2034
+ consent ? consent : consentDocuments && consentDocuments.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: HeadlessLoginPanel_module_default.consentLinks, children: consentDocuments.map((doc, index) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
2035
+ index > 0 ? " \xB7 " : null,
2036
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: doc.href, target: "_blank", rel: "noopener noreferrer", children: doc.label })
2037
+ ] }, doc.id)) }) : null,
2038
+ consentBlocked ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: HeadlessLoginPanel_module_default.consentError, children: labels.consentRequired }) : null
2039
+ ] }) : null,
1629
2040
  showHint ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: HeadlessLoginPanel_module_default.hint, children: hintText }) : null,
1630
2041
  registerEnabled && passwordEnabled ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: HeadlessLoginPanel_module_default.switchMode, children: /* @__PURE__ */ jsxRuntime.jsx(
1631
2042
  "button",
@@ -1811,6 +2222,41 @@ function useAuthGateOptional() {
1811
2222
  return react.useContext(AuthGateContext);
1812
2223
  }
1813
2224
 
2225
+ // src/login-legal.ts
2226
+ var DEFAULT_PLATFORM_TERMS_URL = "https://luminaryworks.dev/legal/terms";
2227
+ var DEFAULT_PLATFORM_PRIVACY_URL = "https://luminaryworks.dev/legal/privacy";
2228
+ function pickEnv(env, name) {
2229
+ const keys = [`VITE_${name}`, `PUBLIC_${name}`, `NEXT_PUBLIC_${name}`, name];
2230
+ for (const key of keys) {
2231
+ const value = env[key]?.trim();
2232
+ if (value) return value;
2233
+ }
2234
+ return void 0;
2235
+ }
2236
+ function readLoginLegalConfigFromEnv(env, defaults2) {
2237
+ return {
2238
+ platformTermsUrl: pickEnv(env, "LEGAL_PLATFORM_TERMS_URL") || defaults2?.platformTermsUrl || DEFAULT_PLATFORM_TERMS_URL,
2239
+ platformPrivacyUrl: pickEnv(env, "LEGAL_PLATFORM_PRIVACY_URL") || defaults2?.platformPrivacyUrl || DEFAULT_PLATFORM_PRIVACY_URL,
2240
+ productTermsUrl: pickEnv(env, "LEGAL_PRODUCT_TERMS_URL") || defaults2?.productTermsUrl || "/legal/terms",
2241
+ productPrivacyUrl: pickEnv(env, "LEGAL_PRODUCT_PRIVACY_URL") || defaults2?.productPrivacyUrl || "/legal/privacy"
2242
+ };
2243
+ }
2244
+ function buildLoginLegalDocuments(urls, labels) {
2245
+ const docs = [
2246
+ {
2247
+ id: "product-terms",
2248
+ href: urls.productTermsUrl,
2249
+ label: labels.productTerms
2250
+ },
2251
+ {
2252
+ id: "privacy",
2253
+ href: urls.productPrivacyUrl || urls.platformPrivacyUrl,
2254
+ label: labels.privacy
2255
+ }
2256
+ ];
2257
+ return docs.filter((row) => row.href.length > 0 && row.label.length > 0);
2258
+ }
2259
+
1814
2260
  // src/LoginLanguageSwitcher.module.scss
1815
2261
  var LoginLanguageSwitcher_module_default = {
1816
2262
  switch: "LoginLanguageSwitcher_module_switch",
@@ -1922,7 +2368,7 @@ function LoginCanvas({
1922
2368
  onChange: onLocaleChange,
1923
2369
  locales,
1924
2370
  label: languageLabel,
1925
- variant: tone === "console" || tone === "data" ? "onDark" : "default"
2371
+ variant: tone === "console" || tone === "data" || tone === "edu" ? "onDark" : "default"
1926
2372
  }
1927
2373
  ) }),
1928
2374
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: fill ? `${LoginCanvas_module_default.slot} ${LoginCanvas_module_default.slotFill}` : LoginCanvas_module_default.slot, children })
@@ -1983,9 +2429,13 @@ exports.AuthGateProvider = AuthGateProvider;
1983
2429
  exports.DEFAULT_DISPOSABLE_EMAIL_BLOCKLIST = DEFAULT_DISPOSABLE_EMAIL_BLOCKLIST;
1984
2430
  exports.DEFAULT_LOGIN_LOCALES = DEFAULT_LOGIN_LOCALES;
1985
2431
  exports.DEFAULT_LOGIN_THEME_COLOR = DEFAULT_LOGIN_THEME_COLOR;
2432
+ exports.DEFAULT_PLATFORM_PRIVACY_URL = DEFAULT_PLATFORM_PRIVACY_URL;
2433
+ exports.DEFAULT_PLATFORM_TERMS_URL = DEFAULT_PLATFORM_TERMS_URL;
1986
2434
  exports.DEFAULT_REGISTER_EMAIL_ALLOWLIST = DEFAULT_REGISTER_EMAIL_ALLOWLIST;
2435
+ exports.ExperienceApiError = ExperienceApiError;
1987
2436
  exports.HeadlessLoginPanel = HeadlessLoginPanel;
1988
2437
  exports.HostedOidcExperienceAdapter = HostedOidcExperienceAdapter;
2438
+ exports.LOGIN_CARD_MAX_WIDTH = LOGIN_CARD_MAX_WIDTH;
1989
2439
  exports.LOGIN_EXPERIENCE_CAPABILITIES = LOGIN_EXPERIENCE_CAPABILITIES;
1990
2440
  exports.LoginCanvas = LoginCanvas;
1991
2441
  exports.LoginLanguageSwitcher = LoginLanguageSwitcher;
@@ -1993,6 +2443,7 @@ exports.LogtoExperienceAdapter = LogtoExperienceAdapter;
1993
2443
  exports.LuminaryAuthProvider = LuminaryAuthProvider;
1994
2444
  exports.ReauthOverlay = ReauthOverlay;
1995
2445
  exports.authGate = authGate;
2446
+ exports.buildLoginLegalDocuments = buildLoginLegalDocuments;
1996
2447
  exports.clearStoredSession = clearStoredSession;
1997
2448
  exports.createLoginExperienceAdapter = createLoginExperienceAdapter;
1998
2449
  exports.createLogtoDirectSignInRequest = createLogtoDirectSignInRequest;
@@ -2010,6 +2461,7 @@ exports.handleSignInCallback = handleSignInCallback;
2010
2461
  exports.handleSignInPopupCallback = handleSignInPopupCallback;
2011
2462
  exports.isIdpConfigured = isIdpConfigured;
2012
2463
  exports.isLogtoRegisterUsername = isLogtoRegisterUsername;
2464
+ exports.isMfaVerificationRequired = isMfaVerificationRequired;
2013
2465
  exports.isOidcPopupWindow = isOidcPopupWindow;
2014
2466
  exports.isValidEmailShape = isValidEmailShape;
2015
2467
  exports.loginLabels = loginLabels;
@@ -2017,6 +2469,7 @@ exports.normalizeLoginLocale = normalizeLoginLocale;
2017
2469
  exports.normalizeRegisterEmailMode = normalizeRegisterEmailMode;
2018
2470
  exports.prepareSignInRequestUrl = prepareSignInRequestUrl;
2019
2471
  exports.readIdpConfigFromEnv = readIdpConfigFromEnv;
2472
+ exports.readLoginLegalConfigFromEnv = readLoginLegalConfigFromEnv;
2020
2473
  exports.readRegisterEmailPolicyFromEnv = readRegisterEmailPolicyFromEnv;
2021
2474
  exports.registerEmailDomainsHint = registerEmailDomainsHint;
2022
2475
  exports.registerEmailRejectionMessage = registerEmailRejectionMessage;