From 45feec59dc4e2b5d06ab66f2c4b435730bd66340 Mon Sep 17 00:00:00 2001 From: drjones Date: Tue, 25 Aug 2026 12:18:41 -0700 Subject: [PATCH] Landing page + SEO + fix top-up modal out-of-bounds - Add premium marketing landing page (hero w/ 3D GPU + Bitcoin, features, pricing, how-it-works, CTA) shown to unauthenticated users - Fix top-up modal rendering out-of-bounds: createPortal to document.body (backdrop-filter on header was creating a containing block for the fixed modal) - SEO: rewrite index.html with meta description/keywords, OpenGraph + Twitter cards, canonical, 3x JSON-LD (Product/Service/Organization) --- index.html | 75 ++++++++++++++++++-- src/App.tsx | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 263 insertions(+), 10 deletions(-) diff --git a/index.html b/index.html index 497cc46..62544d3 100644 --- a/index.html +++ b/index.html @@ -3,16 +3,81 @@ - VortexGPU — Rent a GPU PC by the Hour - - - + + VortexGPU — Rent a GPU PC by the Hour · Bitcoin via BTCPay · No KYC + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- diff --git a/src/App.tsx b/src/App.tsx index 4b2df65..85afaa5 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,8 +1,11 @@ import React, { useState, useEffect, useCallback } from 'react'; +import { createPortal } from 'react-dom'; import { Monitor, Cpu, Plus, Power, Clock, Shield, Terminal, Zap, Bitcoin, Laptop, Server, KeyRound, Sparkles, LogOut, X, ExternalLink, Copy, Globe, UserPlus, LogIn, + ArrowRight, CheckCircle2, Rocket, Lock, Gauge, } from 'lucide-react'; +import { Cyber3DCanvas } from './components/Cyber3DCanvas'; import './index.css'; /** @@ -35,6 +38,7 @@ function App() { const [freeMachines, setFreeMachines] = useState(1); const [error, setError] = useState(''); const [loading, setLoading] = useState(false); + const [view, setView] = useState<'landing' | 'auth'>('landing'); useEffect(() => { const raw = localStorage.getItem('vortex_auth'); @@ -66,7 +70,11 @@ function App() { return () => clearInterval(t); }, [auth, refresh]); - if (!auth) return ; + if (!auth) { + return view === 'landing' + ? setView('auth')} /> + : setView('landing')} />; + } const user = auth.user; const hrs = Math.floor(user.balance_minutes / 60); @@ -307,9 +315,9 @@ function PayModal({ token, onClose, onAdded }: { token: string; onClose: () => v return () => clearInterval(t); }, [invoice, token]); - return ( -
-
+ return createPortal( +
+

Top Up Balance

@@ -340,11 +348,188 @@ function PayModal({ token, onClose, onAdded }: { token: string; onClose: () => v
)}
+
, + document.body + ); +} + +function LandingPage({ onLaunch }: { onLaunch: () => void }) { + return ( +
+ {/* Nav */} +
+
+
+ VORTEXGPU +
+ + +
+
+ + {/* Hero */} +
+
+
+
+
+ Bitcoin · No KYC +
+

+ Rent a real GPU PC by the hour. +

+

+ A full Ubuntu desktop with an RTX 4080 SUPER in your browser, Windows RDP, and Linux SSH. Settled in Bitcoin — no card, no lock-in. +

+
+ + + See pricing + +
+
+ First machine free + 4080 SUPER / 4070 + Clean residential proxy +
+
+
+
+ +
+
+ Settled in BTC via BTCPay +
+
+
+
+ + {/* Stat bar */} +
+
+ {[['$1', 'per hour'], ['1st', 'machine free'], ['RTX 4080', 'SUPER 16GB'], ['BTC', 'via BTCPay']].map(([v, l]) => ( +
+
{v}
+
{l}
+
+ ))} +
+
+ + {/* Features */} +
+
+

Three ways to compute

+

Every machine is a real isolated instance with the GPU attached — not a shared sandbox.

+
+
+ } name="Ubuntu GPU Session" tag="In-browser · 4080 SUPER" desc="A full Ubuntu desktop streaming to your browser with the RTX 4080 attached. Install anything, run any CUDA job." /> + } name="Windows 10" tag="RDP · full desktop" desc="A real Windows 10 VM over RDP. Games, GUI apps, CUDA workloads — a genuine desktop." /> + } name="Linux" tag="SSH · headless" desc="Debian over SSH for headless compute, docker, and long-running server jobs." /> +
+
+ {[ + [, 'Dedicated GPU', 'Real passthrough, not shared'], + [, 'No KYC', 'Email-free Bitcoin checkout'], + [, 'Clean proxy', 'Residential IP on sessions'], + [, 'Isolated', 'Your own VM, full root'], + ].map(([ic, t, d], i) => ( +
+
{ic}{t}
+
{d}
+
+ ))} +
+
+ + {/* Pricing */} +
+
+
+

Simple, honest pricing

+

Pay in Bitcoin. Credits your balance automatically the moment payment confirms.

+
+
+ {[ + ['1 hour', '$1', 'Try it — your first machine is free', 'from-cyan-500 to-blue-600'], + ['5 hours', '$5', 'Most popular for a session', 'from-emerald-500 to-teal-600'], + ['24 hours', '$24', 'Best value for long jobs', 'from-purple-500 to-indigo-600'], + ].map(([h, p, d, g]) => ( +
+
{h}
+
{p}
+
{d}
+ +
+ ))} +
+

First machine free · up to 3 machines · $1/hour per billed machine · no subscription, no card on file

+
+
+ + {/* How it works */} +
+
+

Up and running in a minute

+
+
+ {[ + [, '1 · Create an account', 'Username + password. No email, no KYC.'], + [, '2 · Top up in Bitcoin', 'Pay $1–$24 via BTCPay. Balance credits instantly.'], + [, '3 · Deploy your machine', 'Spawn an Ubuntu session or deploy Windows/Linux. First one is free.'], + ].map(([ic, t, d], i) => ( +
+
{ic}
+
{t}
+
{d}
+
+ ))} +
+
+ + {/* CTA */} +
+
+

Your GPU is waiting.

+

Rent an RTX 4080 SUPER by the hour, paid in Bitcoin, no KYC. First machine free.

+ +
+
+ + {/* Footer */} +
+
+
+ VORTEXGPU +
+
+ $1/hr · Bitcoin via BTCPay · No KYC · Support the build +
+
+
); } -function AuthGate({ onAuthed }: { onAuthed: (a: { token: string; user: User }) => void }) { +function FeatureCard({ icon, name, tag, desc }: { icon: React.ReactNode; name: string; tag: string; desc: string }) { + return ( +
+
{icon}{name}
+
{tag}
+

{desc}

+
+ ); +} + +function AuthGate({ onAuthed, onBack }: { onAuthed: (a: { token: string; user: User }) => void; onBack: () => void }) { const [mode, setMode] = useState<'login' | 'register'>('login'); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); @@ -370,6 +555,9 @@ function AuthGate({ onAuthed }: { onAuthed: (a: { token: string; user: User }) = return (
+
VORTEXGPU