design: add dynamic design-style layout selector for saas, marketplace, and websites

This commit is contained in:
2026-06-08 11:23:01 -07:00
parent fa2e08ea42
commit 32124555ab

View File

@@ -18,7 +18,7 @@ import {
// Entrepreneur path — 4 steps. Each step is a focused question.
const ENTREP_TOTAL = 4;
const ENTREP_STEP_NAMES = ["Type", "Idea", "Goal", "Look"];
const ENTREP_STEP_NAMES = ["Type", "Idea", "Style", "Look"];
const IDEA_PROMPTS = [
"A community for indie game devs to swap playtesters, with weekly demo nights",
@@ -172,62 +172,88 @@ function EntrepType({ value, onChange }) {
);
}
const GOALS = [
const SAAS_STYLES = [
{
id: "first_customer",
icon: "🎯",
label: "First real customer",
desc: "Someone I don't know pays me. Even once.",
id: "sidebar",
label: "Vertical Sidebar",
desc: "Left-side collapsible menu, data-dense. Ideal for CRM/dashboards.",
},
{
id: "ten_users",
icon: "👥",
label: "Ten weekly users",
desc: "A signal the thing actually does something useful.",
id: "topbar",
label: "Top Horizontal + ⌘K",
desc: "Spacious top navigation with global command search bar.",
},
{
id: "mrr_1k",
icon: "📈",
label: "$1k MRR",
desc: "Enough to take it seriously.",
},
{
id: "side_quit",
icon: "🚪",
label: "Replace my day job",
desc: "The long road. Make this the main thing.",
},
{
id: "audience",
icon: "📣",
label: "Build a tiny audience",
desc: "200 emails, a community, something I can talk to.",
},
{
id: "ship_it",
icon: "🚀",
label: "Just ship it",
desc: "I want the thing to exist.",
id: "rail",
label: "Slim Icon Rail",
desc: "Minimalist vertical narrow icon bar, maximizes workspace area.",
},
];
function EntrepGoal({ value, onChange }) {
const MARKETPLACE_STYLES = [
{
id: "flux",
label: "Dark Glass / Flux",
desc: "Modern dark-glass panels with glowing fuchsia aurora backdrops.",
},
{
id: "minimal",
label: "Classic Minimal",
desc: "Warm parchment neutrals, high-contrast typography and clean grids.",
},
];
const GENERAL_STYLES = [
{
id: "bento",
label: "Dark Bento",
desc: "Modern dark UI, bento-box card clusters.",
},
{
id: "swiss",
label: "Editorial Swiss",
desc: "Type-led, gridded, lots of white space — clean and academic.",
},
{
id: "brutalist",
label: "Neo-Brutalist",
desc: "Bold offsets, thick hand-drawn borders, highly tactile and organic.",
},
];
function EntrepStyle({ productType, value, onChange }) {
// Dynamically tailor the styles array based on what they picked on Page 2
const isSaas = productType === "saas";
const isMarketplace = productType === "marketplace";
const styles = isSaas
? SAAS_STYLES
: isMarketplace
? MARKETPLACE_STYLES
: GENERAL_STYLES;
return (
<>
<WizardQ
title="What does “working” look like?"
sub="Helps Vibn decide what to build first — a landing page that converts, or a tool that retains."
title="Choose a starting design style"
sub={
isSaas
? "Select the navigation layout that fits your app's density."
: isMarketplace
? "Select the design aesthetic for your marketplace templates."
: "Select the design layout for your custom pages."
}
/>
<PresetGroup
options={GOALS.map((g) => ({
id: g.id,
label: g.label,
desc: g.desc,
icon: <span style={{ fontSize: 14 }}>{g.icon}</span>,
options={styles.map((s) => ({
id: s.id,
label: s.label,
desc: s.desc,
icon: undefined,
}))}
value={value}
onChange={onChange}
columns={2}
columns={styles.length === 3 ? 1 : 2}
/>
</>
);
@@ -387,9 +413,13 @@ export function EntrepreneurPath({
canNext = (data.idea || "").trim().length >= 8;
} else if (step === 2) {
body = (
<EntrepGoal value={data.goal} onChange={(v) => onUpdate({ goal: v })} />
<EntrepStyle
productType={data.productType}
value={data.designStyle || ""}
onChange={(v) => onUpdate({ designStyle: v })}
/>
);
canNext = !!data.goal;
canNext = !!data.designStyle;
} else {
body = (
<EntrepVibe value={data.vibe} onChange={(v) => onUpdate({ vibe: v })} />