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/lilithcolophon 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#
- Loading —
getMarketingLanding()is awaited server-side; no Suspense boundary inpage.tsxitself, so server blocks until data ready - Default (populated) —
public-marketingverifies 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 - Offline —
public-marketingwarms/landing, waits for the realpublic/sw.jscontroller, asserts/landingis cached in anoshun-*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: reducewhile the same default/mobile assertions run
Interactions#
- Primary CTA —
Begin · 14 days freelinks to/welcome?mode=signup&entry=marketing-landing; clicking it recordspublic_auth_funnel_cta_clickedwithsurface=marketing_landing,step=marketing_signup, andentrySource=marketing-landing, then/welcomerecords 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 recordsstep=marketing_tier_signup - Colophon link —
Read the colophontargets/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-landingreturnsgetMarketingLandingFixture()today. The fixture contains:- rooms: Tara, Arete, Veritas, Nyx, Nisaba, Metis
- letters: Morning practitioner, Careful reader, Skywatching family
- tiers: Solo
$9, Hearth$14, InstitutionalFrom $4
- Writes: none from this page
- Caching: fixture-backed server render;
public/sw.jstreats/landingas 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, andBreadcrumbList - Crawler assets:
/landing/opengraph-imageand/landing/twitter-imagereturn PNG previews
Cross-references#
- Sibling public entry:
welcome.md— the auth-coupled variant - Lilith editorial legal pages:
legal-lilith.md,legal-lilith-privacy.md - Standard legal pages:
legal-privacy.md,legal-terms.md - Component sources:
apps/oshun/web/src/components/lilith/MarketingLanding.tsxapps/oshun/web/src/lib/lilith-data/marketing-landing.ts
- E2E:
apps/oshun/web/e2e/public-marketing.spec.ts
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.tsxfor/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.