Map¶
frontend/src/features/Map/ — the stage map: the ten-stage arc rendered
over artwork, per-stage detail (expressions, history), the
wheel-of-wholeness balance overlay, and the declinable "begin again"
end-of-cycle affordance.
Screen¶
MapScreen (Map tab) renders a responsive row grid (one flex row
[LeftCell | CenterCell | RightCell] per stage as the single source of
vertical truth), the WaveOverlay, a MagnifierLens, a MapDrawer, a
journey-summary narrative, and a Celebration (MapScreen.tsx:1-100).
Layout metrics and label fitting live in mapLayout.ts; geometry in
waveGeometry.ts / magnifierGeometry.ts.
Service layer¶
services/stageService.ts "orchestrates API calls for stages and writes the
result into useStageStore", keeping API access out of the pure store
(stageService.ts:1-8). Key logic, verbatim where load-bearing:
clampProgresspins backend progress into[0, 1], coercing NaN/Infinity/missing to 0 — "without this guard a bad payload renders as 'NaN%' or overflows the progress bar (width: 110%)" (BUG-FE-MAP-003,stageService.ts:18-28,38-41).toStageDatamaps the wireStageontoStageData, resolving the color fromSTAGE_ORDER/STAGE_COLORS(stageService.ts:31-54).- Unlock semantics unify server flag and calendar:
export const isStageUnlocked = (
stage: Pick<StageData, 'isUnlocked' | 'stageNumber'>,
currentStage: number | null,
): boolean => stage.isUnlocked || (currentStage !== null && stage.stageNumber <= currentStage);
"so the padlock matches the Practice/Course stage"
(stageService.ts:56-60).
highestCompletedStageis the baseline the completion celebration watches;isEndOfCyclegates the declinable "begin again" affordance (stageService.ts:62-70).
Hooks¶
| Hook | Responsibility |
|---|---|
useStageAnchors |
measured row anchors for the lens/overlay |
useWheelBalance |
loads wheel.get (/stages/wheel) fullness per Aspect; wheelBalance.ts holds the math; absent stages read thin (MapScreen.tsx:91-93) |
useJourneySummary |
stage history → narrative (journeyNarrative.ts: progressionSentence, rankedStats, unlockTimeline) |
useBeginAgainGuard |
confirms before stages.beginAgain opens a fresh cycle (beginAgain.ts copy) |
Stores and API¶
Stores: useStageStore (six selectors incl. selectCycleNumber,
MapScreen.tsx:25-33), useDaysUntilStage / useDerivedCurrentStage
(calendar unlocks), useDepthPreferencesStore. API: stages
(listAll, history, beginAgain, programCalendar) and wheel.
Per-stage expression detail renders manifestations via
StageExpressionsSection (MapScreen.tsx:73).
Grounded in adepthood@55eef11, 2026-07-31.