V1 Web PWA · Surface walkthrough

Life Balance · Arete · OSHUN

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

walked
8sections2 minread

On this page

Context. surface customer · domain arete · route /domains/arete/balance · auth signed-in · source apps/oshun/web/src/app/domains/arete/balance/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

Purpose#

Internal /domains/arete/* alternate surface for life-balance assessment: a 4-tab workspace (wheel, assessment, history/trends, suggestions to improve). Backed by fixture constants (BALANCE_DOMAINS, BALANCE_SCORES_CURRENT, BALANCE_ASSESSMENT). Renders an SVG radar/spider chart of the eight life domains (career, finance, health, relationships, personal-growth, fun-recreation, physical-environment, spirituality).

Entry points#

  • Direct URL / bookmark — yes (signed-in)
  • No link from /arete polished surface — verify

Layout regions#

page.tsx is a 'use client' page: SR-only "Life Balance · Arete · OSHUN" heading + <AreteLifeBalance />. Component at apps/oshun/web/src/components/domains/arete/AreteLifeBalance.tsx.

  • Container: max-width: 900px; padding: 24px
  • Header: Scale icon + h2 "Life Balance" + subtitle "Assess and optimize balance across all areas of your life"
  • Tab bar (4 tabs):
    • wheel — Balance Wheel (Scale icon)
    • assessment — Assessment (BarChart3 icon)
    • history — Trends (History icon)
    • suggestions — Improve (Lightbulb icon)
  • Content area (per active tab):
    • wheel<BalanceWheelView /> — SVG radar chart with current scores (filled accent polygon) and previous scores (lighter outline polygon). getPoint(index, value) projects each domain to a point on a radius of 160 around center (200, 200). Domain icons (DOMAIN_ICONS: Briefcase / DollarSign / Heart / Users / TrendingUp / Smile / Home / Sparkles) rendered at the perimeter. Overall score (mean of scores[].score) displayed.
    • assessment<AssessmentView />
    • history<TrendsView />
    • suggestions<SuggestionsView />

States#

  • Loading — N/A: client component with sync fixture import
  • Hovered domainhoveredDomain state lights up the spider chart segment (verify in DOM)
  • Tab switching — instant
  • Empty scoresoverallScore would compute as '0'; the radar polygon would be empty (no points)
  • Error (recoverable) — relies on app-level error boundary
  • Offline — purely client; identical offline once loaded
  • Gated — N/A
  • Standalone PWA — no shell chrome around the page; renders bare

Interactions#

Tab bar (4 tabs)#

  • Balance Wheel / Assessment / Trends / Improve (buttons)
    • Function: setActiveTab(tab.id)
    • Keyboard / SR: <button> with no role="tab", no aria-selected
    • Active style: accent tint background, accent foreground
    • Telemetry: none

Balance wheel (SVG)#

  • Radar polygon (path) — fill based on radarPath, derived from current scores projected via getPoint
  • Previous polygon (path) — outlined polygon driven by previousPath; shows score history overlay
  • Domain hotspotshoveredDomain state suggests there's a hover affordance; verify which element receives onMouseEnter / onMouseLeave
  • Domain icons — rendered at each axis end; verify whether clickable

Data & contracts#

  • Reads: import-time BALANCE_DOMAINS, BALANCE_SCORES_CURRENT, BALANCE_ASSESSMENT from @/lib/arete/arete-extended-simulation. No BFF calls.
  • Writes: none — setScores mutations are local
  • Realtime: none
  • Caching: client bundle only
  • Auth/role check: app-level middleware

Cross-references#

  • Domain hub: arete.md
  • Component source: apps/oshun/web/src/components/domains/arete/AreteLifeBalance.tsx
  • Simulation data: apps/oshun/web/src/lib/arete/arete-extended-simulation.ts
  • Types: apps/oshun/web/src/lib/arete/arete-extended-types.ts (BalanceDomain, BalanceScore)

Open questions / known gaps#

  • No counterpart in /arete/* polished routes — balance is a domains-namespace-only surface
  • No shared chrome with the polished /arete Lilith room
  • Score mutations don't persist across reloads (no API write)
  • Verify hover behaviour on radar — hoveredDomain state exists but the source needs deeper read to confirm which mouseevents target it and what the hover affordance looks like