@loafmarkets/ui 0.1.384 → 0.1.385

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
@@ -1900,6 +1900,7 @@ var Orderbook = React5__namespace.forwardRef(
1900
1900
  amountPrecision = 2,
1901
1901
  defaultTab = "orderbook",
1902
1902
  onTabChange,
1903
+ showTradesTab = true,
1903
1904
  rightHeader,
1904
1905
  variant = "auto",
1905
1906
  userOrderPrices,
@@ -1913,7 +1914,9 @@ var Orderbook = React5__namespace.forwardRef(
1913
1914
  ...props
1914
1915
  }, ref) => {
1915
1916
  const resolvedRightHeader = rightHeader ?? /* @__PURE__ */ jsxRuntime.jsx(LoafLiquidityBadge, { className: "text-[0.6rem] orderbook-ll-badge", onClick: onLoafLiquidityClick });
1916
- const [tab, setTab] = React5__namespace.useState(defaultTab);
1917
+ const [tab, setTabState] = React5__namespace.useState(defaultTab);
1918
+ const setTab = setTabState;
1919
+ const effectiveTab = showTradesTab ? tab : "orderbook";
1917
1920
  const [tradeFilter, setTradeFilter] = React5__namespace.useState("all");
1918
1921
  const viewportCompact = useViewportCompact(COMPACT_BREAKPOINT_PX);
1919
1922
  const { userAskPrices, userBidPrices } = React5__namespace.useMemo(() => {
@@ -2007,7 +2010,8 @@ var Orderbook = React5__namespace.forwardRef(
2007
2010
  const midClass = midChangePercent == null ? "text-white" : midChangePercent >= 0 ? "text-[#0ecb81]" : "text-[#f6465d]";
2008
2011
  const tradeFiltered = trades.filter((t) => tradeFilter === "all" || t.type === tradeFilter);
2009
2012
  const layoutProps = {
2010
- tab,
2013
+ tab: effectiveTab,
2014
+ showTradesTab,
2011
2015
  handleTab,
2012
2016
  tradeFilter,
2013
2017
  setTradeFilter,
@@ -2084,6 +2088,7 @@ function SkeletonRow({ compact }) {
2084
2088
  }
2085
2089
  function DesktopOrderbookLayout({
2086
2090
  tab,
2091
+ showTradesTab = true,
2087
2092
  handleTab,
2088
2093
  tradeFilter,
2089
2094
  setTradeFilter,
@@ -2133,7 +2138,7 @@ function DesktopOrderbookLayout({
2133
2138
  ]
2134
2139
  }
2135
2140
  ),
2136
- /* @__PURE__ */ jsxRuntime.jsxs(
2141
+ showTradesTab ? /* @__PURE__ */ jsxRuntime.jsxs(
2137
2142
  "button",
2138
2143
  {
2139
2144
  type: "button",
@@ -2147,7 +2152,7 @@ function DesktopOrderbookLayout({
2147
2152
  tab === "trades" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -bottom-px left-0 h-[2px] w-full bg-[#E6C87E]" }) : null
2148
2153
  ]
2149
2154
  }
2150
- )
2155
+ ) : null
2151
2156
  ] }),
2152
2157
  tab === "trades" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 text-xs", children: [
2153
2158
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -2286,6 +2291,7 @@ function DesktopOrderbookLayout({
2286
2291
  }
2287
2292
  function MobileOrderbookLayout({
2288
2293
  tab,
2294
+ showTradesTab = true,
2289
2295
  handleTab,
2290
2296
  tradeFilter,
2291
2297
  setTradeFilter,
@@ -2334,7 +2340,7 @@ function MobileOrderbookLayout({
2334
2340
  children: "Orderbook"
2335
2341
  }
2336
2342
  ),
2337
- /* @__PURE__ */ jsxRuntime.jsx(
2343
+ showTradesTab ? /* @__PURE__ */ jsxRuntime.jsx(
2338
2344
  "span",
2339
2345
  {
2340
2346
  onClick: () => handleTab("trades"),
@@ -2348,7 +2354,7 @@ function MobileOrderbookLayout({
2348
2354
  },
2349
2355
  children: "Trades"
2350
2356
  }
2351
- )
2357
+ ) : null
2352
2358
  ] }),
2353
2359
  tab === "trades" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 text-[0.6rem] text-white/70", children: ["all", "buy", "sell"].map((filter) => /* @__PURE__ */ jsxRuntime.jsx(
2354
2360
  "button",
@@ -5036,9 +5042,9 @@ var PulsingDot = styled10__default.default.span`
5036
5042
  `;
5037
5043
  function fmtCompactUsd(n) {
5038
5044
  const abs = Math.abs(n);
5039
- if (abs >= 1e6) return `$${(abs / 1e6).toFixed(2)}M`;
5040
- if (abs >= 1e3) return `$${(abs / 1e3).toFixed(1)}K`;
5041
- return `$${abs.toFixed(2)}`;
5045
+ if (abs >= 1e6) return `${(abs / 1e6).toFixed(2)}M`;
5046
+ if (abs >= 1e3) return `${(abs / 1e3).toFixed(1)}K`;
5047
+ return `${abs.toFixed(2)}`;
5042
5048
  }
5043
5049
  function useIsNarrow(maxWidthPx = 768) {
5044
5050
  const query = `(max-width:${maxWidthPx}px)`;
@@ -5389,7 +5395,7 @@ var Header = ({
5389
5395
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5390
5396
  /* @__PURE__ */ jsxRuntime.jsx(SafeAreaCover, {}),
5391
5397
  /* @__PURE__ */ jsxRuntime.jsx(Overlay, { $isOpen: isMobileMenuOpen, onClick: () => setIsMobileMenuOpen(false) }),
5392
- /* @__PURE__ */ jsxRuntime.jsxs(HeaderContainer, { id: "loaf-header", $bgOpacity: headerBgOpacity, children: [
5398
+ /* @__PURE__ */ jsxRuntime.jsxs(HeaderContainer, { id: "loaf-header", $bgOpacity: headerBgOpacity, $menuOpen: isMobileMenuOpen, children: [
5393
5399
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [
5394
5400
  /* @__PURE__ */ jsxRuntime.jsxs(Logo, { children: [
5395
5401
  /* @__PURE__ */ jsxRuntime.jsx(LogoLink, { href: logoHref ?? resolvedHomePath, onClick: handleLogoNavigation, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: Loaf_logo_Banner_default, alt: "LOAF Logo" }) }),
@@ -5865,7 +5871,8 @@ var Overlay = styled10__default.default.div`
5865
5871
  height: 100%;
5866
5872
  background-color: rgba(0, 0, 0, 0.7);
5867
5873
  backdrop-filter: blur(3px);
5868
- z-index: 970;
5874
+ /* Above the trade page's sticky/console layers (z 2000) + close modal (10001). */
5875
+ z-index: 10070;
5869
5876
  `;
5870
5877
  var MobileOnlyButton = styled10__default.default.button.attrs({ type: "button" })`
5871
5878
  display: none;
@@ -5913,7 +5920,11 @@ var HeaderContainer = styled10__default.default.header`
5913
5920
  top: 0;
5914
5921
  left: 0;
5915
5922
  right: 0;
5916
- z-index: 1000;
5923
+ /* Normally 1000. When the mobile menu is open, lift the whole header
5924
+ (and the Nav drawer trapped inside its stacking context) above the
5925
+ backdrop Overlay (10070) AND the trade page's modal layers (10001) so
5926
+ the drawer renders on top instead of being dimmed by the backdrop. */
5927
+ z-index: ${({ $menuOpen }) => $menuOpen ? 10075 : 1e3};
5917
5928
  width: 100%;
5918
5929
  /* Fallback min-height for browsers that can't evaluate calc+env */
5919
5930
  min-height: 56px;
@@ -6007,7 +6018,8 @@ var Nav = styled10__default.default.nav`
6007
6018
  max-width: 100%;
6008
6019
  height: calc(100dvh - var(--loaf-menu-top, calc(56px + max(env(safe-area-inset-top, 0px), var(--telegram-safe-top, 0px)))));
6009
6020
  background: rgb(17, 17, 19);
6010
- z-index: 980;
6021
+ /* Above the trade page's sticky/console layers (z 2000) + close modal (10001). */
6022
+ z-index: 10080;
6011
6023
  /* Gentle fade + slide-down instead of an abrupt slide-in. */
6012
6024
  opacity: ${(props) => props.$isOpen ? "1" : "0"};
6013
6025
  transform: ${(props) => props.$isOpen ? "translateY(0)" : "translateY(-14px)"};
@@ -6025,9 +6037,12 @@ var Nav = styled10__default.default.nav`
6025
6037
  display: flex;
6026
6038
  flex-direction: column;
6027
6039
  align-items: center;
6028
- justify-content: center;
6040
+ /* safe-center keeps centering when the menu fits, but top-aligns (honouring the
6041
+ 2.5rem top padding) when the logged-in menu overflows — otherwise flex
6042
+ centering pushes the first item + padding above the scroll area and clips it. */
6043
+ justify-content: safe center;
6029
6044
  min-height: 100%;
6030
- padding: 2rem 1.5rem 2.5rem;
6045
+ padding: 2.5rem 1.5rem 2.5rem;
6031
6046
  gap: 0.4rem;
6032
6047
  }
6033
6048
  }
@@ -6737,6 +6752,17 @@ PropertySubheader.displayName = "PropertySubheader";
6737
6752
  var DEFAULT_LOGO_SRC = Loaf_logo_Banner_default;
6738
6753
  var DEFAULT_LOGO_ALT = "Loaf";
6739
6754
  var OTP_INPUT_LENGTH = 6;
6755
+ var CODE_PREFIX = "LOAF-";
6756
+ var CODE_SUFFIX_LEN = 5;
6757
+ var normalizeAccessCode = (raw) => CODE_PREFIX + raw.toUpperCase().replace(/^LOAF-?/, "").replace(/[^A-Z0-9]/g, "").slice(0, CODE_SUFFIX_LEN);
6758
+ var friendlyError = (err, fallback) => {
6759
+ const data = err?.response?.data;
6760
+ if (typeof data?.error === "string" && data.error.trim()) return data.error;
6761
+ if (typeof data?.message === "string" && data.message.trim()) return data.message;
6762
+ const msg = err instanceof Error ? err.message : "";
6763
+ if (msg && !/request failed with status code/i.test(msg) && !/network error/i.test(msg)) return msg;
6764
+ return fallback;
6765
+ };
6740
6766
  var LoginPopup = ({
6741
6767
  onClose,
6742
6768
  onOpenEarlyAccess,
@@ -6755,10 +6781,13 @@ var LoginPopup = ({
6755
6781
  renderKycWidget,
6756
6782
  onFundWallet,
6757
6783
  initialView,
6784
+ initialCode,
6758
6785
  kycStatus: kycStatusProp,
6759
6786
  walletAddress,
6760
6787
  onSubmitReferralCode,
6761
- onJoinWaitlist
6788
+ onValidateCode,
6789
+ onCheckAccess,
6790
+ gate
6762
6791
  }) => {
6763
6792
  const [view, setView] = React5.useState(() => initialView ?? "main");
6764
6793
  const [email, setEmail] = React5.useState("");
@@ -6766,19 +6795,17 @@ var LoginPopup = ({
6766
6795
  const [otp, setOtp] = React5.useState(Array(OTP_INPUT_LENGTH).fill(""));
6767
6796
  const [error, setError] = React5.useState("");
6768
6797
  const [copied, setCopied] = React5.useState(false);
6769
- const [referralCode, setReferralCode] = React5.useState("");
6798
+ const [referralCode, setReferralCode] = React5.useState(
6799
+ () => gate && initialCode ? normalizeAccessCode(initialCode) : ""
6800
+ );
6770
6801
  const [referralLoading, setReferralLoading] = React5.useState(false);
6771
6802
  const [referralError, setReferralError] = React5.useState("");
6772
- const [waitlistLoading, setWaitlistLoading] = React5.useState(false);
6773
- const [waitlistMessage, setWaitlistMessage] = React5.useState("");
6803
+ const [codeStatus, setCodeStatus] = React5.useState("idle");
6804
+ const [signInRevealed, setSignInRevealed] = React5.useState(false);
6805
+ const [otpStatus, setOtpStatus] = React5.useState("idle");
6806
+ const [signInMode, setSignInMode] = React5.useState(false);
6774
6807
  const [loading, setLoading] = React5.useState(false);
6775
6808
  const [isSignUp, setIsSignUp] = React5.useState(false);
6776
- const [loginTitle] = React5.useState(() => {
6777
- if (typeof window === "undefined") return null;
6778
- const t = window.__LOAF_LOGIN_TITLE__ ?? null;
6779
- if (t) delete window.__LOAF_LOGIN_TITLE__;
6780
- return t;
6781
- });
6782
6809
  const [fundingAmount] = React5.useState("");
6783
6810
  const [kycLoading, setKycLoading] = React5.useState(false);
6784
6811
  const [showKycWidget, setShowKycWidget] = React5.useState(false);
@@ -6788,6 +6815,64 @@ var LoginPopup = ({
6788
6815
  const [fundingError, setFundingError] = React5.useState("");
6789
6816
  const [transakWidgetUrl, setTransakWidgetUrl] = React5.useState(null);
6790
6817
  const suppressAutoCloseRef = React5__namespace.default.useRef(false);
6818
+ const validatedCodeRef = React5__namespace.default.useRef(null);
6819
+ const finishGate = React5__namespace.default.useCallback(async () => {
6820
+ if (!gate) return true;
6821
+ const code = validatedCodeRef.current;
6822
+ if (code) {
6823
+ try {
6824
+ await onSubmitReferralCode?.(code);
6825
+ window.dispatchEvent(new CustomEvent("loaf:onboarding-start"));
6826
+ return true;
6827
+ } catch {
6828
+ }
6829
+ }
6830
+ const hasAccess = onCheckAccess ? await onCheckAccess() : true;
6831
+ if (hasAccess) return true;
6832
+ suppressAutoCloseRef.current = true;
6833
+ validatedCodeRef.current = null;
6834
+ setOtp(Array(OTP_INPUT_LENGTH).fill(""));
6835
+ setOtpStatus("idle");
6836
+ setSignInMode(false);
6837
+ setSignInRevealed(false);
6838
+ setCodeStatus(code ? "invalid" : "idle");
6839
+ setView("referral");
6840
+ setError(
6841
+ code ? "That code can't be redeemed anymore. Enter a different access code." : "Enter your access code to continue."
6842
+ );
6843
+ return false;
6844
+ }, [gate, onSubmitReferralCode, onCheckAccess]);
6845
+ const runCodeValidation = React5__namespace.default.useCallback(async (fullCode) => {
6846
+ setCodeStatus("checking");
6847
+ setError("");
6848
+ try {
6849
+ const ok = onValidateCode ? await onValidateCode(fullCode) : true;
6850
+ if (!ok) {
6851
+ validatedCodeRef.current = null;
6852
+ setCodeStatus("invalid");
6853
+ return;
6854
+ }
6855
+ validatedCodeRef.current = fullCode;
6856
+ setCodeStatus("valid");
6857
+ if (isAuthenticated) {
6858
+ if (await finishGate()) setTimeout(() => onClose(), 500);
6859
+ return;
6860
+ }
6861
+ setIsSignUp(true);
6862
+ setSignInRevealed(true);
6863
+ } catch {
6864
+ validatedCodeRef.current = null;
6865
+ setCodeStatus("invalid");
6866
+ }
6867
+ }, [onValidateCode, isAuthenticated, finishGate, onClose]);
6868
+ const autoCodeTriedRef = React5__namespace.default.useRef(false);
6869
+ React5.useEffect(() => {
6870
+ if (autoCodeTriedRef.current || !gate || !initialCode) return;
6871
+ const full = normalizeAccessCode(initialCode);
6872
+ if (full.length !== CODE_PREFIX.length + CODE_SUFFIX_LEN) return;
6873
+ autoCodeTriedRef.current = true;
6874
+ void runCodeValidation(full);
6875
+ }, [gate, initialCode, runCodeValidation]);
6791
6876
  React5.useEffect(() => {
6792
6877
  if (typeof initialView === "string") {
6793
6878
  setView(initialView);
@@ -6842,11 +6927,11 @@ var LoginPopup = ({
6842
6927
  }, [autoCloseOnAuth, currentUser, isAuthenticated, onClose, view]);
6843
6928
  React5.useEffect(() => {
6844
6929
  const handleEsc = (e) => {
6845
- if (e.key === "Escape") onClose();
6930
+ if (e.key === "Escape" && !gate) onClose();
6846
6931
  };
6847
6932
  window.addEventListener("keydown", handleEsc);
6848
6933
  return () => window.removeEventListener("keydown", handleEsc);
6849
- }, [onClose]);
6934
+ }, [onClose, gate]);
6850
6935
  const handleWalletLogin = async () => {
6851
6936
  if (onWalletLogin) {
6852
6937
  suppressAutoCloseRef.current = true;
@@ -6858,12 +6943,16 @@ var LoginPopup = ({
6858
6943
  setView("wallet-handle");
6859
6944
  return;
6860
6945
  }
6861
- suppressAutoCloseRef.current = false;
6862
- onClose();
6946
+ if (await finishGate()) {
6947
+ suppressAutoCloseRef.current = false;
6948
+ onClose();
6949
+ }
6863
6950
  return;
6864
6951
  } catch (err) {
6865
6952
  console.error("[LoginTrace][Popup] Wallet login failed", err);
6866
6953
  suppressAutoCloseRef.current = false;
6954
+ setError(friendlyError(err, "Wallet login failed. Please try again."));
6955
+ return;
6867
6956
  }
6868
6957
  }
6869
6958
  onClose();
@@ -6885,6 +6974,13 @@ var LoginPopup = ({
6885
6974
  setError("");
6886
6975
  try {
6887
6976
  await onWalletSignup(handle.trim());
6977
+ if (gate) {
6978
+ if (await finishGate()) {
6979
+ suppressAutoCloseRef.current = false;
6980
+ onClose();
6981
+ }
6982
+ return;
6983
+ }
6888
6984
  if (onSubmitReferralCode) {
6889
6985
  setView("referral");
6890
6986
  } else {
@@ -6896,6 +6992,11 @@ var LoginPopup = ({
6896
6992
  setLoading(false);
6897
6993
  }
6898
6994
  };
6995
+ const handleEmailClick = (signUp = false) => {
6996
+ setIsSignUp(signUp);
6997
+ setView("email");
6998
+ setError("");
6999
+ };
6899
7000
  const handleSendCode = async (event) => {
6900
7001
  event?.preventDefault();
6901
7002
  if (!email || !email.includes("@")) {
@@ -6908,6 +7009,7 @@ var LoginPopup = ({
6908
7009
  }
6909
7010
  setLoading(true);
6910
7011
  setError("");
7012
+ setOtpStatus("idle");
6911
7013
  const normalizedHandle = isSignUp && handle.trim() ? handle.trim() : void 0;
6912
7014
  try {
6913
7015
  const demoResult = await onDemoLogin?.(email, normalizedHandle ?? null);
@@ -6928,11 +7030,15 @@ var LoginPopup = ({
6928
7030
  setView("otp");
6929
7031
  setOtp(Array(OTP_INPUT_LENGTH).fill(""));
6930
7032
  } catch (err) {
6931
- const message = err instanceof Error ? err.message : "Failed to send verification code";
7033
+ const message = friendlyError(err, "We couldn't send a code to that email. Please double-check it and try again.");
6932
7034
  console.error("[LoginTrace][Popup] onSendEmailCode threw", err);
6933
7035
  if (!isSignUp && message.includes("No account found")) {
7036
+ if (signInMode) {
7037
+ setError("No account found for this email. Go back and enter your access code to create one.");
7038
+ setLoading(false);
7039
+ return;
7040
+ }
6934
7041
  setIsSignUp(true);
6935
- setView("email");
6936
7042
  setError("");
6937
7043
  setLoading(false);
6938
7044
  return;
@@ -6944,7 +7050,7 @@ var LoginPopup = ({
6944
7050
  setView("otp");
6945
7051
  setOtp(Array(OTP_INPUT_LENGTH).fill(""));
6946
7052
  } catch (retryErr) {
6947
- setError(retryErr instanceof Error ? retryErr.message : "Failed to send verification code");
7053
+ setError(friendlyError(retryErr, "We couldn't send a code to that email. Please try again."));
6948
7054
  }
6949
7055
  setLoading(false);
6950
7056
  return;
@@ -7038,6 +7144,30 @@ var LoginPopup = ({
7038
7144
  setLoading(false);
7039
7145
  }
7040
7146
  };
7147
+ const runGateOtpVerify = React5__namespace.default.useCallback(async (code) => {
7148
+ if (!onVerifyEmailCode) return;
7149
+ setOtpStatus("checking");
7150
+ setError("");
7151
+ suppressAutoCloseRef.current = true;
7152
+ try {
7153
+ await onVerifyEmailCode({ code, email });
7154
+ if (await finishGate()) {
7155
+ setOtpStatus("valid");
7156
+ setTimeout(() => onClose(), 750);
7157
+ }
7158
+ } catch {
7159
+ suppressAutoCloseRef.current = false;
7160
+ setOtpStatus("invalid");
7161
+ }
7162
+ }, [onVerifyEmailCode, email, finishGate, onClose]);
7163
+ React5.useEffect(() => {
7164
+ if (!gate || view !== "otp") return;
7165
+ if (otp.join("").length < OTP_INPUT_LENGTH) {
7166
+ if (otpStatus === "invalid") setOtpStatus("idle");
7167
+ return;
7168
+ }
7169
+ if (otpStatus === "idle") void runGateOtpVerify(otp.join(""));
7170
+ }, [gate, view, otp, otpStatus, runGateOtpVerify]);
7041
7171
  const handleKycWidgetResult = (result) => {
7042
7172
  setShowKycWidget(false);
7043
7173
  if (result.passed) {
@@ -7134,35 +7264,36 @@ var LoginPopup = ({
7134
7264
  setError("");
7135
7265
  };
7136
7266
  if (view === "main") {
7137
- return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7267
+ return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { $transparent: gate, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7138
7268
  /* @__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" }) }) }),
7139
- /* @__PURE__ */ jsxRuntime.jsx(MainHeading, { children: loginTitle?.title ?? "Welcome to Loaf" }),
7140
- (loginTitle ? loginTitle.subtitle : "Sign in to claim 100k in test USD.") && /* @__PURE__ */ jsxRuntime.jsx(MainSubtitle, { children: loginTitle ? loginTitle.subtitle : "Sign in to claim 100k in test USD." }),
7141
- /* @__PURE__ */ jsxRuntime.jsxs(GateForm, { onSubmit: handleSendCode, children: [
7142
- /* @__PURE__ */ jsxRuntime.jsxs(GateInputRow, { children: [
7143
- /* @__PURE__ */ jsxRuntime.jsx(
7144
- GateInput,
7145
- {
7146
- type: "email",
7147
- placeholder: "Enter your email",
7148
- value: email,
7149
- onChange: (event) => setEmail(event.target.value),
7150
- autoFocus: true
7151
- }
7152
- ),
7153
- /* @__PURE__ */ jsxRuntime.jsx(GateSubmit, { type: "submit", disabled: loading || !email, "aria-label": "Continue with email", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 12h14M13 6l6 6-6 6" }) }) })
7269
+ /* @__PURE__ */ jsxRuntime.jsxs(Title, { children: [
7270
+ /* @__PURE__ */ jsxRuntime.jsxs(LogoContainer3, { children: [
7271
+ /* @__PURE__ */ jsxRuntime.jsx(LogoImage, { src: logoSrc, alt: logoAlt }),
7272
+ /* @__PURE__ */ jsxRuntime.jsx(LogoBeta, { children: "Private Beta" })
7154
7273
  ] }),
7155
- error && /* @__PURE__ */ jsxRuntime.jsx(StatusMessage, { $error: true, children: error })
7274
+ /* @__PURE__ */ jsxRuntime.jsx(TitleText, { children: "Welcome to Loaf" })
7156
7275
  ] }),
7157
- /* @__PURE__ */ jsxRuntime.jsx(GateOr, { children: "or" }),
7158
- /* @__PURE__ */ jsxRuntime.jsxs(LoginButton, { onClick: handleWalletLogin, children: [
7159
- /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/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" }) }),
7160
- "Join with wallet"
7276
+ /* @__PURE__ */ jsxRuntime.jsx(Subtitle, { children: "Sign in to claim 100k in test USD." }),
7277
+ /* @__PURE__ */ jsxRuntime.jsxs(ButtonsContainer, { children: [
7278
+ /* @__PURE__ */ jsxRuntime.jsxs(LoginButton, { onClick: () => handleEmailClick(false), children: [
7279
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z" }) }),
7280
+ "Sign in with Email"
7281
+ ] }),
7282
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "center", color: "var(--color-text-secondary, #848e9c)", fontSize: "0.875rem" }, children: "or" }),
7283
+ /* @__PURE__ */ jsxRuntime.jsxs(LoginButton, { onClick: handleWalletLogin, children: [
7284
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/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" }) }),
7285
+ "Sign in with Wallet"
7286
+ ] })
7287
+ ] }),
7288
+ /* @__PURE__ */ jsxRuntime.jsxs(SignUpPrompt, { children: [
7289
+ "New to Loaf?",
7290
+ " ",
7291
+ /* @__PURE__ */ jsxRuntime.jsx(SignUpLink, { type: "button", onClick: () => handleEmailClick(true), children: "Sign up" })
7161
7292
  ] })
7162
7293
  ] }) });
7163
7294
  }
7164
7295
  if (view === "email") {
7165
- return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7296
+ return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { $transparent: gate, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7166
7297
  /* @__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" }) }) }),
7167
7298
  /* @__PURE__ */ jsxRuntime.jsxs(BackButton, { onClick: handleBack, children: [
7168
7299
  /* @__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" }) }),
@@ -7201,7 +7332,7 @@ var LoginPopup = ({
7201
7332
  ] }) });
7202
7333
  }
7203
7334
  if (view === "wallet-handle") {
7204
- return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: loading ? void 0 : onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7335
+ return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { $transparent: gate, onClick: loading ? void 0 : onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7205
7336
  !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" }) }) }),
7206
7337
  /* @__PURE__ */ jsxRuntime.jsxs(Title, { children: [
7207
7338
  /* @__PURE__ */ jsxRuntime.jsx(LogoContainer3, { children: /* @__PURE__ */ jsxRuntime.jsx(LogoImage, { src: logoSrc, alt: logoAlt }) }),
@@ -7226,7 +7357,71 @@ var LoginPopup = ({
7226
7357
  ] }) });
7227
7358
  }
7228
7359
  if (view === "otp") {
7229
- return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: loading ? void 0 : onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7360
+ if (gate) {
7361
+ return /* @__PURE__ */ jsxRuntime.jsxs(GateShell, { children: [
7362
+ /* @__PURE__ */ jsxRuntime.jsx(GateTint, { $reveal: otpStatus === "valid" ? 3 : 2 }),
7363
+ /* @__PURE__ */ jsxRuntime.jsxs(GateForm, { children: [
7364
+ /* @__PURE__ */ jsxRuntime.jsxs(GateBrand, { children: [
7365
+ /* @__PURE__ */ jsxRuntime.jsx(GateLogoLink, { href: "https://loafmarkets.com", "aria-label": "Go to loafmarkets.com", children: /* @__PURE__ */ jsxRuntime.jsx(GateLogo, { src: logoSrc, alt: logoAlt }) }),
7366
+ /* @__PURE__ */ jsxRuntime.jsx(GateBrandDivider, {}),
7367
+ /* @__PURE__ */ jsxRuntime.jsx(GateBetaTag, { children: "Private Beta" })
7368
+ ] }),
7369
+ /* @__PURE__ */ jsxRuntime.jsxs(GateOtpText, { children: [
7370
+ "We sent a code to",
7371
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
7372
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: email })
7373
+ ] }),
7374
+ /* @__PURE__ */ jsxRuntime.jsx(OTPContainer, { children: otp.map((digit, index) => /* @__PURE__ */ jsxRuntime.jsx(
7375
+ OTPInput,
7376
+ {
7377
+ id: `otp-${index}`,
7378
+ type: "text",
7379
+ inputMode: "numeric",
7380
+ maxLength: 1,
7381
+ $status: otpStatus,
7382
+ readOnly: otpStatus === "valid" || otpStatus === "checking",
7383
+ value: digit,
7384
+ onChange: (event) => handleOTPChange(index, event.target.value),
7385
+ onKeyDown: (event) => handleOTPKeyDown(index, event),
7386
+ onInput: (event) => handleOTPInput(index, event),
7387
+ onPaste: handleOTPPaste,
7388
+ autoComplete: index === 0 ? "one-time-code" : "off",
7389
+ autoFocus: index === 0
7390
+ },
7391
+ index
7392
+ )) }),
7393
+ otpStatus === "invalid" && /* @__PURE__ */ jsxRuntime.jsx(StatusMessage, { $error: true, children: "That code isn't right. Try again." }),
7394
+ /* @__PURE__ */ jsxRuntime.jsxs(GateResendText, { children: [
7395
+ /* @__PURE__ */ jsxRuntime.jsx(
7396
+ "button",
7397
+ {
7398
+ type: "button",
7399
+ onClick: (event) => {
7400
+ event.preventDefault();
7401
+ void handleSendCode(event);
7402
+ },
7403
+ children: "Resend code"
7404
+ }
7405
+ ),
7406
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: " \xB7 " }),
7407
+ /* @__PURE__ */ jsxRuntime.jsx(
7408
+ "button",
7409
+ {
7410
+ type: "button",
7411
+ onClick: () => {
7412
+ setOtp(Array(OTP_INPUT_LENGTH).fill(""));
7413
+ setOtpStatus("idle");
7414
+ setError("");
7415
+ setView("referral");
7416
+ },
7417
+ children: "Back"
7418
+ }
7419
+ )
7420
+ ] })
7421
+ ] })
7422
+ ] });
7423
+ }
7424
+ return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { $transparent: gate, onClick: loading ? void 0 : onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7230
7425
  !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" }) }) }),
7231
7426
  loading ? /* @__PURE__ */ jsxRuntime.jsxs(AccountCreationLoader, { children: [
7232
7427
  /* @__PURE__ */ jsxRuntime.jsx(SpinnerRing, {}),
@@ -7315,8 +7510,8 @@ var LoginPopup = ({
7315
7510
  /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }),
7316
7511
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
7317
7512
  ] }) }),
7318
- /* @__PURE__ */ jsxRuntime.jsx(KycHeading, { children: "Verify Your Identity" }),
7319
- /* @__PURE__ */ jsxRuntime.jsx(KycSubline, { children: "Initial offerings are only available to verified investors" }),
7513
+ /* @__PURE__ */ jsxRuntime.jsx(KycHeading, { children: "Verify Wholesale Status" }),
7514
+ /* @__PURE__ */ jsxRuntime.jsx(KycSubline, { children: "Initial offerings are only available to accredited or wholesale investors" }),
7320
7515
  /* @__PURE__ */ jsxRuntime.jsx(KycStartButton, { type: "button", onClick: handleKycStart, disabled: kycLoading, children: kycLoading ? "Verifying\u2026" : kycStatusProp === "PENDING" || kycStatusProp === "ON_HOLD" ? "Resume Verification" : "Start Verification" }),
7321
7516
  /* @__PURE__ */ jsxRuntime.jsx(KycDuration, { children: "Takes about 2 minutes" }),
7322
7517
  /* @__PURE__ */ jsxRuntime.jsx(KycDivider, {}),
@@ -7402,7 +7597,7 @@ var LoginPopup = ({
7402
7597
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "rgba(255,255,255,0.5)", fontSize: "0.8rem" }, children: "Deposit USDC from an exchange or wallet" })
7403
7598
  ] })
7404
7599
  ] }),
7405
- /* @__PURE__ */ jsxRuntime.jsxs(ModalOptionCard, { onClick: handleFiatFund, disabled: fiatFundingLoading, children: [
7600
+ /* @__PURE__ */ jsxRuntime.jsxs(ModalOptionCard, { onClick: handleFiatFund, disabled: true, children: [
7406
7601
  /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", style: { color: "rgba(255,255,255,0.6)", flexShrink: 0 }, children: [
7407
7602
  /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "22", x2: "21", y2: "22" }),
7408
7603
  /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "6", y1: "18", x2: "6", y2: "11" }),
@@ -7412,7 +7607,10 @@ var LoginPopup = ({
7412
7607
  /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "12 2 20 7 4 7" })
7413
7608
  ] }),
7414
7609
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1 }, children: [
7415
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#fff", fontWeight: 600, fontSize: "0.95rem", marginBottom: "0.25rem" }, children: fiatFundingLoading ? "Loading widget\u2026" : "Bank Deposit" }),
7610
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", marginBottom: "0.25rem" }, children: [
7611
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#fff", fontWeight: 600, fontSize: "0.95rem" }, children: fiatFundingLoading ? "Loading widget\u2026" : "Bank Deposit" }),
7612
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.6rem", fontWeight: 700, color: "#E6C87E", background: "rgba(230,198,86,0.12)", padding: "0.12rem 0.4rem", borderRadius: "4px", textTransform: "uppercase", letterSpacing: "0.04em", whiteSpace: "nowrap" }, children: "Coming Soon" })
7613
+ ] }),
7416
7614
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "rgba(255,255,255,0.5)", fontSize: "0.8rem" }, children: "Deposit to your account via card or bank transfer" })
7417
7615
  ] })
7418
7616
  ] })
@@ -7443,84 +7641,162 @@ var LoginPopup = ({
7443
7641
  setReferralLoading(false);
7444
7642
  }
7445
7643
  };
7446
- const handleJoinWaitlistSkip = async () => {
7447
- if (!onJoinWaitlist || !email) {
7448
- onClose();
7449
- return;
7450
- }
7644
+ const codeSuffix = referralCode.startsWith(CODE_PREFIX) ? referralCode.slice(CODE_PREFIX.length) : referralCode.replace(/^LOAF-?/i, "");
7645
+ const setCodeSuffix = (suffix) => {
7646
+ setReferralCode(CODE_PREFIX + suffix);
7451
7647
  setReferralError("");
7452
- setWaitlistLoading(true);
7453
- try {
7454
- const message = await onJoinWaitlist(email);
7455
- setWaitlistMessage(message || "You're on the waitlist.");
7456
- setTimeout(() => onClose(), 1400);
7457
- } catch (err) {
7458
- setReferralError(err instanceof Error ? err.message : "Couldn't join the waitlist. Please try again.");
7459
- setWaitlistLoading(false);
7648
+ setError("");
7649
+ if (gate) {
7650
+ if (suffix.length === 5) void runCodeValidation(CODE_PREFIX + suffix);
7651
+ else {
7652
+ validatedCodeRef.current = null;
7653
+ setCodeStatus("idle");
7654
+ }
7460
7655
  }
7461
7656
  };
7462
- return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7463
- /* @__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" }) }) }),
7464
- /* @__PURE__ */ jsxRuntime.jsxs(OnboardingStepContainer, { children: [
7465
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
7466
- width: 52,
7467
- height: 52,
7468
- borderRadius: 14,
7469
- background: "linear-gradient(135deg, rgba(230,200,126,0.15) 0%, rgba(230,200,126,0.08) 100%)",
7470
- border: "1px solid rgba(230,200,126,0.25)",
7471
- display: "flex",
7472
- alignItems: "center",
7473
- justifyContent: "center",
7474
- marginBottom: "1.1rem"
7475
- }, 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: [
7476
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" }),
7477
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "9", cy: "7", r: "4" }),
7478
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M23 21v-2a4 4 0 0 0-3-3.87" }),
7479
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 3.13a4 4 0 0 1 0 7.75" })
7480
- ] }) }),
7481
- /* @__PURE__ */ jsxRuntime.jsx(OnboardingHeading, { children: "Enter code to access Private Beta trading" }),
7482
- /* @__PURE__ */ jsxRuntime.jsx(OnboardingSubtext, { style: { marginBottom: "1.5rem" }, children: "Enter code to trade 100k in USDC, or skip to continue." }),
7483
- /* @__PURE__ */ jsxRuntime.jsxs(EmailFormContainer, { style: { width: "100%", marginBottom: 0 }, children: [
7657
+ const handleCodeChange = (e) => {
7658
+ setCodeSuffix(e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, "").slice(0, 5));
7659
+ };
7660
+ const handleCodePaste = (e) => {
7661
+ e.preventDefault();
7662
+ const text = (e.clipboardData.getData("text") || "").toUpperCase();
7663
+ setCodeSuffix(text.replace(/^LOAF-?/, "").replace(/[^A-Z0-9]/g, "").slice(0, 5));
7664
+ };
7665
+ const codeComplete = codeSuffix.length === 5;
7666
+ const codeInput = /* @__PURE__ */ jsxRuntime.jsx(
7667
+ CodeSuffixInput,
7668
+ {
7669
+ type: "text",
7670
+ inputMode: "text",
7671
+ autoComplete: "off",
7672
+ autoCapitalize: "characters",
7673
+ spellCheck: false,
7674
+ maxLength: 5,
7675
+ "aria-label": "Access code",
7676
+ readOnly: codeStatus === "valid",
7677
+ value: codeSuffix,
7678
+ onChange: handleCodeChange,
7679
+ onPaste: handleCodePaste,
7680
+ onKeyDown: (e) => {
7681
+ if (e.key !== "Enter" || !codeComplete) return;
7682
+ if (gate) void runCodeValidation(referralCode);
7683
+ else void handleReferralSubmit();
7684
+ },
7685
+ autoFocus: true
7686
+ }
7687
+ );
7688
+ const signInStep = /* @__PURE__ */ jsxRuntime.jsxs(GateReveal, { children: [
7689
+ /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSendCode, style: { width: "100%" }, children: [
7690
+ /* @__PURE__ */ jsxRuntime.jsxs(CodeInputWrapper, { children: [
7484
7691
  /* @__PURE__ */ jsxRuntime.jsx(
7485
- EmailInput,
7692
+ GateEmailInput,
7486
7693
  {
7487
- type: "text",
7488
- placeholder: "e.g. LOAF-XXXX",
7489
- value: referralCode,
7490
- onChange: (e) => {
7491
- setReferralCode(e.target.value.toUpperCase());
7492
- setReferralError("");
7493
- },
7494
- onKeyDown: (e) => {
7495
- if (e.key === "Enter") void handleReferralSubmit();
7496
- },
7694
+ type: "email",
7695
+ inputMode: "email",
7696
+ autoComplete: "email",
7697
+ placeholder: "Enter your email",
7698
+ value: email,
7699
+ onChange: (event) => setEmail(event.target.value),
7497
7700
  autoFocus: true
7498
7701
  }
7499
7702
  ),
7500
- /* @__PURE__ */ jsxRuntime.jsx(
7501
- SubmitButton,
7502
- {
7503
- type: "button",
7504
- onClick: () => void handleReferralSubmit(),
7505
- disabled: referralLoading || !referralCode.trim(),
7506
- children: referralLoading ? "Verifying\u2026" : "Apply Code"
7507
- }
7508
- ),
7509
- referralError && /* @__PURE__ */ jsxRuntime.jsx(StatusMessage, { $error: true, children: referralError })
7703
+ /* @__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" }) }) })
7704
+ ] }),
7705
+ error && /* @__PURE__ */ jsxRuntime.jsx(StatusMessage, { $error: true, children: error })
7706
+ ] }),
7707
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7708
+ /* @__PURE__ */ jsxRuntime.jsx(GateOr, { children: "or" }),
7709
+ /* @__PURE__ */ jsxRuntime.jsxs(GateWalletButton, { type: "button", onClick: handleWalletLogin, children: [
7710
+ /* @__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" }) }),
7711
+ signInMode ? "Sign in with Wallet" : "Connect Wallet"
7712
+ ] })
7713
+ ] })
7714
+ ] });
7715
+ if (gate) {
7716
+ const codeAccepted = codeStatus === "valid";
7717
+ const showSignIn = signInMode || signInRevealed;
7718
+ return /* @__PURE__ */ jsxRuntime.jsxs(GateShell, { children: [
7719
+ /* @__PURE__ */ jsxRuntime.jsx(GateTint, { $reveal: showSignIn ? 1 : 0 }),
7720
+ /* @__PURE__ */ jsxRuntime.jsxs(GateForm, { children: [
7721
+ /* @__PURE__ */ jsxRuntime.jsxs(GateBrand, { children: [
7722
+ /* @__PURE__ */ jsxRuntime.jsx(GateLogoLink, { href: "https://loafmarkets.com", "aria-label": "Go to loafmarkets.com", children: /* @__PURE__ */ jsxRuntime.jsx(GateLogo, { src: logoSrc, alt: logoAlt }) }),
7723
+ /* @__PURE__ */ jsxRuntime.jsx(GateBrandDivider, {}),
7724
+ /* @__PURE__ */ jsxRuntime.jsx(GateBetaTag, { children: "Private Beta" })
7725
+ ] }),
7726
+ signInMode ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7727
+ signInStep,
7728
+ /* @__PURE__ */ jsxRuntime.jsx(GateResendText, { children: /* @__PURE__ */ jsxRuntime.jsx(
7729
+ "button",
7730
+ {
7731
+ type: "button",
7732
+ onClick: () => {
7733
+ setError("");
7734
+ setSignInMode(false);
7735
+ },
7736
+ children: "\u2190 Enter access code instead"
7737
+ }
7738
+ ) })
7739
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7740
+ /* @__PURE__ */ jsxRuntime.jsxs(CodeInputWrapper, { $status: codeStatus, children: [
7741
+ /* @__PURE__ */ jsxRuntime.jsx(CodePrefix, { children: CODE_PREFIX }),
7742
+ codeInput,
7743
+ /* @__PURE__ */ jsxRuntime.jsx(
7744
+ GateSubmit,
7745
+ {
7746
+ type: "button",
7747
+ "aria-label": "Submit access code",
7748
+ $status: codeStatus,
7749
+ disabled: codeStatus === "checking" || !codeComplete,
7750
+ onClick: () => void runCodeValidation(referralCode),
7751
+ 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" }) })
7752
+ }
7753
+ )
7754
+ ] }),
7755
+ (codeStatus === "invalid" || error && !signInRevealed) && /* @__PURE__ */ jsxRuntime.jsx(StatusMessage, { $error: true, children: error || "That code isn't valid. Double-check and try again." }),
7756
+ signInRevealed ? signInStep : /* @__PURE__ */ jsxRuntime.jsxs(GateResendText, { children: [
7757
+ "Already have an account?",
7758
+ " ",
7759
+ /* @__PURE__ */ jsxRuntime.jsx(
7760
+ "button",
7761
+ {
7762
+ type: "button",
7763
+ onClick: () => {
7764
+ setError("");
7765
+ setIsSignUp(false);
7766
+ setSignInMode(true);
7767
+ },
7768
+ children: "Sign in"
7769
+ }
7770
+ )
7771
+ ] })
7772
+ ] })
7773
+ ] })
7774
+ ] });
7775
+ }
7776
+ return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
7777
+ /* @__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" }) }) }),
7778
+ /* @__PURE__ */ jsxRuntime.jsxs(Title, { children: [
7779
+ /* @__PURE__ */ jsxRuntime.jsxs(LogoContainer3, { children: [
7780
+ /* @__PURE__ */ jsxRuntime.jsx(LogoImage, { src: logoSrc, alt: logoAlt }),
7781
+ /* @__PURE__ */ jsxRuntime.jsx(LogoBeta, { children: "Private Beta" })
7782
+ ] }),
7783
+ /* @__PURE__ */ jsxRuntime.jsx(TitleText, { children: "Enter your access code" })
7784
+ ] }),
7785
+ /* @__PURE__ */ jsxRuntime.jsxs(EmailFormContainer, { style: { width: "100%", marginTop: "1.5rem", marginBottom: 0 }, children: [
7786
+ /* @__PURE__ */ jsxRuntime.jsxs(CodeInputWrapper, { children: [
7787
+ /* @__PURE__ */ jsxRuntime.jsx(CodePrefix, { children: CODE_PREFIX }),
7788
+ codeInput
7510
7789
  ] }),
7511
- waitlistMessage ? /* @__PURE__ */ jsxRuntime.jsxs(StatusMessage, { style: { marginTop: "0.75rem" }, children: [
7512
- "\u2713 ",
7513
- waitlistMessage
7514
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(
7515
- OnboardingSkipButton,
7790
+ /* @__PURE__ */ jsxRuntime.jsx(
7791
+ SubmitButton,
7516
7792
  {
7517
7793
  type: "button",
7518
- onClick: () => void handleJoinWaitlistSkip(),
7519
- disabled: waitlistLoading,
7520
- style: { marginTop: "0.75rem" },
7521
- children: waitlistLoading ? "Joining\u2026" : email ? "Skip for now & join Waitlist" : "Skip for now"
7794
+ onClick: () => void handleReferralSubmit(),
7795
+ disabled: referralLoading || !codeComplete,
7796
+ children: referralLoading ? "Verifying\u2026" : "Continue"
7522
7797
  }
7523
- )
7798
+ ),
7799
+ referralError && /* @__PURE__ */ jsxRuntime.jsx(StatusMessage, { $error: true, children: referralError })
7524
7800
  ] })
7525
7801
  ] }) });
7526
7802
  }
@@ -7640,8 +7916,9 @@ var Overlay2 = styled10__default.default.div`
7640
7916
  left: 0;
7641
7917
  right: 0;
7642
7918
  bottom: 0;
7643
- background-color: rgba(0, 0, 0, 0.8);
7644
- backdrop-filter: blur(4px);
7919
+ background-color: ${(props) => props.$gate ? "var(--color-background, #0a0a0a)" : props.$transparent ? "rgba(0, 0, 0, 0.45)" : "rgba(0, 0, 0, 0.8)"};
7920
+ backdrop-filter: ${(props) => props.$gate ? "none" : props.$transparent ? "blur(2px)" : "blur(4px)"};
7921
+ transition: background-color 0.4s ease, backdrop-filter 0.4s ease;
7645
7922
  display: flex;
7646
7923
  justify-content: center;
7647
7924
  align-items: center;
@@ -7658,15 +7935,15 @@ var Overlay2 = styled10__default.default.div`
7658
7935
  }
7659
7936
  `;
7660
7937
  var PopupContainer = styled10__default.default.div`
7661
- background-color: var(--color-background, #0a0a0a);
7662
- border: 1px solid rgba(230, 198, 86, 0.3);
7938
+ background-color: ${(props) => props.$gate ? "transparent" : "var(--color-background, #0a0a0a)"};
7939
+ border: ${(props) => props.$gate ? "none" : "1px solid rgba(230, 198, 86, 0.3)"};
7663
7940
  border-radius: var(--border-radius, 12px);
7664
7941
  padding: 2.5rem;
7665
7942
  max-width: 440px;
7666
7943
  width: 90%;
7667
7944
  position: relative;
7668
7945
  animation: slideUp 0.3s ease-out;
7669
- box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
7946
+ box-shadow: ${(props) => props.$gate ? "none" : "0 10px 30px rgba(0, 0, 0, 0.3)"};
7670
7947
 
7671
7948
  @keyframes slideUp {
7672
7949
  from {
@@ -7853,29 +8130,27 @@ var Title = styled10__default.default.h2`
7853
8130
  flex-direction: column;
7854
8131
  align-items: center;
7855
8132
  justify-content: center;
7856
- gap: 0.4rem;
8133
+ gap: 1rem;
7857
8134
  `;
7858
- styled10__default.default.p`
7859
- font-size: 0.9rem;
7860
- font-weight: 400;
7861
- color: var(--color-text-secondary, #848e9c);
8135
+ var TitleText = styled10__default.default.span`
7862
8136
  text-align: center;
7863
- margin: 0 0 2rem;
8137
+ line-height: 1.2;
7864
8138
  `;
7865
- var MainHeading = styled10__default.default.h2`
7866
- font-size: 1.5rem;
7867
- font-weight: 700;
7868
- color: var(--color-text, #eaecef);
7869
- text-align: left;
7870
- margin: 0 0 0.35rem;
8139
+ var LogoBeta = styled10__default.default.span`
8140
+ color: var(--color-accent, #E6C87E);
8141
+ font-size: 0.6rem;
8142
+ font-weight: 600;
8143
+ letter-spacing: 0.14em;
8144
+ text-transform: uppercase;
8145
+ white-space: nowrap;
8146
+ padding-bottom: 0.95rem;
7871
8147
  `;
7872
- var MainSubtitle = styled10__default.default.p`
8148
+ var Subtitle = styled10__default.default.p`
7873
8149
  font-size: 0.9rem;
7874
8150
  font-weight: 400;
7875
8151
  color: var(--color-text-secondary, #848e9c);
7876
- text-align: left;
7877
- margin: 0 0 1.5rem;
7878
- line-height: 1.5;
8152
+ text-align: center;
8153
+ margin: 0 0 2rem;
7879
8154
  `;
7880
8155
  var LogoContainer3 = styled10__default.default.div`
7881
8156
  display: flex;
@@ -7885,21 +8160,21 @@ var LogoContainer3 = styled10__default.default.div`
7885
8160
  margin-bottom: 0.5rem;
7886
8161
  `;
7887
8162
  var LogoImage = styled10__default.default.img`
7888
- height: 40px;
8163
+ height: 60px;
7889
8164
  `;
7890
- styled10__default.default.div`
8165
+ var ButtonsContainer = styled10__default.default.div`
7891
8166
  display: flex;
7892
8167
  flex-direction: column;
7893
8168
  gap: 1rem;
7894
8169
  margin-bottom: 1.5rem;
7895
8170
  `;
7896
- styled10__default.default.div`
8171
+ var SignUpPrompt = styled10__default.default.div`
7897
8172
  text-align: center;
7898
8173
  font-size: 0.875rem;
7899
8174
  color: var(--color-text-secondary, #848e9c);
7900
8175
  margin-bottom: 0.5rem;
7901
8176
  `;
7902
- styled10__default.default.button`
8177
+ var SignUpLink = styled10__default.default.button`
7903
8178
  background: none;
7904
8179
  border: none;
7905
8180
  padding: 0;
@@ -7914,23 +8189,19 @@ styled10__default.default.button`
7914
8189
  `;
7915
8190
  var LoginButton = styled10__default.default.button`
7916
8191
  display: flex;
7917
- width: 100%;
7918
- box-sizing: border-box;
7919
8192
  align-items: center;
7920
8193
  justify-content: center;
7921
- gap: 0.55rem;
7922
- padding: 0.55rem 1.1rem;
8194
+ gap: 0.75rem;
8195
+ padding: 1rem 1.5rem;
7923
8196
  background-color: var(--color-background-light, #1a1a1a);
7924
8197
  border: 1px solid rgba(230, 198, 86, 0.2);
7925
8198
  border-radius: var(--border-radius, 8px);
7926
8199
  color: var(--color-text, #eaecef);
7927
- font-size: 0.82rem;
8200
+ font-size: 1rem;
7928
8201
  font-weight: 500;
7929
8202
  cursor: pointer;
7930
8203
  transition: all 0.2s ease;
7931
8204
 
7932
- svg { width: 16px; height: 16px; }
7933
-
7934
8205
  &:hover {
7935
8206
  background-color: rgba(230, 198, 86, 0.1);
7936
8207
  border-color: var(--color-accent, #E6C87E);
@@ -7973,60 +8244,265 @@ var EmailInput = styled10__default.default.input`
7973
8244
  color: var(--color-text-secondary, #848e9c);
7974
8245
  }
7975
8246
  `;
7976
- var GateForm = styled10__default.default.form`
8247
+ var codeBorderColor = (status, focused) => {
8248
+ if (status === "valid") return "var(--color-positive, #00C076)";
8249
+ if (status === "invalid") return "var(--color-negative, #FF5757)";
8250
+ return focused ? "var(--color-accent, #E6C87E)" : "rgba(230, 198, 86, 0.2)";
8251
+ };
8252
+ var CodeInputWrapper = styled10__default.default.div`
7977
8253
  display: flex;
7978
- flex-direction: column;
7979
- gap: 0.6rem;
7980
- width: 100%;
7981
- `;
7982
- var GateInputRow = styled10__default.default.div`
7983
- position: relative;
7984
- width: 100%;
7985
- `;
7986
- var GateInput = styled10__default.default.input`
8254
+ align-items: center;
7987
8255
  width: 100%;
7988
- box-sizing: border-box;
7989
- padding: 1rem 3.25rem 1rem 1.25rem;
8256
+ padding: 1rem 1.25rem;
7990
8257
  background-color: var(--color-background-light, #1a1a1a);
7991
- border: 1px solid rgba(230, 198, 86, 0.2);
8258
+ border: 1px solid ${(props) => codeBorderColor(props.$status, false)};
7992
8259
  border-radius: var(--border-radius, 8px);
7993
- color: var(--color-text, #eaecef);
7994
- font-size: 1rem;
8260
+ 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"};
7995
8261
  transition: all 0.2s ease;
7996
8262
 
7997
- &:focus { outline: none; border-color: var(--color-accent, #E6C87E); }
7998
- &::placeholder { color: var(--color-text-secondary, #848e9c); }
8263
+ &:focus-within {
8264
+ border-color: ${(props) => codeBorderColor(props.$status, true)};
8265
+ }
7999
8266
  `;
8000
- var GateSubmit = styled10__default.default.button`
8267
+ var CodePrefix = styled10__default.default.span`
8268
+ color: var(--color-text-secondary, #848e9c);
8269
+ font-size: 1.1rem;
8270
+ font-weight: 600;
8271
+ letter-spacing: 0.22em;
8272
+ font-family: 'Space Grotesk', monospace;
8273
+ user-select: none;
8274
+ `;
8275
+ var CodeSuffixInput = styled10__default.default.input`
8276
+ flex: 1;
8277
+ min-width: 0;
8278
+ border: none;
8279
+ background: transparent;
8280
+ color: var(--color-text, #eaecef);
8281
+ font-size: 1.1rem;
8282
+ font-weight: 600;
8283
+ letter-spacing: 0.22em;
8284
+ text-transform: uppercase;
8285
+ font-family: 'Space Grotesk', monospace;
8286
+ /* Explicit line-height so iOS in-app WebViews size the caret to the text
8287
+ box instead of rendering a short, top-aligned caret (line-height: normal
8288
+ + webfont + letter-spacing miscomputes it in some WebViews). */
8289
+ line-height: 1.5;
8290
+
8291
+ &:focus {
8292
+ outline: none;
8293
+ }
8294
+
8295
+ &::placeholder {
8296
+ color: rgba(132, 142, 156, 0.45);
8297
+ letter-spacing: 0.22em;
8298
+ }
8299
+ `;
8300
+ var GateBrand = styled10__default.default.div`
8301
+ display: flex;
8302
+ align-items: center;
8303
+ justify-content: center;
8304
+ gap: 0.7rem;
8305
+ margin-bottom: 0.6rem;
8306
+ `;
8307
+ var GateLogoLink = styled10__default.default.a`
8308
+ display: inline-flex;
8309
+ align-items: center;
8310
+ cursor: pointer;
8311
+ transition: opacity 0.15s ease;
8312
+
8313
+ &:hover {
8314
+ opacity: 0.85;
8315
+ }
8316
+ `;
8317
+ var GateLogo = styled10__default.default.img`
8318
+ height: 44px;
8319
+ display: block;
8320
+ `;
8321
+ var GateBrandDivider = styled10__default.default.span`
8322
+ width: 1px;
8323
+ height: 26px;
8324
+ background: rgba(255, 255, 255, 0.18);
8325
+ `;
8326
+ var GateBetaTag = styled10__default.default.span`
8327
+ color: var(--color-text-secondary, #848e9c);
8328
+ font-size: 0.8rem;
8329
+ font-weight: 500;
8330
+ letter-spacing: 0.28em;
8331
+ text-transform: uppercase;
8332
+ `;
8333
+ var GateForm = styled10__default.default.div`
8334
+ display: flex;
8335
+ flex-direction: column;
8336
+ align-items: center;
8337
+ gap: 0.9rem;
8338
+ width: 100%;
8339
+ max-width: 360px;
8340
+ position: relative;
8341
+ z-index: 1;
8342
+ `;
8343
+ var GateShell = styled10__default.default.div`
8344
+ position: fixed;
8345
+ inset: 0;
8346
+ display: flex;
8347
+ align-items: center;
8348
+ justify-content: center;
8349
+ z-index: 10000;
8350
+ background-color: rgba(10, 10, 12, 0.66);
8351
+ `;
8352
+ var GateTint = styled10__default.default.div`
8001
8353
  position: absolute;
8002
- top: 50%;
8003
- right: 0.55rem;
8004
- transform: translateY(-50%);
8005
- width: 34px;
8006
- height: 34px;
8354
+ left: 0;
8355
+ right: 0;
8356
+ bottom: 0;
8357
+ height: calc(${(props) => (3 - Math.max(0, Math.min(3, props.$reveal))) / 3 * 100}% + 90px);
8358
+ background: linear-gradient(
8359
+ to top,
8360
+ var(--color-background, #0a0a0c) calc(100% - 90px),
8361
+ rgba(10, 10, 12, 0) 100%
8362
+ );
8363
+ transition: height 0.65s ease;
8364
+ pointer-events: none;
8365
+ `;
8366
+ var GateOtpText = styled10__default.default.p`
8367
+ margin: 0;
8368
+ text-align: center;
8369
+ font-size: 0.9rem;
8370
+ line-height: 1.5;
8371
+ color: var(--color-text-secondary, #848e9c);
8372
+
8373
+ strong {
8374
+ color: var(--color-text, #eaecef);
8375
+ font-weight: 600;
8376
+ }
8377
+ `;
8378
+ var GateResendText = styled10__default.default.p`
8379
+ margin: 0.2rem 0 0;
8380
+ font-size: 0.85rem;
8381
+ color: var(--color-text-secondary, #848e9c);
8382
+
8383
+ button {
8384
+ background: none;
8385
+ border: none;
8386
+ color: var(--color-accent, #E6C87E);
8387
+ cursor: pointer;
8388
+ text-decoration: underline;
8389
+ font-size: inherit;
8390
+ }
8391
+ `;
8392
+ var GateSubmit = styled10__default.default.button`
8007
8393
  display: flex;
8008
8394
  align-items: center;
8009
8395
  justify-content: center;
8396
+ flex-shrink: 0;
8397
+ width: 28px;
8398
+ height: 28px;
8399
+ margin-left: 0.5rem;
8400
+ padding: 0;
8010
8401
  background: none;
8011
8402
  border: none;
8012
- border-radius: 8px;
8013
- color: var(--color-text-secondary, #848e9c);
8014
8403
  cursor: pointer;
8015
- transition: color 0.2s ease, background 0.2s ease;
8404
+ color: ${(props) => props.$status === "valid" ? "var(--color-positive, #00C076)" : props.$status === "invalid" ? "var(--color-negative, #FF5757)" : "var(--color-accent, #E6C87E)"};
8405
+ transition: color 0.15s ease, transform 0.15s ease, opacity 0.15s ease;
8406
+
8407
+ &:not(:disabled):hover {
8408
+ transform: translateX(2px);
8409
+ }
8016
8410
 
8017
- svg { width: 18px; height: 18px; }
8018
- &:hover:not(:disabled) { color: var(--color-accent, #E6C87E); background: rgba(230, 198, 86, 0.1); }
8019
- &:disabled { opacity: 0.4; cursor: not-allowed; }
8411
+ &:disabled {
8412
+ opacity: ${(props) => props.$status === "valid" ? 1 : 0.35};
8413
+ color: ${(props) => props.$status === "valid" ? "var(--color-positive, #00C076)" : "var(--color-text-secondary, #848e9c)"};
8414
+ cursor: default;
8415
+ }
8416
+ `;
8417
+ var GateEmailInput = styled10__default.default.input`
8418
+ flex: 1;
8419
+ min-width: 0;
8420
+ border: none;
8421
+ background: transparent;
8422
+ color: var(--color-text, #eaecef);
8423
+ font-size: 1rem;
8424
+
8425
+ &:focus {
8426
+ outline: none;
8427
+ }
8428
+
8429
+ &::placeholder {
8430
+ color: rgba(132, 142, 156, 0.5);
8431
+ }
8432
+ `;
8433
+ var GateSpinner = styled10__default.default.span`
8434
+ width: 18px;
8435
+ height: 18px;
8436
+ border: 2px solid rgba(230, 198, 86, 0.3);
8437
+ border-top-color: var(--color-accent, #E6C87E);
8438
+ border-radius: 50%;
8439
+ animation: gateSpin 0.7s linear infinite;
8440
+
8441
+ @keyframes gateSpin {
8442
+ to { transform: rotate(360deg); }
8443
+ }
8020
8444
  `;
8021
8445
  var GateOr = styled10__default.default.div`
8022
8446
  display: flex;
8023
8447
  align-items: center;
8024
- gap: 0.75rem;
8448
+ gap: 0.6rem;
8449
+ width: 100%;
8025
8450
  color: var(--color-text-secondary, #848e9c);
8026
- font-size: 0.8rem;
8027
- margin: 0.4rem 0;
8451
+ font-size: 0.78rem;
8452
+ text-transform: lowercase;
8028
8453
 
8029
- &::before, &::after { content: ""; flex: 1; height: 1px; background: rgba(255, 255, 255, 0.08); }
8454
+ &::before,
8455
+ &::after {
8456
+ content: "";
8457
+ flex: 1;
8458
+ height: 1px;
8459
+ background: rgba(255, 255, 255, 0.1);
8460
+ }
8461
+ `;
8462
+ var GateWalletButton = styled10__default.default.button`
8463
+ display: inline-flex;
8464
+ align-items: center;
8465
+ justify-content: center;
8466
+ gap: 0.5rem;
8467
+ margin-top: 0.1rem;
8468
+ padding: 0.55rem 1.1rem;
8469
+ background: transparent;
8470
+ border: 1px solid rgba(255, 255, 255, 0.12);
8471
+ border-radius: var(--border-radius, 8px);
8472
+ color: var(--color-text-secondary, #848e9c);
8473
+ font-size: 0.85rem;
8474
+ font-weight: 500;
8475
+ cursor: pointer;
8476
+ transition: border-color 0.15s ease, color 0.15s ease;
8477
+
8478
+ svg {
8479
+ width: 16px;
8480
+ height: 16px;
8481
+ }
8482
+
8483
+ &:hover {
8484
+ border-color: rgba(230, 198, 86, 0.4);
8485
+ color: var(--color-text, #eaecef);
8486
+ }
8487
+ `;
8488
+ var GateReveal = styled10__default.default.div`
8489
+ display: flex;
8490
+ flex-direction: column;
8491
+ align-items: center;
8492
+ gap: 0.9rem;
8493
+ width: 100%;
8494
+ animation: gateReveal 0.3s ease-out;
8495
+
8496
+ @keyframes gateReveal {
8497
+ from {
8498
+ opacity: 0;
8499
+ transform: translateY(-6px);
8500
+ }
8501
+ to {
8502
+ opacity: 1;
8503
+ transform: translateY(0);
8504
+ }
8505
+ }
8030
8506
  `;
8031
8507
  var OTPContainer = styled10__default.default.div`
8032
8508
  display: flex;
@@ -8040,15 +8516,17 @@ var OTPInput = styled10__default.default.input`
8040
8516
  font-size: 1.5rem;
8041
8517
  font-weight: 600;
8042
8518
  background-color: var(--color-background-light, #1a1a1a);
8043
- border: 1px solid rgba(230, 198, 86, 0.2);
8519
+ border: 1px solid ${(props) => codeBorderColor(props.$status, false)};
8044
8520
  border-radius: var(--border-radius, 8px);
8045
- color: var(--color-accent, #E6C87E);
8521
+ color: ${(props) => props.$status === "valid" ? "var(--color-positive, #00C076)" : props.$status === "invalid" ? "var(--color-negative, #FF5757)" : "var(--color-accent, #E6C87E)"};
8522
+ 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"};
8523
+ opacity: ${(props) => props.$status === "checking" ? 0.6 : 1};
8046
8524
  transition: all 0.2s ease;
8047
8525
 
8048
8526
  &:focus {
8049
8527
  outline: none;
8050
- border-color: var(--color-accent, #E6C87E);
8051
- box-shadow: 0 0 0 2px rgba(230, 198, 86, 0.2);
8528
+ border-color: ${(props) => codeBorderColor(props.$status, true)};
8529
+ 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)"};
8052
8530
  }
8053
8531
  `;
8054
8532
  var SubmitButton = styled10__default.default.button`
@@ -8416,15 +8894,24 @@ var SpinnerRing = styled10__default.default.div`
8416
8894
  }
8417
8895
  `;
8418
8896
  var PREPARING_FACTS = [
8419
- "Property is the world's largest asset class \u2014 worth over US$300 trillion.",
8420
- "Loaf settles trades in about 1 second. Traditional property takes ~90 days.",
8897
+ // Exchange
8421
8898
  "Our matching engine processes orders in 30 microseconds.",
8422
- "Every token is backed 1:1 by land-title-registered property.",
8423
- "Own a slice of premium real estate \u2014 no mortgage, no paperwork.",
8899
+ "Loaf settles in 1 second. Traditional property takes 30-90 days.",
8424
8900
  "Buy and sell property as easily as a stock, on a live orderbook.",
8425
- "Earn rental yield on the exact fraction of property you own.",
8426
- "Title-backed by the NSW Land Registry \u2014 real ownership, on-chain.",
8427
- "Loaf ran the world's first property IPO."
8901
+ "Continuous price discovery, not a single buyer negotiating in a back room.",
8902
+ "Algo-trade property on our API. Build a bot with Claude using our docs.",
8903
+ // What you're holding
8904
+ "Hold shares secured 1:1 by the underlying property, as regulated securities.",
8905
+ "The same economic exposure as owning the property. Without the friction, gatekeeping, or illiquidity.",
8906
+ "Securitisation of property brings a new dimension of flexibility and tradability.",
8907
+ // Frictionless
8908
+ "Settle in seconds, then sell again whenever you want. No waiting days or weeks.",
8909
+ "99% of the frictions in property transactions can be, and have been, reduced.",
8910
+ // Vision
8911
+ "A family office can rebalance a billion dollars in an afternoon, but couldn't sell a $50M property in under six months.",
8912
+ "Family offices and HNWIs prize capital flexibility. Loaf makes property flexible.",
8913
+ "There's no law of physics that says the world's oldest asset class must stay illiquid.",
8914
+ "What if property underwent an IPO?"
8428
8915
  ];
8429
8916
  var FactCard = styled10__default.default.div`
8430
8917
  margin-top: 1.5rem;
@@ -8532,7 +9019,7 @@ var LogoImage2 = styled10__default.default.img`
8532
9019
  height: 30px;
8533
9020
  width: auto;
8534
9021
  `;
8535
- var LogoBeta = styled10__default.default.span`
9022
+ var LogoBeta2 = styled10__default.default.span`
8536
9023
  font-size: 0.6rem;
8537
9024
  font-weight: 600;
8538
9025
  letter-spacing: 0.08em;
@@ -8690,7 +9177,7 @@ function OnboardingGuide({
8690
9177
  /* @__PURE__ */ jsxRuntime.jsx(CloseButton2, { onClick: onClose, "aria-label": "Skip", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 6l12 12M18 6L6 18" }) }) }),
8691
9178
  /* @__PURE__ */ jsxRuntime.jsxs(LogoRow, { children: [
8692
9179
  /* @__PURE__ */ jsxRuntime.jsx(LogoImage2, { src: logoSrc, alt: "Loaf" }),
8693
- /* @__PURE__ */ jsxRuntime.jsx(LogoBeta, { children: "Private Beta" })
9180
+ /* @__PURE__ */ jsxRuntime.jsx(LogoBeta2, { children: "Private Beta" })
8694
9181
  ] }),
8695
9182
  /* @__PURE__ */ jsxRuntime.jsx(Title2, { children: "You're in \u{1F389}" }),
8696
9183
  /* @__PURE__ */ jsxRuntime.jsx(Subtitle2, { children: "Here's everything you need to make your first trade." }),
@@ -12060,7 +12547,8 @@ function AssetSelectorBar({
12060
12547
  onSelect,
12061
12548
  trailing,
12062
12549
  imageUrl,
12063
- badgeLabel
12550
+ badgeLabel,
12551
+ tickerPrimary
12064
12552
  }) {
12065
12553
  const [isDropdownOpen, setIsDropdownOpen] = React5.useState(false);
12066
12554
  const hasItems = selectorItems && selectorItems.length > 0;
@@ -12071,9 +12559,14 @@ function AssetSelectorBar({
12071
12559
  ];
12072
12560
  return /* @__PURE__ */ jsxRuntime.jsx(AssetSelectorWrapper, { children: /* @__PURE__ */ jsxRuntime.jsxs(IPOAssetSelector, { children: [
12073
12561
  imageUrl && /* @__PURE__ */ jsxRuntime.jsx(AssetThumbnail, { src: imageUrl, alt: propertyName }),
12074
- /* @__PURE__ */ jsxRuntime.jsx(AssetSelectorDropdown, { onClick: () => hasItems && setIsDropdownOpen((prev) => !prev), children: /* @__PURE__ */ jsxRuntime.jsxs(AssetName, { children: [
12075
- propertyName,
12076
- currentTicker ? ` (${currentTicker.toUpperCase()})` : "",
12562
+ /* @__PURE__ */ jsxRuntime.jsx(AssetSelectorDropdown, { $flush: tickerPrimary, onClick: () => hasItems && setIsDropdownOpen((prev) => !prev), children: /* @__PURE__ */ jsxRuntime.jsxs(AssetName, { children: [
12563
+ tickerPrimary && currentTicker ? /* @__PURE__ */ jsxRuntime.jsxs(AssetIdentity, { children: [
12564
+ /* @__PURE__ */ jsxRuntime.jsx(AssetTicker, { children: currentTicker.toUpperCase() }),
12565
+ /* @__PURE__ */ jsxRuntime.jsx(AssetSubName, { children: propertyName })
12566
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
12567
+ propertyName,
12568
+ currentTicker ? ` (${currentTicker.toUpperCase()})` : ""
12569
+ ] }),
12077
12570
  badgeLabel && /* @__PURE__ */ jsxRuntime.jsx(CompetitionBadge, { children: badgeLabel }),
12078
12571
  hasItems && /* @__PURE__ */ jsxRuntime.jsx(
12079
12572
  "svg",
@@ -12102,7 +12595,7 @@ function AssetSelectorBar({
12102
12595
  ] })
12103
12596
  ] })
12104
12597
  ] }, m.label)) }),
12105
- trailing != null && /* @__PURE__ */ jsxRuntime.jsx(TrailingWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(TrailingInner, { children: trailing }) }),
12598
+ trailing != null && /* @__PURE__ */ jsxRuntime.jsx(TrailingWrapper, { className: "asset-bar-trailing", children: /* @__PURE__ */ jsxRuntime.jsx(TrailingInner, { children: trailing }) }),
12106
12599
  isDropdownOpen && hasItems && /* @__PURE__ */ jsxRuntime.jsx(IPODropdown, { children: selectorItems.map((item) => {
12107
12600
  const isCurrent = item.tokenName === currentTokenName;
12108
12601
  const status = item.status?.toUpperCase();
@@ -12193,13 +12686,40 @@ var AssetSelectorDropdown = styled10__default.default.div`
12193
12686
  display: flex;
12194
12687
  align-items: center;
12195
12688
  cursor: pointer;
12196
- padding: 0.5rem;
12689
+ /* $flush (tickerPrimary): no horizontal padding / no hover box, so opening the
12690
+ selector doesn't make the ticker appear shoved right by the highlight box. */
12691
+ padding: ${(p) => p.$flush ? "0.25rem 0" : "0.5rem"};
12197
12692
  border-radius: 8px;
12198
- transition: all 0.2s ease;
12693
+ transition: ${(p) => p.$flush ? "none" : "all 0.2s ease"};
12199
12694
  flex: 0 1 auto;
12200
12695
  min-width: 0;
12201
12696
  overflow: hidden;
12202
- &:hover { background-color: rgba(255,255,255,0.05); }
12697
+ &:hover { background-color: ${(p) => p.$flush ? "transparent" : "rgba(255,255,255,0.05)"}; }
12698
+ `;
12699
+ var AssetIdentity = styled10__default.default.div`
12700
+ display: flex;
12701
+ flex-direction: column;
12702
+ min-width: 0;
12703
+ line-height: 1.2;
12704
+ `;
12705
+ var AssetTicker = styled10__default.default.span`
12706
+ font-weight: 700;
12707
+ font-size: 1.35rem;
12708
+ color: var(--color-text);
12709
+ letter-spacing: -0.01em;
12710
+ white-space: nowrap;
12711
+ overflow: hidden;
12712
+ text-overflow: ellipsis;
12713
+
12714
+ @media (max-width: 480px) { font-size: 1.2rem; }
12715
+ `;
12716
+ var AssetSubName = styled10__default.default.span`
12717
+ font-size: 0.8rem;
12718
+ font-weight: 500;
12719
+ color: rgba(255, 255, 255, 0.4);
12720
+ white-space: nowrap;
12721
+ overflow: hidden;
12722
+ text-overflow: ellipsis;
12203
12723
  `;
12204
12724
  var AssetName = styled10__default.default.div`
12205
12725
  display: flex;
@@ -14877,27 +15397,30 @@ function PortfolioActivityPanel({
14877
15397
  ] }, pos.tokenName);
14878
15398
  })
14879
15399
  ] }),
14880
- positions.length > 0 && closeAllOpen && onClosePosition && /* @__PURE__ */ jsxRuntime.jsx(CloseAllOverlay, { onClick: () => setCloseAllOpen(false), children: /* @__PURE__ */ jsxRuntime.jsxs(CloseAllModal, { onClick: (e) => e.stopPropagation(), children: [
14881
- /* @__PURE__ */ jsxRuntime.jsx(CloseAllModalX, { onClick: () => setCloseAllOpen(false), children: "\xD7" }),
14882
- /* @__PURE__ */ jsxRuntime.jsx(CloseAllTitle, { children: "Confirm Sell All" }),
14883
- /* @__PURE__ */ jsxRuntime.jsx(CloseAllDesc, { children: "This will sell all your positions and cancel their associated TP/SL orders." }),
14884
- /* @__PURE__ */ jsxRuntime.jsxs(CloseAllOption, { onClick: () => setCloseAllType("market"), children: [
14885
- /* @__PURE__ */ jsxRuntime.jsx(CloseAllRadio, { $selected: closeAllType === "market" }),
14886
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Market Sell" })
14887
- ] }),
14888
- /* @__PURE__ */ jsxRuntime.jsxs(CloseAllOption, { onClick: () => setCloseAllType("limit"), children: [
14889
- /* @__PURE__ */ jsxRuntime.jsx(CloseAllRadio, { $selected: closeAllType === "limit" }),
14890
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Limit Sell at Mid Price" })
14891
- ] }),
14892
- /* @__PURE__ */ jsxRuntime.jsxs(CloseAllConfirmBtn, { onClick: () => {
14893
- positions.forEach((pos) => onClosePosition(pos.tokenName, closeAllType, pos.quantity, pos.marketPrice));
14894
- setCloseAllOpen(false);
14895
- }, children: [
14896
- "Confirm ",
14897
- closeAllType === "market" ? "Market" : "Limit",
14898
- " Sell"
14899
- ] })
14900
- ] }) })
15400
+ positions.length > 0 && closeAllOpen && onClosePosition && typeof document !== "undefined" && ReactDOM.createPortal(
15401
+ /* @__PURE__ */ jsxRuntime.jsx(CloseAllOverlay, { onClick: () => setCloseAllOpen(false), children: /* @__PURE__ */ jsxRuntime.jsxs(CloseAllModal, { onClick: (e) => e.stopPropagation(), children: [
15402
+ /* @__PURE__ */ jsxRuntime.jsx(CloseAllModalX, { onClick: () => setCloseAllOpen(false), children: "\xD7" }),
15403
+ /* @__PURE__ */ jsxRuntime.jsx(CloseAllTitle, { children: "Confirm Sell All" }),
15404
+ /* @__PURE__ */ jsxRuntime.jsx(CloseAllDesc, { children: "This will sell all your positions and cancel their associated TP/SL orders." }),
15405
+ /* @__PURE__ */ jsxRuntime.jsxs(CloseAllOption, { onClick: () => setCloseAllType("market"), children: [
15406
+ /* @__PURE__ */ jsxRuntime.jsx(CloseAllRadio, { $selected: closeAllType === "market" }),
15407
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Market Sell" })
15408
+ ] }),
15409
+ /* @__PURE__ */ jsxRuntime.jsxs(CloseAllOption, { onClick: () => setCloseAllType("limit"), children: [
15410
+ /* @__PURE__ */ jsxRuntime.jsx(CloseAllRadio, { $selected: closeAllType === "limit" }),
15411
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Limit Sell at Mid Price" })
15412
+ ] }),
15413
+ /* @__PURE__ */ jsxRuntime.jsxs(CloseAllConfirmBtn, { onClick: () => {
15414
+ positions.forEach((pos) => onClosePosition(pos.tokenName, closeAllType, pos.quantity, pos.marketPrice));
15415
+ setCloseAllOpen(false);
15416
+ }, children: [
15417
+ "Confirm ",
15418
+ closeAllType === "market" ? "Market" : "Limit",
15419
+ " Sell"
15420
+ ] })
15421
+ ] }) }),
15422
+ document.body
15423
+ )
14901
15424
  ] }),
14902
15425
  activeTab === "subscriptions" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
14903
15426
  offeringOrders.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { children: "IPO allocations will appear here once you subscribe." }),
@@ -15354,57 +15877,63 @@ function PortfolioActivityPanel({
15354
15877
  ] }),
15355
15878
  /* @__PURE__ */ jsxRuntime.jsx(PaginationBtn, { disabled: currentPage >= totalPages - 1, onClick: () => setCurrentPage((p) => p + 1), children: "Next \u203A" })
15356
15879
  ] }),
15357
- cancelAllConfirmOpen && /* @__PURE__ */ jsxRuntime.jsx(CancelConfirmOverlay, { onClick: () => setCancelAllConfirmOpen(false), children: /* @__PURE__ */ jsxRuntime.jsxs(CancelConfirmModal, { onClick: (e) => e.stopPropagation(), children: [
15358
- /* @__PURE__ */ jsxRuntime.jsx(CancelConfirmTitle, { children: "Cancel All Orders" }),
15359
- /* @__PURE__ */ jsxRuntime.jsxs(CancelConfirmBody, { children: [
15360
- "Are you sure you want to cancel all ",
15361
- openOrdersCount,
15362
- " open orders? This action cannot be undone."
15363
- ] }),
15364
- /* @__PURE__ */ jsxRuntime.jsxs(CancelConfirmActions, { children: [
15365
- /* @__PURE__ */ jsxRuntime.jsx(CancelConfirmDismiss, { type: "button", onClick: () => setCancelAllConfirmOpen(false), children: "Keep Orders" }),
15366
- /* @__PURE__ */ jsxRuntime.jsx(
15367
- CancelConfirmProceed,
15368
- {
15369
- type: "button",
15370
- disabled: cancellingAll,
15371
- onClick: async () => {
15372
- if (onCancelAllOrders) {
15373
- setCancellingAll(true);
15374
- try {
15375
- await onCancelAllOrders();
15376
- } finally {
15377
- setCancellingAll(false);
15880
+ cancelAllConfirmOpen && typeof document !== "undefined" && ReactDOM.createPortal(
15881
+ /* @__PURE__ */ jsxRuntime.jsx(CancelConfirmOverlay, { onClick: () => setCancelAllConfirmOpen(false), children: /* @__PURE__ */ jsxRuntime.jsxs(CancelConfirmModal, { onClick: (e) => e.stopPropagation(), children: [
15882
+ /* @__PURE__ */ jsxRuntime.jsx(CancelConfirmTitle, { children: "Cancel All Orders" }),
15883
+ /* @__PURE__ */ jsxRuntime.jsxs(CancelConfirmBody, { children: [
15884
+ "Are you sure you want to cancel all ",
15885
+ openOrdersCount,
15886
+ " open orders? This action cannot be undone."
15887
+ ] }),
15888
+ /* @__PURE__ */ jsxRuntime.jsxs(CancelConfirmActions, { children: [
15889
+ /* @__PURE__ */ jsxRuntime.jsx(CancelConfirmDismiss, { type: "button", onClick: () => setCancelAllConfirmOpen(false), children: "Keep Orders" }),
15890
+ /* @__PURE__ */ jsxRuntime.jsx(
15891
+ CancelConfirmProceed,
15892
+ {
15893
+ type: "button",
15894
+ disabled: cancellingAll,
15895
+ onClick: async () => {
15896
+ if (onCancelAllOrders) {
15897
+ setCancellingAll(true);
15898
+ try {
15899
+ await onCancelAllOrders();
15900
+ } finally {
15901
+ setCancellingAll(false);
15902
+ }
15378
15903
  }
15379
- }
15380
- setCancelAllConfirmOpen(false);
15381
- },
15382
- children: cancellingAll ? "Cancelling\u2026" : "Yes, Cancel All"
15383
- }
15384
- )
15385
- ] })
15386
- ] }) }),
15387
- pendingCancelOrderId !== null && /* @__PURE__ */ jsxRuntime.jsx(CancelConfirmOverlay, { onClick: () => setPendingCancelOrderId(null), children: /* @__PURE__ */ jsxRuntime.jsxs(CancelConfirmModal, { onClick: (e) => e.stopPropagation(), children: [
15388
- /* @__PURE__ */ jsxRuntime.jsx(CancelConfirmTitle, { children: "Cancel Order" }),
15389
- /* @__PURE__ */ jsxRuntime.jsx(CancelConfirmBody, { children: "Are you sure you want to cancel this order? This action cannot be undone." }),
15390
- /* @__PURE__ */ jsxRuntime.jsxs(CancelConfirmActions, { children: [
15391
- /* @__PURE__ */ jsxRuntime.jsx(CancelConfirmDismiss, { type: "button", onClick: () => setPendingCancelOrderId(null), children: "Keep Order" }),
15392
- /* @__PURE__ */ jsxRuntime.jsx(
15393
- CancelConfirmProceed,
15394
- {
15395
- type: "button",
15396
- disabled: cancellingOrderId != null,
15397
- onClick: async () => {
15398
- if (onCancelOrder && pendingCancelOrderId !== null) {
15399
- await onCancelOrder(pendingCancelOrderId);
15400
- }
15401
- setPendingCancelOrderId(null);
15402
- },
15403
- children: cancellingOrderId === pendingCancelOrderId ? "Cancelling\u2026" : "Yes, Cancel"
15404
- }
15405
- )
15406
- ] })
15407
- ] }) })
15904
+ setCancelAllConfirmOpen(false);
15905
+ },
15906
+ children: cancellingAll ? "Cancelling\u2026" : "Yes, Cancel All"
15907
+ }
15908
+ )
15909
+ ] })
15910
+ ] }) }),
15911
+ document.body
15912
+ ),
15913
+ pendingCancelOrderId !== null && typeof document !== "undefined" && ReactDOM.createPortal(
15914
+ /* @__PURE__ */ jsxRuntime.jsx(CancelConfirmOverlay, { onClick: () => setPendingCancelOrderId(null), children: /* @__PURE__ */ jsxRuntime.jsxs(CancelConfirmModal, { onClick: (e) => e.stopPropagation(), children: [
15915
+ /* @__PURE__ */ jsxRuntime.jsx(CancelConfirmTitle, { children: "Cancel Order" }),
15916
+ /* @__PURE__ */ jsxRuntime.jsx(CancelConfirmBody, { children: "Are you sure you want to cancel this order? This action cannot be undone." }),
15917
+ /* @__PURE__ */ jsxRuntime.jsxs(CancelConfirmActions, { children: [
15918
+ /* @__PURE__ */ jsxRuntime.jsx(CancelConfirmDismiss, { type: "button", onClick: () => setPendingCancelOrderId(null), children: "Keep Order" }),
15919
+ /* @__PURE__ */ jsxRuntime.jsx(
15920
+ CancelConfirmProceed,
15921
+ {
15922
+ type: "button",
15923
+ disabled: cancellingOrderId != null,
15924
+ onClick: async () => {
15925
+ if (onCancelOrder && pendingCancelOrderId !== null) {
15926
+ await onCancelOrder(pendingCancelOrderId);
15927
+ }
15928
+ setPendingCancelOrderId(null);
15929
+ },
15930
+ children: cancellingOrderId === pendingCancelOrderId ? "Cancelling\u2026" : "Yes, Cancel"
15931
+ }
15932
+ )
15933
+ ] })
15934
+ ] }) }),
15935
+ document.body
15936
+ )
15408
15937
  ] });
15409
15938
  }
15410
15939
  var Container2 = styled10__default.default.div`
@@ -15475,7 +16004,7 @@ var Tab = styled10__default.default.button`
15475
16004
  }
15476
16005
  `;
15477
16006
  var TabCount = styled10__default.default.span`
15478
- color: #E6C656;
16007
+ color: var(--color-accent, #E6C87E);
15479
16008
  font-weight: 600;
15480
16009
  margin-left: 2px;
15481
16010
  `;
@@ -15660,7 +16189,8 @@ var CancelConfirmOverlay = styled10__default.default.div`
15660
16189
  display: flex;
15661
16190
  align-items: center;
15662
16191
  justify-content: center;
15663
- z-index: 1000;
16192
+ /* Above the trade page's fullscreen/sticky layers (TradePage.css uses up to 10001). */
16193
+ z-index: 10050;
15664
16194
  `;
15665
16195
  var CancelConfirmModal = styled10__default.default.div`
15666
16196
  background: #1a1a1a;
@@ -15774,7 +16304,8 @@ var CloseAllOverlay = styled10__default.default.div`
15774
16304
  display: flex;
15775
16305
  align-items: center;
15776
16306
  justify-content: center;
15777
- z-index: 1000;
16307
+ /* Above the trade page's fullscreen/sticky layers (TradePage.css uses up to 10001). */
16308
+ z-index: 10050;
15778
16309
  `;
15779
16310
  var CloseAllModal = styled10__default.default.div`
15780
16311
  background: #1a1a1a;