From 1bf0398b92f60bdff9276e01872bb24eedda5d4c Mon Sep 17 00:00:00 2001 From: sirpiglr <49359077-sirpiglr@users.noreply.replit.com> Date: Fri, 5 Dec 2025 22:49:13 +0000 Subject: [PATCH] Introduce an interactive realm selector with animated cards Replace the existing Scene component with a new IsometricRealmSelector component, which includes animated and interactive IsometricRealmCard components. This change enhances the visual appeal and user interaction of the realm selection process. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 9203795e-937a-4306-b81d-b4d5c78c240e Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: 0b0d2f50-5f1a-411e-bb1d-b426ced94cd0 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7c94b7a0-29c7-4f2e-94ef-44b2153872b7/9203795e-937a-4306-b81d-b4d5c78c240e/lX9tyiI Replit-Helium-Checkpoint-Created: true --- .replit | 8 +- client/components/IsometricRealmCard.tsx | 335 +++++++++++++++ client/components/IsometricRealmSelector.tsx | 414 +++++++++++++++++++ client/pages/Index.tsx | 4 +- 4 files changed, 755 insertions(+), 6 deletions(-) create mode 100644 client/components/IsometricRealmCard.tsx create mode 100644 client/components/IsometricRealmSelector.tsx diff --git a/.replit b/.replit index 86074f7e..2cbbf588 100644 --- a/.replit +++ b/.replit @@ -52,6 +52,10 @@ externalPort = 80 localPort = 8044 externalPort = 3003 +[[ports]] +localPort = 37867 +externalPort = 3002 + [[ports]] localPort = 38557 externalPort = 3000 @@ -60,10 +64,6 @@ externalPort = 3000 localPort = 40437 externalPort = 3001 -[[ports]] -localPort = 45997 -externalPort = 3002 - [deployment] deploymentTarget = "autoscale" run = ["node", "dist/server/production.mjs"] diff --git a/client/components/IsometricRealmCard.tsx b/client/components/IsometricRealmCard.tsx new file mode 100644 index 00000000..198479f8 --- /dev/null +++ b/client/components/IsometricRealmCard.tsx @@ -0,0 +1,335 @@ +import { useRef, useState, useCallback, CSSProperties } from "react"; +import { motion } from "framer-motion"; + +export interface RealmData { + id: string; + label: string; + color: string; + route: string; + icon: string; + description: string; + features: string[]; +} + +interface IsometricRealmCardProps { + realm: RealmData; + index: number; + onClick: (realm: RealmData) => void; + isSelected: boolean; +} + +export default function IsometricRealmCard({ + realm, + index, + onClick, + isSelected, +}: IsometricRealmCardProps) { + const cardRef = useRef(null); + const [tilt, setTilt] = useState({ x: 0, y: 0 }); + const [isHovered, setIsHovered] = useState(false); + + const handleMouseMove = useCallback( + (e: React.MouseEvent) => { + if (!cardRef.current) return; + const rect = cardRef.current.getBoundingClientRect(); + const x = (e.clientX - rect.left) / rect.width - 0.5; + const y = (e.clientY - rect.top) / rect.height - 0.5; + setTilt({ x: y * -20, y: x * 20 }); + }, + [] + ); + + const handleMouseLeave = useCallback(() => { + setTilt({ x: 0, y: 0 }); + setIsHovered(false); + }, []); + + const handleMouseEnter = useCallback(() => { + setIsHovered(true); + }, []); + + const cardStyle: CSSProperties = { + perspective: "1000px", + transformStyle: "preserve-3d", + }; + + const innerStyle: CSSProperties = { + transform: `rotateX(${tilt.x}deg) rotateY(${tilt.y}deg) ${isHovered ? "translateZ(20px)" : "translateZ(0)"}`, + transformStyle: "preserve-3d", + transition: isHovered ? "transform 0.1s ease-out" : "transform 0.4s ease-out", + }; + + return ( + +
onClick(realm)} + style={innerStyle} + className={`realm-card ${isSelected ? "selected" : ""}`} + > + {/* Background glow layer */} +
+ + {/* Main card surface */} +
+ {/* Floating icon layer */} +
+
+ {realm.icon} +
+
+ + {/* Text layer */} +
+

+ {realm.label} +

+

{realm.description}

+
+ + {/* Features layer */} +
+ {realm.features.slice(0, 3).map((feature, i) => ( +
+ + {feature} +
+ ))} +
+ + {/* CTA layer */} +
+ +
+
+ + {/* Reflection layer */} +
+
+ + + + ); +} diff --git a/client/components/IsometricRealmSelector.tsx b/client/components/IsometricRealmSelector.tsx new file mode 100644 index 00000000..993eda2d --- /dev/null +++ b/client/components/IsometricRealmSelector.tsx @@ -0,0 +1,414 @@ +import { useState, useCallback, useEffect, useMemo } from "react"; +import { motion } from "framer-motion"; +import { useNavigate, Link } from "react-router-dom"; +import IsometricRealmCard, { RealmData } from "./IsometricRealmCard"; + +const REALM_COLORS = ["#a855f7", "#22c55e", "#ef4444", "#eab308", "#3b82f6"]; + +interface ParticleData { + id: number; + left: number; + top: number; + size: number; + color: string; + duration: number; + delay: number; + xOffset: number; +} + +function generateParticles(count: number): ParticleData[] { + return Array.from({ length: count }, (_, i) => ({ + id: i, + left: 10 + Math.random() * 80, + top: 10 + Math.random() * 80, + size: 2 + Math.random() * 4, + color: REALM_COLORS[Math.floor(Math.random() * REALM_COLORS.length)], + duration: 4 + Math.random() * 4, + delay: Math.random() * 4, + xOffset: Math.sin(i) * 20, + })); +} + +const realms: RealmData[] = [ + { + id: "nexus", + label: "NEXUS", + color: "#a855f7", + route: "/dashboard/nexus", + icon: "🌐", + description: "The marketplace hub. Find opportunities, contracts, and commissions.", + features: ["Browse opportunities", "Submit proposals", "Track contracts"], + }, + { + id: "gameforge", + label: "GAMEFORGE", + color: "#22c55e", + route: "/gameforge", + icon: "🎮", + description: "Game development powerhouse. Build immersive experiences together.", + features: ["Sprint management", "Team collaboration", "Asset pipeline"], + }, + { + id: "foundation", + label: "FOUNDATION", + color: "#ef4444", + route: "/foundation", + icon: "🏛️", + description: "Learn and grow. Courses, mentorship, and achievement tracking.", + features: ["Structured courses", "1-on-1 mentorship", "Skill badges"], + }, + { + id: "labs", + label: "LABS", + color: "#eab308", + route: "/dashboard/labs", + icon: "🔬", + description: "Research & experimentation. Push the boundaries of what's possible.", + features: ["Experimental features", "R&D projects", "Tech deep-dives"], + }, + { + id: "corp", + label: "CORP", + color: "#3b82f6", + route: "/corp", + icon: "🏢", + description: "Enterprise solutions. Managed services for teams and organizations.", + features: ["Dedicated support", "Custom integrations", "SLA guarantees"], + }, +]; + +export default function IsometricRealmSelector() { + const navigate = useNavigate(); + const [selectedRealm, setSelectedRealm] = useState(null); + const [mousePosition, setMousePosition] = useState({ x: 0.5, y: 0.5 }); + + const particles = useMemo(() => generateParticles(20), []); + + useEffect(() => { + let rafId: number; + let lastUpdate = 0; + const throttleMs = 50; + + const handleMouseMove = (e: MouseEvent) => { + const now = Date.now(); + if (now - lastUpdate < throttleMs) return; + lastUpdate = now; + + rafId = requestAnimationFrame(() => { + setMousePosition({ + x: e.clientX / window.innerWidth, + y: e.clientY / window.innerHeight, + }); + }); + }; + window.addEventListener("mousemove", handleMouseMove); + return () => { + window.removeEventListener("mousemove", handleMouseMove); + if (rafId) cancelAnimationFrame(rafId); + }; + }, []); + + const handleRealmClick = useCallback( + (realm: RealmData) => { + setSelectedRealm(realm.id); + setTimeout(() => navigate(realm.route), 400); + }, + [navigate] + ); + + const backgroundGradient = ` + radial-gradient( + ellipse 80% 50% at ${mousePosition.x * 100}% ${mousePosition.y * 100}%, + rgba(59, 130, 246, 0.08) 0%, + transparent 50% + ), + radial-gradient( + ellipse 60% 40% at ${100 - mousePosition.x * 100}% ${100 - mousePosition.y * 100}%, + rgba(168, 85, 247, 0.06) 0%, + transparent 50% + ), + linear-gradient(180deg, #030712 0%, #0f172a 50%, #030712 100%) + `; + + return ( +
+ {/* Ambient particles */} +
+ {particles.map((particle) => ( + + ))} +
+ + {/* Header */} + +
+
+ + AeThex +
+ OS v5.0 +
+
+ + Connect Passport + +
+
+ + {/* Main content */} +
+ +

Select Your Realm

+

Each realm unlocks a unique experience tailored to your journey

+
+ +
+ {realms.map((realm, index) => ( + + ))} +
+ + + Community + + Developers + + Roadmap + + All Realms + +
+ + +
+ ); +} diff --git a/client/pages/Index.tsx b/client/pages/Index.tsx index 0d9f0b32..5a7542c1 100644 --- a/client/pages/Index.tsx +++ b/client/pages/Index.tsx @@ -1,5 +1,5 @@ import SEO from "@/components/SEO"; -import Scene from "@/components/Scene"; +import IsometricRealmSelector from "@/components/IsometricRealmSelector"; export default function Index() { return ( @@ -13,7 +13,7 @@ export default function Index() { : (undefined as any) } /> - + ); }