V1 Web PWA · Surface walkthrough

Legal · Lilith Terms of Use (editorial variant)

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

walked
9sections3 minread

On this page

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

Last walked. 2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data (2xx), console/page-errors, expected content, screenshot verified; manual screen-reader and real telemetry-delivery checks pending. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md; 2026-06-28 public-legal-pages Playwright pass covered anonymous routing, editorial heading/version/body contract, non-clickable footer markers, 390 px no-overflow, offline-after-load stability, no telemetry hooks, and axe. Manual AT pass and real telemetry delivery remain pending.

Purpose#

Editorial-register terms of use rendered through LegalPage (a Lilith system-page composition), not the standard LegalPageShell. Five roman-numeralled briefs (I · what this is, II · your account, III · what we keep, briefly, IV · AI · disclosed, V · ending the agreement). "Short on purpose" — distinct from /legal/terms.

Entry points#

  • Sidebar nav "Lilith Terms" inside the standard LegalPageShell legal pages
  • Footer link on /landing (Lilith marketing surface)
  • Direct URL / bookmark — yes (anon)

Layout regions#

page.tsx is a one-liner: <LegalPage kind="terms" />. The LegalPage composition (in apps/oshun/web/src/components/lilith/system-pages.tsx) wraps the content in <LWebShell> and renders:

  • Header (shell): LWebShell chrome (no LCustomerNav passed, so no domain nav strip)
  • Page eyebrow: LEyebrow color={L.accent} → "Lilith · legal"
  • Title: Terms of use. in 48px serif (Cormorant Garamond)
  • Version code: LCode color={L.muted} → "Effective · 1 May 2026 · v.0142"
  • Double rule: LDoubleRule
  • Body (max-width 62ch): five roman-numeralled briefs separated by LEyebrow color accents:
    • I · what this is — drop-cap "L" paragraph
    • II · your account
    • III · what we keep, briefly
    • IV · AI · disclosed — explains the glyph and the Settings · AI opt-out
    • V · ending the agreement
    • Sale statement: "We do not sell anything."
  • Footer rule: LRule
  • Footer link row: five italic underlined text spans (not anchors): "Terms", "Privacy", "DPA", "Sub-processors", "DMCA"

States#

  • Loading — N/A; static server component
  • Default — all five briefs render, including the disclosure glyph, Settings · AI reference, v.0142, and "We do not sell anything."
  • Narrow viewport — body is maxWidth: '62ch' so it reflows; LWebShell handles outer padding
  • Print — no print-specific stylesheet on LegalPage (unlike LegalPageShell); confirm output quality
  • Offline after load — once loaded, the URL, heading, and body contract remain stable when the browser context goes offline

Interactions#

  • "Terms" / "Privacy" / "DPA" / "Sub-processors" / "DMCA" (text spans)
    • Function: rendered as italic underlined <span> elements without href attributes — they look like links but are NOT clickable
    • Keyboard: not focusable
    • Screen reader: announces as plain text

Inline ✻ glyph#

  • "✻" disclosure mark — non-interactive; explained in section IV as the marker placed beside AI-assisted features elsewhere in the app (assistant, coach, claim checker, atelier outputs)

"Settings · AI" reference#

  • "Settings · AI" (italic text) — referenced in body copy as the place to disable individual AI features; not hyperlinked here

Data & contracts#

  • Reads: none — static text inside the LegalPage component
  • Writes: none
  • Caching: SSR static; loaded-route offline stability is asserted. Cold offline navigation / per-legal SW path caching is not asserted, and current sw.js does not path-cache /legal/*.
  • Auth: anon (in middleware PUBLIC_PREFIXES)
  • Metadata: title: 'Lilith · terms of use', description: 'Short on purpose. What this is, your account, what we keep, AI disclosed, leaving.'

Cross-references#

E2E coverage#

  • Backed by apps/oshun/web/e2e/public-legal-pages.spec.ts — covers anonymous access, editorial heading/version/body contract, , Settings · AI, "We do not sell anything.", intentionally non-clickable footer markers, 390 px no-overflow, offline-after-load stability, no telemetry hooks, and axe.

Open questions / known gaps#

  • Cold offline navigation / per-legal SW cache is not asserted and current sw.js does not path-cache /legal/*; PWA shell cache coverage remains in the offline-first / PWA walkthroughs.
  • Footer "Terms / Privacy / DPA / Sub-processors / DMCA" entries are <span> not <a> — confirm whether they should be live links to the standard legal pages
  • No "Sub-processors" or "DMCA" route exists yet — footer references both
  • kind="terms" and kind="privacy" share the same LegalPage composition but only swap the title — copy diverges only slightly; confirm whether the two routes are intentional
  • Version string "v.0142" is hard-coded; tie to release notes
  • No printable layout / print stylesheet for this editorial variant