import { readFile } from "node:fs/promises"; import { join } from "node:path"; export interface NavItem { id: string; label: string; href: string; active?: boolean; detail: string; } export interface Feature { slug: string; label: string; href: string; detail: string; prose: () => Promise; } const ROOT = import.meta.dir; const DEFINITIONS: Feature[] = []; export const FEATURES: Feature[] = DEFINITIONS.map((feature) => ({ ...feature, prose: (prose = feature.prose) => prose(), })); export const NAV: NavItem[] = [ { id: "home", label: "Home", href: "/", detail: "Porter discography powered by muddle", }, ...DEFINITIONS.map((feature) => ({ id: feature.slug, label: feature.label, href: feature.href, detail: feature.detail, active: false, })), ]; export function navFor(slug?: string): NavItem[] { return NAV.map((item) => ({ ...item, active: slug ? item.id === slug : item.id === "home", })); } export interface IntroTopic { id: string; label: string; note: string; tint: string; } export const INTRO: IntroTopic[] = [ { id: "scaffold", label: "Scaffold", note: "Every variable is compiled ahead of time so the page ships with zero runtime javascript.", tint: "violet", }, { id: "relations", label: "Relations", note: "Anchors like @introtopic record geometry and computed styles so stylesheets can reason about other elements.", tint: "rose", }, { id: "predict", label: "Prediction", note: "Prerender measures this panel and ships the numbers, so the first click already animates smoothly.", tint: "sky", }, { id: "momentum", label: "Momentum", note: "The whole greeting is server-rendered and hydrates instantly thanks to pre-computed wait.", tint: "amber", }, ];