@loafmarkets/ui 0.1.405 → 0.1.407

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.mjs CHANGED
@@ -5076,6 +5076,7 @@ var Header = ({
5076
5076
  onOrdersNavigate: _onOrdersNavigate,
5077
5077
  onWalletNavigate: _onWalletNavigate,
5078
5078
  onSettingsClick,
5079
+ onReferClick,
5079
5080
  portfolioSummary,
5080
5081
  fundsPending = false,
5081
5082
  transparentOnTop = false,
@@ -5514,7 +5515,7 @@ var Header = ({
5514
5515
  onClick: (event) => {
5515
5516
  event?.preventDefault();
5516
5517
  closeMenus();
5517
- onSettingsClick?.();
5518
+ (onReferClick ?? onSettingsClick)?.();
5518
5519
  },
5519
5520
  children: "Refer"
5520
5521
  }
@@ -5557,7 +5558,7 @@ var Header = ({
5557
5558
  onClick: (event) => {
5558
5559
  event?.preventDefault();
5559
5560
  closeMenus();
5560
- onSettingsClick?.();
5561
+ (onReferClick ?? onSettingsClick)?.();
5561
5562
  },
5562
5563
  children: /* @__PURE__ */ jsx(MenuItem, { children: "Refer" })
5563
5564
  }
@@ -7550,6 +7551,7 @@ var LoginPopup = ({
7550
7551
  ] })
7551
7552
  ] });
7552
7553
  if (gate) {
7554
+ const codeAccepted = codeStatus === "valid";
7553
7555
  const showSignIn = signInMode || signInRevealed;
7554
7556
  return /* @__PURE__ */ jsxs(GateShell, { children: [
7555
7557
  /* @__PURE__ */ jsx(GateTint, { $reveal: showSignIn ? 1 : 0 }),
@@ -7575,30 +7577,35 @@ var LoginPopup = ({
7575
7577
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
7576
7578
  /* @__PURE__ */ jsxs(CodeInputWrapper, { $status: codeStatus, children: [
7577
7579
  /* @__PURE__ */ jsx(CodePrefix, { children: CODE_PREFIX }),
7578
- codeInput
7580
+ codeInput,
7581
+ /* @__PURE__ */ jsx(
7582
+ GateSubmit,
7583
+ {
7584
+ type: "button",
7585
+ "aria-label": "Submit access code",
7586
+ $status: codeStatus,
7587
+ disabled: codeStatus === "checking" || !codeComplete,
7588
+ onClick: () => void runCodeValidation(referralCode),
7589
+ children: codeAccepted ? /* @__PURE__ */ jsx("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M20 6L9 17l-5-5" }) }) : codeStatus === "checking" ? /* @__PURE__ */ jsx(GateSpinner, {}) : /* @__PURE__ */ jsx("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M5 12h14M13 6l6 6-6 6" }) })
7590
+ }
7591
+ )
7579
7592
  ] }),
7580
7593
  (codeStatus === "invalid" || error && !signInRevealed) && /* @__PURE__ */ jsx(StatusMessage, { $error: true, children: error || "That code isn't valid. Double-check and try again." }),
7581
- signInRevealed ? signInStep : /* @__PURE__ */ jsxs(Fragment, { children: [
7582
- /* @__PURE__ */ jsxs(GateResendText, { children: [
7583
- "Already have an account?",
7584
- " ",
7585
- /* @__PURE__ */ jsx(
7586
- "button",
7587
- {
7588
- type: "button",
7589
- onClick: () => {
7590
- setError("");
7591
- setIsSignUp(false);
7592
- setSignInMode(true);
7593
- },
7594
- children: "Sign in"
7595
- }
7596
- )
7597
- ] }),
7598
- /* @__PURE__ */ jsxs(GateEarlyAccess, { href: "https://loafmarkets.com/?waitlist=1", children: [
7599
- "Signup for early access",
7600
- /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M5 12h14M13 6l6 6-6 6" }) })
7601
- ] })
7594
+ signInRevealed ? signInStep : /* @__PURE__ */ jsxs(GateResendText, { children: [
7595
+ "Already have an account?",
7596
+ " ",
7597
+ /* @__PURE__ */ jsx(
7598
+ "button",
7599
+ {
7600
+ type: "button",
7601
+ onClick: () => {
7602
+ setError("");
7603
+ setIsSignUp(false);
7604
+ setSignInMode(true);
7605
+ },
7606
+ children: "Sign in"
7607
+ }
7608
+ )
7602
7609
  ] })
7603
7610
  ] })
7604
7611
  ] })
@@ -7675,12 +7682,12 @@ var LoginPopup = ({
7675
7682
  marginBottom: "1.25rem"
7676
7683
  }, children: [
7677
7684
  /* @__PURE__ */ jsx("div", { style: { width: 7, height: 7, borderRadius: "50%", background: "#0052FF", flexShrink: 0 } }),
7678
- /* @__PURE__ */ jsx("span", { style: { fontSize: "0.72rem", fontWeight: 600, color: "#6b9fff", letterSpacing: "0.02em" }, children: "Base Sepolia" })
7685
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "0.72rem", fontWeight: 600, color: "#6b9fff", letterSpacing: "0.02em" }, children: "Arbitrum Sepolia" })
7679
7686
  ] }),
7680
7687
  /* @__PURE__ */ jsxs("p", { style: { fontSize: "0.82rem", color: "rgba(255,255,255,0.5)", textAlign: "center", marginBottom: "1.1rem", lineHeight: 1.5, maxWidth: 320 }, children: [
7681
7688
  "Send ",
7682
7689
  /* @__PURE__ */ jsx("strong", { style: { color: "rgba(255,255,255,0.8)" }, children: "USDC" }),
7683
- " on Base Sepolia to the address below. Only send on this network."
7690
+ " on Arbitrum Sepolia to the address below. Only send on this network."
7684
7691
  ] }),
7685
7692
  /* @__PURE__ */ jsxs("div", { style: {
7686
7693
  width: "100%",
@@ -8221,33 +8228,6 @@ var GateResendText = styled10.p`
8221
8228
  font-size: inherit;
8222
8229
  }
8223
8230
  `;
8224
- var GateEarlyAccess = styled10.a`
8225
- display: inline-flex;
8226
- align-items: center;
8227
- gap: 0.4rem;
8228
- margin-top: 0.15rem;
8229
- color: var(--color-text-secondary, #848e9c);
8230
- font-size: 0.8rem;
8231
- font-weight: 500;
8232
- letter-spacing: 0.02em;
8233
- text-decoration: none;
8234
- cursor: pointer;
8235
- transition: color 0.15s ease;
8236
-
8237
- svg {
8238
- width: 13px;
8239
- height: 13px;
8240
- transition: transform 0.15s ease;
8241
- }
8242
-
8243
- &:hover {
8244
- color: var(--color-accent, #E6C87E);
8245
- }
8246
-
8247
- &:hover svg {
8248
- transform: translateX(3px);
8249
- }
8250
- `;
8251
8231
  var GateSubmit = styled10.button`
8252
8232
  display: flex;
8253
8233
  align-items: center;
@@ -10325,7 +10305,7 @@ function PropertyOverview({
10325
10305
  isLoading = false,
10326
10306
  ticker,
10327
10307
  contractAddress,
10328
- chain = "Base (Ethereum L2)",
10308
+ chain = "Arbitrum (Ethereum L2)",
10329
10309
  volume24h,
10330
10310
  priceHistory: priceHistoryProp,
10331
10311
  beta = false,
@@ -10364,13 +10344,13 @@ function PropertyOverview({
10364
10344
  const resolvedPropertyType = rawPropertyType?.toLowerCase() === "house" ? "Residential" : rawPropertyType;
10365
10345
  const galleryImages = images ?? [];
10366
10346
  const chainValue = /* @__PURE__ */ jsxs(ChainLogos, { children: [
10367
- /* @__PURE__ */ jsx(ChainLogoImg, { src: "/Base-Symbol.png", alt: "Base" }),
10347
+ /* @__PURE__ */ jsx(ChainLogoImg, { src: "/Arbitrum-Symbol.svg", alt: "Arbitrum" }),
10368
10348
  /* @__PURE__ */ jsx(ChainLogoImg, { src: "/Ethereum-Logo.png", alt: "Ethereum", style: { filter: "brightness(0) invert(1)" } }),
10369
10349
  /* @__PURE__ */ jsx("span", { children: chain })
10370
10350
  ] });
10371
10351
  const tokenDetailsItems = [
10372
10352
  { label: "Chain", value: chainValue },
10373
- { label: "On-Chain Address", value: contractAddress ? truncateAddress(contractAddress) : "\u2014", mono: true, link: contractAddress ? `https://sepolia.basescan.org/address/${contractAddress}` : void 0, copyValue: contractAddress },
10353
+ { label: "On-Chain Address", value: contractAddress ? truncateAddress(contractAddress) : "\u2014", mono: true, link: contractAddress ? `https://sepolia.arbiscan.io/address/${contractAddress}` : void 0, copyValue: contractAddress },
10374
10354
  { label: "Token Ticker", value: ticker ?? "\u2014" },
10375
10355
  { label: "Total Circulating Tokens", value: isLoading && resolvedTokensIssued == null ? loadingSkeleton : resolvedTokensIssued?.toLocaleString() ?? "\u2014" },
10376
10356
  { label: "Legal Structuring", value: "See Documents", docLink: true },
@@ -10390,7 +10370,9 @@ function PropertyOverview({
10390
10370
  ];
10391
10371
  const growthPct = overviewData?.growth5Yr;
10392
10372
  const propertyStats = [
10393
- { label: "Property Value", value: isLoading && tokenMarketCap == null ? loadingSkeleton : tokenMarketCap ? fmtDollar(tokenMarketCap) : "\u2014" },
10373
+ // Property Value = the API offeringValuation (OverviewResponse.offeringValuation), NOT
10374
+ // midPrice×tokensIssued market cap (fixed 2026-07-22). null → '—', never a fabricated cap.
10375
+ { label: "Property Value", value: isLoading && overviewData?.offeringValuation == null ? loadingSkeleton : overviewData?.offeringValuation ? fmtDollar(overviewData.offeringValuation) : "\u2014" },
10394
10376
  ...beta ? [] : [{ label: "Offers", value: "3" }],
10395
10377
  { label: "Growth (5yr)", value: growthPct != null ? `${growthPct > 0 ? "+" : ""}${growthPct}%` : "\u2014" },
10396
10378
  { label: "Last Dividend", value: overviewData?.lastDividend != null ? `$${overviewData.lastDividend.toFixed(2)}` : "\u2014" },
@@ -14891,7 +14873,7 @@ var getOrderStatusMeta = (statusRaw) => {
14891
14873
  return { color: "#E6C87E", bg: "rgba(240,185,11,0.15)" };
14892
14874
  };
14893
14875
  var ChevronDown = () => /* @__PURE__ */ 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__ */ jsx("polyline", { points: "6 9 12 15 18 9" }) });
14894
- var BaseScanIconLink = ({ url }) => /* @__PURE__ */ jsx(TxLink, { href: url, target: "_blank", rel: "noopener noreferrer", title: "View on BaseScan", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
14876
+ var ArbiscanIconLink = ({ url }) => /* @__PURE__ */ jsx(TxLink, { href: url, target: "_blank", rel: "noopener noreferrer", title: "View on Arbiscan", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
14895
14877
  /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
14896
14878
  /* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
14897
14879
  /* @__PURE__ */ jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
@@ -14916,7 +14898,7 @@ function PortfolioActivityPanel({
14916
14898
  defaultTab,
14917
14899
  onTabChange,
14918
14900
  pageSize = ACTIVITY_PAGE_SIZE_DEFAULT,
14919
- blockExplorerBaseUrl: _blockExplorerBaseUrl = "https://sepolia.basescan.org/tx",
14901
+ blockExplorerBaseUrl: _blockExplorerBaseUrl = "https://sepolia.arbiscan.io/tx",
14920
14902
  className,
14921
14903
  style
14922
14904
  }) {
@@ -15360,7 +15342,7 @@ function PortfolioActivityPanel({
15360
15342
  /* @__PURE__ */ jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: "0.35rem" }, children: [
15361
15343
  formatNumber2(order.quantity),
15362
15344
  order.ticker && /* @__PURE__ */ jsx(TickerTag, { style: { marginLeft: 0 }, children: order.ticker.toUpperCase() }),
15363
- order.txHash && /* @__PURE__ */ jsx(BaseScanIconLink, { url: `${_blockExplorerBaseUrl}/${order.txHash}` })
15345
+ order.txHash && /* @__PURE__ */ jsx(ArbiscanIconLink, { url: `${_blockExplorerBaseUrl}/${order.txHash}` })
15364
15346
  ] })
15365
15347
  ] }),
15366
15348
  /* @__PURE__ */ jsxs(CUnitsCell, { children: [
@@ -15413,7 +15395,7 @@ function PortfolioActivityPanel({
15413
15395
  order.status === "REJECTED" && order.rejectionReason && /* @__PURE__ */ 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 })
15414
15396
  ] }),
15415
15397
  /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { $muted: true, children: formatTimestamp(order.createdAt) }) }),
15416
- /* @__PURE__ */ jsx(GridCell, { children: order.txHash && /* @__PURE__ */ jsx(TxLink, { href: `${_blockExplorerBaseUrl}/${order.txHash}`, target: "_blank", rel: "noopener noreferrer", title: "View on BaseScan", children: /* @__PURE__ */ jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
15398
+ /* @__PURE__ */ jsx(GridCell, { children: order.txHash && /* @__PURE__ */ jsx(TxLink, { href: `${_blockExplorerBaseUrl}/${order.txHash}`, target: "_blank", rel: "noopener noreferrer", title: "View on Arbiscan", children: /* @__PURE__ */ jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
15417
15399
  /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
15418
15400
  /* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
15419
15401
  /* @__PURE__ */ jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
@@ -15456,7 +15438,11 @@ function PortfolioActivityPanel({
15456
15438
  /* @__PURE__ */ jsx(CChevronWrap, { $open: ordExpanded, children: /* @__PURE__ */ 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__ */ jsx("polyline", { points: "6 9 12 15 18 9" }) }) })
15457
15439
  ] }),
15458
15440
  ordExpanded && /* @__PURE__ */ jsxs(CExpandedWrap, { children: [
15459
- /* @__PURE__ */ jsxs(CDetailGrid, { children: [
15441
+ /* @__PURE__ */ jsxs(CDetailGrid3, { children: [
15442
+ /* @__PURE__ */ jsxs(CDetailItem, { children: [
15443
+ /* @__PURE__ */ jsx(CDLabel, { children: "Order ID" }),
15444
+ /* @__PURE__ */ jsx(CDValue, { children: order.id > 0 ? `#${order.id}` : "\u2014" })
15445
+ ] }),
15460
15446
  /* @__PURE__ */ jsxs(CDetailItem, { children: [
15461
15447
  /* @__PURE__ */ jsx(CDLabel, { children: "Type" }),
15462
15448
  /* @__PURE__ */ jsx(CDValue, { children: prettyLabel(order.type) })
@@ -15485,7 +15471,8 @@ function PortfolioActivityPanel({
15485
15471
  ] })
15486
15472
  ] }, `open-${order.id}`);
15487
15473
  }) : /* @__PURE__ */ jsxs(Fragment, { children: [
15488
- /* @__PURE__ */ jsxs(GridHeader, { $columns: onCancelOrder ? "1.2fr 0.6fr 0.7fr 0.8fr 1fr 0.8fr 0.8fr 82px" : "1.2fr 0.6fr 0.7fr 0.8fr 1fr 0.8fr 0.8fr", children: [
15474
+ /* @__PURE__ */ jsxs(GridHeader, { $columns: onCancelOrder ? "0.5fr 1.2fr 0.6fr 0.7fr 0.8fr 1fr 0.8fr 0.8fr 82px" : "0.5fr 1.2fr 0.6fr 0.7fr 0.8fr 1fr 0.8fr 0.8fr", children: [
15475
+ /* @__PURE__ */ jsx(GridHeaderCell, { children: "ID" }),
15489
15476
  /* @__PURE__ */ jsx(GridHeaderCell, { children: "Asset" }),
15490
15477
  /* @__PURE__ */ jsx(GridHeaderCell, { children: "Side" }),
15491
15478
  /* @__PURE__ */ jsx(GridHeaderCell, { children: "Type" }),
@@ -15501,7 +15488,8 @@ function PortfolioActivityPanel({
15501
15488
  const filledPercent = order.quantity > 0 ? Math.round(order.filledQuantity / order.quantity * 100) : 0;
15502
15489
  const isCancelling = cancellingOrderId === order.id;
15503
15490
  const sideColor = sideLabel(order.side) === "Buy" ? "#0ecb81" : "#f6465d";
15504
- return /* @__PURE__ */ jsxs(GridRow, { $columns: onCancelOrder ? "1.2fr 0.6fr 0.7fr 0.8fr 1fr 0.8fr 0.8fr 82px" : "1.2fr 0.6fr 0.7fr 0.8fr 1fr 0.8fr 0.8fr", children: [
15491
+ return /* @__PURE__ */ jsxs(GridRow, { $columns: onCancelOrder ? "0.5fr 1.2fr 0.6fr 0.7fr 0.8fr 1fr 0.8fr 0.8fr 82px" : "0.5fr 1.2fr 0.6fr 0.7fr 0.8fr 1fr 0.8fr 0.8fr", children: [
15492
+ /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { $muted: true, children: order.id > 0 ? `#${order.id}` : "\u2014" }) }),
15505
15493
  /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { $primary: true, $color: sideColor, $noHoverColor: true, $clickable: !!onAssetClick, onClick: onAssetClick ? () => onAssetClick(order.tokenName) : void 0, children: order.tokenName }) }),
15506
15494
  /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(SideBadge, { $side: sideLabel(order.side), children: sideLabel(order.side) }) }),
15507
15495
  /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { $muted: true, children: prettyLabel(order.type) }) }),
@@ -15657,7 +15645,7 @@ function PortfolioActivityPanel({
15657
15645
  /* @__PURE__ */ jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: "0.35rem" }, children: [
15658
15646
  formatNumber2(trade.quantity),
15659
15647
  trade.ticker && /* @__PURE__ */ jsx(TickerTag, { style: { marginLeft: 0 }, children: trade.ticker.toUpperCase() }),
15660
- trade.txHash && /* @__PURE__ */ jsx(BaseScanIconLink, { url: `${_blockExplorerBaseUrl}/${trade.txHash}` })
15648
+ trade.txHash && /* @__PURE__ */ jsx(ArbiscanIconLink, { url: `${_blockExplorerBaseUrl}/${trade.txHash}` })
15661
15649
  ] })
15662
15650
  ] }),
15663
15651
  /* @__PURE__ */ jsxs(CUnitsCell, { children: [
@@ -15724,7 +15712,7 @@ function PortfolioActivityPanel({
15724
15712
  /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { children: formatCurrency4(trade.price * trade.quantity) }) }),
15725
15713
  /* @__PURE__ */ jsx(GridCell, { children: settlementMeta ? /* @__PURE__ */ jsx(ActivityTag, { $color: settlementMeta.color, $bg: settlementMeta.bg, children: settlementLabel }) : /* @__PURE__ */ jsx(CellText, { $muted: true, children: "\u2014" }) }),
15726
15714
  /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { $muted: true, children: formatTimestamp(trade.executedAt) }) }),
15727
- /* @__PURE__ */ jsx(GridCell, { children: trade.txHash && /* @__PURE__ */ jsx(TxLink, { href: `${_blockExplorerBaseUrl}/${trade.txHash}`, target: "_blank", rel: "noopener noreferrer", title: "View on BaseScan", children: /* @__PURE__ */ jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
15715
+ /* @__PURE__ */ jsx(GridCell, { children: trade.txHash && /* @__PURE__ */ jsx(TxLink, { href: `${_blockExplorerBaseUrl}/${trade.txHash}`, target: "_blank", rel: "noopener noreferrer", title: "View on Arbiscan", children: /* @__PURE__ */ jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
15728
15716
  /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
15729
15717
  /* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
15730
15718
  /* @__PURE__ */ jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
@@ -15771,7 +15759,7 @@ function PortfolioActivityPanel({
15771
15759
  /* @__PURE__ */ jsx(CDValue, { children: formatTimestamp(t.createdAt) })
15772
15760
  ] })
15773
15761
  ] }),
15774
- txUrl && /* @__PURE__ */ jsx(CExpandedLink, { href: txUrl, target: "_blank", rel: "noopener noreferrer", children: "View on BaseScan \u2197" })
15762
+ txUrl && /* @__PURE__ */ jsx(CExpandedLink, { href: txUrl, target: "_blank", rel: "noopener noreferrer", children: "View on Arbiscan \u2197" })
15775
15763
  ] })
15776
15764
  ] }, rowKey);
15777
15765
  }),
@@ -15797,7 +15785,7 @@ function PortfolioActivityPanel({
15797
15785
  /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { $muted: true, children: formatAddress(t.address) }) }),
15798
15786
  /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(ActivityTag, { $color: statusMeta.color, $bg: statusMeta.bg, children: prettyLabel(t.status) }) }),
15799
15787
  /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { $muted: true, children: formatTimestamp(t.createdAt) }) }),
15800
- /* @__PURE__ */ jsx(GridCell, { children: txUrl && /* @__PURE__ */ jsx(TxLink, { href: txUrl, target: "_blank", rel: "noopener noreferrer", title: "View on BaseScan", children: /* @__PURE__ */ jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
15788
+ /* @__PURE__ */ jsx(GridCell, { children: txUrl && /* @__PURE__ */ jsx(TxLink, { href: txUrl, target: "_blank", rel: "noopener noreferrer", title: "View on Arbiscan", children: /* @__PURE__ */ jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
15801
15789
  /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
15802
15790
  /* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
15803
15791
  /* @__PURE__ */ jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
@@ -18900,13 +18888,14 @@ var CloseButton3 = styled10.button`
18900
18888
  var MainImageContainer = styled10.div`
18901
18889
  position: relative;
18902
18890
  flex: 1;
18891
+ min-height: 0;
18903
18892
  display: flex;
18904
18893
  align-items: center;
18905
18894
  justify-content: center;
18906
- padding: 80px 20px 140px;
18895
+ padding: 20px 20px 160px;
18907
18896
 
18908
18897
  @media (max-width: 768px) {
18909
- padding: 60px 0 110px;
18898
+ padding: 10px 0 130px;
18910
18899
  }
18911
18900
  `;
18912
18901
  var MainImage = styled10.img`
@@ -18918,8 +18907,11 @@ var MainImage = styled10.img`
18918
18907
  opacity: ${(p) => p.$visible ? 1 : 0};
18919
18908
  pointer-events: ${(p) => p.$visible ? "auto" : "none"};
18920
18909
  transition: opacity 300ms ease;
18921
- /* Inset box excludes the bottom thumbnail strip so margin:auto centres the image in the
18922
- space ABOVE the thumbnails (absolute ignores the parent's padding). */
18910
+ /* All slides share the same absolute box so switching only crossfades opacity
18911
+ no relative↔absolute size jump (the "grow then shrink" on navigation).
18912
+ The inset box excludes the bottom thumbnail strip so margin:auto centres the image
18913
+ in the space ABOVE the thumbnails (absolute positioning ignores the parent's padding,
18914
+ which otherwise let the image sink behind the thumbnails / "lean down"). */
18923
18915
  position: absolute;
18924
18916
  top: 24px;
18925
18917
  left: 24px;
@@ -19113,9 +19105,11 @@ function PropertyPhotoGallery({
19113
19105
  isOpen,
19114
19106
  onClose,
19115
19107
  startIndex = 0,
19108
+ startWithVideo = false,
19116
19109
  title = "28 Derby Street, Vaucluse",
19117
19110
  subtitle = "Elara \u2014 Luxury Harbour Residence",
19118
- images
19111
+ images,
19112
+ videoUrl
19119
19113
  }) {
19120
19114
  const galleryImages = images?.length ? images : DEFAULT_IMAGES;
19121
19115
  if (!isOpen) return null;
@@ -19124,16 +19118,19 @@ function PropertyPhotoGallery({
19124
19118
  {
19125
19119
  galleryImages,
19126
19120
  startIndex,
19121
+ startWithVideo,
19127
19122
  title,
19128
19123
  subtitle,
19129
- onClose
19124
+ onClose,
19125
+ videoUrl
19130
19126
  },
19131
- `${startIndex}-${galleryImages.length}`
19127
+ `${startIndex}-${galleryImages.length}-${startWithVideo}`
19132
19128
  );
19133
19129
  }
19134
- function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose }) {
19130
+ function GalleryContent({ galleryImages, startIndex, startWithVideo, title, subtitle, onClose, videoUrl }) {
19135
19131
  const [currentIndex, setCurrentIndex] = useState(() => clampIndex(startIndex, galleryImages.length));
19136
19132
  const [activeHotspotId, setActiveHotspotId] = useState(null);
19133
+ const [showVideo, setShowVideo] = useState(startWithVideo ?? false);
19137
19134
  const sliderRef = useRef(null);
19138
19135
  const [isDragging, setIsDragging] = useState(false);
19139
19136
  const wasDraggingRef = useRef(false);
@@ -19183,7 +19180,7 @@ function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose })
19183
19180
  ] }),
19184
19181
  /* @__PURE__ */ jsx(CloseButton3, { onClick: onClose, "aria-label": "Close gallery", children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "22", height: "22", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { d: "M6 6l12 12M6 18L18 6" }) }) })
19185
19182
  ] }),
19186
- /* @__PURE__ */ jsxs(SliderContainer, { onClick: (event) => event.stopPropagation(), children: [
19183
+ !showVideo && /* @__PURE__ */ jsxs(SliderContainer, { onClick: (event) => event.stopPropagation(), children: [
19187
19184
  /* @__PURE__ */ jsxs(
19188
19185
  SliderTrack,
19189
19186
  {
@@ -19246,7 +19243,21 @@ function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose })
19246
19243
  children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "22", height: "22", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { d: "M15 18l-6-6 6-6" }) })
19247
19244
  }
19248
19245
  ),
19249
- galleryImages.map((image, idx) => /* @__PURE__ */ jsx(MainImage, { src: image.src, alt: image.alt, $visible: idx === currentIndex }, image.alt)),
19246
+ showVideo && videoUrl ? /* @__PURE__ */ jsx(GalleryVideoWrap, { children: /* @__PURE__ */ jsx(
19247
+ "video",
19248
+ {
19249
+ autoPlay: true,
19250
+ loop: true,
19251
+ playsInline: true,
19252
+ muted: true,
19253
+ controls: true,
19254
+ onVolumeChange: (e) => {
19255
+ if (!e.currentTarget.muted) e.currentTarget.muted = true;
19256
+ },
19257
+ style: { objectFit: "contain", borderRadius: 12, boxShadow: "0 30px 80px rgba(0,0,0,0.55)" },
19258
+ children: /* @__PURE__ */ jsx("source", { src: videoUrl, type: "video/mp4" })
19259
+ }
19260
+ ) }) : galleryImages.map((image, idx) => /* @__PURE__ */ jsx(MainImage, { src: image.src, alt: image.alt, $visible: idx === currentIndex }, image.alt)),
19250
19261
  galleryImages[currentIndex]?.hotspots?.map((hotspot) => /* @__PURE__ */ jsx(
19251
19262
  Hotspot,
19252
19263
  {
@@ -19291,11 +19302,83 @@ function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose })
19291
19302
  ]
19292
19303
  }
19293
19304
  ),
19294
- /* @__PURE__ */ jsx(ThumbnailStrip, { onClick: (event) => event.stopPropagation(), children: galleryImages.map((image, idx) => /* @__PURE__ */ jsx(Thumbnail3, { $active: idx === currentIndex, onClick: () => setCurrentIndex(idx), "aria-label": `Preview ${image.label}`, children: /* @__PURE__ */ jsx("img", { src: image.src, alt: image.alt }) }, image.alt)) })
19305
+ /* @__PURE__ */ jsxs(ThumbnailStrip, { onClick: (event) => event.stopPropagation(), children: [
19306
+ galleryImages.map((image, idx) => /* @__PURE__ */ jsx(Thumbnail3, { $active: !showVideo && idx === currentIndex, onClick: () => {
19307
+ setShowVideo(false);
19308
+ setCurrentIndex(idx);
19309
+ }, "aria-label": `Preview ${image.label}`, children: /* @__PURE__ */ jsx("img", { src: image.src, alt: image.alt }) }, image.alt)),
19310
+ videoUrl && /* @__PURE__ */ jsxs(Fragment, { children: [
19311
+ /* @__PURE__ */ jsx(ThumbnailDivider, {}),
19312
+ /* @__PURE__ */ jsxs(VideoBtn, { $active: showVideo, onClick: () => setShowVideo(true), children: [
19313
+ /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
19314
+ /* @__PURE__ */ jsx("rect", { x: "2", y: "4", width: "14", height: "16", rx: "2" }),
19315
+ /* @__PURE__ */ jsx("path", { d: "M16 8l6-4v16l-6-4z" })
19316
+ ] }),
19317
+ "Video"
19318
+ ] })
19319
+ ] })
19320
+ ] })
19295
19321
  ]
19296
19322
  }
19297
19323
  );
19298
19324
  }
19325
+ var GalleryVideoWrap = styled10.div`
19326
+ position: absolute;
19327
+ inset: 0;
19328
+ display: flex;
19329
+ align-items: center;
19330
+ justify-content: center;
19331
+ padding: 20px 20px 160px;
19332
+
19333
+ video {
19334
+ max-width: 90%;
19335
+ max-height: 100%;
19336
+ }
19337
+
19338
+ /* Property videos stay permanently muted — remove the volume + mute buttons
19339
+ from the native player (Chrome/Edge/Safari/iOS/Android). Firefox ignores
19340
+ these and is covered by the onVolumeChange force-mute fallback. */
19341
+ video::-webkit-media-controls-mute-button,
19342
+ video::-webkit-media-controls-volume-slider,
19343
+ video::-webkit-media-controls-volume-control-container {
19344
+ display: none !important;
19345
+ }
19346
+
19347
+ @media (max-width: 768px) {
19348
+ padding: 10px 0 130px;
19349
+
19350
+ video {
19351
+ max-width: 100%;
19352
+ }
19353
+ }
19354
+ `;
19355
+ var ThumbnailDivider = styled10.div`
19356
+ width: 1px;
19357
+ height: 48px;
19358
+ background: rgba(255, 255, 255, 0.15);
19359
+ flex-shrink: 0;
19360
+ align-self: center;
19361
+ `;
19362
+ var VideoBtn = styled10.button`
19363
+ display: flex;
19364
+ align-items: center;
19365
+ gap: 6px;
19366
+ padding: 8px 14px;
19367
+ border-radius: 8px;
19368
+ border: 1px solid ${(p) => p.$active ? "var(--color-accent, #E6C87E)" : "rgba(255, 255, 255, 0.2)"};
19369
+ background: ${(p) => p.$active ? "rgba(240, 185, 11, 0.15)" : "rgba(255, 255, 255, 0.08)"};
19370
+ color: ${(p) => p.$active ? "var(--color-accent, #E6C87E)" : "#fff"};
19371
+ font-size: 0.82rem;
19372
+ font-weight: 500;
19373
+ cursor: pointer;
19374
+ flex-shrink: 0;
19375
+ transition: all 0.2s ease;
19376
+
19377
+ &:hover {
19378
+ background: rgba(255, 255, 255, 0.15);
19379
+ border-color: rgba(255, 255, 255, 0.3);
19380
+ }
19381
+ `;
19299
19382
  var slideIn2 = keyframes`
19300
19383
  from { transform: translateX(110%); opacity: 0; }
19301
19384
  to { transform: translateX(0); opacity: 1; }
@@ -19464,7 +19547,7 @@ var Container3 = styled10.div`
19464
19547
  gap: 8px;
19465
19548
  }
19466
19549
  `;
19467
- var DEFAULT_EXPLORER = "https://sepolia.basescan.org/tx/";
19550
+ var DEFAULT_EXPLORER = "https://sepolia.arbiscan.io/tx/";
19468
19551
  function truncateHash(hash) {
19469
19552
  return `${hash.slice(0, 6)}\u2026${hash.slice(-4)}`;
19470
19553
  }
@@ -20031,8 +20114,7 @@ var SiteFooter = () => {
20031
20114
  /* @__PURE__ */ jsxs(LegalLinks, { children: [
20032
20115
  /* @__PURE__ */ jsx(LegalLink, { href: "/privacy", children: "Privacy Policy" }),
20033
20116
  /* @__PURE__ */ jsx(LegalLink, { href: "/terms", children: "Terms of Use" }),
20034
- /* @__PURE__ */ jsx(LegalLink, { href: "/cookies", children: "Cookie Policy" }),
20035
- /* @__PURE__ */ jsx(LegalLink, { href: "/risk", children: "Risk Warning" })
20117
+ /* @__PURE__ */ jsx(LegalLink, { href: "/cookies", children: "Cookie Policy" })
20036
20118
  ] })
20037
20119
  ] }),
20038
20120
  /* @__PURE__ */ jsx(Disclaimer2, { children: /* @__PURE__ */ 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." }) })