// vibn — Projects Dashboard // Restyled from original (DM Sans + purple/colour accents) → Ink & parchment // Design: Lora serif + Inter sans, #1a1510 ink, #f7f4ee paper, no colour accent // Usage: default export, no required props import { useState } from "react"; const T = { ink: "#1a1510", ink2: "#2c2c2a", ink3: "#444441", mid: "#5f5e5a", muted: "#888780", stone: "#b4b2a9", parch: "#d3d1c7", cream: "#f1efe8", paper: "#f7f4ee", white: "#fdfcfa", border: "#e8e2d9", border2:"#d3d1c7", }; const F = { serif: "'Lora', Georgia, serif", sans: "'Inter', sans-serif" }; // ─── Shared primitives ───────────────────────────────────────────────────────── function StatusPill({ label, variant = "default" }) { const styles = { live: { bg: T.cream, text: T.ink3, border: T.border }, building: { bg: T.cream, text: T.ink3, border: T.border }, default: { bg: T.paper, text: T.muted, border: T.border }, invoiced: { bg: T.ink, text: T.paper, border: T.ink }, unbilled: { bg: T.cream, text: T.ink3, border: T.border }, scheduled: { bg: T.parch, text: T.ink2, border: T.border2 }, }; const s = styles[variant] || styles.default; return ( {label} ); } function InkBtn({ children, onClick, small, outline }) { return ( ); } // ─── Nav ─────────────────────────────────────────────────────────────────────── function Nav({ screen, setScreen }) { return ( ); } // ─── Data ────────────────────────────────────────────────────────────────────── const PROJECTS = [ { id: "launchpad", label: "Launchpad", initial: "L", type: "own", status: "live", url: "launchpad.vibn.app", stats: { visitors: "2.4k", signups: 183, mrr: "$840" }, }, { id: "flowmatic", label: "Flowmatic", initial: "F", type: "client", status: "live", url: "flowmatic.app", client: "Acme Corp", stats: { visitors: "890", signups: 54, mrr: "$210" }, costs: { total: 48.20, llm: 29.20, compute: 11.60, other: 7.40, billed: false }, }, { id: "taskly", label: "Taskly", initial: "T", type: "client", status: "building", url: null, client: "Beta Labs", buildProgress: 60, costs: { total: 12.40, llm: 9.20, compute: 3.20, other: 0, billed: false }, }, ]; const ACTIVITY = [ { text: "Launchpad — Blog post published:", detail: '"How to launch faster with AI"', time: "2h ago" }, { text: "Flowmatic — New signup:", detail: "marcus@email.com", time: "4h ago" }, { text: "Taskly — Checkout page built and deployed", detail: "", time: "6h ago" }, { text: "Launchpad — Newsletter #12", detail: "scheduled", time: "Yesterday" }, ]; const BILLING_ROWS = [ { label: "Flowmatic", initial: "F", client: "Acme Corp", llm: 29.20, compute: 11.60, other: 7.40, total: 48.20, billed: false }, { label: "Taskly", initial: "T", client: "Beta Labs", llm: 9.20, compute: 3.20, other: 0, total: 12.40, billed: false }, { label: "Flowmatic", initial: "F", client: "Acme · Feb", llm: 22.10, compute: 8.40, other: 4.20, total: 34.70, billed: true }, ]; const COST_LOG = [ { time: "2h ago", desc: "LLM: Homepage copy generation", project: "Flowmatic", cost: 0.82 }, { time: "3h ago", desc: "LLM: Checkout page code", project: "Taskly", cost: 1.24 }, { time: "5h ago", desc: "LLM: Weekly newsletter draft", project: "Flowmatic", cost: 0.43 }, { time: "6h ago", desc: "Compute: Build pipeline run", project: "Taskly", cost: 0.18 }, { time: "8h ago", desc: "LLM: Discover phase Q&A", project: "Flowmatic", cost: 0.31 }, { time: "Yesterday", desc: "Email delivery · 240 recipients", project: "Flowmatic", cost: 0.96 }, ]; // ─── Project card ────────────────────────────────────────────────────────────── function ProjectCard({ project }) { const isClient = project.type === "client"; const isBuilding = project.status === "building"; return (
{/* Header preview */} {isBuilding ? (
Build phase · {project.buildProgress}% complete
{isClient && (
Client
)}
) : (
{isClient ? "Client" : "My product"}
)}
{/* Identity row */}
{project.initial}
{project.label}
{isClient ? `${project.client} · ` : ""} {project.url || "Setting up pages…"}
{/* Cost strip — client + building */} {isClient && project.costs && isBuilding && (
Costs so far
${project.costs.total.toFixed(2)}
)} {/* Cost strip — client + live */} {isClient && project.costs && !isBuilding && (
Costs this month
${project.costs.total.toFixed(2)}
LLM ${project.costs.llm.toFixed(2)}
Compute ${project.costs.compute.toFixed(2)}
{!project.costs.billed && ( )}
)} {/* Stats */} {!isBuilding && project.stats && (
{[["visitors", project.stats.visitors], ["signups", project.stats.signups], ["MRR", project.stats.mrr]].map(([k, v]) => (
{v}
{k}
))}
)} {/* Actions */} {isBuilding ? ( ) : (
{[["⬡", "Build"], ["◈", "Grow"]].map(([icon, label]) => (
{icon} {label}
))}
)}
); } // ─── Projects screen ─────────────────────────────────────────────────────────── function ProjectsScreen({ setScreen }) { const totalUnbilled = PROJECTS .filter(p => p.type === "client" && p.costs?.billed === false) .reduce((s, p) => s + p.costs.total, 0); return (

Your projects

3 active · 1 building

{totalUnbilled > 0 && ( )} + New project
{PROJECTS.map(p => )} {/* New project CTA card */}
e.currentTarget.style.background = T.cream} onMouseLeave={e => e.currentTarget.style.background = "transparent"} >
+
New project
For yourself or a client
{/* Activity feed */}
Recent activity
{ACTIVITY.map((a, i) => (
{a.text}{" "}{a.detail && {a.detail}}
{a.time}
))}
); } // ─── Billing screen ──────────────────────────────────────────────────────────── function BillingScreen() { const [tab, setTab] = useState("billing"); const unbilled = BILLING_ROWS.filter(r => !r.billed).reduce((s, r) => s + r.total, 0); return (
{/* Sub-tabs */}
{[["billing", "Client billing"], ["costs", "Cost tracker"]].map(([id, label]) => ( ))}
{tab === "billing" && <>

Client billing

All costs tracked and ready to invoice

Generate invoice
{[ { label: "Total unbilled", value: `$${unbilled.toFixed(2)}` }, { label: "LLM costs", value: "$38.40" }, { label: "Compute", value: "$14.80" }, { label: "Other", value: "$7.40" }, ].map(c => (
{c.label}
{c.value}
))}
Breakdown by client
{["Project / Client", "LLM", "Compute", "Other", "Total", "Status"].map(h => (
{h}
))}
{BILLING_ROWS.map((r, i) => (
{r.initial}
{r.label}
{r.client}
${r.llm.toFixed(2)}
${r.compute.toFixed(2)}
${r.other.toFixed(2)}
${r.total.toFixed(2)}
{!r.billed && ( )}
))}
} {tab === "costs" && <>

Cost tracker

Every dollar spent, broken down by type and project

LLM usage
{[ { label: "Code generation", amount: 21.40, pct: 56 }, { label: "Content & marketing", amount: 10.20, pct: 27 }, { label: "Chat assist", amount: 6.80, pct: 18 }, ].map(r => (
{r.label} ${r.amount.toFixed(2)}
))}
Total LLM $38.40
Infrastructure
{[ { label: "Hosting & compute", amount: 11.60 }, { label: "Database", amount: 3.20 }, { label: "Email delivery", amount: 4.20 }, { label: "Domain & SSL", amount: 3.20 }, ].map(r => (
{r.label} ${r.amount.toFixed(2)}
))}
Total infra $22.20
Recent charges
{["Time", "Description", "Project", "Cost"].map(h => (
{h}
))}
{COST_LOG.map((row, i) => (
{row.time}
{row.desc}
{row.project}
${row.cost.toFixed(2)}
))}
}
); } // ─── Root ────────────────────────────────────────────────────────────────────── export default function Dashboard() { const [screen, setScreen] = useState("projects"); return (
); }