321 lines
15 KiB
TypeScript
321 lines
15 KiB
TypeScript
/**
|
|
* Maps module landing page — static HTML, no React.
|
|
*/
|
|
export function renderLanding(): string {
|
|
return `
|
|
<!-- Hero -->
|
|
<div class="rl-hero">
|
|
<span class="rl-tagline" style="color:#10b981;background:rgba(16,185,129,0.1);border-color:rgba(16,185,129,0.2)">rMaps</span>
|
|
<h1 class="rl-heading" style="background:linear-gradient(135deg,#6ee7b7,#2dd4bf,#67e8f9);-webkit-background-clip:text;background-clip:text">
|
|
Real-Time Collaborative Maps
|
|
</h1>
|
|
<p class="rl-subtext">
|
|
Share live locations, navigate indoor and outdoor spaces, coordinate meetups
|
|
— all from the browser. No app install. No tracking. No data collection.
|
|
</p>
|
|
<div class="rl-cta-row">
|
|
<a href="https://demo.rspace.online/rmaps" class="rl-cta-primary" id="ml-primary"
|
|
style="background:linear-gradient(135deg,#059669,#0d9488)">Try the Demo</a>
|
|
<a href="/create-space" class="rl-cta-secondary">Create a Room</a>
|
|
</div>
|
|
<p style="font-size:0.82rem;color:#64748b;margin-top:1rem">No sign-up required to join. Works on any device.</p>
|
|
</div>
|
|
|
|
<!-- Core Features -->
|
|
<section class="rl-section">
|
|
<div class="rl-container">
|
|
<span class="rl-tagline" style="color:#10b981;background:rgba(16,185,129,0.1);border-color:rgba(16,185,129,0.2);display:block;text-align:center;margin:0 auto 1rem">Core Features</span>
|
|
<h2 class="rl-heading" style="text-align:center;background:linear-gradient(135deg,#6ee7b7,#2dd4bf);-webkit-background-clip:text;background-clip:text">
|
|
Everything you need to find your friends
|
|
</h2>
|
|
<div class="rl-grid-4" style="margin-top:2rem">
|
|
<div class="rl-card">
|
|
<div class="rl-icon-box" style="background:rgba(16,185,129,0.12);color:#10b981">
|
|
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15 10.5a3 3 0 11-6 0 3 3 0 016 0z" />
|
|
<path stroke-linecap="round" stroke-linejoin="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>Live GPS Sharing</h3>
|
|
<p>
|
|
Real-time location updates via WebSocket. See everyone on the map
|
|
as they move, with stale detection and high-accuracy fallback.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="rl-card">
|
|
<div class="rl-icon-box" style="background:rgba(6,182,212,0.12);color:#06b6d4">
|
|
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
|
|
<path stroke-linecap="round" stroke-linejoin="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>Indoor + Outdoor Nav</h3>
|
|
<p>
|
|
Turn-by-turn routing via OSRM outdoors, seamless switch to c3nav
|
|
for indoor venues. Multi-floor, level-aware navigation.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="rl-card">
|
|
<div class="rl-icon-box" style="background:rgba(99,102,241,0.12);color:#6366f1">
|
|
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M3 3v1.5M3 21v-6m0 0l2.77-.693a9 9 0 016.208.682l.108.054a9 9 0 006.086.71l3.114-.732a48.524 48.524 0 01-.005-10.499l-3.11.732a9 9 0 01-6.085-.711l-.108-.054a9 9 0 00-6.208-.682L3 4.5M3 15V4.5" />
|
|
</svg>
|
|
</div>
|
|
<h3>Meeting Points</h3>
|
|
<p>
|
|
Drop waypoints for meetups, events, and points of interest.
|
|
Search by address, share coordinates, or pin from your location.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="rl-card">
|
|
<div class="rl-icon-box" style="background:rgba(244,63,94,0.12);color:#f43f5e">
|
|
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
|
|
<path stroke-linecap="round" stroke-linejoin="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>Privacy First</h3>
|
|
<p>
|
|
Ghost mode, precision levels, one-toggle location sharing.
|
|
Zero tracking, zero data collection. You control who sees you.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- What Makes rMaps Different -->
|
|
<section class="rl-section rl-section--alt">
|
|
<div class="rl-container">
|
|
<span class="rl-tagline" style="color:#2dd4bf;background:rgba(45,212,191,0.1);border-color:rgba(45,212,191,0.2);display:block;text-align:center;margin:0 auto 1rem">Beyond Google Maps</span>
|
|
<h2 class="rl-heading" style="text-align:center;background:linear-gradient(135deg,#6ee7b7,#2dd4bf);-webkit-background-clip:text;background-clip:text">
|
|
What makes rMaps different
|
|
</h2>
|
|
<div class="rl-grid-2" style="margin-top:2rem">
|
|
<div class="rl-integration">
|
|
<div class="rl-icon-box" style="background:rgba(16,185,129,0.12);color:#10b981;font-size:1.25rem;flex-shrink:0">
|
|
🏕️
|
|
</div>
|
|
<div>
|
|
<h3>CCC Event Integration</h3>
|
|
<p>
|
|
Native c3nav integration for 39C3, Camp, and other CCC events. Indoor maps with
|
|
multi-floor routing, venue bounds detection, and automatic map switching
|
|
when you walk inside.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="rl-integration">
|
|
<div class="rl-icon-box" style="background:rgba(6,182,212,0.12);color:#06b6d4;font-size:1.25rem;flex-shrink:0">
|
|
📡
|
|
</div>
|
|
<div>
|
|
<h3>Location Pinging</h3>
|
|
<p>
|
|
Request a friend's location with one tap. Push notifications via
|
|
Web Push API with vibration alerts. Works even when the app is
|
|
backgrounded via service worker.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="rl-integration">
|
|
<div class="rl-icon-box" style="background:rgba(99,102,241,0.12);color:#6366f1;font-size:1.25rem;flex-shrink:0">
|
|
📦
|
|
</div>
|
|
<div>
|
|
<h3>Google Maps Import</h3>
|
|
<p>
|
|
Import your saved places from Google Takeout ZIP exports. GeoJSON
|
|
parsing, auto-emoji mapping by place type, and preview before
|
|
importing.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="rl-integration">
|
|
<div class="rl-icon-box" style="background:rgba(245,158,11,0.12);color:#f59e0b;font-size:1.25rem;flex-shrink:0">
|
|
📱
|
|
</div>
|
|
<div>
|
|
<h3>PWA & Offline Mode</h3>
|
|
<p>
|
|
Install as a native app. Three-tier service worker caching keeps
|
|
maps accessible offline with up to 500 cached tiles. Background
|
|
sync handles location updates.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="rl-integration">
|
|
<div class="rl-icon-box" style="background:rgba(139,92,246,0.12);color:#8b5cf6;font-size:1.25rem;flex-shrink:0">
|
|
🔗
|
|
</div>
|
|
<div>
|
|
<h3>Instant Room Sharing</h3>
|
|
<p>
|
|
Generate a QR code or shareable link for any room. Friends scan or tap
|
|
to join instantly — no account needed, no app download.
|
|
Native share dialog on mobile.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="rl-integration">
|
|
<div class="rl-icon-box" style="background:rgba(244,63,94,0.12);color:#f43f5e;font-size:1.25rem;flex-shrink:0">
|
|
🔄
|
|
</div>
|
|
<div>
|
|
<h3>Conflict-Free Sync</h3>
|
|
<p>
|
|
Automerge CRDT architecture ensures everyone sees the same map state,
|
|
even through disconnections. WebSocket real-time sync with automatic
|
|
reconnection and state recovery.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- How it Works -->
|
|
<section class="rl-section">
|
|
<div class="rl-container">
|
|
<span class="rl-tagline" style="color:#06b6d4;background:rgba(6,182,212,0.1);border-color:rgba(6,182,212,0.2);display:block;text-align:center;margin:0 auto 1rem">How It Works</span>
|
|
<h2 class="rl-heading" style="text-align:center;background:linear-gradient(135deg,#6ee7b7,#2dd4bf);-webkit-background-clip:text;background-clip:text">
|
|
Three steps to find your crew
|
|
</h2>
|
|
<div class="rl-grid-3" style="margin-top:2rem">
|
|
<div class="rl-step">
|
|
<div class="rl-step__num" style="background:rgba(16,185,129,0.15);color:#10b981">1</div>
|
|
<h3>Create a Map Room</h3>
|
|
<p>
|
|
Sign in and name your room. Get a shareable link or a custom slug.
|
|
</p>
|
|
</div>
|
|
<div class="rl-step">
|
|
<div class="rl-step__num" style="background:rgba(6,182,212,0.15);color:#06b6d4">2</div>
|
|
<h3>Share with Friends</h3>
|
|
<p>
|
|
Send the link or scan the QR code. Friends join from any browser
|
|
— no app download, no account creation needed.
|
|
</p>
|
|
</div>
|
|
<div class="rl-step">
|
|
<div class="rl-step__num" style="background:rgba(99,102,241,0.15);color:#6366f1">3</div>
|
|
<h3>Navigate Together</h3>
|
|
<p>
|
|
See everyone in real time. Drop meeting points, get turn-by-turn
|
|
directions, and ping friends when you need to regroup.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Use Cases -->
|
|
<section class="rl-section rl-section--alt">
|
|
<div class="rl-container">
|
|
<span class="rl-tagline" style="color:#6366f1;background:rgba(99,102,241,0.1);border-color:rgba(99,102,241,0.2);display:block;text-align:center;margin:0 auto 1rem">Built For</span>
|
|
<h2 class="rl-heading" style="text-align:center;background:linear-gradient(135deg,#6ee7b7,#2dd4bf);-webkit-background-clip:text;background-clip:text">
|
|
Maps for every gathering
|
|
</h2>
|
|
<div class="rl-grid-3" style="margin-top:2rem">
|
|
<div class="rl-card rl-card--center">
|
|
<div style="font-size:2rem;margin-bottom:0.75rem">🏕️</div>
|
|
<h3>Festivals & Camps</h3>
|
|
<p>
|
|
Navigate massive venues with indoor maps. Find stages, food courts,
|
|
and your crew across multi-day events like CCC Camp.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="rl-card rl-card--center">
|
|
<div style="font-size:2rem;margin-bottom:0.75rem">🏙️</div>
|
|
<h3>City Exploration</h3>
|
|
<p>
|
|
Exploring a new city with friends? Share locations, drop pins at
|
|
restaurants and landmarks, import your Google Maps saved places.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="rl-card rl-card--center">
|
|
<div style="font-size:2rem;margin-bottom:0.75rem">🤝</div>
|
|
<h3>Group Coordination</h3>
|
|
<p>
|
|
Conferences, retreats, team offsites. Set meeting points, ping
|
|
stragglers, and get walking directions to the next session.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<p style="text-align:center;font-size:0.82rem;color:#64748b;margin-top:1.5rem">
|
|
First built for <a href="https://events.ccc.de/" target="_blank" rel="noopener noreferrer" style="color:rgba(16,185,129,0.7)">CCC events</a> — now for any gathering.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Technical Highlights -->
|
|
<section class="rl-section">
|
|
<div class="rl-container">
|
|
<span class="rl-tagline" style="color:#94a3b8;background:rgba(100,116,139,0.1);border-color:rgba(100,116,139,0.2);display:block;text-align:center;margin:0 auto 1rem">Under the Hood</span>
|
|
<h2 class="rl-heading" style="text-align:center;background:linear-gradient(135deg,#6ee7b7,#2dd4bf);-webkit-background-clip:text;background-clip:text">
|
|
Built on open standards
|
|
</h2>
|
|
<div class="rl-grid-4" style="margin-top:2rem">
|
|
<div class="rl-card rl-card--center" style="padding:1rem">
|
|
<p style="font-size:0.875rem;font-weight:600;color:#e2e8f0">MapLibre GL</p>
|
|
<p style="font-size:0.75rem;color:#64748b;margin-top:0.25rem">Open-source maps</p>
|
|
</div>
|
|
<div class="rl-card rl-card--center" style="padding:1rem">
|
|
<p style="font-size:0.875rem;font-weight:600;color:#e2e8f0">OSRM</p>
|
|
<p style="font-size:0.75rem;color:#64748b;margin-top:0.25rem">Outdoor routing</p>
|
|
</div>
|
|
<div class="rl-card rl-card--center" style="padding:1rem">
|
|
<p style="font-size:0.875rem;font-weight:600;color:#e2e8f0">c3nav</p>
|
|
<p style="font-size:0.75rem;color:#64748b;margin-top:0.25rem">Indoor navigation</p>
|
|
</div>
|
|
<div class="rl-card rl-card--center" style="padding:1rem">
|
|
<p style="font-size:0.875rem;font-weight:600;color:#e2e8f0">Automerge</p>
|
|
<p style="font-size:0.75rem;color:#64748b;margin-top:0.25rem">CRDT sync</p>
|
|
</div>
|
|
<div class="rl-card rl-card--center" style="padding:1rem">
|
|
<p style="font-size:0.875rem;font-weight:600;color:#e2e8f0">Web Push</p>
|
|
<p style="font-size:0.75rem;color:#64748b;margin-top:0.25rem">Notifications</p>
|
|
</div>
|
|
<div class="rl-card rl-card--center" style="padding:1rem">
|
|
<p style="font-size:0.875rem;font-weight:600;color:#e2e8f0">Service Worker</p>
|
|
<p style="font-size:0.75rem;color:#64748b;margin-top:0.25rem">Offline & PWA</p>
|
|
</div>
|
|
<div class="rl-card rl-card--center" style="padding:1rem">
|
|
<p style="font-size:0.875rem;font-weight:600;color:#e2e8f0">WebSocket</p>
|
|
<p style="font-size:0.75rem;color:#64748b;margin-top:0.25rem">Real-time sync</p>
|
|
</div>
|
|
<div class="rl-card rl-card--center" style="padding:1rem">
|
|
<p style="font-size:0.875rem;font-weight:600;color:#e2e8f0">EncryptID</p>
|
|
<p style="font-size:0.75rem;color:#64748b;margin-top:0.25rem">Identity & auth</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- CTA -->
|
|
<section class="rl-section rl-section--alt">
|
|
<div class="rl-container" style="text-align:center">
|
|
<h2 class="rl-heading" style="background:linear-gradient(135deg,#6ee7b7,#2dd4bf);-webkit-background-clip:text;background-clip:text">
|
|
Ready to find your crew?
|
|
</h2>
|
|
<p class="rl-subtext">Create a map room and share the link. That's it.</p>
|
|
<div class="rl-cta-row">
|
|
<a href="https://demo.rspace.online/rmaps" class="rl-cta-primary"
|
|
style="background:linear-gradient(135deg,#059669,#0d9488)">Try the Demo</a>
|
|
<a href="/create-space" class="rl-cta-secondary">Create a Space</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<div class="rl-back"><a href="/">← Back to rSpace</a></div>
|
|
`;
|
|
}
|