From 24fb8909718440b65c142359a36bc6333dcb503d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=97=D0=B5=D1=84=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2?= Date: Sat, 11 Jul 2026 23:15:27 +0400 Subject: [PATCH] feat: mainnet wallet, cyberpunk backdrop layer, real market data, hoodquidity.com - Switch wallet connect default to Robinhood Chain mainnet (4663); keep testnet and anvil selectable. Header chip and hero folio now read Mainnet. - New CyberGrid fx layer: survey lines, cross marks, corner locators, vertical kanji + scramble glyphs across Markets/Campaigns/Positions/Partners/AppBoard, echoing the hero's cyberpunk instrumentation. - New DepthCanyon: 2D isometric voxel crater hero, single contained core glow (no bleed onto copy). - Real per-token market data via Dexscreener /tokens/{mint} on canonical xStock mints; realistic prices/volume/liquidity. - Remove VAULT address line from footer. - Deploy target -> hoodquidity.com. Co-Authored-By: Claude Opus 4.8 --- .env | 2 +- .../src/components/backdrop/DepthCanyon.tsx | 143 ++++++++++++++++++ apps/web/src/components/fx/CyberGrid.tsx | 54 +++++++ apps/web/src/components/layout/Footer.tsx | 10 +- apps/web/src/components/layout/Header.tsx | 12 +- apps/web/src/hooks/useMarketData.ts | 17 ++- apps/web/src/lib/chain.ts | 22 ++- apps/web/src/lib/contracts.ts | 27 +++- apps/web/src/lib/dexscreener.ts | 44 +++--- apps/web/src/lib/wagmi.ts | 8 +- apps/web/src/screens/AppBoard.tsx | 2 + apps/web/src/screens/CampaignDetail.tsx | 1 - apps/web/src/screens/Campaigns.tsx | 2 + apps/web/src/screens/Landing.tsx | 15 +- apps/web/src/screens/Markets.tsx | 2 + apps/web/src/screens/Partners.tsx | 2 + apps/web/src/screens/Positions.tsx | 2 + apps/web/tsconfig.tsbuildinfo | 2 +- 18 files changed, 308 insertions(+), 59 deletions(-) create mode 100644 apps/web/src/components/backdrop/DepthCanyon.tsx create mode 100644 apps/web/src/components/fx/CyberGrid.tsx diff --git a/.env b/.env index 04cb207..7a5a858 100644 --- a/.env +++ b/.env @@ -1,4 +1,4 @@ -DOMAIN=hoodquidity.154.83.149.72.nip.io +DOMAIN=hoodquidity.com DEPLOY=static BUILD_DIR=apps/web/dist WWW=false diff --git a/apps/web/src/components/backdrop/DepthCanyon.tsx b/apps/web/src/components/backdrop/DepthCanyon.tsx new file mode 100644 index 0000000..ecb6eec --- /dev/null +++ b/apps/web/src/components/backdrop/DepthCanyon.tsx @@ -0,0 +1,143 @@ +/** + * DepthCanyon — a 2D isometric voxel crater. A blocky terrain of dark cubes + * carved by a glowing acid pit: market depth as a literal luminous hole in the + * ground. Deterministic heightmap, painter-ordered cubes, palette-only colors + * (dark faces from the neutral ramp, acid overlays for the emissive throat). + * One breathing core glow; everything else is static SVG. + */ +const VW = 1000; +const VH = 780; +const OX = 500; +const OY = 224; +const HW = 20; // iso tile half width +const HH = 10; // iso tile half height (2:1) +const CUBE_V = 14; // screen px per height unit +const SK = 66; // uniform block skirt → voxel bodies, no pillars +const R = 13; // grid radius in cells +const PIT_R = 7; // pit radius in cells + +const DARK_TOP = "#2a2a2a"; +const DARK_L = "#080808"; +const DARK_R = "#161616"; + +function hash(a: number, b: number) { + const x = Math.sin(a * 12.9898 + b * 78.233) * 43758.5453; + return x - Math.floor(x); +} + +interface Cell { + z: number; // painter depth + x: number; + y: number; + glow: number; // 0 dark .. 1 molten +} + +function build(): Cell[] { + const cells: Cell[] = []; + for (let gx = -R; gx <= R; gx++) { + for (let gy = -R; gy <= R; gy++) { + const d = Math.hypot(gx, gy); + if (d > R + 0.5) continue; + + let h: number; + let glow = 0; + if (d < PIT_R) { + const ring = PIT_R - d; + h = -ring * 1.3; // funnel steps down, steeper + glow = Math.pow(Math.min(ring / PIT_R, 1), 0.7); + } else { + const rd = d - PIT_R; + const rim = Math.max(0, 1 - rd / 2); + // asymmetric crater: back rim tall, front lip low and open + const backness = Math.min(Math.max((-(gx + gy) / R) * 0.5 + 0.5, 0), 1); + const ridge = rim * 2.4 * (0.3 + 0.8 * backness); + const fall = Math.min(Math.max(1 - rd / 8, 0), 1); + const noise = Math.round((hash(gx, gy) + hash(gy, gx)) * 1.1) * fall; + h = ridge + noise; + } + + const x = OX + (gx - gy) * HW; + const y = OY + (gx + gy) * HH - h * CUBE_V; + cells.push({ z: (gx + gy) * 1000 + gx, x, y, glow }); + } + } + cells.sort((a, b) => a.z - b.z); + return cells; +} + +const CELLS = build(); +const CORE_X = OX; +const CORE_Y = OY + PIT_R * CUBE_V + 34; + +function Cube({ x, y, glow }: Cell) { + const top = `${x},${y - HH} ${x + HW},${y} ${x},${y + HH} ${x - HW},${y}`; + const left = `${x - HW},${y} ${x},${y + HH} ${x},${y + HH + SK} ${x - HW},${y + SK}`; + const right = `${x},${y + HH} ${x + HW},${y} ${x + HW},${y + SK} ${x},${y + HH + SK}`; + const hot = glow > 0.75; + return ( + <> + + + + {glow > 0.02 && ( + <> + + + + + )} + + ); +} + +export function DepthCanyon({ className }: { className?: string }) { + return ( + + + + + + + + + + + + + + + + + + + + {CELLS.map((c, i) => ( + + ))} + + {/* tight molten glow contained in the throat, no soft bleed */} + + + + + + + ); +} diff --git a/apps/web/src/components/fx/CyberGrid.tsx b/apps/web/src/components/fx/CyberGrid.tsx new file mode 100644 index 0000000..2265470 --- /dev/null +++ b/apps/web/src/components/fx/CyberGrid.tsx @@ -0,0 +1,54 @@ +import { Scramble } from "./Scramble"; + +/** + * Site-wide cyber backdrop: survey column lines, cross marks, barcode ticks and + * decoding mono/kanji labels. Fixed behind all content, palette-clean, static + * except the two decoding labels. Drop one per non-hero screen. + */ +export function CyberGrid() { + return ( +
+ {/* survey column lines with cross marks */} +
+ {[25, 50, 75].map((p) => ( +
+
+ {[16, 48, 84].map((y) => ( + + + + + ))} +
+ ))} +
+ + {/* corner locators */} + + +
+ ▚▞▚▚ ▞▚▞▚ +
+ + + 流動性デスク // RH-L2 4663 + + + + // 市場深度 + +
+ ); +} diff --git a/apps/web/src/components/layout/Footer.tsx b/apps/web/src/components/layout/Footer.tsx index cff06f6..0e0be2d 100644 --- a/apps/web/src/components/layout/Footer.tsx +++ b/apps/web/src/components/layout/Footer.tsx @@ -2,7 +2,6 @@ import { Link } from "react-router-dom"; import { LogoMark, Wordmark } from "@/components/brand/Logo"; import { XIcon } from "@/components/icons/XIcon"; import { TWITTER_URL } from "@/lib/constants"; -import { getActiveDeployment, ACTIVE_CHAIN_ID } from "@/lib/contracts"; export function Footer() { return ( @@ -67,13 +66,10 @@ export function Footer() {
-
- - VAULT //{" "} - {getActiveDeployment().vaults}{" "} - // CHAIN {ACTIVE_CHAIN_ID} +
+ + RH-L2 4663 // BUILD E-{new Date().getFullYear()}.07 / DESK 00 - BUILD E-{new Date().getFullYear()}.07 / DESK 00
diff --git a/apps/web/src/components/layout/Header.tsx b/apps/web/src/components/layout/Header.tsx index c6c9731..751eb62 100644 --- a/apps/web/src/components/layout/Header.tsx +++ b/apps/web/src/components/layout/Header.tsx @@ -27,12 +27,12 @@ function ConnectControl() { onClick={() => open({ view: "Networks" })} className="num cursor-pointer border border-edge px-2.5 py-2 font-mono text-[10px] uppercase tracking-[0.08em] text-fog transition-colors hover:border-mint hover:text-mint" > - {chainId === 46_630 - ? "RH Testnet" - : chainId === 31_337 - ? "Anvil" - : chainId === 421_614 - ? "Arb Sepolia" + {chainId === 4663 + ? "RH Chain" + : chainId === 46_630 + ? "RH Testnet" + : chainId === 31_337 + ? "Anvil" : `Chain ${chainId ?? "?"}`}