Skip to content

Wireframe — Tree viewer (Plenny starter cluster)

Wireframe — Tree viewer (Plenny starter cluster)

Data source: GET /tree/state

Phase 9 scope: cluster.first-steps only — 20 nodes, mastery pace-and-pacing, keystone unshaken-step. The full tree (150-200 nodes, 6 regions) is a phase 11+ expansion.

Mock-mode constraints (ADR-0006):

  • All allocations.nodes[].provisional values are false — allocations are confirmed immediately.
  • No provisional pending banner.
  • No quarantine toast.
  • POST /tree/allocate endpoint exists (see open follow-up in tree-state contract); allocations go there on tap confirm.

Node map — cluster.first-steps

Positions are drawn from node.position.{x, y} values in data/src/content/nodes/*.ts. The coordinate system is a 5-column × 5-row logical grid scaled to screen width.

Grid key: x in {-2, -1, 0, 1, 2}, y in {0 ... 4}. y=0 is the entry point at bottom; y=4 is the top (notables + mastery + keystone area).

Node positions (coarse grid, each cell ≈ logical unit):
y=4 [KEYSTONE] [MASTERY]
unshaken-step pace-and-pacing
y=3 [cartographers [guild-pace] [steady-hands]
-eye]
(notable) (notable) (notable)
y=2 [compass- [long-step] [iron-heel]
habit] [margin-note]
y=1.5 [inked-boots] [measured-pace] [margin-note]
y=1 [surveyor's- [deep-breath] [steady-grip]
squint]
y=0 [even-stride]
(entry node)

The three branches fan out from even-stride (y=0, x=0):

  • Left branch (x=-2): cartography track — surveyors-squint → inked-boots → compass-habit → cartographers-eye
  • Centre branch (x=0): step/energy track — deep-breath → measured-pace → long-step → guild-pace
  • Right branch (x=2): guild/quest track — steady-grip → margin-note + iron-heel → steady-hands

mastery-node-pace-and-pacing sits between all three notables (logical position x=0, y=4 or alongside). keystone.unshaken-step sits at x=-2 or x=-3, y=4+, periphery.


Full screen layout

┌─────────────────────────────────────────────┐
│ ← Tree [7 pts ●] │ header: back + available points
├─────────────────────────────────────────────┤
│ Plenny — First Steps / Pierwsze Kroki │ cluster label
│ ─────────────────────────────────────── │
│ │
│ ┌─────────────────────────────────────┐ │ tree canvas
│ │ │ │ (zoomable/pannable, phase 11
│ │ [KEYSTONE ⛓] [MASTERY ◆] │ │ adds full pan+zoom; phase 9
│ │ │ │ is static layout for starter
│ │ [notable] [notable] [notable] │ │ cluster only)
│ │ │ │
│ │ [sm] [sm] [sm] [sm] │ │
│ │ │ │
│ │ [sm] [sm] [sm] │ │
│ │ │ │
│ │ [sm] [sm] [sm] │ │
│ │ │ │
│ │ [ENTRY sm] │ │
│ │ │ │
│ └─────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────┐ │ path preview strip
│ │ Tap a node to see effects │ │ (shows on hover/tap in preview mode)
│ └─────────────────────────────────────┘ │
│ │
├─────────────────────────────────────────────┤
│ ┌────┬────┬────┬────┐ │ bottom tab bar
│ │ 🏠 │[🌳]│ 📜 │ 🔒 │ │ Tree tab active
│ └────┴────┴────┴────┘ │
└─────────────────────────────────────────────┘

Available points counter

Persistent in header, right-aligned: 7 pts ● (example). Color: --color-warning when 0 points available, --color-success when ≥1. A11y: aria-label “7 points available”.


Node visual states

Small node (sm) — 5 states

[○] Unallocated, reachable (white border, dim fill)
[●] Allocated (region accent fill: --color-region-plenny, bright border)
[◐] Reachable but no points available (white border, amber pulse)
[⊘] Locked — prerequisite not met (grey, lock icon overlay at small scale)
[→] Path preview — would be allocated if confirm pressed (accent border, dashed)

Visual sizes:

  • Small node: 24dp circle (visual), 48dp tap target
  • Notable node: 36dp diamond/hexagon (visual), 56dp tap target
  • Mastery node: 40dp double-ring circle (visual), 56dp tap target
  • Keystone: 40dp with distinctive shape (e.g. star-of-points), 56dp tap target

Node detail (expanded view on screen)

Allocated small node:
╔═══════════════════════╗
║ ● Even Stride ║
║ Równy Krok ║
║ +5% step efficiency ║
║ Cost: 1pt · ALLOCATED║
╚═══════════════════════╝
Unallocated notable (reachable):
╔═══════════════════════╗
║ ◈ Cartographer's Eye║
║ Oko Kartografa ║
║ +25% cart. yield ║
║ +10% discovery radius║
║ Cost: 1pt · ALLOCATE ║
╚═══════════════════════╝

Detailed cluster layout (ASCII tree)

Nodes connected by lines representing the requires edges.

⊗UNSHAKEN ◆MASTERY
⊗STEP ◆P&P
│ │
╔════════╪══════╗ ╔════╪══════════╗
│ │ │ │
[◈carto- [●guild- [◈steady-
graphers- pace] hands]
eye] (notable) (notable)
(notable) │ │
│ ┌───┴───┐ ┌────┴────┐
[○compass- [○long- [○measured [○margin- [○iron-
habit] step] -pace] note] heel]
│ │ │ │ │
[○inked- [●deep- [○steady-
boots] breath] grip]
│ │ │
[●surveyor's- ─────────────────────── ─
squint]
\ /
└────────── ──────────────── ┘
[●even-stride]
(entry node — no prereqs)

Legend: = allocated, = unallocated reachable, = unallocated notable, = mastery, = locked keystone


Node type visual spec

TypeShapeBorderFillLabel position
Small (allocated)Circle2dp --color-region-plenny--color-region-plenny at 80%Below (caption)
Small (unallocated, reachable)Circle2dp --color-on-surface-muted--color-surface-variantBelow
Small (locked)Circle2dp --color-disabled--color-surfaceBelow
NotableDiamond / hexagon3dp --color-region-plennySee stateBelow
MasteryDouble ring3dp goldSpecialBelow
Keystone (locked)Star shape3dp --color-disabled--color-surface with lock glyphBelow + lock overlay
Keystone (unlocked, unallocated)Star shape3dp --color-warning pulse--color-surface-elevatedBelow
Keystone (allocated)Star shape3dp --color-region-plennyFull accent fillBelow

Edge lines between nodes: 1dp --color-border when path unallocated, 2dp --color-region-plenny when path allocated.


Notable node visual distinction

Three notables (cartographers-eye, guild-pace, steady-hands) are visually distinct from small nodes:

  • 50% larger visual diameter / taller diamond shape.
  • Gold inner-dot or inner diamond at center when allocated.
  • Hover / focused state shows abbreviated modifier preview inline (e.g. “+25% cart yield”).
  • On long-press (or secondary tap): full popover with PL and EN name, full modifier list.

Mastery node — 3-pick popover

The mastery node pace-and-pacing fires a popover when tapped (only allocatable once all three branches reach their respective notables — this gating is backend-computed). In phase 9 mock mode, the popover appears when the player taps the mastery node regardless of prerequisite state, but the “Confirm” button is disabled if prerequisites are not met.

┌─────────────────────────────────────────────────┐
│ [icon.mastery-pick] Pace and Pacing │
│ Krok i Tempo │
│ │
│ Choose one effect: │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ ○ Cartographer's Pace │ │
│ │ Krok Kartografa │ │
│ │ +15% cartography yield in Plenny │ │
│ │ Best with Cartographer's Eye │ │
│ └─────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ ◉ Guild Pace (recommended) │ │ selected state
│ │ Krok Cechowy │ │
│ │ +10% quest XP from Cech quests │ │
│ │ Best with Steady Hands │ │
│ └─────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ ○ Long Pace │ │
│ │ Długi Krok │ │
│ │ +20 max energy, +5% step efficiency │ │
│ │ Best with Guild Pace │ │
│ └─────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ [Cancel] [Confirm — 1pt] │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘

Popover copy table

Slotplen
Mastery titleKrok i TempoPace and Pacing
Choose promptWybierz jeden efekt:Choose one effect:
Option 1 nameKrok KartografaCartographer's Pace
Option 1 modifier+15% wydajności kartograficznej w Plenny+15% cartography yield in Plenny
Option 1 hintNajlepsze z Okiem KartografaBest with Cartographer's Eye
Option 2 nameKrok CechowyGuild Pace
Option 2 modifier+10% XP z questów Cechu+10% quest XP from Cech quests
Option 2 hintNajlepsze z Pewnymi DłońmiBest with Steady Hands
Option 3 nameDługi KrokLong Pace
Option 3 modifier+20 maks. energii, +5% efektywności kroku+20 max energy, +5% step efficiency
Option 3 hintNajlepsze z Cechowym KrokiemBest with Guild Pace
CancelAnulujCancel
ConfirmPotwierdź — 1 pktConfirm — 1pt

Keystone — locked state with unlock overlay

keystone.unshaken-step is visible on the tree from session start (visibility: “public”). It is locked until Quest 001 (quest.001-first-road) is completed.

┌─────────────────────────────────────┐
│ ⊗ Krok Niezachwiany │
│ Unshaken Step │
│ │
│ [KEYSTONE LOCK OVERLAY] │
│ │
│ ┌─────────────────────────────┐ │
│ │ 🔒 Complete Quest 001 │ │
│ │ to unlock this keystone │ │
│ │ │ │
│ │ Ukończ Quest 001, aby │ │
│ │ odblokować ten keystone │ │
│ └─────────────────────────────┘ │
│ │
│ Effect preview: │
│ +50% step efficiency │
│ +25 max energy │
│ Idle energy regen: REMOVED │
│ │
│ [Dismiss] │
└─────────────────────────────────────┘

Keystone — unlocked state (after Quest 001 completion):

┌─────────────────────────────────────┐
│ ✦ Krok Niezachwiany │ gold star, pulsing glow
│ Unshaken Step │
│ │
│ QUEST COMPLETE — UNLOCKED │ --color-success banner
│ │
│ +50% step efficiency │
│ +25 max energy │
│ Idle energy regen: REMOVED │
│ │
│ ┌─────────────────────────────┐ │
│ │ [Allocate — 0pt] │ │ keystones cost 0pts — quest-gated only
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘

Note for mechanics-designer: The popover shows keystone cost as “0pt” following the pattern from the data file (no cost field on keystones, gated only by quest). If keystones have a point cost, update this wireframe accordingly. FLAG_LEAD: mechanics-designer — confirm whether keystones consume available points or are purely quest-gated.


Allocation confirm modal

Shown after tapping an allocatable node and before committing. In mock mode (ADR-0006): immediate confirm, no provisional pending banner.

┌─────────────────────────────────────────────────┐
│ │
│ Allocate node? │
│ Przydzielić węzeł? │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ ● Even Stride / Równy Krok │ │
│ │ +5% step efficiency │ │
│ └─────────────────────────────────────────┘ │
│ │
│ Points: 7 → 6 │
│ Punkty: 7 → 6 │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ [Cancel / Anuluj] [Confirm / OK] │ │
│ └─────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────┘

Confirm modal copy table

Slotplen
Modal titlePrzydzielić węzeł?Allocate node?
Points remainingPunkty: {before} → {after}Points: {before} → {after}
CancelAnulujCancel
ConfirmOKOK

Mock mode note: In mock mode, pressing Confirm fires POST /tree/allocate and the node state updates synchronously. There is no “provisional” badge after allocation — the node immediately shows as allocated (filled). Production will show a provisional state while the step reconciliation worker validates the energy balance.


Path preview affordance

When the player taps a locked (prereq-gated) node, instead of an error, show which path of nodes is required to reach it:

Node tapped: [cartographers-eye] (requires: inked-boots AND compass-habit)
Path preview highlights:
even-stride → surveyors-squint → inked-boots → compass-habit → [target]
In the tree canvas, all nodes on this path get a dashed `--color-warning` border.
A strip below the canvas shows: "2 nodes needed to reach this notable"
"2 węzły potrzebne do osiągnięcia notables"

Path preview strip text: {n} węzły potrzebne / {n} nodes needed. Clears when player taps elsewhere.


Available points — 0 state

When walker.availablePoints === 0, the tree goes into “browse mode” automatically:

  • Nodes appear in their current state (allocated/unallocated) but no tap triggers the confirm modal.
  • Tapping a node opens its popover for reading modifiers only.
  • A persistent banner at the top of the canvas: Brak dostępnych punktów — ukończ questy, aby zdobyć więcej / No available points — complete quests to earn more.
  • The available points counter in the header shows 0 pts ○ in --color-on-surface-muted.

Keyboard / switch-control focus order

The tree is a 2D layout — flat keyboard navigation would lose spatial context. Proposed focus model for 20 nodes:

Focus traversal strategy: Branch-first, bottom-to-top.

Order:

  1. Available points counter (header right)
  2. Cluster label
  3. Entry node (even-stride) — always first interactive node
  4. Left branch, bottom to top: surveyors-squint → inked-boots → compass-habit → cartographers-eye
  5. Centre branch, bottom to top: deep-breath → measured-pace → long-step → guild-pace
  6. Right branch, bottom to top: steady-grip → margin-note → iron-heel → steady-hands
  7. Mastery node (pace-and-pacing)
  8. Keystone node (unshaken-step)

This order mirrors the visual layout (left-to-right then bottom-to-top within each branch) so that switch-control users building spatial memory can predict the next focus point without seeing the screen.

Arrow key navigation (physical keyboard on iPad or desktop wiki):

  • Left/right arrow: move between branches at the same y-level.
  • Up/down arrow: move within the current branch.
  • Enter/Space: activate node (open confirm modal or popover).
  • Escape: close any open modal or popover.

Screen reader announcement per node: “[Node name] — [EN name / PL name] — [modifier summary] — [state: allocated / unallocated / locked / reachable] — Cost: [n] point(s)”

Example: “Cartographer’s Eye — Oko Kartografa — plus 25% cartography yield, plus 10% discovery radius — unallocated, reachable — Cost: 1 point”


Accessibility — Tree viewer

Walking-specific baseline answers:

CheckResult
One-handed while walkingPARTIAL — the tree is a 2D canvas. At 20 nodes, single-thumb navigation is feasible for node taps but pan/zoom (phase 11) will require two-handed input or a dedicated one-thumb mode. Phase 9 static layout: the cluster fits in one screen at the design scale, so no pan needed.
Glance ≤ 2 secondsPASS — available points counter is the dominant glance read (header, persistent). Node allocation state (gold fill = allocated) is visible at a glance.
Tap target ≥ 48dpPASS — all nodes have 48dp minimum invisible tap targets regardless of visual size.
Color contrast ≥ 4.5:1 bodyPASS — node labels use --color-on-surface on --color-surface. Allocated node fill uses --color-region-plenny text against --color-bg (6.9:1).
Font scale 200%PARTIAL — tree node labels hide at 200% (too small to display legibly); long-press triggers full-detail popover which does scale. Available points counter and cluster label both scale and wrap.
Audio/haptic alternativesPASS — node allocation: medium haptic + click sound. Keystone unlock: heavy haptic + chime. Mastery confirm: medium haptic. Cancel: light haptic.

FLAG_LEAD: mechanics-designer — open question noted above: do keystones consume available points or are they purely quest-unlocked? Answer affects the confirm modal cost display and the available points counter behavior.


TreeViewer prop contract note

See wiki/src/components/TreeViewer.astro for the prop contract comment block updated to match this wireframe. Backend-engineer reading this wireframe: the /tree/state response shape already covers topology + allocations + available blocks. No additional endpoints needed for the phase 9 wiki prototype.