02 / Technique
Type enters on a single axis, then locks.
Each headline is measured at load, once after fonts settle, and on resize. Scroll position produces a 0–1 local progress value. That value reduces either an X or a Y offset to zero; it never combines them. The red block uses the same scroll progress to walk a route whose every leg is horizontal or vertical.
function pointOnRoute(progress) {
const scaled = clamp(progress, 0, 1) * (route.length - 1);
const leg = Math.min(Math.floor(scaled), route.length - 2);
const local = scaled - leg;
const from = route[leg];
const to = route[leg + 1];
return { x: from.x + (to.x - from.x) * local,
y: from.y + (to.y - from.y) * local };
}
const progress = clamp((window.scrollY - (item.top - viewport * .76)) /
(viewport * .58), 0, 1);
const offset = (1 - easeOut(progress)) * item.distance *
(item.axis === 'x' ? track : row);
item.element.style.setProperty(item.axis === 'x' ? '--slide-x' : '--slide-y',
`${offset}px`);