project-bifrost-platform/src/pages/roadmap.astro
Jonathan Hvid 0ea7e3fd96 style(roadmap): more air title→legend, tighter legend→route
Pair the legend visually with the route by widening the gap above it
and narrowing the gap below.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 15:31:41 +02:00

111 lines
3.4 KiB
Text

---
import AppLayout from '../layouts/AppLayout.astro';
import LatestDispatchBanner from '../components/LatestDispatchBanner.astro';
import RoadmapRoute from '../components/RoadmapRoute.astro';
import { getAllRoadmapItems } from '../lib/db';
const user = Astro.locals.user;
const items = getAllRoadmapItems()
.sort((a, b) => a.display_order - b.display_order || a.id - b.id);
---
<AppLayout title="Roadmap" user={user}>
<article class="roadmap-page">
<!-- Single centred header — merges the page lead with the route's
interaction hints. -->
<header class="roadmap-header">
<h1 class="roadmap-title">Roadmap</h1>
<p class="roadmap-sub">
A live picture of the work. What's in motion, what's queued,
what we're still thinking about. Tap or hover any milestone
for the full story. Drag or scroll to move.
</p>
</header>
<!-- Legend lives above the route now — reads as a key the eye picks
up just before walking the path. -->
<div class="roadmap-legend" aria-label="Status legend">
<span><i style="background:#6d8c7c"></i>Shipping</span>
<span><i style="background:#b96b58"></i>In beta</span>
<span><i style="background:#b4b2a9"></i>Exploring</span>
<span><i style="background:#d4d2c8"></i>Considering</span>
</div>
<RoadmapRoute items={items} />
<!-- Latest dispatch sits at the foot of the page with generous
space above so it reads as a separate beat, not a continuation
of the route. -->
<LatestDispatchBanner />
</article>
</AppLayout>
<style>
.roadmap-page {
padding: 0 36px 80px;
max-width: var(--content-max);
margin: 0 auto;
}
/* ── Centred header ──────────────────────────────────────────── */
.roadmap-header {
text-align: center;
max-width: 640px;
margin: 0 auto 56px; /* generous gap to the legend */
padding-top: 32px;
}
.roadmap-title {
font-family: var(--font-serif);
font-weight: 400;
font-size: 48px;
line-height: 1.05;
letter-spacing: var(--tracking-tight);
color: var(--on-surface);
margin: 0 0 14px;
}
.roadmap-sub {
font-size: 14px;
line-height: 1.65;
color: var(--on-surface-variant);
margin: 0 auto;
max-width: 520px;
}
/* ── Legend (above the route, key-style) ─────────────────────── */
.roadmap-legend {
display: flex;
justify-content: center;
gap: 24px;
margin: 0 auto 14px; /* tight to the route — they're paired */
flex-wrap: wrap;
}
.roadmap-legend span {
display: inline-flex;
align-items: center;
gap: 7px;
font-family: var(--font-sans);
font-size: 10px;
letter-spacing: 1px;
text-transform: uppercase;
color: var(--on-surface-variant);
}
.roadmap-legend i {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
/* ── Dispatch banner (foot of page, generous breathing room) ── */
.roadmap-page :global(.rr-dispatch) { margin-top: 112px; }
@media (max-width: 767px) {
.roadmap-page { padding: 0 24px 64px; }
.roadmap-header { padding-top: 24px; margin-bottom: 40px; }
.roadmap-title { font-size: 36px; }
.roadmap-legend { margin-bottom: 12px; }
.roadmap-page :global(.rr-dispatch) { margin-top: 72px; }
}
</style>