V1 Web PWA · Surface walkthrough

V3 — Public launch landing

A per-surface walkthrough of the V1 Web PWA customer surface: layout, states, interactions, data, and cross-references.

walked
8sections5 minread

On this page

Context. surface customer · domain v3-marketing · route /v3/landing · auth anon · source apps/oshun/web/src/app/v3/landing/page.tsx

Last walked. 2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data (2xx), console/page-errors, expected content, screenshot verified; live screen-reader, touch, offline, and telemetry-delivery checks pending a manual AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md

Out of V1 scope. Documented for completeness; route exists under apps/oshun/web/src/app/v3/landing/page.tsx. V3 publishes Tara, Saraswati, and Lilith Commons live spatial rooms with one launch path across native / Pixel Streaming / fallback web.

Purpose#

The single public marketing entry for OSHUN V3: tenant overview, trailer reel, join flow with tenant + client selector, regional-waitlist mode, store-listing band. Modes are driven by URL search params: ?mode=regional-waitlist swaps hero copy + adds the regional notice; ?tenant=tara|saraswati|commons (also accepts saraswati-stage / lilith-commons) preselects the join-flow tenant radio; ?region=<code> formats the region label uppercase in the regional waitlist copy.

Entry points#

  • Marketing campaigns (paid social, search ads) — /v3/landing is the canonical campaign target
  • Regional-only campaigns: /v3/landing?mode=regional-waitlist&region=eu
  • Tenant-deep-linked variants: /v3/landing?tenant=saraswati
  • Brand link OSHUN in the in-page nav → /landing (V1 marketing landing)
  • Status link V3 health in the in-page nav → /status
  • Direct URL / bookmark — yes, anon

Layout regions#

page.tsx is an async server component that reads searchParams.mode, searchParams.region, searchParams.tenant and forwards them to <V3MarketingLanding mode region tenant />. The component is 'use client' and holds local state for tenant selection, email/platform inputs, trailer play/pause, and the join-flow status banner.

  • Hero section (#v3-hero-title)
    • Background image /screenshots/home-shell-wide.png (priority load)
    • In-page nav: brand → /landing, anchor links #tenants / #trailer / #join-flow, status link → /status
    • Eyebrow: "V3 public launch" (or "V3 regional access" in waitlist mode)
    • H1 OSHUN V3
    • Lead paragraph (mode-dependent)
    • Hero actions: Join V3 / Join waitlist#join-flow; Watch trailer#trailer
    • Hero telemetry: 4 launch metrics (Tenants / Clients / Listings / Status)
  • Tenant band (#v3-tenants-title, data-v3-tenant-overview)
    • Section header + lead
    • Tenant grid (3 cards): Tara Live Studio, Saraswati Stage, Lilith Commons — each with image, label, name, summary, 3 bullet rows
  • Trailer section (#v3-trailer-title, data-v3-trailer)
    • Trailer reel: 3 frames with title + caption + runtime chip
    • Trailer panel: play/pause button (toggles aria-pressed), status text, 3-row trailer facts (Primary cut / Store cuts / Poster assets)
  • Join band (#v3-join-title, data-v3-join-flow)
    • Mode-dependent eyebrow + title + lead
    • Regional notice block (data-v3-regional-waitlist) — only in regional waitlist mode
    • 3 proof items (Launch routing ready / Store package aligned / Status visible)
    • Form: email input, client select (native / pixel-streaming / fallback-web), tenant radio group (3 choices: tara / saraswati / commons; each labelled data-v3-tenant-choice="<id>"), submit button with status banner above
  • Store band (#v3-stores-title, data-v3-store-readiness)
    • Section header + lead
    • 5 store tiles: iOS / Android / Meta / Sony / Steam — each with detail copy
      • accent color

States#

  • Loading — server-rendered; image priority load
  • Hydratedhydrated state flips on mount; controls all enable
  • Default modemode === 'default'; hero eyebrow "V3 public launch"; no regional notice
  • Regional-waitlist mode?mode=regional-waitlist; hero eyebrow "V3 regional access"; regional notice block visible; join-flow status defaults to "Regional waitlist accepts updates for <REGION>."
  • Tenant preselected via URL?tenant=saraswati (or saraswati-stage) or ?tenant=commons (or lilith-commons); the matching radio is checked on first render; unknown tenant defaults to tara
  • Trailer paused — initial state; status text reads "The launch trailer package is ready for web, store, and social placements."
  • Trailer playing — after pressing play; aria-pressed="true"; status text reads "The V3 launch trailer reel is running with reduced-motion fallback available."
  • Form submitted (default mode) — status banner reads "{TenantName} invite staged for {email}. Launch will route through {platform}."
  • Form submitted (regional waitlist mode) — status banner reads "{TenantName} regional waitlist saved for {email} in {REGION}."
  • Offline — static images cached by SW; form onSubmit is local-only, no network call (no offline failure mode in current impl)
  • Gated — N/A; anon-readable
  • Standalone PWA — full-bleed hero renders cleanly; safe-area insets respected
  • Reduced motion — trailer reel respects prefers-reduced-motion (status text acknowledges this)

Interactions#

Hero#

  • OSHUN brand (anchor) → /landing
  • Tenants (anchor) → #tenants smooth scroll
  • Trailer (anchor) → #trailer
  • Join (anchor) → #join-flow
  • V3 health (anchor) → /status
  • Join V3 / Join waitlist (anchor) → #join-flow (label depends on mode)
  • Watch trailer (anchor) → #trailer

Tenant cards#

  • Tara Live Studio card — non-interactive content card; 3 bullet rows
  • Saraswati Stage card — same shape
  • Lilith Commons card — same shape

Trailer#

  • Play launch trailer (button) — toggles trailerPlaying state; aria-pressed flips; label and status text update accordingly
    • Keyboard: tab-focusable; space/enter activates
    • Screen reader: aria-pressed announces toggle state
    • Touch target: ≥ 44×44 CSS px

Join form#

  • Email (input, required, type="email") — controlled, bound to email state; native HTML5 validation on submit
  • Preferred client (select) — options: Native app / Pixel Streaming / Fallback web; bound to platform state
  • Tenant radio group (fieldset/legend "Tenant") — 3 radios; name="tenant"; data-v3-tenant-choice="<id>"; clicking sets selectedTenant
  • Submit (button) — calls handleJoinSubmit which preventDefault()s and updates joinStatus based on mode + selected tenant + email + platform
    • Keyboard: tab-focusable; enter inside any form input submits
    • Screen reader: status banner has role="status" so announcements are posted on update
    • Offline behavior: no network call today; status update is local-only

Store band#

  • iOS / Android / Meta / Sony / Steam tiles — non-interactive content tiles with platform names and ratings

Data & contracts#

  • Reads: searchParams.mode, searchParams.region, searchParams.tenant (server) — all optional
  • Writes: none (form is local-state only today; no network submission)
  • Realtime: none
  • Caching: static; suitable for SSG/ISR; image domain whitelist required for /screenshots/*
  • Auth/role check: anon-readable
  • Metadata: title, description, openGraph (with hero screenshot 1440×960), canonical /v3/landing

Cross-references#

  • Sibling V3 routes: none yet (/v3 index is not authored as a separate page)
  • Outbound:
  • Component source: apps/oshun/web/src/components/lilith/V3MarketingLanding.tsx
  • Test: apps/oshun/web/src/components/lilith/V3MarketingLanding.test.tsx
  • Scope: out-of-V1; see ../../matrix/coverage.md "Out-of-V1 (excluded)" section

Open questions / known gaps#

  • Join form submission is local-only — no BFF endpoint wired today. Submit should hit a real waitlist / interest-capture endpoint before launch
  • No explicit consent / GDPR copy near the email input — required for regional waitlist mode in EU
  • No tenant card click target — cards display content but don't navigate to tenant-specific microsites
  • Store tiles are static — no link to actual platform store listings
  • Hero image alt text is generic ("OSHUN shell preview with connected public rooms"); tenant-deep-linked variants don't swap the hero asset
  • No live trailer video — "Play launch trailer" toggles status text only; the actual <video> element is not present