import { useState, useEffect, useRef } from "react";
const FontLoader = () => (
);
/* ─── DATA ─── */
const projects = [
{ id: 1, name: "Meridian", desc: "Client portal for boutique agencies", status: "building", progress: 68, features: 12, phase: "Frontend Gen", lastActive: "2h ago", color: "#3d5afe", domain: "meridian-app.stackless.dev", repo: "stackless/meridian-build", created: "Jan 12, 2026" },
{ id: 2, name: "Tidepool", desc: "Marine research data platform", status: "prd", progress: 45, features: 7, phase: "Features", lastActive: "20m ago", color: "#00897b", domain: null, repo: null, created: "Feb 3, 2026" },
{ id: 3, name: "Canopy", desc: "Internal team knowledge base", status: "live", progress: 100, features: 18, phase: "Deployed", lastActive: "1d ago", color: "#2e7d32", domain: "canopy.stackless.dev", customDomain: "kb.acmecorp.com", repo: "stackless/canopy-build", created: "Nov 28, 2025" },
{ id: 4, name: "Foxglove", desc: "Prescription mgmt for pharmacies", status: "prd", progress: 20, features: 3, phase: "Discovery", lastActive: "now", color: "#e65100", domain: null, repo: null, created: "Feb 27, 2026" },
];
const activityFeed = [
{ time: "2 min ago", project: "Foxglove", action: "Atlas completed Users & Personas phase", type: "atlas" },
{ time: "18 min ago", project: "Foxglove", action: "You described the core prescription workflow", type: "user" },
{ time: "1h ago", project: "Meridian", action: "Build: Dashboard UI component generated", type: "build" },
{ time: "2h ago", project: "Meridian", action: "Build: Authentication system passed all tests", type: "build" },
{ time: "3h ago", project: "Tidepool", action: "Atlas captured 7 features in MoSCoW framework", type: "atlas" },
{ time: "5h ago", project: "Tidepool", action: "You approved Problem Statement section", type: "user" },
{ time: "8h ago", project: "Meridian", action: "Build: Database schema deployed", type: "build" },
{ time: "1d ago", project: "Canopy", action: "Custom domain kb.acmecorp.com verified and active", type: "deploy" },
{ time: "1d ago", project: "Canopy", action: "v1.2 deployed — added search filters", type: "deploy" },
{ time: "2d ago", project: "Meridian", action: "PRD approved — build pipeline started", type: "deploy" },
{ time: "2d ago", project: "Tidepool", action: "Project created", type: "user" },
{ time: "3d ago", project: "Foxglove", action: "Project created", type: "user" },
];
const chatHistory = [
{ from: "atlas", text: "I see you're building Foxglove — prescription management for small pharmacies. We've locked in the problem statement and identified your primary user.\n\nNow let's map the core workflow. When a pharmacist opens Foxglove first thing in the morning, what do they need to see?" },
{ from: "user", text: "They need to see incoming prescriptions from doctors. The current systems are super clunky. They want to see new scripts, verify them, and mark them as filled." },
{ from: "atlas", text: "Clean workflow. Three stages:\n\n1. Receive — new scripts appear in a queue\n2. Verify — check dosage, interactions, patient history\n3. Fill — mark dispensed, update stock\n\nTwo things I want to nail down: does the pharmacist need to message the prescribing doctor back through Foxglove if there's a dosage flag? And are we building for single-location pharmacies or chains with 2–3 stores?" },
];
const prdData = [
{ name: "Executive Summary", status: "done", pct: 100 },
{ name: "Problem Statement", status: "done", pct: 100 },
{ name: "Users & Personas", status: "done", pct: 100 },
{ name: "User Flows", status: "active", pct: 60 },
{ name: "Feature Requirements", status: "pending", pct: 20 },
{ name: "Screen Specs", status: "pending", pct: 0 },
{ name: "Business Model", status: "pending", pct: 0 },
{ name: "Non-Functional Reqs", status: "pending", pct: 0 },
{ name: "Risks", status: "pending", pct: 0 },
];
const discoveryPhases = [
{ name: "Big Picture", done: true },
{ name: "Users", done: true },
{ name: "Features", active: true },
{ name: "Business Model" },
{ name: "Screens" },
{ name: "Risks" },
];
/* ─── Micro Components ─── */
const Tag = ({ children, color = "#1a1a1a", bg = "#1a1a1a10" }) => (
{children}
);
const StatusDot = ({ status }) => {
const c = status === "live" ? "#2e7d32" : status === "building" ? "#3d5afe" : "#d4a04a";
return ;
};
const SectionLabel = ({ children }) => (
{children}
);
const Card = ({ children, style: s = {}, hover = true, ...rest }) => {
const [hovered, setHovered] = useState(false);
return (
setHovered(true)} onMouseLeave={() => setHovered(false)}
style={{ background: "#fff", border: `1px solid ${hovered && hover ? "#d0ccc4" : "#e8e4dc"}`, borderRadius: 10, boxShadow: hovered && hover ? "0 2px 8px #1a1a1a0a" : "0 1px 2px #1a1a1a05", transition: "all 0.15s", ...s }}
{...rest}
>{children}
);
};
const Btn = ({ children, variant = "primary", style: s = {}, ...rest }) => {
const styles = variant === "primary"
? { background: "#1a1a1a", color: "#fff", border: "1px solid #1a1a1a" }
: variant === "secondary"
? { background: "#fff", color: "#1a1a1a", border: "1px solid #e0dcd4" }
: { background: "transparent", color: "#a09a90", border: "1px solid transparent" };
return (
);
};
const InputField = ({ label, value, onChange, placeholder, type = "text", mono = false }) => (
);
const Toggle = ({ on, onToggle, label }) => (
);
/* ─── SIDEBAR ─── */
const Sidebar = ({ activeProject, setActiveProject, view, setView }) => (
);
/* ─── ACTIVITY PAGE ─── */
const ActivityPage = ({ setActiveProject, setView }) => {
const [filter, setFilter] = useState("all");
const filtered = filter === "all" ? activityFeed : activityFeed.filter(a => a.type === filter);
const typeIcon = (t) => t === "atlas" ? "A" : t === "build" ? "⚡" : t === "deploy" ? "▲" : "●";
const typeColor = (t) => t === "atlas" ? "#1a1a1a" : t === "build" ? "#3d5afe" : t === "deploy" ? "#2e7d32" : "#8a8478";
return (
Activity
Everything happening across your projects
{/* Filters */}
{[
{ id: "all", label: "All" },
{ id: "atlas", label: "Atlas" },
{ id: "build", label: "Builds" },
{ id: "deploy", label: "Deploys" },
{ id: "user", label: "You" },
].map(f => (
))}
{/* Feed */}
{/* Timeline line */}
{filtered.map((item, i) => (
e.currentTarget.style.background = "#fff"}
onMouseLeave={e => e.currentTarget.style.background = "transparent"}
>
{/* Dot on timeline */}
·
{item.time}
{item.action}
))}
);
};
/* ─── SETTINGS PAGE ─── */
const SettingsPage = () => {
const [settingsTab, setSettingsTab] = useState("account");
const [emailNotifs, setEmailNotifs] = useState(true);
const [buildNotifs, setBuildNotifs] = useState(true);
const [atlasDigest, setAtlasDigest] = useState(false);
const [darkMode, setDarkMode] = useState(false);
return (
{/* Settings nav */}
Settings
{[
{ id: "account", label: "Account" },
{ id: "notifications", label: "Notifications" },
{ id: "billing", label: "Plan & Billing" },
{ id: "team", label: "Team" },
{ id: "domains", label: "Domains" },
{ id: "api", label: "API Keys" },
{ id: "danger", label: "Danger Zone" },
].map(t => (
))}
{/* Settings content */}
{settingsTab === "account" && (
Account
Manage your profile and preferences
M
Michael
michael@example.com
Change photo
{}} />
{}} type="email" />
{}} placeholder="Optional" />
Save changes
Preferences
Customize your workspace
setDarkMode(!darkMode)} label="Dark mode" />
Default project view
Atlas personality
)}
{settingsTab === "notifications" && (
Notifications
Choose what you hear about and when
setEmailNotifs(!emailNotifs)} label="Email notifications" />
setBuildNotifs(!buildNotifs)} label="Build completion alerts" />
setAtlasDigest(!atlasDigest)} label="Daily Atlas digest" />
Notification frequency
)}
{settingsTab === "billing" && (
Plan & Billing
Manage your subscription and usage
{[
{ label: "Projects", value: "10", used: "4" },
{ label: "Builds/mo", value: "20", used: "3" },
{ label: "Deploys", value: "Unlimited", used: "—" },
].map((m, i) => (
{m.label}
{m.used}
/ {m.value}
))}
Payment method
•••• 4242 — expires 08/27
Update
)}
{settingsTab === "team" && (
Team
Manage collaborators and permissions
{[
{ name: "Michael", email: "michael@example.com", role: "Owner" },
{ name: "Craig F.", email: "craig@example.com", role: "Editor" },
].map((m, i) => (
))}
+ Invite team member
)}
{settingsTab === "domains" && (
Domains
Custom domains for your deployed projects
+ Add custom domain
)}
{settingsTab === "api" && (
API Keys
Access your projects programmatically
Production key
sk_live_••••••••••••3kF9
Reveal
Test key
sk_test_••••••••••••7mR2
Reveal
+ Generate new key
)}
{settingsTab === "danger" && (
Danger Zone
Irreversible actions
Delete account
Permanently remove your account and all projects
Delete
)}
);
};
/* ─── PROJECT DETAIL ─── */
const ProjectDetail = ({ project }) => {
const [tab, setTab] = useState("chat");
const [msgs, setMsgs] = useState(chatHistory);
const [input, setInput] = useState("");
const [typing, setTyping] = useState(false);
const endRef = useRef(null);
useEffect(() => { endRef.current?.scrollIntoView({ behavior: "smooth" }); }, [msgs, typing]);
const send = () => {
if (!input.trim()) return;
setMsgs(p => [...p, { from: "user", text: input }]);
setInput("");
setTyping(true);
setTimeout(() => {
setTyping(false);
setMsgs(p => [...p, { from: "atlas", text: "Good instinct. For multi-location, the core question is inventory: shared pool vs per-store tracking.\n\nOption A — Shared inventory. Simpler, but Store B can't trust the count if Store A just dispensed.\n\nOption B — Per-location with transfers. Accurate, adds a \"request stock\" workflow.\n\nMost independents start single-location and add multi-store as v2. Want to scope it that way?" }]);
}, 2000);
};
const prdPct = Math.round(prdData.reduce((a, s) => a + s.pct, 0) / prdData.length);
return (
{/* Header */}
{project.name[0]}
{project.name}
{project.status === "live" ? "Live" : project.status === "building" ? "Building" : "Defining"}
{project.desc}
{project.progress}%
{/* Tabs */}
{[
{ id: "chat", label: "Atlas" },
{ id: "prd", label: "PRD" },
{ id: "build", label: "Build" },
{ id: "deploy", label: "Deploy" },
{ id: "projsettings", label: "Settings" },
].map(t => (
))}
{/* CHAT */}
{tab === "chat" && (
{msgs.map((m, i) => (
= chatHistory.length ? "enter 0.3s ease" : `enter 0.35s ease ${i * 0.08}s both` }}>
{m.from === "atlas" ? "A" : "M"}
{m.from === "atlas" ? "Atlas" : "You"}
{m.text.split(/(\*\*.*?\*\*)/).map((seg, j) => seg.startsWith("**") && seg.endsWith("**") ? {seg.slice(2, -2)} : seg)}
))}
{typing && (
)}
)}
{/* PRD */}
{tab === "prd" && (
{prdPct}%
{prdData.filter(s => s.status === "done").length}/{prdData.length} approved
{prdData.map((s, i) => (
e.currentTarget.style.borderColor = "#d0ccc4"}
onMouseLeave={e => e.currentTarget.style.borderColor = "#e8e4dc"}>
{s.status === "done" ? "✓" : s.status === "active" ? "◐" : "○"}
{s.name}
{s.pct}%
))}
)}
{/* BUILD */}
{tab === "build" && (
{project.status === "prd" ? (
🔒
Complete your PRD first
Approve all sections with Atlas, then the builder unlocks automatically.
{prdPct}%complete
) : (
Build progress
{["Auth System", "Database", "Dashboard UI", "Rx Queue", "Inventory", "API"].map((f, i) => {
const pct = Math.max(0, Math.min(100, project.progress + (i * -12)));
return (
= 100 ? "live" : pct > 0 ? "building" : "prd"} />
{f}
= 100 ? "#2e7d32" : "#3d5afe" }} />
{pct}%
);
})}
)}
)}
{/* DEPLOY */}
{tab === "deploy" && (
Deployment
Links, environments, and hosting for {project.name}
{/* URLs card */}
Project URLs
{project.domain ? (
<>
{project.customDomain && (
●
Production
{project.customDomain}
SSL Active
Open ↗
)}
⚙
Build repo
{project.repo}
View ↗
>
) : (
No deployment yet — complete your PRD and build to get a live URL.
{project.progress}% to deployment
)}
{/* Custom domain */}
{project.domain && !project.customDomain && (
Custom Domain
Point your own domain to this project. We'll handle SSL certificates automatically.
Connect
)}
{/* Environment vars */}
Environment Variables
{project.domain ? (
<>
{[
{ key: "DATABASE_URL", val: "••••••••••••" },
{ key: "API_SECRET", val: "••••••••••••" },
{ key: "SMTP_HOST", val: "mail.stackless.dev" },
].map((env, i) => (
{env.key}
{env.val}
))}
+ Add variable
>
) : (
Available after first build completes.
)}
{/* Deploy history */}
Deploy History
{project.status === "live" ? (
<>
{[
{ version: "v1.2", time: "1 day ago", status: "live", note: "Added search filters" },
{ version: "v1.1", time: "5 days ago", status: "previous", note: "Bug fix: auth timeout" },
{ version: "v1.0", time: "2 weeks ago", status: "previous", note: "Initial launch" },
].map((d, i) => (
{d.version}
{d.note}
{d.time}
{d.status === "live" && Current}
))}
>
) : project.domain ? (
First deploy will appear here once the build completes.
) : (
No deploys yet.
)}
)}
{/* PROJECT SETTINGS */}
{tab === "projsettings" && (
Project Settings
Configure {project.name}
General
{}} />
Save
Collaborators
+ Invite to project
Export
Download your PRD or project data for external use.
Export PRD as PDF
Export as JSON
Delete project
This action cannot be undone
Delete
)}
{/* Right panel */}
Discovery
{discoveryPhases.map((ph, i) => (
{ph.done ? "✓" : ph.active ? "→" : i + 1}
{ph.name}
))}
Captured
{[
{ k: "Users", v: "Pharmacist" },
{ k: "Workflow", v: "Receive → Verify → Fill" },
{ k: "Scope", v: "Single-location MVP" },
{ k: "Open", v: "Multi-location support?" },
].map((item, i) => (
))}
Project Info
{[
{ k: "Created", v: project.created },
{ k: "Last active", v: project.lastActive },
{ k: "Features", v: `${project.features} defined` },
].map((item, i) => (
))}
);
};
/* ─── DASHBOARD ─── */
const Home = ({ setActiveProject, setView }) => {
const [showNew, setShowNew] = useState(false);
return (
Projects
4 total · 2 in definition · 1 building · 1 live
setShowNew(!showNew)} style={{ display: "flex", alignItems: "center", gap: 6 }}>
+ New project
{showNew && (
A
Atlas
product strategist
Tell me what you want to build. One sentence is fine — I'll ask the right questions to figure out the rest.
Start →
)}
{projects.map((p, i) => (
))}
);
};
/* ─── ROOT ─── */
export default function Stackless() {
const [view, setView] = useState("home");
const [activeProject, setActiveProject] = useState(null);
return (
{view === "home" && !activeProject &&
}
{view === "activity" &&
}
{view === "settings" &&
}
{activeProject &&
}
);
}