@loafmarkets/ui 0.1.89 → 0.1.90

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,7 @@ var Orderbook = React5__namespace.forwardRef(
2003
2004
  onPriceClick,
2004
2005
  onLoafLiquidityClick,
2005
2006
  tradeExplorerUrl,
2007
+ maxLevels,
2006
2008
  className,
2007
2009
  ...props
2008
2010
  }, ref) => {
@@ -2047,8 +2049,10 @@ var Orderbook = React5__namespace.forwardRef(
2047
2049
  onTabChange?.(next);
2048
2050
  };
2049
2051
  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;
2052
+ const effectiveLevels = maxLevels ?? LEVEL_ROWS_VISIBLE;
2053
+ const effectiveCompactLevels = maxLevels ?? COMPACT_ROWS_VISIBLE;
2054
+ const sectionHeight = isCompact ? effectiveCompactLevels * COMPACT_ROW_HEIGHT_PX : effectiveLevels * DEPTH_ROW_HEIGHT_PX;
2055
+ const rowCount = isCompact ? effectiveCompactLevels : effectiveLevels;
2052
2056
  const askVisibleLevels = asks.slice(-rowCount);
2053
2057
  const bidVisibleLevels = bids.slice(0, rowCount);
2054
2058
  const askCumDepths = new Array(askVisibleLevels.length);
@@ -2067,7 +2071,8 @@ var Orderbook = React5__namespace.forwardRef(
2067
2071
  bidCumDepths[i] = acc;
2068
2072
  }
2069
2073
  }
2070
- const combinedMaxCumDepth = Math.max(1, ...askCumDepths, ...bidCumDepths);
2074
+ const askMaxCumDepth = Math.max(1, ...askCumDepths);
2075
+ const bidMaxCumDepth = Math.max(1, ...bidCumDepths);
2071
2076
  const midClass = midChangePercent == null ? "text-white" : midChangePercent >= 0 ? "text-[#0ecb81]" : "text-[#f6465d]";
2072
2077
  const tradeFiltered = trades.filter((t) => tradeFilter === "all" || t.type === tradeFilter);
2073
2078
  const layoutProps = {
@@ -2087,7 +2092,8 @@ var Orderbook = React5__namespace.forwardRef(
2087
2092
  bidVisibleLevels,
2088
2093
  askCumDepths,
2089
2094
  bidCumDepths,
2090
- combinedMaxCumDepth,
2095
+ askMaxCumDepth,
2096
+ bidMaxCumDepth,
2091
2097
  midPrice,
2092
2098
  midChangePercent,
2093
2099
  midClass,
@@ -2097,14 +2103,16 @@ var Orderbook = React5__namespace.forwardRef(
2097
2103
  isLoading,
2098
2104
  seenTradeKeysRef,
2099
2105
  tradeExplorerUrl,
2100
- onPriceClick
2106
+ onPriceClick,
2107
+ levelCount: effectiveLevels,
2108
+ compactLevelCount: effectiveCompactLevels
2101
2109
  };
2102
2110
  return /* @__PURE__ */ jsxRuntime.jsx(
2103
2111
  Card,
2104
2112
  {
2105
2113
  ref,
2106
2114
  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",
2115
+ "w-full max-w-[520px] overflow-hidden rounded-[12px] border border-white/10 bg-[#111111] text-white shadow-md flex flex-col",
2108
2116
  isCompact && "max-w-none",
2109
2117
  className
2110
2118
  ),
@@ -2154,7 +2162,8 @@ function DesktopOrderbookLayout({
2154
2162
  bidVisibleLevels,
2155
2163
  askCumDepths,
2156
2164
  bidCumDepths,
2157
- combinedMaxCumDepth,
2165
+ askMaxCumDepth,
2166
+ bidMaxCumDepth,
2158
2167
  midPrice,
2159
2168
  midChangePercent,
2160
2169
  midClass,
@@ -2164,7 +2173,9 @@ function DesktopOrderbookLayout({
2164
2173
  isLoading,
2165
2174
  seenTradeKeysRef,
2166
2175
  tradeExplorerUrl,
2167
- onPriceClick
2176
+ onPriceClick,
2177
+ levelCount: effectiveLevels,
2178
+ compactLevelCount: _compactLevelCount
2168
2179
  }) {
2169
2180
  const midRef = React5__namespace.useRef(null);
2170
2181
  useMidPriceFlash(midRef, midPrice, "#0b1a24");
@@ -2252,7 +2263,7 @@ function DesktopOrderbookLayout({
2252
2263
  {
2253
2264
  className: "max-h-[380px] overflow-y-auto overflow-x-hidden",
2254
2265
  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) => {
2266
+ 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
2267
  const tradeKey = getTradeKey(trade, i);
2257
2268
  const explorerUrl = trade.txHash && tradeExplorerUrl ? tradeExplorerUrl(trade.txHash) : trade.txHash ? `https://sepolia.etherscan.io/tx/${trade.txHash}` : void 0;
2258
2269
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -2269,20 +2280,20 @@ function DesktopOrderbookLayout({
2269
2280
  );
2270
2281
  }) })
2271
2282
  }
2272
- ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col min-h-0", children: [
2283
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-h-0 overflow-hidden", children: [
2273
2284
  /* @__PURE__ */ jsxRuntime.jsx(
2274
2285
  "div",
2275
2286
  {
2276
- className: "flex flex-col justify-end divide-y divide-white/5 overflow-hidden",
2287
+ className: "flex flex-col justify-end overflow-hidden flex-shrink-0",
2277
2288
  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(
2289
+ 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
2290
  DepthRow,
2280
2291
  {
2281
2292
  side: "ask",
2282
2293
  price: l.price,
2283
2294
  amount: l.amount,
2284
2295
  cumDepth: askCumDepths[i],
2285
- depthPct: askCumDepths[i] / combinedMaxCumDepth * 100,
2296
+ depthPct: askCumDepths[i] / askMaxCumDepth * 100,
2286
2297
  precision,
2287
2298
  amountPrecision,
2288
2299
  hasUserOrder: userAskPrices.has(l.price),
@@ -2296,7 +2307,7 @@ function DesktopOrderbookLayout({
2296
2307
  "div",
2297
2308
  {
2298
2309
  ref: midRef,
2299
- className: "grid grid-cols-2 items-center gap-3 bg-[#0b1a24] px-3 py-2",
2310
+ className: "grid grid-cols-2 items-center gap-3 bg-[#0b1a24] px-3 py-2 flex-shrink-0",
2300
2311
  children: [
2301
2312
  /* @__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
2313
  "$",
@@ -2314,16 +2325,16 @@ function DesktopOrderbookLayout({
2314
2325
  /* @__PURE__ */ jsxRuntime.jsx(
2315
2326
  "div",
2316
2327
  {
2317
- className: "divide-y divide-white/5 overflow-hidden",
2328
+ className: "flex flex-col overflow-hidden flex-shrink-0",
2318
2329
  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(
2330
+ 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
2331
  DepthRow,
2321
2332
  {
2322
2333
  side: "bid",
2323
2334
  price: l.price,
2324
2335
  amount: l.amount,
2325
2336
  cumDepth: bidCumDepths[i],
2326
- depthPct: bidCumDepths[i] / combinedMaxCumDepth * 100,
2337
+ depthPct: bidCumDepths[i] / bidMaxCumDepth * 100,
2327
2338
  precision,
2328
2339
  amountPrecision,
2329
2340
  hasUserOrder: userBidPrices.has(l.price),
@@ -2352,7 +2363,8 @@ function MobileOrderbookLayout({
2352
2363
  bidVisibleLevels: visibleBids,
2353
2364
  askCumDepths,
2354
2365
  bidCumDepths,
2355
- combinedMaxCumDepth,
2366
+ askMaxCumDepth,
2367
+ bidMaxCumDepth,
2356
2368
  midPrice,
2357
2369
  midChangePercent,
2358
2370
  midClass,
@@ -2362,7 +2374,9 @@ function MobileOrderbookLayout({
2362
2374
  isLoading,
2363
2375
  seenTradeKeysRef,
2364
2376
  tradeExplorerUrl,
2365
- onPriceClick
2377
+ onPriceClick,
2378
+ levelCount: _levelCount,
2379
+ compactLevelCount: effectiveCompactLevels
2366
2380
  }) {
2367
2381
  const midRef = React5__namespace.useRef(null);
2368
2382
  useMidPriceFlash(midRef, midPrice, "transparent");
@@ -2434,13 +2448,13 @@ function MobileOrderbookLayout({
2434
2448
  ]
2435
2449
  }
2436
2450
  ),
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(
2451
+ /* @__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
2452
  MobileDepthRow,
2439
2453
  {
2440
2454
  side: "ask",
2441
2455
  price: l.price,
2442
2456
  amount: l.amount,
2443
- depthPct: askCumDepths[i] / combinedMaxCumDepth * 100,
2457
+ depthPct: askCumDepths[i] / askMaxCumDepth * 100,
2444
2458
  precision,
2445
2459
  amountPrecision,
2446
2460
  hasUserOrder: userAskPrices.has(l.price),
@@ -2481,13 +2495,13 @@ function MobileOrderbookLayout({
2481
2495
  ]
2482
2496
  }
2483
2497
  ),
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(
2498
+ /* @__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
2499
  MobileDepthRow,
2486
2500
  {
2487
2501
  side: "bid",
2488
2502
  price: l.price,
2489
2503
  amount: l.amount,
2490
- depthPct: bidCumDepths[i] / combinedMaxCumDepth * 100,
2504
+ depthPct: bidCumDepths[i] / bidMaxCumDepth * 100,
2491
2505
  precision,
2492
2506
  amountPrecision,
2493
2507
  hasUserOrder: userBidPrices.has(l.price),
@@ -2507,7 +2521,7 @@ function MobileOrderbookLayout({
2507
2521
  ]
2508
2522
  }
2509
2523
  ),
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) => {
2524
+ /* @__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
2525
  const tradeKey = getTradeKey(trade, i);
2512
2526
  const explorerUrl = trade.txHash && tradeExplorerUrl ? tradeExplorerUrl(trade.txHash) : trade.txHash ? `https://sepolia.etherscan.io/tx/${trade.txHash}` : void 0;
2513
2527
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -2547,7 +2561,8 @@ function MobileDepthRow({
2547
2561
  style: {
2548
2562
  display: "grid",
2549
2563
  gridTemplateColumns: "1.2fr 0.8fr",
2550
- padding: "0.2rem 0",
2564
+ height: `${COMPACT_ROW_HEIGHT_PX}px`,
2565
+ alignItems: "center",
2551
2566
  fontSize: "0.8rem",
2552
2567
  position: "relative",
2553
2568
  cursor: onPriceClick ? "pointer" : void 0
@@ -2690,7 +2705,7 @@ var PropertyTour = React5__namespace.forwardRef(
2690
2705
  }
2691
2706
  );
2692
2707
  PropertyTour.displayName = "PropertyTour";
2693
- var ITEMS_PER_PAGE = 4;
2708
+ var ITEMS_PER_PAGE = 6;
2694
2709
  var ensureAnimationsInjected = () => {
2695
2710
  if (typeof document === "undefined") return;
2696
2711
  if (document.getElementById("property-news-updates-animations")) return;
@@ -2735,6 +2750,21 @@ var formatDate = (value) => {
2735
2750
  if (!(value instanceof Date) || Number.isNaN(value.getTime())) return "";
2736
2751
  return value.toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" });
2737
2752
  };
2753
+ var formatDateShort = (value) => {
2754
+ const d = typeof value === "string" ? new Date(value) : value;
2755
+ if (!(d instanceof Date) || Number.isNaN(d.getTime())) {
2756
+ if (typeof value === "string") {
2757
+ return value.replace(/\s*\d{4}\s*$/, "");
2758
+ }
2759
+ return "";
2760
+ }
2761
+ const diffMs = Date.now() - d.getTime();
2762
+ const diffS = diffMs / 1e3;
2763
+ if (diffS < 60) return "Just now";
2764
+ if (diffS < 3600) return `${Math.floor(diffS / 60)}m ago`;
2765
+ if (diffS < 86400) return `${Math.floor(diffS / 3600)}h ago`;
2766
+ return d.toLocaleDateString(void 0, { month: "short", day: "numeric" });
2767
+ };
2738
2768
  var formatTimeAgo = (timestamp) => {
2739
2769
  const diff = (Date.now() - new Date(timestamp).getTime()) / 1e3;
2740
2770
  if (diff < 60) return `${Math.floor(diff)}s ago`;
@@ -2745,7 +2775,7 @@ function getSentimentInfo(score) {
2745
2775
  if (score == null) return null;
2746
2776
  if (score > 0.15) return { arrow: "\u25B2", label: "Bullish", color: "#0ecb81" };
2747
2777
  if (score < -0.15) return { arrow: "\u25BC", label: "Bearish", color: "#f6465d" };
2748
- return { arrow: "\u2014", label: "Neutral", color: "#848e9c" };
2778
+ return { arrow: "", label: "Neutral", color: "#848e9c" };
2749
2779
  }
2750
2780
  function NewsArticleModal({ item, onClose }) {
2751
2781
  const sentimentInfo = getSentimentInfo(item.sentimentScore);
@@ -2827,8 +2857,7 @@ function NewsArticleModal({ item, onClose }) {
2827
2857
  border: `1px solid ${sentimentInfo.color}40`
2828
2858
  },
2829
2859
  children: [
2830
- sentimentInfo.arrow,
2831
- " ",
2860
+ sentimentInfo.arrow ? `${sentimentInfo.arrow} ` : "",
2832
2861
  sentimentInfo.label
2833
2862
  ]
2834
2863
  }
@@ -2868,7 +2897,35 @@ function NewsArticleModal({ item, onClose }) {
2868
2897
  )
2869
2898
  ] }),
2870
2899
  /* @__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." })
2900
+ 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." }),
2901
+ 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(
2902
+ "a",
2903
+ {
2904
+ href: item.url,
2905
+ target: "_blank",
2906
+ rel: "noopener noreferrer",
2907
+ style: {
2908
+ display: "inline-flex",
2909
+ alignItems: "center",
2910
+ gap: "0.4rem",
2911
+ fontSize: "0.8rem",
2912
+ fontWeight: 600,
2913
+ color: "var(--color-accent, #f0b90b)",
2914
+ textDecoration: "none",
2915
+ transition: "opacity 0.15s"
2916
+ },
2917
+ onMouseEnter: (e) => {
2918
+ e.currentTarget.style.opacity = "0.8";
2919
+ },
2920
+ onMouseLeave: (e) => {
2921
+ e.currentTarget.style.opacity = "1";
2922
+ },
2923
+ children: [
2924
+ "Read full article",
2925
+ /* @__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" }) })
2926
+ ]
2927
+ }
2928
+ ) })
2872
2929
  ]
2873
2930
  }
2874
2931
  )
@@ -2938,10 +2995,10 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
2938
2995
  children: [
2939
2996
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
2940
2997
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
2941
- 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" }) }),
2998
+ 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" }) }),
2942
2999
  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" } }),
2943
3000
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2944
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: isHomeVariant ? "text-base font-semibold text-white" : "text-lg font-semibold text-white", children: resolvedHeading }),
3001
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: isHomeVariant ? "text-base font-semibold text-white" : "text-lg font-semibold text-white", style: { margin: 0 }, children: resolvedHeading }),
2945
3002
  subheading ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-white/60", children: subheading }) : null
2946
3003
  ] })
2947
3004
  ] }),
@@ -2956,7 +3013,7 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
2956
3013
  "LIVE"
2957
3014
  ] }) : null
2958
3015
  ] }),
2959
- 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(
3016
+ 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(
2960
3017
  "button",
2961
3018
  {
2962
3019
  type: "button",
@@ -2965,7 +3022,8 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
2965
3022
  background: "transparent",
2966
3023
  border: "none",
2967
3024
  borderBottom: homeTab === tab ? "2px solid var(--color-accent, #f0b90b)" : "2px solid transparent",
2968
- padding: "0.5rem 0.75rem",
3025
+ padding: "0 0 0.5rem 0",
3026
+ marginBottom: "-1px",
2969
3027
  fontSize: "0.75rem",
2970
3028
  fontWeight: homeTab === tab ? 600 : 400,
2971
3029
  color: homeTab === tab ? "var(--color-text, #fff)" : "var(--color-text-secondary, #848e9c)",
@@ -2979,7 +3037,7 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
2979
3037
  /* @__PURE__ */ jsxRuntime.jsx(
2980
3038
  "div",
2981
3039
  {
2982
- className: "mt-4 flex flex-1 flex-col gap-3 overflow-hidden",
3040
+ className: cn("flex flex-1 flex-col overflow-hidden", isHomeVariant ? "mt-2 gap-0" : "mt-4 gap-3"),
2983
3041
  style: !isPurchaseVariant && !isHomeVariant ? { minHeight: `${ITEMS_PER_PAGE * 86}px` } : void 0,
2984
3042
  children: isPurchaseVariant ? purchaseItems.length > 0 ? purchaseItems.slice(0, 7).map((purchase, index) => {
2985
3043
  const maxAmount = 6e4;
@@ -3018,7 +3076,7 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
3018
3076
  style: {
3019
3077
  width: "100%",
3020
3078
  textAlign: "left",
3021
- background: "transparent",
3079
+ backgroundColor: "transparent",
3022
3080
  border: "none",
3023
3081
  cursor: "pointer",
3024
3082
  padding: "0.75rem 0",
@@ -3027,18 +3085,28 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
3027
3085
  justifyContent: "space-between",
3028
3086
  alignItems: "flex-start",
3029
3087
  gap: "0.5rem",
3030
- color: "inherit"
3088
+ color: "inherit",
3089
+ transition: "background-color 0.15s"
3090
+ },
3091
+ onMouseEnter: (e) => {
3092
+ e.currentTarget.style.backgroundColor = "rgba(255,255,255,0.04)";
3093
+ const title = e.currentTarget.querySelector("h3");
3094
+ if (title) title.style.color = "var(--color-accent, #E6C87E)";
3095
+ },
3096
+ onMouseLeave: (e) => {
3097
+ e.currentTarget.style.backgroundColor = "transparent";
3098
+ const title = e.currentTarget.querySelector("h3");
3099
+ if (title) title.style.color = "#f8f9fa";
3031
3100
  },
3032
3101
  children: [
3033
3102
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1 }, children: [
3034
- /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { fontSize: "0.85rem", fontWeight: 400, marginBottom: "0.25rem", color: "#f8f9fa", lineHeight: 1.4 }, children: item.title }),
3103
+ /* @__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 }),
3035
3104
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "0.5rem", alignItems: "center", flexWrap: "wrap" }, children: [
3036
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#848e9c", fontSize: "0.7rem" }, children: typeof item.date === "string" ? item.date : formatDate(item.date) }),
3105
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#848e9c", fontSize: "0.7rem" }, children: formatDateShort(item.date) }),
3037
3106
  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 }),
3038
3107
  /* @__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" }),
3039
3108
  sentimentInfo && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "0.65rem", fontWeight: 600, color: sentimentInfo.color }, children: [
3040
- sentimentInfo.arrow,
3041
- " ",
3109
+ sentimentInfo.arrow ? `${sentimentInfo.arrow} ` : "",
3042
3110
  sentimentInfo.label
3043
3111
  ] })
3044
3112
  ] })
@@ -3095,8 +3163,7 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
3095
3163
  ] }),
3096
3164
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "flex-end", gap: "0.3rem", flexShrink: 0 }, children: [
3097
3165
  sentimentInfo && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "0.65rem", fontWeight: 700, color: sentimentInfo.color, whiteSpace: "nowrap" }, children: [
3098
- sentimentInfo.arrow,
3099
- " ",
3166
+ sentimentInfo.arrow ? `${sentimentInfo.arrow} ` : "",
3100
3167
  sentimentInfo.label
3101
3168
  ] }),
3102
3169
  /* @__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" })
@@ -3121,8 +3188,8 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
3121
3188
  type: "button",
3122
3189
  onClick: () => setHomePage((p) => Math.max(0, p - 1)),
3123
3190
  disabled: homePage === 0,
3124
- 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)" },
3125
- children: "Prev"
3191
+ 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)" },
3192
+ 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" }) })
3126
3193
  }
3127
3194
  ),
3128
3195
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "0.7rem", color: "rgba(255,255,255,0.5)" }, children: [
@@ -3136,8 +3203,8 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
3136
3203
  type: "button",
3137
3204
  onClick: () => setHomePage((p) => Math.min(homeTotalPages - 1, p + 1)),
3138
3205
  disabled: homePage >= homeTotalPages - 1,
3139
- 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)" },
3140
- children: "Next"
3206
+ 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)" },
3207
+ 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" }) })
3141
3208
  }
3142
3209
  )
3143
3210
  ] }),
@@ -3148,8 +3215,9 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
3148
3215
  type: "button",
3149
3216
  onClick: () => setPage((p) => Math.max(0, p - 1)),
3150
3217
  disabled: page === 0,
3151
- className: cn("rounded-full border border-white/15 px-3 py-1 uppercase tracking-[0.2em]", page === 0 ? "opacity-40 cursor-not-allowed" : "hover:border-white/40"),
3152
- children: "Prev"
3218
+ className: cn("rounded-full border border-white/15 flex items-center justify-center", page === 0 ? "opacity-40 cursor-not-allowed" : "hover:border-white/40"),
3219
+ style: { width: "28px", height: "28px", padding: 0, background: "transparent", color: "rgba(255,255,255,0.6)" },
3220
+ 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" }) })
3153
3221
  }
3154
3222
  ),
3155
3223
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium text-white/70", children: [
@@ -3164,8 +3232,9 @@ var PropertyNewsUpdates = React5__namespace.forwardRef(
3164
3232
  type: "button",
3165
3233
  onClick: () => setPage((p) => Math.min(totalPages - 1, p + 1)),
3166
3234
  disabled: page >= totalPages - 1,
3167
- className: cn("rounded-full border border-white/15 px-3 py-1 uppercase tracking-[0.2em]", page >= totalPages - 1 ? "opacity-40 cursor-not-allowed" : "hover:border-white/40"),
3168
- children: "Next"
3235
+ 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"),
3236
+ style: { width: "28px", height: "28px", padding: 0, background: "transparent", color: "rgba(255,255,255,0.6)" },
3237
+ 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" }) })
3169
3238
  }
3170
3239
  )
3171
3240
  ] }),
@@ -4668,14 +4737,16 @@ var PropertyHeroHeader = React5__namespace.forwardRef(
4668
4737
  imageUrl,
4669
4738
  imageAlt,
4670
4739
  name,
4740
+ address,
4671
4741
  location,
4672
4742
  price,
4673
4743
  currencySymbol = "$",
4674
4744
  changePercent,
4675
- beds,
4676
- baths,
4677
- cars,
4678
- propertyTypeLabel,
4745
+ priceChange,
4746
+ beds: _beds,
4747
+ baths: _baths,
4748
+ cars: _cars,
4749
+ propertyTypeLabel: _propertyTypeLabel,
4679
4750
  onTrade,
4680
4751
  onMakeOffer,
4681
4752
  tradeButtonLabel = "Trade",
@@ -4691,7 +4762,6 @@ var PropertyHeroHeader = React5__namespace.forwardRef(
4691
4762
  const tradeHoverColor = "#f5dd9a";
4692
4763
  const [isTradeInteracting, setIsTradeInteracting] = React5__namespace.useState(false);
4693
4764
  const [isOfferInteracting, setIsOfferInteracting] = React5__namespace.useState(false);
4694
- const hasAmenities = isLoading || beds != null || baths != null || cars != null || propertyTypeLabel != null;
4695
4765
  const isTradeDisabled = !onTrade;
4696
4766
  const isMakeOfferButtonDisabled = makeOfferDisabled || !onMakeOffer;
4697
4767
  const showMakeOfferButton = !hideMakeOfferButton;
@@ -4704,201 +4774,112 @@ var PropertyHeroHeader = React5__namespace.forwardRef(
4704
4774
  setIsOfferInteracting(state);
4705
4775
  };
4706
4776
  const headingStyle = {
4707
- fontSize: "clamp(1.6rem, 4vw, 2.5rem)",
4708
- marginBottom: "0.5rem",
4777
+ fontSize: "clamp(1.3rem, 3vw, 1.8rem)",
4778
+ marginBottom: "0",
4709
4779
  color: "#ffffff",
4710
4780
  textShadow: "0 2px 4px rgba(0, 0, 0, 0.3)",
4711
4781
  fontWeight: 600,
4712
4782
  lineHeight: 1.2
4713
4783
  };
4714
- return /* @__PURE__ */ jsxRuntime.jsxs(OuterWrapper, { ref, className: cn(className), ...props, children: [
4715
- /* @__PURE__ */ jsxRuntime.jsxs(HeroContainer, { children: [
4716
- /* @__PURE__ */ jsxRuntime.jsx(
4717
- HeroImage,
4718
- {
4719
- src: imageUrl,
4720
- alt: imageAlt ?? name
4721
- }
4722
- ),
4723
- statusBadge ? /* @__PURE__ */ jsxRuntime.jsxs(StatusBadge, { $isLive: statusBadge.variant === "live", children: [
4724
- statusBadge.variant === "live" ? /* @__PURE__ */ jsxRuntime.jsx(PulsingDot, {}) : null,
4725
- statusBadge.label
4726
- ] }) : null,
4727
- /* @__PURE__ */ jsxRuntime.jsx(HeroGradient, { "aria-hidden": "true" }),
4728
- /* @__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: [
4729
- /* @__PURE__ */ jsxRuntime.jsxs(InfoCard, { children: [
4730
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 space-y-2", children: [
4731
- /* @__PURE__ */ jsxRuntime.jsx("h1", { style: headingStyle, className: "break-words", children: name }),
4732
- /* @__PURE__ */ jsxRuntime.jsxs(InfoRow, { className: "mb-3 max-[768px]:mb-[0.6rem] max-[480px]:mb-[0.5rem]", children: [
4733
- /* @__PURE__ */ jsxRuntime.jsx(LocationText, { children: location }),
4734
- isLoading ? /* @__PURE__ */ jsxRuntime.jsx(PriceBlock, { children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 110, height: 18 }) }) : price == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(PriceBlock, { children: [
4735
- formatPrice3(price, currencySymbol),
4736
- changePercent == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(
4737
- "span",
4738
- {
4739
- className: cn(
4740
- "ml-2 flex items-center text-[0.875rem] font-medium",
4741
- isPositive ? "text-[#0ecb81]" : "text-[#f6465d]"
4742
- ),
4743
- children: [
4744
- /* @__PURE__ */ jsxRuntime.jsx(
4745
- "svg",
4746
- {
4747
- xmlns: "http://www.w3.org/2000/svg",
4748
- width: "12",
4749
- height: "12",
4750
- viewBox: "0 0 24 24",
4751
- fill: "currentColor",
4752
- className: "mr-[0.15rem]",
4753
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: isPositive ? "M7 14l5-5 5 5H7z" : "M7 10l5 5 5-5H7z" })
4754
- }
4755
- ),
4756
- Math.abs(changePercent).toFixed(2),
4757
- "%"
4758
- ]
4759
- }
4760
- )
4761
- ] })
4762
- ] })
4763
- ] }),
4764
- /* @__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: [
4765
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
4766
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BedDouble, { className: "mr-2 h-[18px] w-[18px] opacity-60" }),
4767
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 52, height: 14 })
4768
- ] }),
4769
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
4770
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bath, { className: "mr-2 h-[18px] w-[18px] opacity-60" }),
4771
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 56, height: 14 })
4772
- ] }),
4773
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
4774
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CarFront, { className: "mr-2 h-[18px] w-[18px] opacity-60" }),
4775
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 50, height: 14 })
4776
- ] }),
4777
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 60, height: 14 })
4778
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4779
- beds == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
4780
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BedDouble, { className: "mr-2 h-[18px] w-[18px]" }),
4781
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4782
- beds,
4783
- " Beds"
4784
- ] })
4785
- ] }),
4786
- baths == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
4787
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bath, { className: "mr-2 h-[18px] w-[18px]" }),
4788
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4789
- baths,
4790
- " Baths"
4791
- ] })
4784
+ return /* @__PURE__ */ jsxRuntime.jsx(OuterWrapper, { ref, className: cn(className), ...props, children: /* @__PURE__ */ jsxRuntime.jsxs(HeroContainer, { children: [
4785
+ /* @__PURE__ */ jsxRuntime.jsx(
4786
+ HeroImage,
4787
+ {
4788
+ src: imageUrl,
4789
+ alt: imageAlt ?? name
4790
+ }
4791
+ ),
4792
+ statusBadge ? /* @__PURE__ */ jsxRuntime.jsxs(StatusBadge, { $isLive: statusBadge.variant === "live", children: [
4793
+ statusBadge.variant === "live" ? /* @__PURE__ */ jsxRuntime.jsx(PulsingDot, {}) : null,
4794
+ statusBadge.label
4795
+ ] }) : null,
4796
+ /* @__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: [
4797
+ /* @__PURE__ */ jsxRuntime.jsx(InfoCard, { children: /* @__PURE__ */ jsxRuntime.jsxs(CardLayout, { children: [
4798
+ /* @__PURE__ */ jsxRuntime.jsx(Thumbnail, { src: imageUrl, alt: imageAlt ?? name }),
4799
+ /* @__PURE__ */ jsxRuntime.jsx(CardContent2, { children: /* @__PURE__ */ jsxRuntime.jsxs(InfoRow, { children: [
4800
+ /* @__PURE__ */ jsxRuntime.jsx(NameGroup, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column" }, children: [
4801
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.75rem", flexWrap: "wrap" }, children: [
4802
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { style: headingStyle, className: "break-words", children: name }),
4803
+ location ? /* @__PURE__ */ jsxRuntime.jsx(TypeBadge, { children: location }) : null
4792
4804
  ] }),
4793
- cars == null ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
4794
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CarFront, { className: "mr-2 h-[18px] w-[18px]" }),
4795
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4796
- cars,
4797
- " Cars"
4798
- ] })
4805
+ address ? /* @__PURE__ */ jsxRuntime.jsx(AddressText, { children: address }) : null
4806
+ ] }) }),
4807
+ /* @__PURE__ */ jsxRuntime.jsxs(PriceGroup, { children: [
4808
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 110, height: 24 }) : price == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(PriceRow, { children: [
4809
+ /* @__PURE__ */ jsxRuntime.jsx(CurrencyLabel, { children: "USD" }),
4810
+ changePercent != null ? /* @__PURE__ */ jsxRuntime.jsx(PriceArrow, { $isPositive: isPositive, children: isPositive ? "\u25B2" : "\u25BC" }) : null,
4811
+ formatPrice3(price, "")
4799
4812
  ] }),
4800
- propertyTypeLabel == null ? null : /* @__PURE__ */ jsxRuntime.jsx("div", { children: propertyTypeLabel })
4801
- ] }) })
4802
- ] }),
4803
- /* @__PURE__ */ jsxRuntime.jsxs(ActionButtons, { children: [
4804
- /* @__PURE__ */ jsxRuntime.jsx(
4805
- "button",
4806
- {
4807
- type: "button",
4808
- onClick: isTradeDisabled ? void 0 : onTrade,
4809
- 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]",
4810
- style: {
4811
- backgroundColor: isTradeInteracting ? tradeHoverColor : accentColor,
4812
- color: "black",
4813
- padding: "0.75rem 1.5rem",
4814
- borderColor: isTradeInteracting ? accentColor : "transparent",
4815
- boxShadow: isTradeInteracting ? `0 0 0 2px rgba(0,0,0,0.4), 0 0 0 4px ${accentColor}` : "none",
4816
- opacity: isTradeDisabled ? 0.5 : 1,
4817
- cursor: isTradeDisabled ? "not-allowed" : "pointer"
4818
- },
4819
- onMouseEnter: () => setTradeInteraction(true),
4820
- onMouseLeave: () => setTradeInteraction(false),
4821
- onMouseDown: () => setTradeInteraction(true),
4822
- onMouseUp: () => setTradeInteraction(false),
4823
- onFocus: () => setTradeInteraction(true),
4824
- onBlur: () => setTradeInteraction(false),
4825
- onTouchStart: () => setTradeInteraction(true),
4826
- onTouchEnd: () => setTradeInteraction(false),
4827
- disabled: isTradeDisabled,
4828
- "aria-disabled": isTradeDisabled,
4829
- children: tradeButtonLabel
4830
- }
4831
- ),
4832
- showMakeOfferButton ? /* @__PURE__ */ jsxRuntime.jsx(
4833
- "button",
4834
- {
4835
- type: "button",
4836
- onClick: isMakeOfferButtonDisabled ? void 0 : onMakeOffer,
4837
- 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]",
4838
- style: {
4839
- backgroundColor: isOfferInteracting ? accentColor : "transparent",
4840
- borderColor: accentColor,
4841
- color: isOfferInteracting ? "black" : accentColor,
4842
- padding: "0.75rem 1.5rem",
4843
- boxShadow: isOfferInteracting ? `0 0 0 2px rgba(0,0,0,0.4), 0 0 0 4px ${accentColor}` : "none",
4844
- opacity: isMakeOfferButtonDisabled ? 0.5 : 1,
4845
- cursor: isMakeOfferButtonDisabled ? "not-allowed" : "pointer"
4846
- },
4847
- onMouseEnter: () => setOfferInteraction(true),
4848
- onMouseLeave: () => setOfferInteraction(false),
4849
- onMouseDown: () => setOfferInteraction(true),
4850
- onMouseUp: () => setOfferInteraction(false),
4851
- onFocus: () => setOfferInteraction(true),
4852
- onBlur: () => setOfferInteraction(false),
4853
- onTouchStart: () => setOfferInteraction(true),
4854
- onTouchEnd: () => setOfferInteraction(false),
4855
- disabled: isMakeOfferButtonDisabled,
4856
- "aria-disabled": isMakeOfferButtonDisabled,
4857
- children: makeOfferButtonLabel
4858
- }
4859
- ) : null
4860
- ] })
4861
- ] }) })
4862
- ] }),
4863
- hasAmenities ? /* @__PURE__ */ jsxRuntime.jsx(MobileAmenities, { children: isLoading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4864
- /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenity, { children: [
4865
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BedDouble, { className: "h-4 w-4 opacity-60" }),
4866
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 40, height: 12 })
4867
- ] }),
4868
- /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenity, { children: [
4869
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bath, { className: "h-4 w-4 opacity-60" }),
4870
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 44, height: 12 })
4871
- ] }),
4872
- /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenity, { children: [
4873
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CarFront, { className: "h-4 w-4 opacity-60" }),
4874
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 42, height: 12 })
4875
- ] }),
4876
- /* @__PURE__ */ jsxRuntime.jsx(MobileAmenity, { children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 52, height: 12 }) })
4877
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4878
- beds == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenity, { children: [
4879
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BedDouble, { className: "h-4 w-4" }),
4880
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4881
- beds,
4882
- " Beds"
4883
- ] })
4884
- ] }),
4885
- baths == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenity, { children: [
4886
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bath, { className: "h-4 w-4" }),
4887
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4888
- baths,
4889
- " Baths"
4890
- ] })
4891
- ] }),
4892
- cars == null ? null : /* @__PURE__ */ jsxRuntime.jsxs(MobileAmenity, { children: [
4893
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CarFront, { className: "h-4 w-4" }),
4894
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4895
- cars,
4896
- " Cars"
4897
- ] })
4898
- ] }),
4899
- propertyTypeLabel == null ? null : /* @__PURE__ */ jsxRuntime.jsx(MobileAmenity, { children: propertyTypeLabel })
4900
- ] }) }) : null
4901
- ] });
4813
+ changePercent != null ? /* @__PURE__ */ jsxRuntime.jsxs(PriceChangeRow, { $isPositive: isPositive, children: [
4814
+ priceChange != null ? `${isPositive ? "+" : ""}${priceChange.toFixed(2)} ` : null,
4815
+ "(",
4816
+ isPositive ? "+" : "",
4817
+ Math.abs(changePercent).toFixed(2),
4818
+ "%)"
4819
+ ] }) : null
4820
+ ] })
4821
+ ] }) })
4822
+ ] }) }),
4823
+ /* @__PURE__ */ jsxRuntime.jsxs(ActionButtons, { children: [
4824
+ /* @__PURE__ */ jsxRuntime.jsx(
4825
+ "button",
4826
+ {
4827
+ type: "button",
4828
+ onClick: isTradeDisabled ? void 0 : onTrade,
4829
+ 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]",
4830
+ style: {
4831
+ backgroundColor: isTradeInteracting ? tradeHoverColor : accentColor,
4832
+ color: "black",
4833
+ padding: "0.75rem 1.5rem",
4834
+ borderColor: isTradeInteracting ? accentColor : "transparent",
4835
+ boxShadow: isTradeInteracting ? `0 0 0 2px rgba(0,0,0,0.4), 0 0 0 4px ${accentColor}` : "none",
4836
+ opacity: isTradeDisabled ? 0.5 : 1,
4837
+ cursor: isTradeDisabled ? "not-allowed" : "pointer"
4838
+ },
4839
+ onMouseEnter: () => setTradeInteraction(true),
4840
+ onMouseLeave: () => setTradeInteraction(false),
4841
+ onMouseDown: () => setTradeInteraction(true),
4842
+ onMouseUp: () => setTradeInteraction(false),
4843
+ onFocus: () => setTradeInteraction(true),
4844
+ onBlur: () => setTradeInteraction(false),
4845
+ onTouchStart: () => setTradeInteraction(true),
4846
+ onTouchEnd: () => setTradeInteraction(false),
4847
+ disabled: isTradeDisabled,
4848
+ "aria-disabled": isTradeDisabled,
4849
+ children: tradeButtonLabel
4850
+ }
4851
+ ),
4852
+ showMakeOfferButton ? /* @__PURE__ */ jsxRuntime.jsx(
4853
+ "button",
4854
+ {
4855
+ type: "button",
4856
+ onClick: isMakeOfferButtonDisabled ? void 0 : onMakeOffer,
4857
+ 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]",
4858
+ style: {
4859
+ backgroundColor: isOfferInteracting ? accentColor : "transparent",
4860
+ borderColor: accentColor,
4861
+ color: isOfferInteracting ? "black" : accentColor,
4862
+ padding: "0.75rem 1.5rem",
4863
+ boxShadow: isOfferInteracting ? `0 0 0 2px rgba(0,0,0,0.4), 0 0 0 4px ${accentColor}` : "none",
4864
+ opacity: isMakeOfferButtonDisabled ? 0.5 : 1,
4865
+ cursor: isMakeOfferButtonDisabled ? "not-allowed" : "pointer"
4866
+ },
4867
+ onMouseEnter: () => setOfferInteraction(true),
4868
+ onMouseLeave: () => setOfferInteraction(false),
4869
+ onMouseDown: () => setOfferInteraction(true),
4870
+ onMouseUp: () => setOfferInteraction(false),
4871
+ onFocus: () => setOfferInteraction(true),
4872
+ onBlur: () => setOfferInteraction(false),
4873
+ onTouchStart: () => setOfferInteraction(true),
4874
+ onTouchEnd: () => setOfferInteraction(false),
4875
+ disabled: isMakeOfferButtonDisabled,
4876
+ "aria-disabled": isMakeOfferButtonDisabled,
4877
+ children: makeOfferButtonLabel
4878
+ }
4879
+ ) : null
4880
+ ] })
4881
+ ] }) })
4882
+ ] }) });
4902
4883
  }
4903
4884
  );
4904
4885
  PropertyHeroHeader.displayName = "PropertyHeroHeader";
@@ -4941,32 +4922,6 @@ var HeroContainer = styled25__default.default.div`
4941
4922
  border-radius: 6px;
4942
4923
  }
4943
4924
  `;
4944
- var MobileAmenities = styled25__default.default.div`
4945
- display: none;
4946
- align-items: center;
4947
- justify-content: space-between;
4948
- gap: 0.5rem;
4949
- padding: 0.5rem 0.75rem;
4950
- background: rgba(8, 8, 12, 0.85);
4951
- border-radius: 12px;
4952
- border: 1px solid rgba(255, 255, 255, 0.1);
4953
- color: rgba(255, 255, 255, 0.85);
4954
- font-size: 0.85rem;
4955
-
4956
- @media (max-width: 768px) {
4957
- display: flex;
4958
- flex-wrap: wrap;
4959
- }
4960
- `;
4961
- var MobileAmenity = styled25__default.default.span`
4962
- display: inline-flex;
4963
- align-items: center;
4964
- gap: 0.35rem;
4965
- padding: 0.35rem 0.5rem;
4966
- border-radius: 999px;
4967
- background: rgba(255, 255, 255, 0.08);
4968
- font-weight: 500;
4969
- `;
4970
4925
  var HeroImage = styled25__default.default.img`
4971
4926
  width: 100%;
4972
4927
  height: 100%;
@@ -4981,15 +4936,6 @@ var HeroImage = styled25__default.default.img`
4981
4936
  transform: scale(1.0);
4982
4937
  transform-origin: center;
4983
4938
  `;
4984
- var HeroGradient = styled25__default.default.div`
4985
- position: absolute;
4986
- bottom: 0;
4987
- left: 0;
4988
- right: 0;
4989
- width: 100%;
4990
- z-index: 1;
4991
- background: linear-gradient(to top, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0) 100%);
4992
- `;
4993
4939
  var ActionButtons = styled25__default.default.div`
4994
4940
  display: flex;
4995
4941
  flex-wrap: wrap;
@@ -5005,13 +4951,42 @@ var ActionButtons = styled25__default.default.div`
5005
4951
  display: none;
5006
4952
  }
5007
4953
  `;
4954
+ var CardLayout = styled25__default.default.div`
4955
+ display: flex;
4956
+ align-items: center;
4957
+ gap: 1rem;
4958
+
4959
+ @media (max-width: 480px) {
4960
+ gap: 0.75rem;
4961
+ }
4962
+ `;
4963
+ var Thumbnail = styled25__default.default.img`
4964
+ width: 72px;
4965
+ height: 72px;
4966
+ border-radius: 8px;
4967
+ object-fit: cover;
4968
+ flex-shrink: 0;
4969
+ border: 1px solid rgba(255, 255, 255, 0.15);
4970
+
4971
+ @media (max-width: 768px) {
4972
+ width: 56px;
4973
+ height: 56px;
4974
+ border-radius: 6px;
4975
+ }
4976
+
4977
+ @media (max-width: 480px) {
4978
+ width: 48px;
4979
+ height: 48px;
4980
+ }
4981
+ `;
4982
+ var CardContent2 = styled25__default.default.div`
4983
+ min-width: 0;
4984
+ flex: 1;
4985
+ `;
5008
4986
  var InfoCard = styled25__default.default.div`
5009
- display: inline-block;
5010
- width: fit-content;
5011
- max-width: 70%;
5012
4987
  border-radius: 12px;
5013
- background: rgba(0, 0, 0, 0.12);
5014
- padding: 0.75rem 1rem;
4988
+ background: rgba(0, 0, 0, 0.15);
4989
+ padding: 1rem 1.5rem;
5015
4990
  color: #fff;
5016
4991
  backdrop-filter: blur(6px);
5017
4992
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
@@ -5019,45 +4994,92 @@ var InfoCard = styled25__default.default.div`
5019
4994
  min-width: 0;
5020
4995
 
5021
4996
  @media (max-width: 768px) {
5022
- max-width: 85%;
5023
- }
5024
-
5025
- @media (max-width: 640px) {
5026
- max-width: 92%;
4997
+ padding: 0.85rem 1.15rem;
5027
4998
  }
5028
4999
 
5029
5000
  @media (max-width: 480px) {
5030
- max-width: 95%;
5001
+ padding: 0.65rem 0.85rem;
5031
5002
  }
5032
5003
  `;
5033
- var InfoRow = styled25__default.default.div`
5034
- display: grid;
5035
- grid-template-columns: minmax(0, 1fr) auto;
5004
+ var NameGroup = styled25__default.default.div`
5005
+ display: flex;
5036
5006
  align-items: center;
5037
5007
  gap: 0.75rem;
5038
- width: 100%;
5039
-
5040
- @media (max-width: 640px) {
5041
- gap: 0.5rem;
5042
- }
5008
+ min-width: 0;
5009
+ flex-wrap: wrap;
5043
5010
  `;
5044
- var LocationText = styled25__default.default.span`
5045
- font-size: clamp(1rem, 2.6vw, 1.25rem);
5046
- color: rgba(255, 255, 255, 0.9);
5047
- font-weight: 500;
5048
- overflow: hidden;
5049
- text-overflow: ellipsis;
5011
+ var TypeBadge = styled25__default.default.span`
5012
+ display: inline-flex;
5013
+ align-items: center;
5014
+ padding: 0.2rem 0.5rem;
5015
+ border-radius: 4px;
5016
+ font-size: 0.7rem;
5017
+ font-weight: 600;
5018
+ letter-spacing: 0.03em;
5019
+ text-transform: uppercase;
5020
+ line-height: 1;
5021
+ color: #E6C87E;
5022
+ background: rgba(230, 200, 126, 0.12);
5050
5023
  white-space: nowrap;
5024
+ flex-shrink: 0;
5051
5025
  `;
5052
- var PriceBlock = styled25__default.default.span`
5026
+ var InfoRow = styled25__default.default.div`
5053
5027
  display: flex;
5054
- align-items: center;
5055
- font-size: clamp(1rem, 2.2vw, 1.25rem);
5028
+ align-items: baseline;
5029
+ justify-content: space-between;
5030
+ gap: 1rem;
5031
+ `;
5032
+ var PriceGroup = styled25__default.default.div`
5033
+ display: flex;
5034
+ flex-direction: column;
5035
+ align-items: flex-end;
5036
+ flex-shrink: 0;
5037
+ `;
5038
+ var PriceRow = styled25__default.default.span`
5039
+ display: inline-flex;
5040
+ align-items: baseline;
5041
+ font-size: clamp(1.3rem, 3vw, 1.8rem);
5056
5042
  font-weight: 600;
5057
- color: var(--color-accent, #f0b90b);
5058
- padding-left: 1rem;
5059
- border-left: 1px solid rgba(255, 255, 255, 0.25);
5060
- min-height: 1.5rem;
5043
+ color: #fff;
5044
+ font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', 'JetBrains Mono', ui-monospace, monospace;
5045
+ font-variant-numeric: tabular-nums;
5046
+ white-space: nowrap;
5047
+ flex-shrink: 0;
5048
+ `;
5049
+ var CurrencyLabel = styled25__default.default.span`
5050
+ font-size: 0.55em;
5051
+ font-weight: 500;
5052
+ color: rgba(255, 255, 255, 0.4);
5053
+ margin-right: 0.3em;
5054
+ `;
5055
+ var PriceArrow = styled25__default.default.span`
5056
+ color: ${({ $isPositive }) => $isPositive ? "#0ecb81" : "#f6465d"};
5057
+ font-size: 0.65em;
5058
+ margin: 0 0.1em;
5059
+ `;
5060
+ var AddressText = styled25__default.default.p`
5061
+ font-size: 1.1rem;
5062
+ color: rgba(255, 255, 255, 0.7);
5063
+ font-weight: 400;
5064
+ margin: 0.1rem 0 0;
5065
+
5066
+ @media (max-width: 768px) {
5067
+ font-size: 1rem;
5068
+ }
5069
+
5070
+ @media (max-width: 480px) {
5071
+ font-size: 0.9rem;
5072
+ }
5073
+ `;
5074
+ var PriceChangeRow = styled25__default.default.span`
5075
+ display: inline-flex;
5076
+ align-items: center;
5077
+ white-space: nowrap;
5078
+ flex-shrink: 0;
5079
+ font-size: 0.85rem;
5080
+ font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', 'JetBrains Mono', ui-monospace, monospace;
5081
+ font-variant-numeric: tabular-nums;
5082
+ color: ${({ $isPositive }) => $isPositive ? "#0ecb81" : "#f6465d"};
5061
5083
  `;
5062
5084
  var StatusBadge = styled25__default.default.div`
5063
5085
  position: absolute;
@@ -5134,13 +5156,45 @@ var Header = ({
5134
5156
  onProfileNavigate: _onProfileNavigate,
5135
5157
  onOrdersNavigate: _onOrdersNavigate,
5136
5158
  onWalletNavigate: _onWalletNavigate,
5137
- showTradeTab = true
5159
+ showTradeTab = true,
5160
+ portfolioSummary
5138
5161
  }) => {
5139
5162
  const [isUserMenuOpen, setIsUserMenuOpen] = React5.useState(false);
5140
5163
  const [isMobileMenuOpen, setIsMobileMenuOpen] = React5.useState(false);
5141
5164
  const [isMoreMenuOpen, setIsMoreMenuOpen] = React5.useState(false);
5142
5165
  const [showLoginPopup, setShowLoginPopup] = React5.useState(false);
5143
5166
  const [loginPopupInitialView, setLoginPopupInitialView] = React5.useState(void 0);
5167
+ const [isPortfolioBarVisible, setIsPortfolioBarVisible] = React5.useState(() => {
5168
+ if (typeof localStorage === "undefined") return false;
5169
+ return localStorage.getItem("portfolioBarVisible") !== "false";
5170
+ });
5171
+ const portfolioPillRef = React5.useRef(null);
5172
+ const [portfolioArrowLeft, setPortfolioArrowLeft] = React5.useState(null);
5173
+ const togglePortfolioBar = React5.useCallback(() => {
5174
+ setIsPortfolioBarVisible((prev) => {
5175
+ const next = !prev;
5176
+ try {
5177
+ localStorage.setItem("portfolioBarVisible", String(next));
5178
+ } catch {
5179
+ }
5180
+ return next;
5181
+ });
5182
+ }, []);
5183
+ const updatePortfolioArrow = React5.useCallback(() => {
5184
+ const eye = document.getElementById("portfolio-eye-toggle");
5185
+ const pill = portfolioPillRef.current;
5186
+ if (!eye || !pill) return;
5187
+ const eyeRect = eye.getBoundingClientRect();
5188
+ const pillRect = pill.getBoundingClientRect();
5189
+ const offset = eyeRect.left + eyeRect.width / 2 - pillRect.left - 7;
5190
+ setPortfolioArrowLeft(offset);
5191
+ }, []);
5192
+ React5.useEffect(() => {
5193
+ if (!isPortfolioBarVisible || !portfolioSummary) return;
5194
+ updatePortfolioArrow();
5195
+ window.addEventListener("resize", updatePortfolioArrow);
5196
+ return () => window.removeEventListener("resize", updatePortfolioArrow);
5197
+ }, [isPortfolioBarVisible, portfolioSummary, updatePortfolioArrow]);
5144
5198
  React5.useEffect(() => {
5145
5199
  if (typeof window === "undefined") return;
5146
5200
  const ua = navigator.userAgent;
@@ -5518,6 +5572,17 @@ var Header = ({
5518
5572
  }
5519
5573
  ),
5520
5574
  isAuthenticated ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [
5575
+ portfolioSummary && /* @__PURE__ */ jsxRuntime.jsx(
5576
+ PortfolioEyeButton,
5577
+ {
5578
+ id: "portfolio-eye-toggle",
5579
+ type: "button",
5580
+ onClick: togglePortfolioBar,
5581
+ $active: isPortfolioBarVisible,
5582
+ title: isPortfolioBarVisible ? "Hide portfolio" : "Show portfolio",
5583
+ 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" }) })
5584
+ }
5585
+ ),
5521
5586
  /* @__PURE__ */ jsxRuntime.jsxs(UserMenu, { children: [
5522
5587
  /* @__PURE__ */ jsxRuntime.jsxs(
5523
5588
  UserButton,
@@ -5589,7 +5654,52 @@ var Header = ({
5589
5654
  ] })
5590
5655
  ] }),
5591
5656
  /* @__PURE__ */ jsxRuntime.jsx(HeaderSpacer, {}),
5592
- LoginPopupComponent && showLoginPopup && /* @__PURE__ */ jsxRuntime.jsx(
5657
+ isAuthenticated && portfolioSummary && isPortfolioBarVisible && (() => {
5658
+ const fmt = (n) => n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
5659
+ const isPLPositive = portfolioSummary.pnl >= 0;
5660
+ return /* @__PURE__ */ jsxRuntime.jsx(PortfolioBarContainer, { children: /* @__PURE__ */ jsxRuntime.jsxs(PortfolioBarPill, { ref: portfolioPillRef, children: [
5661
+ portfolioArrowLeft !== null && /* @__PURE__ */ jsxRuntime.jsx(PortfolioBarArrow, { style: { left: `${portfolioArrowLeft}px` } }),
5662
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetric, { children: [
5663
+ /* @__PURE__ */ jsxRuntime.jsx(PBMetricLabel, { children: "Holdings" }),
5664
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetricValue, { children: [
5665
+ "$",
5666
+ fmt(portfolioSummary.holdings)
5667
+ ] })
5668
+ ] }),
5669
+ /* @__PURE__ */ jsxRuntime.jsx(PBOperator, { children: "+" }),
5670
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetric, { children: [
5671
+ /* @__PURE__ */ jsxRuntime.jsx(PBMetricLabel, { children: "Cash" }),
5672
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetricValue, { children: [
5673
+ "$",
5674
+ fmt(portfolioSummary.cash)
5675
+ ] })
5676
+ ] }),
5677
+ /* @__PURE__ */ jsxRuntime.jsx(PBOperator, { children: "=" }),
5678
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetric, { children: [
5679
+ /* @__PURE__ */ jsxRuntime.jsx(PBMetricLabel, { children: "Portfolio" }),
5680
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetricValue, { style: { color: "#D4AF37", fontWeight: 700 }, children: [
5681
+ "$",
5682
+ fmt(portfolioSummary.portfolioValue)
5683
+ ] })
5684
+ ] }),
5685
+ /* @__PURE__ */ jsxRuntime.jsx(PBDot, {}),
5686
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetric, { children: [
5687
+ /* @__PURE__ */ jsxRuntime.jsx(PBMetricLabel, { children: "P&L" }),
5688
+ /* @__PURE__ */ jsxRuntime.jsxs(PBMetricValue, { $positive: isPLPositive, $negative: !isPLPositive, children: [
5689
+ isPLPositive ? "+" : "",
5690
+ "$",
5691
+ fmt(Math.abs(portfolioSummary.pnl)),
5692
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "0.6rem", marginLeft: "2px", opacity: 0.7 }, children: [
5693
+ "(",
5694
+ isPLPositive ? "+" : "",
5695
+ portfolioSummary.pnlPercent.toFixed(2),
5696
+ "%)"
5697
+ ] })
5698
+ ] })
5699
+ ] })
5700
+ ] }) });
5701
+ })(),
5702
+ LoginPopupComponent && showLoginPopup && /* @__PURE__ */ jsxRuntime.jsx(
5593
5703
  LoginPopupComponent,
5594
5704
  {
5595
5705
  onClose: handleLoginPopupClose,
@@ -5674,8 +5784,19 @@ var HeaderContainer = styled25__default.default.header`
5674
5784
  box-sizing: border-box;
5675
5785
 
5676
5786
  @media (max-width: 768px) {
5677
- padding: 0 1rem;
5678
- padding-top: max(env(safe-area-inset-top, 0px), var(--telegram-safe-top, 0px));
5787
+ top: 0.5rem;
5788
+ left: 0.75rem;
5789
+ right: 0.75rem;
5790
+ width: calc(100% - 1.5rem);
5791
+ height: 46px;
5792
+ min-height: 46px;
5793
+ padding: 0 0.75rem;
5794
+ border-radius: 12px;
5795
+ background-color: rgba(13, 17, 23, 0.92);
5796
+ backdrop-filter: blur(12px);
5797
+ border: 1px solid rgba(255, 255, 255, 0.08);
5798
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08);
5799
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
5679
5800
  }
5680
5801
  `;
5681
5802
  var HeaderSpacer = styled25__default.default.div`
@@ -5683,6 +5804,10 @@ var HeaderSpacer = styled25__default.default.div`
5683
5804
  min-height: 56px;
5684
5805
  min-height: calc(56px + max(env(safe-area-inset-top, 0px), var(--telegram-safe-top, 0px)));
5685
5806
  flex-shrink: 0;
5807
+
5808
+ @media (max-width: 768px) {
5809
+ min-height: calc(46px + 0.5rem);
5810
+ }
5686
5811
  `;
5687
5812
  var Logo = styled25__default.default.div`
5688
5813
  display: flex;
@@ -6016,6 +6141,151 @@ var MobileNavItem = styled25__default.default.div`
6016
6141
  padding-left: 24px;
6017
6142
  }
6018
6143
  `;
6144
+ var pbShimmer = styled25.keyframes`
6145
+ 0% { background-position: -200% 0; }
6146
+ 100% { background-position: 200% 0; }
6147
+ `;
6148
+ var PortfolioEyeButton = styled25__default.default.button`
6149
+ background: ${(p) => p.$active ? "rgba(212, 175, 55, 0.15)" : "transparent"};
6150
+ border: none;
6151
+ border-radius: 6px;
6152
+ cursor: pointer;
6153
+ padding: 6px;
6154
+ display: flex;
6155
+ align-items: center;
6156
+ justify-content: center;
6157
+ color: ${(p) => p.$active ? "#D4AF37" : "rgba(255,255,255,0.5)"};
6158
+ transition: all 0.2s ease;
6159
+ margin-right: 4px;
6160
+
6161
+ &:hover {
6162
+ background: rgba(212, 175, 55, 0.2);
6163
+ color: #D4AF37;
6164
+ }
6165
+
6166
+ @media (max-width: 768px) {
6167
+ padding: 4px;
6168
+ margin-right: 2px;
6169
+ }
6170
+ `;
6171
+ var PortfolioBarContainer = styled25__default.default.div`
6172
+ position: fixed;
6173
+ top: 56px;
6174
+ top: calc(56px + max(env(safe-area-inset-top, 0px), var(--telegram-safe-top, 0px)));
6175
+ left: 0;
6176
+ right: 0;
6177
+ z-index: 999;
6178
+ display: flex;
6179
+ justify-content: flex-end;
6180
+ align-items: flex-start;
6181
+ padding: 0 5%;
6182
+ pointer-events: none;
6183
+ overflow: visible;
6184
+
6185
+ &::before {
6186
+ content: '';
6187
+ position: absolute;
6188
+ top: 0;
6189
+ left: 40%;
6190
+ right: 0;
6191
+ height: 2px;
6192
+ background: linear-gradient(90deg, transparent 0%, rgba(212, 175, 55, 0.25) 100%);
6193
+ pointer-events: none;
6194
+ }
6195
+
6196
+ @media (max-width: 768px) {
6197
+ top: calc(46px + 0.5rem);
6198
+ padding: 0 0.75rem;
6199
+ justify-content: center;
6200
+
6201
+ &::before {
6202
+ left: 0;
6203
+ right: 0;
6204
+ background: linear-gradient(90deg, transparent 0%, rgba(212, 175, 55, 0.4) 30%, rgba(212, 175, 55, 0.4) 70%, transparent 100%);
6205
+ }
6206
+ }
6207
+ `;
6208
+ var PortfolioBarPill = styled25__default.default.div`
6209
+ pointer-events: auto;
6210
+ display: flex;
6211
+ align-items: center;
6212
+ gap: 1.25rem;
6213
+ padding: 0.5rem 1.5rem;
6214
+ border-radius: 0 0 20px 20px;
6215
+ background: linear-gradient(135deg, rgba(24, 26, 34, 0.98) 0%, rgba(32, 34, 42, 0.97) 100%);
6216
+ backdrop-filter: blur(16px);
6217
+ border: 1px solid rgba(212, 175, 55, 0.25);
6218
+ border-top: none;
6219
+ box-shadow:
6220
+ 0 4px 16px rgba(0, 0, 0, 0.3),
6221
+ 0 0 0 1px rgba(255, 255, 255, 0.03) inset,
6222
+ 0 1px 0 rgba(212, 175, 55, 0.06) inset;
6223
+ position: relative;
6224
+ overflow: visible;
6225
+
6226
+ &::before {
6227
+ content: '';
6228
+ position: absolute;
6229
+ top: 0;
6230
+ left: 0;
6231
+ right: 0;
6232
+ height: 1px;
6233
+ background: linear-gradient(90deg, transparent, rgba(212, 175, 55, 0.3), transparent);
6234
+ background-size: 200% 100%;
6235
+ animation: ${pbShimmer} 4s linear infinite;
6236
+ }
6237
+
6238
+ @media (max-width: 768px) {
6239
+ gap: 0.75rem;
6240
+ padding: 0.4rem 1rem;
6241
+ border-radius: 0 0 16px 16px;
6242
+ }
6243
+ `;
6244
+ var PortfolioBarArrow = styled25__default.default.div`
6245
+ position: absolute;
6246
+ top: -7px;
6247
+ width: 14px;
6248
+ height: 14px;
6249
+ background: linear-gradient(135deg, rgba(26, 28, 36, 1) 0%, rgba(30, 32, 40, 1) 100%);
6250
+ border-left: 1px solid rgba(212, 175, 55, 0.3);
6251
+ border-top: 1px solid rgba(212, 175, 55, 0.3);
6252
+ transform: rotate(45deg);
6253
+ box-shadow: -2px -2px 6px rgba(0, 0, 0, 0.25);
6254
+ pointer-events: none;
6255
+ `;
6256
+ var PBMetric = styled25__default.default.div`
6257
+ display: flex;
6258
+ flex-direction: column;
6259
+ align-items: center;
6260
+ gap: 1px;
6261
+ white-space: nowrap;
6262
+ `;
6263
+ var PBMetricLabel = styled25__default.default.span`
6264
+ font-size: 0.55rem;
6265
+ color: rgba(255, 255, 255, 0.6);
6266
+ text-transform: uppercase;
6267
+ letter-spacing: 0.5px;
6268
+ font-weight: 500;
6269
+ `;
6270
+ var PBMetricValue = styled25__default.default.span`
6271
+ font-size: 0.75rem;
6272
+ font-weight: 600;
6273
+ color: ${(p) => p.$positive ? "#0ecb81" : p.$negative ? "#f6465d" : "#eaecef"};
6274
+ font-variant-numeric: tabular-nums;
6275
+ `;
6276
+ var PBDot = styled25__default.default.div`
6277
+ width: 3px;
6278
+ height: 3px;
6279
+ border-radius: 50%;
6280
+ background: rgba(212, 175, 55, 0.25);
6281
+ flex-shrink: 0;
6282
+ `;
6283
+ var PBOperator = styled25__default.default.span`
6284
+ font-size: 0.7rem;
6285
+ font-weight: 500;
6286
+ color: rgba(255, 255, 255, 0.35);
6287
+ flex-shrink: 0;
6288
+ `;
6019
6289
  var PropertySubheader = React5__namespace.forwardRef(
6020
6290
  ({ className, tabs, activeTabId, onTabChange, actions, ...props }, ref) => {
6021
6291
  const tabsContainerRef = React5__namespace.useRef(null);
@@ -6041,291 +6311,106 @@ var PropertySubheader = React5__namespace.forwardRef(
6041
6311
  {
6042
6312
  ref,
6043
6313
  className: cn(
6044
- "w-full font-normal",
6045
- "flex flex-col-reverse gap-3",
6046
- "md:flex-row md:items-center md:justify-between",
6047
- className
6048
- ),
6049
- ...props,
6050
- children: [
6051
- /* @__PURE__ */ jsxRuntime.jsx(
6052
- "div",
6053
- {
6054
- ref: tabsContainerRef,
6055
- className: cn(
6056
- "flex items-center border-b border-white/10",
6057
- "overflow-x-auto md:overflow-visible",
6058
- "[-webkit-overflow-scrolling:touch]",
6059
- "[scroll-behavior:smooth]",
6060
- "[touch-action:pan-x]",
6061
- "md:border-b-0"
6062
- ),
6063
- style: { WebkitTapHighlightColor: "transparent" },
6064
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-max", children: tabs.map((tab) => {
6065
- const active = tab.id === activeTabId;
6066
- return /* @__PURE__ */ jsxRuntime.jsxs(
6067
- "button",
6068
- {
6069
- type: "button",
6070
- onClick: () => onTabChange?.(tab.id),
6071
- className: cn(
6072
- "relative whitespace-nowrap",
6073
- "px-6 py-4",
6074
- "font-normal",
6075
- "transition-colors",
6076
- "max-[768px]:px-[1.2rem] max-[768px]:py-[0.8rem]",
6077
- "max-[480px]:px-4 max-[480px]:py-[0.7rem] max-[480px]:text-[0.9rem]",
6078
- active ? "font-semibold text-[var(--color-accent,#e6c87e)]" : "text-white/60 hover:text-white"
6079
- ),
6080
- style: {
6081
- borderBottom: active ? "2px solid var(--color-accent, #e6c87e)" : "2px solid transparent",
6082
- minWidth: "80px",
6083
- touchAction: "manipulation"
6084
- },
6085
- children: [
6086
- tab.label,
6087
- tab.hasNotification ? /* @__PURE__ */ jsxRuntime.jsx(
6088
- "span",
6089
- {
6090
- className: "absolute right-[10px] top-[10px] h-2 w-2 rounded-full animate-pulse",
6091
- style: {
6092
- backgroundColor: tab.notificationColor ?? "#f6465d",
6093
- boxShadow: "0 0 0 0 rgba(246, 70, 93, 0.7)"
6094
- }
6095
- }
6096
- ) : null
6097
- ]
6098
- },
6099
- tab.id
6100
- );
6101
- }) })
6102
- }
6103
- ),
6104
- actions != null && actions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
6105
- "div",
6106
- {
6107
- className: cn(
6108
- "flex items-center gap-[10px]",
6109
- "overflow-x-auto md:overflow-visible",
6110
- "[scrollbar-width:none]",
6111
- "md:justify-end",
6112
- "max-[768px]:w-full max-[768px]:justify-center max-[768px]:pb-2 max-[768px]:mb-4"
6113
- ),
6114
- children: actions.map((action) => /* @__PURE__ */ jsxRuntime.jsxs(
6115
- "button",
6116
- {
6117
- type: "button",
6118
- onClick: action.onClick,
6119
- className: cn(
6120
- "flex shrink-0 items-center gap-[5px] whitespace-nowrap",
6121
- "rounded",
6122
- "border border-white/10",
6123
- "bg-transparent",
6124
- "px-3 py-1.5 text-[14px] font-normal",
6125
- "transition-all",
6126
- "max-[768px]:px-2.5 max-[768px]:py-[5px] max-[768px]:text-[13px]",
6127
- "hover:bg-white/5 hover:border-[var(--color-accent,#e6c87e)] hover:text-[var(--color-accent,#e6c87e)]"
6128
- ),
6129
- children: [
6130
- action.icon,
6131
- action.label
6132
- ]
6133
- },
6134
- action.id
6135
- ))
6136
- }
6137
- ) : null
6138
- ]
6139
- }
6140
- );
6141
- }
6142
- );
6143
- PropertySubheader.displayName = "PropertySubheader";
6144
- var slideIn = styled25.keyframes`
6145
- from { transform: translateX(110%); opacity: 0; }
6146
- to { transform: translateX(0); opacity: 1; }
6147
- `;
6148
- var slideOut = styled25.keyframes`
6149
- from { transform: translateX(0); opacity: 1; }
6150
- to { transform: translateX(110%); opacity: 0; }
6151
- `;
6152
- var progressShrink = styled25.keyframes`
6153
- from { width: 100%; }
6154
- to { width: 0%; }
6155
- `;
6156
- var VARIANT_COLORS = {
6157
- success: { accent: "#0ecb81", icon: "\u2713" },
6158
- error: { accent: "#f6465d", icon: "\u2715" },
6159
- info: { accent: "#E6C656", icon: "\u2139" },
6160
- pending: { accent: "#7EB3E6", icon: "\u25CC" }
6161
- };
6162
- var Wrapper = styled25__default.default.div`
6163
- position: relative;
6164
- display: flex;
6165
- flex-direction: column;
6166
- gap: 0;
6167
- width: 340px;
6168
- background: #0d0f1a;
6169
- border: 1px solid rgba(255, 255, 255, 0.08);
6170
- border-radius: 10px;
6171
- overflow: hidden;
6172
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255,255,255,0.04);
6173
- 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`};
6174
- pointer-events: all;
6175
- `;
6176
- var Body = styled25__default.default.div`
6177
- display: flex;
6178
- align-items: flex-start;
6179
- gap: 12px;
6180
- padding: 14px 16px 12px;
6181
- `;
6182
- var IconDot = styled25__default.default.div`
6183
- flex-shrink: 0;
6184
- width: 28px;
6185
- height: 28px;
6186
- border-radius: 50%;
6187
- background: ${({ $color }) => $color}1a;
6188
- border: 1px solid ${({ $color }) => $color}55;
6189
- display: flex;
6190
- align-items: center;
6191
- justify-content: center;
6192
- font-size: 0.75rem;
6193
- font-weight: 700;
6194
- color: ${({ $color }) => $color};
6195
- margin-top: 1px;
6196
- `;
6197
- var Content = styled25__default.default.div`
6198
- flex: 1;
6199
- min-width: 0;
6200
- `;
6201
- var Title = styled25__default.default.p`
6202
- margin: 0 0 2px;
6203
- font-size: 0.8rem;
6204
- font-weight: 600;
6205
- color: #fff;
6206
- letter-spacing: 0.01em;
6207
- `;
6208
- var Amount = styled25__default.default.p`
6209
- margin: 0 0 6px;
6210
- font-size: 1.05rem;
6211
- font-weight: 700;
6212
- color: #E6C656;
6213
- letter-spacing: -0.01em;
6214
- `;
6215
- var TxRow = styled25__default.default.a`
6216
- display: inline-flex;
6217
- align-items: center;
6218
- gap: 5px;
6219
- font-family: 'IBM Plex Mono', 'Space Mono', monospace;
6220
- font-size: 0.68rem;
6221
- color: rgba(255, 255, 255, 0.4);
6222
- text-decoration: none;
6223
- transition: color 0.15s;
6224
- &:hover {
6225
- color: #7EB3E6;
6226
- }
6227
- `;
6228
- var TxArrow = styled25__default.default.span`
6229
- font-size: 0.6rem;
6230
- opacity: 0.6;
6231
- `;
6232
- var CloseBtn = styled25__default.default.button`
6233
- flex-shrink: 0;
6234
- background: none;
6235
- border: none;
6236
- padding: 2px 4px;
6237
- cursor: pointer;
6238
- color: rgba(255, 255, 255, 0.25);
6239
- font-size: 0.9rem;
6240
- line-height: 1;
6241
- transition: color 0.15s;
6242
- &:hover { color: rgba(255, 255, 255, 0.7); }
6243
- `;
6244
- var ProgressBar = styled25__default.default.div`
6245
- height: 2px;
6246
- background: rgba(255, 255, 255, 0.06);
6247
- position: relative;
6248
- &::after {
6249
- content: '';
6250
- position: absolute;
6251
- left: 0;
6252
- top: 0;
6253
- height: 100%;
6254
- background: ${({ $color }) => $color};
6255
- animation: ${styled25.css`${progressShrink} ${({ $duration }) => $duration}ms linear forwards`};
6314
+ "w-full font-normal",
6315
+ "flex flex-col-reverse gap-3",
6316
+ "md:flex-row md:items-center md:justify-between",
6317
+ className
6318
+ ),
6319
+ ...props,
6320
+ children: [
6321
+ /* @__PURE__ */ jsxRuntime.jsx(
6322
+ "div",
6323
+ {
6324
+ ref: tabsContainerRef,
6325
+ className: cn(
6326
+ "flex items-center border-b border-white/10",
6327
+ "overflow-x-auto md:overflow-visible",
6328
+ "[-webkit-overflow-scrolling:touch]",
6329
+ "[scroll-behavior:smooth]",
6330
+ "[touch-action:pan-x]",
6331
+ "md:border-b-0"
6332
+ ),
6333
+ style: { WebkitTapHighlightColor: "transparent" },
6334
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-max", children: tabs.map((tab) => {
6335
+ const active = tab.id === activeTabId;
6336
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6337
+ "button",
6338
+ {
6339
+ type: "button",
6340
+ onClick: () => onTabChange?.(tab.id),
6341
+ className: cn(
6342
+ "relative whitespace-nowrap",
6343
+ "px-6 py-4",
6344
+ "font-normal",
6345
+ "transition-colors",
6346
+ "max-[768px]:px-[1.2rem] max-[768px]:py-[0.8rem]",
6347
+ "max-[480px]:px-4 max-[480px]:py-[0.7rem] max-[480px]:text-[0.9rem]",
6348
+ active ? "font-semibold text-[var(--color-accent,#e6c87e)]" : "text-white/60 hover:text-white"
6349
+ ),
6350
+ style: {
6351
+ borderBottom: active ? "2px solid var(--color-accent, #e6c87e)" : "2px solid transparent",
6352
+ minWidth: "80px",
6353
+ touchAction: "manipulation"
6354
+ },
6355
+ children: [
6356
+ tab.label,
6357
+ tab.hasNotification ? /* @__PURE__ */ jsxRuntime.jsx(
6358
+ "span",
6359
+ {
6360
+ className: "absolute right-[10px] top-[10px] h-2 w-2 rounded-full animate-pulse",
6361
+ style: {
6362
+ backgroundColor: tab.notificationColor ?? "#f6465d",
6363
+ boxShadow: "0 0 0 0 rgba(246, 70, 93, 0.7)"
6364
+ }
6365
+ }
6366
+ ) : null
6367
+ ]
6368
+ },
6369
+ tab.id
6370
+ );
6371
+ }) })
6372
+ }
6373
+ ),
6374
+ actions != null && actions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
6375
+ "div",
6376
+ {
6377
+ className: cn(
6378
+ "flex items-center gap-[10px]",
6379
+ "overflow-x-auto md:overflow-visible",
6380
+ "[scrollbar-width:none]",
6381
+ "md:justify-end",
6382
+ "max-[768px]:w-full max-[768px]:justify-center max-[768px]:pb-2 max-[768px]:mb-4"
6383
+ ),
6384
+ children: actions.map((action) => /* @__PURE__ */ jsxRuntime.jsxs(
6385
+ "button",
6386
+ {
6387
+ type: "button",
6388
+ onClick: action.onClick,
6389
+ className: cn(
6390
+ "flex shrink-0 items-center gap-[5px] whitespace-nowrap",
6391
+ "rounded",
6392
+ "border border-white/10",
6393
+ "bg-transparent",
6394
+ "px-3 py-1.5 text-[14px] font-normal",
6395
+ "transition-all",
6396
+ "max-[768px]:px-2.5 max-[768px]:py-[5px] max-[768px]:text-[13px]",
6397
+ "hover:bg-white/5 hover:border-[var(--color-accent,#e6c87e)] hover:text-[var(--color-accent,#e6c87e)]"
6398
+ ),
6399
+ children: [
6400
+ action.icon,
6401
+ action.label
6402
+ ]
6403
+ },
6404
+ action.id
6405
+ ))
6406
+ }
6407
+ ) : null
6408
+ ]
6409
+ }
6410
+ );
6256
6411
  }
6257
- `;
6258
- var Container = styled25__default.default.div`
6259
- position: fixed;
6260
- bottom: 24px;
6261
- right: 24px;
6262
- z-index: 9999;
6263
- display: flex;
6264
- flex-direction: column-reverse;
6265
- gap: 10px;
6266
- pointer-events: none;
6267
- `;
6268
- var DEFAULT_EXPLORER = "https://sepolia.basescan.org/tx/";
6269
- function truncateHash(hash) {
6270
- return `${hash.slice(0, 6)}\u2026${hash.slice(-4)}`;
6271
- }
6272
- function ToastItem({ toast, onDismiss }) {
6273
- const [exiting, setExiting] = React5.useState(false);
6274
- const timerRef = React5.useRef(null);
6275
- const dismiss = React5.useCallback(() => {
6276
- setExiting(true);
6277
- setTimeout(() => onDismiss(toast.id), 280);
6278
- }, [onDismiss, toast.id]);
6279
- React5.useEffect(() => {
6280
- const duration2 = toast.duration ?? 6e3;
6281
- if (duration2 > 0) {
6282
- timerRef.current = setTimeout(dismiss, duration2);
6283
- }
6284
- return () => {
6285
- if (timerRef.current) clearTimeout(timerRef.current);
6286
- };
6287
- }, [dismiss, toast.duration]);
6288
- const { accent, icon } = VARIANT_COLORS[toast.variant];
6289
- const duration = toast.duration ?? 6e3;
6290
- const explorerBase = toast.explorerUrl ?? DEFAULT_EXPLORER;
6291
- const txUrl = toast.txHash ? `${explorerBase}${toast.txHash}` : void 0;
6292
- return /* @__PURE__ */ jsxRuntime.jsxs(Wrapper, { $exiting: exiting, children: [
6293
- /* @__PURE__ */ jsxRuntime.jsxs(Body, { children: [
6294
- /* @__PURE__ */ jsxRuntime.jsx(IconDot, { $color: accent, children: icon }),
6295
- /* @__PURE__ */ jsxRuntime.jsxs(Content, { children: [
6296
- /* @__PURE__ */ jsxRuntime.jsx(Title, { children: toast.title }),
6297
- toast.amount && /* @__PURE__ */ jsxRuntime.jsx(Amount, { children: toast.amount }),
6298
- toast.txHash && txUrl && /* @__PURE__ */ jsxRuntime.jsxs(TxRow, { href: txUrl, target: "_blank", rel: "noopener noreferrer", children: [
6299
- truncateHash(toast.txHash),
6300
- /* @__PURE__ */ jsxRuntime.jsx(TxArrow, { children: "\u2197" })
6301
- ] })
6302
- ] }),
6303
- /* @__PURE__ */ jsxRuntime.jsx(CloseBtn, { type: "button", onClick: dismiss, "aria-label": "Dismiss", children: "\u2715" })
6304
- ] }),
6305
- duration > 0 && /* @__PURE__ */ jsxRuntime.jsx(ProgressBar, { $color: accent, $duration: duration })
6306
- ] });
6307
- }
6308
- var ToastContext = React5.createContext(null);
6309
- function ToastProvider({ children }) {
6310
- const [toasts, setToasts] = React5.useState([]);
6311
- const addToast = React5.useCallback((data) => {
6312
- const id = `toast-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
6313
- setToasts((prev) => [...prev, { ...data, id }]);
6314
- return id;
6315
- }, []);
6316
- const dismiss = React5.useCallback((id) => {
6317
- setToasts((prev) => prev.filter((t) => t.id !== id));
6318
- }, []);
6319
- return /* @__PURE__ */ jsxRuntime.jsxs(ToastContext.Provider, { value: { toast: addToast, dismiss }, children: [
6320
- children,
6321
- /* @__PURE__ */ jsxRuntime.jsx(Container, { children: toasts.map((t) => /* @__PURE__ */ jsxRuntime.jsx(ToastItem, { toast: t, onDismiss: dismiss }, t.id)) })
6322
- ] });
6323
- }
6324
- function useToast() {
6325
- const ctx = React5.useContext(ToastContext);
6326
- if (!ctx) throw new Error("useToast must be used within a ToastProvider");
6327
- return ctx;
6328
- }
6412
+ );
6413
+ PropertySubheader.displayName = "PropertySubheader";
6329
6414
  var DEFAULT_LOGO_SRC = Loaf_logo_Banner_default;
6330
6415
  var DEFAULT_LOGO_ALT = "Loaf";
6331
6416
  var OTP_INPUT_LENGTH = 6;
@@ -6353,7 +6438,6 @@ var LoginPopup = ({
6353
6438
  const [error, setError] = React5.useState("");
6354
6439
  const [loading, setLoading] = React5.useState(false);
6355
6440
  const [isSignUp, setIsSignUp] = React5.useState(false);
6356
- const { toast } = useToast();
6357
6441
  const [fundingAmount] = React5.useState("");
6358
6442
  const [kycLoading, setKycLoading] = React5.useState(false);
6359
6443
  const [showKycWidget, setShowKycWidget] = React5.useState(false);
@@ -6367,11 +6451,6 @@ var LoginPopup = ({
6367
6451
  setView(initialView);
6368
6452
  }
6369
6453
  }, [initialView]);
6370
- React5.useEffect(() => {
6371
- if (view === "kyc" && renderKycWidget) {
6372
- setShowKycWidget(true);
6373
- }
6374
- }, [view, renderKycWidget]);
6375
6454
  React5.useEffect(() => {
6376
6455
  if (!transakWidgetUrl) return;
6377
6456
  const handleTransakMessage = (event) => {
@@ -6574,19 +6653,10 @@ var LoginPopup = ({
6574
6653
  };
6575
6654
  const handleKycWidgetResult = (result) => {
6576
6655
  setShowKycWidget(false);
6577
- onClose();
6578
6656
  if (result.passed) {
6579
- toast({
6580
- variant: "success",
6581
- title: "KYC submitted \u2014 pending review",
6582
- amount: "Your documents are under review. Please check back in a few minutes."
6583
- });
6657
+ setView("kyc-success");
6584
6658
  } else {
6585
- toast({
6586
- variant: "error",
6587
- title: "Verification unsuccessful",
6588
- amount: "Your identity check didn't pass. Please contact support if you believe this is an error."
6589
- });
6659
+ setView("kyc-failed");
6590
6660
  }
6591
6661
  };
6592
6662
  const handleKycWidgetClose = () => {
@@ -6677,7 +6747,7 @@ var LoginPopup = ({
6677
6747
  if (view === "main") {
6678
6748
  return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
6679
6749
  /* @__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" }) }) }),
6680
- /* @__PURE__ */ jsxRuntime.jsxs(Title2, { children: [
6750
+ /* @__PURE__ */ jsxRuntime.jsxs(Title, { children: [
6681
6751
  /* @__PURE__ */ jsxRuntime.jsx(LogoContainer3, { children: /* @__PURE__ */ jsxRuntime.jsx(LogoImage, { src: logoSrc, alt: logoAlt }) }),
6682
6752
  "Welcome to Loaf"
6683
6753
  ] }),
@@ -6738,7 +6808,7 @@ var LoginPopup = ({
6738
6808
  /* @__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
6809
  "Back"
6740
6810
  ] }),
6741
- /* @__PURE__ */ jsxRuntime.jsxs(Title2, { children: [
6811
+ /* @__PURE__ */ jsxRuntime.jsxs(Title, { children: [
6742
6812
  /* @__PURE__ */ jsxRuntime.jsx(LogoContainer3, { children: /* @__PURE__ */ jsxRuntime.jsx(LogoImage, { src: logoSrc, alt: logoAlt }) }),
6743
6813
  isSignUp ? "Sign up with Email" : "Sign in with Email"
6744
6814
  ] }),
@@ -6777,7 +6847,7 @@ var LoginPopup = ({
6777
6847
  /* @__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" }) }),
6778
6848
  "Back"
6779
6849
  ] }),
6780
- /* @__PURE__ */ jsxRuntime.jsxs(Title2, { children: [
6850
+ /* @__PURE__ */ jsxRuntime.jsxs(Title, { children: [
6781
6851
  /* @__PURE__ */ jsxRuntime.jsx(LogoContainer3, { children: /* @__PURE__ */ jsxRuntime.jsx(LogoImage, { src: logoSrc, alt: logoAlt }) }),
6782
6852
  "Enter Verification Code"
6783
6853
  ] }),
@@ -6893,7 +6963,7 @@ var LoginPopup = ({
6893
6963
  ] }) });
6894
6964
  }
6895
6965
  if (view === "funding") {
6896
- return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(
6966
+ return /* @__PURE__ */ jsxRuntime.jsx(Overlay2, { children: /* @__PURE__ */ jsxRuntime.jsxs(
6897
6967
  FundingPopupContainer,
6898
6968
  {
6899
6969
  onClick: (event) => event.stopPropagation(),
@@ -6963,6 +7033,16 @@ var Overlay2 = styled25__default.default.div`
6963
7033
  justify-content: center;
6964
7034
  align-items: center;
6965
7035
  z-index: 10000;
7036
+ animation: fadeIn 0.2s ease-in-out;
7037
+
7038
+ @keyframes fadeIn {
7039
+ from {
7040
+ opacity: 0;
7041
+ }
7042
+ to {
7043
+ opacity: 1;
7044
+ }
7045
+ }
6966
7046
  `;
6967
7047
  var PopupContainer = styled25__default.default.div`
6968
7048
  background-color: var(--color-background, #0a0a0a);
@@ -6972,8 +7052,20 @@ var PopupContainer = styled25__default.default.div`
6972
7052
  max-width: 440px;
6973
7053
  width: 90%;
6974
7054
  position: relative;
7055
+ animation: slideUp 0.3s ease-out;
6975
7056
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
6976
7057
 
7058
+ @keyframes slideUp {
7059
+ from {
7060
+ transform: translateY(20px);
7061
+ opacity: 0;
7062
+ }
7063
+ to {
7064
+ transform: translateY(0);
7065
+ opacity: 1;
7066
+ }
7067
+ }
7068
+
6977
7069
  @media (max-width: 768px) {
6978
7070
  padding: 2rem;
6979
7071
  max-width: 90%;
@@ -6987,9 +7079,21 @@ var KycPopupContainer = styled25__default.default.div`
6987
7079
  max-width: ${(props) => props.$expanded ? "680px" : "440px"};
6988
7080
  width: 90%;
6989
7081
  position: relative;
7082
+ animation: slideUp 0.3s ease-out;
6990
7083
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
6991
7084
  transition: max-width 0.3s ease;
6992
7085
 
7086
+ @keyframes slideUp {
7087
+ from {
7088
+ transform: translateY(20px);
7089
+ opacity: 0;
7090
+ }
7091
+ to {
7092
+ transform: translateY(0);
7093
+ opacity: 1;
7094
+ }
7095
+ }
7096
+
6993
7097
  @media (max-width: 768px) {
6994
7098
  padding: 1.5rem;
6995
7099
  max-width: 95%;
@@ -7048,7 +7152,7 @@ var CloseButton = styled25__default.default.button`
7048
7152
  color: var(--color-accent, #e6c656);
7049
7153
  }
7050
7154
  `;
7051
- var Title2 = styled25__default.default.h2`
7155
+ var Title = styled25__default.default.h2`
7052
7156
  font-size: 1.75rem;
7053
7157
  font-weight: 600;
7054
7158
  color: var(--color-text, #eaecef);
@@ -7317,9 +7421,21 @@ var FundingPopupContainer = styled25__default.default.div`
7317
7421
  max-width: ${(props) => props.$hasWidget ? "900px" : "440px"};
7318
7422
  width: 90%;
7319
7423
  position: relative;
7424
+ animation: slideUp 0.3s ease-out;
7320
7425
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
7321
7426
  overflow: hidden;
7322
7427
 
7428
+ @keyframes slideUp {
7429
+ from {
7430
+ transform: translateY(20px);
7431
+ opacity: 0;
7432
+ }
7433
+ to {
7434
+ transform: translateY(0);
7435
+ opacity: 1;
7436
+ }
7437
+ }
7438
+
7323
7439
  @media (max-width: 768px) {
7324
7440
  padding: ${(props) => props.$hasWidget ? "0" : "2rem"};
7325
7441
  max-width: 95%;
@@ -7608,7 +7724,7 @@ var PropertyCompareBar = React5__namespace.forwardRef(
7608
7724
  void 0,
7609
7725
  pricePercentFormat
7610
7726
  )}%`;
7611
- const priceContent = formattedPriceValue && propertyValueVariant === "pill" ? /* @__PURE__ */ jsxRuntime.jsxs(PriceBlock2, { $variant: propertyValueVariant, children: [
7727
+ const priceContent = formattedPriceValue && propertyValueVariant === "pill" ? /* @__PURE__ */ jsxRuntime.jsxs(PriceBlock, { $variant: propertyValueVariant, children: [
7612
7728
  /* @__PURE__ */ jsxRuntime.jsx(PriceAmount, { children: formattedPriceValue }),
7613
7729
  formattedPriceChange || formattedPricePercent ? /* @__PURE__ */ jsxRuntime.jsxs(
7614
7730
  PriceChange,
@@ -7921,7 +8037,7 @@ var PropertyValueChange = styled25__default.default.span`
7921
8037
  font-size: 0.65rem;
7922
8038
  }
7923
8039
  `;
7924
- var PriceBlock2 = styled25__default.default.div`
8040
+ var PriceBlock = styled25__default.default.div`
7925
8041
  display: none;
7926
8042
 
7927
8043
  ${({ $variant }) => $variant === "pill" && styled25.css`
@@ -8015,7 +8131,7 @@ function GalleryMapSection({
8015
8131
  /* @__PURE__ */ jsxRuntime.jsxs(ThumbStrip, { children: [
8016
8132
  /* @__PURE__ */ jsxRuntime.jsx(ThumbScroll, { children: images.filter((img) => img.category !== "Floorplan").map((img) => {
8017
8133
  const actualIndex = images.indexOf(img);
8018
- return /* @__PURE__ */ jsxRuntime.jsx(Thumbnail, { "data-active": !showVideo && carouselIndex === actualIndex, onClick: () => {
8134
+ return /* @__PURE__ */ jsxRuntime.jsx(Thumbnail2, { "data-active": !showVideo && carouselIndex === actualIndex, onClick: () => {
8019
8135
  stopAutoPlay();
8020
8136
  setShowVideo(false);
8021
8137
  setCarouselIndex(actualIndex);
@@ -8155,7 +8271,7 @@ var ThumbScroll = styled25__default.default.div`
8155
8271
  scrollbar-width: none;
8156
8272
  &::-webkit-scrollbar { display: none; }
8157
8273
  `;
8158
- var Thumbnail = styled25__default.default.div`
8274
+ var Thumbnail2 = styled25__default.default.div`
8159
8275
  min-width: 60px; height: 45px; border-radius: 4px; overflow: hidden;
8160
8276
  cursor: pointer; border: 2px solid transparent; opacity: 0.6;
8161
8277
  transition: all 0.2s ease; flex-shrink: 0;
@@ -8686,7 +8802,7 @@ function PropertyHistory() {
8686
8802
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.9rem] font-normal ml-3 opacity-80", children: loafListing.date.replace(/\d+,\s|\s\d+$/, "") })
8687
8803
  ] }) }),
8688
8804
  /* @__PURE__ */ jsxRuntime.jsx(SalesTable, { children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: /* @__PURE__ */ jsxRuntime.jsxs(HistoryRow, { $isOwnershipStart: true, children: [
8689
- /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(TypeBadge, { $type: loafListing.type, children: loafListing.type === "Sale" ? "Sold" : loafListing.type }) }),
8805
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(TypeBadge2, { $type: loafListing.type, children: loafListing.type === "Sale" ? "Sold" : loafListing.type }) }),
8690
8806
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: loafListing.saleType ?? "-" }),
8691
8807
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: loafListing.agent })
8692
8808
  ] }) }) }),
@@ -8748,7 +8864,7 @@ function PropertyHistory() {
8748
8864
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.9rem] font-normal ml-3 opacity-80", children: ownershipSale.date.replace(/\d+,\s|\s\d+$/, "") })
8749
8865
  ] }) }),
8750
8866
  ownershipSale && (historyFilter === "all" || historyFilter === "sales") && /* @__PURE__ */ jsxRuntime.jsx(SalesTable, { children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: /* @__PURE__ */ jsxRuntime.jsxs(HistoryRow, { $isOwnershipStart: true, children: [
8751
- /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(TypeBadge, { $type: ownershipSale.type, children: ownershipSale.type === "Sale" ? "Sold" : ownershipSale.type }) }),
8867
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(TypeBadge2, { $type: ownershipSale.type, children: ownershipSale.type === "Sale" ? "Sold" : ownershipSale.type }) }),
8752
8868
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: ownershipSale.saleType ?? "-" }),
8753
8869
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: ownershipSale.agent })
8754
8870
  ] }) }) }),
@@ -8757,7 +8873,7 @@ function PropertyHistory() {
8757
8873
  /* @__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)) })
8758
8874
  ] }),
8759
8875
  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: [
8760
- /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(TypeBadge, { $type: sale.type, children: sale.type === "Sale" ? "Sold" : sale.type }) }),
8876
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(TypeBadge2, { $type: sale.type, children: sale.type === "Sale" ? "Sold" : sale.type }) }),
8761
8877
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: sale.saleType ?? "-" }),
8762
8878
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: sale.agent })
8763
8879
  ] }, sale.id)) }) })
@@ -8900,7 +9016,7 @@ function EventDetails({ event }) {
8900
9016
  onClick: toggleExpand,
8901
9017
  children: [
8902
9018
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-between items-center flex-1 gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
8903
- /* @__PURE__ */ jsxRuntime.jsx(TypeBadge, { $type: event.type, children: event.type === "Sale" ? "Sold" : event.type }),
9019
+ /* @__PURE__ */ jsxRuntime.jsx(TypeBadge2, { $type: event.type, children: event.type === "Sale" ? "Sold" : event.type }),
8904
9020
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2", children: event.date })
8905
9021
  ] }) }),
8906
9022
  /* @__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 }) })
@@ -9144,7 +9260,7 @@ var HistoryRow = styled25__default.default.tr`
9144
9260
  background-color: rgba(255, 255, 255, 0.08);
9145
9261
  }
9146
9262
  `;
9147
- var TypeBadge = styled25__default.default.span`
9263
+ var TypeBadge2 = styled25__default.default.span`
9148
9264
  display: inline-block;
9149
9265
  padding: 0.25rem 0.5rem;
9150
9266
  border-radius: 4px;
@@ -9554,7 +9670,8 @@ function AssetSelectorBar({
9554
9670
  metrics: metricsProp,
9555
9671
  currentTokenName,
9556
9672
  selectorItems,
9557
- onSelect
9673
+ onSelect,
9674
+ trailing
9558
9675
  }) {
9559
9676
  const [isDropdownOpen, setIsDropdownOpen] = React5.useState(false);
9560
9677
  const hasItems = selectorItems && selectorItems.length > 0;
@@ -9592,6 +9709,7 @@ function AssetSelectorBar({
9592
9709
  ] })
9593
9710
  ] })
9594
9711
  ] }, m.label)) }),
9712
+ trailing,
9595
9713
  isDropdownOpen && hasItems && /* @__PURE__ */ jsxRuntime.jsx(IPODropdown, { children: selectorItems.map((item) => {
9596
9714
  const isCurrent = item.tokenName === currentTokenName;
9597
9715
  const status = item.status?.toUpperCase();
@@ -9824,6 +9942,7 @@ function OfferingProgressCard({
9824
9942
  raisedAmount,
9825
9943
  targetAmount,
9826
9944
  isPrivateClient = false,
9945
+ variant = "default",
9827
9946
  style,
9828
9947
  className
9829
9948
  }) {
@@ -9855,7 +9974,109 @@ function OfferingProgressCard({
9855
9974
  const interval = setInterval(() => setCountdown(calculateCountdown()), 1e3);
9856
9975
  return () => clearInterval(interval);
9857
9976
  }, [opensAt]);
9858
- return /* @__PURE__ */ jsxRuntime.jsxs(Container2, { style, className, children: [
9977
+ if (variant === "compact") {
9978
+ return /* @__PURE__ */ jsxRuntime.jsxs(CompactContainer, { style, className, children: [
9979
+ /* @__PURE__ */ jsxRuntime.jsx(ProgressBarOuter, { children: /* @__PURE__ */ jsxRuntime.jsx(ProgressBarInner, { style: { width: `${Math.min(percentSold, 100)}%` } }) }),
9980
+ /* @__PURE__ */ jsxRuntime.jsxs(ProgressInfo, { children: [
9981
+ /* @__PURE__ */ jsxRuntime.jsxs(ProgressSubscribers, { children: [
9982
+ "Subscribers: ",
9983
+ subscriberCount.toLocaleString()
9984
+ ] }),
9985
+ /* @__PURE__ */ jsxRuntime.jsxs(ProgressAmounts, { children: [
9986
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "raised", children: formatCurrency3(computedRaised) }),
9987
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "target", children: [
9988
+ " / ",
9989
+ formatCurrency3(computedTarget)
9990
+ ] })
9991
+ ] })
9992
+ ] })
9993
+ ] });
9994
+ }
9995
+ if (variant === "home") {
9996
+ const isPreLive = !ipoStarted && ipoStatus !== "CLOSED" && ipoStatus !== "CANCELLED";
9997
+ return /* @__PURE__ */ jsxRuntime.jsxs(Container, { style, className, children: [
9998
+ /* @__PURE__ */ jsxRuntime.jsxs(Header2, { children: [
9999
+ /* @__PURE__ */ jsxRuntime.jsxs("h3", { children: [
10000
+ /* @__PURE__ */ jsxRuntime.jsx(fa.FaChartLine, {}),
10001
+ " Offering Progress"
10002
+ ] }),
10003
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", alignItems: "center", gap: "0.4rem" }, children: ipoStarted ? /* @__PURE__ */ jsxRuntime.jsxs(StatusSpan, { $color: "#0ecb81", children: [
10004
+ /* @__PURE__ */ jsxRuntime.jsx(StatusDot, { $color: "#0ecb81", $pulse: true }),
10005
+ "LIVE"
10006
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(StatusSpan, { $color: statusColor || "#D4AF37", children: [
10007
+ /* @__PURE__ */ jsxRuntime.jsx(StatusDot, { $color: statusColor || "#D4AF37" }),
10008
+ statusLabel || "Preparing"
10009
+ ] }) })
10010
+ ] }),
10011
+ isPreLive ? /* @__PURE__ */ jsxRuntime.jsxs(HomePreLiveRow, { children: [
10012
+ countdown ? /* @__PURE__ */ jsxRuntime.jsxs(HomeCountdownSide, { children: [
10013
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownLabel, { children: "Opens In" }),
10014
+ /* @__PURE__ */ jsxRuntime.jsxs(CountdownDigits, { children: [
10015
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownNumber, { children: String(countdown.days).padStart(2, "0") }),
10016
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownUnitLabel, { children: "D" }),
10017
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownSeparator, { children: ":" }),
10018
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownNumber, { children: String(countdown.hours).padStart(2, "0") }),
10019
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownUnitLabel, { children: "H" }),
10020
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownSeparator, { children: ":" }),
10021
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownNumber, { children: String(countdown.minutes).padStart(2, "0") }),
10022
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownUnitLabel, { children: "M" }),
10023
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownSeparator, { children: ":" }),
10024
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownNumber, { children: String(countdown.seconds).padStart(2, "0") }),
10025
+ /* @__PURE__ */ jsxRuntime.jsx(CountdownUnitLabel, { children: "S" })
10026
+ ] })
10027
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(HomeCountdownSide, { children: /* @__PURE__ */ jsxRuntime.jsx(PreLiveStatus, { $statusColor: statusColor, children: "Sale Not Yet Open" }) }),
10028
+ /* @__PURE__ */ jsxRuntime.jsxs(HomeUnitsSide, { children: [
10029
+ /* @__PURE__ */ jsxRuntime.jsx(HomeUnitsLabel, { children: "Units Subscribed" }),
10030
+ /* @__PURE__ */ jsxRuntime.jsxs(HomeUnitsValue, { children: [
10031
+ /* @__PURE__ */ jsxRuntime.jsx(HomeSpinner, {}),
10032
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
10033
+ " / ",
10034
+ supplyToSell.toLocaleString()
10035
+ ] })
10036
+ ] })
10037
+ ] })
10038
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(LiveBody, { children: [
10039
+ /* @__PURE__ */ jsxRuntime.jsxs(LiveTopRow, { children: [
10040
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10041
+ /* @__PURE__ */ jsxRuntime.jsxs(LiveLabel, { children: [
10042
+ "Offering Subscribed ",
10043
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u24D8" })
10044
+ ] }),
10045
+ /* @__PURE__ */ jsxRuntime.jsxs(LivePercent, { children: [
10046
+ percentSold.toFixed(1),
10047
+ "%",
10048
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "arrow", children: "\u2191" })
10049
+ ] })
10050
+ ] }),
10051
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "right" }, children: [
10052
+ /* @__PURE__ */ jsxRuntime.jsx(LiveLabel, { children: "Units Subscribed" }),
10053
+ /* @__PURE__ */ jsxRuntime.jsxs(UnitsValue, { children: [
10054
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: totalSold.toLocaleString() }),
10055
+ /* @__PURE__ */ jsxRuntime.jsxs("small", { children: [
10056
+ "/ ",
10057
+ supplyToSell.toLocaleString()
10058
+ ] })
10059
+ ] })
10060
+ ] })
10061
+ ] }),
10062
+ /* @__PURE__ */ jsxRuntime.jsx(ProgressBarOuter, { children: /* @__PURE__ */ jsxRuntime.jsx(ProgressBarInner, { style: { width: `${Math.min(percentSold, 100)}%` } }) }),
10063
+ /* @__PURE__ */ jsxRuntime.jsxs(ProgressInfo, { children: [
10064
+ /* @__PURE__ */ jsxRuntime.jsxs(ProgressSubscribers, { children: [
10065
+ "Subscribers: ",
10066
+ subscriberCount.toLocaleString()
10067
+ ] }),
10068
+ /* @__PURE__ */ jsxRuntime.jsxs(ProgressAmounts, { children: [
10069
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "raised", children: formatCurrency3(computedRaised) }),
10070
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "target", children: [
10071
+ " / ",
10072
+ formatCurrency3(computedTarget)
10073
+ ] })
10074
+ ] })
10075
+ ] })
10076
+ ] })
10077
+ ] });
10078
+ }
10079
+ return /* @__PURE__ */ jsxRuntime.jsxs(Container, { style, className, children: [
9859
10080
  /* @__PURE__ */ jsxRuntime.jsxs(Header2, { children: [
9860
10081
  /* @__PURE__ */ jsxRuntime.jsxs("h3", { children: [
9861
10082
  /* @__PURE__ */ jsxRuntime.jsx(fa.FaChartLine, {}),
@@ -9923,7 +10144,7 @@ function OfferingProgressCard({
9923
10144
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u24D8" })
9924
10145
  ] }),
9925
10146
  /* @__PURE__ */ jsxRuntime.jsxs(LivePercent, { children: [
9926
- percentSold < 0.1 && percentSold > 0 ? percentSold.toFixed(3) : percentSold.toFixed(1),
10147
+ percentSold.toFixed(1),
9927
10148
  "%",
9928
10149
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "arrow", children: "\u2191" })
9929
10150
  ] })
@@ -9956,7 +10177,7 @@ function OfferingProgressCard({
9956
10177
  ] })
9957
10178
  ] });
9958
10179
  }
9959
- var Container2 = styled25__default.default.div`
10180
+ var Container = styled25__default.default.div`
9960
10181
  background-color: var(--color-card-darker, #111);
9961
10182
  border-radius: 8px;
9962
10183
  padding: 1.5rem;
@@ -10156,6 +10377,59 @@ var ProgressAmounts = styled25__default.default.div`
10156
10377
  .raised { color: #D4AF37; }
10157
10378
  .target { color: rgba(255,255,255,0.3); }
10158
10379
  `;
10380
+ var CompactContainer = styled25__default.default.div`
10381
+ width: 100%;
10382
+ margin: 1.5rem 0;
10383
+ display: flex;
10384
+ flex-direction: column;
10385
+ gap: 0.5rem;
10386
+ `;
10387
+ var HomePreLiveRow = styled25__default.default.div`
10388
+ display: flex;
10389
+ align-items: center;
10390
+ justify-content: space-between;
10391
+ padding-top: 1rem;
10392
+ `;
10393
+ var HomeCountdownSide = styled25__default.default.div`
10394
+ display: flex;
10395
+ flex-direction: column;
10396
+ align-items: center;
10397
+ flex: 1;
10398
+ `;
10399
+ var HomeUnitsSide = styled25__default.default.div`
10400
+ text-align: center;
10401
+ flex-shrink: 0;
10402
+ `;
10403
+ var HomeUnitsLabel = styled25__default.default.div`
10404
+ font-size: 0.6rem;
10405
+ color: var(--color-text-secondary);
10406
+ text-transform: uppercase;
10407
+ letter-spacing: 0.1em;
10408
+ margin-bottom: 0.2rem;
10409
+ `;
10410
+ var HomeUnitsValue = styled25__default.default.div`
10411
+ font-size: 1.1rem;
10412
+ font-weight: 700;
10413
+ font-family: monospace;
10414
+ span {
10415
+ color: var(--color-text-secondary);
10416
+ font-weight: 400;
10417
+ }
10418
+ `;
10419
+ var HomeSpinner = styled25__default.default.span`
10420
+ display: inline-block;
10421
+ width: 14px;
10422
+ height: 14px;
10423
+ border: 2px solid rgba(255, 255, 255, 0.1);
10424
+ border-top-color: var(--color-accent, #f0b90b);
10425
+ border-radius: 50%;
10426
+ animation: homeSpin 1s linear infinite;
10427
+ vertical-align: middle;
10428
+ margin-right: 0.15rem;
10429
+ @keyframes homeSpin {
10430
+ to { transform: rotate(360deg); }
10431
+ }
10432
+ `;
10159
10433
  var MAX_DISPLAY_AMOUNT = 6e4;
10160
10434
  var formatCurrency4 = (amount) => {
10161
10435
  if (amount >= 1e6) return `$${(amount / 1e6).toFixed(2)}M`;
@@ -10492,6 +10766,191 @@ var LiveIndicatorDot = styled25__default.default.span`
10492
10766
  100% { box-shadow: 0 0 0 0 rgba(14,203,129,0); }
10493
10767
  }
10494
10768
  `;
10769
+ var slideIn = styled25.keyframes`
10770
+ from { transform: translateX(110%); opacity: 0; }
10771
+ to { transform: translateX(0); opacity: 1; }
10772
+ `;
10773
+ var slideOut = styled25.keyframes`
10774
+ from { transform: translateX(0); opacity: 1; }
10775
+ to { transform: translateX(110%); opacity: 0; }
10776
+ `;
10777
+ var progressShrink = styled25.keyframes`
10778
+ from { width: 100%; }
10779
+ to { width: 0%; }
10780
+ `;
10781
+ var VARIANT_COLORS = {
10782
+ success: { accent: "#0ecb81", icon: "\u2713" },
10783
+ error: { accent: "#f6465d", icon: "\u2715" },
10784
+ info: { accent: "#E6C656", icon: "\u2139" },
10785
+ pending: { accent: "#7EB3E6", icon: "\u25CC" }
10786
+ };
10787
+ var Wrapper = styled25__default.default.div`
10788
+ position: relative;
10789
+ display: flex;
10790
+ flex-direction: column;
10791
+ gap: 0;
10792
+ width: 340px;
10793
+ background: #0d0f1a;
10794
+ border: 1px solid rgba(255, 255, 255, 0.08);
10795
+ border-radius: 10px;
10796
+ overflow: hidden;
10797
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255,255,255,0.04);
10798
+ 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`};
10799
+ pointer-events: all;
10800
+ `;
10801
+ var Body = styled25__default.default.div`
10802
+ display: flex;
10803
+ align-items: flex-start;
10804
+ gap: 12px;
10805
+ padding: 14px 16px 12px;
10806
+ `;
10807
+ var IconDot = styled25__default.default.div`
10808
+ flex-shrink: 0;
10809
+ width: 28px;
10810
+ height: 28px;
10811
+ border-radius: 50%;
10812
+ background: ${({ $color }) => $color}1a;
10813
+ border: 1px solid ${({ $color }) => $color}55;
10814
+ display: flex;
10815
+ align-items: center;
10816
+ justify-content: center;
10817
+ font-size: 0.75rem;
10818
+ font-weight: 700;
10819
+ color: ${({ $color }) => $color};
10820
+ margin-top: 1px;
10821
+ `;
10822
+ var Content = styled25__default.default.div`
10823
+ flex: 1;
10824
+ min-width: 0;
10825
+ `;
10826
+ var Title2 = styled25__default.default.p`
10827
+ margin: 0 0 2px;
10828
+ font-size: 0.8rem;
10829
+ font-weight: 600;
10830
+ color: #fff;
10831
+ letter-spacing: 0.01em;
10832
+ `;
10833
+ var Amount = styled25__default.default.p`
10834
+ margin: 0 0 6px;
10835
+ font-size: 1.05rem;
10836
+ font-weight: 700;
10837
+ color: #E6C656;
10838
+ letter-spacing: -0.01em;
10839
+ `;
10840
+ var TxRow = styled25__default.default.a`
10841
+ display: inline-flex;
10842
+ align-items: center;
10843
+ gap: 5px;
10844
+ font-family: 'IBM Plex Mono', 'Space Mono', monospace;
10845
+ font-size: 0.68rem;
10846
+ color: rgba(255, 255, 255, 0.4);
10847
+ text-decoration: none;
10848
+ transition: color 0.15s;
10849
+ &:hover {
10850
+ color: #7EB3E6;
10851
+ }
10852
+ `;
10853
+ var TxArrow = styled25__default.default.span`
10854
+ font-size: 0.6rem;
10855
+ opacity: 0.6;
10856
+ `;
10857
+ var CloseBtn = styled25__default.default.button`
10858
+ flex-shrink: 0;
10859
+ background: none;
10860
+ border: none;
10861
+ padding: 2px 4px;
10862
+ cursor: pointer;
10863
+ color: rgba(255, 255, 255, 0.25);
10864
+ font-size: 0.9rem;
10865
+ line-height: 1;
10866
+ transition: color 0.15s;
10867
+ &:hover { color: rgba(255, 255, 255, 0.7); }
10868
+ `;
10869
+ var ProgressBar = styled25__default.default.div`
10870
+ height: 2px;
10871
+ background: rgba(255, 255, 255, 0.06);
10872
+ position: relative;
10873
+ &::after {
10874
+ content: '';
10875
+ position: absolute;
10876
+ left: 0;
10877
+ top: 0;
10878
+ height: 100%;
10879
+ background: ${({ $color }) => $color};
10880
+ animation: ${styled25.css`${progressShrink} ${({ $duration }) => $duration}ms linear forwards`};
10881
+ }
10882
+ `;
10883
+ var Container2 = styled25__default.default.div`
10884
+ position: fixed;
10885
+ bottom: 24px;
10886
+ right: 24px;
10887
+ z-index: 9999;
10888
+ display: flex;
10889
+ flex-direction: column-reverse;
10890
+ gap: 10px;
10891
+ pointer-events: none;
10892
+ `;
10893
+ var DEFAULT_EXPLORER = "https://sepolia.basescan.org/tx/";
10894
+ function truncateHash(hash) {
10895
+ return `${hash.slice(0, 6)}\u2026${hash.slice(-4)}`;
10896
+ }
10897
+ function ToastItem({ toast, onDismiss }) {
10898
+ const [exiting, setExiting] = React5.useState(false);
10899
+ const timerRef = React5.useRef(null);
10900
+ const dismiss = React5.useCallback(() => {
10901
+ setExiting(true);
10902
+ setTimeout(() => onDismiss(toast.id), 280);
10903
+ }, [onDismiss, toast.id]);
10904
+ React5.useEffect(() => {
10905
+ const duration2 = toast.duration ?? 6e3;
10906
+ if (duration2 > 0) {
10907
+ timerRef.current = setTimeout(dismiss, duration2);
10908
+ }
10909
+ return () => {
10910
+ if (timerRef.current) clearTimeout(timerRef.current);
10911
+ };
10912
+ }, [dismiss, toast.duration]);
10913
+ const { accent, icon } = VARIANT_COLORS[toast.variant];
10914
+ const duration = toast.duration ?? 6e3;
10915
+ const explorerBase = toast.explorerUrl ?? DEFAULT_EXPLORER;
10916
+ const txUrl = toast.txHash ? `${explorerBase}${toast.txHash}` : void 0;
10917
+ return /* @__PURE__ */ jsxRuntime.jsxs(Wrapper, { $exiting: exiting, children: [
10918
+ /* @__PURE__ */ jsxRuntime.jsxs(Body, { children: [
10919
+ /* @__PURE__ */ jsxRuntime.jsx(IconDot, { $color: accent, children: icon }),
10920
+ /* @__PURE__ */ jsxRuntime.jsxs(Content, { children: [
10921
+ /* @__PURE__ */ jsxRuntime.jsx(Title2, { children: toast.title }),
10922
+ toast.amount && /* @__PURE__ */ jsxRuntime.jsx(Amount, { children: toast.amount }),
10923
+ toast.txHash && txUrl && /* @__PURE__ */ jsxRuntime.jsxs(TxRow, { href: txUrl, target: "_blank", rel: "noopener noreferrer", children: [
10924
+ truncateHash(toast.txHash),
10925
+ /* @__PURE__ */ jsxRuntime.jsx(TxArrow, { children: "\u2197" })
10926
+ ] })
10927
+ ] }),
10928
+ /* @__PURE__ */ jsxRuntime.jsx(CloseBtn, { type: "button", onClick: dismiss, "aria-label": "Dismiss", children: "\u2715" })
10929
+ ] }),
10930
+ duration > 0 && /* @__PURE__ */ jsxRuntime.jsx(ProgressBar, { $color: accent, $duration: duration })
10931
+ ] });
10932
+ }
10933
+ var ToastContext = React5.createContext(null);
10934
+ function ToastProvider({ children }) {
10935
+ const [toasts, setToasts] = React5.useState([]);
10936
+ const addToast = React5.useCallback((data) => {
10937
+ const id = `toast-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
10938
+ setToasts((prev) => [...prev, { ...data, id }]);
10939
+ return id;
10940
+ }, []);
10941
+ const dismiss = React5.useCallback((id) => {
10942
+ setToasts((prev) => prev.filter((t) => t.id !== id));
10943
+ }, []);
10944
+ return /* @__PURE__ */ jsxRuntime.jsxs(ToastContext.Provider, { value: { toast: addToast, dismiss }, children: [
10945
+ children,
10946
+ /* @__PURE__ */ jsxRuntime.jsx(Container2, { children: toasts.map((t) => /* @__PURE__ */ jsxRuntime.jsx(ToastItem, { toast: t, onDismiss: dismiss }, t.id)) })
10947
+ ] });
10948
+ }
10949
+ function useToast() {
10950
+ const ctx = React5.useContext(ToastContext);
10951
+ if (!ctx) throw new Error("useToast must be used within a ToastProvider");
10952
+ return ctx;
10953
+ }
10495
10954
  function OrderPanel({
10496
10955
  statusLabel,
10497
10956
  statusColor,
@@ -11648,7 +12107,14 @@ function PortfolioActivityPanel({
11648
12107
  formatTimestamp(trade.executedAt)
11649
12108
  ] })
11650
12109
  ] }),
11651
- 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" }),
12110
+ /* @__PURE__ */ jsxRuntime.jsx(
12111
+ ActivityTag,
12112
+ {
12113
+ $color: trade.side === "SELL" ? "#f6465d" : "#0ecb81",
12114
+ $bg: trade.side === "SELL" ? "rgba(246,70,93,0.12)" : "rgba(14,203,129,0.12)",
12115
+ children: sideLabel(trade.side)
12116
+ }
12117
+ ),
11652
12118
  /* @__PURE__ */ jsxRuntime.jsx(ActivityAmount, { children: formatCurrency5(trade.price * trade.quantity) })
11653
12119
  ] }, trade.tradeId))
11654
12120
  ] }),
@@ -13720,7 +14186,7 @@ function PropertyValuation({
13720
14186
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
13721
14187
  /* @__PURE__ */ jsxRuntime.jsxs(PricingModelDetail, { children: [
13722
14188
  /* @__PURE__ */ jsxRuntime.jsx(PropertyDetailLabel, { children: "Last Price" }),
13723
- /* @__PURE__ */ jsxRuntime.jsx(PricingDetailValue, { children: formatCompact(lastPrice) })
14189
+ /* @__PURE__ */ jsxRuntime.jsx(PricingDetailValue, { children: formatCurrency6(lastPrice) })
13724
14190
  ] }),
13725
14191
  /* @__PURE__ */ jsxRuntime.jsxs(PricingModelDetail, { children: [
13726
14192
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", width: "100%" }, children: [
@@ -13731,11 +14197,11 @@ function PropertyValuation({
13731
14197
  ] })
13732
14198
  ] }),
13733
14199
  /* @__PURE__ */ jsxRuntime.jsxs(PricingDetailValue, { style: { color: "var(--color-accent)", fontWeight: "bold" }, children: [
13734
- formatCompact(fairValue),
14200
+ formatCurrency6(fairValue),
13735
14201
  " ",
13736
14202
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "0.85em", fontWeight: "normal", opacity: 0.8 }, children: [
13737
14203
  "(",
13738
- formatCompact(fairValue * tokensOutstanding),
14204
+ formatCurrency6(fairValue * tokensOutstanding, { maximumFractionDigits: 0 }),
13739
14205
  ")"
13740
14206
  ] })
13741
14207
  ] })
@@ -13752,7 +14218,7 @@ function PropertyValuation({
13752
14218
  /* @__PURE__ */ jsxRuntime.jsx(GaugeIndicator, { type: "fairValue", position: 50 }),
13753
14219
  /* @__PURE__ */ jsxRuntime.jsxs(GaugePriceTag, { position: gaugePosition, children: [
13754
14220
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Last Price" }),
13755
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatCompact(lastPrice) })
14221
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatCurrency6(lastPrice) })
13756
14222
  ] }),
13757
14223
  /* @__PURE__ */ jsxRuntime.jsx(GaugeIndicator, { type: "lastPrice", position: gaugePosition })
13758
14224
  ] }),
@@ -13760,36 +14226,36 @@ function PropertyValuation({
13760
14226
  /* @__PURE__ */ jsxRuntime.jsx(ValuationItem, { children: /* @__PURE__ */ jsxRuntime.jsxs(ValuationValue, { style: { color: "#4CAF50" }, children: [
13761
14227
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
13762
14228
  "< ",
13763
- formatCompact(undervaluedThreshold)
14229
+ formatCurrency6(undervaluedThreshold)
13764
14230
  ] }),
13765
14231
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "valuation-amount-span", style: { fontSize: "0.8rem", fontWeight: "normal" }, children: [
13766
14232
  "(",
13767
- formatCompact(undervaluedThreshold * tokensOutstanding),
14233
+ formatMillions(undervaluedThreshold * tokensOutstanding),
13768
14234
  ")"
13769
14235
  ] })
13770
14236
  ] }) }),
13771
14237
  /* @__PURE__ */ jsxRuntime.jsx(ValuationItem, { children: /* @__PURE__ */ jsxRuntime.jsxs(ValuationValue, { style: { color: "var(--color-accent)" }, children: [
13772
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatCompact(fairValue) }),
14238
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatCurrency6(fairValue) }),
13773
14239
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "valuation-amount-span", style: { fontSize: "0.8rem", fontWeight: "normal" }, children: [
13774
14240
  "(",
13775
- formatCompact(fairValue * tokensOutstanding),
14241
+ formatMillions(fairValue * tokensOutstanding),
13776
14242
  ")"
13777
14243
  ] })
13778
14244
  ] }) }),
13779
14245
  /* @__PURE__ */ jsxRuntime.jsx(ValuationItem, { children: /* @__PURE__ */ jsxRuntime.jsxs(ValuationValue, { style: { color: "#F44336" }, children: [
13780
14246
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
13781
14247
  "> ",
13782
- formatCompact(overvaluedThreshold)
14248
+ formatCurrency6(overvaluedThreshold)
13783
14249
  ] }),
13784
14250
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "valuation-amount-span", style: { fontSize: "0.8rem", fontWeight: "normal" }, children: [
13785
14251
  "(",
13786
- formatCompact(overvaluedThreshold * tokensOutstanding),
14252
+ formatMillions(overvaluedThreshold * tokensOutstanding),
13787
14253
  ")"
13788
14254
  ] })
13789
14255
  ] }) })
13790
14256
  ] })
13791
14257
  ] }),
13792
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
14258
+ /* @__PURE__ */ jsxRuntime.jsxs(HiddenMobileChart, { children: [
13793
14259
  /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { marginBottom: "1rem", fontSize: "1.1rem", color: "#fff" }, children: "Historical Valuation" }),
13794
14260
  /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { children: /* @__PURE__ */ jsxRuntime.jsxs(ChartBackground, { children: [
13795
14261
  axisLabels.map((label, index) => /* @__PURE__ */ jsxRuntime.jsx(YAxisLabel, { style: { top: `${10 + index * 22}%` }, children: label }, `${label}-${index}`)),
@@ -13908,7 +14374,15 @@ function PropertyValuation({
13908
14374
  ] })
13909
14375
  ] }) })
13910
14376
  ] })
13911
- ] })
14377
+ ] }),
14378
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "desktop-only-historical-chart", style: { marginBottom: "1rem", fontSize: "1.1rem", color: "#fff" }, children: "Historical Valuation" }),
14379
+ /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { className: "desktop-only-historical-chart", children: /* @__PURE__ */ jsxRuntime.jsxs(ChartBackground, { children: [
14380
+ axisLabels.map((label, index) => /* @__PURE__ */ jsxRuntime.jsx(YAxisLabel, { style: { top: `${10 + index * 22}%` }, children: label }, `${label}-${index}`)),
14381
+ /* @__PURE__ */ jsxRuntime.jsxs(ValuationSvg, { viewBox: `0 0 ${CHART_WIDTH} ${CHART_HEIGHT}`, preserveAspectRatio: "none", children: [
14382
+ valuationPath ? /* @__PURE__ */ jsxRuntime.jsx("path", { d: valuationPath, fill: "none", stroke: "#D4AF37", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", vectorEffect: "non-scaling-stroke" }) : null,
14383
+ fairValuePath ? /* @__PURE__ */ jsxRuntime.jsx("path", { d: fairValuePath, fill: "none", stroke: "#FFFFFF", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", vectorEffect: "non-scaling-stroke" }) : null
14384
+ ] })
14385
+ ] }) })
13912
14386
  ] })
13913
14387
  ] }),
13914
14388
  /* @__PURE__ */ jsxRuntime.jsxs(RecentSalesSection, { children: [
@@ -13982,14 +14456,6 @@ function formatMillions(value) {
13982
14456
  }
13983
14457
  return `$${(value / 1e6).toFixed(2)}m`;
13984
14458
  }
13985
- function formatCompact(value) {
13986
- if (value == null || !Number.isFinite(value)) return "\u2014";
13987
- const abs = Math.abs(value);
13988
- if (abs >= 1e9) return `$${(value / 1e9).toFixed(2)}B`;
13989
- if (abs >= 1e6) return `$${(value / 1e6).toFixed(2)}M`;
13990
- if (abs >= 1e3) return `$${(value / 1e3).toFixed(1)}K`;
13991
- return formatCurrency6(value);
13992
- }
13993
14459
  function formatBedroomLabel(bedrooms) {
13994
14460
  if (!Number.isFinite(bedrooms)) return "\u2014";
13995
14461
  return `${bedrooms} Bed`;
@@ -14113,6 +14579,12 @@ var GaugePriceTag = styled25__default.default.div`
14113
14579
  color: var(--color-accent);
14114
14580
  }
14115
14581
  `;
14582
+ var HiddenMobileChart = styled25__default.default.div`
14583
+ display: none;
14584
+ @media (max-width: 480px) {
14585
+ display: block;
14586
+ }
14587
+ `;
14116
14588
  var ValuationWrapper = styled25__default.default.div`
14117
14589
  display: flex;
14118
14590
  flex-direction: column;
@@ -14164,10 +14636,9 @@ var PricingModelCard = styled25__default.default.div`
14164
14636
  var PricingModelHeader = styled25__default.default.div`
14165
14637
  display: flex;
14166
14638
  justify-content: space-between;
14167
- align-items: flex-start;
14639
+ align-items: center;
14168
14640
  margin-bottom: 1.5rem;
14169
14641
  gap: 1rem;
14170
- flex-wrap: wrap;
14171
14642
 
14172
14643
  .valuation-info {
14173
14644
  display: flex;
@@ -14175,7 +14646,6 @@ var PricingModelHeader = styled25__default.default.div`
14175
14646
  gap: 0.25rem;
14176
14647
  font-size: 0.85rem;
14177
14648
  color: rgba(255, 255, 255, 0.75);
14178
- flex-shrink: 0;
14179
14649
  }
14180
14650
  `;
14181
14651
  var PricingModelTitle = styled25__default.default.h3`
@@ -14242,31 +14712,15 @@ var ValuationDetails = styled25__default.default.div`
14242
14712
  display: flex;
14243
14713
  justify-content: space-between;
14244
14714
  margin-top: 1rem;
14245
- gap: 0.25rem;
14246
14715
  `;
14247
14716
  var ValuationItem = styled25__default.default.div`
14248
14717
  display: flex;
14249
14718
  flex-direction: column;
14250
- min-width: 0;
14251
- overflow: hidden;
14252
14719
  `;
14253
14720
  var ValuationValue = styled25__default.default.div`
14254
14721
  font-size: 1rem;
14255
14722
  font-weight: 600;
14256
14723
  color: #fff;
14257
- display: flex;
14258
- flex-direction: column;
14259
- gap: 2px;
14260
- overflow-wrap: break-word;
14261
- word-break: break-word;
14262
-
14263
- @media (max-width: 480px) {
14264
- font-size: 0.72rem;
14265
-
14266
- .valuation-amount-span {
14267
- display: none;
14268
- }
14269
- }
14270
14724
  `;
14271
14725
  var ChartContainer = styled25__default.default.div`
14272
14726
  width: 100%;
@@ -14679,7 +15133,7 @@ var ThumbnailStrip = styled25__default.default.div`
14679
15133
  display: none;
14680
15134
  }
14681
15135
  `;
14682
- var Thumbnail2 = styled25__default.default.button`
15136
+ var Thumbnail3 = styled25__default.default.button`
14683
15137
  width: 86px;
14684
15138
  height: 64px;
14685
15139
  border-radius: 6px;
@@ -15015,7 +15469,7 @@ function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose })
15015
15469
  ]
15016
15470
  }
15017
15471
  ),
15018
- /* @__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)) })
15472
+ /* @__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)) })
15019
15473
  ]
15020
15474
  }
15021
15475
  );