feat(tours): add guided tour links to 7 landing pages and startTour() to 5 components

Landing pages now consistently include "Start Guided Tour →" in the
hero CTA area. Components that already had internal tours (rbnb, rvnb,
rsplat) get a public startTour() wrapper; rtime and rmeets get full
TourEngine integration with contextual steps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-03-31 09:33:11 -07:00
parent 636360ce5f
commit 81d8102f69
12 changed files with 79 additions and 0 deletions

View File

@ -15,6 +15,11 @@ export function renderLanding(): string {
<a href="https://demo.rspace.online/crowdsurf" class="rl-cta-primary">Start Swiping</a>
<a href="/create-space" class="rl-cta-secondary">Create a Space</a>
</div>
<p style="font-size:0.82rem;margin-top:0.5rem">
<a href="#" onclick="document.querySelector('folk-crowdsurf-dashboard')?.startTour?.();window.__rspaceHideInfo?.();return false" style="color:var(--rs-primary,#06b6d4);text-decoration:none">
Start Guided Tour &rarr;
</a>
</p>
</div>
<!-- How it works -->

View File

@ -450,6 +450,8 @@ class FolkBnbView extends HTMLElement {
el.textContent = s || '';
return el.innerHTML;
}
startTour() { this.#tour?.start(); }
}
if (!customElements.get('folk-bnb-view')) {

View File

@ -27,6 +27,11 @@ export function renderLanding(): string {
</a>
<a href="#principles" class="rl-cta-secondary">Learn More</a>
</div>
<p style="font-size:0.82rem;margin-top:0.5rem">
<a href="#" onclick="document.querySelector('folk-bnb-view')?.startTour?.();window.__rspaceHideInfo?.();return false" style="color:var(--rs-primary,#06b6d4);text-decoration:none">
Start Guided Tour &rarr;
</a>
</p>
</div>
<!-- Principles (4-card grid) -->

View File

@ -19,6 +19,11 @@ export function renderLanding(): string {
<a href="https://demo.rspace.online/rdata" class="rl-cta-primary" id="ml-primary">View Dashboard</a>
<a href="/create-space" class="rl-cta-secondary">Create a Space</a>
</div>
<p style="font-size:0.82rem;margin-top:0.5rem">
<a href="#" onclick="document.querySelector('folk-content-tree')?.startTour?.();window.__rspaceHideInfo?.();return false" style="color:var(--rs-primary,#06b6d4);text-decoration:none">
Start Guided Tour &rarr;
</a>
</p>
</div>
<!-- Features -->

View File

@ -390,6 +390,24 @@ class FolkJitsiRoom extends HTMLElement {
this.directorCanvas = null;
this.destroyDirectorHls();
}
/* ── Guided Tour ── */
private _tour: import('../../../shared/tour-engine').TourEngine | null = null;
private async _initTour() {
if (this._tour) return;
const { TourEngine } = await import('../../../shared/tour-engine');
this._tour = new TourEngine(this.shadow as unknown as ShadowRoot, [
{ target: '#jitsi-meet', title: 'Video Meeting', message: 'Your self-hosted Jitsi Meet room. All video and audio stays on your own infrastructure.' },
{ target: '.jitsi-container', title: 'Full-Screen Controls', message: 'Use the Jitsi toolbar for mute, camera, screen share, chat, and more — all built in.' },
], 'rmeets_tour_done', () => this.shadow.querySelector('.jitsi-container') as HTMLElement);
}
async startTour() {
await this._initTour();
this._tour?.start();
}
}
customElements.define("folk-jitsi-room", FolkJitsiRoom);

View File

@ -18,6 +18,11 @@ export function renderLanding(): string {
<a href="https://demo.rspace.online/rmeets" class="rl-cta-primary" id="ml-primary">Start a Meeting</a>
<a href="/create-space" class="rl-cta-secondary">Create a Space</a>
</div>
<p style="font-size:0.82rem;margin-top:0.5rem">
<a href="#" onclick="document.querySelector('folk-jitsi-room')?.startTour?.();window.__rspaceHideInfo?.();return false" style="color:var(--rs-primary,#06b6d4);text-decoration:none">
Start Guided Tour &rarr;
</a>
</p>
</div>
<!-- Why Self-Host -->

View File

@ -1160,6 +1160,8 @@ export class FolkSplatViewer extends HTMLElement {
renderer.dispose();
};
}
startTour() { this._tour?.start(); }
}
// ── Helpers ──

View File

@ -17,6 +17,11 @@ export function renderLanding(): string {
<a href="https://demo.rspace.online/rsplat" class="rl-cta-primary" id="ml-primary">Open Canvas</a>
<a href="/create-space" class="rl-cta-secondary">Create a Space</a>
</div>
<p style="font-size:0.82rem;margin-top:0.5rem">
<a href="#" onclick="document.querySelector('folk-splat-viewer')?.startTour?.();window.__rspaceHideInfo?.();return false" style="color:var(--rs-primary,#06b6d4);text-decoration:none">
Start Guided Tour &rarr;
</a>
</p>
</div>
<!-- Features -->

View File

@ -1270,6 +1270,26 @@ class FolkTimebankApp extends HTMLElement {
this.shadow.getElementById('taskEditOverlay')!.classList.remove('visible');
this.editingTaskNode = null;
}
/* ── Guided Tour ── */
private _tour: import('../../../shared/tour-engine').TourEngine | null = null;
private async _initTour() {
if (this._tour) return;
const { TourEngine } = await import('../../../shared/tour-engine');
this._tour = new TourEngine(this.shadow as unknown as ShadowRoot, [
{ target: '.tab-bar', title: 'Pool & Weave Views', message: 'Switch between the Commitment Pool (visual orbs) and the Weaving Dashboard (SVG node editor).' },
{ target: '#pool-canvas', title: 'Commitment Pool', message: 'Each floating orb represents a time commitment — sized by hours, colored by skill category.' },
{ target: '#addBtn', title: 'Add a Commitment', message: 'Pledge your hours with a skill category. Your commitment joins the pool for others to see.', advanceOnClick: true },
{ target: '.stats-bar', title: 'Community Stats', message: 'See total hours available and how many contributors are in the pool at a glance.' },
], 'rtime_tour_done', () => this.shadow.querySelector('.main') as HTMLElement);
}
async startTour() {
await this._initTour();
this._tour?.start();
}
}
// ── CSS ──

View File

@ -27,6 +27,11 @@ export function renderLanding(): string {
</a>
<a href="/create-space" class="rl-cta-secondary">Create a Space</a>
</div>
<p style="font-size:0.82rem;margin-top:0.5rem">
<a href="#" onclick="document.querySelector('folk-timebank-app')?.startTour?.();window.__rspaceHideInfo?.();return false" style="color:var(--rs-primary,#06b6d4);text-decoration:none">
Start Guided Tour &rarr;
</a>
</p>
</div>
<!-- ELI5: What is Timebanking? -->

View File

@ -503,6 +503,8 @@ class FolkVnbView extends HTMLElement {
el.textContent = s || '';
return el.innerHTML;
}
startTour() { this.#tour?.start(); }
}
if (!customElements.get('folk-vnb-view')) {

View File

@ -28,6 +28,11 @@ export function renderLanding(): string {
</a>
<a href="#principles" class="rl-cta-secondary">Learn More</a>
</div>
<p style="font-size:0.82rem;margin-top:0.5rem">
<a href="#" onclick="document.querySelector('folk-vnb-view')?.startTour?.();window.__rspaceHideInfo?.();return false" style="color:var(--rs-primary,#06b6d4);text-decoration:none">
Start Guided Tour &rarr;
</a>
</p>
</div>
<!-- Principles (4-card grid) -->