feat: overhaul landing page and add demo with SVG map

Overhaul landing page from login screen to proper hero + features.
Add interactive demo page showing CCC Camp 2026 event with SVG camp
map, animated friend markers, status system, and friend list panel.
Add ecosystem footer to both pages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-02-15 08:58:54 -07:00
parent 9a8ea19f89
commit 96e46af9dc
2 changed files with 779 additions and 138 deletions

481
src/app/demo/page.tsx Normal file
View File

@ -0,0 +1,481 @@
import Link from 'next/link'
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'rMaps Demo - CCC Camp 2026',
description: 'See how rMaps helps you find your friends at events. A demo showcasing real-time location sharing, event maps, and privacy-first friend finding at CCC Camp 2026.',
openGraph: {
title: 'rMaps Demo - CCC Camp 2026',
description: 'Privacy-first real-time location sharing for events. Find your crew at CCC Camp 2026.',
url: 'https://rmaps.online/demo',
siteName: 'rMaps',
type: 'website',
},
}
/* ─── Mock Data ─────────────────────────────────────────────── */
const friends = [
{
name: 'Mika',
emoji: '🦊',
color: '#10b981',
status: 'At Main Stage',
lastSeen: '1 min ago',
x: 520,
y: 155,
online: true,
},
{
name: 'Zara',
emoji: '🐙',
color: '#6366f1',
status: 'Heading to Food Court',
lastSeen: '3 min ago',
x: 340,
y: 260,
online: true,
},
{
name: 'Leo',
emoji: '🐻',
color: '#f59e0b',
status: 'In Tent',
lastSeen: '12 min ago',
x: 160,
y: 310,
online: false,
},
{
name: 'Ren',
emoji: '🦉',
color: '#ef4444',
status: 'At Workshop Hall',
lastSeen: '2 min ago',
x: 640,
y: 290,
online: true,
},
{
name: 'Juno',
emoji: '🐧',
color: '#ec4899',
status: 'Getting coffee',
lastSeen: '5 min ago',
x: 400,
y: 180,
online: true,
},
{
name: 'Kai',
emoji: '🐝',
color: '#06b6d4',
status: 'At Soldering Village',
lastSeen: '8 min ago',
x: 280,
y: 130,
online: true,
},
]
const statusOptions = [
'At Main Stage',
'Heading to Food Court',
'In Tent',
'At Workshop Hall',
'Getting coffee',
'At Soldering Village',
'Exploring',
'At the Lake',
'On my way!',
]
/* ─── SVG Camp Map ─────────────────────────────────────────── */
function CampMap() {
return (
<div className="relative w-full rounded-xl bg-slate-900/60 overflow-hidden border border-slate-700/30">
<svg viewBox="0 0 800 400" className="w-full h-auto" xmlns="http://www.w3.org/2000/svg">
{/* Background terrain */}
<rect width="800" height="400" fill="#0c1222" />
{/* Grass / ground patches */}
<ellipse cx="400" cy="200" rx="380" ry="180" fill="#0f1a2e" />
<ellipse cx="400" cy="200" rx="360" ry="170" fill="#111d33" />
{/* Paths - main walkways */}
<path
d="M100 200 L350 200 L500 150 L700 200"
fill="none"
stroke="rgba(148,163,184,0.15)"
strokeWidth="20"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M350 200 L350 350"
fill="none"
stroke="rgba(148,163,184,0.15)"
strokeWidth="16"
strokeLinecap="round"
/>
<path
d="M500 150 L600 300"
fill="none"
stroke="rgba(148,163,184,0.15)"
strokeWidth="14"
strokeLinecap="round"
/>
<path
d="M350 200 L250 120"
fill="none"
stroke="rgba(148,163,184,0.12)"
strokeWidth="12"
strokeLinecap="round"
/>
{/* ── Area: Main Stage (top right) ── */}
<rect x="460" y="100" width="140" height="90" rx="12" fill="rgba(16,185,129,0.08)" stroke="rgba(16,185,129,0.25)" strokeWidth="1.5" />
<rect x="490" y="115" width="80" height="30" rx="4" fill="rgba(16,185,129,0.15)" />
<text x="530" y="135" textAnchor="middle" fill="rgba(16,185,129,0.7)" fontSize="11" fontWeight="600">STAGE</text>
<text x="530" y="175" textAnchor="middle" fill="#94a3b8" fontSize="11" fontWeight="600">Main Stage</text>
{/* ── Area: Food Court (center-left) ── */}
<rect x="290" y="220" width="130" height="80" rx="12" fill="rgba(249,115,22,0.08)" stroke="rgba(249,115,22,0.25)" strokeWidth="1.5" />
{/* Food stall icons */}
<rect x="305" y="235" width="20" height="15" rx="3" fill="rgba(249,115,22,0.2)" />
<rect x="335" y="235" width="20" height="15" rx="3" fill="rgba(249,115,22,0.2)" />
<rect x="365" y="235" width="20" height="15" rx="3" fill="rgba(249,115,22,0.2)" />
<rect x="305" y="260" width="20" height="15" rx="3" fill="rgba(249,115,22,0.2)" />
<rect x="335" y="260" width="20" height="15" rx="3" fill="rgba(249,115,22,0.2)" />
<rect x="365" y="260" width="20" height="15" rx="3" fill="rgba(249,115,22,0.2)" />
<text x="355" y="292" textAnchor="middle" fill="#94a3b8" fontSize="11" fontWeight="600">Food Court</text>
{/* ── Area: Workshops (right) ── */}
<rect x="570" y="240" width="150" height="90" rx="12" fill="rgba(99,102,241,0.08)" stroke="rgba(99,102,241,0.25)" strokeWidth="1.5" />
<rect x="585" y="255" width="50" height="25" rx="4" fill="rgba(99,102,241,0.12)" />
<rect x="645" y="255" width="50" height="25" rx="4" fill="rgba(99,102,241,0.12)" />
<rect x="585" y="288" width="50" height="25" rx="4" fill="rgba(99,102,241,0.12)" />
<rect x="645" y="288" width="50" height="25" rx="4" fill="rgba(99,102,241,0.12)" />
<text x="645" y="325" textAnchor="middle" fill="#94a3b8" fontSize="11" fontWeight="600">Workshops</text>
{/* ── Area: Camping (bottom-left) ── */}
<rect x="90" y="260" width="160" height="100" rx="12" fill="rgba(234,179,8,0.06)" stroke="rgba(234,179,8,0.2)" strokeWidth="1.5" />
{/* Tent icons */}
<polygon points="120,300 135,280 150,300" fill="rgba(234,179,8,0.15)" stroke="rgba(234,179,8,0.3)" strokeWidth="1" />
<polygon points="165,310 180,290 195,310" fill="rgba(234,179,8,0.15)" stroke="rgba(234,179,8,0.3)" strokeWidth="1" />
<polygon points="120,335 135,315 150,335" fill="rgba(234,179,8,0.12)" stroke="rgba(234,179,8,0.25)" strokeWidth="1" />
<polygon points="175,340 190,320 205,340" fill="rgba(234,179,8,0.12)" stroke="rgba(234,179,8,0.25)" strokeWidth="1" />
<text x="170" y="355" textAnchor="middle" fill="#94a3b8" fontSize="11" fontWeight="600">Camping</text>
{/* ── Area: Soldering Village (top-left) ── */}
<rect x="200" y="80" width="120" height="70" rx="12" fill="rgba(6,182,212,0.08)" stroke="rgba(6,182,212,0.25)" strokeWidth="1.5" />
<rect x="215" y="95" width="30" height="20" rx="3" fill="rgba(6,182,212,0.15)" />
<rect x="255" y="95" width="30" height="20" rx="3" fill="rgba(6,182,212,0.15)" />
<text x="260" y="140" textAnchor="middle" fill="#94a3b8" fontSize="10" fontWeight="600">Soldering Village</text>
{/* ── Area: Info / Coffee (center) ── */}
<circle cx="400" cy="180" r="22" fill="rgba(148,163,184,0.06)" stroke="rgba(148,163,184,0.2)" strokeWidth="1" />
<text x="400" y="176" textAnchor="middle" fill="#64748b" fontSize="14">&#9749;</text>
<text x="400" y="192" textAnchor="middle" fill="#64748b" fontSize="7">INFO</text>
{/* ── Entrance marker ── */}
<rect x="60" y="185" width="50" height="30" rx="6" fill="rgba(148,163,184,0.1)" stroke="rgba(148,163,184,0.2)" strokeWidth="1" />
<text x="85" y="204" textAnchor="middle" fill="#64748b" fontSize="9" fontWeight="600">ENTER</text>
{/* ── Trees / decoration ── */}
<circle cx="450" cy="350" r="8" fill="rgba(16,185,129,0.1)" />
<circle cx="470" cy="345" r="6" fill="rgba(16,185,129,0.08)" />
<circle cx="130" cy="230" r="6" fill="rgba(16,185,129,0.08)" />
<circle cx="750" cy="150" r="10" fill="rgba(16,185,129,0.06)" />
<circle cx="740" cy="170" r="7" fill="rgba(16,185,129,0.08)" />
{/* ── Friend markers ── */}
{friends.map((f) => (
<g key={f.name}>
{/* Pulse ring for online friends */}
{f.online && (
<circle cx={f.x} cy={f.y} r="14" fill="none" stroke={f.color} strokeWidth="2" opacity="0.3">
<animate attributeName="r" from="14" to="24" dur="2s" repeatCount="indefinite" />
<animate attributeName="opacity" from="0.4" to="0" dur="2s" repeatCount="indefinite" />
</circle>
)}
{/* Dot */}
<circle cx={f.x} cy={f.y} r="12" fill={f.color} stroke="#0f172a" strokeWidth="3" />
{/* Emoji */}
<text x={f.x} y={f.y + 4} textAnchor="middle" fontSize="12">{f.emoji}</text>
{/* Name label */}
<rect x={f.x - 20} y={f.y + 16} width="40" height="16" rx="4" fill="rgba(15,23,42,0.85)" stroke={f.color} strokeWidth="0.5" />
<text x={f.x} y={f.y + 27} textAnchor="middle" fill="#e2e8f0" fontSize="9" fontWeight="500">{f.name}</text>
</g>
))}
</svg>
{/* Map legend */}
<div className="absolute bottom-3 left-3 flex flex-wrap gap-3 text-xs text-slate-400">
<span className="flex items-center gap-1">
<span className="w-2 h-2 rounded-full bg-emerald-500" /> Stage
</span>
<span className="flex items-center gap-1">
<span className="w-2 h-2 rounded-full bg-orange-500" /> Food
</span>
<span className="flex items-center gap-1">
<span className="w-2 h-2 rounded-full bg-indigo-500" /> Workshops
</span>
<span className="flex items-center gap-1">
<span className="w-2 h-2 rounded-full bg-yellow-500" /> Camping
</span>
</div>
{/* Simulated live badge */}
<div className="absolute top-3 right-3 flex items-center gap-1.5 bg-slate-800/80 backdrop-blur-sm rounded-full px-3 py-1.5 border border-slate-700/50">
<span className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" />
<span className="text-xs text-slate-300 font-medium">Live</span>
</div>
</div>
)
}
/* ─── Friend List Panel ────────────────────────────────────── */
function FriendListPanel() {
return (
<div className="bg-slate-800/50 rounded-2xl border border-slate-700/50 overflow-hidden">
<div className="px-5 py-3 border-b border-slate-700/50 flex items-center justify-between">
<div className="flex items-center gap-2">
<span className="text-xl">👥</span>
<span className="font-semibold text-sm">Friends in Room</span>
</div>
<span className="text-xs text-slate-400">{friends.filter((f) => f.online).length}/{friends.length} online</span>
</div>
<div className="p-3 space-y-1">
{friends.map((f) => (
<div
key={f.name}
className="flex items-center gap-3 px-3 py-2.5 rounded-lg hover:bg-slate-700/30 transition-colors"
>
{/* Avatar */}
<div
className="w-9 h-9 rounded-full flex items-center justify-center text-lg flex-shrink-0 ring-2"
style={{ backgroundColor: `${f.color}20`, boxShadow: `0 0 0 2px ${f.color}` }}
>
{f.emoji}
</div>
{/* Info */}
<div className="min-w-0 flex-1">
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-slate-200">{f.name}</span>
<span
className="w-2 h-2 rounded-full flex-shrink-0"
style={{ backgroundColor: f.online ? '#10b981' : '#6b7280', boxShadow: f.online ? '0 0 6px #10b981' : 'none' }}
/>
</div>
<p className="text-xs text-slate-400 truncate">{f.status}</p>
</div>
{/* Last seen */}
<span className="text-xs text-slate-500 flex-shrink-0">{f.lastSeen}</span>
</div>
))}
</div>
{/* Status selector preview */}
<div className="px-5 py-3 border-t border-slate-700/50">
<p className="text-xs text-slate-500 mb-2">Your status:</p>
<div className="flex flex-wrap gap-1.5">
{statusOptions.slice(0, 5).map((s) => (
<span
key={s}
className={`text-xs px-2.5 py-1 rounded-full border transition-colors cursor-default ${
s === 'At Main Stage'
? 'bg-emerald-500/15 border-emerald-500/40 text-emerald-400'
: 'bg-slate-700/30 border-slate-600/40 text-slate-400 hover:border-slate-500'
}`}
>
{s}
</span>
))}
<span className="text-xs px-2.5 py-1 rounded-full bg-slate-700/30 border border-slate-600/40 text-slate-500 cursor-default">
+{statusOptions.length - 5} more
</span>
</div>
</div>
</div>
)
}
/* ─── Page ──────────────────────────────────────────────────── */
export default function DemoPage() {
return (
<div className="min-h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900 text-white">
{/* Nav */}
<nav className="border-b border-slate-700/50 backdrop-blur-sm sticky top-0 z-50 bg-slate-900/80">
<div className="max-w-7xl mx-auto px-6 py-4 flex items-center justify-between">
<div className="flex items-center gap-3">
<Link href="/" className="flex items-center gap-2">
<div className="w-8 h-8 bg-gradient-to-br from-emerald-400 to-emerald-600 rounded-lg flex items-center justify-center font-bold text-slate-900 text-sm">
rM
</div>
<span className="font-semibold text-lg">rMaps</span>
</Link>
<span className="text-slate-600">/</span>
<span className="text-sm text-slate-400">Demo</span>
</div>
<Link
href="/"
className="text-sm px-4 py-2 bg-emerald-600 hover:bg-emerald-500 rounded-lg transition-colors font-medium"
>
Create Your Map
</Link>
</div>
</nav>
{/* Hero / Event Header */}
<section className="max-w-7xl mx-auto px-6 pt-12 pb-8">
<div className="text-center max-w-3xl mx-auto">
<div className="inline-flex items-center gap-2 px-4 py-1.5 bg-emerald-500/10 border border-emerald-500/20 rounded-full text-emerald-400 text-sm mb-6">
<span className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" />
Live Demo
</div>
<h1 className="text-4xl sm:text-5xl font-bold mb-4 bg-gradient-to-r from-emerald-300 via-teal-300 to-cyan-300 bg-clip-text text-transparent">
CCC Camp 2026
</h1>
<p className="text-lg text-slate-300 mb-3">
Find your friends across the campground in real time
</p>
<div className="flex flex-wrap items-center justify-center gap-4 text-sm text-slate-400 mb-6">
<span>📍 Ziegeleipark Mildenberg</span>
<span>📅 Aug 2026</span>
<span>👥 6 friends connected</span>
</div>
{/* Member avatars */}
<div className="flex items-center justify-center gap-2">
{friends.map((f) => (
<div
key={f.name}
className="w-10 h-10 rounded-full flex items-center justify-center text-lg ring-2 ring-slate-800"
style={{ backgroundColor: `${f.color}30` }}
title={f.name}
>
{f.emoji}
</div>
))}
<span className="text-sm text-slate-400 ml-2">6 friends</span>
</div>
</div>
</section>
{/* Intro text */}
<section className="max-w-7xl mx-auto px-6 pb-6">
<p className="text-center text-sm text-slate-400 max-w-2xl mx-auto">
This demo shows how <span className="text-slate-200 font-medium">rMaps</span> works at a
real event. See your friends on the camp map, check their status, and find each other without
sharing your location with any central server.
</p>
</section>
{/* Main Demo Content */}
<section className="max-w-7xl mx-auto px-6 pb-16">
<div className="grid lg:grid-cols-3 gap-6">
{/* Map - takes 2 columns */}
<div className="lg:col-span-2">
<div className="bg-slate-800/50 rounded-2xl border border-slate-700/50 overflow-hidden">
<div className="flex items-center justify-between px-5 py-3 border-b border-slate-700/50">
<div className="flex items-center gap-2">
<span className="text-xl">🗺</span>
<span className="font-semibold text-sm">Camp Map</span>
</div>
<div className="flex items-center gap-2">
<span className="text-xs text-slate-400">Last updated 2 min ago</span>
</div>
</div>
<div className="p-4">
<CampMap />
</div>
</div>
</div>
{/* Friend List - 1 column */}
<div className="lg:col-span-1">
<FriendListPanel />
</div>
</div>
</section>
{/* How It Works (brief) */}
<section className="max-w-7xl mx-auto px-6 pb-16">
<h2 className="text-2xl font-bold text-center mb-8">How rMaps Works at Events</h2>
<div className="grid sm:grid-cols-3 gap-6">
<div className="bg-slate-800/30 rounded-xl border border-slate-700/30 p-6 text-center">
<div className="w-12 h-12 mx-auto mb-4 bg-emerald-500/10 rounded-xl flex items-center justify-center text-2xl">
📱
</div>
<h3 className="font-semibold mb-2 text-slate-200">Open &amp; Share</h3>
<p className="text-sm text-slate-400">
Create a map room and share the link with your crew. No app install needed.
</p>
</div>
<div className="bg-slate-800/30 rounded-xl border border-slate-700/30 p-6 text-center">
<div className="w-12 h-12 mx-auto mb-4 bg-indigo-500/10 rounded-xl flex items-center justify-center text-2xl">
📍
</div>
<h3 className="font-semibold mb-2 text-slate-200">See Everyone</h3>
<p className="text-sm text-slate-400">
Friends appear on the map in real time. Set your status so everyone knows where you are.
</p>
</div>
<div className="bg-slate-800/30 rounded-xl border border-slate-700/30 p-6 text-center">
<div className="w-12 h-12 mx-auto mb-4 bg-rose-500/10 rounded-xl flex items-center justify-center text-2xl">
🔒
</div>
<h3 className="font-semibold mb-2 text-slate-200">Stay Private</h3>
<p className="text-sm text-slate-400">
Only people in your room see your location. Go invisible anytime. No tracking.
</p>
</div>
</div>
</section>
{/* Bottom CTA */}
<section className="max-w-7xl mx-auto px-6 pb-20 text-center">
<div className="bg-slate-800/50 rounded-2xl border border-slate-700/50 p-10">
<h2 className="text-3xl font-bold mb-3">Ready to Find Your Friends?</h2>
<p className="text-slate-400 mb-6 max-w-lg mx-auto">
Create a map room for your next event. Share the link, and never lose your crew in the crowd again.
</p>
<Link
href="/"
className="inline-block px-8 py-4 bg-emerald-600 hover:bg-emerald-500 rounded-xl text-lg font-medium transition-all shadow-lg shadow-emerald-900/30"
>
Create Your Map
</Link>
</div>
</section>
{/* Footer */}
<footer className="border-t border-slate-700/50 py-8">
<div className="max-w-7xl mx-auto px-6">
<div className="flex flex-wrap items-center justify-center gap-4 text-sm text-slate-500 mb-4">
<span className="font-medium text-slate-400">r* Ecosystem</span>
<a href="https://rspace.online" className="hover:text-slate-300 transition-colors">🌌 rSpace</a>
<a href="https://rmaps.online" className="hover:text-slate-300 transition-colors font-medium text-slate-300">🗺 rMaps</a>
<a href="https://rnotes.online" className="hover:text-slate-300 transition-colors">📝 rNotes</a>
<a href="https://rvote.online" className="hover:text-slate-300 transition-colors">🗳 rVote</a>
<a href="https://rfunds.online" className="hover:text-slate-300 transition-colors">💰 rFunds</a>
<a href="https://rtrips.online" className="hover:text-slate-300 transition-colors"> rTrips</a>
<a href="https://rcart.online" className="hover:text-slate-300 transition-colors">🛒 rCart</a>
<a href="https://rwallet.online" className="hover:text-slate-300 transition-colors">💼 rWallet</a>
<a href="https://rfiles.online" className="hover:text-slate-300 transition-colors">📁 rFiles</a>
<a href="https://rnetwork.online" className="hover:text-slate-300 transition-colors">🌐 rNetwork</a>
</div>
<p className="text-center text-xs text-slate-600">
Part of the r* ecosystem collaborative tools for communities.
</p>
</div>
</footer>
</div>
)
}

View File

@ -2,6 +2,7 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import Link from 'next/link';
import { nanoid } from 'nanoid'; import { nanoid } from 'nanoid';
import { AuthButton } from '@/components/AuthButton'; import { AuthButton } from '@/components/AuthButton';
import { useAuthStore } from '@/stores/auth'; import { useAuthStore } from '@/stores/auth';
@ -99,14 +100,165 @@ export default function HomePage() {
}; };
return ( return (
<main className="min-h-screen flex flex-col items-center justify-center p-4"> <div className="min-h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900">
<div className="max-w-md w-full space-y-8"> {/* ── Hero Section ─────────────────────────────────────────── */}
{/* Logo/Title */} <section className="relative overflow-hidden">
<div className="text-center"> {/* Subtle background grid */}
<h1 className="text-5xl font-bold mb-2"> <div className="absolute inset-0 opacity-[0.03]" style={{
backgroundImage: 'radial-gradient(circle, #10b981 1px, transparent 1px)',
backgroundSize: '40px 40px',
}} />
<div className="relative max-w-5xl mx-auto px-6 pt-16 pb-12 text-center">
{/* Logo */}
<div className="flex items-center justify-center gap-3 mb-8">
<div className="w-12 h-12 bg-gradient-to-br from-emerald-400 to-emerald-600 rounded-xl flex items-center justify-center font-bold text-slate-900 text-lg">
rM
</div>
<h1 className="text-4xl sm:text-5xl font-bold">
<span className="text-rmaps-primary">r</span>Maps <span className="text-rmaps-primary">r</span>Maps
</h1> </h1>
<p className="text-white/60">Find your friends at events</p> </div>
{/* Headline */}
<h2 className="text-3xl sm:text-5xl font-bold mb-4 bg-gradient-to-r from-emerald-300 via-teal-200 to-cyan-300 bg-clip-text text-transparent leading-tight">
Find Your Friends, Anywhere
</h2>
<p className="text-lg sm:text-xl text-white/60 max-w-2xl mx-auto mb-8">
Privacy-first real-time location sharing for events, festivals, and camps.
See where your crew is without trusting a central server.
</p>
{/* CTA buttons */}
<div className="flex flex-col sm:flex-row items-center justify-center gap-4 mb-6">
<Link
href="/demo"
className="px-8 py-3.5 bg-emerald-600 hover:bg-emerald-500 text-white font-medium rounded-xl transition-all shadow-lg shadow-emerald-900/30 text-lg"
>
Try the Demo
</Link>
<a
href="#get-started"
className="px-8 py-3.5 bg-white/5 hover:bg-white/10 text-white font-medium rounded-xl transition-colors border border-white/10 text-lg"
>
Get Started
</a>
</div>
<p className="text-sm text-white/40">
No app install. No sign-up required to join a room.
</p>
</div>
</section>
{/* ── Feature Cards ────────────────────────────────────────── */}
<section className="max-w-5xl mx-auto px-6 pb-16">
<div className="grid sm:grid-cols-3 gap-6">
{/* Real-time GPS */}
<div className="bg-slate-800/40 rounded-2xl border border-slate-700/40 p-6 text-center hover:border-emerald-500/30 transition-colors">
<div className="w-14 h-14 mx-auto mb-4 bg-emerald-500/10 rounded-xl flex items-center justify-center">
<svg className="w-7 h-7 text-emerald-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M15 10.5a3 3 0 11-6 0 3 3 0 016 0z" />
<path strokeLinecap="round" strokeLinejoin="round" d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1115 0z" />
</svg>
</div>
<h3 className="text-lg font-semibold mb-2 text-white">Real-time GPS</h3>
<p className="text-sm text-white/50">
Share your live location with friends. See everyone on the map updating in real time as you move.
</p>
</div>
{/* Event Maps */}
<div className="bg-slate-800/40 rounded-2xl border border-slate-700/40 p-6 text-center hover:border-indigo-500/30 transition-colors">
<div className="w-14 h-14 mx-auto mb-4 bg-indigo-500/10 rounded-xl flex items-center justify-center">
<svg className="w-7 h-7 text-indigo-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M9 6.75V15m6-6v8.25m.503 3.498l4.875-2.437c.381-.19.622-.58.622-1.006V4.82c0-.836-.88-1.38-1.628-1.006l-3.869 1.934c-.317.159-.69.159-1.006 0L9.503 3.252a1.125 1.125 0 00-1.006 0L3.622 5.689C3.24 5.88 3 6.27 3 6.695V19.18c0 .836.88 1.38 1.628 1.006l3.869-1.934c.317-.159.69-.159 1.006 0l4.994 2.497c.317.158.69.158 1.006 0z" />
</svg>
</div>
<h3 className="text-lg font-semibold mb-2 text-white">Event Maps</h3>
<p className="text-sm text-white/50">
Navigate festivals, camps, and conferences. Custom maps with labeled stages, food courts, and meeting points.
</p>
</div>
{/* Privacy First */}
<div className="bg-slate-800/40 rounded-2xl border border-slate-700/40 p-6 text-center hover:border-rose-500/30 transition-colors">
<div className="w-14 h-14 mx-auto mb-4 bg-rose-500/10 rounded-xl flex items-center justify-center">
<svg className="w-7 h-7 text-rose-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75L11.25 15 15 9.75m-3-7.036A11.959 11.959 0 013.598 6 11.99 11.99 0 003 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285z" />
</svg>
</div>
<h3 className="text-lg font-semibold mb-2 text-white">Privacy First</h3>
<p className="text-sm text-white/50">
Zero-knowledge architecture. You control who sees you. Go invisible anytime. No tracking, no data collection.
</p>
</div>
</div>
</section>
{/* ── How It Works ─────────────────────────────────────────── */}
<section className="max-w-5xl mx-auto px-6 pb-20">
<h2 className="text-2xl sm:text-3xl font-bold text-center mb-10 text-white">How It Works</h2>
<div className="grid sm:grid-cols-3 gap-8">
{/* Step 1 */}
<div className="flex flex-col items-center text-center">
<div className="w-12 h-12 rounded-full bg-emerald-500/15 border border-emerald-500/30 flex items-center justify-center text-emerald-400 font-bold text-lg mb-4">
1
</div>
<h3 className="font-semibold text-white mb-2">Create a Map Room</h3>
<p className="text-sm text-white/50">
Sign in and create a room for your event. Get a shareable link like <span className="text-white/70 font-mono text-xs">rmaps.online/ccc-camp</span>
</p>
</div>
{/* Step 2 */}
<div className="flex flex-col items-center text-center">
<div className="w-12 h-12 rounded-full bg-indigo-500/15 border border-indigo-500/30 flex items-center justify-center text-indigo-400 font-bold text-lg mb-4">
2
</div>
<h3 className="font-semibold text-white mb-2">Share with Friends</h3>
<p className="text-sm text-white/50">
Send the link to your crew. They join instantly from any device -- no app download, no account needed.
</p>
</div>
{/* Step 3 */}
<div className="flex flex-col items-center text-center">
<div className="w-12 h-12 rounded-full bg-cyan-500/15 border border-cyan-500/30 flex items-center justify-center text-cyan-400 font-bold text-lg mb-4">
3
</div>
<h3 className="font-semibold text-white mb-2">Find Each Other</h3>
<p className="text-sm text-white/50">
See everyone on the map in real time. Set your status, share meeting points, and never lose your friends again.
</p>
</div>
</div>
{/* Connector lines (decorative) */}
<div className="hidden sm:flex items-center justify-center mt-8">
<div className="flex items-center gap-2 text-white/20 text-sm">
<span>Built for</span>
<a
href="https://events.ccc.de/"
target="_blank"
rel="noopener noreferrer"
className="text-rmaps-primary/60 hover:text-rmaps-primary transition-colors"
>
CCC events
</a>
<span>and beyond</span>
</div>
</div>
</section>
{/* ── Get Started (existing login/room interface) ──────────── */}
<section id="get-started" className="scroll-mt-8 pb-16">
<main className="flex flex-col items-center px-4">
<div className="max-w-md w-full space-y-8">
{/* Section heading */}
<div className="text-center">
<h2 className="text-2xl sm:text-3xl font-bold mb-2 text-white">Get Started</h2>
<p className="text-white/50 text-sm mb-4">Create or join a map room</p>
<div className="mt-3"> <div className="mt-3">
<AuthButton /> <AuthButton />
</div> </div>
@ -133,7 +285,7 @@ export default function HomePage() {
<div className="room-panel rounded-2xl p-6 space-y-6"> <div className="room-panel rounded-2xl p-6 space-y-6">
{/* User Setup */} {/* User Setup */}
<div className="space-y-4"> <div className="space-y-4">
<h2 className="text-lg font-medium">Your Profile</h2> <h3 className="text-lg font-medium">Your Profile</h3>
<div> <div>
<label className="block text-sm text-white/60 mb-2">Your Name</label> <label className="block text-sm text-white/60 mb-2">Your Name</label>
@ -241,23 +393,31 @@ export default function HomePage() {
</div> </div>
)} )}
</div> </div>
{/* Footer */}
<div className="text-center text-white/40 text-sm space-y-2">
<p>Privacy-first location sharing</p>
<p>
Built for{' '}
<a
href="https://events.ccc.de/"
target="_blank"
rel="noopener noreferrer"
className="text-rmaps-primary hover:underline"
>
CCC events
</a>
</p>
</div>
</div> </div>
</main> </main>
</section>
{/* ── Ecosystem Footer ─────────────────────────────────────── */}
<footer className="border-t border-slate-700/50 py-8">
<div className="max-w-7xl mx-auto px-6">
<div className="flex flex-wrap items-center justify-center gap-4 text-sm text-slate-500 mb-4">
<span className="font-medium text-slate-400">r* Ecosystem</span>
<a href="https://rspace.online" className="hover:text-slate-300 transition-colors">🌌 rSpace</a>
<a href="https://rmaps.online" className="hover:text-slate-300 transition-colors font-medium text-slate-300">🗺 rMaps</a>
<a href="https://rnotes.online" className="hover:text-slate-300 transition-colors">📝 rNotes</a>
<a href="https://rvote.online" className="hover:text-slate-300 transition-colors">🗳 rVote</a>
<a href="https://rfunds.online" className="hover:text-slate-300 transition-colors">💰 rFunds</a>
<a href="https://rtrips.online" className="hover:text-slate-300 transition-colors"> rTrips</a>
<a href="https://rcart.online" className="hover:text-slate-300 transition-colors">🛒 rCart</a>
<a href="https://rwallet.online" className="hover:text-slate-300 transition-colors">💼 rWallet</a>
<a href="https://rfiles.online" className="hover:text-slate-300 transition-colors">📁 rFiles</a>
<a href="https://rnetwork.online" className="hover:text-slate-300 transition-colors">🌐 rNetwork</a>
</div>
<p className="text-center text-xs text-slate-600">
Part of the r* ecosystem collaborative tools for communities.
</p>
</div>
</footer>
</div>
); );
} }