@loafmarkets/ui 0.1.375 → 0.1.376

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
@@ -6626,6 +6626,14 @@ PropertySubheader.displayName = "PropertySubheader";
6626
6626
  var DEFAULT_LOGO_SRC = Loaf_logo_Banner_default;
6627
6627
  var DEFAULT_LOGO_ALT = "Loaf";
6628
6628
  var OTP_INPUT_LENGTH = 6;
6629
+ var friendlyError = (err, fallback) => {
6630
+ const data = err?.response?.data;
6631
+ if (typeof data?.error === "string" && data.error.trim()) return data.error;
6632
+ if (typeof data?.message === "string" && data.message.trim()) return data.message;
6633
+ const msg = err instanceof Error ? err.message : "";
6634
+ if (msg && !/request failed with status code/i.test(msg) && !/network error/i.test(msg)) return msg;
6635
+ return fallback;
6636
+ };
6629
6637
  var LoginPopup = ({
6630
6638
  onClose,
6631
6639
  onOpenEarlyAccess,
@@ -6647,7 +6655,9 @@ var LoginPopup = ({
6647
6655
  kycStatus: kycStatusProp,
6648
6656
  walletAddress,
6649
6657
  onSubmitReferralCode,
6650
- onJoinWaitlist
6658
+ onValidateCode,
6659
+ onCheckAccess,
6660
+ gate
6651
6661
  }) => {
6652
6662
  const [view, setView] = React5.useState(() => initialView ?? "main");
6653
6663
  const [email, setEmail] = React5.useState("");
@@ -6658,8 +6668,10 @@ var LoginPopup = ({
6658
6668
  const [referralCode, setReferralCode] = React5.useState("");
6659
6669
  const [referralLoading, setReferralLoading] = React5.useState(false);
6660
6670
  const [referralError, setReferralError] = React5.useState("");
6661
- const [waitlistLoading, setWaitlistLoading] = React5.useState(false);
6662
- const [waitlistMessage, setWaitlistMessage] = React5.useState("");
6671
+ const [codeStatus, setCodeStatus] = React5.useState("idle");
6672
+ const [signInRevealed, setSignInRevealed] = React5.useState(false);
6673
+ const [otpStatus, setOtpStatus] = React5.useState("idle");
6674
+ const [signInMode, setSignInMode] = React5.useState(false);
6663
6675
  const [loading, setLoading] = React5.useState(false);
6664
6676
  const [isSignUp, setIsSignUp] = React5.useState(false);
6665
6677
  const [fundingAmount] = React5.useState("");
@@ -6671,6 +6683,33 @@ var LoginPopup = ({
6671
6683
  const [fundingError, setFundingError] = React5.useState("");
6672
6684
  const [transakWidgetUrl, setTransakWidgetUrl] = React5.useState(null);
6673
6685
  const suppressAutoCloseRef = React5__namespace.default.useRef(false);
6686
+ const validatedCodeRef = React5__namespace.default.useRef(null);
6687
+ const finishGate = React5__namespace.default.useCallback(async () => {
6688
+ if (!gate) return true;
6689
+ const code = validatedCodeRef.current;
6690
+ if (code) {
6691
+ try {
6692
+ await onSubmitReferralCode?.(code);
6693
+ window.dispatchEvent(new CustomEvent("loaf:onboarding-start"));
6694
+ return true;
6695
+ } catch {
6696
+ }
6697
+ }
6698
+ const hasAccess = onCheckAccess ? await onCheckAccess() : true;
6699
+ if (hasAccess) return true;
6700
+ suppressAutoCloseRef.current = true;
6701
+ validatedCodeRef.current = null;
6702
+ setOtp(Array(OTP_INPUT_LENGTH).fill(""));
6703
+ setOtpStatus("idle");
6704
+ setSignInMode(false);
6705
+ setSignInRevealed(false);
6706
+ setCodeStatus(code ? "invalid" : "idle");
6707
+ setView("referral");
6708
+ setError(
6709
+ code ? "That code can't be redeemed anymore. Enter a different access code." : "Enter your access code to continue."
6710
+ );
6711
+ return false;
6712
+ }, [gate, onSubmitReferralCode, onCheckAccess]);
6674
6713
  React5.useEffect(() => {
6675
6714
  if (typeof initialView === "string") {
6676
6715
  setView(initialView);
@@ -6725,11 +6764,11 @@ var LoginPopup = ({
6725
6764
  }, [autoCloseOnAuth, currentUser, isAuthenticated, onClose, view]);
6726
6765
  React5.useEffect(() => {
6727
6766
  const handleEsc = (e) => {
6728
- if (e.key === "Escape") onClose();
6767
+ if (e.key === "Escape" && !gate) onClose();
6729
6768
  };
6730
6769
  window.addEventListener("keydown", handleEsc);
6731
6770
  return () => window.removeEventListener("keydown", handleEsc);
6732
- }, [onClose]);
6771
+ }, [onClose, gate]);
6733
6772
  const handleWalletLogin = async () => {
6734
6773
  if (onWalletLogin) {
6735
6774
  suppressAutoCloseRef.current = true;
@@ -6741,12 +6780,16 @@ var LoginPopup = ({
6741
6780
  setView("wallet-handle");
6742
6781
  return;
6743
6782
  }
6744
- suppressAutoCloseRef.current = false;
6745
- onClose();
6783
+ if (await finishGate()) {
6784
+ suppressAutoCloseRef.current = false;
6785
+ onClose();
6786
+ }
6746
6787
  return;
6747
6788
  } catch (err) {
6748
6789
  console.error("[LoginTrace][Popup] Wallet login failed", err);
6749
6790
  suppressAutoCloseRef.current = false;
6791
+ setError(friendlyError(err, "Wallet login failed. Please try again."));
6792
+ return;
6750
6793
  }
6751
6794
  }
6752
6795
  onClose();
@@ -6768,6 +6811,13 @@ var LoginPopup = ({
6768
6811
  setError("");
6769
6812
  try {
6770
6813
  await onWalletSignup(handle.trim());
6814
+ if (gate) {
6815
+ if (await finishGate()) {
6816
+ suppressAutoCloseRef.current = false;
6817
+ onClose();
6818
+ }
6819
+ return;
6820
+ }
6771
6821
  if (onSubmitReferralCode) {
6772
6822
  setView("referral");
6773
6823
  } else {
@@ -6796,6 +6846,7 @@ var LoginPopup = ({
6796
6846
  }
6797
6847
  setLoading(true);
6798
6848
  setError("");
6849
+ setOtpStatus("idle");
6799
6850
  const normalizedHandle = isSignUp && handle.trim() ? handle.trim() : void 0;
6800
6851
  try {
6801
6852
  const demoResult = await onDemoLogin?.(email, normalizedHandle ?? null);
@@ -6816,9 +6867,14 @@ var LoginPopup = ({
6816
6867
  setView("otp");
6817
6868
  setOtp(Array(OTP_INPUT_LENGTH).fill(""));
6818
6869
  } catch (err) {
6819
- const message = err instanceof Error ? err.message : "Failed to send verification code";
6870
+ const message = friendlyError(err, "We couldn't send a code to that email. Please double-check it and try again.");
6820
6871
  console.error("[LoginTrace][Popup] onSendEmailCode threw", err);
6821
6872
  if (!isSignUp && message.includes("No account found")) {
6873
+ if (signInMode) {
6874
+ setError("No account found for this email. Go back and enter your access code to create one.");
6875
+ setLoading(false);
6876
+ return;
6877
+ }
6822
6878
  setIsSignUp(true);
6823
6879
  setError("");
6824
6880
  setLoading(false);
@@ -6831,7 +6887,7 @@ var LoginPopup = ({
6831
6887
  setView("otp");
6832
6888
  setOtp(Array(OTP_INPUT_LENGTH).fill(""));
6833
6889
  } catch (retryErr) {
6834
- setError(retryErr instanceof Error ? retryErr.message : "Failed to send verification code");
6890
+ setError(friendlyError(retryErr, "We couldn't send a code to that email. Please try again."));
6835
6891
  }
6836
6892
  setLoading(false);
6837
6893
  return;
@@ -6925,6 +6981,30 @@ var LoginPopup = ({
6925
6981
  setLoading(false);
6926
6982
  }
6927
6983
  };
6984
+ const runGateOtpVerify = React5__namespace.default.useCallback(async (code) => {
6985
+ if (!onVerifyEmailCode) return;
6986
+ setOtpStatus("checking");
6987
+ setError("");
6988
+ suppressAutoCloseRef.current = true;
6989
+ try {
6990
+ await onVerifyEmailCode({ code, email });
6991
+ if (await finishGate()) {
6992
+ setOtpStatus("valid");
6993
+ setTimeout(() => onClose(), 750);
6994
+ }
6995
+ } catch {
6996
+ suppressAutoCloseRef.current = false;
6997
+ setOtpStatus("invalid");
6998
+ }
6999
+ }, [onVerifyEmailCode, email, finishGate, onClose]);
7000
+ React5.useEffect(() => {
7001
+ if (!gate || view !== "otp") return;
7002
+ if (otp.join("").length < OTP_INPUT_LENGTH) {
7003
+ if (otpStatus === "invalid") setOtpStatus("idle");
7004
+ return;
7005
+ }
7006
+ if (otpStatus === "idle") void runGateOtpVerify(otp.join(""));
7007
+ }, [gate, view, otp, otpStatus, runGateOtpVerify]);
6928
7008
  const handleKycWidgetResult = (result) => {
6929
7009
  setShowKycWidget(false);
6930
7010
  if (result.passed) {
@@ -7021,7 +7101,7 @@ var LoginPopup = ({
7021
7101
  setError("");
7022
7102
  };
7023
7103
  if (view === "main") {
7024
- return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7104
+ return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { $transparent: gate, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7025
7105
  /* @__PURE__ */ jsxRuntime.jsx(CloseButton, { onClick: onClose, "aria-label": "Close login popup", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) }),
7026
7106
  /* @__PURE__ */ jsxRuntime.jsxs(Title, { children: [
7027
7107
  /* @__PURE__ */ jsxRuntime.jsxs(LogoContainer3, { children: [
@@ -7050,7 +7130,7 @@ var LoginPopup = ({
7050
7130
  ] }) });
7051
7131
  }
7052
7132
  if (view === "email") {
7053
- return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7133
+ return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { $transparent: gate, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7054
7134
  /* @__PURE__ */ jsxRuntime.jsx(CloseButton, { onClick: onClose, "aria-label": "Close login popup", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) }),
7055
7135
  /* @__PURE__ */ jsxRuntime.jsxs(BackButton, { onClick: handleBack, children: [
7056
7136
  /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" }) }),
@@ -7089,7 +7169,7 @@ var LoginPopup = ({
7089
7169
  ] }) });
7090
7170
  }
7091
7171
  if (view === "wallet-handle") {
7092
- return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: loading ? void 0 : onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7172
+ return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { $transparent: gate, onClick: loading ? void 0 : onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7093
7173
  !loading && /* @__PURE__ */ jsxRuntime.jsx(CloseButton, { onClick: onClose, "aria-label": "Close login popup", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) }),
7094
7174
  /* @__PURE__ */ jsxRuntime.jsxs(Title, { children: [
7095
7175
  /* @__PURE__ */ jsxRuntime.jsx(LogoContainer3, { children: /* @__PURE__ */ jsxRuntime.jsx(LogoImage, { src: logoSrc, alt: logoAlt }) }),
@@ -7114,7 +7194,71 @@ var LoginPopup = ({
7114
7194
  ] }) });
7115
7195
  }
7116
7196
  if (view === "otp") {
7117
- return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: loading ? void 0 : onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7197
+ if (gate) {
7198
+ return /* @__PURE__ */ jsxRuntime.jsxs(GateShell, { children: [
7199
+ /* @__PURE__ */ jsxRuntime.jsx(GateTint, { $reveal: otpStatus === "valid" ? 3 : 2 }),
7200
+ /* @__PURE__ */ jsxRuntime.jsxs(GateForm, { children: [
7201
+ /* @__PURE__ */ jsxRuntime.jsxs(GateBrand, { children: [
7202
+ /* @__PURE__ */ jsxRuntime.jsx(GateLogoLink, { href: "https://loafmarkets.com", "aria-label": "Go to loafmarkets.com", children: /* @__PURE__ */ jsxRuntime.jsx(GateLogo, { src: logoSrc, alt: logoAlt }) }),
7203
+ /* @__PURE__ */ jsxRuntime.jsx(GateBrandDivider, {}),
7204
+ /* @__PURE__ */ jsxRuntime.jsx(GateBetaTag, { children: "Private Beta" })
7205
+ ] }),
7206
+ /* @__PURE__ */ jsxRuntime.jsxs(GateOtpText, { children: [
7207
+ "We sent a code to",
7208
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
7209
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: email })
7210
+ ] }),
7211
+ /* @__PURE__ */ jsxRuntime.jsx(OTPContainer, { children: otp.map((digit, index) => /* @__PURE__ */ jsxRuntime.jsx(
7212
+ OTPInput,
7213
+ {
7214
+ id: `otp-${index}`,
7215
+ type: "text",
7216
+ inputMode: "numeric",
7217
+ maxLength: 1,
7218
+ $status: otpStatus,
7219
+ readOnly: otpStatus === "valid" || otpStatus === "checking",
7220
+ value: digit,
7221
+ onChange: (event) => handleOTPChange(index, event.target.value),
7222
+ onKeyDown: (event) => handleOTPKeyDown(index, event),
7223
+ onInput: (event) => handleOTPInput(index, event),
7224
+ onPaste: handleOTPPaste,
7225
+ autoComplete: index === 0 ? "one-time-code" : "off",
7226
+ autoFocus: index === 0
7227
+ },
7228
+ index
7229
+ )) }),
7230
+ otpStatus === "invalid" && /* @__PURE__ */ jsxRuntime.jsx(StatusMessage, { $error: true, children: "That code isn't right. Try again." }),
7231
+ /* @__PURE__ */ jsxRuntime.jsxs(GateResendText, { children: [
7232
+ /* @__PURE__ */ jsxRuntime.jsx(
7233
+ "button",
7234
+ {
7235
+ type: "button",
7236
+ onClick: (event) => {
7237
+ event.preventDefault();
7238
+ void handleSendCode(event);
7239
+ },
7240
+ children: "Resend code"
7241
+ }
7242
+ ),
7243
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: " \xB7 " }),
7244
+ /* @__PURE__ */ jsxRuntime.jsx(
7245
+ "button",
7246
+ {
7247
+ type: "button",
7248
+ onClick: () => {
7249
+ setOtp(Array(OTP_INPUT_LENGTH).fill(""));
7250
+ setOtpStatus("idle");
7251
+ setError("");
7252
+ setView("referral");
7253
+ },
7254
+ children: "Back"
7255
+ }
7256
+ )
7257
+ ] })
7258
+ ] })
7259
+ ] });
7260
+ }
7261
+ return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { $transparent: gate, onClick: loading ? void 0 : onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7118
7262
  !loading && /* @__PURE__ */ jsxRuntime.jsx(CloseButton, { onClick: onClose, "aria-label": "Close login popup", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) }),
7119
7263
  loading ? /* @__PURE__ */ jsxRuntime.jsxs(AccountCreationLoader, { children: [
7120
7264
  /* @__PURE__ */ jsxRuntime.jsx(SpinnerRing, {}),
@@ -7334,84 +7478,186 @@ var LoginPopup = ({
7334
7478
  setReferralLoading(false);
7335
7479
  }
7336
7480
  };
7337
- const handleJoinWaitlistSkip = async () => {
7338
- if (!onJoinWaitlist || !email) {
7339
- onClose();
7340
- return;
7481
+ const CODE_PREFIX = "LOAF-";
7482
+ const codeSuffix = referralCode.startsWith(CODE_PREFIX) ? referralCode.slice(CODE_PREFIX.length) : referralCode.replace(/^LOAF-?/i, "");
7483
+ const runCodeValidation = async (fullCode) => {
7484
+ setCodeStatus("checking");
7485
+ setError("");
7486
+ try {
7487
+ const ok = onValidateCode ? await onValidateCode(fullCode) : true;
7488
+ if (!ok) {
7489
+ validatedCodeRef.current = null;
7490
+ setCodeStatus("invalid");
7491
+ return;
7492
+ }
7493
+ validatedCodeRef.current = fullCode;
7494
+ setCodeStatus("valid");
7495
+ if (isAuthenticated) {
7496
+ if (await finishGate()) setTimeout(() => onClose(), 500);
7497
+ return;
7498
+ }
7499
+ setIsSignUp(true);
7500
+ setSignInRevealed(true);
7501
+ } catch {
7502
+ validatedCodeRef.current = null;
7503
+ setCodeStatus("invalid");
7341
7504
  }
7505
+ };
7506
+ const setCodeSuffix = (suffix) => {
7507
+ setReferralCode(CODE_PREFIX + suffix);
7342
7508
  setReferralError("");
7343
- setWaitlistLoading(true);
7344
- try {
7345
- const message = await onJoinWaitlist(email);
7346
- setWaitlistMessage(message || "You're on the waitlist.");
7347
- setTimeout(() => onClose(), 1400);
7348
- } catch (err) {
7349
- setReferralError(err instanceof Error ? err.message : "Couldn't join the waitlist. Please try again.");
7350
- setWaitlistLoading(false);
7509
+ setError("");
7510
+ if (gate) {
7511
+ if (suffix.length === 5) void runCodeValidation(CODE_PREFIX + suffix);
7512
+ else {
7513
+ validatedCodeRef.current = null;
7514
+ setCodeStatus("idle");
7515
+ }
7351
7516
  }
7352
7517
  };
7353
- return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7354
- /* @__PURE__ */ jsxRuntime.jsx(CloseButton, { onClick: onClose, "aria-label": "Close login popup", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) }),
7355
- /* @__PURE__ */ jsxRuntime.jsxs(OnboardingStepContainer, { children: [
7356
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
7357
- width: 52,
7358
- height: 52,
7359
- borderRadius: 14,
7360
- background: "linear-gradient(135deg, rgba(230,200,126,0.15) 0%, rgba(230,200,126,0.08) 100%)",
7361
- border: "1px solid rgba(230,200,126,0.25)",
7362
- display: "flex",
7363
- alignItems: "center",
7364
- justifyContent: "center",
7365
- marginBottom: "1.1rem"
7366
- }, children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "#e6c87e", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round", children: [
7367
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" }),
7368
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "9", cy: "7", r: "4" }),
7369
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M23 21v-2a4 4 0 0 0-3-3.87" }),
7370
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 3.13a4 4 0 0 1 0 7.75" })
7371
- ] }) }),
7372
- /* @__PURE__ */ jsxRuntime.jsx(OnboardingHeading, { children: "Enter code to access Private Beta trading" }),
7373
- /* @__PURE__ */ jsxRuntime.jsx(OnboardingSubtext, { style: { marginBottom: "1.5rem" }, children: "Enter code to trade 100k in USDC, or skip to continue." }),
7374
- /* @__PURE__ */ jsxRuntime.jsxs(EmailFormContainer, { style: { width: "100%", marginBottom: 0 }, children: [
7518
+ const handleCodeChange = (e) => {
7519
+ setCodeSuffix(e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, "").slice(0, 5));
7520
+ };
7521
+ const handleCodePaste = (e) => {
7522
+ e.preventDefault();
7523
+ const text = (e.clipboardData.getData("text") || "").toUpperCase();
7524
+ setCodeSuffix(text.replace(/^LOAF-?/, "").replace(/[^A-Z0-9]/g, "").slice(0, 5));
7525
+ };
7526
+ const codeComplete = codeSuffix.length === 5;
7527
+ const codeInput = /* @__PURE__ */ jsxRuntime.jsx(
7528
+ CodeSuffixInput,
7529
+ {
7530
+ type: "text",
7531
+ inputMode: "text",
7532
+ autoComplete: "off",
7533
+ autoCapitalize: "characters",
7534
+ spellCheck: false,
7535
+ maxLength: 5,
7536
+ "aria-label": "Access code",
7537
+ readOnly: codeStatus === "valid",
7538
+ value: codeSuffix,
7539
+ onChange: handleCodeChange,
7540
+ onPaste: handleCodePaste,
7541
+ onKeyDown: (e) => {
7542
+ if (e.key !== "Enter" || !codeComplete) return;
7543
+ if (gate) void runCodeValidation(referralCode);
7544
+ else void handleReferralSubmit();
7545
+ },
7546
+ autoFocus: true
7547
+ }
7548
+ );
7549
+ const signInStep = /* @__PURE__ */ jsxRuntime.jsxs(GateReveal, { children: [
7550
+ /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSendCode, style: { width: "100%" }, children: [
7551
+ /* @__PURE__ */ jsxRuntime.jsxs(CodeInputWrapper, { children: [
7375
7552
  /* @__PURE__ */ jsxRuntime.jsx(
7376
- EmailInput,
7553
+ GateEmailInput,
7377
7554
  {
7378
- type: "text",
7379
- placeholder: "e.g. LOAF-XXXX",
7380
- value: referralCode,
7381
- onChange: (e) => {
7382
- setReferralCode(e.target.value.toUpperCase());
7383
- setReferralError("");
7384
- },
7385
- onKeyDown: (e) => {
7386
- if (e.key === "Enter") void handleReferralSubmit();
7387
- },
7555
+ type: "email",
7556
+ inputMode: "email",
7557
+ autoComplete: "email",
7558
+ placeholder: "Enter your email",
7559
+ value: email,
7560
+ onChange: (event) => setEmail(event.target.value),
7388
7561
  autoFocus: true
7389
7562
  }
7390
7563
  ),
7391
- /* @__PURE__ */ jsxRuntime.jsx(
7392
- SubmitButton,
7393
- {
7394
- type: "button",
7395
- onClick: () => void handleReferralSubmit(),
7396
- disabled: referralLoading || !referralCode.trim(),
7397
- children: referralLoading ? "Verifying\u2026" : "Apply Code"
7398
- }
7399
- ),
7400
- referralError && /* @__PURE__ */ jsxRuntime.jsx(StatusMessage, { $error: true, children: referralError })
7564
+ /* @__PURE__ */ jsxRuntime.jsx(GateSubmit, { type: "submit", "aria-label": "Continue", disabled: loading || !email, children: loading ? /* @__PURE__ */ jsxRuntime.jsx(GateSpinner, {}) : /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 12h14M13 6l6 6-6 6" }) }) })
7401
7565
  ] }),
7402
- waitlistMessage ? /* @__PURE__ */ jsxRuntime.jsxs(StatusMessage, { style: { marginTop: "0.75rem" }, children: [
7403
- "\u2713 ",
7404
- waitlistMessage
7405
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(
7406
- OnboardingSkipButton,
7566
+ error && /* @__PURE__ */ jsxRuntime.jsx(StatusMessage, { $error: true, children: error })
7567
+ ] }),
7568
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7569
+ /* @__PURE__ */ jsxRuntime.jsx(GateOr, { children: "or" }),
7570
+ /* @__PURE__ */ jsxRuntime.jsxs(GateWalletButton, { type: "button", onClick: handleWalletLogin, children: [
7571
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 18v1c0 1.1-.9 2-2 2H5c-1.11 0-2-.9-2-2V5c0-1.1.89-2 2-2h14c1.1 0 2 .9 2 2v1h-9c-1.11 0-2 .9-2 2v8c0 1.1.89 2 2 2h9zm-9-2h10V8H12v8zm4-2.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" }) }),
7572
+ signInMode ? "Sign in with Wallet" : "Connect Wallet"
7573
+ ] })
7574
+ ] })
7575
+ ] });
7576
+ if (gate) {
7577
+ const codeAccepted = codeStatus === "valid";
7578
+ const showSignIn = signInMode || signInRevealed;
7579
+ return /* @__PURE__ */ jsxRuntime.jsxs(GateShell, { children: [
7580
+ /* @__PURE__ */ jsxRuntime.jsx(GateTint, { $reveal: showSignIn ? 1 : 0 }),
7581
+ /* @__PURE__ */ jsxRuntime.jsxs(GateForm, { children: [
7582
+ /* @__PURE__ */ jsxRuntime.jsxs(GateBrand, { children: [
7583
+ /* @__PURE__ */ jsxRuntime.jsx(GateLogoLink, { href: "https://loafmarkets.com", "aria-label": "Go to loafmarkets.com", children: /* @__PURE__ */ jsxRuntime.jsx(GateLogo, { src: logoSrc, alt: logoAlt }) }),
7584
+ /* @__PURE__ */ jsxRuntime.jsx(GateBrandDivider, {}),
7585
+ /* @__PURE__ */ jsxRuntime.jsx(GateBetaTag, { children: "Private Beta" })
7586
+ ] }),
7587
+ signInMode ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7588
+ signInStep,
7589
+ /* @__PURE__ */ jsxRuntime.jsx(GateResendText, { children: /* @__PURE__ */ jsxRuntime.jsx(
7590
+ "button",
7591
+ {
7592
+ type: "button",
7593
+ onClick: () => {
7594
+ setError("");
7595
+ setSignInMode(false);
7596
+ },
7597
+ children: "\u2190 Enter access code instead"
7598
+ }
7599
+ ) })
7600
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7601
+ /* @__PURE__ */ jsxRuntime.jsxs(CodeInputWrapper, { $status: codeStatus, children: [
7602
+ /* @__PURE__ */ jsxRuntime.jsx(CodePrefix, { children: CODE_PREFIX }),
7603
+ codeInput,
7604
+ /* @__PURE__ */ jsxRuntime.jsx(
7605
+ GateSubmit,
7606
+ {
7607
+ type: "button",
7608
+ "aria-label": "Submit access code",
7609
+ $status: codeStatus,
7610
+ disabled: codeStatus === "checking" || !codeComplete,
7611
+ onClick: () => void runCodeValidation(referralCode),
7612
+ children: codeAccepted ? /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6L9 17l-5-5" }) }) : codeStatus === "checking" ? /* @__PURE__ */ jsxRuntime.jsx(GateSpinner, {}) : /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 12h14M13 6l6 6-6 6" }) })
7613
+ }
7614
+ )
7615
+ ] }),
7616
+ (codeStatus === "invalid" || error && !signInRevealed) && /* @__PURE__ */ jsxRuntime.jsx(StatusMessage, { $error: true, children: error || "That code isn't valid. Double-check and try again." }),
7617
+ signInRevealed ? signInStep : /* @__PURE__ */ jsxRuntime.jsxs(GateResendText, { children: [
7618
+ "Already have an account?",
7619
+ " ",
7620
+ /* @__PURE__ */ jsxRuntime.jsx(
7621
+ "button",
7622
+ {
7623
+ type: "button",
7624
+ onClick: () => {
7625
+ setError("");
7626
+ setIsSignUp(false);
7627
+ setSignInMode(true);
7628
+ },
7629
+ children: "Sign in"
7630
+ }
7631
+ )
7632
+ ] })
7633
+ ] })
7634
+ ] })
7635
+ ] });
7636
+ }
7637
+ return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7638
+ /* @__PURE__ */ jsxRuntime.jsx(CloseButton, { onClick: onClose, "aria-label": "Close login popup", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) }),
7639
+ /* @__PURE__ */ jsxRuntime.jsxs(Title, { children: [
7640
+ /* @__PURE__ */ jsxRuntime.jsxs(LogoContainer3, { children: [
7641
+ /* @__PURE__ */ jsxRuntime.jsx(LogoImage, { src: logoSrc, alt: logoAlt }),
7642
+ /* @__PURE__ */ jsxRuntime.jsx(LogoBeta, { children: "Private Beta" })
7643
+ ] }),
7644
+ /* @__PURE__ */ jsxRuntime.jsx(TitleText, { children: "Enter your access code" })
7645
+ ] }),
7646
+ /* @__PURE__ */ jsxRuntime.jsxs(EmailFormContainer, { style: { width: "100%", marginTop: "1.5rem", marginBottom: 0 }, children: [
7647
+ /* @__PURE__ */ jsxRuntime.jsxs(CodeInputWrapper, { children: [
7648
+ /* @__PURE__ */ jsxRuntime.jsx(CodePrefix, { children: CODE_PREFIX }),
7649
+ codeInput
7650
+ ] }),
7651
+ /* @__PURE__ */ jsxRuntime.jsx(
7652
+ SubmitButton,
7407
7653
  {
7408
7654
  type: "button",
7409
- onClick: () => void handleJoinWaitlistSkip(),
7410
- disabled: waitlistLoading,
7411
- style: { marginTop: "0.75rem" },
7412
- children: waitlistLoading ? "Joining\u2026" : email ? "Skip for now & join Waitlist" : "Skip for now"
7655
+ onClick: () => void handleReferralSubmit(),
7656
+ disabled: referralLoading || !codeComplete,
7657
+ children: referralLoading ? "Verifying\u2026" : "Continue"
7413
7658
  }
7414
- )
7659
+ ),
7660
+ referralError && /* @__PURE__ */ jsxRuntime.jsx(StatusMessage, { $error: true, children: referralError })
7415
7661
  ] })
7416
7662
  ] }) });
7417
7663
  }
@@ -7531,8 +7777,9 @@ var Overlay2 = styled10__default.default.div`
7531
7777
  left: 0;
7532
7778
  right: 0;
7533
7779
  bottom: 0;
7534
- background-color: rgba(0, 0, 0, 0.8);
7535
- backdrop-filter: blur(4px);
7780
+ background-color: ${(props) => props.$gate ? "var(--color-background, #0a0a0a)" : props.$transparent ? "rgba(0, 0, 0, 0.45)" : "rgba(0, 0, 0, 0.8)"};
7781
+ backdrop-filter: ${(props) => props.$gate ? "none" : props.$transparent ? "blur(2px)" : "blur(4px)"};
7782
+ transition: background-color 0.4s ease, backdrop-filter 0.4s ease;
7536
7783
  display: flex;
7537
7784
  justify-content: center;
7538
7785
  align-items: center;
@@ -7549,15 +7796,15 @@ var Overlay2 = styled10__default.default.div`
7549
7796
  }
7550
7797
  `;
7551
7798
  var PopupContainer = styled10__default.default.div`
7552
- background-color: var(--color-background, #0a0a0a);
7553
- border: 1px solid rgba(230, 198, 86, 0.3);
7799
+ background-color: ${(props) => props.$gate ? "transparent" : "var(--color-background, #0a0a0a)"};
7800
+ border: ${(props) => props.$gate ? "none" : "1px solid rgba(230, 198, 86, 0.3)"};
7554
7801
  border-radius: var(--border-radius, 12px);
7555
7802
  padding: 2.5rem;
7556
7803
  max-width: 440px;
7557
7804
  width: 90%;
7558
7805
  position: relative;
7559
7806
  animation: slideUp 0.3s ease-out;
7560
- box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
7807
+ box-shadow: ${(props) => props.$gate ? "none" : "0 10px 30px rgba(0, 0, 0, 0.3)"};
7561
7808
 
7562
7809
  @keyframes slideUp {
7563
7810
  from {
@@ -7858,6 +8105,268 @@ var EmailInput = styled10__default.default.input`
7858
8105
  color: var(--color-text-secondary, #848e9c);
7859
8106
  }
7860
8107
  `;
8108
+ var codeBorderColor = (status, focused) => {
8109
+ if (status === "valid") return "var(--color-positive, #00C076)";
8110
+ if (status === "invalid") return "var(--color-negative, #FF5757)";
8111
+ return focused ? "var(--color-accent, #E6C87E)" : "rgba(230, 198, 86, 0.2)";
8112
+ };
8113
+ var CodeInputWrapper = styled10__default.default.div`
8114
+ display: flex;
8115
+ align-items: center;
8116
+ width: 100%;
8117
+ padding: 1rem 1.25rem;
8118
+ background-color: var(--color-background-light, #1a1a1a);
8119
+ border: 1px solid ${(props) => codeBorderColor(props.$status, false)};
8120
+ border-radius: var(--border-radius, 8px);
8121
+ box-shadow: ${(props) => props.$status === "valid" ? "0 0 0 1px var(--color-positive, #00C076)" : props.$status === "invalid" ? "0 0 0 1px var(--color-negative, #FF5757)" : "none"};
8122
+ transition: all 0.2s ease;
8123
+
8124
+ &:focus-within {
8125
+ border-color: ${(props) => codeBorderColor(props.$status, true)};
8126
+ }
8127
+ `;
8128
+ var CodePrefix = styled10__default.default.span`
8129
+ color: var(--color-text-secondary, #848e9c);
8130
+ font-size: 1.1rem;
8131
+ font-weight: 600;
8132
+ letter-spacing: 0.22em;
8133
+ font-family: 'Space Grotesk', monospace;
8134
+ user-select: none;
8135
+ `;
8136
+ var CodeSuffixInput = styled10__default.default.input`
8137
+ flex: 1;
8138
+ min-width: 0;
8139
+ border: none;
8140
+ background: transparent;
8141
+ color: var(--color-text, #eaecef);
8142
+ font-size: 1.1rem;
8143
+ font-weight: 600;
8144
+ letter-spacing: 0.22em;
8145
+ text-transform: uppercase;
8146
+ font-family: 'Space Grotesk', monospace;
8147
+
8148
+ &:focus {
8149
+ outline: none;
8150
+ }
8151
+
8152
+ &::placeholder {
8153
+ color: rgba(132, 142, 156, 0.45);
8154
+ letter-spacing: 0.22em;
8155
+ }
8156
+ `;
8157
+ var GateBrand = styled10__default.default.div`
8158
+ display: flex;
8159
+ align-items: center;
8160
+ justify-content: center;
8161
+ gap: 0.7rem;
8162
+ margin-bottom: 0.6rem;
8163
+ `;
8164
+ var GateLogoLink = styled10__default.default.a`
8165
+ display: inline-flex;
8166
+ align-items: center;
8167
+ cursor: pointer;
8168
+ transition: opacity 0.15s ease;
8169
+
8170
+ &:hover {
8171
+ opacity: 0.85;
8172
+ }
8173
+ `;
8174
+ var GateLogo = styled10__default.default.img`
8175
+ height: 44px;
8176
+ display: block;
8177
+ `;
8178
+ var GateBrandDivider = styled10__default.default.span`
8179
+ width: 1px;
8180
+ height: 26px;
8181
+ background: rgba(255, 255, 255, 0.18);
8182
+ `;
8183
+ var GateBetaTag = styled10__default.default.span`
8184
+ color: var(--color-text-secondary, #848e9c);
8185
+ font-size: 0.8rem;
8186
+ font-weight: 500;
8187
+ letter-spacing: 0.28em;
8188
+ text-transform: uppercase;
8189
+ `;
8190
+ var GateForm = styled10__default.default.div`
8191
+ display: flex;
8192
+ flex-direction: column;
8193
+ align-items: center;
8194
+ gap: 0.9rem;
8195
+ width: 100%;
8196
+ max-width: 360px;
8197
+ position: relative;
8198
+ z-index: 1;
8199
+ `;
8200
+ var GateShell = styled10__default.default.div`
8201
+ position: fixed;
8202
+ inset: 0;
8203
+ display: flex;
8204
+ align-items: center;
8205
+ justify-content: center;
8206
+ z-index: 10000;
8207
+ background-color: rgba(10, 10, 12, 0.66);
8208
+ animation: gateFade 0.25s ease-in-out;
8209
+
8210
+ @keyframes gateFade {
8211
+ from { opacity: 0; }
8212
+ to { opacity: 1; }
8213
+ }
8214
+ `;
8215
+ var GateTint = styled10__default.default.div`
8216
+ position: absolute;
8217
+ left: 0;
8218
+ right: 0;
8219
+ bottom: 0;
8220
+ height: calc(${(props) => (3 - Math.max(0, Math.min(3, props.$reveal))) / 3 * 100}% + 90px);
8221
+ background: linear-gradient(
8222
+ to top,
8223
+ var(--color-background, #0a0a0c) calc(100% - 90px),
8224
+ rgba(10, 10, 12, 0) 100%
8225
+ );
8226
+ transition: height 0.65s ease;
8227
+ pointer-events: none;
8228
+ `;
8229
+ var GateOtpText = styled10__default.default.p`
8230
+ margin: 0;
8231
+ text-align: center;
8232
+ font-size: 0.9rem;
8233
+ line-height: 1.5;
8234
+ color: var(--color-text-secondary, #848e9c);
8235
+
8236
+ strong {
8237
+ color: var(--color-text, #eaecef);
8238
+ font-weight: 600;
8239
+ }
8240
+ `;
8241
+ var GateResendText = styled10__default.default.p`
8242
+ margin: 0.2rem 0 0;
8243
+ font-size: 0.85rem;
8244
+ color: var(--color-text-secondary, #848e9c);
8245
+
8246
+ button {
8247
+ background: none;
8248
+ border: none;
8249
+ color: var(--color-accent, #E6C87E);
8250
+ cursor: pointer;
8251
+ text-decoration: underline;
8252
+ font-size: inherit;
8253
+ }
8254
+ `;
8255
+ var GateSubmit = styled10__default.default.button`
8256
+ display: flex;
8257
+ align-items: center;
8258
+ justify-content: center;
8259
+ flex-shrink: 0;
8260
+ width: 28px;
8261
+ height: 28px;
8262
+ margin-left: 0.5rem;
8263
+ padding: 0;
8264
+ background: none;
8265
+ border: none;
8266
+ cursor: pointer;
8267
+ color: ${(props) => props.$status === "valid" ? "var(--color-positive, #00C076)" : props.$status === "invalid" ? "var(--color-negative, #FF5757)" : "var(--color-accent, #E6C87E)"};
8268
+ transition: color 0.15s ease, transform 0.15s ease, opacity 0.15s ease;
8269
+
8270
+ &:not(:disabled):hover {
8271
+ transform: translateX(2px);
8272
+ }
8273
+
8274
+ &:disabled {
8275
+ opacity: ${(props) => props.$status === "valid" ? 1 : 0.35};
8276
+ color: ${(props) => props.$status === "valid" ? "var(--color-positive, #00C076)" : "var(--color-text-secondary, #848e9c)"};
8277
+ cursor: default;
8278
+ }
8279
+ `;
8280
+ var GateEmailInput = styled10__default.default.input`
8281
+ flex: 1;
8282
+ min-width: 0;
8283
+ border: none;
8284
+ background: transparent;
8285
+ color: var(--color-text, #eaecef);
8286
+ font-size: 1rem;
8287
+
8288
+ &:focus {
8289
+ outline: none;
8290
+ }
8291
+
8292
+ &::placeholder {
8293
+ color: rgba(132, 142, 156, 0.5);
8294
+ }
8295
+ `;
8296
+ var GateSpinner = styled10__default.default.span`
8297
+ width: 18px;
8298
+ height: 18px;
8299
+ border: 2px solid rgba(230, 198, 86, 0.3);
8300
+ border-top-color: var(--color-accent, #E6C87E);
8301
+ border-radius: 50%;
8302
+ animation: gateSpin 0.7s linear infinite;
8303
+
8304
+ @keyframes gateSpin {
8305
+ to { transform: rotate(360deg); }
8306
+ }
8307
+ `;
8308
+ var GateOr = styled10__default.default.div`
8309
+ display: flex;
8310
+ align-items: center;
8311
+ gap: 0.6rem;
8312
+ width: 100%;
8313
+ color: var(--color-text-secondary, #848e9c);
8314
+ font-size: 0.78rem;
8315
+ text-transform: lowercase;
8316
+
8317
+ &::before,
8318
+ &::after {
8319
+ content: "";
8320
+ flex: 1;
8321
+ height: 1px;
8322
+ background: rgba(255, 255, 255, 0.1);
8323
+ }
8324
+ `;
8325
+ var GateWalletButton = styled10__default.default.button`
8326
+ display: inline-flex;
8327
+ align-items: center;
8328
+ justify-content: center;
8329
+ gap: 0.5rem;
8330
+ margin-top: 0.1rem;
8331
+ padding: 0.55rem 1.1rem;
8332
+ background: transparent;
8333
+ border: 1px solid rgba(255, 255, 255, 0.12);
8334
+ border-radius: var(--border-radius, 8px);
8335
+ color: var(--color-text-secondary, #848e9c);
8336
+ font-size: 0.85rem;
8337
+ font-weight: 500;
8338
+ cursor: pointer;
8339
+ transition: border-color 0.15s ease, color 0.15s ease;
8340
+
8341
+ svg {
8342
+ width: 16px;
8343
+ height: 16px;
8344
+ }
8345
+
8346
+ &:hover {
8347
+ border-color: rgba(230, 198, 86, 0.4);
8348
+ color: var(--color-text, #eaecef);
8349
+ }
8350
+ `;
8351
+ var GateReveal = styled10__default.default.div`
8352
+ display: flex;
8353
+ flex-direction: column;
8354
+ align-items: center;
8355
+ gap: 0.9rem;
8356
+ width: 100%;
8357
+ animation: gateReveal 0.3s ease-out;
8358
+
8359
+ @keyframes gateReveal {
8360
+ from {
8361
+ opacity: 0;
8362
+ transform: translateY(-6px);
8363
+ }
8364
+ to {
8365
+ opacity: 1;
8366
+ transform: translateY(0);
8367
+ }
8368
+ }
8369
+ `;
7861
8370
  var OTPContainer = styled10__default.default.div`
7862
8371
  display: flex;
7863
8372
  gap: 0.5rem;
@@ -7870,15 +8379,17 @@ var OTPInput = styled10__default.default.input`
7870
8379
  font-size: 1.5rem;
7871
8380
  font-weight: 600;
7872
8381
  background-color: var(--color-background-light, #1a1a1a);
7873
- border: 1px solid rgba(230, 198, 86, 0.2);
8382
+ border: 1px solid ${(props) => codeBorderColor(props.$status, false)};
7874
8383
  border-radius: var(--border-radius, 8px);
7875
- color: var(--color-accent, #E6C87E);
8384
+ color: ${(props) => props.$status === "valid" ? "var(--color-positive, #00C076)" : props.$status === "invalid" ? "var(--color-negative, #FF5757)" : "var(--color-accent, #E6C87E)"};
8385
+ box-shadow: ${(props) => props.$status === "valid" ? "0 0 0 1px var(--color-positive, #00C076)" : props.$status === "invalid" ? "0 0 0 1px var(--color-negative, #FF5757)" : "none"};
8386
+ opacity: ${(props) => props.$status === "checking" ? 0.6 : 1};
7876
8387
  transition: all 0.2s ease;
7877
8388
 
7878
8389
  &:focus {
7879
8390
  outline: none;
7880
- border-color: var(--color-accent, #E6C87E);
7881
- box-shadow: 0 0 0 2px rgba(230, 198, 86, 0.2);
8391
+ border-color: ${(props) => codeBorderColor(props.$status, true)};
8392
+ box-shadow: 0 0 0 2px ${(props) => props.$status === "valid" ? "rgba(0, 192, 118, 0.25)" : props.$status === "invalid" ? "rgba(255, 87, 87, 0.25)" : "rgba(230, 198, 86, 0.2)"};
7882
8393
  }
7883
8394
  `;
7884
8395
  var SubmitButton = styled10__default.default.button`