# ANTIGRAVITY_TEST_PLAN.md — Oshun Web App Comprehensive Frontend Browser Test Plan

> **Purpose**: Exhaustive browser-based frontend testing of the OSHUN web app
> (`apps/oshun/web`) backed by real dev infrastructure (BFF, domain APIs,
> database, Redis). Every feature is tested end-to-end. When a test fails, the
> underlying issue is fixed before proceeding.
>
> **Test Environment**: Oshun web on `http://localhost:3010`, BFF on
> `http://localhost:4010`, Tara API on `http://localhost:4101`, Veritas API on
> `http://localhost:4201`, Nyx API on `http://localhost:4301`, Arete API on
> `http://localhost:4401`.
>
> **Legend**: `[ ]` = not started · `[/]` = in progress · `[x]` = passed · `[!]`
> = failed → fixed → re-verified

---

## Section 1 — Infrastructure & Environment Readiness

### 1.1 Backend Services Boot

- [ ] Start PostgreSQL database and verify connection
- [ ] Start Redis and verify connection
- [ ] Start Tara API (`localhost:4101`) and confirm `/health` returns 200
- [ ] Start Veritas API (`localhost:4201`) and confirm `/health` returns 200
- [ ] Start Nyx API (`localhost:4301`) and confirm `/health` returns 200
- [ ] Start Arete API (`localhost:4401`) and confirm `/health` returns 200
- [ ] Start Oshun BFF (`localhost:4010`) and confirm `/v1/health` returns 200
- [ ] Verify BFF can reach all four domain APIs (adapters connect successfully)
- [ ] Verify BFF CORS allows requests from `localhost:3010`

### 1.2 Web App Boot

- [ ] Start Oshun web (`localhost:3010`) via `npm run dev` or equivalent
- [ ] Verify the home page (`/`) loads without console errors
- [ ] Verify no unhandled promise rejections on initial load
- [ ] Verify all CSS loads (no unstyled flash / FOUC)
- [ ] Verify all fonts load (custom web fonts from Google Fonts or similar)
- [ ] Verify favicon and page title are set correctly
- [ ] Verify `<meta>` description tag is present

### 1.3 Dev Auth Token

- [ ] Verify the dev auth token
      (`dev.eyJzdWIiOiJ1MTIzIiwic2NvcGVzIjpbImRvbWFpbjoqIl19`) is accepted by
      BFF
- [ ] Verify BFF returns 401 for requests without auth header
- [ ] Verify BFF returns 401 for requests with malformed token
- [ ] Verify BFF returns correct user identity from token payload

---

## Section 2 — Home Dashboard (`/`)

### 2.1 Page Layout & Structure

- [ ] Page loads and renders the `<main>` element with class `shell`
- [ ] Shell route navigator is visible with "Home" as the active tab
- [ ] Page has a hero section with a user greeting
- [ ] Hero shows a dynamic title mentioning Tara, Veritas, Nyx, and Arete
- [ ] Hero shows a subtitle about tracking momentum
- [ ] Hero shows the current day and date in locale format
- [ ] Hero shows "Synced at" with the current time

### 2.2 User Greeting

- [ ] `UserGreeting` component renders
- [ ] Greeting text is contextual to time of day (e.g., "Good morning" / "Good
      afternoon" / "Good evening")
- [ ] Greeting displays correctly at different browser-simulated times

### 2.3 KPI Metrics Grid

- [ ] Four metric tiles are displayed: Streak, Saved, Sessions, Domains
- [ ] Each tile shows a value and a label
- [ ] KPI grid has proper `aria-label="Dashboard metrics"`
- [ ] KPI tiles are styled distinctly (background, border, or elevation)
- [ ] KPI layout is responsive — stacks on narrow viewports, grid on wide

### 2.4 Universal Search Panel (on Home)

- [ ] Search panel renders with an input field
- [ ] Clicking the search input activates the search experience
- [ ] Typing a query shows search results (test with "meditation")
- [ ] Search results display domain badges for each result
- [ ] Pressing Escape or clicking outside closes search
- [ ] Empty query shows recent searches or suggestions
- [ ] Search panel is wrapped in `<Suspense>` (no layout shift on load)

### 2.5 Domain Switcher Entry Panel (on Home)

- [ ] Domain switcher renders on the home page with `surface="home"`
- [ ] All four domain pills are visible: Tara, Veritas, Nyx, Arete
- [ ] Each pill has the correct accent color
- [ ] Clicking a domain pill navigates to that domain's route
- [ ] Domain switcher responds to hover states

### 2.6 Daily Plan Panel

- [ ] Daily plan panel renders with heading "Daily plan"
- [ ] Plan description text mentions Tara breathwork, Veritas deep read, Nyx
      evening check-in
- [ ] Progress track bar is visible
- [ ] Progress fill is rendered (styled span inside track)
- [ ] "1 of 3 complete" meta text is shown
- [ ] QuickActionsTrayPanel renders inside the daily plan section

### 2.7 Quick Actions Tray (on Home)

- [ ] Quick actions tray renders with `surface="home"`
- [ ] Action buttons are visible (e.g., Resume, Save, Continue, Streak)
- [ ] Each action button is clickable
- [ ] Actions are styled with hover / active states
- [ ] Actions are accessible with keyboard navigation

### 2.8 Cross-Domain Activity List

- [ ] Activity panel renders with heading "Cross-domain activity"
- [ ] Three activity items are listed
- [ ] Each item shows a title (e.g., "Completed Tara breath sequence")
- [ ] Each item shows relative time metadata (e.g., "24 min ago")
- [ ] Activity list uses `<ul>` and `<li>` for semantic HTML

### 2.9 Notifications Center Panel (on Home)

- [ ] Notifications center renders on the home page
- [ ] Notification items are displayed with correct domain colours
- [ ] Each notification shows title, body, and timestamp
- [ ] Notifications are grouped by time (Now, Today, Earlier)
- [ ] Unread notifications have a visual indicator (dot or badge)
- [ ] Domain filter pills allow filtering by domain
- [ ] "All domains" filter is active by default
- [ ] Clicking a domain filter filters the notification list
- [ ] High-priority notifications are distinguished visually
- [ ] Notification kind labels (Reminder, Update, Event, Insight) are shown
- [ ] Notifications fetch from BFF endpoint `/v1/notifications`
- [ ] Mark-read functionality works (notification dot disappears)
- [ ] Bulk mark-read button works if available
- [ ] Notifications panel handles API errors gracefully (shows error state or
      fallback)
- [ ] Notifications panel handles empty state (no notifications)

### 2.10 Profile Settings Panel (on Home)

- [ ] Profile settings panel renders on the home page
- [ ] User profile section shows name, email, plan tier
- [ ] Profile avatar or placeholder is shown
- [ ] Theme toggle cycles through System → Light → Dark
- [ ] Language toggle cycles through English → Spanish → French
- [ ] Reduced motion toggle works
- [ ] High contrast toggle works
- [ ] Haptics toggle works
- [ ] Offline downloads toggle works
- [ ] Sync on cellular toggle works
- [ ] Privacy settings section is visible
- [ ] Biometric lock toggle works
- [ ] Crash reporting toggle works
- [ ] Private profile toggle works
- [ ] Cross-domain personalization toggle works
- [ ] Consent controls section renders
- [ ] Each consent type has a toggle (analytics, personalization, marketing)
- [ ] Data export format cycle works (JSON → CSV → etc.)
- [ ] "Request data export" button triggers export flow
- [ ] "Request data deletion" button shows confirmation dialog
- [ ] Data deletion confirmation requires explicit confirmation
- [ ] Cancel data deletion request works
- [ ] Billing section shows current plan and status
- [ ] Billing recovery status is displayed when applicable
- [ ] Upgrade button triggers checkout flow
- [ ] Add backup payment method button works
- [ ] Retry billing now button works (for failed payments)
- [ ] Schedule billing retry works
- [ ] Session management / linked devices section renders

### 2.11 Domain Hub Grid

- [ ] Panel with heading "Domain hub" renders
- [ ] Description mentions jumping into any surface
- [ ] Four domain cards are rendered: Tara, Veritas, Nyx, Arete
- [ ] Each card shows the domain name as `<h3>`
- [ ] Each card shows a description (tagline)
- [ ] Each card shows up to 2 capabilities in a `<ul>`
- [ ] Each card has a CTA link (e.g., "Open Tara", "Open Veritas")
- [ ] CTA links navigate to the correct domain route (e.g.,
      `/domains/tara?origin=home`)
- [ ] Each card applies `--domain-accent` CSS custom property for accent colour
- [ ] Domain cards are responsive — single column on mobile, grid on desktop
- [ ] Hover state on domain cards works (elevation, shadow, or scale)

### 2.12 PWA Install Prompt (on Home)

- [ ] PwaInstallPrompt component renders
- [ ] In a supporting browser, an install prompt or banner is shown
- [ ] Install button click triggers the browser install flow
- [ ] Dismissing the prompt hides it

---

## Section 3 — Explore Page (`/explore`)

### 3.1 Page Layout & Navigation

- [ ] Navigate to `/explore` — page loads without errors
- [ ] Shell route navigator shows "Explore" as the active tab
- [ ] Page has the Explore layout and structure

### 3.2 Universal Search (on Explore)

- [ ] UniversalSearchPanel renders
- [ ] Search input is functional (type a query, results appear)
- [ ] Navigating to `/explore?q=meditation` hydrates the query in the page
- [ ] Hydrated query shows "Searching for: meditation" text
- [ ] Search results from BFF `/v1/search` are displayed
- [ ] Each search result shows domain badge, title, snippet

### 3.3 Domain Switcher (on Explore)

- [ ] DomainSwitcherEntryPanel renders with `surface="explore"`
- [ ] All four domain filter pills visible with correct colours
- [ ] Clicking a domain filter navigates or filters appropriately

### 3.4 Curated Collections

- [ ] Collections section renders with heading "Curated collections"
- [ ] Description reads "Cross-domain packs designed for specific rhythms and
      goals"
- [ ] 5 collection cards render: Daily Clarity Stack, Night Observer Pack,
      Weekly Reset Sequence, Mindful Morning Starter, Stargazer Wellness
- [ ] Each card shows title, description, and badge (Popular, Curated, New,
      Featured)
- [ ] Each card shows domain pills with correct accent colours
- [ ] Domain pills show correct labels (Tara, Veritas, Nyx, Arete)
- [ ] Collection cards have hover states
- [ ] Collection grid is responsive

### 3.5 Editorial Spotlights

- [ ] Spotlights section renders with heading "Editor picks"
- [ ] Description is present
- [ ] 4 spotlight cards render
- [ ] Each spotlight card shows domain name, title, subtitle, and read time
- [ ] Domain name is colored with the domain accent
- [ ] Clicking a spotlight card navigates to the domain route with
      `origin=explore`
- [ ] Spotlights include: "How the credibility loop works" (Veritas), "Evening
      recovery breathwork" (Tara), "Night observer checklist" (Nyx), "The
      science of streaks" (Arete)
- [ ] Hover state on spotlight cards works

### 3.6 Quick Actions (on Explore)

- [ ] Quick actions section renders with heading "Quick actions"
- [ ] QuickActionsTrayPanel renders with `surface="explore"`
- [ ] Action buttons are clickable

### 3.7 Back Navigation

- [ ] "Back to dashboard" link navigates to `/`

---

## Section 4 — Activity Page (`/activity`)

### 4.1 Page Layout & Navigation

- [ ] Navigate to `/activity` — page loads without errors
- [ ] Shell route navigator shows "Activity" as the active tab
- [ ] Hero section shows "Activity" eyebrow and "Your unified timeline" title
- [ ] Subtitle mentions Tara, Veritas, Nyx, and Arete

### 4.2 Activity KPI Metrics

- [ ] Four metric tiles are displayed: Unread, Priority, Streak, Domains
- [ ] Unread count matches the actual count of unread timeline items
- [ ] Priority count matches timeline items with `priority: 'high'`
- [ ] Streak shows "7d"
- [ ] Domains shows "4"

### 4.3 Weekly Progress Panel

- [ ] Panel shows "Weekly progress" heading
- [ ] Shows "5 of 7 actions complete this week"
- [ ] Progress bar renders at ~71% fill
- [ ] Completion percentage text shows "71% completion rate"

### 4.4 Milestones Panel

- [ ] Panel shows "Milestones" heading
- [ ] Three milestones are listed: 7-day streak, Read 25 articles, First sky
      observation
- [ ] 7-day streak shows 100% progress and "Completed!"
- [ ] Read 25 articles shows 68% and "17 of 25"
- [ ] First sky observation shows 0% and "Not started"
- [ ] Each milestone has a progress bar track with fill

### 4.5 Achievements Section

- [ ] Achievements panel renders with heading "Achievements"
- [ ] Description reads "Unlock achievements by using domains together"
- [ ] 4 achievement cards render
- [ ] "Cross-Domain Explorer" shows 75% progress, not unlocked, 4 domain pills
- [ ] "Mindful Reader" shows 100% progress and "Unlocked" badge
- [ ] "Night Owl" shows 40% progress, Nyx domain pill
- [ ] "Consistency Champion" shows 50% progress, Arete domain pill
- [ ] Unlocked achievements are visually distinct (class `unlocked`)
- [ ] Domain pills have correct accent colours
- [ ] Progress bars render for non-unlocked achievements

### 4.6 Timeline Section

- [ ] Timeline section renders with heading "Timeline"
- [ ] Entry count is shown (e.g., "8 entries")
- [ ] Timeline items are grouped by time buckets: "Just now", "Earlier today",
      "Yesterday", "This week", "Older"
- [ ] Each group has a label heading
- [ ] Each timeline card shows:
  - [ ] Domain name with accent color dot
  - [ ] Kind label (Reminder, Update, Event, Insight)
  - [ ] Priority badge for high-priority items
  - [ ] Relative timestamp (e.g., "2h ago", "yesterday")
  - [ ] Title and body text
  - [ ] Unread dot for unread items

### 4.7 Timeline Data Fetching

- [ ] On page load, timeline data fetches from BFF `GET /v1/activity`
- [ ] Auth header is sent with the fetch request
- [ ] Fetched data replaces static fallback timeline
- [ ] Pagination state (`hasMore`, `nextCursor`) is tracked
- [ ] If fetch fails, fallback static data remains visible (graceful
      degradation)
- [ ] Console error is logged on fetch failure

### 4.8 Load More Pagination

- [ ] "Load more" button renders when `hasMore` is true
- [ ] Clicking "Load more" fetches the next page from BFF with cursor parameter
- [ ] New items are appended to the existing timeline
- [ ] Button shows "Loading..." while fetching
- [ ] Button is disabled while loading
- [ ] Button disappears when `hasMore` becomes false
- [ ] Multiple sequential "Load more" clicks work correctly

### 4.9 Back Navigation

- [ ] "Back to dashboard" link navigates to `/`

---

## Section 5 — Profile Page (`/profile`)

### 5.1 Page Layout & Navigation

- [ ] Navigate to `/profile` — page loads without errors
- [ ] Shell route navigator shows "Profile" as the active tab
- [ ] ProfileSettingsPanel renders (full feature set as tested in Section 2.10)

### 5.2 Search Params Hydration

- [ ] Navigate to `/profile?path=settings/privacy` — shows "Hydrated path:
      /settings/privacy"
- [ ] Navigate to `/profile?intent=upgrade&domain=tara&requiredTier=pro` —
      upgrade intent is passed to ProfileSettingsPanel
- [ ] Upgrade prompt highlights the target domain and tier
- [ ] Without search params, no hydrated path section is shown

### 5.3 Profile Settings Full Feature Test

- [ ] All profile settings features from Section 2.10 work on the dedicated
      profile page
- [ ] Theme changes persist across page navigation
- [ ] Language changes update UI labels
- [ ] Privacy toggles save state

### 5.4 Back Navigation

- [ ] "Back to dashboard" link navigates to `/`

---

## Section 6 — Welcome / Marketing Landing (`/welcome`)

### 6.1 Page Layout

- [ ] Navigate to `/welcome` — page loads without errors
- [ ] Public marketing content is displayed (accessible to unauthenticated
      visitors)
- [ ] OSHUN branding is prominent

### 6.2 Platform Overview

- [ ] Hero section describes the OSHUN super-app concept
- [ ] All four domains are showcased with cards/sections
- [ ] Each domain card shows: name, tagline, accent colour, icon, capabilities
      (up to 4), CTA, availability status
- [ ] Domain information comes from `@oshun/domain-registry`

### 6.3 Features Section

- [ ] "Cross-domain context" feature card renders with description
- [ ] "Unified progress" feature card renders with description
- [ ] Additional feature cards render as defined

### 6.4 Testimonials

- [ ] At least 2 testimonial quotes are shown
- [ ] Each quote has an author attribution
- [ ] Testimonials include mentions of specific domain features

### 6.5 Call to Action

- [ ] Clear CTA buttons for download / sign up are present
- [ ] CTA links navigate correctly

### 6.6 Welcome Sub-Pages

- [ ] `/welcome/domains` loads and shows domain-specific detail content
- [ ] `/welcome/download` loads and shows download/install instructions
- [ ] Links between welcome sub-pages work correctly

---

## Section 7 — Domain Navigation & Routing

### 7.1 Domain Route via `/domains/[domainId]`

- [ ] `/domains/tara` loads and routes to the Tara domain experience
- [ ] `/domains/veritas` loads and routes to the Veritas domain experience
- [ ] `/domains/nyx` loads and routes to the Nyx domain experience
- [ ] `/domains/arete` loads and routes to the Arete domain experience
- [ ] Invalid domain ID (e.g., `/domains/foobar`) shows an error or 404 state

### 7.2 Back-Stack & Origin Parameters

- [ ] `/domains/tara?origin=home` — back navigation returns to home
- [ ] `/domains/tara?origin=explore` — back navigation returns to explore
- [ ] `/domains/tara?origin=activity` — back navigation returns to activity
- [ ] `/domains/tara?origin=profile` — back navigation returns to profile
- [ ] Default origin is "home" when no origin param is provided
- [ ] `/domains/tara?stack=veritas,nyx` — domain stack context is parsed
      correctly
- [ ] Cross-domain navigation chain works (Tara → Veritas → Nyx with stack
      tracking)

### 7.3 Canonical Routes

- [ ] `/d/tara` loads the Tara domain via canonical domain prefix
- [ ] `/d/veritas` loads the Veritas domain
- [ ] `/d/nyx` loads the Nyx domain
- [ ] `/d/arete` loads the Arete domain
- [ ] `/d/tara/meditations` loads Tara with path hydration
- [ ] `/app/home` loads the home shell route via canonical shell prefix
- [ ] `/app/explore` loads the explore shell route
- [ ] `/app/activity` loads the activity shell route
- [ ] `/app/profile` loads the profile shell route

### 7.4 Deep Link Handling

- [ ] Deep links with path segments are hydrated into domain surfaces
- [ ] URL query parameters are preserved through navigation
- [ ] Browser back/forward buttons work correctly with domain navigation
- [ ] Refreshing a domain page reloads the correct domain state

---

## Section 8 — Domain Route Experience Component

### 8.1 Entitlement & Access Check

- [ ] DomainRouteExperience component loads with correct domain ID
- [ ] Access check is performed via `evaluateDomainAccess`
- [ ] If user has access, domain surface renders
- [ ] If user lacks access, denied message from
      `formatDomainAccessDeniedMessage` shows
- [ ] Entitlement tier checking works (free vs. pro vs. premium)
- [ ] Upgrade prompt is shown for gated content with correct target tier

### 8.2 Domain Unavailable State

- [ ] When `?unavailable=true` is passed, graceful unavailable fallback renders
- [ ] Unavailable message includes a "reason" if `?reason=...` is passed
- [ ] Unavailable state includes a back-to-origin navigation link

### 8.3 Offline Fallback

- [ ] When `?offline=true` is passed, offline fallback card renders
- [ ] Offline fallback includes contextual messaging per domain

### 8.4 Domain Surface Router

- [ ] DomainSurfaceRouter correctly routes to TaraSurface for `tara`
- [ ] DomainSurfaceRouter correctly routes to VeritasSurface for `veritas`
- [ ] DomainSurfaceRouter correctly routes to NyxSurface for `nyx`
- [ ] DomainSurfaceRouter correctly routes to AreteSurface for `arete`
- [ ] Hydrated path is passed through to surface component

### 8.5 Domain Navigation Header

- [ ] Domain experience shows a close/back button
- [ ] Close button navigates back to the origin route
- [ ] Domain name and accent color are displayed in the header
- [ ] Domain-to-domain navigation links are available
- [ ] Domain sequence navigation (prev/next domain) works

---

## Section 9 — Tara Domain Surface

### 9.1 Tara Surface Layout

- [ ] TaraSurface renders when navigating to `/domains/tara`
- [ ] Tara accent colour (#2BC6B4) is applied
- [ ] Close/back button works correctly

### 9.2 Featured Session

- [ ] Featured session card renders with title "Morning clarity breath"
- [ ] Session shows description, duration (12 min), and instructor (Sage)
- [ ] Session category shows "Breathwork" and level shows "Beginner"
- [ ] Featured session card has a CTA to start the session

### 9.3 Daily Stats

- [ ] Four stats tiles render: Streak (7 days), Today (12 min), This week (84
      min), Sessions (42 total)
- [ ] Stats are styled consistently with the Tara accent

### 9.4 Session Library

- [ ] List of sessions renders (Sleep sanctuary, Deep focus flow, Gratitude
      reflection, etc.)
- [ ] Each session shows title, duration, category, and level
- [ ] Sessions are clickable

### 9.5 Courses Section

- [ ] Course cards render (7-day mindfulness foundations, Breathwork mastery)
- [ ] Each course shows title, session count, progress, and description
- [ ] Progress is shown visually (e.g., "3/7 sessions")

### 9.6 Quick Actions (Tara)

- [ ] Quick action buttons render: Meditate, Browse, Favorites
- [ ] Each action navigates to the correct path

### 9.7 Backend Data Fetch

- [ ] TaraSurface calls `fetchBackendData` on mount
- [ ] Data is fetched from Tara API endpoints
- [ ] Featured session data is updated from backend response
- [ ] Session library is populated with real data
- [ ] Courses are populated with real progress data
- [ ] Stats are updated from backend
- [ ] Loading state is shown while fetching
- [ ] Error state is handled gracefully if API fails

### 9.8 Breathwork Timer

- [ ] BreathworkTimer component renders when a breathwork session is started
- [ ] Timer displays countdown/countup
- [ ] Breath phase indicators work (inhale, hold, exhale)
- [ ] Timer can be paused and resumed
- [ ] Timer completion triggers session end flow

### 9.9 Session Player

- [ ] SessionPlayer component renders when a session is launched
- [ ] Audio playback controls are visible (play/pause, progress bar)
- [ ] Session progress is tracked
- [ ] Player shows session title and duration
- [ ] Closing the player returns to the session list

### 9.10 Favorites Sync

- [ ] Favoriting a session persists via API
- [ ] Favorites list shows saved sessions
- [ ] Unfavoriting removes from the list
- [ ] Favorites sync across page reloads

---

## Section 10 — Veritas Domain Surface

### 10.1 Veritas Surface Layout

- [ ] VeritasSurface renders when navigating to `/domains/veritas`
- [ ] Veritas accent colour (#27A3F3) is applied
- [ ] Close/back button works correctly

### 10.2 Trending Claims

- [ ] Trending claims list renders with initial claims
- [ ] Claim: "Global renewable energy capacity surpassed fossil fuels for the
      first time"
- [ ] Claim: "Economic growth forecasts revised upward across emerging markets"
- [ ] Each claim shows: headline, source, confidence score, category, time ago
- [ ] Confidence score has colour coding (green for high, yellow for moderate,
      red for low)
- [ ] Confidence text label shows (Verified, Likely, Unverified, etc.)

### 10.3 Reading Queue

- [ ] Reading queue section shows saved articles
- [ ] Each item shows title, read time, and saved status
- [ ] Clicking a queue item opens it (or navigates to detail)
- [ ] Queue items include: "Deep dive: AI regulation frameworks compared" (8
      min), "Investigation: Water infrastructure spending gaps" (12 min)

### 10.4 Quick Actions (Veritas)

- [ ] Quick action buttons render: Trending now, Reading queue, Source
      directory, Topic alerts
- [ ] Each action navigates to the correct path or opens the correct overlay

### 10.5 Backend Data Fetch

- [ ] VeritasSurface calls `fetchBackendData` on mount
- [ ] Trending claims are populated from Veritas API
- [ ] Reading queue is populated from API
- [ ] Loading state is shown
- [ ] Error state is handled gracefully

### 10.6 Article Reader Overlay

- [ ] Clicking a claim or article opens the ArticleReaderOverlay
- [ ] Article reader shows full article content
- [ ] Source attribution and confidence indicators are displayed
- [ ] Reader overlay can be closed
- [ ] Reader handles long-form content with scrolling

### 10.7 Reading Queue Overlay

- [ ] ReadingQueueOverlay opens from quick actions or nav
- [ ] Full queue list is shown with all saved articles
- [ ] Articles can be removed from queue
- [ ] Overlay can be closed

### 10.8 Source Directory Overlay

- [ ] SourceDirectoryOverlay opens from quick actions
- [ ] List of trusted/rated sources is shown
- [ ] Sources have credibility ratings
- [ ] Overlay can be closed

### 10.9 Follow/Alert Preferences

- [ ] Topic follow/unfollow works
- [ ] Alert preferences for followed topics can be set
- [ ] Follow state persists across page reloads

---

## Section 11 — Nyx Domain Surface

### 11.1 Nyx Surface Layout

- [ ] NyxSurface renders when navigating to `/domains/nyx`
- [ ] Nyx accent colour (#7D7CFF) is applied
- [ ] Close/back button works correctly

### 11.2 Tonight's Sky Highlights

- [ ] Tonight's highlights section renders
- [ ] "Jupiter at opposition" highlight shows with description, visibility
      (Excellent), time window, type
- [ ] "ISS pass visible" highlight shows with details
- [ ] Visibility labels have colour coding (Excellent, Good, Fair)
- [ ] Time windows are shown for each event

### 11.3 Upcoming Events

- [ ] Upcoming events section renders
- [ ] Events include: Quadrantid meteor shower peak, Venus greatest elongation,
      etc.
- [ ] Each event shows title, date, type, and importance (Major, Notable, Minor)
- [ ] Importance has visual styling differences

### 11.4 Observation Conditions

- [ ] Current observation conditions panel renders
- [ ] Shows: cloud cover, transparency, seeing rating
- [ ] Visual indicators for each condition metric

### 11.5 Quick Actions (Nyx)

- [ ] Quick action buttons: Tonight's sky, Sky map, Event calendar, Observation
      log
- [ ] Each action navigates to the correct path or opens overlay

### 11.6 Backend Data Fetch

- [ ] NyxSurface calls `fetchNyxData` on mount
- [ ] Tonight's highlights populated from Nyx API
- [ ] Upcoming events populated from API
- [ ] Conditions populated from API
- [ ] Loading and error states handled

### 11.7 Nightly Highlights Overlay

- [ ] NightlyHighlightsOverlay opens from quick action
- [ ] Full list of tonight's celestial events is shown
- [ ] Each event has detailed information
- [ ] Overlay can be closed

### 11.8 Sky Map Overlay

- [ ] SkyMapOverlay opens from quick action
- [ ] Star map or sky visualization renders
- [ ] Map is interactive or shows relevant sky objects
- [ ] Overlay can be closed

### 11.9 Event Calendar Overlay

- [ ] EventCalendarOverlay opens from quick action
- [ ] Calendar view shows upcoming astronomical events
- [ ] Events are clickable for detail
- [ ] Overlay can be closed

### 11.10 Night Mode Treatment

- [ ] Nyx surface has legibility-safe night mode colours
- [ ] Contrast is sufficient for dark backgrounds
- [ ] No brightness-jarring elements

### 11.11 Observation Logging

- [ ] Observation log can be accessed
- [ ] User can log an observation (date, sky objects, notes)
- [ ] Logged observations persist

---

## Section 12 — Arete Domain Surface

### 12.1 Arete Surface Layout

- [ ] AreteSurface renders when navigating to `/domains/arete`
- [ ] Arete accent colour (#3AC77B) is applied
- [ ] Close/back button works correctly

### 12.2 Daily Check-In

- [ ] Check-in prompts are displayed (4 prompts)
- [ ] Prompts include: "How are you feeling right now?", "What is your top
      priority for today?", "Name one thing you are grateful for.", "What habit
      did you honor this morning?"
- [ ] Check-in can be completed within the surface

### 12.3 Active Goals

- [ ] Active goals section renders
- [ ] Goals show title, horizon (short/mid/long), progress percentage, and
      status
- [ ] Goal progress bars are rendered visually
- [ ] Goals include items like short-horizon, mid-horizon, and long-horizon
      goals

### 12.4 Habits Tracker

- [ ] Habits list renders
- [ ] Each habit shows: name, today's done status, current streak, best streak
- [ ] Habits include: Morning meditation, Read 30 minutes, Gratitude practice,
      No screen after 10 PM
- [ ] Toggle habit completion works (clicking marks as done/undone)
- [ ] Habit streak counts update correctly
- [ ] Habits state persists

### 12.5 Journal Section

- [ ] Recent journal entries section renders
- [ ] Each entry shows date, excerpt, and mood
- [ ] Journal entries include entries with different moods (Focused, Reflective,
      etc.)

### 12.6 Weekly Summary

- [ ] Weekly summary stats render
- [ ] Shows: check-ins completed, habits tracked, journal entries, average mood

### 12.7 Coach Insights

- [ ] AI coach insights section renders
- [ ] Three insight messages are displayed
- [ ] Insights reference user's actual patterns

### 12.8 Quick Actions (Arete)

- [ ] Quick action buttons: Daily check-in, Dashboard, Goals, Journal
- [ ] Each action navigates correctly or opens overlay

### 12.9 Backend Data Fetch

- [ ] AreteSurface calls `fetchAreteData` on mount
- [ ] Goals populated from Arete API
- [ ] Habits populated from API
- [ ] Journal entries populated from API
- [ ] Weekly summary populated from API
- [ ] Loading and error states handled

### 12.10 Daily Check-In Overlay

- [ ] DailyCheckInOverlay opens from quick action
- [ ] Full check-in flow with all prompts
- [ ] Submitting check-in posts to API
- [ ] Confirmation shown on completion
- [ ] Overlay can be closed

### 12.11 Journal Overlay

- [ ] JournalOverlay opens from quick action
- [ ] Full journal view with past entries
- [ ] New journal entry can be created
- [ ] Entry text, mood tag, and timestamp are submitted
- [ ] Overlay can be closed

### 12.12 Goals Overlay

- [ ] GoalsOverlay opens from quick action
- [ ] Full goals management view
- [ ] Goals can be created, updated, and marked as complete
- [ ] Goal horizons (short/mid/long) are selectable
- [ ] Overlay can be closed

### 12.13 Wheel-of-Life / Balance Check-In

- [ ] Balance check-in surface is accessible
- [ ] Multi-dimensional self-assessment works
- [ ] Results are displayed visually

---

## Section 13 — Shell Navigation (`ShellRouteNavigator`)

### 13.1 Tab Bar

- [ ] Tab bar renders at the top or bottom of every shell page
- [ ] Four tabs are present: Home, Explore, Activity, Profile
- [ ] Active tab is visually highlighted
- [ ] Clicking each tab navigates to the correct route
- [ ] Tab bar persists across all shell routes

### 13.2 Active State

- [ ] On `/`, Home is active
- [ ] On `/explore`, Explore is active
- [ ] On `/activity`, Activity is active
- [ ] On `/profile`, Profile is active

### 13.3 Keyboard Navigation

- [ ] Tab key moves focus between tabs
- [ ] Enter/Space keypress activates a tab
- [ ] Focus ring is visible on keyboard navigation

---

## Section 14 — BFF API Integration Tests (via Frontend)

### 14.1 Home API (`GET /v1/home`)

- [ ] Home page triggers fetch to `/v1/home`
- [ ] Response includes personalized greeting data
- [ ] Response includes domain cards data
- [ ] Response includes daily plan data
- [ ] Response includes activity preview
- [ ] Response is correctly rendered in the UI

### 14.2 Continue API (`GET /v1/continue`)

- [ ] Continue/resume items are fetched
- [ ] Resumable items from each domain are shown
- [ ] Each item has enough context to resume (title, progress, domain)

### 14.3 Domains API (`GET /v1/domains`)

- [ ] Domains endpoint returns metadata for all four domains
- [ ] Each domain includes: availability status, metadata, accent colour
- [ ] Unavailable domains show appropriate fallback in UI

### 14.4 Activity API (`GET /v1/activity`)

- [ ] Activity timeline fetches correctly
- [ ] Pagination with cursor works
- [ ] Domain filter parameter works
- [ ] Timeline items have correct structure (id, domain, kind, title, detail,
      occurredAt)

### 14.5 Search API (`GET /v1/search`)

- [ ] Search with query returns results
- [ ] Results are blended across domains
- [ ] Ranking strategy prioritizes relevant results
- [ ] Empty query returns no results or suggestions
- [ ] Query with no matches returns empty state

### 14.6 Search Suggestions API

- [ ] Search suggestions endpoint returns suggestions for partial queries
- [ ] Recent searches are returned
- [ ] Suggestions include domain context

### 14.7 Notifications API (`GET /v1/notifications`)

- [ ] Notifications fetch returns items grouped/sortable
- [ ] Each notification has: id, domain, kind, priority, title, body, timestamp,
      read status
- [ ] Unread count matches UI display

### 14.8 Notification Preferences API

- [ ] GET notification preferences returns per-domain settings
- [ ] PUT notification preferences saves changes
- [ ] Quiet hours configuration works
- [ ] Digest scheduling configuration works

### 14.9 Notification Write API

- [ ] Mark-read endpoint (`POST /v1/notifications/read`) works
- [ ] Bulk mark-read works
- [ ] Marking as read updates the UI

### 14.10 Favorites API

- [ ] GET favorites returns saved items across domains
- [ ] POST favorite saves a new item
- [ ] DELETE favorite removes an item
- [ ] Favorites sync across page reloads

### 14.11 Recommendations API (`GET /v1/recommendations`)

- [ ] Recommendations endpoint returns cross-domain suggestions
- [ ] Each recommendation has explanation labels
- [ ] Recommendations carousel renders on home page
- [ ] Feedback controls (hide, less like this, more like this) work

### 14.12 Entitlements API (`GET /v1/entitlements`)

- [ ] Entitlements check returns current tier
- [ ] Domain access levels are correct for the tier
- [ ] Upgrade paths are shown for gated features

### 14.13 Device Tokens API

- [ ] Device token registration works for push notifications
- [ ] Token is sent with correct metadata

### 14.14 Session Audio API

- [ ] Session audio endpoint returns audio URLs for Tara sessions
- [ ] Audio URLs are playable in the browser

### 14.15 Routines API

- [ ] GET routines returns morning/evening routine configurations
- [ ] Routines span multiple domains (e.g., Tara + Arete)
- [ ] Routine progress is tracked

### 14.16 Achievements API

- [ ] GET achievements returns cross-domain achievements
- [ ] Achievement progress percentages are correct
- [ ] Unlocked achievements are distinguished

### 14.17 Wearable API

- [ ] Wearable endpoint returns streak/reminder/summary data
- [ ] Data is formatted for wearable companion display

### 14.18 Assistant API

- [ ] AI assistant endpoint accepts queries
- [ ] Responses are contextual to user's domains and activity
- [ ] Response cards render in the UI

### 14.19 Desktop API

- [ ] Desktop-specific endpoints work
- [ ] Desktop surface data is served correctly

---

## Section 15 — Tara API End-to-End (Frontend → BFF → Tara API → DB)

### 15.1 Authentication Routes

- [ ] Tara auth endpoints respond correctly through BFF
- [ ] Auth token is validated
- [ ] User identity is resolved

### 15.2 Meditations

- [ ] `GET /meditations` returns meditation list
- [ ] Meditations have title, description, duration, category, level
- [ ] Meditation detail endpoint returns full metadata
- [ ] Meditation audio/resource URLs are accessible

### 15.3 Sessions

- [ ] `GET /sessions` returns session history for the user
- [ ] `POST /sessions` creates a new session record
- [ ] Session completion updates progress
- [ ] Session duration is tracked

### 15.4 Courses

- [ ] `GET /courses` returns course list with progress
- [ ] Course detail shows individual lesson/session list
- [ ] Course progress (e.g., 3/7 sessions) is accurate
- [ ] Completing a session updates course progress

### 15.5 Collections

- [ ] `GET /collections` returns curated meditation collections
- [ ] Collections have title, description, and meditation list
- [ ] Collection items are renderable in the UI

### 15.6 Favorites

- [ ] `GET /favorites` returns user's favorite meditations
- [ ] `POST /favorites` adds a meditation to favorites
- [ ] `DELETE /favorites/:id` removes from favorites
- [ ] Favorites changes reflect immediately in UI

### 15.7 Downloads

- [ ] `GET /downloads` returns list of downloaded content
- [ ] Download initiation works
- [ ] Download progress/status is tracked

### 15.8 Achievements

- [ ] `GET /achievements` returns Tara-specific achievements
- [ ] Achievement progress is calculated from usage data

### 15.9 History

- [ ] `GET /history` returns chronological session history
- [ ] History includes session metadata (duration, date, meditation title)
- [ ] History pagination works

### 15.10 Progress

- [ ] `GET /progress` returns user's streaks, total time, session count
- [ ] Progress data matches what the UI displays

### 15.11 Search (Tara)

- [ ] `GET /search?q=breath` returns matching meditations
- [ ] Search results include title, category, instructor
- [ ] Empty search returns no results

### 15.12 Subscription

- [ ] Subscription status is retrievable
- [ ] Free vs. Pro vs. Premium access levels are enforced
- [ ] Upgrade flow is accessible

### 15.13 Teachers

- [ ] `GET /teachers` returns teacher/instructor profiles
- [ ] Each teacher has name, bio, and meditation count
- [ ] Teacher detail shows their meditation library

### 15.14 Users

- [ ] `GET /users/me` returns current user profile
- [ ] User profile includes preferences and settings
- [ ] Profile update endpoint works

### 15.15 Notifications (Tara)

- [ ] Tara-specific notifications are retrievable
- [ ] Notification preferences for Tara domain work

### 15.16 Analytics

- [ ] Analytics events are trackable
- [ ] Session completion events fire correctly
- [ ] Event payloads include required fields

---

## Section 16 — Cross-Domain Features

### 16.1 Universal Search E2E

- [ ] Search from home page returns results across all four domains
- [ ] Results show correct domain badges
- [ ] Clicking a result navigates to the correct domain surface
- [ ] Search from explore page works identically
- [ ] Keyboard shortcut to focus search works (if implemented)
- [ ] Search with filters applied returns filtered results
- [ ] Search handles special characters gracefully
- [ ] Search handles very long queries gracefully
- [ ] Zero-result state shows helpful messaging

### 16.2 Unified Bookmarks / Save

- [ ] Save a Tara session from the Tara surface
- [ ] Save a Veritas article from the Veritas surface
- [ ] Save a Nyx event from the Nyx surface
- [ ] Save an Arete goal from the Arete surface
- [ ] Navigate to the unified library (saved items)
- [ ] All saved items appear regardless of domain
- [ ] Unsave an item removes it from the library
- [ ] Saves persist across page reloads
- [ ] Saves sync across browser tabs (if applicable)

### 16.3 Cross-Domain Recommendations

- [ ] Recommendation carousel renders on home page
- [ ] Recommendations span multiple domains
- [ ] Each recommendation shows an explanation label ("Suggested because...")
- [ ] "Hide" control works and removes the recommendation
- [ ] "Less like this" control updates preferences
- [ ] "More like this" control updates preferences
- [ ] Recommendations refresh after preference changes

### 16.4 Cross-Domain Streaks

- [ ] Streak counter reflects activity across all domains
- [ ] Consecutive-day tracking works
- [ ] Streak milestone notifications trigger
- [ ] Streak reset works correctly when a day is missed

### 16.5 Morning/Evening Routines

- [ ] Morning routine spanning Tara + Arete is accessible
- [ ] Routine steps can be followed in sequence
- [ ] Routine completion updates progress
- [ ] Evening routine works similarly

### 16.6 Cross-Domain Achievements

- [ ] "Cross-Domain Explorer" achievement tracks 4-domain usage
- [ ] "Mindful Reader" achievement tracks Veritas + Tara combo
- [ ] Progress increments correctly with qualifying actions
- [ ] Achievement unlock notification appears at 100%

---

## Section 17 — PWA & Installation

### 17.1 Web App Manifest

- [ ] `/manifest.json` (or linked manifest) is accessible
- [ ] Manifest includes: name, short_name, description, start_url, display,
      theme_color, background_color
- [ ] Icons are defined in correct sizes
- [ ] Manifest validates without errors

### 17.2 Service Worker

- [ ] Service worker registers successfully
- [ ] Core offline routes are cached
- [ ] Static assets are cached
- [ ] Service worker update is handled (user prompted or auto-updated)
- [ ] `PwaBootstrap` component initializes SW correctly

### 17.3 Install Prompt

- [ ] PwaInstallPrompt component renders (in supporting browsers)
- [ ] Install button triggers browser install dialog
- [ ] Post-install guidance is shown
- [ ] Dismiss button hides the prompt

### 17.4 Smart App Banner

- [ ] SmartAppBanner component renders
- [ ] Banner shows app download link with correct store links
- [ ] Banner is dismissible
- [ ] Banner includes deep link to current content

### 17.5 Offline Behavior

- [ ] Disconnecting network shows global offline banner
- [ ] Cached pages remain accessible offline
- [ ] Uncached pages show offline fallback
- [ ] Reconnecting network hides offline banner
- [ ] Queued actions send once online

### 17.6 Runtime Caching

- [ ] BFF API responses are cached by service worker
- [ ] Cached API data is served when offline
- [ ] Stale-while-revalidate pattern works for appropriate endpoints

---

## Section 18 — Responsive Design & Accessibility

### 18.1 Responsive Layout (320px Mobile)

- [ ] Home page renders without horizontal overflow at 320px viewport
- [ ] Navigation tabs are usable at 320px
- [ ] Domain cards stack vertically
- [ ] KPI grid adapts to narrow width
- [ ] Text is readable without zooming
- [ ] Touch targets are minimum 44x44px

### 18.2 Responsive Layout (768px Tablet)

- [ ] Layout adapts to 2-column where appropriate
- [ ] Domain cards use a 2-column grid
- [ ] Panels have appropriate padding

### 18.3 Responsive Layout (1440px Desktop)

- [ ] Full-width layout is utilized
- [ ] Domain cards use a 4-column grid
- [ ] Split grid panels render side by side
- [ ] Maximum content width constraint is applied

### 18.4 Responsive Layout (>1920px Ultrawide)

- [ ] Content doesn't stretch beyond readable width
- [ ] Layout remains centered or constrained

### 18.5 Accessibility — Semantic HTML

- [ ] All pages use `<main>` element
- [ ] Headings follow proper hierarchy (single `<h1>`, then `<h2>`, `<h3>` etc.)
- [ ] Interactive elements use `<button>`, `<a>`, `<input>` appropriately
- [ ] Lists use `<ul>` or `<ol>` with `<li>` items
- [ ] Tables use `<table>`, `<thead>`, `<tbody>`, `<tr>`, `<td>`, `<th>` if
      present
- [ ] `aria-label` attributes on sections without visible headings

### 18.6 Accessibility — Keyboard Navigation

- [ ] All interactive elements are focusable via Tab key
- [ ] Focus order follows visual reading order
- [ ] Focus ring is visible on all focused elements
- [ ] Skip-to-main-content link is present
- [ ] Modal/overlay traps focus within itself
- [ ] Escape key closes overlays
- [ ] Enter/Space activates buttons and links

### 18.7 Accessibility — Screen Reader

- [ ] All images have alt text
- [ ] All icons have aria-label or sr-only text
- [ ] Dynamic content updates are announced (live regions)
- [ ] Form inputs have associated labels
- [ ] Error messages are associated with their inputs

### 18.8 Accessibility — Visual

- [ ] Text contrast meets WCAG AA (4.5:1 for normal text, 3:1 for large text)
- [ ] Colour is not the only means of conveying information
- [ ] UI is usable with 200% browser zoom
- [ ] Reduced-motion preference is respected (`prefers-reduced-motion`)
- [ ] High contrast mode works when toggled

---

## Section 19 — Error States & Edge Cases

### 19.1 Network Error Handling

- [ ] BFF unreachable — home page shows fallback data or error state
- [ ] Tara API unreachable — Tara surface shows error state
- [ ] Veritas API unreachable — Veritas surface shows error state
- [ ] Nyx API unreachable — Nyx surface shows error state
- [ ] Arete API unreachable — Arete surface shows error state
- [ ] Partial domain outage — available domains still work
- [ ] Slow network — loading spinners/skeletons are shown

### 19.2 Invalid Data Handling

- [ ] Malformed API response — UI doesn't crash
- [ ] Missing required fields — graceful fallbacks
- [ ] Empty arrays — empty state messages shown
- [ ] Null values — no uncaught type errors

### 19.3 Auth Edge Cases

- [ ] Expired token — redirects to auth or shows re-auth prompt
- [ ] Revoked session — handles 401 gracefully
- [ ] No token — public pages still work, private pages redirect

### 19.4 Navigation Edge Cases

- [ ] Double-click prevention on navigation (no duplicate pushes)
- [ ] Rapid switching between domains doesn't cause state contamination
- [ ] Browser history length doesn't grow unbounded with domain switching
- [ ] Page refresh preserves current route and state

### 19.5 Data Consistency

- [ ] Completing a Tara session on the Tara surface updates the home dashboard
      metrics
- [ ] Saving a Veritas article updates the favorites count
- [ ] Achievement progress updates propagate to the activity page
- [ ] Notification read state syncs between notification center and activity
      timeline

---

## Section 20 — Performance & Quality

### 20.1 Page Load Performance

- [ ] Home page first contentful paint (FCP) < 2.5s
- [ ] Home page largest contentful paint (LCP) < 4s
- [ ] Home page cumulative layout shift (CLS) < 0.1
- [ ] Home page interaction to next paint (INP) < 200ms
- [ ] Explore page loads within acceptable thresholds
- [ ] Activity page loads within acceptable thresholds
- [ ] Profile page loads within acceptable thresholds
- [ ] Each domain surface loads within acceptable thresholds

### 20.2 Bundle Size

- [ ] JavaScript bundle for initial page load is reasonable (< 500KB gzipped)
- [ ] Code splitting works (domain surfaces are lazily loaded)
- [ ] No duplicate library inclusions in bundles

### 20.3 Lighthouse Audit

- [ ] Run Lighthouse on `/` — Performance score ≥ 80
- [ ] Run Lighthouse on `/` — Accessibility score ≥ 90
- [ ] Run Lighthouse on `/` — Best Practices score ≥ 90
- [ ] Run Lighthouse on `/` — SEO score ≥ 90
- [ ] Run Lighthouse on `/` — PWA installability checks pass
- [ ] Run Lighthouse on `/explore` — all scores within budget
- [ ] Run Lighthouse on `/activity` — all scores within budget
- [ ] Run Lighthouse on `/welcome` — all scores within budget

### 20.4 Console Cleanliness

- [ ] No console errors on any page during normal usage
- [ ] No console warnings related to React (key warnings, deprecated APIs)
- [ ] No unhandled promise rejections
- [ ] No 404 resource requests (images, fonts, scripts)

### 20.5 Animation & Scroll Performance

- [ ] Page transitions are smooth (no jank)
- [ ] Scrolling on activity timeline is smooth
- [ ] Overlay open/close animations run at 60fps
- [ ] Domain card hover animations are smooth
- [ ] Progress bar animations are smooth

---

## Summary

| Section   | Feature Area                 | Test Count |
| --------- | ---------------------------- | ---------- |
| 1         | Infrastructure & Environment | 17         |
| 2         | Home Dashboard               | 75         |
| 3         | Explore Page                 | 32         |
| 4         | Activity Page                | 44         |
| 5         | Profile Page                 | 12         |
| 6         | Welcome/Marketing            | 18         |
| 7         | Domain Navigation & Routing  | 22         |
| 8         | Domain Route Experience      | 17         |
| 9         | Tara Domain Surface          | 35         |
| 10        | Veritas Domain Surface       | 28         |
| 11        | Nyx Domain Surface           | 32         |
| 12        | Arete Domain Surface         | 42         |
| 13        | Shell Navigation             | 11         |
| 14        | BFF API Integration          | 50         |
| 15        | Tara API E2E                 | 40         |
| 16        | Cross-Domain Features        | 28         |
| 17        | PWA & Installation           | 19         |
| 18        | Responsive & Accessibility   | 32         |
| 19        | Error States & Edge Cases    | 19         |
| 20        | Performance & Quality        | 22         |
| **Total** |                              | **~575**   |

> **Procedure**: Work through each section sequentially. For each `[ ]` task,
> test in the browser against real dev infrastructure. If a test fails,
> investigate, fix the root cause (frontend, BFF, or domain API), re-verify, and
> mark with `[x]` before proceeding. All issues are resolved in place — no test
> is skipped.
