v-if="loading" swaps out <div ref="tableWrap"> for a brand new DOM
node every time loading toggles true -> false. mounted() only attaches
the scroll listener once, to whichever wrap existed at mount time --
enterYearMode(), exitYearMode(), and jumpToYear() all trigger that
swap, silently orphaning the listener on the old (now-detached) node.
After any of those three, scrolling stopped calling checkEdges()/
detectCurrentYear() at all, freezing the footer's year totals.
ensureScrollListener() re-attaches (idempotently, via a dataset flag)
after every such transition. Verified: the wrap element does change
identity across jumpToYear(), and the new element picks up the
listener and fetches totals for the newly-visible year correctly.