Context
CODE-QUALITY-AUDIT.md §1 (Top-5 #3). The three scrollytelling components are 100% structurally identical (~47 lines each), differing only in name and which StickyVisualization/NarrativeSteps they import:
src/components/eviction-data/EvictionScrollytelling.tsx
src/components/campaign-finance-data/CampaignFinanceScrollytelling.tsx
src/components/sidewalk-data/SidewalkScrollytelling.tsx
The work
Effort: Low (~an hour). Removes ~100 lines of duplication and the only any types in the codebase.
Priority: Low — code-health cleanup, no user-facing change.
Context
CODE-QUALITY-AUDIT.md§1 (Top-5 #3). The three scrollytelling components are 100% structurally identical (~47 lines each), differing only in name and whichStickyVisualization/NarrativeStepsthey import:src/components/eviction-data/EvictionScrollytelling.tsxsrc/components/campaign-finance-data/CampaignFinanceScrollytelling.tsxsrc/components/sidewalk-data/SidewalkScrollytelling.tsxThe work
ScrollytellingWrappertaking the viz + steps as props/children; collapse the three files to thin wrappers.useLocale.tsandstyles.cssout ofsidewalk-data/(where eviction & campaign-finance currently reach across to import them) intosrc/components/shared/orsrc/utils/.let scroller: anydeclarations with the proper scrollama type already used in the sidewalk component.@components/*, etc.) consistently while touching these files.Effort: Low (~an hour). Removes ~100 lines of duplication and the only
anytypes in the codebase.Priority: Low — code-health cleanup, no user-facing change.