@loafmarkets/ui 0.1.102 → 0.1.103

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
@@ -1796,6 +1796,11 @@ function useViewportCompact(breakpoint) {
1796
1796
  return isCompact;
1797
1797
  }
1798
1798
  var formatNumber = (value, precision) => value.toFixed(precision);
1799
+ var formatTradeTime = (time) => {
1800
+ const d = new Date(time);
1801
+ if (Number.isNaN(d.getTime())) return time;
1802
+ return d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false });
1803
+ };
1799
1804
  var FLASH_DURATION_MS = 450;
1800
1805
  var FLASH_UP_COLOR = "rgba(14, 203, 129, 0.35)";
1801
1806
  var FLASH_DOWN_COLOR = "rgba(246, 70, 93, 0.35)";
@@ -1865,14 +1870,12 @@ function TradeRow({
1865
1870
  {
1866
1871
  ref: rowRef,
1867
1872
  className: "grid items-center",
1868
- style: { gridTemplateColumns: "1.2fr 0.8fr", padding: "0.2rem 0", fontSize: "0.8rem" },
1873
+ style: { gridTemplateColumns: "1fr 1fr 1fr", padding: "0.2rem 0", fontSize: "0.8rem" },
1869
1874
  children: [
1870
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { color: trade.type === "buy" ? "#0ecb81" : "#f6465d", fontWeight: 500 }, children: [
1871
- "$",
1872
- formatNumber(trade.price, precision)
1873
- ] }),
1874
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "right", paddingRight: "0.5rem", display: "flex", alignItems: "center", justifyContent: "flex-end", gap: "4px" }, children: [
1875
- formatNumber(trade.amount, amountPrecision),
1875
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: trade.type === "buy" ? "#0ecb81" : "#f6465d" }, className: "tabular-nums", children: formatNumber(trade.price, precision) }),
1876
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "right" }, className: "tabular-nums text-white/90", children: formatNumber(trade.amount, amountPrecision) }),
1877
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "right", paddingRight: "0.5rem", display: "flex", alignItems: "center", justifyContent: "flex-end", gap: "4px" }, className: "tabular-nums text-white/50", children: [
1878
+ trade.time != null && /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatTradeTime(trade.time) }),
1876
1879
  explorerUrl && /* @__PURE__ */ jsxRuntime.jsx(
1877
1880
  "a",
1878
1881
  {
@@ -1893,24 +1896,22 @@ function TradeRow({
1893
1896
  "div",
1894
1897
  {
1895
1898
  ref: rowRef,
1896
- className: "grid grid-cols-3 items-center gap-3 px-3 py-1.5",
1899
+ className: "relative grid grid-cols-3 items-center gap-3 px-3 text-[0.8rem]",
1900
+ style: { height: `${DEPTH_ROW_HEIGHT_PX}px` },
1897
1901
  children: [
1898
- /* @__PURE__ */ jsxRuntime.jsxs(
1902
+ /* @__PURE__ */ jsxRuntime.jsx(
1899
1903
  "div",
1900
1904
  {
1901
1905
  className: cn(
1902
1906
  "tabular-nums",
1903
1907
  trade.type === "buy" ? "text-[#0ecb81]" : "text-[#f6465d]"
1904
1908
  ),
1905
- children: [
1906
- "$",
1907
- formatNumber(trade.price, precision)
1908
- ]
1909
+ children: formatNumber(trade.price, precision)
1909
1910
  }
1910
1911
  ),
1911
1912
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right tabular-nums text-white/90", children: formatNumber(trade.amount, amountPrecision) }),
1912
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-1.5", children: [
1913
- trade.time != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tabular-nums text-white/50 text-xs", children: trade.time }),
1913
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-1.5 tabular-nums text-white/50", children: [
1914
+ trade.time != null && /* @__PURE__ */ jsxRuntime.jsx("span", { children: trade.time }),
1914
1915
  explorerUrl && /* @__PURE__ */ jsxRuntime.jsx(
1915
1916
  "a",
1916
1917
  {
@@ -1978,8 +1979,8 @@ function DepthRow({
1978
1979
  );
1979
1980
  }
1980
1981
  var clamp3 = (value, min, max) => Math.min(max, Math.max(min, value));
1981
- var LEVEL_ROWS_VISIBLE = 6;
1982
- var DEPTH_ROW_HEIGHT_PX = 26;
1982
+ var LEVEL_ROWS_VISIBLE = 5;
1983
+ var DEPTH_ROW_HEIGHT_PX = 28;
1983
1984
  var COMPACT_ROWS_VISIBLE = 5;
1984
1985
  var COMPACT_ROW_HEIGHT_PX = 30;
1985
1986
  var COMPACT_BREAKPOINT_PX = 1024;
@@ -2003,6 +2004,8 @@ var Orderbook = React5__namespace.forwardRef(
2003
2004
  onPriceClick,
2004
2005
  onLoafLiquidityClick,
2005
2006
  tradeExplorerUrl,
2007
+ maxLevels,
2008
+ fillHeight = false,
2006
2009
  className,
2007
2010
  ...props
2008
2011
  }, ref) => {
@@ -2047,8 +2050,10 @@ var Orderbook = React5__namespace.forwardRef(
2047
2050
  onTabChange?.(next);
2048
2051
  };
2049
2052
  const isCompact = variant === "compact" || variant === "auto" && viewportCompact;
2050
- const sectionHeight = isCompact ? COMPACT_ROWS_VISIBLE * COMPACT_ROW_HEIGHT_PX : LEVEL_ROWS_VISIBLE * DEPTH_ROW_HEIGHT_PX;
2051
- const rowCount = isCompact ? COMPACT_ROWS_VISIBLE : LEVEL_ROWS_VISIBLE;
2053
+ const effectiveLevels = maxLevels ?? LEVEL_ROWS_VISIBLE;
2054
+ const effectiveCompactLevels = maxLevels ?? COMPACT_ROWS_VISIBLE;
2055
+ const sectionHeight = isCompact ? effectiveCompactLevels * COMPACT_ROW_HEIGHT_PX : effectiveLevels * DEPTH_ROW_HEIGHT_PX;
2056
+ const rowCount = isCompact ? effectiveCompactLevels : effectiveLevels;
2052
2057
  const askVisibleLevels = asks.slice(-rowCount);
2053
2058
  const bidVisibleLevels = bids.slice(0, rowCount);
2054
2059
  const askCumDepths = new Array(askVisibleLevels.length);
@@ -2067,7 +2072,8 @@ var Orderbook = React5__namespace.forwardRef(
2067
2072
  bidCumDepths[i] = acc;
2068
2073
  }
2069
2074
  }
2070
- const combinedMaxCumDepth = Math.max(1, ...askCumDepths, ...bidCumDepths);
2075
+ const askMaxCumDepth = Math.max(1, ...askCumDepths);
2076
+ const bidMaxCumDepth = Math.max(1, ...bidCumDepths);
2071
2077
  const midClass = midChangePercent == null ? "text-white" : midChangePercent >= 0 ? "text-[#0ecb81]" : "text-[#f6465d]";
2072
2078
  const tradeFiltered = trades.filter((t) => tradeFilter === "all" || t.type === tradeFilter);
2073
2079
  const layoutProps = {
@@ -2087,7 +2093,8 @@ var Orderbook = React5__namespace.forwardRef(
2087
2093
  bidVisibleLevels,
2088
2094
  askCumDepths,
2089
2095
  bidCumDepths,
2090
- combinedMaxCumDepth,
2096
+ askMaxCumDepth,
2097
+ bidMaxCumDepth,
2091
2098
  midPrice,
2092
2099
  midChangePercent,
2093
2100
  midClass,
@@ -2097,15 +2104,19 @@ var Orderbook = React5__namespace.forwardRef(
2097
2104
  isLoading,
2098
2105
  seenTradeKeysRef,
2099
2106
  tradeExplorerUrl,
2100
- onPriceClick
2107
+ onPriceClick,
2108
+ levelCount: effectiveLevels,
2109
+ compactLevelCount: effectiveCompactLevels,
2110
+ fillHeight
2101
2111
  };
2102
2112
  return /* @__PURE__ */ jsxRuntime.jsx(
2103
2113
  Card,
2104
2114
  {
2105
2115
  ref,
2106
2116
  className: cn(
2107
- "w-full max-w-[520px] overflow-hidden rounded-[12px] border border-white/10 bg-[#111111] text-white shadow-md flex flex-col h-full",
2117
+ "w-full max-w-[520px] overflow-hidden rounded-[12px] border border-white/10 bg-[#111111] text-white shadow-md flex flex-col",
2108
2118
  isCompact && "max-w-none",
2119
+ fillHeight && "h-full",
2109
2120
  className
2110
2121
  ),
2111
2122
  ...props,
@@ -2154,7 +2165,8 @@ function DesktopOrderbookLayout({
2154
2165
  bidVisibleLevels,
2155
2166
  askCumDepths,
2156
2167
  bidCumDepths,
2157
- combinedMaxCumDepth,
2168
+ askMaxCumDepth,
2169
+ bidMaxCumDepth,
2158
2170
  midPrice,
2159
2171
  midChangePercent,
2160
2172
  midClass,
@@ -2164,7 +2176,10 @@ function DesktopOrderbookLayout({
2164
2176
  isLoading,
2165
2177
  seenTradeKeysRef,
2166
2178
  tradeExplorerUrl,
2167
- onPriceClick
2179
+ onPriceClick,
2180
+ levelCount: effectiveLevels,
2181
+ compactLevelCount: _compactLevelCount,
2182
+ fillHeight
2168
2183
  }) {
2169
2184
  const midRef = React5__namespace.useRef(null);
2170
2185
  useMidPriceFlash(midRef, midPrice, "#0b1a24");
@@ -2252,7 +2267,7 @@ function DesktopOrderbookLayout({
2252
2267
  {
2253
2268
  className: "max-h-[380px] overflow-y-auto overflow-x-hidden",
2254
2269
  style: { scrollbarGutter: "stable" },
2255
- children: isLoading && tradeFiltered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-white/5", children: Array.from({ length: LEVEL_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, {}, `trade-skel-${i}`)) }) : tradeFiltered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-10 text-center text-sm text-white/50", children: "No trades" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-white/5", children: tradeFiltered.map((trade, i) => {
2270
+ children: isLoading && tradeFiltered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { children: Array.from({ length: effectiveLevels }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, {}, `trade-skel-${i}`)) }) : tradeFiltered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-10 text-center text-sm text-white/50", children: "No trades" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { children: tradeFiltered.map((trade, i) => {
2256
2271
  const tradeKey = getTradeKey(trade, i);
2257
2272
  const explorerUrl = trade.txHash && tradeExplorerUrl ? tradeExplorerUrl(trade.txHash) : trade.txHash ? `https://sepolia.etherscan.io/tx/${trade.txHash}` : void 0;
2258
2273
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -2269,20 +2284,20 @@ function DesktopOrderbookLayout({
2269
2284
  );
2270
2285
  }) })
2271
2286
  }
2272
- ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col min-h-0", children: [
2287
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col min-h-0 overflow-hidden", fillHeight && "flex-1"), children: [
2273
2288
  /* @__PURE__ */ jsxRuntime.jsx(
2274
2289
  "div",
2275
2290
  {
2276
- className: "flex flex-col justify-end divide-y divide-white/5 overflow-hidden",
2277
- style: { height: `${sectionHeight}px` },
2278
- children: isLoading ? Array.from({ length: LEVEL_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, {}, `ask-skel-${i}`)) : askVisibleLevels.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center px-3 text-xs text-white/40", children: "No asks" }) : askVisibleLevels.map((l, i) => /* @__PURE__ */ jsxRuntime.jsx(
2291
+ className: cn("flex flex-col justify-end overflow-hidden", !fillHeight && "flex-shrink-0"),
2292
+ style: fillHeight ? { flex: 1, minHeight: 0 } : { height: `${sectionHeight}px` },
2293
+ children: isLoading ? Array.from({ length: effectiveLevels }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, {}, `ask-skel-${i}`)) : askVisibleLevels.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center px-3 text-xs text-white/40", children: "No asks" }) : askVisibleLevels.map((l, i) => /* @__PURE__ */ jsxRuntime.jsx(
2279
2294
  DepthRow,
2280
2295
  {
2281
2296
  side: "ask",
2282
2297
  price: l.price,
2283
2298
  amount: l.amount,
2284
2299
  cumDepth: askCumDepths[i],
2285
- depthPct: askCumDepths[i] / combinedMaxCumDepth * 100,
2300
+ depthPct: askCumDepths[i] / askMaxCumDepth * 100,
2286
2301
  precision,
2287
2302
  amountPrecision,
2288
2303
  hasUserOrder: userAskPrices.has(l.price),
@@ -2296,7 +2311,7 @@ function DesktopOrderbookLayout({
2296
2311
  "div",
2297
2312
  {
2298
2313
  ref: midRef,
2299
- className: "grid grid-cols-2 items-center gap-3 bg-[#0b1a24] px-3 py-2",
2314
+ className: "grid grid-cols-2 items-center gap-3 bg-[#0b1a24] px-3 py-2 flex-shrink-0",
2300
2315
  children: [
2301
2316
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-lg font-semibold tabular-nums", midClass), children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 110, height: 20 }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2302
2317
  "$",
@@ -2314,16 +2329,16 @@ function DesktopOrderbookLayout({
2314
2329
  /* @__PURE__ */ jsxRuntime.jsx(
2315
2330
  "div",
2316
2331
  {
2317
- className: "divide-y divide-white/5 overflow-hidden",
2318
- style: { height: `${sectionHeight}px` },
2319
- children: isLoading ? Array.from({ length: LEVEL_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, {}, `bid-skel-${i}`)) : bidVisibleLevels.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center px-3 text-xs text-white/40", children: "No bids" }) : bidVisibleLevels.map((l, i) => /* @__PURE__ */ jsxRuntime.jsx(
2332
+ className: cn("flex flex-col overflow-hidden", !fillHeight && "flex-shrink-0"),
2333
+ style: fillHeight ? { flex: 1, minHeight: 0 } : { height: `${sectionHeight}px` },
2334
+ children: isLoading ? Array.from({ length: effectiveLevels }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, {}, `bid-skel-${i}`)) : bidVisibleLevels.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center px-3 text-xs text-white/40", children: "No bids" }) : bidVisibleLevels.map((l, i) => /* @__PURE__ */ jsxRuntime.jsx(
2320
2335
  DepthRow,
2321
2336
  {
2322
2337
  side: "bid",
2323
2338
  price: l.price,
2324
2339
  amount: l.amount,
2325
2340
  cumDepth: bidCumDepths[i],
2326
- depthPct: bidCumDepths[i] / combinedMaxCumDepth * 100,
2341
+ depthPct: bidCumDepths[i] / bidMaxCumDepth * 100,
2327
2342
  precision,
2328
2343
  amountPrecision,
2329
2344
  hasUserOrder: userBidPrices.has(l.price),
@@ -2352,7 +2367,8 @@ function MobileOrderbookLayout({
2352
2367
  bidVisibleLevels: visibleBids,
2353
2368
  askCumDepths,
2354
2369
  bidCumDepths,
2355
- combinedMaxCumDepth,
2370
+ askMaxCumDepth,
2371
+ bidMaxCumDepth,
2356
2372
  midPrice,
2357
2373
  midChangePercent,
2358
2374
  midClass,
@@ -2362,7 +2378,9 @@ function MobileOrderbookLayout({
2362
2378
  isLoading,
2363
2379
  seenTradeKeysRef,
2364
2380
  tradeExplorerUrl,
2365
- onPriceClick
2381
+ onPriceClick,
2382
+ levelCount: _levelCount,
2383
+ compactLevelCount: effectiveCompactLevels
2366
2384
  }) {
2367
2385
  const midRef = React5__namespace.useRef(null);
2368
2386
  useMidPriceFlash(midRef, midPrice, "transparent");
@@ -2434,13 +2452,13 @@ function MobileOrderbookLayout({
2434
2452
  ]
2435
2453
  }
2436
2454
  ),
2437
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column" }, children: isLoading ? Array.from({ length: COMPACT_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, { compact: true }, `m-ask-skel-${i}`)) : visibleAsks.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0.75rem 0", textAlign: "center", color: "rgba(255,255,255,0.4)", fontSize: "0.72rem" }, children: "No asks" }) : visibleAsks.map((l, i) => /* @__PURE__ */ jsxRuntime.jsx(
2455
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", height: `${effectiveCompactLevels * COMPACT_ROW_HEIGHT_PX}px`, justifyContent: "flex-end", overflow: "hidden" }, children: isLoading ? Array.from({ length: effectiveCompactLevels }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, { compact: true }, `m-ask-skel-${i}`)) : visibleAsks.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0.75rem 0", textAlign: "center", color: "rgba(255,255,255,0.4)", fontSize: "0.72rem" }, children: "No asks" }) : visibleAsks.map((l, i) => /* @__PURE__ */ jsxRuntime.jsx(
2438
2456
  MobileDepthRow,
2439
2457
  {
2440
2458
  side: "ask",
2441
2459
  price: l.price,
2442
2460
  amount: l.amount,
2443
- depthPct: askCumDepths[i] / combinedMaxCumDepth * 100,
2461
+ depthPct: askCumDepths[i] / askMaxCumDepth * 100,
2444
2462
  precision,
2445
2463
  amountPrecision,
2446
2464
  hasUserOrder: userAskPrices.has(l.price),
@@ -2481,13 +2499,13 @@ function MobileOrderbookLayout({
2481
2499
  ]
2482
2500
  }
2483
2501
  ),
2484
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column" }, children: isLoading ? Array.from({ length: COMPACT_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, { compact: true }, `m-bid-skel-${i}`)) : visibleBids.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0.75rem 0", textAlign: "center", color: "rgba(255,255,255,0.4)", fontSize: "0.72rem" }, children: "No bids" }) : visibleBids.map((l, i) => /* @__PURE__ */ jsxRuntime.jsx(
2502
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", height: `${effectiveCompactLevels * COMPACT_ROW_HEIGHT_PX}px`, overflow: "hidden" }, children: isLoading ? Array.from({ length: effectiveCompactLevels }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, { compact: true }, `m-bid-skel-${i}`)) : visibleBids.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0.75rem 0", textAlign: "center", color: "rgba(255,255,255,0.4)", fontSize: "0.72rem" }, children: "No bids" }) : visibleBids.map((l, i) => /* @__PURE__ */ jsxRuntime.jsx(
2485
2503
  MobileDepthRow,
2486
2504
  {
2487
2505
  side: "bid",
2488
2506
  price: l.price,
2489
2507
  amount: l.amount,
2490
- depthPct: bidCumDepths[i] / combinedMaxCumDepth * 100,
2508
+ depthPct: bidCumDepths[i] / bidMaxCumDepth * 100,
2491
2509
  precision,
2492
2510
  amountPrecision,
2493
2511
  hasUserOrder: userBidPrices.has(l.price),
@@ -2507,7 +2525,7 @@ function MobileOrderbookLayout({
2507
2525
  ]
2508
2526
  }
2509
2527
  ),
2510
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, overflowY: "auto", minHeight: 0 }, children: isLoading && tradeFiltered.length === 0 ? Array.from({ length: COMPACT_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, { compact: true }, `m-trade-skel-${i}`)) : tradeFiltered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-6 text-center text-[0.7rem] text-white/50", children: "No trades" }) : tradeFiltered.map((trade, i) => {
2528
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, overflowY: "auto", minHeight: 0 }, children: isLoading && tradeFiltered.length === 0 ? Array.from({ length: effectiveCompactLevels }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, { compact: true }, `m-trade-skel-${i}`)) : tradeFiltered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-6 text-center text-[0.7rem] text-white/50", children: "No trades" }) : tradeFiltered.map((trade, i) => {
2511
2529
  const tradeKey = getTradeKey(trade, i);
2512
2530
  const explorerUrl = trade.txHash && tradeExplorerUrl ? tradeExplorerUrl(trade.txHash) : trade.txHash ? `https://sepolia.etherscan.io/tx/${trade.txHash}` : void 0;
2513
2531
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -2547,7 +2565,8 @@ function MobileDepthRow({
2547
2565
  style: {
2548
2566
  display: "grid",
2549
2567
  gridTemplateColumns: "1.2fr 0.8fr",
2550
- padding: "0.2rem 0",
2568
+ height: `${COMPACT_ROW_HEIGHT_PX}px`,
2569
+ alignItems: "center",
2551
2570
  fontSize: "0.8rem",
2552
2571
  position: "relative",
2553
2572
  cursor: onPriceClick ? "pointer" : void 0
@@ -2690,7 +2709,7 @@ var PropertyTour = React5__namespace.forwardRef(
2690
2709
  }
2691
2710
  );
2692
2711
  PropertyTour.displayName = "PropertyTour";
2693
- var ITEMS_PER_PAGE = 4;
2712
+ var ITEMS_PER_PAGE = 6;
2694
2713
  var ensureAnimationsInjected = () => {
2695
2714
  if (typeof document === "undefined") return;
2696
2715
  if (document.getElementById("property-news-updates-animations")) return;
@@ -2735,6 +2754,22 @@ var formatDate = (value) => {
2735
2754
  if (!(value instanceof Date) || Number.isNaN(value.getTime())) return "";
2736
2755
  return value.toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" });
2737
2756
  };
2757
+ var formatDateShort = (value) => {
2758
+ const d = typeof value === "string" ? new Date(value) : value;
2759
+ if (!(d instanceof Date) || Number.isNaN(d.getTime())) {
2760
+ if (typeof value === "string") {
2761
+ return value.replace(/\s*\d{4}\s*$/, "");
2762
+ }
2763
+ return "";
2764
+ }
2765
+ const diffMs = Date.now() - d.getTime();
2766
+ const diffS = diffMs / 1e3;
2767
+ if (diffS < 60) return "Just now";
2768
+ if (diffS < 3600) return `${Math.floor(diffS / 60)}m ago`;
2769
+ if (diffS < 86400) return `${Math.floor(diffS / 3600)}h ago`;
2770
+ const time = d.toLocaleTimeString(void 0, { hour: "numeric", minute: "2-digit", hour12: true });
2771
+ return `${time} \xB7 ${d.toLocaleDateString(void 0, { month: "short", day: "numeric" })}`;
2772
+ };
2738
2773
  var formatTimeAgo = (timestamp) => {
2739
2774
  const diff = (Date.now() - new Date(timestamp).getTime()) / 1e3;
2740
2775
  if (diff < 60) return `${Math.floor(diff)}s ago`;
@@ -2745,7 +2780,7 @@ function getSentimentInfo(score) {
2745
2780
  if (score == null) return null;
2746
2781
  if (score > 0.15) return { arrow: "\u25B2", label: "Bullish", color: "#0ecb81" };
2747
2782
  if (score < -0.15) return { arrow: "\u25BC", label: "Bearish", color: "#f6465d" };
2748
- return { arrow: "\u2014", label: "Neutral", color: "#848e9c" };
2783
+ return { arrow: "", label: "Neutral", color: "#848e9c" };
2749
2784
  }
2750
2785
  function NewsArticleModal({ item, onClose }) {
2751
2786
  const sentimentInfo = getSentimentInfo(item.sentimentScore);
@@ -2827,8 +2862,7 @@ function NewsArticleModal({ item, onClose }) {
2827
2862
  border: `1px solid ${sentimentInfo.color}40`
2828
2863
  },
2829
2864
  children: [
2830
- sentimentInfo.arrow,
2831
- " ",
2865
+ sentimentInfo.arrow ? `${sentimentInfo.arrow} ` : "",
2832
2866
  sentimentInfo.label
2833
2867
  ]
2834
2868
  }
@@ -2868,7 +2902,35 @@ function NewsArticleModal({ item, onClose }) {
2868
2902
  )
2869
2903
  ] }),
2870
2904
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "1px", background: "rgba(255,255,255,0.08)", marginBottom: "1.25rem" } }),
2871
- item.summary ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.875rem", color: "rgba(255,255,255,0.8)", lineHeight: 1.75, margin: 0 }, children: item.summary }) : /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.8rem", color: "rgba(255,255,255,0.35)", fontStyle: "italic", margin: 0 }, children: "Summary not available for this article." })
2905
+ item.summary ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.875rem", color: "rgba(255,255,255,0.8)", lineHeight: 1.75, margin: 0 }, children: item.summary }) : /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.8rem", color: "rgba(255,255,255,0.35)", fontStyle: "italic", margin: 0 }, children: "Summary not available for this article." }),
2906
+ item.url && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: "1.25rem", paddingTop: "1rem", borderTop: "1px solid rgba(255,255,255,0.08)" }, children: /* @__PURE__ */ jsxRuntime.jsxs(
2907
+ "a",
2908
+ {
2909
+ href: item.url,
2910
+ target: "_blank",
2911
+ rel: "noopener noreferrer",
2912
+ style: {
2913
+ display: "inline-flex",
2914
+ alignItems: "center",
2915
+ gap: "0.4rem",
2916
+ fontSize: "0.8rem",
2917
+ fontWeight: 600,
2918
+ color: "var(--color-accent, #f0b90b)",
2919
+ textDecoration: "none",
2920
+ transition: "opacity 0.15s"
2921
+ },
2922
+ onMouseEnter: (e) => {
2923
+ e.currentTarget.style.opacity = "0.8";
2924
+ },
2925
+ onMouseLeave: (e) => {
2926
+ e.currentTarget.style.opacity = "1";
2927
+ },
2928
+ children: [
2929
+ "Read full article",
2930
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 19H5V5h7V3H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z" }) })
2931
+ ]
2932
+ }
2933
+ ) })
2872
2934
  ]
2873
2935
  }
2874
2936
  )
@@ -2900,6 +2962,7 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
2900
2962
  const [homeTab, setHomeTab] = React5__namespace.useState("all");
2901
2963
  const [homePage, setHomePage] = React5__namespace.useState(0);
2902
2964
  const purchaseItems = purchasesProp ?? [];
2965
+ const [page, setPage] = React5__namespace.useState(0);
2903
2966
  const [selectedItem, setSelectedItem] = React5__namespace.useState(null);
2904
2967
  React5__namespace.useEffect(() => {
2905
2968
  ensureAnimationsInjected();
@@ -2908,6 +2971,14 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
2908
2971
  setHomePage(0);
2909
2972
  }, [homeTab]);
2910
2973
  const hasItems = Array.isArray(items) && items.length > 0;
2974
+ const totalPages = React5__namespace.useMemo(
2975
+ () => hasItems ? Math.max(1, Math.ceil(items.length / ITEMS_PER_PAGE)) : 1,
2976
+ [hasItems, items.length]
2977
+ );
2978
+ React5__namespace.useEffect(() => {
2979
+ setPage((prev) => Math.min(prev, totalPages - 1));
2980
+ }, [totalPages]);
2981
+ const paginatedItems = hasItems ? items.slice(page * ITEMS_PER_PAGE, page * ITEMS_PER_PAGE + ITEMS_PER_PAGE) : [];
2911
2982
  const homeFilteredItems = React5__namespace.useMemo(
2912
2983
  () => hasItems ? items.filter((it) => homeTab === "all" || it.type === homeTab) : [],
2913
2984
  [hasItems, items, homeTab]
@@ -2929,10 +3000,10 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
2929
3000
  children: [
2930
3001
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
2931
3002
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
2932
- isHomeVariant && /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", style: { color: "var(--color-text, #fff)" }, 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-2zm-5 14H4v-4h11v4zm0-5H4V9h11v4zm5 5h-4V9h4v9z" }) }),
3003
+ isHomeVariant && /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", style: { color: "var(--color-text, #fff)", flexShrink: 0, display: "block" }, 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-2zm-5 14H4v-4h11v4zm0-5H4V9h11v4zm5 5h-4V9h4v9z" }) }),
2933
3004
  isPurchaseVariant && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "inline-block", width: "8px", height: "8px", borderRadius: "50%", backgroundColor: "#0ecb81", boxShadow: "0 0 8px rgba(14,203,129,0.8)", animation: "propertyNewsPulse 1.5s infinite" } }),
2934
3005
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2935
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: isHomeVariant ? "text-base font-semibold text-white" : "text-lg font-semibold text-white", children: resolvedHeading }),
3006
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: isHomeVariant ? "text-base font-semibold text-white" : "text-lg font-semibold text-white", style: { margin: 0 }, children: resolvedHeading }),
2936
3007
  subheading ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-white/60", children: subheading }) : null
2937
3008
  ] })
2938
3009
  ] }),
@@ -2947,7 +3018,7 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
2947
3018
  "LIVE"
2948
3019
  ] }) : null
2949
3020
  ] }),
2950
- isHomeVariant && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", gap: 0, marginTop: "0.75rem", marginBottom: "0.25rem" }, children: ["all", "property", "market"].map((tab) => /* @__PURE__ */ jsxRuntime.jsx(
3021
+ isHomeVariant && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", gap: "1.5rem", marginTop: "0.75rem", marginBottom: "0.5rem", borderBottom: "1px solid rgba(255, 255, 255, 0.08)", paddingBottom: "0.5rem" }, children: ["all", "property", "market"].map((tab) => /* @__PURE__ */ jsxRuntime.jsx(
2951
3022
  "button",
2952
3023
  {
2953
3024
  type: "button",
@@ -2956,7 +3027,8 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
2956
3027
  background: "transparent",
2957
3028
  border: "none",
2958
3029
  borderBottom: homeTab === tab ? "2px solid var(--color-accent, #f0b90b)" : "2px solid transparent",
2959
- padding: "0.5rem 0.75rem",
3030
+ padding: "0 0 0.5rem 0",
3031
+ marginBottom: "-1px",
2960
3032
  fontSize: "0.75rem",
2961
3033
  fontWeight: homeTab === tab ? 600 : 400,
2962
3034
  color: homeTab === tab ? "var(--color-text, #fff)" : "var(--color-text-secondary, #848e9c)",
@@ -2970,7 +3042,8 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
2970
3042
  /* @__PURE__ */ jsxRuntime.jsx(
2971
3043
  "div",
2972
3044
  {
2973
- className: "mt-4 flex flex-1 flex-col gap-3 overflow-hidden",
3045
+ className: cn("flex flex-1 flex-col overflow-hidden", isHomeVariant ? "mt-2 gap-0" : "mt-4 gap-3"),
3046
+ style: !isPurchaseVariant && !isHomeVariant ? { minHeight: `${ITEMS_PER_PAGE * 86}px` } : void 0,
2974
3047
  children: isPurchaseVariant ? purchaseItems.length > 0 ? purchaseItems.slice(0, 7).map((purchase, index) => {
2975
3048
  const maxAmount = 6e4;
2976
3049
  const barPercent = Math.min(85, Math.max(15, purchase.amount / maxAmount * 100));
@@ -3008,7 +3081,7 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
3008
3081
  style: {
3009
3082
  width: "100%",
3010
3083
  textAlign: "left",
3011
- background: "transparent",
3084
+ backgroundColor: "transparent",
3012
3085
  border: "none",
3013
3086
  cursor: "pointer",
3014
3087
  padding: "0.75rem 0",
@@ -3017,18 +3090,28 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
3017
3090
  justifyContent: "space-between",
3018
3091
  alignItems: "flex-start",
3019
3092
  gap: "0.5rem",
3020
- color: "inherit"
3093
+ color: "inherit",
3094
+ transition: "background-color 0.15s"
3095
+ },
3096
+ onMouseEnter: (e) => {
3097
+ e.currentTarget.style.backgroundColor = "rgba(255,255,255,0.04)";
3098
+ const title = e.currentTarget.querySelector("h3");
3099
+ if (title) title.style.color = "var(--color-accent, #E6C87E)";
3100
+ },
3101
+ onMouseLeave: (e) => {
3102
+ e.currentTarget.style.backgroundColor = "transparent";
3103
+ const title = e.currentTarget.querySelector("h3");
3104
+ if (title) title.style.color = "#f8f9fa";
3021
3105
  },
3022
3106
  children: [
3023
3107
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1 }, children: [
3024
- /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { fontSize: "0.85rem", fontWeight: 400, marginBottom: "0.25rem", color: "#f8f9fa", lineHeight: 1.4 }, children: item.title }),
3108
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { fontSize: "0.95rem", fontWeight: 500, marginBottom: "0.35rem", color: "#f8f9fa", lineHeight: 1.45, transition: "color 0.15s" }, children: item.title }),
3025
3109
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "0.5rem", alignItems: "center", flexWrap: "wrap" }, children: [
3026
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#848e9c", fontSize: "0.7rem" }, children: typeof item.date === "string" ? item.date : formatDate(item.date) }),
3110
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#848e9c", fontSize: "0.7rem" }, children: formatDateShort(item.date) }),
3027
3111
  item.source && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { padding: "0.1rem 0.4rem", borderRadius: "3px", fontSize: "0.62rem", fontWeight: 500, backgroundColor: "rgba(255,255,255,0.07)", color: "#848e9c", whiteSpace: "nowrap" }, children: item.source }),
3028
3112
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { padding: "0.15rem 0.4rem", borderRadius: "2px", fontSize: "0.65rem", fontWeight: 500, backgroundColor: isProperty ? "rgba(14,203,129,0.1)" : "rgba(240,185,11,0.1)", color: isProperty ? "#0ecb81" : "#f0b90b" }, children: isProperty ? "Property Update" : "Market News" }),
3029
3113
  sentimentInfo && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "0.65rem", fontWeight: 600, color: sentimentInfo.color }, children: [
3030
- sentimentInfo.arrow,
3031
- " ",
3114
+ sentimentInfo.arrow ? `${sentimentInfo.arrow} ` : "",
3032
3115
  sentimentInfo.label
3033
3116
  ] })
3034
3117
  ] })
@@ -3038,11 +3121,12 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
3038
3121
  },
3039
3122
  key
3040
3123
  );
3041
- }) : emptyState ?? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col items-center justify-center py-10 text-center text-sm text-white/60", children: "No property news yet." }) : hasItems ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { overflowY: "auto", maxHeight: "520px", display: "flex", flexDirection: "column", gap: "0" }, children: items.map((item, index) => {
3042
- const key = item.displayId ?? item.id ?? `${item.title}-${index}`;
3124
+ }) : emptyState ?? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col items-center justify-center py-10 text-center text-sm text-white/60", children: "No property news yet." }) : hasItems ? paginatedItems.map((item, index) => {
3125
+ const absoluteIndex = page * ITEMS_PER_PAGE + index;
3126
+ const key = item.displayId ?? item.id ?? `${item.title}-${absoluteIndex}`;
3043
3127
  const catStyle = categoryStyles[item.type] ?? categoryStyles.market;
3044
- const dateLabel = item.isNew ?? (highlightFirst && index === 0) ? "Just now" : typeof item.date === "string" && item.date.trim().length > 0 ? item.date : formatDate(item.date);
3045
- const isHighlighted = item.isNew ?? (highlightFirst && index === 0);
3128
+ const dateLabel = item.isNew ?? (highlightFirst && absoluteIndex === 0) ? "Just now" : typeof item.date === "string" && item.date.trim().length > 0 ? item.date : formatDate(item.date);
3129
+ const isHighlighted = item.isNew ?? (highlightFirst && absoluteIndex === 0);
3046
3130
  const sentimentInfo = getSentimentInfo(item.sentimentScore);
3047
3131
  return /* @__PURE__ */ jsxRuntime.jsx(
3048
3132
  "button",
@@ -3084,8 +3168,7 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
3084
3168
  ] }),
3085
3169
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "flex-end", gap: "0.3rem", flexShrink: 0 }, children: [
3086
3170
  sentimentInfo && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "0.65rem", fontWeight: 700, color: sentimentInfo.color, whiteSpace: "nowrap" }, children: [
3087
- sentimentInfo.arrow,
3088
- " ",
3171
+ sentimentInfo.arrow ? `${sentimentInfo.arrow} ` : "",
3089
3172
  sentimentInfo.label
3090
3173
  ] }),
3091
3174
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { padding: "0.25rem 0.6rem", borderRadius: "4px", border: `1px solid ${catStyle.borderColor}`, backgroundColor: catStyle.backgroundColor, color: catStyle.color, fontSize: "0.68rem", fontWeight: 600, textTransform: "uppercase", whiteSpace: "nowrap" }, children: item.type === "property" ? catStyle.label : "Market News" })
@@ -3097,7 +3180,7 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
3097
3180
  },
3098
3181
  key
3099
3182
  );
3100
- }) }) : emptyState ?? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center rounded-2xl border border-dashed border-white/20 px-6 py-10 text-center text-sm text-white/60", children: [
3183
+ }) : emptyState ?? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center rounded-2xl border border-dashed border-white/20 px-6 py-10 text-center text-sm text-white/60", children: [
3101
3184
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Newspaper, { className: "mb-3 h-8 w-8 text-white/40" }),
3102
3185
  "No property news yet. Updates will land here as soon as we receive new intelligence."
3103
3186
  ] })
@@ -3110,8 +3193,8 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
3110
3193
  type: "button",
3111
3194
  onClick: () => setHomePage((p) => Math.max(0, p - 1)),
3112
3195
  disabled: homePage === 0,
3113
- style: { background: "transparent", border: "1px solid rgba(255,255,255,0.15)", borderRadius: "999px", padding: "0.2rem 0.75rem", fontSize: "0.7rem", textTransform: "uppercase", letterSpacing: "0.15em", cursor: homePage === 0 ? "not-allowed" : "pointer", opacity: homePage === 0 ? 0.4 : 1, color: "rgba(255,255,255,0.6)" },
3114
- children: "Prev"
3196
+ style: { background: "transparent", border: "1px solid rgba(255,255,255,0.15)", borderRadius: "50%", width: "28px", height: "28px", display: "flex", alignItems: "center", justifyContent: "center", padding: 0, cursor: homePage === 0 ? "not-allowed" : "pointer", opacity: homePage === 0 ? 0.4 : 1, color: "rgba(255,255,255,0.6)" },
3197
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" }) })
3115
3198
  }
3116
3199
  ),
3117
3200
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "0.7rem", color: "rgba(255,255,255,0.5)" }, children: [
@@ -3125,8 +3208,38 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
3125
3208
  type: "button",
3126
3209
  onClick: () => setHomePage((p) => Math.min(homeTotalPages - 1, p + 1)),
3127
3210
  disabled: homePage >= homeTotalPages - 1,
3128
- style: { background: "transparent", border: "1px solid rgba(255,255,255,0.15)", borderRadius: "999px", padding: "0.2rem 0.75rem", fontSize: "0.7rem", textTransform: "uppercase", letterSpacing: "0.15em", cursor: homePage >= homeTotalPages - 1 ? "not-allowed" : "pointer", opacity: homePage >= homeTotalPages - 1 ? 0.4 : 1, color: "rgba(255,255,255,0.6)" },
3129
- children: "Next"
3211
+ style: { background: "transparent", border: "1px solid rgba(255,255,255,0.15)", borderRadius: "50%", width: "28px", height: "28px", display: "flex", alignItems: "center", justifyContent: "center", padding: 0, cursor: homePage >= homeTotalPages - 1 ? "not-allowed" : "pointer", opacity: homePage >= homeTotalPages - 1 ? 0.4 : 1, color: "rgba(255,255,255,0.6)" },
3212
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) })
3213
+ }
3214
+ )
3215
+ ] }),
3216
+ !isPurchaseVariant && !isHomeVariant && hasItems && totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 flex items-center justify-between text-xs text-white/60", children: [
3217
+ /* @__PURE__ */ jsxRuntime.jsx(
3218
+ "button",
3219
+ {
3220
+ type: "button",
3221
+ onClick: () => setPage((p) => Math.max(0, p - 1)),
3222
+ disabled: page === 0,
3223
+ className: cn("rounded-full border border-white/15 flex items-center justify-center", page === 0 ? "opacity-40 cursor-not-allowed" : "hover:border-white/40"),
3224
+ style: { width: "28px", height: "28px", padding: 0, background: "transparent", color: "rgba(255,255,255,0.6)" },
3225
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" }) })
3226
+ }
3227
+ ),
3228
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium text-white/70", children: [
3229
+ "Page ",
3230
+ page + 1,
3231
+ " / ",
3232
+ totalPages
3233
+ ] }),
3234
+ /* @__PURE__ */ jsxRuntime.jsx(
3235
+ "button",
3236
+ {
3237
+ type: "button",
3238
+ onClick: () => setPage((p) => Math.min(totalPages - 1, p + 1)),
3239
+ disabled: page >= totalPages - 1,
3240
+ className: cn("rounded-full border border-white/15 flex items-center justify-center", page >= totalPages - 1 ? "opacity-40 cursor-not-allowed" : "hover:border-white/40"),
3241
+ style: { width: "28px", height: "28px", padding: 0, background: "transparent", color: "rgba(255,255,255,0.6)" },
3242
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) })
3130
3243
  }
3131
3244
  )
3132
3245
  ] }),
@@ -4629,14 +4742,16 @@ var PropertyHeroHeader = React5__namespace.forwardRef(
4629
4742
  imageUrl,
4630
4743
  imageAlt,
4631
4744
  name,
4745
+ address,
4632
4746
  location,
4633
4747
  price,
4634
4748
  currencySymbol = "$",
4635
4749
  changePercent,
4636
- beds,
4637
- baths,
4638
- cars,
4639
- propertyTypeLabel,
4750
+ priceChange,
4751
+ beds: _beds,
4752
+ baths: _baths,
4753
+ cars: _cars,
4754
+ propertyTypeLabel: _propertyTypeLabel,
4640
4755
  onTrade,
4641
4756
  onMakeOffer,
4642
4757
  tradeButtonLabel = "Trade",
@@ -4652,7 +4767,6 @@ var PropertyHeroHeader = React5__namespace.forwardRef(
4652
4767
  const tradeHoverColor = "#f5dd9a";
4653
4768
  const [isTradeInteracting, setIsTradeInteracting] = React5__namespace.useState(false);
4654
4769
  const [isOfferInteracting, setIsOfferInteracting] = React5__namespace.useState(false);
4655
- const hasAmenities = isLoading || beds != null || baths != null || cars != null || propertyTypeLabel != null;
4656
4770
  const isTradeDisabled = !onTrade;
4657
4771
  const isMakeOfferButtonDisabled = makeOfferDisabled || !onMakeOffer;
4658
4772
  const showMakeOfferButton = !hideMakeOfferButton;
@@ -4665,201 +4779,112 @@ var PropertyHeroHeader = React5__namespace.forwardRef(
4665
4779
  setIsOfferInteracting(state);
4666
4780
  };
4667
4781
  const headingStyle = {
4668
- fontSize: "clamp(1.6rem, 4vw, 2.5rem)",
4669
- marginBottom: "0.5rem",
4782
+ fontSize: "clamp(1.3rem, 3vw, 1.8rem)",
4783
+ marginBottom: "0",
4670
4784
  color: "#ffffff",
4671
4785
  textShadow: "0 2px 4px rgba(0, 0, 0, 0.3)",
4672
4786
  fontWeight: 600,
4673
4787
  lineHeight: 1.2
4674
4788
  };
4675
- return /* @__PURE__ */ jsxRuntime.jsxs(OuterWrapper, { ref, className: cn(className), ...props, children: [
4676
- /* @__PURE__ */ jsxRuntime.jsxs(HeroContainer, { children: [
4677
- /* @__PURE__ */ jsxRuntime.jsx(
4678
- HeroImage,
4679
- {
4680
- src: imageUrl,
4681
- alt: imageAlt ?? name
4682
- }
4683
- ),
4684
- statusBadge ? /* @__PURE__ */ jsxRuntime.jsxs(StatusBadge, { $isLive: statusBadge.variant === "live", children: [
4685
- statusBadge.variant === "live" ? /* @__PURE__ */ jsxRuntime.jsx(PulsingDot, {}) : null,
4686
- statusBadge.label
4687
- ] }) : null,
4688
- /* @__PURE__ */ jsxRuntime.jsx(HeroGradient, { "aria-hidden": "true" }),
4689
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-0 right-0 z-10 flex w-full items-end justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[1800px] flex-wrap items-end justify-between gap-4 p-8 max-[768px]:flex-col max-[768px]:items-start max-[768px]:gap-4 max-[768px]:p-6 max-[480px]:p-4", children: [
4690
- /* @__PURE__ */ jsxRuntime.jsxs(InfoCard, { children: [
4691
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 space-y-2", children: [
4692
- /* @__PURE__ */ jsxRuntime.jsx("h1", { style: headingStyle, className: "break-words", children: name }),
4693
- /* @__PURE__ */ jsxRuntime.jsxs(InfoRow, { className: "mb-3 max-[768px]:mb-[0.6rem] max-[480px]:mb-[0.5rem]", children: [
4694
- /* @__PURE__ */ jsxRuntime.jsx(LocationText, { children: location }),
4695
- isLoading ? /* @__PURE__ */ jsxRuntime.jsx(PriceBlock, { children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 110, height: 18 }) }) : price == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(PriceBlock, { children: [
4696
- formatPrice3(price, currencySymbol),
4697
- changePercent == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(
4698
- "span",
4699
- {
4700
- className: cn(
4701
- "ml-2 flex items-center text-[0.875rem] font-medium",
4702
- isPositive ? "text-[#0ecb81]" : "text-[#f6465d]"
4703
- ),
4704
- children: [
4705
- /* @__PURE__ */ jsxRuntime.jsx(
4706
- "svg",
4707
- {
4708
- xmlns: "http://www.w3.org/2000/svg",
4709
- width: "12",
4710
- height: "12",
4711
- viewBox: "0 0 24 24",
4712
- fill: "currentColor",
4713
- className: "mr-[0.15rem]",
4714
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: isPositive ? "M7 14l5-5 5 5H7z" : "M7 10l5 5 5-5H7z" })
4715
- }
4716
- ),
4717
- Math.abs(changePercent).toFixed(2),
4718
- "%"
4719
- ]
4720
- }
4721
- )
4722
- ] })
4723
- ] })
4724
- ] }),
4725
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-6 text-[0.95rem] text-white/90 max-[768px]:hidden", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4726
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
4727
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BedDouble, { className: "mr-2 h-[18px] w-[18px] opacity-60" }),
4728
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 52, height: 14 })
4729
- ] }),
4730
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
4731
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bath, { className: "mr-2 h-[18px] w-[18px] opacity-60" }),
4732
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 56, height: 14 })
4733
- ] }),
4734
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
4735
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CarFront, { className: "mr-2 h-[18px] w-[18px] opacity-60" }),
4736
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 50, height: 14 })
4737
- ] }),
4738
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 60, height: 14 })
4739
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4740
- beds == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
4741
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BedDouble, { className: "mr-2 h-[18px] w-[18px]" }),
4742
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4743
- beds,
4744
- " Beds"
4745
- ] })
4746
- ] }),
4747
- baths == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
4748
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bath, { className: "mr-2 h-[18px] w-[18px]" }),
4749
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4750
- baths,
4751
- " Baths"
4752
- ] })
4789
+ return /* @__PURE__ */ jsxRuntime.jsx(OuterWrapper, { ref, className: cn(className), ...props, children: /* @__PURE__ */ jsxRuntime.jsxs(HeroContainer, { children: [
4790
+ /* @__PURE__ */ jsxRuntime.jsx(
4791
+ HeroImage,
4792
+ {
4793
+ src: imageUrl,
4794
+ alt: imageAlt ?? name
4795
+ }
4796
+ ),
4797
+ statusBadge ? /* @__PURE__ */ jsxRuntime.jsxs(StatusBadge, { $isLive: statusBadge.variant === "live", children: [
4798
+ statusBadge.variant === "live" ? /* @__PURE__ */ jsxRuntime.jsx(PulsingDot, {}) : null,
4799
+ statusBadge.label
4800
+ ] }) : null,
4801
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-0 right-0 z-10 flex w-full items-end justify-center", style: { background: "linear-gradient(to top, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0) 100%)" }, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[1800px] flex-wrap items-end justify-between gap-4 p-8 max-[768px]:flex-col max-[768px]:items-start max-[768px]:gap-4 max-[768px]:p-6 max-[480px]:p-4", children: [
4802
+ /* @__PURE__ */ jsxRuntime.jsx(InfoCard, { children: /* @__PURE__ */ jsxRuntime.jsxs(CardLayout, { children: [
4803
+ /* @__PURE__ */ jsxRuntime.jsx(Thumbnail, { src: imageUrl, alt: imageAlt ?? name }),
4804
+ /* @__PURE__ */ jsxRuntime.jsx(CardContent2, { children: /* @__PURE__ */ jsxRuntime.jsxs(InfoRow, { children: [
4805
+ /* @__PURE__ */ jsxRuntime.jsx(NameGroup, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column" }, children: [
4806
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.75rem", flexWrap: "wrap" }, children: [
4807
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { style: headingStyle, className: "break-words", children: name }),
4808
+ location ? /* @__PURE__ */ jsxRuntime.jsx(TypeBadge, { children: location }) : null
4753
4809
  ] }),
4754
- cars == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
4755
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CarFront, { className: "mr-2 h-[18px] w-[18px]" }),
4756
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4757
- cars,
4758
- " Cars"
4759
- ] })
4810
+ address ? /* @__PURE__ */ jsxRuntime.jsx(AddressText, { children: address }) : null
4811
+ ] }) }),
4812
+ /* @__PURE__ */ jsxRuntime.jsxs(PriceGroup, { children: [
4813
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 110, height: 24 }) : price == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(PriceRow, { children: [
4814
+ /* @__PURE__ */ jsxRuntime.jsx(CurrencyLabel, { children: "USD" }),
4815
+ changePercent != null ? /* @__PURE__ */ jsxRuntime.jsx(PriceArrow, { $isPositive: isPositive, children: isPositive ? "\u25B2" : "\u25BC" }) : null,
4816
+ formatPrice3(price, "")
4760
4817
  ] }),
4761
- propertyTypeLabel == null ? null : /* @__PURE__ */ jsxRuntime.jsx("div", { children: propertyTypeLabel })
4762
- ] }) })
4763
- ] }),
4764
- /* @__PURE__ */ jsxRuntime.jsxs(ActionButtons, { children: [
4765
- /* @__PURE__ */ jsxRuntime.jsx(
4766
- "button",
4767
- {
4768
- type: "button",
4769
- onClick: isTradeDisabled ? void 0 : onTrade,
4770
- className: "flex items-center justify-center rounded border font-semibold transition-all duration-200 hover:-translate-y-0.5 hover:shadow-[0_4px_8px_rgba(0,0,0,0.2)] active:translate-y-0 active:shadow-[0_2px_4px_rgba(0,0,0,0.1)] text-[0.95rem] max-[480px]:text-[0.9rem]",
4771
- style: {
4772
- backgroundColor: isTradeInteracting ? tradeHoverColor : accentColor,
4773
- color: "black",
4774
- padding: "0.75rem 1.5rem",
4775
- borderColor: isTradeInteracting ? accentColor : "transparent",
4776
- boxShadow: isTradeInteracting ? `0 0 0 2px rgba(0,0,0,0.4), 0 0 0 4px ${accentColor}` : "none",
4777
- opacity: isTradeDisabled ? 0.5 : 1,
4778
- cursor: isTradeDisabled ? "not-allowed" : "pointer"
4779
- },
4780
- onMouseEnter: () => setTradeInteraction(true),
4781
- onMouseLeave: () => setTradeInteraction(false),
4782
- onMouseDown: () => setTradeInteraction(true),
4783
- onMouseUp: () => setTradeInteraction(false),
4784
- onFocus: () => setTradeInteraction(true),
4785
- onBlur: () => setTradeInteraction(false),
4786
- onTouchStart: () => setTradeInteraction(true),
4787
- onTouchEnd: () => setTradeInteraction(false),
4788
- disabled: isTradeDisabled,
4789
- "aria-disabled": isTradeDisabled,
4790
- children: tradeButtonLabel
4791
- }
4792
- ),
4793
- showMakeOfferButton ? /* @__PURE__ */ jsxRuntime.jsx(
4794
- "button",
4795
- {
4796
- type: "button",
4797
- onClick: isMakeOfferButtonDisabled ? void 0 : onMakeOffer,
4798
- className: "flex items-center justify-center rounded border font-semibold transition-all duration-200 hover:-translate-y-0.5 hover:shadow-[0_4px_8px_rgba(0,0,0,0.2)] active:translate-y-0 active:shadow-[0_2px_4px_rgba(0,0,0,0.1)] text-[0.95rem] max-[480px]:text-[0.9rem]",
4799
- style: {
4800
- backgroundColor: isOfferInteracting ? accentColor : "transparent",
4801
- borderColor: accentColor,
4802
- color: isOfferInteracting ? "black" : accentColor,
4803
- padding: "0.75rem 1.5rem",
4804
- boxShadow: isOfferInteracting ? `0 0 0 2px rgba(0,0,0,0.4), 0 0 0 4px ${accentColor}` : "none",
4805
- opacity: isMakeOfferButtonDisabled ? 0.5 : 1,
4806
- cursor: isMakeOfferButtonDisabled ? "not-allowed" : "pointer"
4807
- },
4808
- onMouseEnter: () => setOfferInteraction(true),
4809
- onMouseLeave: () => setOfferInteraction(false),
4810
- onMouseDown: () => setOfferInteraction(true),
4811
- onMouseUp: () => setOfferInteraction(false),
4812
- onFocus: () => setOfferInteraction(true),
4813
- onBlur: () => setOfferInteraction(false),
4814
- onTouchStart: () => setOfferInteraction(true),
4815
- onTouchEnd: () => setOfferInteraction(false),
4816
- disabled: isMakeOfferButtonDisabled,
4817
- "aria-disabled": isMakeOfferButtonDisabled,
4818
- children: makeOfferButtonLabel
4819
- }
4820
- ) : null
4821
- ] })
4822
- ] }) })
4823
- ] }),
4824
- hasAmenities ? /* @__PURE__ */ jsxRuntime.jsx(MobileAmenities, { children: isLoading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4825
- /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenity, { children: [
4826
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BedDouble, { className: "h-4 w-4 opacity-60" }),
4827
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 40, height: 12 })
4828
- ] }),
4829
- /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenity, { children: [
4830
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bath, { className: "h-4 w-4 opacity-60" }),
4831
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 44, height: 12 })
4832
- ] }),
4833
- /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenity, { children: [
4834
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CarFront, { className: "h-4 w-4 opacity-60" }),
4835
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 42, height: 12 })
4836
- ] }),
4837
- /* @__PURE__ */ jsxRuntime.jsx(MobileAmenity, { children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 52, height: 12 }) })
4838
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4839
- beds == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenity, { children: [
4840
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BedDouble, { className: "h-4 w-4" }),
4841
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4842
- beds,
4843
- " Beds"
4844
- ] })
4845
- ] }),
4846
- baths == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenity, { children: [
4847
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bath, { className: "h-4 w-4" }),
4848
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4849
- baths,
4850
- " Baths"
4851
- ] })
4852
- ] }),
4853
- cars == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenity, { children: [
4854
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CarFront, { className: "h-4 w-4" }),
4855
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4856
- cars,
4857
- " Cars"
4858
- ] })
4859
- ] }),
4860
- propertyTypeLabel == null ? null : /* @__PURE__ */ jsxRuntime.jsx(MobileAmenity, { children: propertyTypeLabel })
4861
- ] }) }) : null
4862
- ] });
4818
+ changePercent != null ? /* @__PURE__ */ jsxRuntime.jsxs(PriceChangeRow, { $isPositive: isPositive, children: [
4819
+ priceChange != null ? `${isPositive ? "+" : ""}${priceChange.toFixed(2)} ` : null,
4820
+ "(",
4821
+ isPositive ? "+" : "",
4822
+ Math.abs(changePercent).toFixed(2),
4823
+ "%)"
4824
+ ] }) : null
4825
+ ] })
4826
+ ] }) })
4827
+ ] }) }),
4828
+ /* @__PURE__ */ jsxRuntime.jsxs(ActionButtons, { children: [
4829
+ /* @__PURE__ */ jsxRuntime.jsx(
4830
+ "button",
4831
+ {
4832
+ type: "button",
4833
+ onClick: isTradeDisabled ? void 0 : onTrade,
4834
+ className: "flex items-center justify-center rounded border font-semibold transition-all duration-200 hover:-translate-y-0.5 hover:shadow-[0_4px_8px_rgba(0,0,0,0.2)] active:translate-y-0 active:shadow-[0_2px_4px_rgba(0,0,0,0.1)] text-[0.95rem] max-[480px]:text-[0.9rem]",
4835
+ style: {
4836
+ backgroundColor: isTradeInteracting ? tradeHoverColor : accentColor,
4837
+ color: "black",
4838
+ padding: "0.75rem 1.5rem",
4839
+ borderColor: isTradeInteracting ? accentColor : "transparent",
4840
+ boxShadow: isTradeInteracting ? `0 0 0 2px rgba(0,0,0,0.4), 0 0 0 4px ${accentColor}` : "none",
4841
+ opacity: isTradeDisabled ? 0.5 : 1,
4842
+ cursor: isTradeDisabled ? "not-allowed" : "pointer"
4843
+ },
4844
+ onMouseEnter: () => setTradeInteraction(true),
4845
+ onMouseLeave: () => setTradeInteraction(false),
4846
+ onMouseDown: () => setTradeInteraction(true),
4847
+ onMouseUp: () => setTradeInteraction(false),
4848
+ onFocus: () => setTradeInteraction(true),
4849
+ onBlur: () => setTradeInteraction(false),
4850
+ onTouchStart: () => setTradeInteraction(true),
4851
+ onTouchEnd: () => setTradeInteraction(false),
4852
+ disabled: isTradeDisabled,
4853
+ "aria-disabled": isTradeDisabled,
4854
+ children: tradeButtonLabel
4855
+ }
4856
+ ),
4857
+ showMakeOfferButton ? /* @__PURE__ */ jsxRuntime.jsx(
4858
+ "button",
4859
+ {
4860
+ type: "button",
4861
+ onClick: isMakeOfferButtonDisabled ? void 0 : onMakeOffer,
4862
+ className: "flex items-center justify-center rounded border font-semibold transition-all duration-200 hover:-translate-y-0.5 hover:shadow-[0_4px_8px_rgba(0,0,0,0.2)] active:translate-y-0 active:shadow-[0_2px_4px_rgba(0,0,0,0.1)] text-[0.95rem] max-[480px]:text-[0.9rem]",
4863
+ style: {
4864
+ backgroundColor: isOfferInteracting ? accentColor : "transparent",
4865
+ borderColor: accentColor,
4866
+ color: isOfferInteracting ? "black" : accentColor,
4867
+ padding: "0.75rem 1.5rem",
4868
+ boxShadow: isOfferInteracting ? `0 0 0 2px rgba(0,0,0,0.4), 0 0 0 4px ${accentColor}` : "none",
4869
+ opacity: isMakeOfferButtonDisabled ? 0.5 : 1,
4870
+ cursor: isMakeOfferButtonDisabled ? "not-allowed" : "pointer"
4871
+ },
4872
+ onMouseEnter: () => setOfferInteraction(true),
4873
+ onMouseLeave: () => setOfferInteraction(false),
4874
+ onMouseDown: () => setOfferInteraction(true),
4875
+ onMouseUp: () => setOfferInteraction(false),
4876
+ onFocus: () => setOfferInteraction(true),
4877
+ onBlur: () => setOfferInteraction(false),
4878
+ onTouchStart: () => setOfferInteraction(true),
4879
+ onTouchEnd: () => setOfferInteraction(false),
4880
+ disabled: isMakeOfferButtonDisabled,
4881
+ "aria-disabled": isMakeOfferButtonDisabled,
4882
+ children: makeOfferButtonLabel
4883
+ }
4884
+ ) : null
4885
+ ] })
4886
+ ] }) })
4887
+ ] }) });
4863
4888
  }
4864
4889
  );
4865
4890
  PropertyHeroHeader.displayName = "PropertyHeroHeader";
@@ -4902,32 +4927,6 @@ var HeroContainer = styled25__default.default.div`
4902
4927
  border-radius: 6px;
4903
4928
  }
4904
4929
  `;
4905
- var MobileAmenities = styled25__default.default.div`
4906
- display: none;
4907
- align-items: center;
4908
- justify-content: space-between;
4909
- gap: 0.5rem;
4910
- padding: 0.5rem 0.75rem;
4911
- background: rgba(8, 8, 12, 0.85);
4912
- border-radius: 12px;
4913
- border: 1px solid rgba(255, 255, 255, 0.1);
4914
- color: rgba(255, 255, 255, 0.85);
4915
- font-size: 0.85rem;
4916
-
4917
- @media (max-width: 768px) {
4918
- display: flex;
4919
- flex-wrap: wrap;
4920
- }
4921
- `;
4922
- var MobileAmenity = styled25__default.default.span`
4923
- display: inline-flex;
4924
- align-items: center;
4925
- gap: 0.35rem;
4926
- padding: 0.35rem 0.5rem;
4927
- border-radius: 999px;
4928
- background: rgba(255, 255, 255, 0.08);
4929
- font-weight: 500;
4930
- `;
4931
4930
  var HeroImage = styled25__default.default.img`
4932
4931
  width: 100%;
4933
4932
  height: 100%;
@@ -4942,15 +4941,6 @@ var HeroImage = styled25__default.default.img`
4942
4941
  transform: scale(1.0);
4943
4942
  transform-origin: center;
4944
4943
  `;
4945
- var HeroGradient = styled25__default.default.div`
4946
- position: absolute;
4947
- bottom: 0;
4948
- left: 0;
4949
- right: 0;
4950
- width: 100%;
4951
- z-index: 1;
4952
- background: linear-gradient(to top, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0) 100%);
4953
- `;
4954
4944
  var ActionButtons = styled25__default.default.div`
4955
4945
  display: flex;
4956
4946
  flex-wrap: wrap;
@@ -4966,13 +4956,42 @@ var ActionButtons = styled25__default.default.div`
4966
4956
  display: none;
4967
4957
  }
4968
4958
  `;
4959
+ var CardLayout = styled25__default.default.div`
4960
+ display: flex;
4961
+ align-items: center;
4962
+ gap: 1rem;
4963
+
4964
+ @media (max-width: 480px) {
4965
+ gap: 0.75rem;
4966
+ }
4967
+ `;
4968
+ var Thumbnail = styled25__default.default.img`
4969
+ width: 72px;
4970
+ height: 72px;
4971
+ border-radius: 8px;
4972
+ object-fit: cover;
4973
+ flex-shrink: 0;
4974
+ border: 1px solid rgba(255, 255, 255, 0.15);
4975
+
4976
+ @media (max-width: 768px) {
4977
+ width: 56px;
4978
+ height: 56px;
4979
+ border-radius: 6px;
4980
+ }
4981
+
4982
+ @media (max-width: 480px) {
4983
+ width: 48px;
4984
+ height: 48px;
4985
+ }
4986
+ `;
4987
+ var CardContent2 = styled25__default.default.div`
4988
+ min-width: 0;
4989
+ flex: 1;
4990
+ `;
4969
4991
  var InfoCard = styled25__default.default.div`
4970
- display: inline-block;
4971
- width: fit-content;
4972
- max-width: 70%;
4973
4992
  border-radius: 12px;
4974
- background: rgba(0, 0, 0, 0.12);
4975
- padding: 0.75rem 1rem;
4993
+ background: rgba(0, 0, 0, 0.15);
4994
+ padding: 1rem 1.5rem;
4976
4995
  color: #fff;
4977
4996
  backdrop-filter: blur(6px);
4978
4997
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
@@ -4980,66 +4999,113 @@ var InfoCard = styled25__default.default.div`
4980
4999
  min-width: 0;
4981
5000
 
4982
5001
  @media (max-width: 768px) {
4983
- max-width: 85%;
4984
- }
4985
-
4986
- @media (max-width: 640px) {
4987
- max-width: 92%;
5002
+ padding: 0.85rem 1.15rem;
4988
5003
  }
4989
5004
 
4990
5005
  @media (max-width: 480px) {
4991
- max-width: 95%;
5006
+ padding: 0.65rem 0.85rem;
4992
5007
  }
4993
5008
  `;
4994
- var InfoRow = styled25__default.default.div`
4995
- display: grid;
4996
- grid-template-columns: minmax(0, 1fr) auto;
5009
+ var NameGroup = styled25__default.default.div`
5010
+ display: flex;
4997
5011
  align-items: center;
4998
5012
  gap: 0.75rem;
4999
- width: 100%;
5000
-
5001
- @media (max-width: 640px) {
5002
- gap: 0.5rem;
5003
- }
5013
+ min-width: 0;
5014
+ flex-wrap: wrap;
5004
5015
  `;
5005
- var LocationText = styled25__default.default.span`
5006
- font-size: clamp(1rem, 2.6vw, 1.25rem);
5007
- color: rgba(255, 255, 255, 0.9);
5008
- font-weight: 500;
5009
- overflow: hidden;
5010
- text-overflow: ellipsis;
5016
+ var TypeBadge = styled25__default.default.span`
5017
+ display: inline-flex;
5018
+ align-items: center;
5019
+ padding: 0.2rem 0.5rem;
5020
+ border-radius: 4px;
5021
+ font-size: 0.7rem;
5022
+ font-weight: 600;
5023
+ letter-spacing: 0.03em;
5024
+ text-transform: uppercase;
5025
+ line-height: 1;
5026
+ color: #E6C87E;
5027
+ background: rgba(230, 200, 126, 0.12);
5011
5028
  white-space: nowrap;
5029
+ flex-shrink: 0;
5012
5030
  `;
5013
- var PriceBlock = styled25__default.default.span`
5031
+ var InfoRow = styled25__default.default.div`
5014
5032
  display: flex;
5015
- align-items: center;
5016
- font-size: clamp(1rem, 2.2vw, 1.25rem);
5017
- font-weight: 600;
5018
- color: var(--color-accent, #f0b90b);
5019
- padding-left: 1rem;
5020
- border-left: 1px solid rgba(255, 255, 255, 0.25);
5021
- min-height: 1.5rem;
5033
+ align-items: baseline;
5034
+ justify-content: space-between;
5035
+ gap: 1rem;
5022
5036
  `;
5023
- var StatusBadge = styled25__default.default.div`
5024
- position: absolute;
5025
- top: 1rem;
5026
- left: 1rem;
5037
+ var PriceGroup = styled25__default.default.div`
5027
5038
  display: flex;
5028
- align-items: center;
5029
- gap: 0.5rem;
5030
- background-color: ${({ $isLive }) => $isLive ? "rgba(20, 20, 20, 0.85)" : "rgba(240, 185, 11, 0.9)"};
5031
- color: ${({ $isLive }) => $isLive ? "#f0b90b" : "#000"};
5032
- padding: 0.5rem 1rem;
5033
- border-radius: 6px;
5039
+ flex-direction: column;
5040
+ align-items: flex-end;
5041
+ flex-shrink: 0;
5042
+ `;
5043
+ var PriceRow = styled25__default.default.span`
5044
+ display: inline-flex;
5045
+ align-items: baseline;
5046
+ font-size: clamp(1.3rem, 3vw, 1.8rem);
5034
5047
  font-weight: 600;
5035
- font-size: 0.875rem;
5036
- z-index: 10;
5037
- border: ${({ $isLive }) => $isLive ? "1px solid rgba(240, 185, 11, 0.5)" : "none"};
5038
- backdrop-filter: blur(8px);
5048
+ color: #fff;
5049
+ font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', 'JetBrains Mono', ui-monospace, monospace;
5050
+ font-variant-numeric: tabular-nums;
5051
+ white-space: nowrap;
5052
+ flex-shrink: 0;
5039
5053
  `;
5040
- var PulsingDot = styled25__default.default.span`
5041
- display: inline-block;
5042
- width: 8px;
5054
+ var CurrencyLabel = styled25__default.default.span`
5055
+ font-size: 0.55em;
5056
+ font-weight: 500;
5057
+ color: rgba(255, 255, 255, 0.4);
5058
+ margin-right: 0.3em;
5059
+ `;
5060
+ var PriceArrow = styled25__default.default.span`
5061
+ color: ${({ $isPositive }) => $isPositive ? "#0ecb81" : "#f6465d"};
5062
+ font-size: 0.65em;
5063
+ margin: 0 0.1em;
5064
+ `;
5065
+ var AddressText = styled25__default.default.p`
5066
+ font-size: 1.1rem;
5067
+ color: rgba(255, 255, 255, 0.7);
5068
+ font-weight: 400;
5069
+ margin: 0.1rem 0 0;
5070
+
5071
+ @media (max-width: 768px) {
5072
+ font-size: 1rem;
5073
+ }
5074
+
5075
+ @media (max-width: 480px) {
5076
+ font-size: 0.9rem;
5077
+ }
5078
+ `;
5079
+ var PriceChangeRow = styled25__default.default.span`
5080
+ display: inline-flex;
5081
+ align-items: center;
5082
+ white-space: nowrap;
5083
+ flex-shrink: 0;
5084
+ font-size: 0.85rem;
5085
+ font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', 'JetBrains Mono', ui-monospace, monospace;
5086
+ font-variant-numeric: tabular-nums;
5087
+ color: ${({ $isPositive }) => $isPositive ? "#0ecb81" : "#f6465d"};
5088
+ `;
5089
+ var StatusBadge = styled25__default.default.div`
5090
+ position: absolute;
5091
+ top: 1rem;
5092
+ left: 1rem;
5093
+ display: flex;
5094
+ align-items: center;
5095
+ gap: 0.5rem;
5096
+ background-color: ${({ $isLive }) => $isLive ? "rgba(20, 20, 20, 0.85)" : "rgba(240, 185, 11, 0.9)"};
5097
+ color: ${({ $isLive }) => $isLive ? "#f0b90b" : "#000"};
5098
+ padding: 0.5rem 1rem;
5099
+ border-radius: 6px;
5100
+ font-weight: 600;
5101
+ font-size: 0.875rem;
5102
+ z-index: 10;
5103
+ border: ${({ $isLive }) => $isLive ? "1px solid rgba(240, 185, 11, 0.5)" : "none"};
5104
+ backdrop-filter: blur(8px);
5105
+ `;
5106
+ var PulsingDot = styled25__default.default.span`
5107
+ display: inline-block;
5108
+ width: 8px;
5043
5109
  height: 8px;
5044
5110
  background-color: #f0b90b;
5045
5111
  border-radius: 50%;
@@ -5095,13 +5161,45 @@ var Header = ({
5095
5161
  onProfileNavigate: _onProfileNavigate,
5096
5162
  onOrdersNavigate: _onOrdersNavigate,
5097
5163
  onWalletNavigate: _onWalletNavigate,
5098
- showTradeTab = true
5164
+ showTradeTab = true,
5165
+ portfolioSummary
5099
5166
  }) => {
5100
5167
  const [isUserMenuOpen, setIsUserMenuOpen] = React5.useState(false);
5101
5168
  const [isMobileMenuOpen, setIsMobileMenuOpen] = React5.useState(false);
5102
5169
  const [isMoreMenuOpen, setIsMoreMenuOpen] = React5.useState(false);
5103
5170
  const [showLoginPopup, setShowLoginPopup] = React5.useState(false);
5104
5171
  const [loginPopupInitialView, setLoginPopupInitialView] = React5.useState(void 0);
5172
+ const [isPortfolioBarVisible, setIsPortfolioBarVisible] = React5.useState(() => {
5173
+ if (typeof localStorage === "undefined") return false;
5174
+ return localStorage.getItem("portfolioBarVisible") !== "false";
5175
+ });
5176
+ const portfolioPillRef = React5.useRef(null);
5177
+ const [portfolioArrowLeft, setPortfolioArrowLeft] = React5.useState(null);
5178
+ const togglePortfolioBar = React5.useCallback(() => {
5179
+ setIsPortfolioBarVisible((prev) => {
5180
+ const next = !prev;
5181
+ try {
5182
+ localStorage.setItem("portfolioBarVisible", String(next));
5183
+ } catch {
5184
+ }
5185
+ return next;
5186
+ });
5187
+ }, []);
5188
+ const updatePortfolioArrow = React5.useCallback(() => {
5189
+ const eye = document.getElementById("portfolio-eye-toggle");
5190
+ const pill = portfolioPillRef.current;
5191
+ if (!eye || !pill) return;
5192
+ const eyeRect = eye.getBoundingClientRect();
5193
+ const pillRect = pill.getBoundingClientRect();
5194
+ const offset = eyeRect.left + eyeRect.width / 2 - pillRect.left - 7;
5195
+ setPortfolioArrowLeft(offset);
5196
+ }, []);
5197
+ React5.useEffect(() => {
5198
+ if (!isPortfolioBarVisible || !portfolioSummary) return;
5199
+ updatePortfolioArrow();
5200
+ window.addEventListener("resize", updatePortfolioArrow);
5201
+ return () => window.removeEventListener("resize", updatePortfolioArrow);
5202
+ }, [isPortfolioBarVisible, portfolioSummary, updatePortfolioArrow]);
5105
5203
  React5.useEffect(() => {
5106
5204
  if (typeof window === "undefined") return;
5107
5205
  const ua = navigator.userAgent;
@@ -5479,6 +5577,17 @@ var Header = ({
5479
5577
  }
5480
5578
  ),
5481
5579
  isAuthenticated ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [
5580
+ portfolioSummary && /* @__PURE__ */ jsxRuntime.jsx(
5581
+ PortfolioEyeButton,
5582
+ {
5583
+ id: "portfolio-eye-toggle",
5584
+ type: "button",
5585
+ onClick: togglePortfolioBar,
5586
+ $active: isPortfolioBarVisible,
5587
+ title: isPortfolioBarVisible ? "Hide portfolio" : "Show portfolio",
5588
+ children: isPortfolioBarVisible ? /* @__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: "M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" }) }) : /* @__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: "M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46A11.804 11.804 0 001 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z" }) })
5589
+ }
5590
+ ),
5482
5591
  /* @__PURE__ */ jsxRuntime.jsxs(UserMenu, { children: [
5483
5592
  /* @__PURE__ */ jsxRuntime.jsxs(
5484
5593
  UserButton,
@@ -5550,6 +5659,51 @@ var Header = ({
5550
5659
  ] })
5551
5660
  ] }),
5552
5661
  /* @__PURE__ */ jsxRuntime.jsx(HeaderSpacer, {}),
5662
+ isAuthenticated && portfolioSummary && isPortfolioBarVisible && (() => {
5663
+ const fmt = (n) => n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
5664
+ const isPLPositive = portfolioSummary.pnl >= 0;
5665
+ return /* @__PURE__ */ jsxRuntime.jsx(PortfolioBarContainer, { children: /* @__PURE__ */ jsxRuntime.jsxs(PortfolioBarPill, { ref: portfolioPillRef, children: [
5666
+ portfolioArrowLeft !== null && /* @__PURE__ */ jsxRuntime.jsx(PortfolioBarArrow, { style: { left: `${portfolioArrowLeft}px` } }),
5667
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetric, { children: [
5668
+ /* @__PURE__ */ jsxRuntime.jsx(PBMetricLabel, { children: "Holdings" }),
5669
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetricValue, { children: [
5670
+ "$",
5671
+ fmt(portfolioSummary.holdings)
5672
+ ] })
5673
+ ] }),
5674
+ /* @__PURE__ */ jsxRuntime.jsx(PBOperator, { children: "+" }),
5675
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetric, { children: [
5676
+ /* @__PURE__ */ jsxRuntime.jsx(PBMetricLabel, { children: "Cash" }),
5677
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetricValue, { children: [
5678
+ "$",
5679
+ fmt(portfolioSummary.cash)
5680
+ ] })
5681
+ ] }),
5682
+ /* @__PURE__ */ jsxRuntime.jsx(PBOperator, { children: "=" }),
5683
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetric, { children: [
5684
+ /* @__PURE__ */ jsxRuntime.jsx(PBMetricLabel, { children: "Portfolio" }),
5685
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetricValue, { style: { color: "#D4AF37", fontWeight: 700 }, children: [
5686
+ "$",
5687
+ fmt(portfolioSummary.portfolioValue)
5688
+ ] })
5689
+ ] }),
5690
+ /* @__PURE__ */ jsxRuntime.jsx(PBDot, {}),
5691
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetric, { children: [
5692
+ /* @__PURE__ */ jsxRuntime.jsx(PBMetricLabel, { children: "P&L" }),
5693
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetricValue, { $positive: isPLPositive, $negative: !isPLPositive, children: [
5694
+ isPLPositive ? "+" : "",
5695
+ "$",
5696
+ fmt(Math.abs(portfolioSummary.pnl)),
5697
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "0.6rem", marginLeft: "2px", opacity: 0.7 }, children: [
5698
+ "(",
5699
+ isPLPositive ? "+" : "",
5700
+ portfolioSummary.pnlPercent.toFixed(2),
5701
+ "%)"
5702
+ ] })
5703
+ ] })
5704
+ ] })
5705
+ ] }) });
5706
+ })(),
5553
5707
  LoginPopupComponent && showLoginPopup && /* @__PURE__ */ jsxRuntime.jsx(
5554
5708
  LoginPopupComponent,
5555
5709
  {
@@ -5635,8 +5789,19 @@ var HeaderContainer = styled25__default.default.header`
5635
5789
  box-sizing: border-box;
5636
5790
 
5637
5791
  @media (max-width: 768px) {
5638
- padding: 0 1rem;
5639
- padding-top: max(env(safe-area-inset-top, 0px), var(--telegram-safe-top, 0px));
5792
+ top: 0.5rem;
5793
+ left: 0.75rem;
5794
+ right: 0.75rem;
5795
+ width: calc(100% - 1.5rem);
5796
+ height: 46px;
5797
+ min-height: 46px;
5798
+ padding: 0 0.75rem;
5799
+ border-radius: 12px;
5800
+ background-color: rgba(13, 17, 23, 0.92);
5801
+ backdrop-filter: blur(12px);
5802
+ border: 1px solid rgba(255, 255, 255, 0.08);
5803
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08);
5804
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
5640
5805
  }
5641
5806
  `;
5642
5807
  var HeaderSpacer = styled25__default.default.div`
@@ -5644,6 +5809,10 @@ var HeaderSpacer = styled25__default.default.div`
5644
5809
  min-height: 56px;
5645
5810
  min-height: calc(56px + max(env(safe-area-inset-top, 0px), var(--telegram-safe-top, 0px)));
5646
5811
  flex-shrink: 0;
5812
+
5813
+ @media (max-width: 768px) {
5814
+ min-height: calc(46px + 0.5rem);
5815
+ }
5647
5816
  `;
5648
5817
  var Logo = styled25__default.default.div`
5649
5818
  display: flex;
@@ -5977,6 +6146,151 @@ var MobileNavItem = styled25__default.default.div`
5977
6146
  padding-left: 24px;
5978
6147
  }
5979
6148
  `;
6149
+ var pbShimmer = styled25.keyframes`
6150
+ 0% { background-position: -200% 0; }
6151
+ 100% { background-position: 200% 0; }
6152
+ `;
6153
+ var PortfolioEyeButton = styled25__default.default.button`
6154
+ background: ${(p) => p.$active ? "rgba(212, 175, 55, 0.15)" : "transparent"};
6155
+ border: none;
6156
+ border-radius: 6px;
6157
+ cursor: pointer;
6158
+ padding: 6px;
6159
+ display: flex;
6160
+ align-items: center;
6161
+ justify-content: center;
6162
+ color: ${(p) => p.$active ? "#D4AF37" : "rgba(255,255,255,0.5)"};
6163
+ transition: all 0.2s ease;
6164
+ margin-right: 4px;
6165
+
6166
+ &:hover {
6167
+ background: rgba(212, 175, 55, 0.2);
6168
+ color: #D4AF37;
6169
+ }
6170
+
6171
+ @media (max-width: 768px) {
6172
+ padding: 4px;
6173
+ margin-right: 2px;
6174
+ }
6175
+ `;
6176
+ var PortfolioBarContainer = styled25__default.default.div`
6177
+ position: fixed;
6178
+ top: 56px;
6179
+ top: calc(56px + max(env(safe-area-inset-top, 0px), var(--telegram-safe-top, 0px)));
6180
+ left: 0;
6181
+ right: 0;
6182
+ z-index: 999;
6183
+ display: flex;
6184
+ justify-content: flex-end;
6185
+ align-items: flex-start;
6186
+ padding: 0 5%;
6187
+ pointer-events: none;
6188
+ overflow: visible;
6189
+
6190
+ &::before {
6191
+ content: '';
6192
+ position: absolute;
6193
+ top: 0;
6194
+ left: 40%;
6195
+ right: 0;
6196
+ height: 2px;
6197
+ background: linear-gradient(90deg, transparent 0%, rgba(212, 175, 55, 0.25) 100%);
6198
+ pointer-events: none;
6199
+ }
6200
+
6201
+ @media (max-width: 768px) {
6202
+ top: calc(46px + 0.5rem);
6203
+ padding: 0 0.75rem;
6204
+ justify-content: center;
6205
+
6206
+ &::before {
6207
+ left: 0;
6208
+ right: 0;
6209
+ background: linear-gradient(90deg, transparent 0%, rgba(212, 175, 55, 0.4) 30%, rgba(212, 175, 55, 0.4) 70%, transparent 100%);
6210
+ }
6211
+ }
6212
+ `;
6213
+ var PortfolioBarPill = styled25__default.default.div`
6214
+ pointer-events: auto;
6215
+ display: flex;
6216
+ align-items: center;
6217
+ gap: 1.25rem;
6218
+ padding: 0.5rem 1.5rem;
6219
+ border-radius: 0 0 20px 20px;
6220
+ background: linear-gradient(135deg, rgba(24, 26, 34, 0.98) 0%, rgba(32, 34, 42, 0.97) 100%);
6221
+ backdrop-filter: blur(16px);
6222
+ border: 1px solid rgba(212, 175, 55, 0.25);
6223
+ border-top: none;
6224
+ box-shadow:
6225
+ 0 4px 16px rgba(0, 0, 0, 0.3),
6226
+ 0 0 0 1px rgba(255, 255, 255, 0.03) inset,
6227
+ 0 1px 0 rgba(212, 175, 55, 0.06) inset;
6228
+ position: relative;
6229
+ overflow: visible;
6230
+
6231
+ &::before {
6232
+ content: '';
6233
+ position: absolute;
6234
+ top: 0;
6235
+ left: 0;
6236
+ right: 0;
6237
+ height: 1px;
6238
+ background: linear-gradient(90deg, transparent, rgba(212, 175, 55, 0.3), transparent);
6239
+ background-size: 200% 100%;
6240
+ animation: ${pbShimmer} 4s linear infinite;
6241
+ }
6242
+
6243
+ @media (max-width: 768px) {
6244
+ gap: 0.75rem;
6245
+ padding: 0.4rem 1rem;
6246
+ border-radius: 0 0 16px 16px;
6247
+ }
6248
+ `;
6249
+ var PortfolioBarArrow = styled25__default.default.div`
6250
+ position: absolute;
6251
+ top: -7px;
6252
+ width: 14px;
6253
+ height: 14px;
6254
+ background: linear-gradient(135deg, rgba(26, 28, 36, 1) 0%, rgba(30, 32, 40, 1) 100%);
6255
+ border-left: 1px solid rgba(212, 175, 55, 0.3);
6256
+ border-top: 1px solid rgba(212, 175, 55, 0.3);
6257
+ transform: rotate(45deg);
6258
+ box-shadow: -2px -2px 6px rgba(0, 0, 0, 0.25);
6259
+ pointer-events: none;
6260
+ `;
6261
+ var PBMetric = styled25__default.default.div`
6262
+ display: flex;
6263
+ flex-direction: column;
6264
+ align-items: center;
6265
+ gap: 1px;
6266
+ white-space: nowrap;
6267
+ `;
6268
+ var PBMetricLabel = styled25__default.default.span`
6269
+ font-size: 0.55rem;
6270
+ color: rgba(255, 255, 255, 0.6);
6271
+ text-transform: uppercase;
6272
+ letter-spacing: 0.5px;
6273
+ font-weight: 500;
6274
+ `;
6275
+ var PBMetricValue = styled25__default.default.span`
6276
+ font-size: 0.75rem;
6277
+ font-weight: 600;
6278
+ color: ${(p) => p.$positive ? "#0ecb81" : p.$negative ? "#f6465d" : "#eaecef"};
6279
+ font-variant-numeric: tabular-nums;
6280
+ `;
6281
+ var PBDot = styled25__default.default.div`
6282
+ width: 3px;
6283
+ height: 3px;
6284
+ border-radius: 50%;
6285
+ background: rgba(212, 175, 55, 0.25);
6286
+ flex-shrink: 0;
6287
+ `;
6288
+ var PBOperator = styled25__default.default.span`
6289
+ font-size: 0.7rem;
6290
+ font-weight: 500;
6291
+ color: rgba(255, 255, 255, 0.35);
6292
+ flex-shrink: 0;
6293
+ `;
5980
6294
  var PropertySubheader = React5__namespace.forwardRef(
5981
6295
  ({ className, tabs, activeTabId, onTabChange, actions, ...props }, ref) => {
5982
6296
  const tabsContainerRef = React5__namespace.useRef(null);
@@ -6102,191 +6416,6 @@ var PropertySubheader = React5__namespace.forwardRef(
6102
6416
  }
6103
6417
  );
6104
6418
  PropertySubheader.displayName = "PropertySubheader";
6105
- var slideIn = styled25.keyframes`
6106
- from { transform: translateX(110%); opacity: 0; }
6107
- to { transform: translateX(0); opacity: 1; }
6108
- `;
6109
- var slideOut = styled25.keyframes`
6110
- from { transform: translateX(0); opacity: 1; }
6111
- to { transform: translateX(110%); opacity: 0; }
6112
- `;
6113
- var progressShrink = styled25.keyframes`
6114
- from { width: 100%; }
6115
- to { width: 0%; }
6116
- `;
6117
- var VARIANT_COLORS = {
6118
- success: { accent: "#0ecb81", icon: "\u2713" },
6119
- error: { accent: "#f6465d", icon: "\u2715" },
6120
- info: { accent: "#E6C656", icon: "\u2139" },
6121
- pending: { accent: "#7EB3E6", icon: "\u25CC" }
6122
- };
6123
- var Wrapper = styled25__default.default.div`
6124
- position: relative;
6125
- display: flex;
6126
- flex-direction: column;
6127
- gap: 0;
6128
- width: 340px;
6129
- background: #0d0f1a;
6130
- border: 1px solid rgba(255, 255, 255, 0.08);
6131
- border-radius: 10px;
6132
- overflow: hidden;
6133
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255,255,255,0.04);
6134
- animation: ${({ $exiting }) => $exiting ? styled25.css`${slideOut} 0.28s cubic-bezier(0.4,0,1,1) forwards` : styled25.css`${slideIn} 0.32s cubic-bezier(0,0,0.2,1) forwards`};
6135
- pointer-events: all;
6136
- `;
6137
- var Body = styled25__default.default.div`
6138
- display: flex;
6139
- align-items: flex-start;
6140
- gap: 12px;
6141
- padding: 14px 16px 12px;
6142
- `;
6143
- var IconDot = styled25__default.default.div`
6144
- flex-shrink: 0;
6145
- width: 28px;
6146
- height: 28px;
6147
- border-radius: 50%;
6148
- background: ${({ $color }) => $color}1a;
6149
- border: 1px solid ${({ $color }) => $color}55;
6150
- display: flex;
6151
- align-items: center;
6152
- justify-content: center;
6153
- font-size: 0.75rem;
6154
- font-weight: 700;
6155
- color: ${({ $color }) => $color};
6156
- margin-top: 1px;
6157
- `;
6158
- var Content = styled25__default.default.div`
6159
- flex: 1;
6160
- min-width: 0;
6161
- `;
6162
- var Title = styled25__default.default.p`
6163
- margin: 0 0 2px;
6164
- font-size: 0.8rem;
6165
- font-weight: 600;
6166
- color: #fff;
6167
- letter-spacing: 0.01em;
6168
- `;
6169
- var Amount = styled25__default.default.p`
6170
- margin: 0 0 6px;
6171
- font-size: 1.05rem;
6172
- font-weight: 700;
6173
- color: #E6C656;
6174
- letter-spacing: -0.01em;
6175
- `;
6176
- var TxRow = styled25__default.default.a`
6177
- display: inline-flex;
6178
- align-items: center;
6179
- gap: 5px;
6180
- font-family: 'IBM Plex Mono', 'Space Mono', monospace;
6181
- font-size: 0.68rem;
6182
- color: rgba(255, 255, 255, 0.4);
6183
- text-decoration: none;
6184
- transition: color 0.15s;
6185
- &:hover {
6186
- color: #7EB3E6;
6187
- }
6188
- `;
6189
- var TxArrow = styled25__default.default.span`
6190
- font-size: 0.6rem;
6191
- opacity: 0.6;
6192
- `;
6193
- var CloseBtn = styled25__default.default.button`
6194
- flex-shrink: 0;
6195
- background: none;
6196
- border: none;
6197
- padding: 2px 4px;
6198
- cursor: pointer;
6199
- color: rgba(255, 255, 255, 0.25);
6200
- font-size: 0.9rem;
6201
- line-height: 1;
6202
- transition: color 0.15s;
6203
- &:hover { color: rgba(255, 255, 255, 0.7); }
6204
- `;
6205
- var ProgressBar = styled25__default.default.div`
6206
- height: 2px;
6207
- background: rgba(255, 255, 255, 0.06);
6208
- position: relative;
6209
- &::after {
6210
- content: '';
6211
- position: absolute;
6212
- left: 0;
6213
- top: 0;
6214
- height: 100%;
6215
- background: ${({ $color }) => $color};
6216
- animation: ${styled25.css`${progressShrink} ${({ $duration }) => $duration}ms linear forwards`};
6217
- }
6218
- `;
6219
- var Container = styled25__default.default.div`
6220
- position: fixed;
6221
- bottom: 24px;
6222
- right: 24px;
6223
- z-index: 9999;
6224
- display: flex;
6225
- flex-direction: column-reverse;
6226
- gap: 10px;
6227
- pointer-events: none;
6228
- `;
6229
- var DEFAULT_EXPLORER = "https://sepolia.basescan.org/tx/";
6230
- function truncateHash(hash) {
6231
- return `${hash.slice(0, 6)}\u2026${hash.slice(-4)}`;
6232
- }
6233
- function ToastItem({ toast, onDismiss }) {
6234
- const [exiting, setExiting] = React5.useState(false);
6235
- const timerRef = React5.useRef(null);
6236
- const dismiss = React5.useCallback(() => {
6237
- setExiting(true);
6238
- setTimeout(() => onDismiss(toast.id), 280);
6239
- }, [onDismiss, toast.id]);
6240
- React5.useEffect(() => {
6241
- const duration2 = toast.duration ?? 6e3;
6242
- if (duration2 > 0) {
6243
- timerRef.current = setTimeout(dismiss, duration2);
6244
- }
6245
- return () => {
6246
- if (timerRef.current) clearTimeout(timerRef.current);
6247
- };
6248
- }, [dismiss, toast.duration]);
6249
- const { accent, icon } = VARIANT_COLORS[toast.variant];
6250
- const duration = toast.duration ?? 6e3;
6251
- const explorerBase = toast.explorerUrl ?? DEFAULT_EXPLORER;
6252
- const txUrl = toast.txHash ? `${explorerBase}${toast.txHash}` : void 0;
6253
- return /* @__PURE__ */ jsxRuntime.jsxs(Wrapper, { $exiting: exiting, children: [
6254
- /* @__PURE__ */ jsxRuntime.jsxs(Body, { children: [
6255
- /* @__PURE__ */ jsxRuntime.jsx(IconDot, { $color: accent, children: icon }),
6256
- /* @__PURE__ */ jsxRuntime.jsxs(Content, { children: [
6257
- /* @__PURE__ */ jsxRuntime.jsx(Title, { children: toast.title }),
6258
- toast.amount && /* @__PURE__ */ jsxRuntime.jsx(Amount, { children: toast.amount }),
6259
- toast.txHash && txUrl && /* @__PURE__ */ jsxRuntime.jsxs(TxRow, { href: txUrl, target: "_blank", rel: "noopener noreferrer", children: [
6260
- truncateHash(toast.txHash),
6261
- /* @__PURE__ */ jsxRuntime.jsx(TxArrow, { children: "\u2197" })
6262
- ] })
6263
- ] }),
6264
- /* @__PURE__ */ jsxRuntime.jsx(CloseBtn, { type: "button", onClick: dismiss, "aria-label": "Dismiss", children: "\u2715" })
6265
- ] }),
6266
- duration > 0 && /* @__PURE__ */ jsxRuntime.jsx(ProgressBar, { $color: accent, $duration: duration })
6267
- ] });
6268
- }
6269
- var ToastContext = React5.createContext(null);
6270
- function ToastProvider({ children }) {
6271
- const [toasts, setToasts] = React5.useState([]);
6272
- const addToast = React5.useCallback((data) => {
6273
- const id = `toast-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
6274
- setToasts((prev) => [...prev, { ...data, id }]);
6275
- return id;
6276
- }, []);
6277
- const dismiss = React5.useCallback((id) => {
6278
- setToasts((prev) => prev.filter((t) => t.id !== id));
6279
- }, []);
6280
- return /* @__PURE__ */ jsxRuntime.jsxs(ToastContext.Provider, { value: { toast: addToast, dismiss }, children: [
6281
- children,
6282
- /* @__PURE__ */ jsxRuntime.jsx(Container, { children: toasts.map((t) => /* @__PURE__ */ jsxRuntime.jsx(ToastItem, { toast: t, onDismiss: dismiss }, t.id)) })
6283
- ] });
6284
- }
6285
- function useToast() {
6286
- const ctx = React5.useContext(ToastContext);
6287
- if (!ctx) throw new Error("useToast must be used within a ToastProvider");
6288
- return ctx;
6289
- }
6290
6419
  var DEFAULT_LOGO_SRC = Loaf_logo_Banner_default;
6291
6420
  var DEFAULT_LOGO_ALT = "Loaf";
6292
6421
  var OTP_INPUT_LENGTH = 6;
@@ -6314,7 +6443,6 @@ var LoginPopup = ({
6314
6443
  const [error, setError] = React5.useState("");
6315
6444
  const [loading, setLoading] = React5.useState(false);
6316
6445
  const [isSignUp, setIsSignUp] = React5.useState(false);
6317
- const { toast } = useToast();
6318
6446
  const [fundingAmount] = React5.useState("");
6319
6447
  const [kycLoading, setKycLoading] = React5.useState(false);
6320
6448
  const [showKycWidget, setShowKycWidget] = React5.useState(false);
@@ -6328,11 +6456,6 @@ var LoginPopup = ({
6328
6456
  setView(initialView);
6329
6457
  }
6330
6458
  }, [initialView]);
6331
- React5.useEffect(() => {
6332
- if (view === "kyc" && renderKycWidget) {
6333
- setShowKycWidget(true);
6334
- }
6335
- }, [view, renderKycWidget]);
6336
6459
  React5.useEffect(() => {
6337
6460
  if (!transakWidgetUrl) return;
6338
6461
  const handleTransakMessage = (event) => {
@@ -6535,19 +6658,10 @@ var LoginPopup = ({
6535
6658
  };
6536
6659
  const handleKycWidgetResult = (result) => {
6537
6660
  setShowKycWidget(false);
6538
- onClose();
6539
6661
  if (result.passed) {
6540
- toast({
6541
- variant: "success",
6542
- title: "KYC submitted \u2014 pending review",
6543
- amount: "Your documents are under review. Please check back in a few minutes."
6544
- });
6662
+ setView("kyc-success");
6545
6663
  } else {
6546
- toast({
6547
- variant: "error",
6548
- title: "Verification unsuccessful",
6549
- amount: "Your identity check didn't pass. Please contact support if you believe this is an error."
6550
- });
6664
+ setView("kyc-failed");
6551
6665
  }
6552
6666
  };
6553
6667
  const handleKycWidgetClose = () => {
@@ -6638,7 +6752,7 @@ var LoginPopup = ({
6638
6752
  if (view === "main") {
6639
6753
  return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
6640
6754
  /* @__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" }) }) }),
6641
- /* @__PURE__ */ jsxRuntime.jsxs(Title2, { children: [
6755
+ /* @__PURE__ */ jsxRuntime.jsxs(Title, { children: [
6642
6756
  /* @__PURE__ */ jsxRuntime.jsx(LogoContainer3, { children: /* @__PURE__ */ jsxRuntime.jsx(LogoImage, { src: logoSrc, alt: logoAlt }) }),
6643
6757
  "Welcome to Loaf"
6644
6758
  ] }),
@@ -6699,7 +6813,7 @@ var LoginPopup = ({
6699
6813
  /* @__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" }) }),
6700
6814
  "Back"
6701
6815
  ] }),
6702
- /* @__PURE__ */ jsxRuntime.jsxs(Title2, { children: [
6816
+ /* @__PURE__ */ jsxRuntime.jsxs(Title, { children: [
6703
6817
  /* @__PURE__ */ jsxRuntime.jsx(LogoContainer3, { children: /* @__PURE__ */ jsxRuntime.jsx(LogoImage, { src: logoSrc, alt: logoAlt }) }),
6704
6818
  isSignUp ? "Sign up with Email" : "Sign in with Email"
6705
6819
  ] }),
@@ -6738,7 +6852,7 @@ var LoginPopup = ({
6738
6852
  /* @__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" }) }),
6739
6853
  "Back"
6740
6854
  ] }),
6741
- /* @__PURE__ */ jsxRuntime.jsxs(Title2, { children: [
6855
+ /* @__PURE__ */ jsxRuntime.jsxs(Title, { children: [
6742
6856
  /* @__PURE__ */ jsxRuntime.jsx(LogoContainer3, { children: /* @__PURE__ */ jsxRuntime.jsx(LogoImage, { src: logoSrc, alt: logoAlt }) }),
6743
6857
  "Enter Verification Code"
6744
6858
  ] }),
@@ -6854,7 +6968,7 @@ var LoginPopup = ({
6854
6968
  ] }) });
6855
6969
  }
6856
6970
  if (view === "funding") {
6857
- return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(
6971
+ return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { children: /* @__PURE__ */ jsxRuntime.jsxs(
6858
6972
  FundingPopupContainer,
6859
6973
  {
6860
6974
  onClick: (event) => event.stopPropagation(),
@@ -6924,6 +7038,16 @@ var Overlay2 = styled25__default.default.div`
6924
7038
  justify-content: center;
6925
7039
  align-items: center;
6926
7040
  z-index: 10000;
7041
+ animation: fadeIn 0.2s ease-in-out;
7042
+
7043
+ @keyframes fadeIn {
7044
+ from {
7045
+ opacity: 0;
7046
+ }
7047
+ to {
7048
+ opacity: 1;
7049
+ }
7050
+ }
6927
7051
  `;
6928
7052
  var PopupContainer = styled25__default.default.div`
6929
7053
  background-color: var(--color-background, #0a0a0a);
@@ -6933,8 +7057,20 @@ var PopupContainer = styled25__default.default.div`
6933
7057
  max-width: 440px;
6934
7058
  width: 90%;
6935
7059
  position: relative;
7060
+ animation: slideUp 0.3s ease-out;
6936
7061
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
6937
7062
 
7063
+ @keyframes slideUp {
7064
+ from {
7065
+ transform: translateY(20px);
7066
+ opacity: 0;
7067
+ }
7068
+ to {
7069
+ transform: translateY(0);
7070
+ opacity: 1;
7071
+ }
7072
+ }
7073
+
6938
7074
  @media (max-width: 768px) {
6939
7075
  padding: 2rem;
6940
7076
  max-width: 90%;
@@ -6948,9 +7084,21 @@ var KycPopupContainer = styled25__default.default.div`
6948
7084
  max-width: ${(props) => props.$expanded ? "680px" : "440px"};
6949
7085
  width: 90%;
6950
7086
  position: relative;
7087
+ animation: slideUp 0.3s ease-out;
6951
7088
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
6952
7089
  transition: max-width 0.3s ease;
6953
7090
 
7091
+ @keyframes slideUp {
7092
+ from {
7093
+ transform: translateY(20px);
7094
+ opacity: 0;
7095
+ }
7096
+ to {
7097
+ transform: translateY(0);
7098
+ opacity: 1;
7099
+ }
7100
+ }
7101
+
6954
7102
  @media (max-width: 768px) {
6955
7103
  padding: 1.5rem;
6956
7104
  max-width: 95%;
@@ -7009,7 +7157,7 @@ var CloseButton = styled25__default.default.button`
7009
7157
  color: var(--color-accent, #e6c656);
7010
7158
  }
7011
7159
  `;
7012
- var Title2 = styled25__default.default.h2`
7160
+ var Title = styled25__default.default.h2`
7013
7161
  font-size: 1.75rem;
7014
7162
  font-weight: 600;
7015
7163
  color: var(--color-text, #eaecef);
@@ -7278,9 +7426,21 @@ var FundingPopupContainer = styled25__default.default.div`
7278
7426
  max-width: ${(props) => props.$hasWidget ? "900px" : "440px"};
7279
7427
  width: 90%;
7280
7428
  position: relative;
7429
+ animation: slideUp 0.3s ease-out;
7281
7430
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
7282
7431
  overflow: hidden;
7283
7432
 
7433
+ @keyframes slideUp {
7434
+ from {
7435
+ transform: translateY(20px);
7436
+ opacity: 0;
7437
+ }
7438
+ to {
7439
+ transform: translateY(0);
7440
+ opacity: 1;
7441
+ }
7442
+ }
7443
+
7284
7444
  @media (max-width: 768px) {
7285
7445
  padding: ${(props) => props.$hasWidget ? "0" : "2rem"};
7286
7446
  max-width: 95%;
@@ -7569,7 +7729,7 @@ var PropertyCompareBar = React5__namespace.forwardRef(
7569
7729
  void 0,
7570
7730
  pricePercentFormat
7571
7731
  )}%`;
7572
- const priceContent = formattedPriceValue && propertyValueVariant === "pill" ? /* @__PURE__ */ jsxRuntime.jsxs(PriceBlock2, { $variant: propertyValueVariant, children: [
7732
+ const priceContent = formattedPriceValue && propertyValueVariant === "pill" ? /* @__PURE__ */ jsxRuntime.jsxs(PriceBlock, { $variant: propertyValueVariant, children: [
7573
7733
  /* @__PURE__ */ jsxRuntime.jsx(PriceAmount, { children: formattedPriceValue }),
7574
7734
  formattedPriceChange || formattedPricePercent ? /* @__PURE__ */ jsxRuntime.jsxs(
7575
7735
  PriceChange,
@@ -7882,7 +8042,7 @@ var PropertyValueChange = styled25__default.default.span`
7882
8042
  font-size: 0.65rem;
7883
8043
  }
7884
8044
  `;
7885
- var PriceBlock2 = styled25__default.default.div`
8045
+ var PriceBlock = styled25__default.default.div`
7886
8046
  display: none;
7887
8047
 
7888
8048
  ${({ $variant }) => $variant === "pill" && styled25.css`
@@ -7976,7 +8136,7 @@ function GalleryMapSection({
7976
8136
  /* @__PURE__ */ jsxRuntime.jsxs(ThumbStrip, { children: [
7977
8137
  /* @__PURE__ */ jsxRuntime.jsx(ThumbScroll, { children: images.filter((img) => img.category !== "Floorplan").map((img) => {
7978
8138
  const actualIndex = images.indexOf(img);
7979
- return /* @__PURE__ */ jsxRuntime.jsx(Thumbnail, { "data-active": !showVideo && carouselIndex === actualIndex, onClick: () => {
8139
+ return /* @__PURE__ */ jsxRuntime.jsx(Thumbnail2, { "data-active": !showVideo && carouselIndex === actualIndex, onClick: () => {
7980
8140
  stopAutoPlay();
7981
8141
  setShowVideo(false);
7982
8142
  setCarouselIndex(actualIndex);
@@ -8116,7 +8276,7 @@ var ThumbScroll = styled25__default.default.div`
8116
8276
  scrollbar-width: none;
8117
8277
  &::-webkit-scrollbar { display: none; }
8118
8278
  `;
8119
- var Thumbnail = styled25__default.default.div`
8279
+ var Thumbnail2 = styled25__default.default.div`
8120
8280
  min-width: 60px; height: 45px; border-radius: 4px; overflow: hidden;
8121
8281
  cursor: pointer; border: 2px solid transparent; opacity: 0.6;
8122
8282
  transition: all 0.2s ease; flex-shrink: 0;
@@ -8647,7 +8807,7 @@ function PropertyHistory() {
8647
8807
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.9rem] font-normal ml-3 opacity-80", children: loafListing.date.replace(/\d+,\s|\s\d+$/, "") })
8648
8808
  ] }) }),
8649
8809
  /* @__PURE__ */ jsxRuntime.jsx(SalesTable, { children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: /* @__PURE__ */ jsxRuntime.jsxs(HistoryRow, { $isOwnershipStart: true, children: [
8650
- /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(TypeBadge, { $type: loafListing.type, children: loafListing.type === "Sale" ? "Sold" : loafListing.type }) }),
8810
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(TypeBadge2, { $type: loafListing.type, children: loafListing.type === "Sale" ? "Sold" : loafListing.type }) }),
8651
8811
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: loafListing.saleType ?? "-" }),
8652
8812
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: loafListing.agent })
8653
8813
  ] }) }) }),
@@ -8709,7 +8869,7 @@ function PropertyHistory() {
8709
8869
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.9rem] font-normal ml-3 opacity-80", children: ownershipSale.date.replace(/\d+,\s|\s\d+$/, "") })
8710
8870
  ] }) }),
8711
8871
  ownershipSale && (historyFilter === "all" || historyFilter === "sales") && /* @__PURE__ */ jsxRuntime.jsx(SalesTable, { children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: /* @__PURE__ */ jsxRuntime.jsxs(HistoryRow, { $isOwnershipStart: true, children: [
8712
- /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(TypeBadge, { $type: ownershipSale.type, children: ownershipSale.type === "Sale" ? "Sold" : ownershipSale.type }) }),
8872
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(TypeBadge2, { $type: ownershipSale.type, children: ownershipSale.type === "Sale" ? "Sold" : ownershipSale.type }) }),
8713
8873
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: ownershipSale.saleType ?? "-" }),
8714
8874
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: ownershipSale.agent })
8715
8875
  ] }) }) }),
@@ -8718,7 +8878,7 @@ function PropertyHistory() {
8718
8878
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2", children: events.map((event) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsx(EventDetails, { event }) }, event.id)) })
8719
8879
  ] }),
8720
8880
  otherSales.length > 0 && (historyFilter === "all" || historyFilter === "sales") && /* @__PURE__ */ jsxRuntime.jsx(SalesTable, { children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: otherSales.map((sale) => /* @__PURE__ */ jsxRuntime.jsxs(HistoryRow, { children: [
8721
- /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(TypeBadge, { $type: sale.type, children: sale.type === "Sale" ? "Sold" : sale.type }) }),
8881
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(TypeBadge2, { $type: sale.type, children: sale.type === "Sale" ? "Sold" : sale.type }) }),
8722
8882
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: sale.saleType ?? "-" }),
8723
8883
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: sale.agent })
8724
8884
  ] }, sale.id)) }) })
@@ -8861,7 +9021,7 @@ function EventDetails({ event }) {
8861
9021
  onClick: toggleExpand,
8862
9022
  children: [
8863
9023
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-between items-center flex-1 gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
8864
- /* @__PURE__ */ jsxRuntime.jsx(TypeBadge, { $type: event.type, children: event.type === "Sale" ? "Sold" : event.type }),
9024
+ /* @__PURE__ */ jsxRuntime.jsx(TypeBadge2, { $type: event.type, children: event.type === "Sale" ? "Sold" : event.type }),
8865
9025
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2", children: event.date })
8866
9026
  ] }) }),
8867
9027
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center text-[var(--color-text-secondary)] w-6 h-6 rounded-full transition-colors duration-200 hover:bg-white/10", children: expanded ? /* @__PURE__ */ jsxRuntime.jsx(bi.BiChevronUp, { size: 20 }) : /* @__PURE__ */ jsxRuntime.jsx(bi.BiChevronDown, { size: 20 }) })
@@ -9105,7 +9265,7 @@ var HistoryRow = styled25__default.default.tr`
9105
9265
  background-color: rgba(255, 255, 255, 0.08);
9106
9266
  }
9107
9267
  `;
9108
- var TypeBadge = styled25__default.default.span`
9268
+ var TypeBadge2 = styled25__default.default.span`
9109
9269
  display: inline-block;
9110
9270
  padding: 0.25rem 0.5rem;
9111
9271
  border-radius: 4px;
@@ -9515,7 +9675,9 @@ function AssetSelectorBar({
9515
9675
  metrics: metricsProp,
9516
9676
  currentTokenName,
9517
9677
  selectorItems,
9518
- onSelect
9678
+ onSelect,
9679
+ trailing,
9680
+ imageUrl
9519
9681
  }) {
9520
9682
  const [isDropdownOpen, setIsDropdownOpen] = React5.useState(false);
9521
9683
  const hasItems = selectorItems && selectorItems.length > 0;
@@ -9524,6 +9686,7 @@ function AssetSelectorBar({
9524
9686
  ...offeringValuation != null ? [{ label: "Offering Valuation", value: `$${offeringValuation.toLocaleString()}` }] : []
9525
9687
  ];
9526
9688
  return /* @__PURE__ */ jsxRuntime.jsx(AssetSelectorWrapper, { children: /* @__PURE__ */ jsxRuntime.jsxs(IPOAssetSelector, { children: [
9689
+ imageUrl && /* @__PURE__ */ jsxRuntime.jsx(AssetThumbnail, { src: imageUrl, alt: propertyName }),
9527
9690
  /* @__PURE__ */ jsxRuntime.jsx(AssetSelectorDropdown, { onClick: () => hasItems && setIsDropdownOpen((prev) => !prev), children: /* @__PURE__ */ jsxRuntime.jsxs(AssetName, { children: [
9528
9691
  propertyName,
9529
9692
  hasItems && /* @__PURE__ */ jsxRuntime.jsx(
@@ -9544,7 +9707,7 @@ function AssetSelectorBar({
9544
9707
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
9545
9708
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9546
9709
  /* @__PURE__ */ jsxRuntime.jsx(MetricLabel2, { children: m.label }),
9547
- /* @__PURE__ */ jsxRuntime.jsx(MetricValue, { $accent: !!m.accent, children: m.value })
9710
+ /* @__PURE__ */ jsxRuntime.jsx(MetricValue, { $accent: !!m.accent, $secondary: !!m.secondary, children: m.value })
9548
9711
  ] }),
9549
9712
  m.change != null && /* @__PURE__ */ jsxRuntime.jsxs(MetricChange, { $positive: m.change >= 0, children: [
9550
9713
  m.change >= 0 ? "\u2191" : "\u2193",
@@ -9553,11 +9716,12 @@ function AssetSelectorBar({
9553
9716
  ] })
9554
9717
  ] })
9555
9718
  ] }, m.label)) }),
9719
+ trailing,
9556
9720
  isDropdownOpen && hasItems && /* @__PURE__ */ jsxRuntime.jsx(IPODropdown, { children: selectorItems.map((item) => {
9557
9721
  const isCurrent = item.tokenName === currentTokenName;
9558
9722
  const status = item.status?.toUpperCase();
9559
9723
  const statusLabel = status === "PENDING" ? "Coming Soon" : status === "CLOSED" ? "Closed" : status === "CANCELLED" ? "Cancelled" : null;
9560
- return /* @__PURE__ */ jsxRuntime.jsxs(
9724
+ return /* @__PURE__ */ jsxRuntime.jsx(
9561
9725
  IPOOption,
9562
9726
  {
9563
9727
  onClick: () => {
@@ -9568,16 +9732,19 @@ function AssetSelectorBar({
9568
9732
  },
9569
9733
  $selected: isCurrent,
9570
9734
  style: { cursor: isCurrent ? "default" : "pointer" },
9571
- children: [
9572
- /* @__PURE__ */ jsxRuntime.jsxs(IPOOptionName, { children: [
9573
- item.streetAddress,
9574
- item.ticker ? ` (${item.ticker})` : ""
9575
- ] }),
9576
- /* @__PURE__ */ jsxRuntime.jsxs(IPOOptionLocation, { children: [
9577
- item.suburb,
9578
- statusLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { children: statusLabel })
9735
+ children: /* @__PURE__ */ jsxRuntime.jsxs(IPOOptionInner, { children: [
9736
+ item.imageUrl && /* @__PURE__ */ jsxRuntime.jsx(IPOOptionThumb, { src: item.imageUrl, alt: item.streetAddress }),
9737
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9738
+ /* @__PURE__ */ jsxRuntime.jsxs(IPOOptionName, { children: [
9739
+ item.streetAddress,
9740
+ item.ticker ? ` (${item.ticker})` : ""
9741
+ ] }),
9742
+ /* @__PURE__ */ jsxRuntime.jsxs(IPOOptionLocation, { children: [
9743
+ item.suburb,
9744
+ statusLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { children: statusLabel })
9745
+ ] })
9579
9746
  ] })
9580
- ]
9747
+ ] })
9581
9748
  },
9582
9749
  item.tokenName
9583
9750
  );
@@ -9612,6 +9779,20 @@ var IPOAssetSelector = styled25__default.default.div`
9612
9779
  padding: 0.6rem 0.75rem;
9613
9780
  }
9614
9781
  `;
9782
+ var AssetThumbnail = styled25__default.default.img`
9783
+ width: 40px;
9784
+ height: 40px;
9785
+ border-radius: 8px;
9786
+ object-fit: cover;
9787
+ flex-shrink: 0;
9788
+ border: 1px solid rgba(255, 255, 255, 0.1);
9789
+
9790
+ @media (max-width: 768px) {
9791
+ width: 32px;
9792
+ height: 32px;
9793
+ border-radius: 6px;
9794
+ }
9795
+ `;
9615
9796
  var AssetSelectorDropdown = styled25__default.default.div`
9616
9797
  display: flex;
9617
9798
  align-items: center;
@@ -9679,16 +9860,16 @@ var MetricLabel2 = styled25__default.default.span`
9679
9860
  }
9680
9861
  `;
9681
9862
  var MetricValue = styled25__default.default.span`
9682
- font-size: 1.25rem;
9683
- font-weight: 700;
9684
- color: ${(p) => p.$accent ? "#D4AF37" : "#fff"};
9863
+ font-size: ${(p) => p.$secondary ? "0.95rem" : "1.25rem"};
9864
+ font-weight: ${(p) => p.$secondary ? "600" : "700"};
9865
+ color: ${(p) => p.$accent ? "#D4AF37" : p.$secondary ? "rgba(255,255,255,0.7)" : "#fff"};
9685
9866
 
9686
9867
  @media (max-width: 768px) {
9687
- font-size: 1.05rem;
9868
+ font-size: ${(p) => p.$secondary ? "0.85rem" : "1.05rem"};
9688
9869
  }
9689
9870
 
9690
9871
  @media (max-width: 480px) {
9691
- font-size: 0.95rem;
9872
+ font-size: ${(p) => p.$secondary ? "0.8rem" : "0.95rem"};
9692
9873
  }
9693
9874
  `;
9694
9875
  var MetricChange = styled25__default.default.span`
@@ -9750,6 +9931,19 @@ var IPOOption = styled25__default.default.div`
9750
9931
  &:hover { background: linear-gradient(90deg, rgba(255,255,255,0.06) 0%, transparent 100%); }
9751
9932
  ${(p) => p.$selected && `background: linear-gradient(90deg, rgba(56,97,251,0.15) 0%, transparent 100%);`}
9752
9933
  `;
9934
+ var IPOOptionInner = styled25__default.default.div`
9935
+ display: flex;
9936
+ align-items: center;
9937
+ gap: 1rem;
9938
+ `;
9939
+ var IPOOptionThumb = styled25__default.default.img`
9940
+ width: 36px;
9941
+ height: 36px;
9942
+ border-radius: 6px;
9943
+ object-fit: cover;
9944
+ flex-shrink: 0;
9945
+ border: 1px solid rgba(255, 255, 255, 0.08);
9946
+ `;
9753
9947
  var IPOOptionName = styled25__default.default.div`
9754
9948
  font-weight: 600;
9755
9949
  font-size: 1rem;
@@ -9785,6 +9979,7 @@ function OfferingProgressCard({
9785
9979
  raisedAmount,
9786
9980
  targetAmount,
9787
9981
  isPrivateClient = false,
9982
+ variant = "default",
9788
9983
  style,
9789
9984
  className
9790
9985
  }) {
@@ -9816,7 +10011,109 @@ function OfferingProgressCard({
9816
10011
  const interval = setInterval(() => setCountdown(calculateCountdown()), 1e3);
9817
10012
  return () => clearInterval(interval);
9818
10013
  }, [opensAt]);
9819
- return /* @__PURE__ */ jsxRuntime.jsxs(Container2, { style, className, children: [
10014
+ if (variant === "compact") {
10015
+ return /* @__PURE__ */ jsxRuntime.jsxs(CompactContainer, { style, className, children: [
10016
+ /* @__PURE__ */ jsxRuntime.jsx(ProgressBarOuter, { children: /* @__PURE__ */ jsxRuntime.jsx(ProgressBarInner, { style: { width: `${Math.min(percentSold, 100)}%` } }) }),
10017
+ /* @__PURE__ */ jsxRuntime.jsxs(ProgressInfo, { children: [
10018
+ /* @__PURE__ */ jsxRuntime.jsxs(ProgressSubscribers, { children: [
10019
+ "Subscribers: ",
10020
+ subscriberCount.toLocaleString()
10021
+ ] }),
10022
+ /* @__PURE__ */ jsxRuntime.jsxs(ProgressAmounts, { children: [
10023
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "raised", children: formatCurrency3(computedRaised) }),
10024
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "target", children: [
10025
+ " / ",
10026
+ formatCurrency3(computedTarget)
10027
+ ] })
10028
+ ] })
10029
+ ] })
10030
+ ] });
10031
+ }
10032
+ if (variant === "home") {
10033
+ const isPreLive = !ipoStarted && ipoStatus !== "CLOSED" && ipoStatus !== "CANCELLED";
10034
+ return /* @__PURE__ */ jsxRuntime.jsxs(Container, { style, className, children: [
10035
+ /* @__PURE__ */ jsxRuntime.jsxs(Header2, { children: [
10036
+ /* @__PURE__ */ jsxRuntime.jsxs("h3", { children: [
10037
+ /* @__PURE__ */ jsxRuntime.jsx(fa.FaChartLine, {}),
10038
+ " Offering Progress"
10039
+ ] }),
10040
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", alignItems: "center", gap: "0.4rem" }, children: ipoStarted ? /* @__PURE__ */ jsxRuntime.jsxs(StatusSpan, { $color: "#0ecb81", children: [
10041
+ /* @__PURE__ */ jsxRuntime.jsx(StatusDot, { $color: "#0ecb81", $pulse: true }),
10042
+ "LIVE"
10043
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(StatusSpan, { $color: statusColor || "#D4AF37", children: [
10044
+ /* @__PURE__ */ jsxRuntime.jsx(StatusDot, { $color: statusColor || "#D4AF37" }),
10045
+ statusLabel || "Preparing"
10046
+ ] }) })
10047
+ ] }),
10048
+ isPreLive ? /* @__PURE__ */ jsxRuntime.jsxs(HomePreLiveRow, { children: [
10049
+ countdown ? /* @__PURE__ */ jsxRuntime.jsxs(HomeCountdownSide, { children: [
10050
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownLabel, { children: "Opens In" }),
10051
+ /* @__PURE__ */ jsxRuntime.jsxs(CountdownDigits, { children: [
10052
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownNumber, { children: String(countdown.days).padStart(2, "0") }),
10053
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownUnitLabel, { children: "D" }),
10054
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownSeparator, { children: ":" }),
10055
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownNumber, { children: String(countdown.hours).padStart(2, "0") }),
10056
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownUnitLabel, { children: "H" }),
10057
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownSeparator, { children: ":" }),
10058
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownNumber, { children: String(countdown.minutes).padStart(2, "0") }),
10059
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownUnitLabel, { children: "M" }),
10060
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownSeparator, { children: ":" }),
10061
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownNumber, { children: String(countdown.seconds).padStart(2, "0") }),
10062
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownUnitLabel, { children: "S" })
10063
+ ] })
10064
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(HomeCountdownSide, { children: /* @__PURE__ */ jsxRuntime.jsx(PreLiveStatus, { $statusColor: statusColor, children: "Sale Not Yet Open" }) }),
10065
+ /* @__PURE__ */ jsxRuntime.jsxs(HomeUnitsSide, { children: [
10066
+ /* @__PURE__ */ jsxRuntime.jsx(HomeUnitsLabel, { children: "Units Subscribed" }),
10067
+ /* @__PURE__ */ jsxRuntime.jsxs(HomeUnitsValue, { children: [
10068
+ /* @__PURE__ */ jsxRuntime.jsx(HomeSpinner, {}),
10069
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
10070
+ " / ",
10071
+ supplyToSell.toLocaleString()
10072
+ ] })
10073
+ ] })
10074
+ ] })
10075
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(LiveBody, { children: [
10076
+ /* @__PURE__ */ jsxRuntime.jsxs(LiveTopRow, { children: [
10077
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10078
+ /* @__PURE__ */ jsxRuntime.jsxs(LiveLabel, { children: [
10079
+ "Offering Subscribed ",
10080
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u24D8" })
10081
+ ] }),
10082
+ /* @__PURE__ */ jsxRuntime.jsxs(LivePercent, { children: [
10083
+ percentSold.toFixed(1),
10084
+ "%",
10085
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "arrow", children: "\u2191" })
10086
+ ] })
10087
+ ] }),
10088
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "right" }, children: [
10089
+ /* @__PURE__ */ jsxRuntime.jsx(LiveLabel, { children: "Units Subscribed" }),
10090
+ /* @__PURE__ */ jsxRuntime.jsxs(UnitsValue, { children: [
10091
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: totalSold.toLocaleString() }),
10092
+ /* @__PURE__ */ jsxRuntime.jsxs("small", { children: [
10093
+ "/ ",
10094
+ supplyToSell.toLocaleString()
10095
+ ] })
10096
+ ] })
10097
+ ] })
10098
+ ] }),
10099
+ /* @__PURE__ */ jsxRuntime.jsx(ProgressBarOuter, { children: /* @__PURE__ */ jsxRuntime.jsx(ProgressBarInner, { style: { width: `${Math.min(percentSold, 100)}%` } }) }),
10100
+ /* @__PURE__ */ jsxRuntime.jsxs(ProgressInfo, { children: [
10101
+ /* @__PURE__ */ jsxRuntime.jsxs(ProgressSubscribers, { children: [
10102
+ "Subscribers: ",
10103
+ subscriberCount.toLocaleString()
10104
+ ] }),
10105
+ /* @__PURE__ */ jsxRuntime.jsxs(ProgressAmounts, { children: [
10106
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "raised", children: formatCurrency3(computedRaised) }),
10107
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "target", children: [
10108
+ " / ",
10109
+ formatCurrency3(computedTarget)
10110
+ ] })
10111
+ ] })
10112
+ ] })
10113
+ ] })
10114
+ ] });
10115
+ }
10116
+ return /* @__PURE__ */ jsxRuntime.jsxs(Container, { style, className, children: [
9820
10117
  /* @__PURE__ */ jsxRuntime.jsxs(Header2, { children: [
9821
10118
  /* @__PURE__ */ jsxRuntime.jsxs("h3", { children: [
9822
10119
  /* @__PURE__ */ jsxRuntime.jsx(fa.FaChartLine, {}),
@@ -9884,7 +10181,7 @@ function OfferingProgressCard({
9884
10181
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u24D8" })
9885
10182
  ] }),
9886
10183
  /* @__PURE__ */ jsxRuntime.jsxs(LivePercent, { children: [
9887
- percentSold < 0.1 && percentSold > 0 ? percentSold.toFixed(3) : percentSold.toFixed(1),
10184
+ percentSold.toFixed(1),
9888
10185
  "%",
9889
10186
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "arrow", children: "\u2191" })
9890
10187
  ] })
@@ -9917,7 +10214,7 @@ function OfferingProgressCard({
9917
10214
  ] })
9918
10215
  ] });
9919
10216
  }
9920
- var Container2 = styled25__default.default.div`
10217
+ var Container = styled25__default.default.div`
9921
10218
  background-color: var(--color-card-darker, #111);
9922
10219
  border-radius: 8px;
9923
10220
  padding: 1.5rem;
@@ -10117,6 +10414,59 @@ var ProgressAmounts = styled25__default.default.div`
10117
10414
  .raised { color: #D4AF37; }
10118
10415
  .target { color: rgba(255,255,255,0.3); }
10119
10416
  `;
10417
+ var CompactContainer = styled25__default.default.div`
10418
+ width: 100%;
10419
+ margin: 1.5rem 0;
10420
+ display: flex;
10421
+ flex-direction: column;
10422
+ gap: 0.5rem;
10423
+ `;
10424
+ var HomePreLiveRow = styled25__default.default.div`
10425
+ display: flex;
10426
+ align-items: center;
10427
+ justify-content: space-between;
10428
+ padding-top: 1rem;
10429
+ `;
10430
+ var HomeCountdownSide = styled25__default.default.div`
10431
+ display: flex;
10432
+ flex-direction: column;
10433
+ align-items: center;
10434
+ flex: 1;
10435
+ `;
10436
+ var HomeUnitsSide = styled25__default.default.div`
10437
+ text-align: center;
10438
+ flex-shrink: 0;
10439
+ `;
10440
+ var HomeUnitsLabel = styled25__default.default.div`
10441
+ font-size: 0.6rem;
10442
+ color: var(--color-text-secondary);
10443
+ text-transform: uppercase;
10444
+ letter-spacing: 0.1em;
10445
+ margin-bottom: 0.2rem;
10446
+ `;
10447
+ var HomeUnitsValue = styled25__default.default.div`
10448
+ font-size: 1.1rem;
10449
+ font-weight: 700;
10450
+ font-family: monospace;
10451
+ span {
10452
+ color: var(--color-text-secondary);
10453
+ font-weight: 400;
10454
+ }
10455
+ `;
10456
+ var HomeSpinner = styled25__default.default.span`
10457
+ display: inline-block;
10458
+ width: 14px;
10459
+ height: 14px;
10460
+ border: 2px solid rgba(255, 255, 255, 0.1);
10461
+ border-top-color: var(--color-accent, #f0b90b);
10462
+ border-radius: 50%;
10463
+ animation: homeSpin 1s linear infinite;
10464
+ vertical-align: middle;
10465
+ margin-right: 0.15rem;
10466
+ @keyframes homeSpin {
10467
+ to { transform: rotate(360deg); }
10468
+ }
10469
+ `;
10120
10470
  var MAX_DISPLAY_AMOUNT = 6e4;
10121
10471
  var formatCurrency4 = (amount) => {
10122
10472
  if (amount >= 1e6) return `$${(amount / 1e6).toFixed(2)}M`;
@@ -10406,53 +10756,238 @@ var PurchaseItem = styled25__default.default.div`
10406
10756
  padding: 0.4rem 0.6rem;
10407
10757
  }
10408
10758
  `;
10409
- var PurchaseInfo = styled25__default.default.div`
10410
- display: flex;
10411
- flex-direction: column;
10759
+ var PurchaseInfo = styled25__default.default.div`
10760
+ display: flex;
10761
+ flex-direction: column;
10762
+ min-width: 0;
10763
+ `;
10764
+ var PurchaseName = styled25__default.default.div`
10765
+ font-weight: 500;
10766
+ font-size: 0.875rem;
10767
+ color: #fff;
10768
+ white-space: nowrap;
10769
+ overflow: hidden;
10770
+ text-overflow: ellipsis;
10771
+ `;
10772
+ var PurchaseTime = styled25__default.default.div`
10773
+ font-size: 0.7rem;
10774
+ color: var(--color-text-secondary);
10775
+ margin-top: 0.125rem;
10776
+ `;
10777
+ var PurchaseAmount = styled25__default.default.div`
10778
+ font-weight: 600;
10779
+ font-size: 0.875rem;
10780
+ color: #fff;
10781
+ white-space: nowrap;
10782
+ margin-left: 1rem;
10783
+ `;
10784
+ var LiveIndicatorDot = styled25__default.default.span`
10785
+ display: inline-block;
10786
+ width: 8px;
10787
+ height: 8px;
10788
+ background-color: ${(p) => p.$active ? "#0ecb81" : "#848e9c"};
10789
+ border-radius: 50%;
10790
+ position: relative;
10791
+ &:after {
10792
+ content: '';
10793
+ position: absolute;
10794
+ width: 100%;
10795
+ height: 100%;
10796
+ border-radius: 50%;
10797
+ background-color: ${(p) => p.$active ? "#0ecb81" : "transparent"};
10798
+ animation: ${(p) => p.$active ? "liveGlow 2s infinite" : "none"};
10799
+ }
10800
+ @keyframes liveGlow {
10801
+ 0% { box-shadow: 0 0 0 0 rgba(14,203,129,0.4); }
10802
+ 70% { box-shadow: 0 0 0 10px rgba(14,203,129,0); }
10803
+ 100% { box-shadow: 0 0 0 0 rgba(14,203,129,0); }
10804
+ }
10805
+ `;
10806
+ var slideIn = styled25.keyframes`
10807
+ from { transform: translateX(110%); opacity: 0; }
10808
+ to { transform: translateX(0); opacity: 1; }
10809
+ `;
10810
+ var slideOut = styled25.keyframes`
10811
+ from { transform: translateX(0); opacity: 1; }
10812
+ to { transform: translateX(110%); opacity: 0; }
10813
+ `;
10814
+ var progressShrink = styled25.keyframes`
10815
+ from { width: 100%; }
10816
+ to { width: 0%; }
10817
+ `;
10818
+ var VARIANT_COLORS = {
10819
+ success: { accent: "#0ecb81", icon: "\u2713" },
10820
+ error: { accent: "#f6465d", icon: "\u2715" },
10821
+ info: { accent: "#E6C656", icon: "\u2139" },
10822
+ pending: { accent: "#7EB3E6", icon: "\u25CC" }
10823
+ };
10824
+ var Wrapper = styled25__default.default.div`
10825
+ position: relative;
10826
+ display: flex;
10827
+ flex-direction: column;
10828
+ gap: 0;
10829
+ width: 340px;
10830
+ background: #0d0f1a;
10831
+ border: 1px solid rgba(255, 255, 255, 0.08);
10832
+ border-radius: 10px;
10833
+ overflow: hidden;
10834
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255,255,255,0.04);
10835
+ animation: ${({ $exiting }) => $exiting ? styled25.css`${slideOut} 0.28s cubic-bezier(0.4,0,1,1) forwards` : styled25.css`${slideIn} 0.32s cubic-bezier(0,0,0.2,1) forwards`};
10836
+ pointer-events: all;
10837
+ `;
10838
+ var Body = styled25__default.default.div`
10839
+ display: flex;
10840
+ align-items: flex-start;
10841
+ gap: 12px;
10842
+ padding: 14px 16px 12px;
10843
+ `;
10844
+ var IconDot = styled25__default.default.div`
10845
+ flex-shrink: 0;
10846
+ width: 28px;
10847
+ height: 28px;
10848
+ border-radius: 50%;
10849
+ background: ${({ $color }) => $color}1a;
10850
+ border: 1px solid ${({ $color }) => $color}55;
10851
+ display: flex;
10852
+ align-items: center;
10853
+ justify-content: center;
10854
+ font-size: 0.75rem;
10855
+ font-weight: 700;
10856
+ color: ${({ $color }) => $color};
10857
+ margin-top: 1px;
10858
+ `;
10859
+ var Content = styled25__default.default.div`
10860
+ flex: 1;
10412
10861
  min-width: 0;
10413
10862
  `;
10414
- var PurchaseName = styled25__default.default.div`
10415
- font-weight: 500;
10416
- font-size: 0.875rem;
10863
+ var Title2 = styled25__default.default.p`
10864
+ margin: 0 0 2px;
10865
+ font-size: 0.8rem;
10866
+ font-weight: 600;
10417
10867
  color: #fff;
10418
- white-space: nowrap;
10419
- overflow: hidden;
10420
- text-overflow: ellipsis;
10868
+ letter-spacing: 0.01em;
10421
10869
  `;
10422
- var PurchaseTime = styled25__default.default.div`
10423
- font-size: 0.7rem;
10424
- color: var(--color-text-secondary);
10425
- margin-top: 0.125rem;
10870
+ var Amount = styled25__default.default.p`
10871
+ margin: 0 0 6px;
10872
+ font-size: 1.05rem;
10873
+ font-weight: 700;
10874
+ color: #E6C656;
10875
+ letter-spacing: -0.01em;
10426
10876
  `;
10427
- var PurchaseAmount = styled25__default.default.div`
10428
- font-weight: 600;
10429
- font-size: 0.875rem;
10430
- color: #fff;
10431
- white-space: nowrap;
10432
- margin-left: 1rem;
10877
+ var TxRow = styled25__default.default.a`
10878
+ display: inline-flex;
10879
+ align-items: center;
10880
+ gap: 5px;
10881
+ font-family: 'IBM Plex Mono', 'Space Mono', monospace;
10882
+ font-size: 0.68rem;
10883
+ color: rgba(255, 255, 255, 0.4);
10884
+ text-decoration: none;
10885
+ transition: color 0.15s;
10886
+ &:hover {
10887
+ color: #7EB3E6;
10888
+ }
10433
10889
  `;
10434
- var LiveIndicatorDot = styled25__default.default.span`
10435
- display: inline-block;
10436
- width: 8px;
10437
- height: 8px;
10438
- background-color: ${(p) => p.$active ? "#0ecb81" : "#848e9c"};
10439
- border-radius: 50%;
10890
+ var TxArrow = styled25__default.default.span`
10891
+ font-size: 0.6rem;
10892
+ opacity: 0.6;
10893
+ `;
10894
+ var CloseBtn = styled25__default.default.button`
10895
+ flex-shrink: 0;
10896
+ background: none;
10897
+ border: none;
10898
+ padding: 2px 4px;
10899
+ cursor: pointer;
10900
+ color: rgba(255, 255, 255, 0.25);
10901
+ font-size: 0.9rem;
10902
+ line-height: 1;
10903
+ transition: color 0.15s;
10904
+ &:hover { color: rgba(255, 255, 255, 0.7); }
10905
+ `;
10906
+ var ProgressBar = styled25__default.default.div`
10907
+ height: 2px;
10908
+ background: rgba(255, 255, 255, 0.06);
10440
10909
  position: relative;
10441
- &:after {
10910
+ &::after {
10442
10911
  content: '';
10443
10912
  position: absolute;
10444
- width: 100%;
10913
+ left: 0;
10914
+ top: 0;
10445
10915
  height: 100%;
10446
- border-radius: 50%;
10447
- background-color: ${(p) => p.$active ? "#0ecb81" : "transparent"};
10448
- animation: ${(p) => p.$active ? "liveGlow 2s infinite" : "none"};
10449
- }
10450
- @keyframes liveGlow {
10451
- 0% { box-shadow: 0 0 0 0 rgba(14,203,129,0.4); }
10452
- 70% { box-shadow: 0 0 0 10px rgba(14,203,129,0); }
10453
- 100% { box-shadow: 0 0 0 0 rgba(14,203,129,0); }
10916
+ background: ${({ $color }) => $color};
10917
+ animation: ${styled25.css`${progressShrink} ${({ $duration }) => $duration}ms linear forwards`};
10454
10918
  }
10455
10919
  `;
10920
+ var Container2 = styled25__default.default.div`
10921
+ position: fixed;
10922
+ bottom: 24px;
10923
+ right: 24px;
10924
+ z-index: 9999;
10925
+ display: flex;
10926
+ flex-direction: column-reverse;
10927
+ gap: 10px;
10928
+ pointer-events: none;
10929
+ `;
10930
+ var DEFAULT_EXPLORER = "https://sepolia.basescan.org/tx/";
10931
+ function truncateHash(hash) {
10932
+ return `${hash.slice(0, 6)}\u2026${hash.slice(-4)}`;
10933
+ }
10934
+ function ToastItem({ toast, onDismiss }) {
10935
+ const [exiting, setExiting] = React5.useState(false);
10936
+ const timerRef = React5.useRef(null);
10937
+ const dismiss = React5.useCallback(() => {
10938
+ setExiting(true);
10939
+ setTimeout(() => onDismiss(toast.id), 280);
10940
+ }, [onDismiss, toast.id]);
10941
+ React5.useEffect(() => {
10942
+ const duration2 = toast.duration ?? 6e3;
10943
+ if (duration2 > 0) {
10944
+ timerRef.current = setTimeout(dismiss, duration2);
10945
+ }
10946
+ return () => {
10947
+ if (timerRef.current) clearTimeout(timerRef.current);
10948
+ };
10949
+ }, [dismiss, toast.duration]);
10950
+ const { accent, icon } = VARIANT_COLORS[toast.variant];
10951
+ const duration = toast.duration ?? 6e3;
10952
+ const explorerBase = toast.explorerUrl ?? DEFAULT_EXPLORER;
10953
+ const txUrl = toast.txHash ? `${explorerBase}${toast.txHash}` : void 0;
10954
+ return /* @__PURE__ */ jsxRuntime.jsxs(Wrapper, { $exiting: exiting, children: [
10955
+ /* @__PURE__ */ jsxRuntime.jsxs(Body, { children: [
10956
+ /* @__PURE__ */ jsxRuntime.jsx(IconDot, { $color: accent, children: icon }),
10957
+ /* @__PURE__ */ jsxRuntime.jsxs(Content, { children: [
10958
+ /* @__PURE__ */ jsxRuntime.jsx(Title2, { children: toast.title }),
10959
+ toast.amount && /* @__PURE__ */ jsxRuntime.jsx(Amount, { children: toast.amount }),
10960
+ toast.txHash && txUrl && /* @__PURE__ */ jsxRuntime.jsxs(TxRow, { href: txUrl, target: "_blank", rel: "noopener noreferrer", children: [
10961
+ truncateHash(toast.txHash),
10962
+ /* @__PURE__ */ jsxRuntime.jsx(TxArrow, { children: "\u2197" })
10963
+ ] })
10964
+ ] }),
10965
+ /* @__PURE__ */ jsxRuntime.jsx(CloseBtn, { type: "button", onClick: dismiss, "aria-label": "Dismiss", children: "\u2715" })
10966
+ ] }),
10967
+ duration > 0 && /* @__PURE__ */ jsxRuntime.jsx(ProgressBar, { $color: accent, $duration: duration })
10968
+ ] });
10969
+ }
10970
+ var ToastContext = React5.createContext(null);
10971
+ function ToastProvider({ children }) {
10972
+ const [toasts, setToasts] = React5.useState([]);
10973
+ const addToast = React5.useCallback((data) => {
10974
+ const id = `toast-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
10975
+ setToasts((prev) => [...prev, { ...data, id }]);
10976
+ return id;
10977
+ }, []);
10978
+ const dismiss = React5.useCallback((id) => {
10979
+ setToasts((prev) => prev.filter((t) => t.id !== id));
10980
+ }, []);
10981
+ return /* @__PURE__ */ jsxRuntime.jsxs(ToastContext.Provider, { value: { toast: addToast, dismiss }, children: [
10982
+ children,
10983
+ /* @__PURE__ */ jsxRuntime.jsx(Container2, { children: toasts.map((t) => /* @__PURE__ */ jsxRuntime.jsx(ToastItem, { toast: t, onDismiss: dismiss }, t.id)) })
10984
+ ] });
10985
+ }
10986
+ function useToast() {
10987
+ const ctx = React5.useContext(ToastContext);
10988
+ if (!ctx) throw new Error("useToast must be used within a ToastProvider");
10989
+ return ctx;
10990
+ }
10456
10991
  function OrderPanel({
10457
10992
  statusLabel,
10458
10993
  statusColor,
@@ -11352,6 +11887,7 @@ function PortfolioActivityPanel({
11352
11887
  positions = [],
11353
11888
  showPositionsTab = false,
11354
11889
  onPositionClick,
11890
+ onClosePosition,
11355
11891
  offeringOrders = [],
11356
11892
  openOrders = [],
11357
11893
  orderHistory = [],
@@ -11449,50 +11985,52 @@ function PortfolioActivityPanel({
11449
11985
  ] }),
11450
11986
  activeTab === "positions" && showPositionsTab && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11451
11987
  positions.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { children: "No positions yet. Subscribe to an offering or buy on the secondary market." }),
11452
- positions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: pageSlice(positions).map((pos) => {
11453
- const currentValue = pos.quantity * pos.marketPrice;
11454
- const costBasis = pos.quantity * pos.averageEntryPrice;
11455
- const pnl = pos.propertyPnl ?? currentValue - costBasis;
11456
- const pnlPercent = pos.propertyPnlPercent ?? pos.percentChange ?? 0;
11457
- const totalPortfolioValue = positions.reduce((sum, p) => sum + p.quantity * p.marketPrice, 0);
11458
- const portfolioPercent = totalPortfolioValue > 0 ? currentValue / totalPortfolioValue * 100 : 0;
11459
- const isPositive = pnl >= 0;
11460
- return /* @__PURE__ */ jsxRuntime.jsxs(HoldingsItem, { onClick: () => onPositionClick?.(pos.tokenName, pos.isIpoAllocation), children: [
11461
- /* @__PURE__ */ jsxRuntime.jsxs(HoldingsLeft, { children: [
11462
- /* @__PURE__ */ jsxRuntime.jsx(HoldingsProperty, { children: pos.tokenName }),
11463
- /* @__PURE__ */ jsxRuntime.jsxs(HoldingsPortfolio, { children: [
11464
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
11465
- portfolioPercent.toFixed(1),
11466
- "%"
11988
+ positions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11989
+ /* @__PURE__ */ jsxRuntime.jsxs(PositionsHeader, { $hasClose: !!onClosePosition, children: [
11990
+ /* @__PURE__ */ jsxRuntime.jsx(PositionsHeaderCell, { children: "Asset" }),
11991
+ /* @__PURE__ */ jsxRuntime.jsx(PositionsHeaderCell, { $align: "right", children: "Size" }),
11992
+ /* @__PURE__ */ jsxRuntime.jsx(PositionsHeaderCell, { $align: "right", children: "Value" }),
11993
+ /* @__PURE__ */ jsxRuntime.jsx(PositionsHeaderCell, { $align: "right", children: "Entry Price" }),
11994
+ /* @__PURE__ */ jsxRuntime.jsx(PositionsHeaderCell, { $align: "right", children: "Mark Price" }),
11995
+ /* @__PURE__ */ jsxRuntime.jsx(PositionsHeaderCell, { $align: "right", children: "PNL (%)" }),
11996
+ onClosePosition && /* @__PURE__ */ jsxRuntime.jsx(PositionsHeaderCell, { $align: "right", children: "Close" })
11997
+ ] }),
11998
+ pageSlice(positions).map((pos) => {
11999
+ const currentValue = pos.quantity * pos.marketPrice;
12000
+ const costBasis = pos.quantity * pos.averageEntryPrice;
12001
+ const pnl = pos.propertyPnl ?? currentValue - costBasis;
12002
+ const pnlPercent = pos.propertyPnlPercent ?? pos.percentChange ?? 0;
12003
+ const isPositive = pnl >= 0;
12004
+ return /* @__PURE__ */ jsxRuntime.jsxs(PositionsRow, { $hasClose: !!onClosePosition, onClick: () => onPositionClick?.(pos.tokenName, pos.isIpoAllocation), children: [
12005
+ /* @__PURE__ */ jsxRuntime.jsx(PositionsCell, { children: /* @__PURE__ */ jsxRuntime.jsx(HoldingsProperty, { children: pos.tokenName }) }),
12006
+ /* @__PURE__ */ jsxRuntime.jsx(PositionsCell, { $align: "right", children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#fff", fontSize: "0.8rem" }, children: formatNumber2(pos.quantity) }) }),
12007
+ /* @__PURE__ */ jsxRuntime.jsx(PositionsCell, { $align: "right", children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#fff", fontSize: "0.8rem" }, children: formatCurrency5(currentValue) }) }),
12008
+ /* @__PURE__ */ jsxRuntime.jsx(PositionsCell, { $align: "right", children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "rgba(255,255,255,0.7)", fontSize: "0.8rem" }, children: formatCurrency5(pos.averageEntryPrice) }) }),
12009
+ /* @__PURE__ */ jsxRuntime.jsx(PositionsCell, { $align: "right", children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#fff", fontSize: "0.8rem" }, children: formatCurrency5(pos.marketPrice) }) }),
12010
+ /* @__PURE__ */ jsxRuntime.jsxs(PositionsCell, { $align: "right", children: [
12011
+ /* @__PURE__ */ jsxRuntime.jsxs(PnLAmount, { $positive: isPositive, children: [
12012
+ isPositive ? "+" : "-",
12013
+ formatCurrency5(Math.abs(pnl))
11467
12014
  ] }),
11468
- " of portfolio"
11469
- ] })
11470
- ] }),
11471
- /* @__PURE__ */ jsxRuntime.jsxs(HoldingsQuantity, { children: [
11472
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
11473
- pos.quantity.toFixed(2),
11474
- " ",
11475
- pos.tokenName
11476
- ] }),
11477
- /* @__PURE__ */ jsxRuntime.jsxs(HoldingsAvgEntry, { children: [
11478
- "Avg ",
11479
- formatCurrency5(pos.averageEntryPrice)
11480
- ] })
11481
- ] }),
11482
- /* @__PURE__ */ jsxRuntime.jsxs(HoldingsPnL, { children: [
11483
- /* @__PURE__ */ jsxRuntime.jsxs(PnLAmount, { $positive: isPositive, children: [
11484
- isPositive ? "+" : "-",
11485
- "$",
11486
- Math.abs(pnl).toFixed(2)
12015
+ /* @__PURE__ */ jsxRuntime.jsxs(PnLPercentage, { $positive: isPositive, children: [
12016
+ isPositive ? "+" : "",
12017
+ pnlPercent.toFixed(1),
12018
+ "%"
12019
+ ] })
11487
12020
  ] }),
11488
- /* @__PURE__ */ jsxRuntime.jsxs(PnLPercentage, { $positive: isPositive, children: [
11489
- isPositive ? "+" : "",
11490
- pnlPercent.toFixed(1),
11491
- "%"
11492
- ] })
11493
- ] })
11494
- ] }, pos.tokenName);
11495
- }) })
12021
+ onClosePosition && /* @__PURE__ */ jsxRuntime.jsx(PositionsCell, { $align: "right", children: /* @__PURE__ */ jsxRuntime.jsxs(CloseActions, { children: [
12022
+ /* @__PURE__ */ jsxRuntime.jsx(CloseBtn2, { onClick: (e) => {
12023
+ e.stopPropagation();
12024
+ onClosePosition(pos.tokenName, "limit", pos.quantity, pos.marketPrice);
12025
+ }, children: "Limit" }),
12026
+ /* @__PURE__ */ jsxRuntime.jsx(CloseBtn2, { onClick: (e) => {
12027
+ e.stopPropagation();
12028
+ onClosePosition(pos.tokenName, "market", pos.quantity, pos.marketPrice);
12029
+ }, children: "Market" })
12030
+ ] }) })
12031
+ ] }, pos.tokenName);
12032
+ })
12033
+ ] })
11496
12034
  ] }),
11497
12035
  activeTab === "subscriptions" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11498
12036
  offeringOrders.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { children: "IPO allocations will appear here once you subscribe." }),
@@ -11609,7 +12147,14 @@ function PortfolioActivityPanel({
11609
12147
  formatTimestamp(trade.executedAt)
11610
12148
  ] })
11611
12149
  ] }),
11612
- trade.status === "SETTLEMENT_FAILED" ? /* @__PURE__ */ jsxRuntime.jsx(ActivityTag, { $color: "#f6465d", $bg: "rgba(246,70,93,0.12)", children: "Failed" }) : trade.status === "SETTLED" ? /* @__PURE__ */ jsxRuntime.jsx(ActivityTag, { $color: "#0ecb81", $bg: "rgba(14,203,129,0.12)", children: "Settled" }) : /* @__PURE__ */ jsxRuntime.jsx(ActivityTag, { $color: "#f0b90b", $bg: "rgba(240,185,11,0.15)", children: "Settling" }),
12150
+ /* @__PURE__ */ jsxRuntime.jsx(
12151
+ ActivityTag,
12152
+ {
12153
+ $color: trade.side === "SELL" ? "#f6465d" : "#0ecb81",
12154
+ $bg: trade.side === "SELL" ? "rgba(246,70,93,0.12)" : "rgba(14,203,129,0.12)",
12155
+ children: sideLabel(trade.side)
12156
+ }
12157
+ ),
11613
12158
  /* @__PURE__ */ jsxRuntime.jsx(ActivityAmount, { children: formatCurrency5(trade.price * trade.quantity) })
11614
12159
  ] }, trade.tradeId))
11615
12160
  ] }),
@@ -11787,8 +12332,8 @@ var ActivityPrimary = styled25__default.default.span`
11787
12332
  font-weight: 500;
11788
12333
  `;
11789
12334
  var ActivitySecondary = styled25__default.default.span`
11790
- font-size: 0.7rem;
11791
- color: rgba(255, 255, 255, 0.5);
12335
+ font-size: 0.6rem;
12336
+ color: rgba(255, 255, 255, 0.35);
11792
12337
  `;
11793
12338
  var ActivityTag = styled25__default.default.span`
11794
12339
  font-size: 0.58rem;
@@ -11867,53 +12412,42 @@ var PaginationLabel = styled25__default.default.span`
11867
12412
  font-size: 0.8rem;
11868
12413
  color: rgba(255, 255, 255, 0.4);
11869
12414
  `;
11870
- var HoldingsItem = styled25__default.default.div`
12415
+ var PositionsHeader = styled25__default.default.div`
12416
+ display: grid;
12417
+ grid-template-columns: ${(p) => p.$hasClose ? "1.2fr 0.8fr 1fr 1fr 1fr 1.2fr auto" : "1.2fr 0.8fr 1fr 1fr 1fr 1.2fr"};
12418
+ gap: 0 0.5rem;
12419
+ padding: 0.4rem 0.5rem;
12420
+ border-bottom: 1px solid rgba(255, 255, 255, 0.06);
12421
+ `;
12422
+ var PositionsHeaderCell = styled25__default.default.div`
12423
+ font-size: 0.68rem;
12424
+ font-weight: 500;
12425
+ color: rgba(255, 255, 255, 0.4);
12426
+ text-align: ${(p) => p.$align || "left"};
12427
+ white-space: nowrap;
12428
+ `;
12429
+ var PositionsRow = styled25__default.default.div`
11871
12430
  display: grid;
11872
- grid-template-columns: 1fr 1fr 1fr;
12431
+ grid-template-columns: ${(p) => p.$hasClose ? "1.2fr 0.8fr 1fr 1fr 1fr 1.2fr auto" : "1.2fr 0.8fr 1fr 1fr 1fr 1.2fr"};
11873
12432
  align-items: center;
11874
- padding: 0.5rem 0;
11875
- min-height: 50px;
12433
+ gap: 0 0.5rem;
12434
+ padding: 0.5rem 0.5rem;
11876
12435
  cursor: pointer;
11877
- &:hover { background: rgba(255, 255, 255, 0.015); }
12436
+ border-bottom: 1px solid rgba(255, 255, 255, 0.03);
12437
+ &:last-child { border-bottom: none; }
12438
+ &:hover { background: rgba(255, 255, 255, 0.02); }
11878
12439
  `;
11879
- var HoldingsLeft = styled25__default.default.div`
12440
+ var PositionsCell = styled25__default.default.div`
11880
12441
  display: flex;
11881
12442
  flex-direction: column;
11882
- gap: 0.15rem;
12443
+ align-items: ${(p) => p.$align === "right" ? "flex-end" : "flex-start"};
12444
+ gap: 0.1rem;
11883
12445
  `;
11884
12446
  var HoldingsProperty = styled25__default.default.div`
11885
- font-size: 0.85rem;
12447
+ font-size: 0.8rem;
11886
12448
  font-weight: 600;
11887
12449
  color: #fff;
11888
12450
  `;
11889
- var HoldingsPortfolio = styled25__default.default.div`
11890
- font-size: 0.7rem;
11891
- color: rgba(255, 255, 255, 0.5);
11892
- span {
11893
- color: var(--color-accent, #E6C87E);
11894
- font-weight: 500;
11895
- }
11896
- `;
11897
- var HoldingsQuantity = styled25__default.default.div`
11898
- display: flex;
11899
- flex-direction: column;
11900
- align-items: center;
11901
- gap: 0.15rem;
11902
- font-size: 0.85rem;
11903
- font-weight: 500;
11904
- color: #fff;
11905
- `;
11906
- var HoldingsAvgEntry = styled25__default.default.div`
11907
- font-size: 0.7rem;
11908
- color: var(--color-accent, #E6C87E);
11909
- font-weight: 500;
11910
- `;
11911
- var HoldingsPnL = styled25__default.default.div`
11912
- display: flex;
11913
- flex-direction: column;
11914
- align-items: flex-end;
11915
- gap: 0.15rem;
11916
- `;
11917
12451
  var PnLAmount = styled25__default.default.div`
11918
12452
  font-size: 0.85rem;
11919
12453
  font-weight: 600;
@@ -12017,6 +12551,28 @@ var CancelConfirmProceed = styled25__default.default.button`
12017
12551
  cursor: not-allowed;
12018
12552
  }
12019
12553
  `;
12554
+ var CloseActions = styled25__default.default.div`
12555
+ display: flex;
12556
+ gap: 0.35rem;
12557
+ align-items: center;
12558
+ `;
12559
+ var CloseBtn2 = styled25__default.default.button`
12560
+ background: transparent;
12561
+ border: 1px solid rgba(246, 70, 93, 0.25);
12562
+ border-radius: 4px;
12563
+ padding: 0.15rem 0.5rem;
12564
+ font-size: 0.62rem;
12565
+ font-weight: 600;
12566
+ color: #f6465d;
12567
+ cursor: pointer;
12568
+ white-space: nowrap;
12569
+ transition: all 0.15s ease;
12570
+
12571
+ &:hover {
12572
+ background: rgba(246, 70, 93, 0.1);
12573
+ border-color: rgba(246, 70, 93, 0.5);
12574
+ }
12575
+ `;
12020
12576
  function NewsOrdersSection({ newsItems, newsConnectionStatus, activityData }) {
12021
12577
  return /* @__PURE__ */ jsxRuntime.jsxs(Row2, { children: [
12022
12578
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -13681,7 +14237,7 @@ function PropertyValuation({
13681
14237
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
13682
14238
  /* @__PURE__ */ jsxRuntime.jsxs(PricingModelDetail, { children: [
13683
14239
  /* @__PURE__ */ jsxRuntime.jsx(PropertyDetailLabel, { children: "Last Price" }),
13684
- /* @__PURE__ */ jsxRuntime.jsx(PricingDetailValue, { children: formatCompact(lastPrice) })
14240
+ /* @__PURE__ */ jsxRuntime.jsx(PricingDetailValue, { children: formatCurrency6(lastPrice) })
13685
14241
  ] }),
13686
14242
  /* @__PURE__ */ jsxRuntime.jsxs(PricingModelDetail, { children: [
13687
14243
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", width: "100%" }, children: [
@@ -13692,11 +14248,11 @@ function PropertyValuation({
13692
14248
  ] })
13693
14249
  ] }),
13694
14250
  /* @__PURE__ */ jsxRuntime.jsxs(PricingDetailValue, { style: { color: "var(--color-accent)", fontWeight: "bold" }, children: [
13695
- formatCompact(fairValue),
14251
+ formatCurrency6(fairValue),
13696
14252
  " ",
13697
14253
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "0.85em", fontWeight: "normal", opacity: 0.8 }, children: [
13698
14254
  "(",
13699
- formatCompact(fairValue * tokensOutstanding),
14255
+ formatCurrency6(fairValue * tokensOutstanding, { maximumFractionDigits: 0 }),
13700
14256
  ")"
13701
14257
  ] })
13702
14258
  ] })
@@ -13713,7 +14269,7 @@ function PropertyValuation({
13713
14269
  /* @__PURE__ */ jsxRuntime.jsx(GaugeIndicator, { type: "fairValue", position: 50 }),
13714
14270
  /* @__PURE__ */ jsxRuntime.jsxs(GaugePriceTag, { position: gaugePosition, children: [
13715
14271
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Last Price" }),
13716
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatCompact(lastPrice) })
14272
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatCurrency6(lastPrice) })
13717
14273
  ] }),
13718
14274
  /* @__PURE__ */ jsxRuntime.jsx(GaugeIndicator, { type: "lastPrice", position: gaugePosition })
13719
14275
  ] }),
@@ -13721,36 +14277,36 @@ function PropertyValuation({
13721
14277
  /* @__PURE__ */ jsxRuntime.jsx(ValuationItem, { children: /* @__PURE__ */ jsxRuntime.jsxs(ValuationValue, { style: { color: "#4CAF50" }, children: [
13722
14278
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
13723
14279
  "< ",
13724
- formatCompact(undervaluedThreshold)
14280
+ formatCurrency6(undervaluedThreshold)
13725
14281
  ] }),
13726
14282
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "valuation-amount-span", style: { fontSize: "0.8rem", fontWeight: "normal" }, children: [
13727
14283
  "(",
13728
- formatCompact(undervaluedThreshold * tokensOutstanding),
14284
+ formatMillions(undervaluedThreshold * tokensOutstanding),
13729
14285
  ")"
13730
14286
  ] })
13731
14287
  ] }) }),
13732
14288
  /* @__PURE__ */ jsxRuntime.jsx(ValuationItem, { children: /* @__PURE__ */ jsxRuntime.jsxs(ValuationValue, { style: { color: "var(--color-accent)" }, children: [
13733
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatCompact(fairValue) }),
14289
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatCurrency6(fairValue) }),
13734
14290
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "valuation-amount-span", style: { fontSize: "0.8rem", fontWeight: "normal" }, children: [
13735
14291
  "(",
13736
- formatCompact(fairValue * tokensOutstanding),
14292
+ formatMillions(fairValue * tokensOutstanding),
13737
14293
  ")"
13738
14294
  ] })
13739
14295
  ] }) }),
13740
14296
  /* @__PURE__ */ jsxRuntime.jsx(ValuationItem, { children: /* @__PURE__ */ jsxRuntime.jsxs(ValuationValue, { style: { color: "#F44336" }, children: [
13741
14297
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
13742
14298
  "> ",
13743
- formatCompact(overvaluedThreshold)
14299
+ formatCurrency6(overvaluedThreshold)
13744
14300
  ] }),
13745
14301
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "valuation-amount-span", style: { fontSize: "0.8rem", fontWeight: "normal" }, children: [
13746
14302
  "(",
13747
- formatCompact(overvaluedThreshold * tokensOutstanding),
14303
+ formatMillions(overvaluedThreshold * tokensOutstanding),
13748
14304
  ")"
13749
14305
  ] })
13750
14306
  ] }) })
13751
14307
  ] })
13752
14308
  ] }),
13753
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
14309
+ /* @__PURE__ */ jsxRuntime.jsxs(HiddenMobileChart, { children: [
13754
14310
  /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { marginBottom: "1rem", fontSize: "1.1rem", color: "#fff" }, children: "Historical Valuation" }),
13755
14311
  /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { children: /* @__PURE__ */ jsxRuntime.jsxs(ChartBackground, { children: [
13756
14312
  axisLabels.map((label, index) => /* @__PURE__ */ jsxRuntime.jsx(YAxisLabel, { style: { top: `${10 + index * 22}%` }, children: label }, `${label}-${index}`)),
@@ -13869,7 +14425,15 @@ function PropertyValuation({
13869
14425
  ] })
13870
14426
  ] }) })
13871
14427
  ] })
13872
- ] })
14428
+ ] }),
14429
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "desktop-only-historical-chart", style: { marginBottom: "1rem", fontSize: "1.1rem", color: "#fff" }, children: "Historical Valuation" }),
14430
+ /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { className: "desktop-only-historical-chart", children: /* @__PURE__ */ jsxRuntime.jsxs(ChartBackground, { children: [
14431
+ axisLabels.map((label, index) => /* @__PURE__ */ jsxRuntime.jsx(YAxisLabel, { style: { top: `${10 + index * 22}%` }, children: label }, `${label}-${index}`)),
14432
+ /* @__PURE__ */ jsxRuntime.jsxs(ValuationSvg, { viewBox: `0 0 ${CHART_WIDTH} ${CHART_HEIGHT}`, preserveAspectRatio: "none", children: [
14433
+ valuationPath ? /* @__PURE__ */ jsxRuntime.jsx("path", { d: valuationPath, fill: "none", stroke: "#D4AF37", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", vectorEffect: "non-scaling-stroke" }) : null,
14434
+ fairValuePath ? /* @__PURE__ */ jsxRuntime.jsx("path", { d: fairValuePath, fill: "none", stroke: "#FFFFFF", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", vectorEffect: "non-scaling-stroke" }) : null
14435
+ ] })
14436
+ ] }) })
13873
14437
  ] })
13874
14438
  ] }),
13875
14439
  /* @__PURE__ */ jsxRuntime.jsxs(RecentSalesSection, { children: [
@@ -13943,14 +14507,6 @@ function formatMillions(value) {
13943
14507
  }
13944
14508
  return `$${(value / 1e6).toFixed(2)}m`;
13945
14509
  }
13946
- function formatCompact(value) {
13947
- if (value == null || !Number.isFinite(value)) return "\u2014";
13948
- const abs = Math.abs(value);
13949
- if (abs >= 1e9) return `$${(value / 1e9).toFixed(2)}B`;
13950
- if (abs >= 1e6) return `$${(value / 1e6).toFixed(2)}M`;
13951
- if (abs >= 1e3) return `$${(value / 1e3).toFixed(1)}K`;
13952
- return formatCurrency6(value);
13953
- }
13954
14510
  function formatBedroomLabel(bedrooms) {
13955
14511
  if (!Number.isFinite(bedrooms)) return "\u2014";
13956
14512
  return `${bedrooms} Bed`;
@@ -14074,6 +14630,12 @@ var GaugePriceTag = styled25__default.default.div`
14074
14630
  color: var(--color-accent);
14075
14631
  }
14076
14632
  `;
14633
+ var HiddenMobileChart = styled25__default.default.div`
14634
+ display: none;
14635
+ @media (max-width: 480px) {
14636
+ display: block;
14637
+ }
14638
+ `;
14077
14639
  var ValuationWrapper = styled25__default.default.div`
14078
14640
  display: flex;
14079
14641
  flex-direction: column;
@@ -14125,10 +14687,9 @@ var PricingModelCard = styled25__default.default.div`
14125
14687
  var PricingModelHeader = styled25__default.default.div`
14126
14688
  display: flex;
14127
14689
  justify-content: space-between;
14128
- align-items: flex-start;
14690
+ align-items: center;
14129
14691
  margin-bottom: 1.5rem;
14130
14692
  gap: 1rem;
14131
- flex-wrap: wrap;
14132
14693
 
14133
14694
  .valuation-info {
14134
14695
  display: flex;
@@ -14136,7 +14697,6 @@ var PricingModelHeader = styled25__default.default.div`
14136
14697
  gap: 0.25rem;
14137
14698
  font-size: 0.85rem;
14138
14699
  color: rgba(255, 255, 255, 0.75);
14139
- flex-shrink: 0;
14140
14700
  }
14141
14701
  `;
14142
14702
  var PricingModelTitle = styled25__default.default.h3`
@@ -14203,31 +14763,15 @@ var ValuationDetails = styled25__default.default.div`
14203
14763
  display: flex;
14204
14764
  justify-content: space-between;
14205
14765
  margin-top: 1rem;
14206
- gap: 0.25rem;
14207
14766
  `;
14208
14767
  var ValuationItem = styled25__default.default.div`
14209
14768
  display: flex;
14210
14769
  flex-direction: column;
14211
- min-width: 0;
14212
- overflow: hidden;
14213
14770
  `;
14214
14771
  var ValuationValue = styled25__default.default.div`
14215
14772
  font-size: 1rem;
14216
14773
  font-weight: 600;
14217
14774
  color: #fff;
14218
- display: flex;
14219
- flex-direction: column;
14220
- gap: 2px;
14221
- overflow-wrap: break-word;
14222
- word-break: break-word;
14223
-
14224
- @media (max-width: 480px) {
14225
- font-size: 0.72rem;
14226
-
14227
- .valuation-amount-span {
14228
- display: none;
14229
- }
14230
- }
14231
14775
  `;
14232
14776
  var ChartContainer = styled25__default.default.div`
14233
14777
  width: 100%;
@@ -14640,7 +15184,7 @@ var ThumbnailStrip = styled25__default.default.div`
14640
15184
  display: none;
14641
15185
  }
14642
15186
  `;
14643
- var Thumbnail2 = styled25__default.default.button`
15187
+ var Thumbnail3 = styled25__default.default.button`
14644
15188
  width: 86px;
14645
15189
  height: 64px;
14646
15190
  border-radius: 6px;
@@ -14976,7 +15520,7 @@ function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose })
14976
15520
  ]
14977
15521
  }
14978
15522
  ),
14979
- /* @__PURE__ */ jsxRuntime.jsx(ThumbnailStrip, { onClick: (event) => event.stopPropagation(), children: galleryImages.map((image, idx) => /* @__PURE__ */ jsxRuntime.jsx(Thumbnail2, { $active: idx === currentIndex, onClick: () => setCurrentIndex(idx), "aria-label": `Preview ${image.label}`, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: image.src, alt: image.alt }) }, image.alt)) })
15523
+ /* @__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)) })
14980
15524
  ]
14981
15525
  }
14982
15526
  );