Derive masonry columns from width + instrument rotation reflow
Created by: jedmund
Summary
- Replace the size-class + AppStorage column-count scheme with a width-driven bucket (2/3/4/5) derived from each
ScrollView's live width via.onGeometryChangewith anInttransform, so reflow fires only on bucket flips — not on every width pixel during a rotation animation. iPhone is locked to portrait since the width-driven scheme has no need for an iPhone-landscape bucket. - Add
OSSignposter+ companionLoggerprobes (masonry-distribute,column-bucket-change,cell-onAppear/cell-onDisappear,pixivimage-load,cellframe-write,appstorage-first-read) under subsystemcom.attractor.pixillate, categoryrotation, so Instruments' Points-of-Interest track surfaces the moving pieces of a column-bucket flip next time reflow regresses. Probes are effectively free when Instruments isn't recording.
Cold-install + rotate on a physical iPad (iPad Pro 11", iOS 26.x) is now smooth — no squished first frame. Keeping the probes in place so the next regression is one trace away from a diagnosis.
Test plan
-
Builds for iPad Pro 13" simulator (iOS 26.2, Debug). -
Cold install on physical iPad → rotate once → no freeze, no squished frame. -
Verify Home / Tag / Profile / RelatedIllustsSection all reflow cleanly on rotation. -
Verify detail overlay's nested RelatedIllustsSectionalso repaginates on rotation. -
Spot-check signposts: log stream --predicate 'subsystem == "com.attractor.pixillate" && category == "rotation"'with the iPad tethered. -
Verify the "Grid" section no longer appears in Settings.