Root causes found by deep CSS + Vue audit:
1. Missing .mjr-show-details CSS rule (PRIMARY cause of reload impression)
- .mjr-card-info had no hide rule in the main grid
- applyGridSettingsClasses() toggles .mjr-show-details on the container
- estimateRowHeight() assumed metaHeight=0 when showDetails=false
- But .mjr-card-info was always rendered (~44px) -> virtualizer under-
estimated every row -> repositioned all rows on first measure -> visual
jump that looked like a full grid reload on each scroll
Fix: add .mjr-grid .mjr-card-info { display:none } default with
.mjr-grid.mjr-show-details .mjr-card-info { display:block } toggle
(same pattern already used by the bottom feed at line 9119)
2. estimateRowHeight metaHeight constant was 82px instead of ~52px
- Actual card-info height: padding 12 + filename 15 + margin 4 + row 13 = 44px
- 82px caused over-allocation when showDetails=true -> gap between rows
that the virtualizer would correct on measure -> same jump artifact
Fix: reduce to 52px (44px actual + 8px buffer for font variance)
3. scale(0.92) on .is-selected caused a visible blink on selection change
- The 8% shrink animated over 120ms transition; rapid selection change
(e.g. keyboard nav) caused all de-selected cards to snap back -> blink
Fix: reduce to scale(0.97) - still gives inset feel without the flash
4. Skeleton card min-height:146px conflicted with computed skeletonCardStyle
height -> skeleton cards taller than real cards -> layout jump on first
asset load
Fix: remove min-height from .mjr-grid-skeleton-card