Replace the fragile per-row tail/maxVirtual state with a clean global-
metrics approach:
- Measure cardWidth, stride, paddingLeft, viewportWidth, rightDeadzone
once from the first synced row; use the same values for all rows.
- Per-row max scroll computed purely from math:
max(0, paddingLeft + (N-1)*stride - maxVisibleLeft)
where maxVisibleLeft = viewportWidth - cardWidth - rightDeadzone.
- Global virtual offset (syncedRowsCurrentOffset/targetOffset) is shared
across all rows; each row clamps independently in applySyncedRowScroll.
- Tail is a global constant (= rightDeadzone) applied to all rows.
- Fix scrolling-back bug: desiredOffset was stuck at currentOffset when
moving left; now always computed from anchor column position.
- Avoid full animation sweep on view entry: init current/target offset
from existing DOM scrollLeft on first use.
Also removes per-row --sync-row-max-virtual CSS var and simplifies
.media-row padding to use only --sync-row-tail.