diff --git a/modules/books/landing.ts b/modules/books/landing.ts new file mode 100644 index 0000000..16280d2 --- /dev/null +++ b/modules/books/landing.ts @@ -0,0 +1,118 @@ +/** + * rBooks — rich landing page body. + * Returned by landingPage() in the module export; + * the shell wraps it with header, CSS, and analytics. + */ +export function renderLanding(): string { + const demo = "https://demo.rspace.online/rbooks"; + + return ` + +
+ rBooks +

Your Community's Library

+

+ Upload, share, and read PDFs together. A beautiful flipbook reader, + searchable catalog, and community contributions — all self-hosted. +

+
+ Start Your Library + Create a Space +
+
+ + +
+
+

How It Works

+
+
+
1
+

Upload PDFs

+

Drag-and-drop any PDF. Add title, author, tags, and a license — it is processed instantly.

+
+
+
2
+

Browse the Library

+

Search by title, author, or tag. Featured books rise to the top.

+
+
+
3
+

Read with Flipbook

+

Open any book in the interactive flipbook reader. Turn pages, zoom in, and bookmark your place.

+
+
+
+
+ + +
+
+

Features

+
+
+
📖
+

Flipbook Reader

+

Realistic page-turn animations, zoom, and full-screen mode for a natural reading experience.

+
+
+
+

PDF Processing

+

Automatic page counting, metadata extraction, and optimized delivery to the reader.

+
+
+
📚
+

Space Libraries

+

Each community space gets its own curated collection with search and tagging.

+
+
+
👥
+

Community Contributions

+

Members upload and share. View counts and download stats track engagement.

+
+
+
+
+ + +
+
+

Works With the Ecosystem

+

+ rBooks connects to other rSpace modules to extend your library. +

+
+
+
📜
+
+

rPubs

+

Write and publish your own books with the collaborative editor, then list them in rBooks.

+
+
+
+
🛒
+
+

rCart

+

Sell premium PDFs through your community storefront with integrated checkout.

+
+
+
+
+
+ + +
+
+

Ready to Build Your Library?

+

+ Upload your first PDF and let your community start reading. +

+ +
+
+ +
← Back to rSpace
`; +} diff --git a/modules/books/mod.ts b/modules/books/mod.ts index 8b65407..24f9de8 100644 --- a/modules/books/mod.ts +++ b/modules/books/mod.ts @@ -13,6 +13,7 @@ import { sql } from "../../shared/db/pool"; import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; +import { renderLanding } from "./landing"; import { verifyEncryptIDToken, extractToken, @@ -301,6 +302,7 @@ export const booksModule: RSpaceModule = { description: "Community PDF library with flipbook reader", routes, standaloneDomain: "rbooks.online", + landingPage: renderLanding, feeds: [ { id: "reading-list", diff --git a/modules/cal/landing.ts b/modules/cal/landing.ts new file mode 100644 index 0000000..9376527 --- /dev/null +++ b/modules/cal/landing.ts @@ -0,0 +1,266 @@ +/** + * rCal landing page — relational calendar. + */ +export function renderLanding(): string { + return ` + +
+ rCal +

Time is shared.
Your calendar should be too.

+

+ A spatiotemporal calendar that couples where and when, supports natural cycles, + and zooms from 30-second moments to geological epochs. +

+
+ Try the Demo + Create a Space +
+
+ + +
+
+

Design principles

+
+
+
🤝
+

Shared by Default

+

Calendars belong to spaces, not individuals. Everyone sees the same schedule.

+
+
+
🗺
+

Spatiotemporal

+

Events have places, not just times. Where and when are coupled at every zoom level.

+
+
+
🌙
+

Natural Cycles

+

Lunar phases, solstices, and seasonal rhythms overlaid on the Gregorian grid.

+
+
+
🔭
+

Multi-Scale Zoom

+

Ten zoom levels from 30-second moments to cosmic time. One unified timeline.

+
+
+
+
+ + +
+
+

Why rCal

+
+
+

Where + When

+

Every event carries location context. Zoom into a city and see only what happens there.

+
+
+

Coupled Zoom

+

Temporal and spatial zoom are linked. Zoom out in time and the map zooms out too.

+
+
+

Multi-Source Sync

+

Pull events from ICS feeds, CalDAV servers, and other r* modules into one view.

+
+
+

Lunar Overlay

+

Moon phases computed and displayed alongside events. Plan by natural cycles.

+
+
+

r* Ecosystem Embeds

+

rVote deadlines, rWork sprints, rFunds milestones — all surface as calendar events.

+
+
+

Self-Hosted

+

Your data lives on your infrastructure. No vendor lock-in, no surveillance calendars.

+
+
+
+
+ + +
+
+

Temporal zoom

+

Ten levels of time — from the blink of an eye to deep time.

+
+
+
+ 0 +
+ Moment +
+ 30 s +
+
+ 1 +
+ Minute +
+ 1–10 min +
+
+ 2 +
+ Hour +
+ 1–6 hrs +
+
+ 3 +
+ Day +
+ 24 hrs +
+
+ 4 +
+ Week +
+ 7 days +
+
+ 5 +
+ Lunar +
+ 29.5 days +
+
+ 6 +
+ Season +
+ ~90 days +
+
+ 7 +
+ Year +
+ 365 days +
+
+ 8 +
+ Epoch +
+ decades–centuries +
+
+ 9 +
+ Cosmic +
+ geological +
+
+
+
+
+ + +
+
+

Four views

+
+
+
📅
+

Temporal

+

Classic calendar grid — day, week, month. The view you know.

+

T to switch

+
+
+
🗺
+

Spatial

+

Map view with events pinned to locations. Zoom couples time and space.

+

S to switch

+
+
+
🌙
+

Lunar

+

Moon-phase overlay with illumination percentages. Plan with natural rhythms.

+

L to switch

+
+
+
🧩
+

Context

+

Events grouped by r* source module. See your rWork sprints next to rVote deadlines.

+

C to switch

+
+
+
+
+ + +
+
+

Ecosystem integration

+

rCal pulls events from across the r* ecosystem automatically.

+
+
+
✈️
+
+

rTrips

+

Travel itineraries appear as multi-day calendar events with location pins.

+
+
+
+
🗺
+
+

rMaps

+

Location-tagged events render on the spatial view map layer.

+
+
+
+
👥
+
+

rNetwork

+

Meeting events auto-link to participant profiles and relationship context.

+
+
+
+
🛒
+
+

rCart

+

Group-buy deadlines and fulfillment ETAs show up as calendar milestones.

+
+
+
+
📝
+
+

rNotes

+

Meeting notes link back to the calendar event that spawned them.

+
+
+
+
🌐
+
+

rSpace

+

Space-level milestones and deadlines aggregate across all modules into one timeline.

+
+
+
+
+
+ + +
+
+

See time differently

+

+ A calendar that understands place, cycles, and community. Try the demo or create your own space. +

+ +
+
+ +
+ ← Back to rSpace +
`; +} diff --git a/modules/cal/mod.ts b/modules/cal/mod.ts index a5881ab..9ab17ef 100644 --- a/modules/cal/mod.ts +++ b/modules/cal/mod.ts @@ -13,6 +13,7 @@ import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; import { verifyEncryptIDToken, extractToken } from "@encryptid/sdk/server"; +import { renderLanding } from "./landing"; const routes = new Hono(); @@ -394,6 +395,7 @@ export const calModule: RSpaceModule = { description: "Temporal coordination calendar with lunar, solar, and seasonal systems", routes, standaloneDomain: "rcal.online", + landingPage: renderLanding, feeds: [ { id: "events", diff --git a/modules/cart/landing.ts b/modules/cart/landing.ts new file mode 100644 index 0000000..157255b --- /dev/null +++ b/modules/cart/landing.ts @@ -0,0 +1,127 @@ +/** + * rCart landing page — group shopping, together. + */ +export function renderLanding(): string { + return ` + +
+ rCart +

Group Shopping, Together

+

+ A shared shopping cart for communities. Pool orders, unlock bulk pricing, + and fulfill locally through the cosmolocal provider network. +

+
+ Browse the Shop + Create with rPubs +
+
+ + +
+
+

How it works

+
+
+ 1 +

Create a Space

+

Your space is your shared shopping context. Members see the same catalog and cart.

+
+
+ 2 +

Add Products

+

List print-ready artifacts from rPubs, or browse what others have published.

+
+
+ 3 +

Pay Together

+

Pool orders to hit bulk pricing tiers. Pay with crypto or card. Revenue splits automatically.

+
+
+
+
+ + +
+
+

Features

+
+
+
+ +
+

Universal Cart

+

One cart shared across your space. Members add items, pool orders, and hit bulk thresholds together.

+
+
+
+ +
+

Crypto + Card

+

Pay with credit card or cryptocurrency. x402 protocol support for instant crypto payments.

+
+
+
+ +
+

Real-time Updates

+

Order status updates in real time — from placement through production to delivery.

+
+
+
+ +
+

Passkey Login

+

Passwordless authentication with EncryptID passkeys. One tap to sign in across all r* apps.

+
+
+
+
+ + +
+
+
+
+

Cosmolocal fulfillment

+

+ Every order is matched to the nearest capable provider. Design is global, manufacturing is local. +

+
    +
  • Provider matching — automatic routing by capability, location, and cost
  • +
  • Revenue splits — creator, community, and provider shares via rFunds
  • +
  • Order tracking — real-time status from accepted to delivered
  • +
  • Volume pricing — automatic tier detection from pooled orders
  • +
+
+
+
+
+ +
+

Nearest Provider Wins

+

Less shipping, lower emissions,
faster delivery, local jobs.

+
+
+
+
+
+ + +
+
+

Ready to shop together?

+

+ Browse the catalog, pool orders with your community, and support local providers. +

+ +
+
+ +
+ ← Back to rSpace +
`; +} diff --git a/modules/cart/mod.ts b/modules/cart/mod.ts index 66d3bcf..47ca254 100644 --- a/modules/cart/mod.ts +++ b/modules/cart/mod.ts @@ -15,6 +15,7 @@ import { getModuleInfoList } from "../../shared/module"; import { depositOrderRevenue } from "./flow"; import type { RSpaceModule } from "../../shared/module"; import { verifyEncryptIDToken, extractToken } from "@encryptid/sdk/server"; +import { renderLanding } from "./landing"; const routes = new Hono(); @@ -460,6 +461,7 @@ export const cartModule: RSpaceModule = { description: "Cosmolocal print-on-demand shop", routes, standaloneDomain: "rcart.online", + landingPage: renderLanding, feeds: [ { id: "orders", diff --git a/modules/choices/landing.ts b/modules/choices/landing.ts new file mode 100644 index 0000000..7c5ad15 --- /dev/null +++ b/modules/choices/landing.ts @@ -0,0 +1,120 @@ +/** + * rChoices — rich landing page body. + * Returned by landingPage() in the module export; + * the shell wraps it with header, CSS, and analytics. + */ +export function renderLanding(): string { + const demo = "https://demo.rspace.online/rchoices"; + + return ` + +
+ rChoices +

Decide Together, Fairly

+

+ Quadratic voting, ranked choice, and multi-criteria scoring — all as + interactive shapes on your canvas. Drop a choice, let members vote, + watch results emerge in real time. +

+
+ Make Better Decisions + Create a Space +
+
+ + +
+
+

How It Works

+
+
+
1
+

Create a Choice Shape

+

Pick a voting method, name it, and add options. The shape appears on the canvas.

+
+
+
2
+

Members Vote

+

Space members interact with the shape to cast votes, rank preferences, or score criteria.

+
+
+
3
+

Results Emerge

+

Live tallies update as votes arrive. View charts, rankings, and spider diagrams in real time.

+
+
+
+
+ + +
+
+

Voting Methods

+

+ Three powerful mechanisms, each designed for different decision contexts. +

+
+
+
+

Quadratic Voting

+

Express intensity of preference. The cost of additional votes on one option grows exponentially, balancing passion with fairness.

+
+
+
📋
+

Ranked Choice

+

Order your preferences from first to last. Instant-runoff tabulation finds the option with the broadest support.

+
+
+
🕸
+

Multi-Criteria Scoring

+

Score options across weighted attributes. Spider diagrams reveal trade-offs at a glance.

+
+
+
+
+ + +
+
+

Features

+
+
+
🎨
+

Canvas Integration

+

Choice shapes live on the canvas alongside notes, images, and other shapes — full spatial context.

+
+
+
+

Real-time Results

+

Tallies, rankings, and spider charts update live as members vote via Automerge CRDT sync.

+
+
+
🔧
+

Configurable Parameters

+

Set vote budgets, deadlines, anonymity, and quorum thresholds per choice shape.

+
+
+
+

rVote Integration

+

Connect to rVote for formal governance proposals backed by on-canvas choices.

+
+
+
+
+ + +
+
+

Better Decisions Start Here

+

+ Drop a choice shape on your canvas and let your community weigh in. +

+ +
+
+ +
← Back to rSpace
`; +} diff --git a/modules/choices/mod.ts b/modules/choices/mod.ts index db15100..9a233a9 100644 --- a/modules/choices/mod.ts +++ b/modules/choices/mod.ts @@ -11,6 +11,7 @@ import { Hono } from "hono"; import { renderShell } from "../../server/shell"; import type { RSpaceModule } from "../../shared/module"; +import { renderLanding } from "./landing"; import { getModuleInfoList } from "../../shared/module"; import { getDocumentData } from "../../server/community-store"; @@ -67,6 +68,7 @@ export const choicesModule: RSpaceModule = { description: "Polls, rankings, and multi-criteria scoring", routes, standaloneDomain: "rchoices.online", + landingPage: renderLanding, feeds: [ { id: "poll-results", diff --git a/modules/data/landing.ts b/modules/data/landing.ts new file mode 100644 index 0000000..de6fca7 --- /dev/null +++ b/modules/data/landing.ts @@ -0,0 +1,120 @@ +/** + * rData — rich landing page body. + * Returned by landingPage() in the module export; + * the shell wraps it with header, CSS, and analytics. + */ +export function renderLanding(): string { + const demo = "https://demo.rspace.online/rdata"; + + return ` + +
+ rData +

Privacy-First Analytics

+

+ See how your community engages without tracking individuals. + No cookies, no consent banners, no third-party data — just + clean, real-time metrics from your own server. +

+
+ View Analytics + Create a Space +
+
+ + +
+
+

How It Works

+
+
+
1
+

Auto-Instrumented

+

Every rSpace module is automatically tracked — no code changes, no tag managers.

+
+
+
2
+

View Dashboard

+

Open rData to see page views, active visitors, referrers, and top content in real time.

+
+
+
3
+

Share Insights

+

Export stats or embed dashboard widgets in your canvas to keep the community informed.

+
+
+
+
+ + +
+
+

Features

+
+
+
🔒
+

No Cookies Required

+

Umami uses a privacy-friendly fingerprinting method. Zero cookies, zero local storage.

+
+
+
+

GDPR Compliant

+

No personal data collected. No consent banner needed. Compliant out of the box.

+
+
+
+

Real-Time Dashboard

+

Active visitors, page views, bounce rate, and session duration update live.

+
+
+
🦾
+

Lightweight Script

+

Under 2 KB tracker script. No impact on page load performance.

+
+
+
+
+ + +
+
+

Why Self-Hosted Analytics?

+

+ Compare rData with third-party analytics platforms. +

+
+
+
🚫
+

No Third-Party Data

+

Your visitor metrics never leave your server. No ad networks, no data brokers, no surprises.

+
+
+
🚫
+

No Cookie Banners

+

Because no cookies are set, you skip the annoying consent popups entirely.

+
+
+
🦿
+

Sub-2 KB Script

+

Google Analytics loads 45 KB+. The Umami tracker is under 2 KB — 20x lighter.

+
+
+
+
+ + +
+
+

Analytics Without the Guilt

+

+ Respect your visitors. Understand your community. Keep your data. +

+ +
+
+ +
← Back to rSpace
`; +} diff --git a/modules/data/mod.ts b/modules/data/mod.ts index a28e72c..bf7c58c 100644 --- a/modules/data/mod.ts +++ b/modules/data/mod.ts @@ -9,6 +9,7 @@ import { Hono } from "hono"; import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; +import { renderLanding } from "./landing"; const routes = new Hono(); @@ -139,6 +140,7 @@ export const dataModule: RSpaceModule = { description: "Privacy-first analytics for the r* ecosystem", routes, standaloneDomain: "rdata.online", + landingPage: renderLanding, feeds: [ { id: "analytics", diff --git a/modules/files/landing.ts b/modules/files/landing.ts new file mode 100644 index 0000000..64cd83d --- /dev/null +++ b/modules/files/landing.ts @@ -0,0 +1,94 @@ +/** + * Files module landing page — rich content for rspace.online/rfiles + */ + +export function renderLanding(): string { + return ` + +
+ rFiles +

Share Files, Your Way

+

+ Upload, organize, and share with public links and memory cards. + Built for communities who want control over their shared files. +

+
+ Start Sharing + Create a Space +
+
+ + +
+
+

How It Works

+
+
+
1
+

Upload Files

+

Drag and drop any file type. Images, documents, archives -- everything is welcome.

+
+
+
2
+

Organize in Folders

+

Group files by project, topic, or team. Tag and search across your whole library.

+
+
+
3
+

Share with Links

+

Generate public share links with optional expiration, download limits, and password protection.

+
+
+
+
+ + +
+
+

Features

+

+ Everything you need for community file management, without the surveillance. +

+
+
+
🔗
+

Public Share Links

+

Create expiring, password-protected, download-limited share links for any file.

+
+
+
📄
+

Memory Cards

+

Attach structured metadata cards to files -- notes, context, and tags that travel with the content.

+
+
+
📁
+

Folder Organization

+

Nest files in folders, tag freely, and search by name, type, or metadata across your library.

+
+
+
🌐
+

Multi-Space Storage

+

Each community space gets its own file library. Share across spaces or keep things private.

+
+
+
+
+ + +
+
+

Ready to share?

+

+ Try the demo or create your own space to start uploading. +

+ +
+
+ +
+ ← Back to rSpace +
`; +} diff --git a/modules/files/mod.ts b/modules/files/mod.ts index 5486f98..c67f8d0 100644 --- a/modules/files/mod.ts +++ b/modules/files/mod.ts @@ -13,6 +13,7 @@ import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; import { verifyEncryptIDToken, extractToken } from "@encryptid/sdk/server"; +import { renderLanding } from "./landing"; const routes = new Hono(); @@ -384,6 +385,7 @@ export const filesModule: RSpaceModule = { icon: "\uD83D\uDCC1", description: "File sharing, share links, and memory cards", routes, + landingPage: renderLanding, standaloneDomain: "rfiles.online", feeds: [ { diff --git a/modules/forum/landing.ts b/modules/forum/landing.ts new file mode 100644 index 0000000..86d5f62 --- /dev/null +++ b/modules/forum/landing.ts @@ -0,0 +1,186 @@ +/** + * Forum module landing page — static HTML, no React. + */ +export function renderLanding(): string { + return ` + +
+ rForum +

+ Deploy Your Own Discourse Forum in Minutes +

+

+ Automated cloud provisioning for self-hosted Discourse. + No DevOps required. Choose your region, configure your settings, and go live. +

+
+ Get Started + View Pricing +
+
+ + +
+
+

How It Works

+
+
+
+ + + + +
+

1. Configure

+

+ Choose your subdomain, server region, and instance size. + Add SMTP credentials for email delivery. Set your admin email. +

+
+ +
+
+ + + +
+

2. Provision

+

+ We create a cloud server on Hetzner, install Discourse, + configure SSL via Let's Encrypt, and set up DNS. Takes about 10-15 minutes. +

+
+ +
+
+ + + +
+

3. Go Live

+

+ Your forum is ready. Log in as admin, customize your community, + invite members, and start conversations. Full SSH access included. +

+
+
+
+
+ + +
+
+

+ Transparent Pricing +

+

+ Pay only for the cloud server. Hetzner pricing passed through directly — no markup. +

+
+ +
+

Starter

+

Small communities

+
+ €3.79/mo +
+

Hetzner CX22

+
    +
  • 2 vCPU cores
  • +
  • 4 GB RAM
  • +
  • 40 GB NVMe SSD
  • +
  • Up to ~500 users
  • +
+
+ + +
+ RECOMMENDED +

Standard

+

Growing communities

+
+ €6.80/mo +
+

Hetzner CX32

+
    +
  • 4 vCPU cores
  • +
  • 8 GB RAM
  • +
  • 80 GB NVMe SSD
  • +
  • Up to ~2,000 users
  • +
+
+ + +
+

Performance

+

Large communities

+
+ €13.80/mo +
+

Hetzner CX42

+
    +
  • 8 vCPU cores
  • +
  • 16 GB RAM
  • +
  • 160 GB NVMe SSD
  • +
  • Up to ~10,000 users
  • +
+
+
+
+
+ + +
+
+

+ What You Get +

+
+
+

Automated SSL

+

Let's Encrypt certificates provisioned automatically during setup.

+
+
+

Multiple Regions

+

Deploy in Germany, Finland, or the US East/West Coast.

+
+
+

Full SSH Access

+

Your server, your rules. SSH in anytime for custom configuration.

+
+
+

One-Click Updates

+

Discourse's built-in admin panel handles version upgrades.

+
+
+

DNS Management

+

Automatic DNS setup for *.rforum.online subdomains.

+
+
+

Real-Time Logs

+

Watch your forum provision step-by-step in the dashboard.

+
+
+
+
+ + +
+
+

+ Ready to launch your community? +

+

+ Deploy a production Discourse forum in under 15 minutes. No DevOps experience needed. +

+ +
+
+ +
← Back to rSpace
+`; +} diff --git a/modules/forum/mod.ts b/modules/forum/mod.ts index 892e1d3..0ccc72b 100644 --- a/modules/forum/mod.ts +++ b/modules/forum/mod.ts @@ -12,6 +12,7 @@ import { getModuleInfoList } from "../../shared/module"; import { provisionInstance, destroyInstance } from "./lib/provisioner"; import type { RSpaceModule } from "../../shared/module"; import { verifyEncryptIDToken, extractToken } from "@encryptid/sdk/server"; +import { renderLanding } from "./landing"; const routes = new Hono(); @@ -175,6 +176,7 @@ export const forumModule: RSpaceModule = { icon: "\uD83D\uDCAC", description: "Deploy and manage Discourse forums", routes, + landingPage: renderLanding, standaloneDomain: "rforum.online", feeds: [ { diff --git a/modules/funds/landing.ts b/modules/funds/landing.ts new file mode 100644 index 0000000..6b4ebb8 --- /dev/null +++ b/modules/funds/landing.ts @@ -0,0 +1,117 @@ +/** + * Funds module landing page — rich content for rspace.online/rfunds + */ + +export function renderLanding(): string { + return ` + +
+ rFunds +

Visualize Your Community's Money

+

+ Budget flows, river visualization, and conviction funding. + Watch resources move through your community in real time. +

+
+ See Your Funds Flow + Create a Space +
+
+ + +
+
+

How It Works

+
+
+
1
+

Define Budget Streams

+

Create named flows between funding pools. Set rates, thresholds, and allocation rules.

+
+
+
2
+

Watch Money Flow

+

The river visualization animates budget movement in real time -- deposits, withdrawals, and funnels.

+
+
+
3
+

Govern Allocation

+

Community members signal preferences through conviction funding. Resources flow where attention goes.

+
+
+
+
+ + +
+
+

Features

+

+ Transparent treasury management for communities of any size. +

+
+
+
🌊
+

River Visualization

+

Animated flow diagram showing how funds move between pools, funnels, and outcomes in real time.

+
+
+
💡
+

Conviction Funding

+

Continuous signaling lets community members express preferences that compound over time.

+
+
+
💨
+

Budget Streams

+

Named flows between funding pools with configurable rates, thresholds, and activation rules.

+
+
+
📊
+

Treasury Dashboard

+

Full overview of balances, inflows, outflows, and historical transaction data for your community.

+
+
+
+
+ + +
+
+

Ecosystem Integration

+
+
+
💰
+
+

rWallet

+

Connects to rWallet for on-chain balances and wallet-based treasury tracking.

+
+
+
+
🗳
+
+

rVote

+

Pairs with rVote for governance decisions that direct fund allocation.

+
+
+
+
+
+ + +
+
+

See your community's funds in motion

+

+ Try the demo or create a space to set up your own budget flows. +

+ +
+
+ +
+ ← Back to rSpace +
`; +} diff --git a/modules/funds/mod.ts b/modules/funds/mod.ts index 7669328..6de9e27 100644 --- a/modules/funds/mod.ts +++ b/modules/funds/mod.ts @@ -12,6 +12,7 @@ import { renderShell } from "../../server/shell"; import type { RSpaceModule } from "../../shared/module"; import { getModuleInfoList } from "../../shared/module"; import { verifyEncryptIDToken, extractToken } from "@encryptid/sdk/server"; +import { renderLanding } from "./landing"; const FLOW_SERVICE_URL = process.env.FLOW_SERVICE_URL || "http://payment-flow:3010"; @@ -245,6 +246,7 @@ export const fundsModule: RSpaceModule = { icon: "\uD83C\uDF0A", description: "Budget flows, river visualization, and treasury management", routes, + landingPage: renderLanding, standaloneDomain: "rfunds.online", feeds: [ { diff --git a/modules/inbox/landing.ts b/modules/inbox/landing.ts new file mode 100644 index 0000000..45bfb3d --- /dev/null +++ b/modules/inbox/landing.ts @@ -0,0 +1,153 @@ +/** + * Inbox module landing page — static HTML, no React. + */ +export function renderLanding(): string { + return ` + +
+ rInbox +

+ Collaborative Multi-Sig Inbox +

+

+ A shared email client where teams read, discuss, and approve messages + together — with cryptographic multi-signature workflows before anything gets sent. +

+
+ Open Inbox + Create a Space +
+
+ + +
+
+

How It Works

+
+
+
+ + + +
+

1. Connect Mailbox

+

+ Your team shares one real email address. Every member sees every thread + in real-time — no forwarding, no BCC chains, no lost context. +

+
+ +
+
+ + + +
+

2. Triage Together

+

+ Comment on any thread privately before replying. Tag members, + discuss strategy, and reach consensus — all alongside the original message. +

+
+ +
+
+ + + +
+

3. Approve with Multi-Sig

+

+ Outbound emails require M-of-N cryptographic signatures before sending. + Every approval is auditable — no rogue replies. +

+
+
+
+
+ + +
+
+

+ Collaboration Features +

+

Built for collective intelligence, not individual productivity.

+
+
+

Real-Time Collaboration

+
    +
  • Threaded Comments — discuss any email privately before replying
  • +
  • Draft Reviews — collaborative draft editing with inline suggestions
  • +
  • Forwarding Rules — route incoming messages by sender, subject, or tag
  • +
  • Inline Signatures — per-mailbox signature templates with merge fields
  • +
  • Read Receipts — see who has read each thread and when
  • +
+
+
+

Approval Workflows

+
    +
  • Multi-sig sending — outbound emails require M-of-N approval
  • +
  • Configurable thresholds — set approval requirements per mailbox
  • +
  • Audit trail — every approval, rejection, and edit is logged
  • +
  • Role-based access — Admin, Reviewer, Approver, Viewer, Bot
  • +
  • Deadline alerts — notifications when approvals are waiting
  • +
+
+
+
+
+ + +
+
+

+ Team Roles +

+

Fine-grained access control for every team member.

+
+
+

Admin

+

Full control, manage members

+
+
+

Reviewer

+

Read, comment, suggest edits

+
+
+

Approver

+

Sign outbound emails

+
+
+

Viewer

+

Read-only access

+
+
+

Bot

+

Automated integrations

+
+
+
+
+ + +
+
+

+ Start collaborating on email +

+

+ Sign in with your passkey to join a shared inbox. +

+ +
+
+ +
← Back to rSpace
+`; +} diff --git a/modules/inbox/mod.ts b/modules/inbox/mod.ts index 84b264b..8c59293 100644 --- a/modules/inbox/mod.ts +++ b/modules/inbox/mod.ts @@ -13,6 +13,7 @@ import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; import { verifyEncryptIDToken, extractToken } from "@encryptid/sdk/server"; +import { renderLanding } from "./landing"; const routes = new Hono(); @@ -599,6 +600,7 @@ export const inboxModule: RSpaceModule = { icon: "\u{1F4E8}", description: "Collaborative email with multisig approval", routes, + landingPage: renderLanding, standaloneDomain: "rinbox.online", feeds: [ { diff --git a/modules/maps/landing.ts b/modules/maps/landing.ts new file mode 100644 index 0000000..3f22b18 --- /dev/null +++ b/modules/maps/landing.ts @@ -0,0 +1,320 @@ +/** + * Maps module landing page — static HTML, no React. + */ +export function renderLanding(): string { + return ` + +
+ rMaps +

+ Real-Time Collaborative Maps +

+

+ Share live locations, navigate indoor and outdoor spaces, coordinate meetups + — all from the browser. No app install. No tracking. No data collection. +

+
+ Try the Demo + Create a Room +
+

No sign-up required to join. Works on any device.

+
+ + +
+
+ Core Features +

+ Everything you need to find your friends +

+
+
+
+ + + + +
+

Live GPS Sharing

+

+ Real-time location updates via WebSocket. See everyone on the map + as they move, with stale detection and high-accuracy fallback. +

+
+ +
+
+ + + +
+

Indoor + Outdoor Nav

+

+ Turn-by-turn routing via OSRM outdoors, seamless switch to c3nav + for indoor venues. Multi-floor, level-aware navigation. +

+
+ +
+
+ + + +
+

Meeting Points

+

+ Drop waypoints for meetups, events, and points of interest. + Search by address, share coordinates, or pin from your location. +

+
+ +
+
+ + + +
+

Privacy First

+

+ Ghost mode, precision levels, one-toggle location sharing. + Zero tracking, zero data collection. You control who sees you. +

+
+
+
+
+ + +
+
+ Beyond Google Maps +

+ What makes rMaps different +

+
+
+
+ 🏕️ +
+
+

CCC Event Integration

+

+ 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. +

+
+
+ +
+
+ 📡 +
+
+

Location Pinging

+

+ 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. +

+
+
+ +
+
+ 📦 +
+
+

Google Maps Import

+

+ Import your saved places from Google Takeout ZIP exports. GeoJSON + parsing, auto-emoji mapping by place type, and preview before + importing. +

+
+
+ +
+
+ 📱 +
+
+

PWA & Offline Mode

+

+ 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. +

+
+
+ +
+
+ 🔗 +
+
+

Instant Room Sharing

+

+ 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. +

+
+
+ +
+
+ 🔄 +
+
+

Conflict-Free Sync

+

+ Automerge CRDT architecture ensures everyone sees the same map state, + even through disconnections. WebSocket real-time sync with automatic + reconnection and state recovery. +

+
+
+
+
+
+ + +
+
+ How It Works +

+ Three steps to find your crew +

+
+
+
1
+

Create a Map Room

+

+ Sign in and name your room. Get a shareable link or a custom slug. +

+
+
+
2
+

Share with Friends

+

+ Send the link or scan the QR code. Friends join from any browser + — no app download, no account creation needed. +

+
+
+
3
+

Navigate Together

+

+ See everyone in real time. Drop meeting points, get turn-by-turn + directions, and ping friends when you need to regroup. +

+
+
+
+
+ + +
+
+ Built For +

+ Maps for every gathering +

+
+
+
🏕️
+

Festivals & Camps

+

+ Navigate massive venues with indoor maps. Find stages, food courts, + and your crew across multi-day events like CCC Camp. +

+
+ +
+
🏙️
+

City Exploration

+

+ Exploring a new city with friends? Share locations, drop pins at + restaurants and landmarks, import your Google Maps saved places. +

+
+ +
+
🤝
+

Group Coordination

+

+ Conferences, retreats, team offsites. Set meeting points, ping + stragglers, and get walking directions to the next session. +

+
+
+

+ First built for CCC events — now for any gathering. +

+
+
+ + +
+
+ Under the Hood +

+ Built on open standards +

+
+
+

MapLibre GL

+

Open-source maps

+
+
+

OSRM

+

Outdoor routing

+
+
+

c3nav

+

Indoor navigation

+
+
+

Automerge

+

CRDT sync

+
+
+

Web Push

+

Notifications

+
+
+

Service Worker

+

Offline & PWA

+
+
+

WebSocket

+

Real-time sync

+
+
+

EncryptID

+

Identity & auth

+
+
+
+
+ + +
+
+

+ Ready to find your crew? +

+

Create a map room and share the link. That's it.

+ +
+
+ +
← Back to rSpace
+`; +} diff --git a/modules/maps/mod.ts b/modules/maps/mod.ts index 9897903..569006b 100644 --- a/modules/maps/mod.ts +++ b/modules/maps/mod.ts @@ -10,6 +10,7 @@ import { Hono } from "hono"; import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; +import { renderLanding } from "./landing"; const routes = new Hono(); @@ -167,6 +168,7 @@ export const mapsModule: RSpaceModule = { icon: "\u{1F5FA}", description: "Real-time collaborative location sharing and indoor/outdoor maps", routes, + landingPage: renderLanding, standaloneDomain: "rmaps.online", feeds: [ { diff --git a/modules/notes/landing.ts b/modules/notes/landing.ts new file mode 100644 index 0000000..2142ade --- /dev/null +++ b/modules/notes/landing.ts @@ -0,0 +1,183 @@ +/** + * Notes module landing page — static HTML, no React. + */ +export function renderLanding(): string { + return ` + +
+ rNotes +

+ Capture Everything, Find Anything, and Share your Insights +

+

+ Notes, clips, voice recordings, and live transcription — all in one place. + Speak and watch your words appear in real time, or drop in audio and video files to transcribe offline. +

+
+ Open Notebook + Unlock Article + Transcribe +
+
+ + +
+
+

How It Works

+
+
+
1
+

Live Transcribe

+

Speak and watch your words appear in real time. WebSocket streaming with live timestamps.

+
+
+
2
+

Audio & Video

+

Drop in audio or video files and get a full transcript. Powered by NVIDIA Parakeet — runs entirely in your browser.

+
+
+
3
+

Notebooks & Tags

+

Organize transcripts into notebooks alongside notes, clips, code, and files. Tag freely, search everything.

+
+
+
4
+

Private & Offline

+

Parakeet.js runs entirely in the browser. Your audio never leaves your device — full offline support.

+
+
+
+
+ + +
+
+

Memory Cards

+

+ Every note is a Memory Card — a typed, structured unit of knowledge with hierarchy, + properties, and attachments. Designed for round-trip interoperability with Logseq. +

+
+ +
+
+ + + +
+

7 Card Types

+
+ note + link + task + idea + person + reference + file +
+

Each card type has distinct styling and behavior. Typed notes surface in filtered views and canvas visualizations.

+
+ + +
+
+ + + +
+

Hierarchy & Properties

+

+ Nest cards under parents to build knowledge trees. Add structured + key:: value + properties — compatible with Logseq's property syntax. +

+
+
type:: idea
+
status:: doing
+
tags:: #research, #web3
+
+
+ + +
+
+ + + +
+

Logseq Import & Export

+

+ Export your notebooks as Logseq-compatible ZIP archives. Import a Logseq graph and keep your pages, + properties, tags, and hierarchy intact. +

+

+ Round-trip fidelity: card types, tags, attachments, and parent-child structure all survive the journey. +

+
+ + +
+
+ + + +
+

Dual Format Storage

+

+ Every card stores rich TipTap JSON for editing and portable Markdown for search, export, and interoperability. + Write once, read anywhere. +

+
+ + +
+
+ + + +
+

Structured Attachments

+

+ Attach images, PDFs, audio, and files to any card with roles (primary, preview, supporting) and captions. + Thumbnails render inline. +

+
+ + +
+
+ + + +
+

FUN, Not CRUD

+

+ Forget, + Update, + New — + nothing is permanently destroyed. Forgotten cards are archived and can be remembered at any time. +

+
+
+
+
+ + +
+
+

Start capturing

+

Notes, voice, clips, and code — all in one notebook.

+ +
+
+ +
← Back to rSpace
+`; +} diff --git a/modules/notes/mod.ts b/modules/notes/mod.ts index bde88b0..4d7607a 100644 --- a/modules/notes/mod.ts +++ b/modules/notes/mod.ts @@ -13,6 +13,7 @@ import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; import { verifyEncryptIDToken, extractToken } from "@encryptid/sdk/server"; +import { renderLanding } from "./landing"; const routes = new Hono(); @@ -379,6 +380,7 @@ export const notesModule: RSpaceModule = { icon: "\u{1F4DD}", description: "Notebooks with rich-text notes, voice transcription, and collaboration", routes, + landingPage: renderLanding, standaloneDomain: "rnotes.online", feeds: [ { diff --git a/modules/photos/landing.ts b/modules/photos/landing.ts new file mode 100644 index 0000000..2a12d4f --- /dev/null +++ b/modules/photos/landing.ts @@ -0,0 +1,94 @@ +/** + * Photos module landing page — rich content for rspace.online/rphotos + */ + +export function renderLanding(): string { + return ` + +
+ rPhotos +

Community Photo Commons

+

+ Share memories with your community, powered by Immich. + Self-hosted, AI-organized, and privacy-first. +

+
+ Browse Gallery + Create a Space +
+
+ + +
+
+

How It Works

+
+
+
1
+

Upload Photos

+

Drop photos from any device. Bulk upload entire albums or individual shots.

+
+
+
2
+

Auto-Organize

+

Immich's AI detects faces and objects, sorting your photos into smart groups automatically.

+
+
+
3
+

Share Albums

+

Create shared albums for events, projects, or teams. Everyone in the space can contribute.

+
+
+
+
+ + +
+
+

Features

+

+ A full-featured photo platform that respects your community's data. +

+
+
+
🤖
+

Immich-Powered

+

AI-driven face and object detection for automatic organization, search, and discovery.

+
+
+
📷
+

Shared Albums

+

Collaborative photo albums for events, gatherings, and ongoing projects. Everyone can add.

+
+
+
📅
+

Timeline View

+

Browse photos chronologically. Scroll through your community's visual history day by day.

+
+
+
🔒
+

Privacy-First

+

Self-hosted storage means your photos never leave your infrastructure. No third-party scanning.

+
+
+
+
+ + +
+
+

Your photos, your community

+

+ Try the demo gallery or create a space to start your own photo commons. +

+ +
+
+ +
+ ← Back to rSpace +
`; +} diff --git a/modules/photos/mod.ts b/modules/photos/mod.ts index 1e0e6fe..58cc623 100644 --- a/modules/photos/mod.ts +++ b/modules/photos/mod.ts @@ -10,6 +10,7 @@ import { Hono } from "hono"; import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; +import { renderLanding } from "./landing"; const routes = new Hono(); @@ -126,6 +127,7 @@ export const photosModule: RSpaceModule = { icon: "📸", description: "Community photo commons", routes, + landingPage: renderLanding, standaloneDomain: "rphotos.online", feeds: [ { diff --git a/modules/pubs/landing.ts b/modules/pubs/landing.ts new file mode 100644 index 0000000..118f6c1 --- /dev/null +++ b/modules/pubs/landing.ts @@ -0,0 +1,221 @@ +/** + * rPubs landing page — community pocket press. + */ +export function renderLanding(): string { + return ` + +
+ rPubs +

Write it. Press it. Share it.

+

+ Drop in a markdown document, pick a pocket format, and get a print-ready PDF in seconds. + Group up with other authors to unlock bulk pricing through collaborative print runs. +

+
+ Try the Press + Browse the Shop +
+
+ + +
+
+

How it works

+
+
+ 1 +

Write / paste

+

Drop in markdown or rich text. Headings, images, footnotes — it all just works.

+
+
+ 2 +

Press it

+

Pick a pocket format. rPubs typesets your document with Typst and generates a print-ready PDF.

+
+
+ 3 +

Print locally

+

Print at home, at a local shop, or list it on rCart for cosmolocal fulfillment.

+
+
+
+
+ + +
+
+

Four pocket formats

+

From palm-sized zines to digest readers. All print-ready at 300 dpi with bleeds.

+
+
+
+ +
+

A7 Pocket

+

74 × 105 mm — fits in a shirt pocket. Perfect for poems, manifestos, tiny zines.

+
+
+
+ +
+

Quarter Letter

+

4.25 × 5.5" — half a half-sheet. Great for chapbooks and field guides.

+
+
+
+ +
+

A6 Booklet

+

105 × 148 mm — postcard size. The workhorse format for essays and readers.

+
+
+
+ +
+

Digest

+

5.5 × 8.5" — half-letter. Standard trade paperback for longer works.

+
+
+
+
+ + +
+
+

Group buys — better together

+

Pool orders across titles. The more copies in a run, the cheaper each one gets.

+
+
+

25+ copies

+

Saddle-stitch binding

+

$8

+

per copy

+
+
+

50+ copies

+

Perfect-bind

+

$6

+ Save 25% +

per copy

+
+
+

100+ copies

+

Trade edition

+

$4.50

+ Save 44% +

per copy

+
+
+
+
+ + +
+
+

How collaborative print runs work

+
+
+ 1 +

Authors list titles

+

Publish your print-ready artifact to the rCart catalog.

+
+
+ 2 +

Readers pre-order

+

Buyers add copies to a shared cart. Orders accumulate toward tier thresholds.

+
+
+ 3 +

Threshold met

+

When the combined order hits a tier, the print run triggers automatically.

+
+
+ 4 +

Local fulfillment

+

The nearest cosmolocal provider prints and ships. Revenue splits to creator, community, and provider.

+
+
+
+
+ + +
+
+

Cross-title batching

+

+ Orders from different titles count toward the same tier. A community reading list + can hit trade-edition pricing even if no single title has 100 orders. +

+
+

Example batch

+
+
+ The Commons35 copies +
+
+ Mycelial Networks40 copies +
+
+ Cosmolocal Reader30 copies +
+
+
combined
+
+ 105 copies + = Trade edition @ $4.50/copy +
+
+
+
+ + +
+
+
+
+

rCart integration

+

+ Group purchasing is built right into the shop. Every rPubs artifact can be listed, + batched, and fulfilled through rCart. +

+
    +
  • One-click listing — publish to the rCart catalog straight from the press
  • +
  • Group carts — space members pool orders automatically
  • +
  • Revenue splits — creator, community, and provider shares via rFunds
  • +
  • Cosmolocal fulfillment — nearest provider prints and ships
  • +
  • Order tracking — real-time status from press to doorstep
  • +
+
+
+
+
+ +
+

Shop + Press

+

rPubs creates the artifact.
rCart sells and fulfills it.

+
+
+
+
+
+ + +
+
+ rPubs × Cosmolocal +

Design global, manufacture local

+

+ Every print run is routed to the nearest capable provider. Reduce shipping emissions, + support local economies, and still benefit from shared design and pooled demand. +

+ +
+
+ +
+ ← Back to rSpace +
`; +} diff --git a/modules/pubs/mod.ts b/modules/pubs/mod.ts index 6456c5e..82bdc2a 100644 --- a/modules/pubs/mod.ts +++ b/modules/pubs/mod.ts @@ -16,6 +16,7 @@ import type { BookFormat } from "./formats"; import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; +import { renderLanding } from "./landing"; const ARTIFACTS_DIR = process.env.ARTIFACTS_DIR || "/tmp/rpubs-artifacts"; @@ -342,6 +343,7 @@ export const pubsModule: RSpaceModule = { description: "Drop in a document, get a pocket book", routes, standaloneDomain: "rpubs.online", + landingPage: renderLanding, feeds: [ { id: "publications", diff --git a/modules/rsocials/landing.ts b/modules/rsocials/landing.ts new file mode 100644 index 0000000..3879a99 --- /dev/null +++ b/modules/rsocials/landing.ts @@ -0,0 +1,165 @@ +/** + * rSocials — rich landing page body. + * Returned by landingPage() in the module export; + * the shell wraps it with header, CSS, and analytics. + */ +export function renderLanding(): string { + const demo = "https://demo.rspace.online/rsocials"; + + return ` + +
+ rSocials +

Social Media Under Your Control

+

+ Schedule, publish, and analyze across every major platform — all + from your self-hosted rSpace instance. No per-seat pricing, no + third-party data mining. +

+
+ Try Demo + Create a Space +
+
+ + +
+
+

How It Works

+
+
+
1
+

Connect Platforms

+

Link your X/Twitter, LinkedIn, Instagram, TikTok, and more in one place.

+
+
+
2
+

Schedule Content

+

Draft posts, attach media, pick dates, and queue them up across every channel.

+
+
+
3
+

Publish & Analyze

+

Posts go live on schedule. Track engagement, reach, and growth from a single dashboard.

+
+
+
+
+ + +
+
+

Supported Platforms

+

+ Publish everywhere your audience lives — 16 platforms and counting. +

+
+

X / Twitter

+

LinkedIn

+

Facebook

+

Instagram

+

TikTok

+

YouTube

+

Pinterest

+

Reddit

+

Threads

+

BlueSky

+

Mastodon

+

Dribbble

+

Slack

+

Discord

+

Telegram

+

RSS

+
+
+
+ + +
+
+

Features

+
+
+
📅
+

Calendar View

+

Visual month/week/day planner so you never double-post or miss a slot.

+
+
+
+

AI Copywriting

+

Generate caption variations, hashtags, and thread hooks with a single click.

+
+
+
🎨
+

Post Designer

+

Resize images, add text overlays, and preview how posts look on each platform.

+
+
+
👥
+

Team Collaboration

+

Invite editors & approvers. Review queues keep quality high.

+
+
+
🛠
+

Per-Platform Optimization

+

Tailor copy, image crops, and hashtags for each network automatically.

+
+
+
📶
+

RSS Auto-Post

+

Watch any RSS feed and auto-publish new items to selected channels.

+
+
+
📈
+

Analytics Dashboard

+

Unified metrics across all platforms: impressions, clicks, engagement rate.

+
+
+
🌐
+

rSpace Ecosystem

+

Connect to rPubs, rForum, and more for seamless cross-posting.

+
+
+
+
+ + +
+
+

Why Self-Hosted?

+
+
+
🔒
+

Data Sovereignty

+

API tokens and analytics stay on your server. No third-party vendor sees your audience data.

+
+
+
💰
+

No Per-Seat Pricing

+

Add unlimited team members. Pay only for hosting, not per-user SaaS fees.

+
+
+
🔌
+

Open Source & Extensible

+

Fork it, theme it, add custom integrations. Postiz under the hood, rSpace on top.

+
+
+
+
+ + +
+
+

Ready to Own Your Social Presence?

+

+ Deploy rSocials in your rSpace and start scheduling in minutes. +

+ +
+
+ +
← Back to rSpace
`; +} diff --git a/modules/rsocials/mod.ts b/modules/rsocials/mod.ts index 54383f9..96b6fc3 100644 --- a/modules/rsocials/mod.ts +++ b/modules/rsocials/mod.ts @@ -9,6 +9,7 @@ import { Hono } from "hono"; import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; +import { renderLanding } from "./landing"; const routes = new Hono(); @@ -187,6 +188,7 @@ export const socialsModule: RSpaceModule = { description: "Federated social feed aggregator for communities", routes, standaloneDomain: "rsocials.online", + landingPage: renderLanding, feeds: [ { id: "social-feed", diff --git a/modules/splat/landing.ts b/modules/splat/landing.ts new file mode 100644 index 0000000..69b87cd --- /dev/null +++ b/modules/splat/landing.ts @@ -0,0 +1,94 @@ +/** + * Splat module landing page — rich content for rspace.online/rsplat + */ + +export function renderLanding(): string { + return ` + +
+ rSplat +

3D Gaussian Splats on the Infinite Canvas

+

+ View, share, and gate 3D scenes captured with Gaussian splatting. + Three.js-powered viewing with optional x402 micropayment gating. +

+
+ Explore Splats + Create a Space +
+
+ + +
+
+

How It Works

+
+
+
1
+

Upload .ply/.splat Files

+

Upload Gaussian splat files captured from real-world scenes or generated from photos and video.

+
+
+
2
+

View in Browser

+

Explore 3D scenes directly in the browser with orbit controls, zoom, and pan. No app install needed.

+
+
+
3
+

Gate with x402 Micropayments

+

Optionally gate uploads with HTTP 402 micropayments. Monetize premium 3D content natively.

+
+
+
+
+ + +
+
+

Features

+

+ A complete pipeline from capture to community gallery. +

+
+
+
🎨
+

Three.js Viewer

+

Hardware-accelerated WebGL rendering with orbit controls, smooth camera, and full-screen mode.

+
+
+
🖼
+

Canvas Integration

+

Embed splats as spatial elements on the rSpace infinite canvas alongside other module content.

+
+
+
💰
+

x402 Gating

+

Monetize 3D content with HTTP 402 micropayments. Viewers pay per-view or per-download automatically.

+
+
+
🌄
+

Community Gallery

+

Browse, search, and discover 3D scenes shared by your community. Sorted by recent, popular, or tagged.

+
+
+
+
+ + +
+
+

Step into 3D

+

+ Explore the demo gallery or upload your own Gaussian splats. +

+ +
+
+ +
+ ← Back to rSpace +
`; +} diff --git a/modules/splat/mod.ts b/modules/splat/mod.ts index a4a934c..fcb9190 100644 --- a/modules/splat/mod.ts +++ b/modules/splat/mod.ts @@ -13,6 +13,7 @@ import { sql } from "../../shared/db/pool"; import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; +import { renderLanding } from "./landing"; import { verifyEncryptIDToken, extractToken, @@ -539,6 +540,7 @@ export const splatModule: RSpaceModule = { icon: "🔮", description: "3D Gaussian splat viewer", routes, + landingPage: renderLanding, standaloneDomain: "rsplat.online", hidden: true, diff --git a/modules/swag/landing.ts b/modules/swag/landing.ts new file mode 100644 index 0000000..9a2db29 --- /dev/null +++ b/modules/swag/landing.ts @@ -0,0 +1,123 @@ +/** + * Swag module landing page — rich content for rspace.online/rswag + */ + +export function renderLanding(): string { + return ` + +
+ rSwag +

Design Community Merch

+

+ Stickers, posters, and tees from your browser. + Upload a design, pick a product, and get print-ready files instantly. +

+
+ Start Designing + Create a Space +
+
+ + +
+
+

How It Works

+
+
+
1
+

Choose a Product

+

Pick from stickers, posters, t-shirts, or patches. Each product has print-ready specs built in.

+
+
+
2
+

Upload Your Design

+

Drop in your artwork. Sharp resizes, crops, and optimizes for the selected product automatically.

+
+
+
3
+

Preview & Order

+

See a live mockup, download print-ready files, or send directly to rCart for community ordering.

+
+
+
+
+ + +
+
+

Products

+

+ Four product types, each with professional print specs. +

+
+
+
🧾
+

Stickers

+

Vinyl die-cut stickers. Weatherproof, UV-resistant, and ready for laptops, bottles, and walls.

+
+
+
🖼
+

Posters

+

A3 and A2 prints at 300 DPI. Gallery-quality paper with bleed margins included.

+
+
+
👕
+

T-Shirts

+

Direct-to-garment (DTG) printing. Full-color designs on comfortable, pre-shrunk cotton.

+
+
+
🧵
+

Patches

+

Embroidered patches with iron-on backing. Perfect for jackets, bags, and hats.

+
+
+
+
+ + +
+
+

Features

+
+
+
👁
+

Live Preview

+

See your design on product mockups before committing. Adjust and iterate in real time.

+
+
+
🖨
+

Print-Ready Export

+

Download files with correct DPI, bleed margins, and color profiles for professional printing.

+
+
+
+

Sharp Processing

+

Server-side image processing with Sharp. Fast resizing, format conversion, and optimization.

+
+
+
🛒
+

rCart Integration

+

Send finished designs directly to rCart for community ordering and fulfillment.

+
+
+
+
+ + +
+
+

Make something your community can wear

+

+ Try the designer or create a space to start your merch line. +

+ +
+
+ +
+ ← Back to rSpace +
`; +} diff --git a/modules/swag/mod.ts b/modules/swag/mod.ts index d4099e2..17380cf 100644 --- a/modules/swag/mod.ts +++ b/modules/swag/mod.ts @@ -14,6 +14,7 @@ import { processImage } from "./process-image"; import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; +import { renderLanding } from "./landing"; const routes = new Hono(); @@ -246,6 +247,7 @@ export const swagModule: RSpaceModule = { icon: "\u{1F3A8}", description: "Design print-ready swag: stickers, posters, tees", routes, + landingPage: renderLanding, standaloneDomain: "rswag.online", feeds: [ { diff --git a/modules/trips/landing.ts b/modules/trips/landing.ts new file mode 100644 index 0000000..d8a7066 --- /dev/null +++ b/modules/trips/landing.ts @@ -0,0 +1,212 @@ +/** + * Trips module landing page — static HTML, no React. + */ +export function renderLanding(): string { + return ` + +
+ rTrips +

Plan Your Trip, Naturally

+

+ Describe your dream trip in plain language. We'll structure it into + itineraries, budgets, and bookings — then give you a collaborative + canvas to plan together in real-time. +

+
+ Try Demo + Create a Space +
+
+ + +
+
+

How It Works

+

Three steps from dream to departure.

+
+
+
1
+

Describe It

+

+ Tell us about your trip in natural language. “Fly from Toronto to Bali + for 2 weeks in March, budget $3000.” We parse it into structured data + you can refine. +

+
+
+
2
+

We Structure It

+

+ AI extracts destinations, dates, budgets, and bookings into organized views. + Edit itineraries, track expenses, manage packing lists — all structured + and searchable. +

+
+
+
3
+

Collaborate on Canvas

+

+ Open the collaborative canvas to plan visually with your travel partners. + Drag destinations, connect itineraries, and brainstorm together in real-time + or async. +

+
+
+
+
+ + +
+
+

Everything You Need to Travel Together

+

+ rTrips brings every piece of trip planning into one place — so your group + spends less time coordinating and more time exploring. +

+
+
+
+ + + +
+

Collaborative Itineraries

+

+ Build day-by-day plans together in real-time. Everyone can add destinations, + suggest activities, and rearrange the schedule — changes sync instantly. +

+
+ +
+
+ + + +
+

Smart Suggestions

+

+ AI-powered recommendations for destinations, restaurants, and activities based + on your group's interests, budget, and travel dates. +

+
+ +
+
+ + + +
+

Budget Tracking

+

+ Split costs, track expenses across the group, and keep a running total so + everyone knows exactly where the money goes. No more messy spreadsheets. +

+
+ +
+
+ + + +
+

Map Integration

+

+ Visualize your entire trip on rMaps. See routes between destinations, + nearby points of interest, and real-time location sharing during travel days. +

+
+ +
+
+ + + +
+

Packing Lists

+

+ Shared checklists so nothing gets forgotten. Assign items to people, mark + off as you pack, and see at a glance what the group still needs. +

+
+ +
+
+ + + +
+

Offline Access

+

+ Download your full itinerary, maps, and booking confirmations for travel + without connectivity. Everything you need, even without a signal. +

+
+
+
+
+ + +
+
+

Built for Groups

+

+ Solo trip planners are everywhere. rTrips is purpose-built for the messy, beautiful + reality of traveling with other people. +

+
+
+
+ + + +
+

Friends & Family

+

+ Family reunions, friend getaways, multi-generational trips. Everyone contributes + ideas, votes on restaurants, and stays in sync without endless group chats. +

+
+ +
+
+ + + +
+

Teams & Offsites

+

+ Company retreats, conference travel, team offsites. Coordinate logistics, + share flight details, and manage group bookings from a single shared workspace. +

+
+ +
+
+ + + +
+

Retreats & Events

+

+ Yoga retreats, wedding trips, festival crews. Organize large groups with + sub-itineraries, optional activities, and shared costs that stay transparent. +

+
+
+
+
+ + +
+
+

Ready to plan your next adventure?

+

Just describe where you want to go. We'll handle the rest.

+ +
+
+ +
← Back to rSpace
+`; +} diff --git a/modules/trips/mod.ts b/modules/trips/mod.ts index 8284f15..e2b0bf1 100644 --- a/modules/trips/mod.ts +++ b/modules/trips/mod.ts @@ -13,6 +13,7 @@ import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; import { verifyEncryptIDToken, extractToken } from "@encryptid/sdk/server"; +import { renderLanding } from "./landing"; const OSRM_URL = process.env.OSRM_URL || "http://osrm-backend:5000"; @@ -271,6 +272,7 @@ export const tripsModule: RSpaceModule = { icon: "\u{2708}\u{FE0F}", description: "Collaborative trip planner with itinerary, bookings, and expense splitting", routes, + landingPage: renderLanding, standaloneDomain: "rtrips.online", feeds: [ { diff --git a/modules/tube/landing.ts b/modules/tube/landing.ts new file mode 100644 index 0000000..fafd78c --- /dev/null +++ b/modules/tube/landing.ts @@ -0,0 +1,110 @@ +/** + * Tube module landing page — rich content for rspace.online/rtube + */ + +export function renderLanding(): string { + return ` + +
+ rTube +

Community Video Platform

+

+ Host, stream, and share video without big tech. + Your community's video library with HLS streaming and RTMP ingest. +

+
+ Start Streaming + Create a Space +
+
+ + +
+
+

How It Works

+
+
+
1
+

Upload Videos

+

Drop video files in any major format. MP4, WebM, MKV, MOV -- they all work.

+
+
+
2
+

Stream Live

+

Point OBS or any RTMP-compatible software at your space's ingest URL and go live instantly.

+
+
+
3
+

Share with Your Community

+

Videos are organized by space. Share links, embed on your canvas, or browse the community library.

+
+
+
+
+ + +
+
+

Features

+

+ Everything you need to run your own community video platform. +

+
+
+
📺
+

HLS Streaming

+

Adaptive bitrate streaming ensures smooth playback on any connection speed or device.

+
+
+
📡
+

RTMP Ingest

+

Go live with OBS, Streamlabs, or any RTMP-compatible streaming software. One URL, instant broadcast.

+
+
+
+

R2 Storage

+

Videos stored on Cloudflare R2 for fast, globally distributed delivery with no egress fees.

+
+
+
🎥
+

Community Channels

+

Each space gets its own video channel. Organize content by community, project, or topic.

+
+
+
+
+ + +
+
+

Technical Details

+
+
    +
  • H.264 / H.265 hardware-accelerated codec support
  • +
  • WebM (VP8/VP9) for open-format video
  • +
  • Adaptive bitrate HLS for smooth playback on any connection
  • +
  • HTTP Range requests for efficient seeking and partial downloads
  • +
  • RTMP ingest compatible with OBS, Streamlabs, and ffmpeg
  • +
+
+
+
+ + +
+
+

Your community's own video platform

+

+ Try the demo or create a space to start hosting and streaming. +

+ +
+
+ +
+ ← Back to rSpace +
`; +} diff --git a/modules/tube/mod.ts b/modules/tube/mod.ts index 16621ac..7fabc3c 100644 --- a/modules/tube/mod.ts +++ b/modules/tube/mod.ts @@ -10,6 +10,7 @@ import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; import { verifyEncryptIDToken, extractToken } from "@encryptid/sdk/server"; +import { renderLanding } from "./landing"; import { S3Client, ListObjectsV2Command, GetObjectCommand, HeadObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3"; const routes = new Hono(); @@ -209,6 +210,7 @@ export const tubeModule: RSpaceModule = { icon: "\u{1F3AC}", description: "Community video hosting & live streaming", routes, + landingPage: renderLanding, standaloneDomain: "rtube.online", feeds: [ { diff --git a/modules/vote/landing.ts b/modules/vote/landing.ts new file mode 100644 index 0000000..3a1d19f --- /dev/null +++ b/modules/vote/landing.ts @@ -0,0 +1,184 @@ +/** + * rVote landing page — democratic backlog prioritization. + */ +export function renderLanding(): string { + return ` + +
+ rVote +

Democratic Backlog
Prioritization

+

+ Quadratic conviction voting with time-decay. Surface the ideas your community actually cares about — + not just the loudest voices. +

+
+ Try the Demo + Create a Space +
+
+ + +
+
+

Three ideas, one system

+
+
+
+ +
+

Quadratic Cost

+

Each additional vote on the same proposal costs quadratically more credits. One vote = 1 credit, two = 4, three = 9. Prevents plutocratic capture.

+
+
+
+ +
+

Reddit-style Ranking

+

Proposals accumulate conviction score from community votes. The most supported ideas float to the top.

+
+
+
+ +
+

Vote Decay

+

Votes lose weight over 30–60 days. Stale support fades automatically — no need to manually close polls.

+
+
+
+
+ + +
+
+

What is Quadratic Priority Ranking?

+
+
+

The Problem

+

Traditional voting (1 person = 1 vote) lets small, passionate groups dominate. + Token-weighted voting lets whales decide everything. Neither reflects genuine community preference.

+
+
+

The Solution

+

Quadratic voting makes strong preferences expensive. You can signal that you care a lot — + but it costs quadratically more. This balances intensity of preference with breadth of support.

+
+
+
+
+ + +
+
+

Vote cost calculator

+

The cost of conviction grows quadratically.

+
+
+
+
1
+
vote
+
1 credit
+
+
+
2
+
votes
+
4 credits
+
+
+
3
+
votes
+
9 credits
+
+
+
4
+
votes
+
16 credits
+
+
+
5
+
votes
+
25 credits
+
+
+
+
+
+ + +
+
+

The lifecycle of a proposal

+
+
+ 1 +

Ranking (QPR)

+

Community members spend credits to upvote proposals. Conviction score accumulates with quadratic cost.

+
+
+ 2 +

Score reaches +100

+

When a proposal crosses the promotion threshold (default 100), it automatically enters the final vote.

+
+
+ 3 +

Pass / Fail Vote

+

A time-limited binary vote (Yes / No / Abstain) decides the outcome. Simple majority wins.

+
+
+
+
+ + +
+
+

Built for real governance

+
+
+
+ +
+

Earn Credits Daily

+

Every verified member receives a daily credit allowance. No pay-to-play.

+
+
+
+ +
+

Vote Decay

+

Votes decay linearly from day 30 to day 60. Stale support fades, keeping rankings fresh.

+
+
+
+ +
+

Sybil Resistant

+

Passkey authentication via EncryptID. One person, one identity, one credit stream.

+
+
+
+ +
+

Auto Promotion

+

Proposals that hit the threshold automatically move to a final pass/fail vote. No admin bottleneck.

+
+
+
+
+ + +
+
+

Ready to prioritize democratically?

+

+ Create a governance space, submit proposals, and let your community decide what matters most. +

+ +
+
+ +
+ ← Back to rSpace +
`; +} diff --git a/modules/vote/mod.ts b/modules/vote/mod.ts index 6d36285..fecabd0 100644 --- a/modules/vote/mod.ts +++ b/modules/vote/mod.ts @@ -13,6 +13,7 @@ import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; import { verifyEncryptIDToken, extractToken } from "@encryptid/sdk/server"; +import { renderLanding } from "./landing"; const routes = new Hono(); @@ -346,6 +347,7 @@ export const voteModule: RSpaceModule = { description: "Conviction voting engine for collaborative governance", routes, standaloneDomain: "rvote.online", + landingPage: renderLanding, feeds: [ { id: "proposals", diff --git a/modules/wallet/landing.ts b/modules/wallet/landing.ts new file mode 100644 index 0000000..b7e505b --- /dev/null +++ b/modules/wallet/landing.ts @@ -0,0 +1,119 @@ +/** + * rWallet — rich landing page body. + * Returned by landingPage() in the module export; + * the shell wraps it with header, CSS, and analytics. + */ +export function renderLanding(): string { + const demo = "https://demo.rspace.online/rwallet"; + + return ` + +
+ rWallet +

Community Treasury, Transparent

+

+ Visualize your Safe multisig across every chain — balances, + transactions, and governance — all in one client-side dashboard. + No backend database, no custody risk. +

+
+ View Your Treasury + Create a Space +
+
+ + +
+
+

How It Works

+
+
+
1
+

Connect Your Safe

+

Paste any Safe address. rWallet auto-detects which chains it lives on.

+
+
+
2
+

View Across Chains

+

See token balances, USD valuations, and transaction history for every chain in one view.

+
+
+
3
+

Govern Together

+

Review pending multisig transactions and coordinate approvals with your team.

+
+
+
+
+ + +
+
+

Features

+
+
+
+

Multi-Chain Support

+

Ethereum, Polygon, Base, Gnosis, Arbitrum, Optimism, Celo, Avalanche, BSC, and zkSync.

+
+
+
📋
+

Transaction History

+

Browse incoming and outgoing transfers with human-readable labels and USD values.

+
+
+
🔐
+

Multisig Governance

+

See signer thresholds, pending confirmations, and execution status at a glance.

+
+
+
💰
+

Token Balances

+

ERC-20 and native token balances aggregated across all detected chains.

+
+
+
+
+ + +
+
+

Ecosystem Integration

+

+ rWallet connects to other rSpace modules for a complete treasury workflow. +

+
+
+
📈
+
+

rFunds

+

Overlay budget categories on your wallet data to see where funds are allocated and how they flow.

+
+
+
+
+
+

rVote

+

Link governance proposals directly to treasury transactions for full accountability.

+
+
+
+
+
+ + +
+
+

Ready to Open Your Treasury?

+

+ Paste a Safe address and explore your multichain holdings in seconds. +

+ +
+
+ +
← Back to rSpace
`; +} diff --git a/modules/wallet/mod.ts b/modules/wallet/mod.ts index 6714ee0..8da25a4 100644 --- a/modules/wallet/mod.ts +++ b/modules/wallet/mod.ts @@ -9,6 +9,7 @@ import { Hono } from "hono"; import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; +import { renderLanding } from "./landing"; const routes = new Hono(); @@ -113,6 +114,7 @@ export const walletModule: RSpaceModule = { description: "Multichain Safe wallet visualization and treasury management", routes, standaloneDomain: "rwallet.online", + landingPage: renderLanding, feeds: [ { id: "balances", diff --git a/modules/work/landing.ts b/modules/work/landing.ts new file mode 100644 index 0000000..a08221b --- /dev/null +++ b/modules/work/landing.ts @@ -0,0 +1,127 @@ +/** + * rWork landing page — collective task management. + */ +export function renderLanding(): string { + return ` + +
+ rWork +

Get things done,
together

+

+ Kanban boards, team spaces, and real-time collaboration — built for groups + that share work, not just assign it. +

+
+ Try the Demo + Create a Space +
+
+ + +
+
+

How it works

+
+
+ 1 +

Create a Space

+

Every workspace lives inside an rSpace — shared by default with your team.

+
+
+ 2 +

Add Tasks

+

Create tasks with titles, descriptions, labels, and priorities. Drag them across columns.

+
+
+ 3 +

Collaborate

+

Assign, comment, and track progress in real time. Everyone sees the same board.

+
+
+
+
+ + +
+
+

Features

+

Everything you need for collaborative task management, nothing you don't.

+
+
+
+ +
+

Kanban Boards

+

Drag-and-drop columns with customizable statuses. See everything at a glance.

+
+
+
+ +
+

Team Spaces

+

Each workspace is scoped to a space. Members share boards, tasks, and activity.

+
+
+
+ +
+

Real-time Sync

+

Changes propagate instantly. No refresh needed — everyone stays in sync.

+
+
+
+ +
+

Markdown Native

+

Task descriptions support full markdown. Write rich content without leaving the board.

+
+
+
+ +
+

Custom Pipelines

+

Define your own status columns — TODO, In Progress, Review, Done, or whatever fits.

+
+
+
+ +
+

Notifications

+

Get notified when tasks are assigned, moved, or commented on.

+
+
+
+ +
+

Acceptance Criteria

+

Define clear done conditions. Check them off as you go.

+
+
+
+ +
+

rSpace Ecosystem

+

Tasks link to rVote proposals, rCal events, rFunds budgets, and more.

+
+
+
+
+ + +
+
+

Ready to collaborate?

+

+ Create a workspace, invite your team, and start shipping together. +

+ +
+
+ +
+ ← Back to rSpace +
`; +} diff --git a/modules/work/mod.ts b/modules/work/mod.ts index ba03d2a..c32a5cf 100644 --- a/modules/work/mod.ts +++ b/modules/work/mod.ts @@ -13,6 +13,7 @@ import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; import { verifyEncryptIDToken, extractToken } from "@encryptid/sdk/server"; +import { renderLanding } from "./landing"; const routes = new Hono(); @@ -236,6 +237,7 @@ export const workModule: RSpaceModule = { description: "Kanban workspace boards for collaborative task management", routes, standaloneDomain: "rwork.online", + landingPage: renderLanding, feeds: [ { id: "task-activity", diff --git a/server/index.ts b/server/index.ts index 6cb423b..0975a78 100644 --- a/server/index.ts +++ b/server/index.ts @@ -1081,14 +1081,23 @@ const server = Bun.serve({ const mod = allModules.find((m) => m.id === firstSegment); if (mod) { if (pathSegments.length === 1) { - // Try proxying the rich standalone landing page + // 1. Check for inline rich landing page + if (mod.landingPage) { + const html = renderModuleLanding({ + module: mod, + modules: getModuleInfoList(), + bodyHTML: mod.landingPage(), + }); + return new Response(html, { headers: { "Content-Type": "text/html; charset=utf-8" } }); + } + // 2. Try proxying the rich standalone landing page const proxyHtml = await fetchLandingPage(mod, getModuleInfoList()); if (proxyHtml) { return new Response(proxyHtml, { headers: { "Content-Type": "text/html; charset=utf-8" }, }); } - // Fallback to generic landing page + // 3. Fallback to generic landing page const html = renderModuleLanding({ module: mod, modules: getModuleInfoList(), diff --git a/server/shell.ts b/server/shell.ts index 80ec06a..8d4f7e9 100644 --- a/server/shell.ts +++ b/server/shell.ts @@ -423,13 +423,36 @@ export interface ModuleLandingOptions { modules: ModuleInfo[]; /** Theme */ theme?: "dark" | "light"; + /** Rich body HTML from a module's landing.ts (replaces generic hero) */ + bodyHTML?: string; } export function renderModuleLanding(opts: ModuleLandingOptions): string { - const { module: mod, modules, theme = "dark" } = opts; + const { module: mod, modules, theme = "dark", bodyHTML } = opts; const moduleListJSON = JSON.stringify(modules); const demoUrl = `https://demo.rspace.online/${mod.id}`; + const cssBlock = bodyHTML + ? `\n ` + : ``; + + const bodyContent = bodyHTML + ? bodyHTML + : `
+
+ ${mod.icon} +

${escapeHtml(mod.name)}

+

${escapeHtml(mod.description)}

+ +
+
+
+ ← Back to rSpace +
`; + return ` @@ -438,7 +461,7 @@ export function renderModuleLanding(opts: ModuleLandingOptions): string { ${escapeHtml(mod.name)} — rSpace - + ${cssBlock} @@ -452,20 +475,7 @@ export function renderModuleLanding(opts: ModuleLandingOptions): string { -
-
- ${mod.icon} -

${escapeHtml(mod.name)}

-

${escapeHtml(mod.description)}

- -
-
-
- ← Back to rSpace -
+ ${bodyContent}