TextCore.ts: shared text rendering with dirty-check caching, zoom-bucket
resolution, and optional word-wrap. TextSprite and StickySprite now
compose TextCore instead of duplicating text logic.
Sticky resize now bakes width only (fontSize stays stable), so dragging
a sticky wider/narrower reflows text with auto-adjusted height — like
a resizable text box.
Add TextSharpnessManager for crisp text rendering at all zoom levels:
- Discrete zoom buckets (0.5–3x) avoid texture churn on small zoom changes
- Initial bucket applied to all items on setup and newly created items
via SceneManager.onItemCreated callback (fixes blurry-on-load)
- Visibility check uses getItemWorldBounds for correct grouped item coords
- TextSprite/StickySprite gain setZoomBucket() for resolution control
Remove fontSize +/- controls from contextual toolbar — font size is now
controlled purely through direct manipulation (resize → bake).
- Replace 50ms setTimeout with queueMicrotask for editor open
- Skip updateFromData() entirely when no inputs changed
- Cache background redraw inputs, skip Graphics clear+redraw when shape unchanged
- Separate text-only, style-only, and bg-only update paths