Files
archy/.planning/phases/01-federation-mesh-hardening/01-13-SUMMARY.md
T
archipelagoandClaude Opus 5 5f366f7589
Demo images / Build & push demo images (push) Successful in 4m25s
fix(01-13): on-brand scroll cue makes the onboarding tickbox findable (UIFIX-03)
On a short viewport the seed-confirmation tickbox sits below the fold inside
the step's scrolling area while Continue stays pinned and disabled in the
fixed footer — onboarding reads as broken rather than incomplete.

The cue is a sticky-bottom scrim and glass pill inside the scroll region, and
its visibility comes from real geometry: scrollHeight vs clientHeight for
overflow, then a getBoundingClientRect comparison of the tickbox's bottom
against the container's. On a tall screen the element does not render at all,
so those screens are unchanged. Rects rather than offsetTop because offsetTop
is relative to the nearest positioned ancestor — here the outer card, not the
scroll container.

It is wayfinding only: activating it scrolls the tickbox into view and never
sets confirmed, focuses Continue, or auto-ticks, which a test pins.

Listener setup was moved onto both onMounted paths — the sessionStorage
restore path returned early, so a user navigating back would have had no cue.

Verified: 6 new tests plus the full frontend suite green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 05:54:40 -04:00

7.5 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, requirements-completed, coverage, duration, completed, status
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions requirements-completed coverage duration completed status
01-federation-mesh-hardening 13 ui
vue
onboarding
scroll
accessibility
reduced-motion
phase provides
01-federation-mesh-hardening OnboardingSeedGenerate.vue's existing flex-column step layout — a scrolling content region between a fixed header and a fixed footer whose Continue button stays pinned and disabled until `confirmed` is ticked
An overflow-derived bottom scroll cue on the seed step that appears only when the confirmation tickbox is actually below the fold, scrolls it into view when activated, and disappears once it is visible
A vitest suite pinning the cue's show/hide contract, including the no-overflow no-render case
onboarding
web5
added patterns
Derive an affordance's visibility from a real measurement (scrollHeight vs clientHeight, plus getBoundingClientRect comparison of target vs container bottom) rather than a viewport-height guess — the cue is then structurally incapable of appearing when there is nothing below.
Measure with viewport-relative rects, not offsetTop/offsetHeight: offsetTop is relative to the nearest *positioned* ancestor, which here is the outer card (it carries `relative` for z-index stacking), not the scroll container.
created modified
neode-ui/src/views/__tests__/OnboardingScrollCue.test.ts
neode-ui/src/views/OnboardingSeedGenerate.vue
The cue is a sticky-bottom element inside the scroll region (gradient scrim + a glass pill reading 'One more step below' with a bobbing chevron), not a fixed overlay — so it rides the scroll container and cannot cover the fixed footer.
Wayfinding only: `revealConfirm` calls scrollIntoView on the tickbox label and nothing else. It never sets `confirmed`, never focuses or enables Continue, and never auto-ticks on scroll — pinned by a dedicated test.
Re-measure on scroll, window resize, and a ResizeObserver on the content wrapper, plus watches on `words` and `loading` — the word grid arrives asynchronously and changes height when the words/QR tabs switch, either of which can flip the region into overflow.
onMounted was restructured so listener setup runs on both paths (restored-from-sessionStorage and freshly generated). The previous early `return` on the restore path would otherwise have skipped setup entirely for a user navigating back.
UIFIX-03
id description requirement verification human_judgment
D1 On a short viewport the cue appears, telling the user there is more below UIFIX-03
kind ref status
unit neode-ui/src/views/__tests__/OnboardingScrollCue.test.ts#renders the cue when there is overflow and the tickbox is below the fold pass
false
id description requirement verification human_judgment
D2 Activating the cue brings the tickbox into view in one action, without touching confirmation state UIFIX-03
kind ref status
unit …#activating the cue scrolls the tickbox into view and never touches confirmed pass
false
id description requirement verification human_judgment
D3 The cue disappears once the tickbox is visible and does not reappear while it stays visible UIFIX-03
kind ref status
unit …#removes the cue once scrolling brings the tickbox into view pass
false
id description requirement verification human_judgment
D4 On a tall viewport the cue never renders — no element, no reserved space, no layout shift UIFIX-03
kind ref status
unit …#renders no cue when the scroll region reports no overflow pass
false
id description requirement verification human_judgment
D5 The cue is absent while the seed is generating (no tickbox to point at yet) and once the box is ticked UIFIX-03
kind ref status
unit …#never shows the cue while loading, regardless of overflow; …#removes the cue once the tickbox is ticked pass
false
id description requirement verification human_judgment
D6 The cue's motion is disabled under prefers-reduced-motion, per the site-wide convention UIFIX-03
kind ref status
other @media (prefers-reduced-motion: reduce) { .onb-cue-chevron { animation: none; } } in OnboardingSeedGenerate.vue's scoped style pass
false
70min 2026-08-01 complete

Phase 1 Plan 13: On-Brand Scroll Cue for the Onboarding Tickbox (UIFIX-03) Summary

Added a measurement-driven scroll cue to the seed step so the confirmation tickbox is never silently below the fold on a short screen — and made it structurally impossible for that cue to appear on a screen tall enough not to need it.

Performance

  • Duration: ~70 min (across two sessions — see Deviations)
  • Completed: 2026-08-01
  • Tasks: 2/2
  • Files modified: 2 (1 view, 1 new test file)

Accomplishments

  • A sticky-bottom cue inside the seed step's scroll region: a gradient scrim with a glass pill ("One more step below") and a bobbing chevron, styled to the house dark/glass language rather than a bolted-on arrow.
  • Visibility is derived from real geometry — scrollHeight > clientHeight for overflow, then a getBoundingClientRect() comparison of the tickbox's bottom against the scroll container's bottom. On a tall viewport the element does not render at all, so tall screens are byte-identical to before.
  • Activating the cue smooth-scrolls the tickbox into view and does nothing else; a test asserts confirmed is untouched, so the affordance can never become a way to skip the confirmation.
  • The cue also stays hidden while the seed is generating and after the box is ticked, and its chevron animation is disabled under prefers-reduced-motion.
  • Listener/observer setup was moved onto both onMounted paths — previously the sessionStorage-restore path returned early, which would have left a user navigating back to this step with no cue at all.

Files Created/Modified

  • neode-ui/src/views/OnboardingSeedGenerate.vue — refs on the scroll container, content wrapper and tickbox label; updateScrollCue() measurement; revealConfirm(); scroll/resize/ResizeObserver wiring with matching teardown in onUnmounted; the cue markup and its scoped CSS (fade transition, chevron bob, reduced-motion guard).
  • neode-ui/src/views/__tests__/OnboardingScrollCue.test.ts — 6 tests pinning the full contract.

Deviations from Plan

Process deviation: executor killed mid-verification by an SSH disconnect

Found during: post-implementation verification Issue: The orchestrating session and its agents died when the operator's SSH connection dropped. This plan's implementation and test file were complete and on disk but uncommitted, and no SUMMARY had been written. Resolution: A follow-on session re-ran the suite (6/6 green), confirmed the full frontend suite was green, wrote this SUMMARY, and committed. Files modified: none beyond the original work

Known Stubs

None.

Threat Flags

None — a presentational affordance with no new endpoint, no auth surface, and no state mutation. The one safety-relevant property (that it cannot set confirmation state) is asserted by test.

Self-Check: PASSED

  • FOUND: neode-ui/src/views/OnboardingSeedGenerate.vue (modified)
  • FOUND: neode-ui/src/views/__tests__/OnboardingScrollCue.test.ts (created, 6 tests)
  • CONFIRMED: npx vitest run full frontend suite green