src/components/about/story-timeline.tsx and src/components/downloads/get-started-steps.tsx duplicate the scroll-drawn-line mechanism (~80 lines: offset-walk threshold measurement, bidirectional reached sync via useMotionValueEvent, ResizeObserver re-measure, track/fill/tip render).
Extraction was deliberately deferred at review of get-started-steps because PR #234 was mid-flight on story-timeline. After both are on main:
- Extract a behaviour hook
useScrollIgnition({ listRef, trackRef, markerRefs, offset }) → { scrollYProgress, tipTop, reached, thresholds } into src/lib/ or a src/components/motion/ home (align with the motion-kit ADR when it lands).
- Keep colour systems and marker anatomy per-component (gradient + per-marker accent on about vs single red numbered circles on downloads).
- Prefer get-started-steps' track-relative coordinate space (thresholds divided by the track's own height — story-timeline's list-relative version has a small latent drift).
- Migrate story-timeline's local
usePrefersReducedMotion copy to the shared src/lib/use-prefers-reduced-motion.ts.
src/components/about/story-timeline.tsxandsrc/components/downloads/get-started-steps.tsxduplicate the scroll-drawn-line mechanism (~80 lines: offset-walk threshold measurement, bidirectionalreachedsync viauseMotionValueEvent, ResizeObserver re-measure, track/fill/tip render).Extraction was deliberately deferred at review of get-started-steps because PR #234 was mid-flight on story-timeline. After both are on main:
useScrollIgnition({ listRef, trackRef, markerRefs, offset }) → { scrollYProgress, tipTop, reached, thresholds }intosrc/lib/or asrc/components/motion/home (align with the motion-kit ADR when it lands).usePrefersReducedMotioncopy to the sharedsrc/lib/use-prefers-reduced-motion.ts.