diff --git a/src/pages/roadmap.astro b/src/pages/roadmap.astro new file mode 100644 index 0000000..06e9d69 --- /dev/null +++ b/src/pages/roadmap.astro @@ -0,0 +1,213 @@ +--- +import { readFileSync } from 'fs'; +import { join } from 'path'; +import AppLayout from '../layouts/AppLayout.astro'; +import { marked } from 'marked'; + +const user = Astro.locals.user; + +// Single-file roadmap — not a content collection +const raw = readFileSync(join(process.cwd(), 'content/roadmap.md'), 'utf-8'); + +// Strip YAML frontmatter +const body = raw.replace(/^---[\s\S]*?---\n/, ''); + +// Parse sections by ## headings +function parseSections(md: string) { + const sectionRe = /^## (.+)$/gm; + const sections: { title: string; items: { title: string; body: string; pilotOnly: boolean }[] }[] = []; + const matches = [...md.matchAll(sectionRe)]; + + for (let i = 0; i < matches.length; i++) { + const m = matches[i]; + const start = m.index! + m[0].length; + const end = matches[i + 1]?.index ?? md.length; + const sectionBody = md.slice(start, end).trim(); + + // Each item starts with **Title** — description + const itemRe = /\*\*([^*]+)\*\*\s*—\s*([\s\S]*?)(?=\n\n\*\*|\n\n##|$)/g; + const items: { title: string; body: string; pilotOnly: boolean }[] = []; + let itemMatch: RegExpExecArray | null; + while ((itemMatch = itemRe.exec(sectionBody)) !== null) { + const rawBody = itemMatch[2].trim(); + const pilotOnly = rawBody.includes('`pilot-only`'); + const cleanBody = rawBody.replace(/`pilot-only`/g, '').trim(); + items.push({ title: itemMatch[1], body: cleanBody, pilotOnly }); + } + + sections.push({ title: m[1], items }); + } + return sections; +} + +const sections = parseSections(body); + +const horizonColors: Record = { + 'In progress': 'var(--pigment-copper)', + 'Next': 'var(--pigment-ochre)', + 'Later': 'var(--pigment-indigo)', +}; +--- + +
+ + + +
+ {sections.map((section) => ( +
+
+
+ +
    + {section.items.map((item) => ( +
  • +
    +

    {item.title}

    + {item.pilotOnly && ( + + Pilot + + )} +
    +

    {item.body}

    +
  • + ))} +
+
+ ))} +
+ +
+
+ +