15b0b95413
The kanban drawer had grown the only edge-aware masked scroller in the tree, and the next surface that wants one would have copied it. Lift it to components/ui as FadeScroll, export it on the plugin SDK, and leave kanban's ScrollFade as a name its call sites already pass `max` to. The mask math comes out as two pure functions. jsdom's CSS parser drops any gradient containing calc(), so a rendered mask-image can't be read back off the style attribute -- edgeMask/scrollEdges are testable for real where the component's inline style is not.