Spaces:
Sleeping
Sleeping
| import clsx from "clsx"; | |
| import Badge from "@/components/ui/Badge"; | |
| export interface RoadmapItem { | |
| name: string; | |
| status: "live" | "next" | "north-star"; | |
| /** leading data figure, typeset in mono (e.g. "34.57 h") */ | |
| stat?: string; | |
| detail: string; | |
| } | |
| export interface RoadmapStripProps { | |
| items: RoadmapItem[]; | |
| } | |
| const statusMeta: Record< | |
| RoadmapItem["status"], | |
| { label: string; variant: "accent" | "outline" | "ghost"; card: string } | |
| > = { | |
| live: { | |
| label: "Live", | |
| variant: "accent", | |
| card: "hairline depth-1 bg-surface", | |
| }, | |
| next: { | |
| label: "Next", | |
| variant: "outline", | |
| card: "hairline depth-1 bg-surface", | |
| }, | |
| "north-star": { | |
| label: "North star", | |
| variant: "ghost", | |
| card: "border border-dashed border-line bg-transparent", | |
| }, | |
| }; | |
| /** Multi-dataset roadmap: live anchor → next corpus → north-star evaluation. */ | |
| export default function RoadmapStrip({ items }: RoadmapStripProps) { | |
| return ( | |
| <ol className="grid gap-3 md:grid-cols-3 stagger-spring"> | |
| {items.map((item, i) => { | |
| const meta = statusMeta[item.status]; | |
| return ( | |
| <li | |
| key={item.name} | |
| className={clsx("flex flex-col gap-2 rounded-sm p-5", meta.card)} | |
| > | |
| <div className="flex items-center justify-between gap-2"> | |
| <span className="num text-[11px] tracking-[0.18em] text-muted"> | |
| {String(i + 1).padStart(2, "0")} | |
| </span> | |
| <Badge variant={meta.variant}> | |
| {item.status === "live" && ( | |
| <span | |
| aria-hidden | |
| className="pulse-dot inline-block size-1.5 rounded-full bg-accent" | |
| /> | |
| )} | |
| {meta.label} | |
| </Badge> | |
| </div> | |
| <h3 | |
| className={clsx( | |
| "font-display text-xl", | |
| item.status === "north-star" ? "text-muted" : "text-text", | |
| )} | |
| > | |
| {item.name} | |
| </h3> | |
| <p className="text-[13px] leading-relaxed text-muted"> | |
| {item.stat && ( | |
| <span className="num text-text">{item.stat} </span> | |
| )} | |
| {item.detail} | |
| </p> | |
| </li> | |
| ); | |
| })} | |
| </ol> | |
| ); | |
| } | |