V1 Web PWA · Surface walkthrough

Landing — OSHUN public marketing front

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

walked
8sections3 minread

On this page

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

Last walked. 2026-06-30 Playwright real-dev-infra deepening — default render, exact rooms/letters/tiers, primary and tier CTA destinations, public-auth-funnel handoff telemetry, social metadata/PNG previews, sitemap entry, mobile standalone no-overflow/44 px CTA targets, reduced-motion fixture default, and warmed real-service-worker offline document replay verified in apps/oshun/web/e2e/public-marketing.spec.ts

Purpose#

The public editorial face of OSHUN: one anonymous route that explains the six rooms, shows product screenshots, and routes readers into the /welcome sign-up panel with entry=marketing-landing. Distinct from /welcome, which is the auth-coupled entry surface.

Entry points#

  • Marketing campaigns (paid social, search ads) pointing to /landing
  • Outbound newsletter "view in browser" link
  • Direct URL / bookmark — yes (anon)
  • Search/social crawlers through canonical, OpenGraph, Twitter card, and JSON-LD metadata
  • /legal/lilith colophon link from the lede

Layout regions#

page.tsx is a thin server component: const data = await getMarketingLanding(); return <MarketingLanding data={data} />. MarketingLanding renders inside the shared Lilith LWebShell.

  • Masthead: OSHUN broadsheet masthead with dated issue marker
  • Product preview strip: two screenshot images under [data-marketing-visual-strip]
  • Three-column lede: manifesto copy, primary sign-up CTA, colophon link, field-guide pull quote, by-the-numbers cells, and six room inventory
  • Launch rooms in use: three static letter/scenario pull quotes
  • Membership: three pricing tiers (solo, hearth, institutional) with tier-specific sign-up links
  • Footer: text-only Lilith-register footer. The "Privacy" and "Colophon" entries are rendered as spans, not legal navigation anchors.

States#

  • LoadinggetMarketingLanding() is awaited server-side; no Suspense boundary in page.tsx itself, so server blocks until data ready
  • Default (populated)public-marketing verifies the fixture-backed room, letter, tier, screenshot, structured-data, metadata, and sitemap render
  • Error (unrecoverable) — there is no segment error.tsx; failures fall through the app-level error boundary
  • Offlinepublic-marketing warms /landing, waits for the real public/sw.js controller, asserts /landing is cached in an oshun-* cache, then reloads offline and verifies a service-worker response without the generic offline fallback markers
  • Standalone PWA — 390 px standalone launch is mocked through the shared PWA helper and verified for no horizontal overflow
  • Reduced motion — the shared E2E fixture emulates prefers-reduced-motion: reduce while the same default/mobile assertions run

Interactions#

  • Primary CTABegin · 14 days free links to /welcome?mode=signup&entry=marketing-landing; clicking it records public_auth_funnel_cta_clicked with surface=marketing_landing, step=marketing_signup, and entrySource=marketing-landing, then /welcome records the viewed event with the same entry source
  • Pricing tier CTAs — exact destinations are: /welcome?mode=signup&entry=marketing-landing&tier=Solo, /welcome?mode=signup&entry=marketing-landing&tier=Hearth, and /welcome?mode=signup&entry=marketing-landing&tier=Institutional; the Hearth click is browser-driven and records step=marketing_tier_signup
  • Colophon linkRead the colophon targets /legal/lilith
  • Letters/scenarios — the three pull quotes are static: "Morning practitioner", "Careful reader", and "Skywatching family". There are no carousel controls.
  • Footer markers — footer is present, contains "Privacy" and "Colophon" copy, and intentionally has zero descendant anchors

Data & contracts#

  • Reads: getMarketingLanding() from @/lib/lilith-data/marketing-landing returns getMarketingLandingFixture() today. The fixture contains:
    • rooms: Tara, Arete, Veritas, Nyx, Nisaba, Metis
    • letters: Morning practitioner, Careful reader, Skywatching family
    • tiers: Solo $9, Hearth $14, Institutional From $4
  • Writes: none from this page
  • Caching: fixture-backed server render; public/sw.js treats /landing as an exact shell navigation route and caches the rendered HTML after a warm online navigation
  • Auth/role check: anon (in middleware PUBLIC_PREFIXES)
  • Metadata: title: 'OSHUN — One calm shell for six practices', description: 'OSHUN connects Tara meditation, Arete habits, Veritas evidence, Nyx skywatching, Nisaba reading, and Metis learning in one calm companion.', alternates.canonical: '/landing'
  • Structured data: JSON-LD graph includes Organization, WebApplication, OfferCatalog, and BreadcrumbList
  • Crawler assets: /landing/opengraph-image and /landing/twitter-image return PNG previews

Cross-references#

Open questions / known gaps#

  • getMarketingLanding() is still fixture-backed; BFF/CMS ownership, freshness policy, and release process are future wiring work.
  • There is no route-local error.tsx for /landing.
  • The footer's "Privacy" and "Colophon" markers are text-only by design today. If product wants footer navigation, the component needs real anchors and the walkthrough should move those checks from negative to positive assertions.