From 2f4258aa328f14aa488de2d16a8299e5e3cbd992 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Fri, 10 Apr 2026 22:30:55 -0400 Subject: [PATCH] feat: refresh landing page with glow animation, SVG icons, interop diagram MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restore personality from old Next.js landing: animated hero glow, playful "MySpace → (you)rSpace" copy, SVG feature cards with teal/indigo accents, shield graphic for EncryptID, interoperability ASCII diagram, sharper philosophy copy, ecosystem grid with r*.online domains, richer footer. Co-Authored-By: Claude Opus 4.6 --- server/landing.ts | 417 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 375 insertions(+), 42 deletions(-) diff --git a/server/landing.ts b/server/landing.ts index f7f96782..f55cb6a2 100644 --- a/server/landing.ts +++ b/server/landing.ts @@ -17,10 +17,11 @@ export function renderMainLanding(modules: ModuleInfo[]): string { const ecosystemCards = modules .map( (m) => ` - -
${m.icon}
-

${escapeHtml(m.name)}

-

${escapeHtml(m.description)}

+
+
${m.icon}
+

${escapeHtml(m.name)}

+ ${m.standaloneDomain ? `${escapeHtml(m.standaloneDomain)}` : ""} +

${escapeHtml(m.description)}

`, ) .join("\n"); @@ -76,22 +77,31 @@ export function renderMainLanding(modules: ModuleInfo[]): string { -
+
+
Community Platform

(you)rSpace

-

Remember back when the internet was cool?

+

+ Remember back when the internet was cool? +

+

+ We may not have MySpace anymore, but we have (you)rSpace. +

- A collaborative, local-first platform with ${modules.length}+ interoperable tools. - Own your data, run your community, connect your world — no landlords required. + Build digital spaces to collaborate on improving your physical world. + Local-first, zero-knowledge privacy, outside the walls of big tech.

Local-First + Self-Hosted + Open Source + Offline-Ready
@@ -104,33 +114,45 @@ export function renderMainLanding(modules: ModuleInfo[]): string { Each tool works on its own, and they all work together.

-
-
💰
+
+
+ +

Community Funds

Budget rivers, revenue splits, and enoughness thresholds. Transparent finances with quadratic funding built in.

-
-
💬
+
+
+ +

Messaging & Forum

Real-time chat, threaded discussions, and async forums. All synced across devices with CRDT magic.

-
-
📁
+
+
+ +

Files & Media

Upload, organize, and share with memory cards. Public links, folder trees, and metadata that travels with content.

-
-
🔐
+
+
+ +

Passkey Identity

One passwordless login for the entire ecosystem. EncryptID uses WebAuthn — no passwords to leak, no accounts to hack.

-
-
📊
+
+
+ +

Dashboards & Data

Community analytics, voting results, spatial canvases. See everything at a glance and drill into what matters.

-
-
🛡
+
+
+ +

Privacy by Design

Your data lives on your device first. End-to-end encrypted sync, per-document keys, zero-knowledge architecture.

@@ -145,23 +167,31 @@ export function renderMainLanding(modules: ModuleInfo[]): string {
EncryptID

One Passkey for Everything

+

+ Secure by default, not by opt-in. +

Sign in once with your fingerprint or device PIN. Your passkey works - across every rApp — no passwords, no email verification loops, - no third-party auth providers. + across every rApp — no passwords, no email loops, + no third-party auth providers watching over your shoulder.

    -
  • WebAuthn passkeys — phishing-resistant by default
  • +
  • WebAuthn passkeys — phishing-resistant, device-bound credentials
  • Guardian recovery — 2-of-3 trusted contacts restore access
  • -
  • Device linking — QR scan adds your phone or tablet
  • -
  • One RP ID — shared across all r*.online domains
  • +
  • Device linking — scan a QR to add your phone or tablet
  • +
  • One RP ID — works across all r*.online domains
-
-
🔒
-

Passwordless Login

-

Touch your fingerprint sensor, tap your security key, or use your device PIN. That’s it.

+
+ + + + + + + +

Touch. Tap. Done.

@@ -193,17 +223,52 @@ export function renderMainLanding(modules: ModuleInfo[]): string {

Only changed bytes travel over the wire. Reconnect after days offline and catch up in seconds.

+

+ Under the hood: Automerge CRDTs model every document as a mergeable data structure. + IndexedDB persists the full state locally so you never lose work. + A Service Worker caches the app shell for instant loads — even without a network connection. +

+
+ + + +
+
+

Interoperable by Design

+

+ Every rApp reads and writes to the same sync layer. + No import/export rituals — data flows between tools automatically. +

+
+
  rDocs   rCal   rTasks   rMaps   rWallet  ...
+    |       |       |       |       |
+    v       v       v       v       v
+ +--------------------------------------+
+ |     Automerge  Sync  Layer           |
+ |   (encrypted, per-document keys)     |
+ +--------------------------------------+
+    |       |       |       |       |
+    v       v       v       v       v
+  Your    Your    Your    Your    Your
+ Device  Phone  Laptop  Server  Backup
+
-
+

The Internet as It Was Always Meant to Be

-

+

No algorithms deciding what you see. No ads. No data harvesting. Just tools that work for you, run by you, owned by you. - rSpace is infrastructure for communities who refuse to rent their digital commons. +

+

+ rSpace is infrastructure for communities who refuse to rent their digital commons + from landlords who read the mail, count the footsteps, and sell the maps. +

+

+ Your space. Your community. Your rules.

Learn More @@ -212,7 +277,7 @@ export function renderMainLanding(modules: ModuleInfo[]): string {
-
+

${modules.length} rApps and Growing

@@ -227,14 +292,25 @@ export function renderMainLanding(modules: ModuleInfo[]): string {

@@ -432,7 +508,9 @@ const SPACE_DASHBOARD_CSS = ` `; const MAIN_LANDING_CSS = ` -/* Main landing page extras (on top of rl-* utilities) */ +/* ── Main landing page extras (on top of rl-* utilities) ── */ + +/* Background + diagonal stripe overlay */ body { background: linear-gradient( 170deg, @@ -445,8 +523,57 @@ body { ); background-attachment: fixed; } +body::before { + content: ""; + position: fixed; inset: 0; + background: repeating-linear-gradient( + -45deg, + transparent, + transparent 60px, + rgba(20,184,166,0.015) 60px, + rgba(20,184,166,0.015) 61px + ); + pointer-events: none; + z-index: 0; +} +[data-theme="light"] body { + background: linear-gradient(170deg, #f8fafc 0%, #f1f5f9 50%, #e2e8f0 100%); +} +[data-theme="light"] body::before { + background: repeating-linear-gradient( + -45deg, + transparent, + transparent 60px, + rgba(20,184,166,0.03) 60px, + rgba(20,184,166,0.03) 61px + ); +} + +/* ── Hero ── */ +.hero-glow-wrap { position: relative; overflow: hidden; } +.hero-glow { + position: absolute; + top: 50%; left: 50%; + width: 600px; height: 600px; + transform: translate(-50%, -60%); + border-radius: 50%; + background: radial-gradient(circle, rgba(20,184,166,0.15) 0%, transparent 70%); + animation: hero-pulse 4s ease-in-out infinite; + pointer-events: none; + z-index: 0; +} +[data-theme="light"] .hero-glow { + background: radial-gradient(circle, rgba(20,184,166,0.1) 0%, transparent 70%); +} +@keyframes hero-pulse { + 0%, 100% { opacity: 0.6; transform: translate(-50%, -60%) scale(1); } + 50% { opacity: 1; transform: translate(-50%, -60%) scale(1.08); } +} +.rl-hero > * { position: relative; z-index: 1; } + .main-wordmark { font-size: 3.5rem; + text-shadow: 0 0 40px rgba(20,184,166,0.2); } @media (min-width: 640px) { .main-wordmark { font-size: 4.5rem; } } .main-wordmark__accent { @@ -454,12 +581,218 @@ body { -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } + +.accent-cool { + color: var(--rs-accent); + font-weight: 700; + -webkit-text-fill-color: var(--rs-accent); +} + +/* Badge bar with star separators */ .main-badges { display: flex; gap: 0.5rem; justify-content: center; flex-wrap: wrap; + align-items: center; margin-top: 1.5rem; } +.main-badges .rl-badge { + font-weight: 800; + letter-spacing: 0.04em; +} +.badge-sep { + color: var(--rs-accent); + font-size: 0.5rem; + opacity: 0.6; +} + +/* ── Feature Cards (SVG icons, border glow) ── */ +.feat-card { + background: var(--rs-card-bg); + border: 2px solid var(--rs-card-border); + border-radius: 1rem; + padding: 1.75rem; + text-align: center; + transition: border-color 0.25s, box-shadow 0.25s, transform 0.2s; +} +.feat-card:hover { + transform: translateY(-2px); +} +.feat-card--teal:hover { + border-color: rgba(20,184,166,0.5); + box-shadow: 0 0 20px rgba(20,184,166,0.12); +} +.feat-card--indigo:hover { + border-color: rgba(99,102,241,0.5); + box-shadow: 0 0 20px rgba(99,102,241,0.12); +} +.feat-card__icon { + width: 3rem; height: 3rem; border-radius: 0.75rem; + display: flex; align-items: center; justify-content: center; + margin: 0 auto 1rem; + font-size: 1.5rem; +} +.feat-card--teal .feat-card__icon { + background: rgba(20,184,166,0.12); color: #14b8a6; +} +.feat-card--indigo .feat-card__icon { + background: rgba(99,102,241,0.12); color: #6366f1; +} +.feat-card h3 { + font-size: 0.95rem; font-weight: 600; color: var(--rs-text-primary); margin-bottom: 0.5rem; +} +.feat-card p { + font-size: 0.875rem; color: var(--rs-text-secondary); line-height: 1.6; +} + +/* ── EncryptID Visual ── */ +.encryptid-visual { + text-align: center; +} +.encryptid-shield { + width: 140px; height: 160px; + color: var(--rs-accent); + filter: drop-shadow(0 0 20px rgba(20,184,166,0.2)); +} +.encryptid-visual__label { + font-size: 0.9rem; font-weight: 600; + color: var(--rs-text-secondary); + margin-top: 1rem; +} + +/* ── Offline-First Explainer ── */ +.offline-explain { + text-align: center; + font-size: 0.85rem; + color: var(--rs-text-muted); + line-height: 1.65; + max-width: 640px; + margin: 2rem auto 0; + border-top: 1px solid var(--rs-border-subtle); + padding-top: 1.5rem; +} +.offline-explain strong { + color: var(--rs-text-secondary); + font-weight: 600; +} + +/* ── Interop Diagram ── */ +.interop-diagram { + margin-top: 2rem; +} +.interop-pre { + display: inline-block; + text-align: left; + font-family: "SF Mono", "Fira Code", "Cascadia Code", monospace; + font-size: 0.78rem; + line-height: 1.6; + color: var(--rs-text-secondary); + background: var(--rs-card-bg); + border: 1px solid var(--rs-card-border); + border-radius: 0.75rem; + padding: 1.5rem 2rem; + overflow-x: auto; + max-width: 100%; + box-shadow: 0 2px 12px rgba(0,0,0,0.15); +} +[data-theme="light"] .interop-pre { + box-shadow: 0 2px 12px rgba(0,0,0,0.06); +} + +/* ── Philosophy Punch ── */ +.philosophy-punch { + font-size: 1.3rem; + font-weight: 700; + background: var(--rs-gradient-brand); + -webkit-background-clip: text; -webkit-text-fill-color: transparent; + background-clip: text; + margin: 1.5rem 0 0; + letter-spacing: -0.01em; +} + +/* ── Ecosystem Cards ── */ +.eco-card { + background: var(--rs-card-bg); + border: 2px solid var(--rs-card-border); + border-radius: 1rem; + padding: 1.5rem; + text-align: center; + transition: border-color 0.25s, box-shadow 0.25s, transform 0.2s; + display: flex; flex-direction: column; align-items: center; +} +.eco-card:hover { + border-color: rgba(20,184,166,0.4); + box-shadow: 0 0 16px rgba(20,184,166,0.1); + transform: translateY(-2px); +} +.eco-card__icon { + font-size: 1.75rem; + margin-bottom: 0.5rem; +} +.eco-card__name { + font-size: 0.9rem; font-weight: 600; + color: var(--rs-text-primary); + margin: 0 0 0.15rem; +} +.eco-card__domain { + font-size: 0.65rem; font-weight: 600; + color: var(--rs-accent); + opacity: 0.75; + letter-spacing: 0.02em; + margin-bottom: 0.4rem; + display: block; +} +.eco-card__desc { + font-size: 0.78rem; color: var(--rs-text-secondary); + line-height: 1.5; margin: 0; +} + +/* ── Footer ── */ .main-footer { border-top: 1px solid var(--rs-border-subtle); - padding: 2.5rem 1.5rem; + padding: 2.5rem 1.5rem 2rem; +} +.footer-quicklinks { + display: flex; gap: 1.25rem; justify-content: center; flex-wrap: wrap; + margin-bottom: 1.25rem; +} +.footer-quicklinks a { + font-size: 0.75rem; font-weight: 600; + color: var(--rs-text-muted); + text-decoration: none; + transition: color 0.2s; +} +.footer-quicklinks a:hover { color: var(--rs-accent); } +.footer-tagline { + font-size: 0.8rem; font-weight: 700; + color: var(--rs-accent); + letter-spacing: 0.06em; + text-transform: uppercase; + margin: 0 0 1rem; + opacity: 0.7; +} +.footer-links { + display: flex; gap: 1.5rem; justify-content: center; flex-wrap: wrap; + margin-bottom: 1rem; +} +.footer-links a { + color: #94a3b8; font-size: 0.8rem; text-decoration: none; + transition: color 0.2s; +} +.footer-links a:hover { color: var(--rs-text-primary); } +.footer-tech { + color: #64748b; font-size: 0.75rem; margin: 0; +} + +/* ── Retro Shadow Utility ── */ +.retro-shadow { + box-shadow: 2px 2px 0 var(--rs-card-border); +} + +/* ── Responsive ── */ +@media (max-width: 480px) { + .main-wordmark { font-size: 2.75rem; } + .hero-glow { width: 350px; height: 350px; } + .interop-pre { font-size: 0.65rem; padding: 1rem; } + .philosophy-punch { font-size: 1.1rem; } + .footer-quicklinks { gap: 0.75rem; } } `;