From 22a55aa073e1decec1da69da3c9542e08536ce93 Mon Sep 17 00:00:00 2001 From: Jonathan Hvid Date: Tue, 12 May 2026 15:15:47 +0200 Subject: [PATCH] feat(roadmap): centred 'Roadmap' page header + legend escapes route component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Page-level rebuild. /roadmap.astro renders a centred header block that reads as one calm vertical stack: Roadmap ← 11px tracked uppercase eyebrow (--on-surface-variant) Roadmap ← 48px serif h1, single word A live picture of the work… ← 14px subtitle, 480px max-width The eyebrow + h1 read 'Roadmap → Roadmap' on purpose — the tracked uppercase eyebrow primes the eye for the serif headline, and the repetition feels confident rather than redundant. If it starts to grate in practice, the eyebrow's the easy drop. 'What we are building.' is gone. The earlier 'The route' sub-header inside is gone. The two prev/next arrow buttons in that sub-header are gone (the single right-edge advance arrow lands in the next commit). Legend moves out of and into /roadmap.astro as the page's final block. With the route still .rr-fullbleed, this lets the legend return to centred content-column width — exactly the spec's 'header-centred / route-wide / legend-centred' rhythm. Mid-state in this commit: the advance arrow doesn't exist yet, so there's no in-page scroll affordance beyond the still-active scroll-snap behaviour. Step 3 adds the arrow; step 4 strips the snap and adds drag + wheel + animated glide. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/components/RoadmapRoute.astro | 104 ++---------------------------- src/pages/roadmap.astro | 91 ++++++++++++++++++-------- 2 files changed, 69 insertions(+), 126 deletions(-) diff --git a/src/components/RoadmapRoute.astro b/src/components/RoadmapRoute.astro index 3bdb2f6..493d452 100644 --- a/src/components/RoadmapRoute.astro +++ b/src/components/RoadmapRoute.astro @@ -52,23 +52,6 @@ const initialShippingX = lastShippingIndex >= 0 ? layout.itemX[lastShippingIndex ---
- -
-

The route

-
- - -
-
- -
- Shipping - In beta - Exploring - Considering -
+ - +
    {items.map((item, i) => (
  1. @@ -174,8 +151,6 @@ const initialShippingX = lastShippingIndex >= 0 ? layout.itemX[lastShippingIndex const svg = section.querySelector('#rr-path-svg'); const pathD = section.querySelector('#rr-path-d'); const milestones = Array.from(section.querySelectorAll('.rr-milestone')); - const prev = section.querySelector('#rr-prev'); - const next = section.querySelector('#rr-next'); const fadeL = section.querySelector('#rr-fade-l'); const fadeR = section.querySelector('#rr-fade-r'); if (!scroll || !track || !svg) return; @@ -219,16 +194,12 @@ const initialShippingX = lastShippingIndex >= 0 ? layout.itemX[lastShippingIndex milestones.forEach((m, i) => { m.style.left = `${itemX[i]}px`; }); } - const step = () => scroll!.clientWidth * 0.72; - prev?.addEventListener('click', () => scroll!.scrollBy({ left: -step(), behavior: 'smooth' })); - next?.addEventListener('click', () => scroll!.scrollBy({ left: step(), behavior: 'smooth' })); - + /* Arrow handler + edge-state updates are rewritten in the next commit + (drag + wheel + glide). For now only the fades update on scroll. */ function updateNav() { const max = scroll!.scrollWidth - scroll!.clientWidth; const atStart = scroll!.scrollLeft <= 2; const atEnd = scroll!.scrollLeft >= max - 2; - if (prev) prev.disabled = atStart; - if (next) next.disabled = atEnd; if (fadeL) fadeL.style.opacity = atStart ? '0' : '1'; if (fadeR) fadeR.style.opacity = atEnd ? '0' : '1'; } @@ -259,45 +230,6 @@ const initialShippingX = lastShippingIndex >= 0 ? layout.itemX[lastShippingIndex