@loafmarkets/ui 0.1.404 → 0.1.405

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.d.mts CHANGED
@@ -706,11 +706,6 @@ type HeaderProps = {
706
706
  onOrdersNavigate?: () => void;
707
707
  onWalletNavigate?: () => void;
708
708
  onSettingsClick?: () => void;
709
- /** Fired by the "Refer" CTA button + user-menu "Refer" item. When omitted, both
710
- * fall back to `onSettingsClick` (so existing consumers are unchanged). Lets a
711
- * consumer route Refer somewhere other than Settings (e.g. an invite modal)
712
- * without DOM-level click interception. */
713
- onReferClick?: () => void;
714
709
  portfolioSummary?: HeaderPortfolioData | null;
715
710
  /**
716
711
  * True while a brand-new user's test funds (100k mock USD) are being deposited
@@ -721,7 +716,7 @@ type HeaderProps = {
721
716
  /**
722
717
  * The bar's authed CTA button. Defaults to "deposit" (the funding flow) so
723
718
  * existing consumers are unchanged. "refer" swaps it for a Refer button that
724
- * fires `onReferClick` (falling back to `onSettingsClick` when not provided).
719
+ * opens the Settings popup (same `onSettingsClick` as the user-menu Refer item).
725
720
  */
726
721
  headerCta?: "deposit" | "refer";
727
722
  /** Show the "Refer" user-menu item. Off by default — referral is feature-flagged
@@ -1098,7 +1093,7 @@ type ToastData = {
1098
1093
  amount?: string;
1099
1094
  /** On-chain tx hash — shown truncated with a block explorer link */
1100
1095
  txHash?: string;
1101
- /** Explorer base URL, defaults to Arbitrum Sepolia */
1096
+ /** Explorer base URL, defaults to Base Sepolia */
1102
1097
  explorerUrl?: string;
1103
1098
  /** Auto-dismiss after ms. 0 = never. Default 6000 */
1104
1099
  duration?: number;
@@ -1274,13 +1269,11 @@ type PropertyPhotoGalleryProps = {
1274
1269
  isOpen: boolean;
1275
1270
  onClose: () => void;
1276
1271
  startIndex?: number;
1277
- startWithVideo?: boolean;
1278
1272
  images?: PropertyGalleryImage[];
1279
1273
  title?: string;
1280
1274
  subtitle?: string;
1281
- videoUrl?: string;
1282
1275
  };
1283
- declare function PropertyPhotoGallery({ isOpen, onClose, startIndex, startWithVideo, title, subtitle, images, videoUrl, }: PropertyPhotoGalleryProps): react_jsx_runtime.JSX.Element | null;
1276
+ declare function PropertyPhotoGallery({ isOpen, onClose, startIndex, title, subtitle, images, }: PropertyPhotoGalleryProps): react_jsx_runtime.JSX.Element | null;
1284
1277
 
1285
1278
  type UseAdaptivePollingOptions = {
1286
1279
  enabled: boolean;
package/dist/index.d.ts CHANGED
@@ -706,11 +706,6 @@ type HeaderProps = {
706
706
  onOrdersNavigate?: () => void;
707
707
  onWalletNavigate?: () => void;
708
708
  onSettingsClick?: () => void;
709
- /** Fired by the "Refer" CTA button + user-menu "Refer" item. When omitted, both
710
- * fall back to `onSettingsClick` (so existing consumers are unchanged). Lets a
711
- * consumer route Refer somewhere other than Settings (e.g. an invite modal)
712
- * without DOM-level click interception. */
713
- onReferClick?: () => void;
714
709
  portfolioSummary?: HeaderPortfolioData | null;
715
710
  /**
716
711
  * True while a brand-new user's test funds (100k mock USD) are being deposited
@@ -721,7 +716,7 @@ type HeaderProps = {
721
716
  /**
722
717
  * The bar's authed CTA button. Defaults to "deposit" (the funding flow) so
723
718
  * existing consumers are unchanged. "refer" swaps it for a Refer button that
724
- * fires `onReferClick` (falling back to `onSettingsClick` when not provided).
719
+ * opens the Settings popup (same `onSettingsClick` as the user-menu Refer item).
725
720
  */
726
721
  headerCta?: "deposit" | "refer";
727
722
  /** Show the "Refer" user-menu item. Off by default — referral is feature-flagged
@@ -1098,7 +1093,7 @@ type ToastData = {
1098
1093
  amount?: string;
1099
1094
  /** On-chain tx hash — shown truncated with a block explorer link */
1100
1095
  txHash?: string;
1101
- /** Explorer base URL, defaults to Arbitrum Sepolia */
1096
+ /** Explorer base URL, defaults to Base Sepolia */
1102
1097
  explorerUrl?: string;
1103
1098
  /** Auto-dismiss after ms. 0 = never. Default 6000 */
1104
1099
  duration?: number;
@@ -1274,13 +1269,11 @@ type PropertyPhotoGalleryProps = {
1274
1269
  isOpen: boolean;
1275
1270
  onClose: () => void;
1276
1271
  startIndex?: number;
1277
- startWithVideo?: boolean;
1278
1272
  images?: PropertyGalleryImage[];
1279
1273
  title?: string;
1280
1274
  subtitle?: string;
1281
- videoUrl?: string;
1282
1275
  };
1283
- declare function PropertyPhotoGallery({ isOpen, onClose, startIndex, startWithVideo, title, subtitle, images, videoUrl, }: PropertyPhotoGalleryProps): react_jsx_runtime.JSX.Element | null;
1276
+ declare function PropertyPhotoGallery({ isOpen, onClose, startIndex, title, subtitle, images, }: PropertyPhotoGalleryProps): react_jsx_runtime.JSX.Element | null;
1284
1277
 
1285
1278
  type UseAdaptivePollingOptions = {
1286
1279
  enabled: boolean;
package/dist/index.js CHANGED
@@ -5101,7 +5101,6 @@ var Header = ({
5101
5101
  onOrdersNavigate: _onOrdersNavigate,
5102
5102
  onWalletNavigate: _onWalletNavigate,
5103
5103
  onSettingsClick,
5104
- onReferClick,
5105
5104
  portfolioSummary,
5106
5105
  fundsPending = false,
5107
5106
  transparentOnTop = false,
@@ -5540,7 +5539,7 @@ var Header = ({
5540
5539
  onClick: (event) => {
5541
5540
  event?.preventDefault();
5542
5541
  closeMenus();
5543
- (onReferClick ?? onSettingsClick)?.();
5542
+ onSettingsClick?.();
5544
5543
  },
5545
5544
  children: "Refer"
5546
5545
  }
@@ -5583,7 +5582,7 @@ var Header = ({
5583
5582
  onClick: (event) => {
5584
5583
  event?.preventDefault();
5585
5584
  closeMenus();
5586
- (onReferClick ?? onSettingsClick)?.();
5585
+ onSettingsClick?.();
5587
5586
  },
5588
5587
  children: /* @__PURE__ */ jsxRuntime.jsx(MenuItem, { children: "Refer" })
5589
5588
  }
@@ -7576,7 +7575,6 @@ var LoginPopup = ({
7576
7575
  ] })
7577
7576
  ] });
7578
7577
  if (gate) {
7579
- const codeAccepted = codeStatus === "valid";
7580
7578
  const showSignIn = signInMode || signInRevealed;
7581
7579
  return /* @__PURE__ */ jsxRuntime.jsxs(GateShell, { children: [
7582
7580
  /* @__PURE__ */ jsxRuntime.jsx(GateTint, { $reveal: showSignIn ? 1 : 0 }),
@@ -7602,35 +7600,30 @@ var LoginPopup = ({
7602
7600
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7603
7601
  /* @__PURE__ */ jsxRuntime.jsxs(CodeInputWrapper, { $status: codeStatus, children: [
7604
7602
  /* @__PURE__ */ jsxRuntime.jsx(CodePrefix, { children: CODE_PREFIX }),
7605
- codeInput,
7606
- /* @__PURE__ */ jsxRuntime.jsx(
7607
- GateSubmit,
7608
- {
7609
- type: "button",
7610
- "aria-label": "Submit access code",
7611
- $status: codeStatus,
7612
- disabled: codeStatus === "checking" || !codeComplete,
7613
- onClick: () => void runCodeValidation(referralCode),
7614
- 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" }) })
7615
- }
7616
- )
7603
+ codeInput
7617
7604
  ] }),
7618
7605
  (codeStatus === "invalid" || error && !signInRevealed) && /* @__PURE__ */ jsxRuntime.jsx(StatusMessage, { $error: true, children: error || "That code isn't valid. Double-check and try again." }),
7619
- signInRevealed ? signInStep : /* @__PURE__ */ jsxRuntime.jsxs(GateResendText, { children: [
7620
- "Already have an account?",
7621
- " ",
7622
- /* @__PURE__ */ jsxRuntime.jsx(
7623
- "button",
7624
- {
7625
- type: "button",
7626
- onClick: () => {
7627
- setError("");
7628
- setIsSignUp(false);
7629
- setSignInMode(true);
7630
- },
7631
- children: "Sign in"
7632
- }
7633
- )
7606
+ signInRevealed ? signInStep : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7607
+ /* @__PURE__ */ jsxRuntime.jsxs(GateResendText, { children: [
7608
+ "Already have an account?",
7609
+ " ",
7610
+ /* @__PURE__ */ jsxRuntime.jsx(
7611
+ "button",
7612
+ {
7613
+ type: "button",
7614
+ onClick: () => {
7615
+ setError("");
7616
+ setIsSignUp(false);
7617
+ setSignInMode(true);
7618
+ },
7619
+ children: "Sign in"
7620
+ }
7621
+ )
7622
+ ] }),
7623
+ /* @__PURE__ */ jsxRuntime.jsxs(GateEarlyAccess, { href: "https://loafmarkets.com/?waitlist=1", children: [
7624
+ "Signup for early access",
7625
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { 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" }) })
7626
+ ] })
7634
7627
  ] })
7635
7628
  ] })
7636
7629
  ] })
@@ -7707,12 +7700,12 @@ var LoginPopup = ({
7707
7700
  marginBottom: "1.25rem"
7708
7701
  }, children: [
7709
7702
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: 7, height: 7, borderRadius: "50%", background: "#0052FF", flexShrink: 0 } }),
7710
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.72rem", fontWeight: 600, color: "#6b9fff", letterSpacing: "0.02em" }, children: "Arbitrum Sepolia" })
7703
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.72rem", fontWeight: 600, color: "#6b9fff", letterSpacing: "0.02em" }, children: "Base Sepolia" })
7711
7704
  ] }),
7712
7705
  /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { fontSize: "0.82rem", color: "rgba(255,255,255,0.5)", textAlign: "center", marginBottom: "1.1rem", lineHeight: 1.5, maxWidth: 320 }, children: [
7713
7706
  "Send ",
7714
7707
  /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { color: "rgba(255,255,255,0.8)" }, children: "USDC" }),
7715
- " on Arbitrum Sepolia to the address below. Only send on this network."
7708
+ " on Base Sepolia to the address below. Only send on this network."
7716
7709
  ] }),
7717
7710
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
7718
7711
  width: "100%",
@@ -8253,6 +8246,33 @@ var GateResendText = styled10__default.default.p`
8253
8246
  font-size: inherit;
8254
8247
  }
8255
8248
  `;
8249
+ var GateEarlyAccess = styled10__default.default.a`
8250
+ display: inline-flex;
8251
+ align-items: center;
8252
+ gap: 0.4rem;
8253
+ margin-top: 0.15rem;
8254
+ color: var(--color-text-secondary, #848e9c);
8255
+ font-size: 0.8rem;
8256
+ font-weight: 500;
8257
+ letter-spacing: 0.02em;
8258
+ text-decoration: none;
8259
+ cursor: pointer;
8260
+ transition: color 0.15s ease;
8261
+
8262
+ svg {
8263
+ width: 13px;
8264
+ height: 13px;
8265
+ transition: transform 0.15s ease;
8266
+ }
8267
+
8268
+ &:hover {
8269
+ color: var(--color-accent, #E6C87E);
8270
+ }
8271
+
8272
+ &:hover svg {
8273
+ transform: translateX(3px);
8274
+ }
8275
+ `;
8256
8276
  var GateSubmit = styled10__default.default.button`
8257
8277
  display: flex;
8258
8278
  align-items: center;
@@ -10330,7 +10350,7 @@ function PropertyOverview({
10330
10350
  isLoading = false,
10331
10351
  ticker,
10332
10352
  contractAddress,
10333
- chain = "Arbitrum (Ethereum L2)",
10353
+ chain = "Base (Ethereum L2)",
10334
10354
  volume24h,
10335
10355
  priceHistory: priceHistoryProp,
10336
10356
  beta = false,
@@ -10369,13 +10389,13 @@ function PropertyOverview({
10369
10389
  const resolvedPropertyType = rawPropertyType?.toLowerCase() === "house" ? "Residential" : rawPropertyType;
10370
10390
  const galleryImages = images ?? [];
10371
10391
  const chainValue = /* @__PURE__ */ jsxRuntime.jsxs(ChainLogos, { children: [
10372
- /* @__PURE__ */ jsxRuntime.jsx(ChainLogoImg, { src: "/Arbitrum-Symbol.svg", alt: "Arbitrum" }),
10392
+ /* @__PURE__ */ jsxRuntime.jsx(ChainLogoImg, { src: "/Base-Symbol.png", alt: "Base" }),
10373
10393
  /* @__PURE__ */ jsxRuntime.jsx(ChainLogoImg, { src: "/Ethereum-Logo.png", alt: "Ethereum", style: { filter: "brightness(0) invert(1)" } }),
10374
10394
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: chain })
10375
10395
  ] });
10376
10396
  const tokenDetailsItems = [
10377
10397
  { label: "Chain", value: chainValue },
10378
- { label: "On-Chain Address", value: contractAddress ? truncateAddress(contractAddress) : "\u2014", mono: true, link: contractAddress ? `https://sepolia.arbiscan.io/address/${contractAddress}` : void 0, copyValue: contractAddress },
10398
+ { label: "On-Chain Address", value: contractAddress ? truncateAddress(contractAddress) : "\u2014", mono: true, link: contractAddress ? `https://sepolia.basescan.org/address/${contractAddress}` : void 0, copyValue: contractAddress },
10379
10399
  { label: "Token Ticker", value: ticker ?? "\u2014" },
10380
10400
  { label: "Total Circulating Tokens", value: isLoading && resolvedTokensIssued == null ? loadingSkeleton : resolvedTokensIssued?.toLocaleString() ?? "\u2014" },
10381
10401
  { label: "Legal Structuring", value: "See Documents", docLink: true },
@@ -10395,9 +10415,7 @@ function PropertyOverview({
10395
10415
  ];
10396
10416
  const growthPct = overviewData?.growth5Yr;
10397
10417
  const propertyStats = [
10398
- // Property Value = the API offeringValuation (OverviewResponse.offeringValuation), NOT
10399
- // midPrice×tokensIssued market cap (fixed 2026-07-22). null → '—', never a fabricated cap.
10400
- { label: "Property Value", value: isLoading && overviewData?.offeringValuation == null ? loadingSkeleton : overviewData?.offeringValuation ? fmtDollar(overviewData.offeringValuation) : "\u2014" },
10418
+ { label: "Property Value", value: isLoading && tokenMarketCap == null ? loadingSkeleton : tokenMarketCap ? fmtDollar(tokenMarketCap) : "\u2014" },
10401
10419
  ...beta ? [] : [{ label: "Offers", value: "3" }],
10402
10420
  { label: "Growth (5yr)", value: growthPct != null ? `${growthPct > 0 ? "+" : ""}${growthPct}%` : "\u2014" },
10403
10421
  { label: "Last Dividend", value: overviewData?.lastDividend != null ? `$${overviewData.lastDividend.toFixed(2)}` : "\u2014" },
@@ -14898,7 +14916,7 @@ var getOrderStatusMeta = (statusRaw) => {
14898
14916
  return { color: "#E6C87E", bg: "rgba(240,185,11,0.15)" };
14899
14917
  };
14900
14918
  var ChevronDown = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "rgba(255,255,255,0.5)", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "6 9 12 15 18 9" }) });
14901
- var ArbiscanIconLink = ({ url }) => /* @__PURE__ */ jsxRuntime.jsx(TxLink, { href: url, target: "_blank", rel: "noopener noreferrer", title: "View on Arbiscan", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
14919
+ var BaseScanIconLink = ({ url }) => /* @__PURE__ */ jsxRuntime.jsx(TxLink, { href: url, target: "_blank", rel: "noopener noreferrer", title: "View on BaseScan", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
14902
14920
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
14903
14921
  /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "15 3 21 3 21 9" }),
14904
14922
  /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
@@ -14923,7 +14941,7 @@ function PortfolioActivityPanel({
14923
14941
  defaultTab,
14924
14942
  onTabChange,
14925
14943
  pageSize = ACTIVITY_PAGE_SIZE_DEFAULT,
14926
- blockExplorerBaseUrl: _blockExplorerBaseUrl = "https://sepolia.arbiscan.io/tx",
14944
+ blockExplorerBaseUrl: _blockExplorerBaseUrl = "https://sepolia.basescan.org/tx",
14927
14945
  className,
14928
14946
  style
14929
14947
  }) {
@@ -15367,7 +15385,7 @@ function PortfolioActivityPanel({
15367
15385
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: "0.35rem" }, children: [
15368
15386
  formatNumber2(order.quantity),
15369
15387
  order.ticker && /* @__PURE__ */ jsxRuntime.jsx(TickerTag, { style: { marginLeft: 0 }, children: order.ticker.toUpperCase() }),
15370
- order.txHash && /* @__PURE__ */ jsxRuntime.jsx(ArbiscanIconLink, { url: `${_blockExplorerBaseUrl}/${order.txHash}` })
15388
+ order.txHash && /* @__PURE__ */ jsxRuntime.jsx(BaseScanIconLink, { url: `${_blockExplorerBaseUrl}/${order.txHash}` })
15371
15389
  ] })
15372
15390
  ] }),
15373
15391
  /* @__PURE__ */ jsxRuntime.jsxs(CUnitsCell, { children: [
@@ -15420,7 +15438,7 @@ function PortfolioActivityPanel({
15420
15438
  order.status === "REJECTED" && order.rejectionReason && /* @__PURE__ */ jsxRuntime.jsx(CellText, { $muted: true, style: { fontSize: "0.62rem", marginTop: "0.2rem", maxWidth: "120px", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, title: order.rejectionReason, children: order.rejectionReason })
15421
15439
  ] }),
15422
15440
  /* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: /* @__PURE__ */ jsxRuntime.jsx(CellText, { $muted: true, children: formatTimestamp(order.createdAt) }) }),
15423
- /* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: order.txHash && /* @__PURE__ */ jsxRuntime.jsx(TxLink, { href: `${_blockExplorerBaseUrl}/${order.txHash}`, target: "_blank", rel: "noopener noreferrer", title: "View on Arbiscan", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
15441
+ /* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: order.txHash && /* @__PURE__ */ jsxRuntime.jsx(TxLink, { href: `${_blockExplorerBaseUrl}/${order.txHash}`, target: "_blank", rel: "noopener noreferrer", title: "View on BaseScan", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
15424
15442
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
15425
15443
  /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "15 3 21 3 21 9" }),
15426
15444
  /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
@@ -15664,7 +15682,7 @@ function PortfolioActivityPanel({
15664
15682
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: "0.35rem" }, children: [
15665
15683
  formatNumber2(trade.quantity),
15666
15684
  trade.ticker && /* @__PURE__ */ jsxRuntime.jsx(TickerTag, { style: { marginLeft: 0 }, children: trade.ticker.toUpperCase() }),
15667
- trade.txHash && /* @__PURE__ */ jsxRuntime.jsx(ArbiscanIconLink, { url: `${_blockExplorerBaseUrl}/${trade.txHash}` })
15685
+ trade.txHash && /* @__PURE__ */ jsxRuntime.jsx(BaseScanIconLink, { url: `${_blockExplorerBaseUrl}/${trade.txHash}` })
15668
15686
  ] })
15669
15687
  ] }),
15670
15688
  /* @__PURE__ */ jsxRuntime.jsxs(CUnitsCell, { children: [
@@ -15731,7 +15749,7 @@ function PortfolioActivityPanel({
15731
15749
  /* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: /* @__PURE__ */ jsxRuntime.jsx(CellText, { children: formatCurrency4(trade.price * trade.quantity) }) }),
15732
15750
  /* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: settlementMeta ? /* @__PURE__ */ jsxRuntime.jsx(ActivityTag, { $color: settlementMeta.color, $bg: settlementMeta.bg, children: settlementLabel }) : /* @__PURE__ */ jsxRuntime.jsx(CellText, { $muted: true, children: "\u2014" }) }),
15733
15751
  /* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: /* @__PURE__ */ jsxRuntime.jsx(CellText, { $muted: true, children: formatTimestamp(trade.executedAt) }) }),
15734
- /* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: trade.txHash && /* @__PURE__ */ jsxRuntime.jsx(TxLink, { href: `${_blockExplorerBaseUrl}/${trade.txHash}`, target: "_blank", rel: "noopener noreferrer", title: "View on Arbiscan", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
15752
+ /* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: trade.txHash && /* @__PURE__ */ jsxRuntime.jsx(TxLink, { href: `${_blockExplorerBaseUrl}/${trade.txHash}`, target: "_blank", rel: "noopener noreferrer", title: "View on BaseScan", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
15735
15753
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
15736
15754
  /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "15 3 21 3 21 9" }),
15737
15755
  /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
@@ -15778,7 +15796,7 @@ function PortfolioActivityPanel({
15778
15796
  /* @__PURE__ */ jsxRuntime.jsx(CDValue, { children: formatTimestamp(t.createdAt) })
15779
15797
  ] })
15780
15798
  ] }),
15781
- txUrl && /* @__PURE__ */ jsxRuntime.jsx(CExpandedLink, { href: txUrl, target: "_blank", rel: "noopener noreferrer", children: "View on Arbiscan \u2197" })
15799
+ txUrl && /* @__PURE__ */ jsxRuntime.jsx(CExpandedLink, { href: txUrl, target: "_blank", rel: "noopener noreferrer", children: "View on BaseScan \u2197" })
15782
15800
  ] })
15783
15801
  ] }, rowKey);
15784
15802
  }),
@@ -15804,7 +15822,7 @@ function PortfolioActivityPanel({
15804
15822
  /* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: /* @__PURE__ */ jsxRuntime.jsx(CellText, { $muted: true, children: formatAddress(t.address) }) }),
15805
15823
  /* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: /* @__PURE__ */ jsxRuntime.jsx(ActivityTag, { $color: statusMeta.color, $bg: statusMeta.bg, children: prettyLabel(t.status) }) }),
15806
15824
  /* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: /* @__PURE__ */ jsxRuntime.jsx(CellText, { $muted: true, children: formatTimestamp(t.createdAt) }) }),
15807
- /* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: txUrl && /* @__PURE__ */ jsxRuntime.jsx(TxLink, { href: txUrl, target: "_blank", rel: "noopener noreferrer", title: "View on Arbiscan", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
15825
+ /* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: txUrl && /* @__PURE__ */ jsxRuntime.jsx(TxLink, { href: txUrl, target: "_blank", rel: "noopener noreferrer", title: "View on BaseScan", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
15808
15826
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
15809
15827
  /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "15 3 21 3 21 9" }),
15810
15828
  /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
@@ -18907,14 +18925,13 @@ var CloseButton3 = styled10__default.default.button`
18907
18925
  var MainImageContainer = styled10__default.default.div`
18908
18926
  position: relative;
18909
18927
  flex: 1;
18910
- min-height: 0;
18911
18928
  display: flex;
18912
18929
  align-items: center;
18913
18930
  justify-content: center;
18914
- padding: 20px 20px 160px;
18931
+ padding: 80px 20px 140px;
18915
18932
 
18916
18933
  @media (max-width: 768px) {
18917
- padding: 10px 0 130px;
18934
+ padding: 60px 0 110px;
18918
18935
  }
18919
18936
  `;
18920
18937
  var MainImage = styled10__default.default.img`
@@ -18926,11 +18943,8 @@ var MainImage = styled10__default.default.img`
18926
18943
  opacity: ${(p) => p.$visible ? 1 : 0};
18927
18944
  pointer-events: ${(p) => p.$visible ? "auto" : "none"};
18928
18945
  transition: opacity 300ms ease;
18929
- /* All slides share the same absolute box so switching only crossfades opacity
18930
- no relative↔absolute size jump (the "grow then shrink" on navigation).
18931
- The inset box excludes the bottom thumbnail strip so margin:auto centres the image
18932
- in the space ABOVE the thumbnails (absolute positioning ignores the parent's padding,
18933
- which otherwise let the image sink behind the thumbnails / "lean down"). */
18946
+ /* Inset box excludes the bottom thumbnail strip so margin:auto centres the image in the
18947
+ space ABOVE the thumbnails (absolute ignores the parent's padding). */
18934
18948
  position: absolute;
18935
18949
  top: 24px;
18936
18950
  left: 24px;
@@ -19124,11 +19138,9 @@ function PropertyPhotoGallery({
19124
19138
  isOpen,
19125
19139
  onClose,
19126
19140
  startIndex = 0,
19127
- startWithVideo = false,
19128
19141
  title = "28 Derby Street, Vaucluse",
19129
19142
  subtitle = "Elara \u2014 Luxury Harbour Residence",
19130
- images,
19131
- videoUrl
19143
+ images
19132
19144
  }) {
19133
19145
  const galleryImages = images?.length ? images : DEFAULT_IMAGES;
19134
19146
  if (!isOpen) return null;
@@ -19137,19 +19149,16 @@ function PropertyPhotoGallery({
19137
19149
  {
19138
19150
  galleryImages,
19139
19151
  startIndex,
19140
- startWithVideo,
19141
19152
  title,
19142
19153
  subtitle,
19143
- onClose,
19144
- videoUrl
19154
+ onClose
19145
19155
  },
19146
- `${startIndex}-${galleryImages.length}-${startWithVideo}`
19156
+ `${startIndex}-${galleryImages.length}`
19147
19157
  );
19148
19158
  }
19149
- function GalleryContent({ galleryImages, startIndex, startWithVideo, title, subtitle, onClose, videoUrl }) {
19159
+ function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose }) {
19150
19160
  const [currentIndex, setCurrentIndex] = React5.useState(() => clampIndex(startIndex, galleryImages.length));
19151
19161
  const [activeHotspotId, setActiveHotspotId] = React5.useState(null);
19152
- const [showVideo, setShowVideo] = React5.useState(startWithVideo ?? false);
19153
19162
  const sliderRef = React5.useRef(null);
19154
19163
  const [isDragging, setIsDragging] = React5.useState(false);
19155
19164
  const wasDraggingRef = React5.useRef(false);
@@ -19199,7 +19208,7 @@ function GalleryContent({ galleryImages, startIndex, startWithVideo, title, subt
19199
19208
  ] }),
19200
19209
  /* @__PURE__ */ jsxRuntime.jsx(CloseButton3, { onClick: onClose, "aria-label": "Close gallery", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", width: "22", height: "22", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 6l12 12M6 18L18 6" }) }) })
19201
19210
  ] }),
19202
- !showVideo && /* @__PURE__ */ jsxRuntime.jsxs(SliderContainer, { onClick: (event) => event.stopPropagation(), children: [
19211
+ /* @__PURE__ */ jsxRuntime.jsxs(SliderContainer, { onClick: (event) => event.stopPropagation(), children: [
19203
19212
  /* @__PURE__ */ jsxRuntime.jsxs(
19204
19213
  SliderTrack,
19205
19214
  {
@@ -19262,21 +19271,7 @@ function GalleryContent({ galleryImages, startIndex, startWithVideo, title, subt
19262
19271
  children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", width: "22", height: "22", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 18l-6-6 6-6" }) })
19263
19272
  }
19264
19273
  ),
19265
- showVideo && videoUrl ? /* @__PURE__ */ jsxRuntime.jsx(GalleryVideoWrap, { children: /* @__PURE__ */ jsxRuntime.jsx(
19266
- "video",
19267
- {
19268
- autoPlay: true,
19269
- loop: true,
19270
- playsInline: true,
19271
- muted: true,
19272
- controls: true,
19273
- onVolumeChange: (e) => {
19274
- if (!e.currentTarget.muted) e.currentTarget.muted = true;
19275
- },
19276
- style: { objectFit: "contain", borderRadius: 12, boxShadow: "0 30px 80px rgba(0,0,0,0.55)" },
19277
- children: /* @__PURE__ */ jsxRuntime.jsx("source", { src: videoUrl, type: "video/mp4" })
19278
- }
19279
- ) }) : galleryImages.map((image, idx) => /* @__PURE__ */ jsxRuntime.jsx(MainImage, { src: image.src, alt: image.alt, $visible: idx === currentIndex }, image.alt)),
19274
+ galleryImages.map((image, idx) => /* @__PURE__ */ jsxRuntime.jsx(MainImage, { src: image.src, alt: image.alt, $visible: idx === currentIndex }, image.alt)),
19280
19275
  galleryImages[currentIndex]?.hotspots?.map((hotspot) => /* @__PURE__ */ jsxRuntime.jsx(
19281
19276
  Hotspot,
19282
19277
  {
@@ -19321,83 +19316,11 @@ function GalleryContent({ galleryImages, startIndex, startWithVideo, title, subt
19321
19316
  ]
19322
19317
  }
19323
19318
  ),
19324
- /* @__PURE__ */ jsxRuntime.jsxs(ThumbnailStrip, { onClick: (event) => event.stopPropagation(), children: [
19325
- galleryImages.map((image, idx) => /* @__PURE__ */ jsxRuntime.jsx(Thumbnail3, { $active: !showVideo && idx === currentIndex, onClick: () => {
19326
- setShowVideo(false);
19327
- setCurrentIndex(idx);
19328
- }, "aria-label": `Preview ${image.label}`, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: image.src, alt: image.alt }) }, image.alt)),
19329
- videoUrl && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19330
- /* @__PURE__ */ jsxRuntime.jsx(ThumbnailDivider, {}),
19331
- /* @__PURE__ */ jsxRuntime.jsxs(VideoBtn, { $active: showVideo, onClick: () => setShowVideo(true), children: [
19332
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
19333
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "2", y: "4", width: "14", height: "16", rx: "2" }),
19334
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 8l6-4v16l-6-4z" })
19335
- ] }),
19336
- "Video"
19337
- ] })
19338
- ] })
19339
- ] })
19319
+ /* @__PURE__ */ jsxRuntime.jsx(ThumbnailStrip, { onClick: (event) => event.stopPropagation(), children: galleryImages.map((image, idx) => /* @__PURE__ */ jsxRuntime.jsx(Thumbnail3, { $active: idx === currentIndex, onClick: () => setCurrentIndex(idx), "aria-label": `Preview ${image.label}`, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: image.src, alt: image.alt }) }, image.alt)) })
19340
19320
  ]
19341
19321
  }
19342
19322
  );
19343
19323
  }
19344
- var GalleryVideoWrap = styled10__default.default.div`
19345
- position: absolute;
19346
- inset: 0;
19347
- display: flex;
19348
- align-items: center;
19349
- justify-content: center;
19350
- padding: 20px 20px 160px;
19351
-
19352
- video {
19353
- max-width: 90%;
19354
- max-height: 100%;
19355
- }
19356
-
19357
- /* Property videos stay permanently muted — remove the volume + mute buttons
19358
- from the native player (Chrome/Edge/Safari/iOS/Android). Firefox ignores
19359
- these and is covered by the onVolumeChange force-mute fallback. */
19360
- video::-webkit-media-controls-mute-button,
19361
- video::-webkit-media-controls-volume-slider,
19362
- video::-webkit-media-controls-volume-control-container {
19363
- display: none !important;
19364
- }
19365
-
19366
- @media (max-width: 768px) {
19367
- padding: 10px 0 130px;
19368
-
19369
- video {
19370
- max-width: 100%;
19371
- }
19372
- }
19373
- `;
19374
- var ThumbnailDivider = styled10__default.default.div`
19375
- width: 1px;
19376
- height: 48px;
19377
- background: rgba(255, 255, 255, 0.15);
19378
- flex-shrink: 0;
19379
- align-self: center;
19380
- `;
19381
- var VideoBtn = styled10__default.default.button`
19382
- display: flex;
19383
- align-items: center;
19384
- gap: 6px;
19385
- padding: 8px 14px;
19386
- border-radius: 8px;
19387
- border: 1px solid ${(p) => p.$active ? "var(--color-accent, #E6C87E)" : "rgba(255, 255, 255, 0.2)"};
19388
- background: ${(p) => p.$active ? "rgba(240, 185, 11, 0.15)" : "rgba(255, 255, 255, 0.08)"};
19389
- color: ${(p) => p.$active ? "var(--color-accent, #E6C87E)" : "#fff"};
19390
- font-size: 0.82rem;
19391
- font-weight: 500;
19392
- cursor: pointer;
19393
- flex-shrink: 0;
19394
- transition: all 0.2s ease;
19395
-
19396
- &:hover {
19397
- background: rgba(255, 255, 255, 0.15);
19398
- border-color: rgba(255, 255, 255, 0.3);
19399
- }
19400
- `;
19401
19324
  var slideIn2 = styled10.keyframes`
19402
19325
  from { transform: translateX(110%); opacity: 0; }
19403
19326
  to { transform: translateX(0); opacity: 1; }
@@ -19566,7 +19489,7 @@ var Container3 = styled10__default.default.div`
19566
19489
  gap: 8px;
19567
19490
  }
19568
19491
  `;
19569
- var DEFAULT_EXPLORER = "https://sepolia.arbiscan.io/tx/";
19492
+ var DEFAULT_EXPLORER = "https://sepolia.basescan.org/tx/";
19570
19493
  function truncateHash(hash) {
19571
19494
  return `${hash.slice(0, 6)}\u2026${hash.slice(-4)}`;
19572
19495
  }
@@ -20133,7 +20056,8 @@ var SiteFooter = () => {
20133
20056
  /* @__PURE__ */ jsxRuntime.jsxs(LegalLinks, { children: [
20134
20057
  /* @__PURE__ */ jsxRuntime.jsx(LegalLink, { href: "/privacy", children: "Privacy Policy" }),
20135
20058
  /* @__PURE__ */ jsxRuntime.jsx(LegalLink, { href: "/terms", children: "Terms of Use" }),
20136
- /* @__PURE__ */ jsxRuntime.jsx(LegalLink, { href: "/cookies", children: "Cookie Policy" })
20059
+ /* @__PURE__ */ jsxRuntime.jsx(LegalLink, { href: "/cookies", children: "Cookie Policy" }),
20060
+ /* @__PURE__ */ jsxRuntime.jsx(LegalLink, { href: "/risk", children: "Risk Warning" })
20137
20061
  ] })
20138
20062
  ] }),
20139
20063
  /* @__PURE__ */ jsxRuntime.jsx(Disclaimer2, { children: /* @__PURE__ */ jsxRuntime.jsx(DisclaimerText, { children: "Warning: Digital asset prices can be volatile. The value of your investment can go down or up and you may not get back the amount invested. Past gains are not indicative of future returns. You are solely responsible for your investment decisions and Loaf is not liable for any losses you may incur. The information here should not be regarded as financial or investment advice. For more information, see our Terms of Use and Risk Warning." }) })