Files
vibn-frontend/components/design-scaffolds.tsx
Mark Henderson 16766f587d feat: full palette themes for DaisyUI and HeroUI marketing scaffolds
DaisyUI scaffold now has 12 named themes (Dark, Light, Cupcake, Bee,
Synthwave, Cyberpunk, Retro, Dracula, Night, Forest, Coffee, Winter).
Each theme changes the page background, card bg, text, borders, and
primary color — swatch shows a split circle of bg+primary so you can
preview the full palette at a glance.

HeroUI marketing scaffold has 6 prebuilt themes (Purple, Blue, Teal,
Rose, Dark, Modern) matching heroui.com/themes.

ThemeColor type now supports optional bg/cardBg/textColor/borderColor/
mutedText fields for full-page dark/light palette overrides.

Made-with: Cursor
2026-03-02 13:58:02 -08:00

1151 lines
70 KiB
TypeScript

"use client";
import { useState } from "react";
/**
* Design scaffolds — styled React mockups showing what each UI library
* looks like for a given surface. Used in the Design page preview area.
*
* Each scaffold is rendered at its natural size inside a scaled container,
* giving the user a realistic feel for the library's visual language.
*/
// ---------------------------------------------------------------------------
// Shared mock data
// ---------------------------------------------------------------------------
const TABLE_ROWS = [
{ name: "Alice Martin", email: "alice@co.com", role: "Admin", status: "Active", date: "Jan 12" },
{ name: "Ben Walsh", email: "ben@co.com", role: "Member", status: "Pending", date: "Jan 14" },
{ name: "Clara Kim", email: "clara@co.com", role: "Member", status: "Active", date: "Jan 15" },
{ name: "David Osei", email: "david@co.com", role: "Viewer", status: "Inactive", date: "Jan 16" },
];
type Page = "Dashboard" | "Users" | "Settings";
// ---------------------------------------------------------------------------
// Theme color definitions
// ---------------------------------------------------------------------------
export interface ThemeColor {
id: string;
label: string;
primary: string; // button bg, active dot, toggle on
primaryFg: string; // text on primary bg
activeBg: string; // sidebar active item bg
activeFg: string; // sidebar active item text
ring: string; // focus ring / subtle tint
// optional full-page palette (used by DaisyUI & dark themes)
bg?: string;
cardBg?: string;
textColor?: string;
borderColor?: string;
mutedText?: string;
}
export const SHADCN_THEMES: ThemeColor[] = [
{ id: "neutral", label: "Neutral", primary: "#18181b", primaryFg: "#fff", activeBg: "#f4f4f5", activeFg: "#18181b", ring: "#e4e4e7" },
{ id: "blue", label: "Blue", primary: "#3b82f6", primaryFg: "#fff", activeBg: "#eff6ff", activeFg: "#1d4ed8", ring: "#bfdbfe" },
{ id: "green", label: "Green", primary: "#22c55e", primaryFg: "#fff", activeBg: "#f0fdf4", activeFg: "#15803d", ring: "#bbf7d0" },
{ id: "orange", label: "Orange", primary: "#f97316", primaryFg: "#fff", activeBg: "#fff7ed", activeFg: "#c2410c", ring: "#fed7aa" },
{ id: "red", label: "Red", primary: "#ef4444", primaryFg: "#fff", activeBg: "#fef2f2", activeFg: "#b91c1c", ring: "#fecaca" },
{ id: "rose", label: "Rose", primary: "#f43f5e", primaryFg: "#fff", activeBg: "#fff1f2", activeFg: "#be123c", ring: "#fecdd3" },
{ id: "violet", label: "Violet", primary: "#8b5cf6", primaryFg: "#fff", activeBg: "#f5f3ff", activeFg: "#6d28d9", ring: "#ddd6fe" },
{ id: "yellow", label: "Yellow", primary: "#eab308", primaryFg: "#000", activeBg: "#fefce8", activeFg: "#a16207", ring: "#fef08a" },
];
export const MANTINE_THEMES: ThemeColor[] = [
{ id: "blue", label: "Blue", primary: "#228be6", primaryFg: "#fff", activeBg: "#e7f5ff", activeFg: "#1971c2", ring: "#a5d8ff" },
{ id: "teal", label: "Teal", primary: "#12b886", primaryFg: "#fff", activeBg: "#e6fcf5", activeFg: "#087f5b", ring: "#96f2d7" },
{ id: "violet", label: "Violet", primary: "#7950f2", primaryFg: "#fff", activeBg: "#f3f0ff", activeFg: "#5f3dc4", ring: "#d0bfff" },
{ id: "red", label: "Red", primary: "#fa5252", primaryFg: "#fff", activeBg: "#fff5f5", activeFg: "#c92a2a", ring: "#ffc9c9" },
{ id: "orange", label: "Orange", primary: "#fd7e14", primaryFg: "#fff", activeBg: "#fff4e6", activeFg: "#d9480f", ring: "#ffd8a8" },
{ id: "green", label: "Green", primary: "#40c057", primaryFg: "#fff", activeBg: "#ebfbee", activeFg: "#2f9e44", ring: "#b2f2bb" },
];
export const HEROUI_THEMES: ThemeColor[] = [
{ id: "violet", label: "Violet", primary: "#7c3aed", primaryFg: "#fff", activeBg: "rgba(124,58,237,0.3)", activeFg: "#c084fc", ring: "rgba(168,85,247,0.3)" },
{ id: "blue", label: "Blue", primary: "#2563eb", primaryFg: "#fff", activeBg: "rgba(37,99,235,0.3)", activeFg: "#93c5fd", ring: "rgba(59,130,246,0.3)" },
{ id: "rose", label: "Rose", primary: "#e11d48", primaryFg: "#fff", activeBg: "rgba(225,29,72,0.3)", activeFg: "#fda4af", ring: "rgba(244,63,94,0.3)" },
{ id: "green", label: "Green", primary: "#16a34a", primaryFg: "#fff", activeBg: "rgba(22,163,74,0.3)", activeFg: "#86efac", ring: "rgba(34,197,94,0.3)" },
{ id: "orange", label: "Orange", primary: "#ea580c", primaryFg: "#fff", activeBg: "rgba(234,88,12,0.3)", activeFg: "#fdba74", ring: "rgba(249,115,22,0.3)" },
];
// DaisyUI named themes — each has a full page palette
export const DAISY_THEMES: ThemeColor[] = [
{ id: "dark", label: "Dark", primary: "#793ef9", primaryFg: "#fff", activeBg: "rgba(121,62,249,0.2)", activeFg: "#a78bfa", ring: "#4c1d95", bg: "#1d232a", cardBg: "#191e24", textColor: "#a6adba", borderColor: "#2a323c", mutedText: "#6b7280" },
{ id: "light", label: "Light", primary: "#570df8", primaryFg: "#fff", activeBg: "#f3f0ff", activeFg: "#4c1d95", ring: "#ddd6fe", bg: "#fff", cardBg: "#fff", textColor: "#1f2937", borderColor: "#e5e7eb", mutedText: "#6b7280" },
{ id: "cupcake", label: "Cupcake", primary: "#65c3c8", primaryFg: "#291334", activeBg: "#d9f5f6", activeFg: "#0e6b70", ring: "#a7eaec", bg: "#faf7f5", cardBg: "#fff", textColor: "#291334", borderColor: "#e9e3df", mutedText: "#9ca3af" },
{ id: "bumblebee", label: "Bee", primary: "#e0a82e", primaryFg: "#1f2937", activeBg: "#fef9e5", activeFg: "#92650a", ring: "#fde68a", bg: "#fff", cardBg: "#fff", textColor: "#1f2937", borderColor: "#e5e7eb", mutedText: "#6b7280" },
{ id: "synthwave", label: "Synth", primary: "#e779c1", primaryFg: "#2d1b69", activeBg: "rgba(231,121,193,0.2)",activeFg: "#f0abdc", ring: "#701a75", bg: "#1a103c", cardBg: "#221551", textColor: "#e2e8f0", borderColor: "#4c3585", mutedText: "#a78bfa" },
{ id: "cyberpunk", label: "Cyber", primary: "#ff7598", primaryFg: "#1f2937", activeBg: "#fff0f3", activeFg: "#9d174d", ring: "#fca5a5", bg: "#ffee00", cardBg: "#fff", textColor: "#1f2937", borderColor: "#1f2937", mutedText: "#374151" },
{ id: "retro", label: "Retro", primary: "#ef9995", primaryFg: "#282425", activeBg: "#fde8e7", activeFg: "#7f1d1d", ring: "#fca5a5", bg: "#e4d8b4", cardBg: "#f7f0d8", textColor: "#282425", borderColor: "#d4b483", mutedText: "#6b5745" },
{ id: "dracula", label: "Dracula", primary: "#ff79c6", primaryFg: "#282a36", activeBg: "rgba(255,121,198,0.15)",activeFg: "#ff79c6",ring: "#bd93f9", bg: "#282a36", cardBg: "#343746", textColor: "#f8f8f2", borderColor: "#44475a", mutedText: "#6272a4" },
{ id: "night", label: "Night", primary: "#38bdf8", primaryFg: "#0c1a2b", activeBg: "rgba(56,189,248,0.15)",activeFg: "#38bdf8", ring: "#0284c7", bg: "#1d232a", cardBg: "#191e24", textColor: "#a6adba", borderColor: "#2a323c", mutedText: "#4b5563" },
{ id: "forest", label: "Forest", primary: "#1eb854", primaryFg: "#fff", activeBg: "rgba(30,184,84,0.15)", activeFg: "#1eb854", ring: "#15803d", bg: "#171212", cardBg: "#1d1d1d", textColor: "#d1d5db", borderColor: "#292929", mutedText: "#4b5563" },
{ id: "coffee", label: "Coffee", primary: "#db924b", primaryFg: "#20150e", activeBg: "rgba(219,146,75,0.15)",activeFg: "#db924b", ring: "#92400e", bg: "#20150e", cardBg: "#2a1c12", textColor: "#d1b59c", borderColor: "#3d261a", mutedText: "#78523a" },
{ id: "winter", label: "Winter", primary: "#047aed", primaryFg: "#fff", activeBg: "#e0f0ff", activeFg: "#0369a1", ring: "#bae6fd", bg: "#fff", cardBg: "#f0f9ff", textColor: "#1e3a5f", borderColor: "#bae6fd", mutedText: "#64748b" },
];
export const TREMOR_THEMES: ThemeColor[] = [
{ id: "blue", label: "Blue", primary: "#2563eb", primaryFg: "#fff", activeBg: "#eff6ff", activeFg: "#1d4ed8", ring: "#bfdbfe" },
{ id: "indigo", label: "Indigo", primary: "#4f46e5", primaryFg: "#fff", activeBg: "#eef2ff", activeFg: "#3730a3", ring: "#c7d2fe" },
{ id: "teal", label: "Teal", primary: "#0d9488", primaryFg: "#fff", activeBg: "#f0fdfa", activeFg: "#0f766e", ring: "#99f6e4" },
{ id: "rose", label: "Rose", primary: "#e11d48", primaryFg: "#fff", activeBg: "#fff1f2", activeFg: "#be123c", ring: "#fecdd3" },
{ id: "amber", label: "Amber", primary: "#d97706", primaryFg: "#fff", activeBg: "#fffbeb", activeFg: "#92400e", ring: "#fde68a" },
];
// Small swatch strip rendered inside each scaffold's header
function ThemeSwatches({ themes, selected, onSelect }: {
themes: ThemeColor[];
selected: ThemeColor;
onSelect: (t: ThemeColor) => void;
}) {
return (
<div className="flex items-center gap-1 flex-wrap">
{themes.map(t => (
<button
key={t.id}
title={t.label}
onClick={() => onSelect(t)}
className="w-4 h-4 rounded-full transition-transform hover:scale-110 border"
style={{
background: t.bg ? `linear-gradient(135deg, ${t.bg} 50%, ${t.primary} 50%)` : t.primary,
borderColor: selected.id === t.id ? t.primary : "transparent",
outline: selected.id === t.id ? `2px solid ${t.primary}` : "none",
outlineOffset: 2,
}}
/>
))}
</div>
);
}
// ---------------------------------------------------------------------------
// WEB APP — shadcn
// ---------------------------------------------------------------------------
function ShadcnDashboard({ t }: { t: ThemeColor }) {
return (
<div className="flex-1 p-5 bg-zinc-50 overflow-auto">
<div className="grid grid-cols-3 gap-3 mb-4">
{["Total Revenue", "Active Users", "Conversions"].map((label, i) => (
<div key={label} className="bg-white rounded-lg border p-3">
<p className="text-[10px] text-zinc-500 mb-1">{label}</p>
<p className="text-lg font-bold text-zinc-900">{["$12,400", "2,841", "18.2%"][i]}</p>
<p className="text-[10px] text-zinc-400">+{[12, 8, 3][i]}% from last month</p>
</div>
))}
</div>
<div className="bg-white rounded-lg border mb-3">
<div className="px-4 py-3 border-b"><span className="text-xs font-semibold text-zinc-700">Revenue</span></div>
<div className="p-4 flex items-end gap-1.5 h-24">
{[40,60,45,75,65,85,70,90,55,80,75,95].map((h,i)=>(
<div key={i} className="flex-1 rounded-sm" style={{ height:`${h}%`, background: i===11 ? t.primary : t.ring }} />
))}
</div>
</div>
<div className="bg-white rounded-lg border">
<div className="px-4 py-3 border-b"><span className="text-xs font-semibold text-zinc-700">Recent activity</span></div>
{TABLE_ROWS.slice(0,3).map(r=>(
<div key={r.name} className="flex items-center gap-3 px-4 py-2.5 border-b last:border-0">
<div className="w-6 h-6 rounded-full bg-zinc-200 shrink-0" />
<div className="flex-1"><p className="text-[11px] font-medium text-zinc-800">{r.name}</p><p className="text-[10px] text-zinc-400">{r.email}</p></div>
<span className="px-1.5 py-0.5 rounded text-[9px] font-medium" style={r.status==="Active"?{background:t.activeBg,color:t.activeFg}:{background:"#f4f4f5",color:"#a1a1aa"}}>{r.status}</span>
</div>
))}
</div>
</div>
);
}
function ShadcnUsers({ t }: { t: ThemeColor }) {
return (
<div className="flex-1 p-5 bg-zinc-50 overflow-auto">
<div className="bg-white rounded-lg border">
<div className="px-4 py-3 border-b flex items-center justify-between">
<span className="text-xs font-semibold text-zinc-700">Team members</span>
<div className="flex gap-2">
<input className="h-7 px-2.5 rounded-md border border-zinc-200 text-[11px] outline-none w-32" placeholder="Search..." />
<div className="h-7 px-3 rounded-md text-[11px] flex items-center cursor-pointer" style={{ background: t.primary, color: t.primaryFg }}>Invite</div>
</div>
</div>
<table className="w-full text-[11px]">
<thead><tr className="border-b bg-zinc-50">{["Name","Role","Status","Joined",""].map(h=><th key={h} className="px-4 py-2 text-left text-[10px] text-zinc-500 font-medium">{h}</th>)}</tr></thead>
<tbody>{TABLE_ROWS.map(r=>(
<tr key={r.name} className="border-b last:border-0 hover:bg-zinc-50">
<td className="px-4 py-2.5">
<div className="flex items-center gap-2"><div className="w-5 h-5 rounded-full bg-zinc-200" /><div><p className="font-medium text-zinc-800">{r.name}</p><p className="text-[10px] text-zinc-400">{r.email}</p></div></div>
</td>
<td className="px-4 py-2.5"><span className="px-1.5 py-0.5 rounded border border-zinc-200 text-[9px] text-zinc-600">{r.role}</span></td>
<td className="px-4 py-2.5"><span className="px-1.5 py-0.5 rounded text-[9px] font-medium" style={r.status==="Active"?{background:t.primary,color:t.primaryFg}:r.status==="Pending"?{background:"#f4f4f5",color:"#71717a"}:{background:"#fafafa",color:"#a1a1aa"}}>{r.status}</span></td>
<td className="px-4 py-2.5 text-zinc-400">{r.date}</td>
<td className="px-4 py-2.5"><div className="h-6 px-2 rounded border border-zinc-200 text-[9px] flex items-center text-zinc-500 cursor-pointer w-fit">···</div></td>
</tr>
))}</tbody>
</table>
</div>
</div>
);
}
function ShadcnSettings({ t }: { t: ThemeColor }) {
return (
<div className="flex-1 p-5 bg-zinc-50 overflow-auto">
<div className="bg-white rounded-lg border mb-3">
<div className="px-4 py-3 border-b"><span className="text-xs font-semibold text-zinc-700">General</span></div>
<div className="p-4 space-y-3">
{[{l:"Workspace name",v:"Acme Inc"},{l:"Slug",v:"acme-inc"},{l:"Email",v:"admin@acme.com"}].map(f=>(
<div key={f.l}>
<label className="text-[10px] font-medium text-zinc-600 block mb-1">{f.l}</label>
<input defaultValue={f.v} className="w-full h-8 px-3 rounded-md border border-zinc-200 text-[11px] outline-none" style={{ outlineColor: t.primary }} />
</div>
))}
<div className="pt-1"><div className="h-7 px-3 rounded-md text-[11px] inline-flex items-center cursor-pointer" style={{ background: t.primary, color: t.primaryFg }}>Save changes</div></div>
</div>
</div>
<div className="bg-white rounded-lg border">
<div className="px-4 py-3 border-b"><span className="text-xs font-semibold text-zinc-700">Notifications</span></div>
<div className="p-4 space-y-3">
{["Email digests","Push notifications","Security alerts","Product updates"].map((label,i)=>(
<div key={label} className="flex items-center justify-between">
<div><p className="text-[11px] font-medium text-zinc-700">{label}</p><p className="text-[10px] text-zinc-400">Receive {label.toLowerCase()}</p></div>
<div className="w-8 h-4 rounded-full relative cursor-pointer" style={{ background: [true,false,true,false][i] ? t.primary : "#e4e4e7" }}>
<div className="absolute top-0.5 w-3 h-3 rounded-full bg-white shadow" style={{ transform: [true,false,true,false][i] ? "translateX(16px)" : "translateX(2px)" }} />
</div>
</div>
))}
</div>
</div>
</div>
);
}
export function WebAppShadcn() {
const [page, setPage] = useState<Page>("Dashboard");
const [theme, setTheme] = useState<ThemeColor>(SHADCN_THEMES[0]);
const NAV_ITEMS: { label: Page; icon: string }[] = [
{ label: "Dashboard", icon: "▦" },
{ label: "Users", icon: "◎" },
{ label: "Settings", icon: "⚙" },
];
return (
<div className="flex h-full bg-white font-sans text-sm">
{/* Sidebar */}
<div className="w-44 border-r flex flex-col py-4 px-3 gap-1 bg-white shrink-0">
<div className="flex items-center gap-2 px-2 mb-4">
<div className="w-6 h-6 rounded" style={{ background: theme.primary }} />
<span className="font-semibold text-zinc-900 text-xs">Acme Inc</span>
</div>
{NAV_ITEMS.map(({ label, icon }) => (
<button key={label} onClick={() => setPage(label)}
className="flex items-center gap-2 px-2 py-1.5 rounded-md text-xs cursor-pointer w-full text-left transition-colors"
style={page===label ? { background: theme.activeBg, color: theme.activeFg, fontWeight: 600 } : { color: "#71717a" }}>
<span className="text-[11px]">{icon}</span>{label}
</button>
))}
</div>
{/* Main */}
<div className="flex-1 flex flex-col min-w-0">
<div className="h-12 border-b flex items-center justify-between px-5 shrink-0">
<span className="font-semibold text-zinc-900 text-sm">{page}</span>
<div className="flex items-center gap-3">
<ThemeSwatches themes={SHADCN_THEMES} selected={theme} onSelect={setTheme} />
<div className="h-7 px-3 rounded-md border border-zinc-200 text-[11px] flex items-center text-zinc-600">Export</div>
<div className="h-7 px-3 rounded-md text-[11px] flex items-center" style={{ background: theme.primary, color: theme.primaryFg }}>+ New</div>
</div>
</div>
{page === "Dashboard" && <ShadcnDashboard t={theme} />}
{page === "Users" && <ShadcnUsers t={theme} />}
{page === "Settings" && <ShadcnSettings t={theme} />}
</div>
</div>
);
}
function MantineDashboard({ t }: { t: ThemeColor }) {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#f8f9fa" }}>
<div className="grid grid-cols-3 gap-3 mb-4">
{[{l:"Total Revenue",v:"$12,400",c:"#2f9e44"},{l:"Active Users",v:"2,841",c:"#228be6"},{l:"Conversions",v:"18.2%",c:"#e67700"}].map(item=>(
<div key={item.l} className="rounded-lg p-3" style={{ background:"#fff", border:"1px solid #e9ecef" }}>
<p className="text-[10px] mb-1" style={{ color:"#868e96" }}>{item.l}</p>
<p className="text-lg font-bold" style={{ color:"#212529" }}>{item.v}</p>
<p className="text-[10px]" style={{ color:item.c }}> trending up</p>
</div>
))}
</div>
<div className="rounded-lg mb-3" style={{ background:"#fff", border:"1px solid #e9ecef" }}>
<div className="px-4 py-3" style={{ borderBottom:"1px solid #e9ecef" }}><span className="text-xs font-semibold" style={{ color:"#212529" }}>Monthly revenue</span></div>
<div className="p-4 flex items-end gap-1.5 h-24">
{[40,60,45,75,65,85,70,90,55,80,75,95].map((h,i)=>(
<div key={i} className="flex-1 rounded-sm" style={{ height:`${h}%`, background:i===11?"#228be6":"#d0ebff" }} />
))}
</div>
</div>
<div className="rounded-lg" style={{ background:"#fff", border:"1px solid #e9ecef" }}>
<div className="px-4 py-3" style={{ borderBottom:"1px solid #e9ecef" }}><span className="text-xs font-semibold" style={{ color:"#212529" }}>Recent</span></div>
{TABLE_ROWS.slice(0,3).map(r=>(
<div key={r.name} className="flex items-center gap-3 px-4 py-2.5" style={{ borderBottom:"1px solid #f1f3f5" }}>
<div className="w-6 h-6 rounded-full shrink-0" style={{ background:"#d0ebff" }} />
<div className="flex-1"><p className="text-[11px] font-semibold" style={{ color:"#212529" }}>{r.name}</p><p className="text-[10px]" style={{ color:"#868e96" }}>{r.email}</p></div>
<span className="px-1.5 py-0.5 rounded text-[9px] font-medium" style={r.status==="Active"?{background:"#d3f9d8",color:"#2f9e44"}:{background:"#f1f3f5",color:"#868e96"}}>{r.status}</span>
</div>
))}
</div>
</div>
);
}
function MantineUsers({ t }: { t: ThemeColor }) {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#f8f9fa" }}>
<div className="rounded-lg" style={{ background:"#fff", border:"1px solid #e9ecef" }}>
<div className="px-4 py-3 flex items-center justify-between" style={{ borderBottom:"1px solid #e9ecef" }}>
<span className="text-xs font-semibold" style={{ color:"#212529" }}>Team members</span>
<div className="flex gap-2">
<input className="h-7 px-2.5 text-[11px] rounded" style={{ border:"1px solid #dee2e6", outline:"none", width:130 }} placeholder="Search members..." />
<button className="h-7 px-3 rounded text-[11px] font-medium" style={{ background: t.primary, color: t.primaryFg }}>+ Invite</button>
</div>
</div>
<table className="w-full text-[11px]">
<thead><tr style={{ borderBottom:"1px solid #e9ecef", background:"#f8f9fa" }}>{["Member","Role","Status","Joined","Actions"].map(h=><th key={h} className="px-4 py-2 text-left text-[10px] font-semibold" style={{ color:"#868e96" }}>{h}</th>)}</tr></thead>
<tbody>{TABLE_ROWS.map(r=>(
<tr key={r.name} style={{ borderBottom:"1px solid #f1f3f5" }}>
<td className="px-4 py-2.5"><div className="flex items-center gap-2"><div className="w-6 h-6 rounded-full" style={{ background: t.ring }} /><div><p className="font-semibold" style={{ color:"#212529" }}>{r.name}</p><p style={{ color:"#868e96" }}>{r.email}</p></div></div></td>
<td className="px-4 py-2.5"><span className="px-1.5 py-0.5 rounded text-[9px]" style={{ background: t.activeBg, color: t.activeFg }}>{r.role}</span></td>
<td className="px-4 py-2.5"><span className="px-1.5 py-0.5 rounded text-[9px] font-medium" style={r.status==="Active"?{background:"#d3f9d8",color:"#2f9e44"}:r.status==="Pending"?{background:"#fff3bf",color:"#e67700"}:{background:"#f1f3f5",color:"#868e96"}}>{r.status}</span></td>
<td className="px-4 py-2.5" style={{ color:"#adb5bd" }}>{r.date}</td>
<td className="px-4 py-2.5"><button className="text-[10px] px-2 py-1 rounded" style={{ border:"1px solid #dee2e6", color:"#495057" }}>Manage</button></td>
</tr>
))}</tbody>
</table>
</div>
</div>
);
}
function MantineSettings({ t }: { t: ThemeColor }) {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#f8f9fa" }}>
<div className="rounded-lg mb-3" style={{ background:"#fff", border:"1px solid #e9ecef" }}>
<div className="px-4 py-3" style={{ borderBottom:"1px solid #e9ecef" }}><span className="text-xs font-semibold" style={{ color:"#212529" }}>Workspace</span></div>
<div className="p-4 space-y-3">
{[{l:"Name",v:"Acme Inc"},{l:"Slug",v:"acme-inc"},{l:"Email",v:"admin@acme.com"}].map(f=>(
<div key={f.l}>
<label className="text-[10px] font-semibold block mb-1" style={{ color:"#495057" }}>{f.l}</label>
<input defaultValue={f.v} className="w-full h-8 px-3 rounded text-[11px]" style={{ border:"1px solid #dee2e6", outline:"none" }} />
</div>
))}
<button className="h-8 px-4 rounded text-[11px] font-medium" style={{ background: t.primary, color: t.primaryFg }}>Save</button>
</div>
</div>
<div className="rounded-lg" style={{ background:"#fff", border:"1px solid #e9ecef" }}>
<div className="px-4 py-3" style={{ borderBottom:"1px solid #e9ecef" }}><span className="text-xs font-semibold" style={{ color:"#212529" }}>Notifications</span></div>
<div className="p-4 space-y-3">
{["Email digests","Push notifications","Security alerts","Product updates"].map((label,i)=>(
<div key={label} className="flex items-center justify-between">
<div><p className="text-[11px] font-medium" style={{ color:"#212529" }}>{label}</p><p className="text-[10px]" style={{ color:"#868e96" }}>Get notified via {label.split(" ")[0].toLowerCase()}</p></div>
<div className="w-8 h-4 rounded-full relative cursor-pointer" style={{ background:[true,false,true,false][i] ? t.primary : "#dee2e6" }}>
<div className="absolute top-0.5 w-3 h-3 rounded-full bg-white shadow" style={{ transform:[true,false,true,false][i]?"translateX(16px)":"translateX(2px)" }} />
</div>
</div>
))}
</div>
</div>
</div>
);
}
export function WebAppMantine() {
const [page, setPage] = useState<Page>("Dashboard");
const [theme, setTheme] = useState<ThemeColor>(MANTINE_THEMES[0]);
const NAV: { label: Page; icon: string }[] = [
{ label: "Dashboard", icon: "▦" },
{ label: "Users", icon: "◎" },
{ label: "Settings", icon: "⚙" },
];
return (
<div className="flex h-full font-sans text-sm" style={{ background: "#f8f9fa" }}>
<div className="w-44 flex flex-col py-4 px-3 gap-0.5 shrink-0" style={{ background: "#fff", borderRight: "1px solid #e9ecef" }}>
<div className="flex items-center gap-2 px-2 mb-4">
<div className="w-6 h-6 rounded" style={{ background: theme.primary }} />
<span className="font-bold text-xs" style={{ color: theme.activeFg }}>Acme Inc</span>
</div>
{NAV.map(({ label, icon }) => (
<button key={label} onClick={() => setPage(label)}
className="flex items-center gap-2 px-2 py-2 rounded text-xs cursor-pointer w-full text-left"
style={page===label?{background: theme.activeBg, color: theme.activeFg, fontWeight:600}:{color:"#495057"}}>
<span>{icon}</span>{label}
</button>
))}
</div>
<div className="flex-1 flex flex-col min-w-0">
<div className="h-12 flex items-center justify-between px-5 shrink-0" style={{ background:"#fff", borderBottom:"1px solid #e9ecef" }}>
<span className="font-bold text-sm" style={{ color: "#212529" }}>{page}</span>
<div className="flex items-center gap-3">
<ThemeSwatches themes={MANTINE_THEMES} selected={theme} onSelect={setTheme} />
<button className="h-7 px-3 rounded text-[11px] font-medium" style={{ border:"1px solid #dee2e6", color:"#495057" }}>Export</button>
<button className="h-7 px-3 rounded text-[11px] font-medium" style={{ background: theme.primary, color: theme.primaryFg }}>+ New</button>
</div>
</div>
{page === "Dashboard" && <MantineDashboard t={theme} />}
{page === "Users" && <MantineUsers t={theme} />}
{page === "Settings" && <MantineSettings t={theme} />}
</div>
</div>
);
}
function HeroUIDashboard() {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#fafafa" }}>
<div className="grid grid-cols-3 gap-3 mb-4">
{["Revenue","Users","Conversion"].map((label,i)=>(
<div key={label} className="rounded-2xl p-3" style={{ background:"#fff", boxShadow:"0 2px 8px rgba(0,0,0,0.06)", border:"1px solid #f4f4f5" }}>
<p className="text-[10px] mb-1" style={{ color:"#a1a1aa" }}>{label}</p>
<p className="text-lg font-bold" style={{ color:"#18181b" }}>{["$12,400","2,841","18.2%"][i]}</p>
<p className="text-[10px]" style={{ color:"#a855f7" }}>+{[12,8,3][i]}% this month</p>
</div>
))}
</div>
<div className="rounded-2xl mb-3" style={{ background:"#fff", boxShadow:"0 2px 8px rgba(0,0,0,0.06)", border:"1px solid #f4f4f5" }}>
<div className="px-4 py-3" style={{ borderBottom:"1px solid #f4f4f5" }}><span className="text-xs font-semibold" style={{ color:"#18181b" }}>Revenue</span></div>
<div className="p-4 flex items-end gap-1.5 h-24">
{[40,60,45,75,65,85,70,90,55,80,75,95].map((h,i)=>(
<div key={i} className="flex-1 rounded-md" style={{ height:`${h}%`, background:i===11?"linear-gradient(180deg,#a855f7,#ec4899)":"rgba(168,85,247,0.15)" }} />
))}
</div>
</div>
<div className="rounded-2xl" style={{ background:"#fff", boxShadow:"0 2px 8px rgba(0,0,0,0.06)", border:"1px solid #f4f4f5" }}>
<div className="px-4 py-3" style={{ borderBottom:"1px solid #f4f4f5" }}><span className="text-xs font-semibold" style={{ color:"#18181b" }}>Recent activity</span></div>
{TABLE_ROWS.slice(0,3).map(r=>(
<div key={r.name} className="flex items-center gap-3 px-4 py-2.5" style={{ borderBottom:"1px solid #fafafa" }}>
<div className="w-7 h-7 rounded-full shrink-0" style={{ background:"linear-gradient(135deg,rgba(168,85,247,0.2),rgba(236,72,153,0.2))" }} />
<div className="flex-1"><p className="text-[11px] font-semibold" style={{ color:"#18181b" }}>{r.name}</p><p className="text-[10px]" style={{ color:"#a1a1aa" }}>{r.email}</p></div>
<span className="px-2 py-0.5 rounded-full text-[9px] font-semibold" style={r.status==="Active"?{background:"rgba(34,197,94,0.1)",color:"#16a34a"}:{background:"#f4f4f5",color:"#a1a1aa"}}>{r.status}</span>
</div>
))}
</div>
</div>
);
}
function HeroUIUsers() {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#fafafa" }}>
<div className="rounded-2xl" style={{ background:"#fff", boxShadow:"0 2px 8px rgba(0,0,0,0.06)", border:"1px solid #f4f4f5" }}>
<div className="px-4 py-3 flex items-center justify-between" style={{ borderBottom:"1px solid #f4f4f5" }}>
<span className="text-xs font-semibold" style={{ color:"#18181b" }}>Team members</span>
<div className="flex gap-2">
<input className="h-7 px-3 rounded-full text-[11px]" style={{ border:"1px solid #e4e4e7", outline:"none", width:130 }} placeholder="Search..." />
<button className="h-7 px-3 rounded-full text-[11px] font-semibold text-white" style={{ background:"linear-gradient(135deg,#7c3aed,#ec4899)" }}>+ Invite</button>
</div>
</div>
<table className="w-full text-[11px]">
<thead><tr style={{ borderBottom:"1px solid #f4f4f5" }}>{["Member","Role","Status","Joined",""].map(h=><th key={h} className="px-4 py-2.5 text-left text-[10px] font-medium" style={{ color:"#a1a1aa" }}>{h}</th>)}</tr></thead>
<tbody>{TABLE_ROWS.map(r=>(
<tr key={r.name} style={{ borderBottom:"1px solid #fafafa" }}>
<td className="px-4 py-3"><div className="flex items-center gap-2.5"><div className="w-7 h-7 rounded-full" style={{ background:"linear-gradient(135deg,rgba(168,85,247,0.2),rgba(236,72,153,0.2))" }} /><div><p className="font-semibold" style={{ color:"#18181b" }}>{r.name}</p><p style={{ color:"#a1a1aa" }}>{r.email}</p></div></div></td>
<td className="px-4 py-3"><span className="px-2 py-0.5 rounded-full text-[9px]" style={{ background:"rgba(124,58,237,0.1)", color:"#7c3aed" }}>{r.role}</span></td>
<td className="px-4 py-3"><span className="px-2 py-0.5 rounded-full text-[9px] font-semibold" style={r.status==="Active"?{background:"rgba(34,197,94,0.1)",color:"#16a34a"}:r.status==="Pending"?{background:"rgba(234,179,8,0.1)",color:"#a16207"}:{background:"#f4f4f5",color:"#a1a1aa"}}>{r.status}</span></td>
<td className="px-4 py-3" style={{ color:"#d4d4d8" }}>{r.date}</td>
<td className="px-4 py-3"><button className="h-6 px-2.5 rounded-full text-[10px]" style={{ background:"rgba(124,58,237,0.08)", color:"#7c3aed" }}>Manage</button></td>
</tr>
))}</tbody>
</table>
</div>
</div>
);
}
function HeroUISettings() {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#fafafa" }}>
<div className="rounded-2xl mb-3" style={{ background:"#fff", boxShadow:"0 2px 8px rgba(0,0,0,0.06)", border:"1px solid #f4f4f5" }}>
<div className="px-4 py-3" style={{ borderBottom:"1px solid #f4f4f5" }}><span className="text-xs font-semibold" style={{ color:"#18181b" }}>Profile</span></div>
<div className="p-4 space-y-3">
{[{l:"Workspace name",v:"Acme Inc"},{l:"Slug",v:"acme-inc"},{l:"Email",v:"admin@acme.com"}].map(f=>(
<div key={f.l}>
<label className="text-[10px] font-semibold block mb-1" style={{ color:"#71717a" }}>{f.l}</label>
<input defaultValue={f.v} className="w-full h-8 px-3 rounded-xl text-[11px]" style={{ border:"1px solid #e4e4e7", outline:"none" }} />
</div>
))}
<button className="h-8 px-4 rounded-full text-[11px] font-semibold text-white" style={{ background:"linear-gradient(135deg,#7c3aed,#ec4899)" }}>Save changes</button>
</div>
</div>
<div className="rounded-2xl" style={{ background:"#fff", boxShadow:"0 2px 8px rgba(0,0,0,0.06)", border:"1px solid #f4f4f5" }}>
<div className="px-4 py-3" style={{ borderBottom:"1px solid #f4f4f5" }}><span className="text-xs font-semibold" style={{ color:"#18181b" }}>Notifications</span></div>
<div className="p-4 space-y-3">
{["Email digests","Push notifications","Security alerts","Product updates"].map((label,i)=>(
<div key={label} className="flex items-center justify-between">
<p className="text-[11px]" style={{ color:"#18181b" }}>{label}</p>
<div className="w-8 h-4 rounded-full relative cursor-pointer" style={{ background:[true,false,true,false][i]?"linear-gradient(135deg,#7c3aed,#ec4899)":"#e4e4e7" }}>
<div className="absolute top-0.5 w-3 h-3 rounded-full bg-white shadow" style={{ transform:[true,false,true,false][i]?"translateX(16px)":"translateX(2px)" }} />
</div>
</div>
))}
</div>
</div>
</div>
);
}
export function WebAppHeroUI() {
const [page, setPage] = useState<Page>("Dashboard");
const [theme, setTheme] = useState<ThemeColor>(HEROUI_THEMES[0]);
const NAV: { label: Page; icon: string }[] = [
{ label: "Dashboard", icon: "▦" },
{ label: "Users", icon: "◎" },
{ label: "Settings", icon: "⚙" },
];
return (
<div className="flex h-full font-sans text-sm" style={{ background: "#fafafa" }}>
<div className="w-44 flex flex-col py-4 px-3 gap-1 shrink-0" style={{ background: "linear-gradient(180deg,#1a1a2e,#16213e)", color: "#fff" }}>
<div className="flex items-center gap-2 px-2 mb-4">
<div className="w-6 h-6 rounded-full" style={{ background: theme.primary }} />
<span className="font-bold text-xs text-white">Acme Inc</span>
</div>
{NAV.map(({ label, icon }) => (
<button key={label} onClick={() => setPage(label)}
className="flex items-center gap-2 px-2 py-2 rounded-xl text-xs cursor-pointer w-full text-left"
style={page===label?{background: theme.activeBg, color: theme.activeFg, fontWeight:600}:{color:"rgba(255,255,255,0.5)"}}>
<span>{icon}</span>{label}
</button>
))}
</div>
<div className="flex-1 flex flex-col min-w-0">
<div className="h-12 flex items-center justify-between px-5 bg-white shrink-0" style={{ borderBottom: "1px solid #f0f0f0" }}>
<span className="font-bold text-sm" style={{ color: theme.primary }}>{page}</span>
<div className="flex items-center gap-3">
<ThemeSwatches themes={HEROUI_THEMES} selected={theme} onSelect={setTheme} />
<button className="h-7 px-3 rounded-full text-[11px] font-medium" style={{ border:"1px solid #e4e4e7", color:"#71717a" }}>Export</button>
<button className="h-7 px-3 rounded-full text-[11px] font-semibold" style={{ background: theme.primary, color: theme.primaryFg }}>+ New</button>
</div>
</div>
{page === "Dashboard" && <HeroUIDashboard />}
{page === "Users" && <HeroUIUsers />}
{page === "Settings" && <HeroUISettings />}
</div>
</div>
);
}
function TremorDashboard() {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#f9fafb" }}>
<div className="grid grid-cols-3 gap-3 mb-4">
{[{l:"Revenue",v:"$12,400",c:"#2563eb",bg:"#dbeafe",pct:65},{l:"Users",v:"2,841",c:"#7c3aed",bg:"#ede9fe",pct:48},{l:"Conversion",v:"18.2%",c:"#059669",bg:"#d1fae5",pct:72}].map(item=>(
<div key={item.l} className="rounded-xl p-3 bg-white" style={{ border:"1px solid #e5e7eb" }}>
<div className="flex items-center justify-between mb-2">
<p className="text-[10px] font-medium" style={{ color:"#6b7280" }}>{item.l}</p>
<div className="w-5 h-5 rounded" style={{ background:item.bg, display:"flex", alignItems:"center", justifyContent:"center" }}><div className="w-2 h-2 rounded-sm" style={{ background:item.c }} /></div>
</div>
<p className="text-lg font-bold" style={{ color:"#111827" }}>{item.v}</p>
<div className="mt-2 h-1.5 rounded-full" style={{ background:"#f3f4f6" }}><div className="h-full rounded-full" style={{ width:`${item.pct}%`, background:item.c }} /></div>
</div>
))}
</div>
<div className="bg-white rounded-xl p-4 mb-3" style={{ border:"1px solid #e5e7eb" }}>
<p className="text-xs font-semibold mb-3" style={{ color:"#111827" }}>Revenue over time</p>
<div className="flex items-end gap-1.5 h-20">
{[40,65,55,80,70,90,75,85,60,95,80,100].map((h,i)=>(
<div key={i} className="flex-1 rounded-t" style={{ height:`${h}%`, background:i===11?"#2563eb":"#dbeafe" }} />
))}
</div>
<div className="flex justify-between mt-1">
{["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"].map(m=><span key={m} className="text-[8px]" style={{ color:"#9ca3af" }}>{m}</span>)}
</div>
</div>
<div className="bg-white rounded-xl p-3" style={{ border:"1px solid #e5e7eb" }}>
{TABLE_ROWS.slice(0,3).map(r=>(
<div key={r.name} className="flex items-center gap-3 py-2 border-b last:border-0" style={{ borderColor:"#f3f4f6" }}>
<div className="w-2 h-2 rounded-full" style={{ background:r.status==="Active"?"#059669":"#d1d5db" }} />
<span className="text-[11px] flex-1" style={{ color:"#111827" }}>{r.name}</span>
<span className="text-[10px]" style={{ color:"#6b7280" }}>{r.role}</span>
</div>
))}
</div>
</div>
);
}
function TremorUsers() {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#f9fafb" }}>
<div className="grid grid-cols-2 gap-3 mb-4">
{[{l:"Total",v:"2,841",c:"#2563eb"},{l:"Active",v:"1,940",c:"#059669"},{l:"Pending",v:"647",c:"#d97706"},{l:"Inactive",v:"254",c:"#6b7280"}].map(s=>(
<div key={s.l} className="rounded-xl p-3 bg-white flex items-center gap-3" style={{ border:"1px solid #e5e7eb" }}>
<div className="w-8 h-8 rounded-full flex items-center justify-center" style={{ background:`${s.c}18` }}><div className="w-3 h-3 rounded-full" style={{ background:s.c }} /></div>
<div><p className="text-[10px]" style={{ color:"#6b7280" }}>{s.l}</p><p className="text-sm font-bold" style={{ color:"#111827" }}>{s.v}</p></div>
</div>
))}
</div>
<div className="bg-white rounded-xl" style={{ border:"1px solid #e5e7eb" }}>
<div className="px-4 py-3 flex items-center justify-between" style={{ borderBottom:"1px solid #f3f4f6" }}>
<span className="text-xs font-semibold" style={{ color:"#111827" }}>All users</span>
<input className="h-7 px-3 rounded-lg text-[11px]" style={{ border:"1px solid #e5e7eb", outline:"none", width:130 }} placeholder="Filter..." />
</div>
<table className="w-full text-[11px]">
<thead><tr style={{ borderBottom:"1px solid #f3f4f6" }}>{["Name","Role","Status","Date"].map(h=><th key={h} className="px-4 py-2 text-left text-[10px] font-medium" style={{ color:"#9ca3af" }}>{h}</th>)}</tr></thead>
<tbody>{TABLE_ROWS.map(r=>(
<tr key={r.name} style={{ borderBottom:"1px solid #f9fafb" }}>
<td className="px-4 py-2.5 font-medium" style={{ color:"#111827" }}>{r.name}</td>
<td className="px-4 py-2.5" style={{ color:"#6b7280" }}>{r.role}</td>
<td className="px-4 py-2.5"><div className="flex items-center gap-1.5"><div className="w-1.5 h-1.5 rounded-full" style={{ background:r.status==="Active"?"#059669":r.status==="Pending"?"#d97706":"#d1d5db" }} /><span style={{ color:"#374151" }}>{r.status}</span></div></td>
<td className="px-4 py-2.5" style={{ color:"#9ca3af" }}>{r.date}</td>
</tr>
))}</tbody>
</table>
</div>
</div>
);
}
function TremorSettings() {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#f9fafb" }}>
<div className="bg-white rounded-xl mb-3 p-4" style={{ border:"1px solid #e5e7eb" }}>
<p className="text-xs font-semibold mb-3" style={{ color:"#111827" }}>Workspace</p>
<div className="space-y-3">
{[{l:"Name",v:"Acme Inc"},{l:"Domain",v:"acme.com"},{l:"Timezone",v:"UTC-8"}].map(f=>(
<div key={f.l}>
<label className="text-[10px] font-medium block mb-1" style={{ color:"#6b7280" }}>{f.l}</label>
<input defaultValue={f.v} className="w-full h-8 px-3 rounded-lg text-[11px]" style={{ border:"1px solid #e5e7eb", outline:"none" }} />
</div>
))}
<button className="h-8 px-4 rounded-lg text-[11px] font-medium text-white" style={{ background:"#2563eb" }}>Save</button>
</div>
</div>
<div className="bg-white rounded-xl p-4" style={{ border:"1px solid #e5e7eb" }}>
<p className="text-xs font-semibold mb-3" style={{ color:"#111827" }}>Alerts</p>
{["Email digests","Anomaly alerts","Weekly report","API warnings"].map((label,i)=>(
<div key={label} className="flex items-center justify-between py-2 border-b last:border-0" style={{ borderColor:"#f3f4f6" }}>
<p className="text-[11px]" style={{ color:"#374151" }}>{label}</p>
<div className="w-8 h-4 rounded-full relative" style={{ background:[true,true,false,true][i]?"#2563eb":"#e5e7eb" }}>
<div className="absolute top-0.5 w-3 h-3 rounded-full bg-white shadow" style={{ transform:[true,true,false,true][i]?"translateX(16px)":"translateX(2px)" }} />
</div>
</div>
))}
</div>
</div>
);
}
export function WebAppTremor() {
const [page, setPage] = useState<Page>("Dashboard");
const [theme, setTheme] = useState<ThemeColor>(TREMOR_THEMES[0]);
const NAV: { label: Page; icon: string }[] = [
{ label: "Dashboard", icon: "▦" },
{ label: "Users", icon: "◎" },
{ label: "Settings", icon: "⚙" },
];
return (
<div className="flex h-full font-sans text-sm bg-white">
<div className="w-44 border-r flex flex-col py-4 px-3 gap-1 shrink-0" style={{ background:"#fff" }}>
<div className="flex items-center gap-2 px-2 mb-4">
<div className="w-6 h-6 rounded" style={{ background: theme.primary }} />
<span className="font-bold text-xs" style={{ color: theme.activeFg }}>Acme Inc</span>
</div>
{NAV.map(({ label, icon }) => (
<button key={label} onClick={() => setPage(label)}
className="flex items-center gap-2 px-2 py-2 rounded text-xs cursor-pointer w-full text-left"
style={page===label?{background: theme.activeBg, color: theme.activeFg, fontWeight:600}:{color:"#6b7280"}}>
<span>{icon}</span>{label}
</button>
))}
</div>
<div className="flex-1 flex flex-col min-w-0" style={{ background:"#f9fafb" }}>
<div className="h-12 flex items-center justify-between px-5 bg-white shrink-0" style={{ borderBottom:"1px solid #e5e7eb" }}>
<span className="font-bold text-sm" style={{ color:"#111827" }}>{page}</span>
<div className="flex items-center gap-3">
<ThemeSwatches themes={TREMOR_THEMES} selected={theme} onSelect={setTheme} />
<button className="h-7 px-3 rounded-lg text-[11px] font-medium" style={{ background: theme.primary, color: theme.primaryFg }}>+ New</button>
</div>
</div>
{page === "Dashboard" && <TremorDashboard />}
{page === "Users" && <TremorUsers />}
{page === "Settings" && <TremorSettings />}
</div>
</div>
);
}
// ---------------------------------------------------------------------------
// MARKETING scaffolds
// ---------------------------------------------------------------------------
export function MarketingDaisy() {
const [theme, setTheme] = useState<ThemeColor>(DAISY_THEMES[0]);
const isDark = !!theme.bg && ["#1d232a","#282a36","#1a103c","#171212","#20150e","#ffee00"].includes(theme.bg) === false
? theme.bg.startsWith("#1") || theme.bg.startsWith("#2") || theme.bg === "#ffee00"
: false;
const textColor = theme.textColor ?? "#f8f8f2";
const mutedText = theme.mutedText ?? "rgba(255,255,255,0.5)";
const cardBg = theme.cardBg ?? "rgba(255,255,255,0.05)";
const borderColor = theme.borderColor ?? "rgba(255,255,255,0.1)";
const bg = theme.bg ?? "#1d232a";
return (
<div className="h-full font-sans" style={{ background: bg, color: textColor }}>
<nav className="flex items-center justify-between px-6 py-3" style={{ borderBottom:`1px solid ${borderColor}` }}>
<div className="flex items-center gap-2">
<div className="w-6 h-6 rounded" style={{ background: theme.primary }} />
<span className="font-bold text-sm" style={{ color: textColor }}>Acme</span>
</div>
<div className="flex gap-4 text-xs" style={{ color: mutedText }}>
{["Features","Pricing","Docs","Blog"].map(i=><span key={i}>{i}</span>)}
</div>
<div className="flex items-center gap-2">
<ThemeSwatches themes={DAISY_THEMES} selected={theme} onSelect={setTheme} />
<button className="h-7 px-3 rounded-full text-[11px] font-bold" style={{ background:`${borderColor}`, color: textColor }}>Login</button>
<button className="h-7 px-3 rounded-full text-[11px] font-bold" style={{ background: theme.primary, color: theme.primaryFg }}>Get started</button>
</div>
</nav>
<div className="px-10 pt-10 pb-6 text-center">
<div className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-[10px] font-bold mb-4" style={{ background:`${theme.primary}22`, color: theme.primary, border:`1px solid ${theme.primary}44` }}>
{theme.label} theme v2.0
</div>
<h1 className="text-2xl font-black mb-2" style={{ color: textColor }}>Build faster,<br />ship smarter</h1>
<p className="text-xs mb-6 mx-auto" style={{ color: mutedText, maxWidth:280 }}>The all-in-one platform that helps teams build, launch, and scale their products.</p>
<div className="flex gap-2 justify-center mb-6">
<button className="h-9 px-5 rounded-full text-xs font-bold" style={{ background: theme.primary, color: theme.primaryFg }}>Start for free</button>
<button className="h-9 px-5 rounded-full text-xs font-bold" style={{ border:`1px solid ${borderColor}`, color: textColor }}>See demo </button>
</div>
</div>
<div className="grid grid-cols-3 gap-3 px-8">
{[{icon:"⚡",title:"Lightning fast",desc:"Deploy in seconds, not hours"},{icon:"🔒",title:"Secure by default",desc:"Enterprise-grade security built in"},{icon:"📈",title:"Scales with you",desc:"From zero to millions of users"}].map(f=>(
<div key={f.title} className="p-3 rounded-xl text-center" style={{ background: cardBg, border:`1px solid ${borderColor}` }}>
<div className="text-xl mb-1">{f.icon}</div>
<p className="text-[11px] font-bold mb-0.5" style={{ color: textColor }}>{f.title}</p>
<p className="text-[10px]" style={{ color: mutedText }}>{f.desc}</p>
</div>
))}
</div>
<div className="px-8 mt-4">
<div className="rounded-xl p-4" style={{ background: cardBg, border:`1px solid ${borderColor}` }}>
<div className="flex items-center gap-3 mb-3">
<div className="flex-1 h-8 rounded-lg" style={{ background: borderColor }} />
<button className="h-8 px-3 rounded-lg text-[11px] font-bold" style={{ background: theme.primary, color: theme.primaryFg }}>Subscribe</button>
</div>
<div className="flex gap-2">
{["badge","badge-outline","badge-soft"].map((b,i)=>(
<span key={b} className="px-2 py-0.5 rounded-full text-[9px] font-bold" style={i===0?{background:theme.primary,color:theme.primaryFg}:i===1?{border:`1px solid ${theme.primary}`,color:theme.primary}:{background:`${theme.primary}22`,color:theme.primary}}>{["Primary","Outline","Soft"][i]}</span>
))}
</div>
</div>
</div>
</div>
);
}
// Extended HeroUI marketing themes — these match heroui.com/themes prebuilt options
const HEROUI_MARKETING_THEMES: ThemeColor[] = [
{ id: "purple", label: "Purple", primary: "#7c3aed", primaryFg: "#fff", activeBg: "rgba(124,58,237,0.08)", activeFg: "#7c3aed", ring: "rgba(124,58,237,0.15)", bg: "#fff" },
{ id: "blue", label: "Blue", primary: "#2563eb", primaryFg: "#fff", activeBg: "rgba(37,99,235,0.08)", activeFg: "#2563eb", ring: "rgba(37,99,235,0.15)", bg: "#fff" },
{ id: "teal", label: "Teal", primary: "#0d9488", primaryFg: "#fff", activeBg: "rgba(13,148,136,0.08)", activeFg: "#0d9488", ring: "rgba(13,148,136,0.15)", bg: "#fff" },
{ id: "rose", label: "Rose", primary: "#e11d48", primaryFg: "#fff", activeBg: "rgba(225,29,72,0.08)", activeFg: "#e11d48", ring: "rgba(225,29,72,0.15)", bg: "#fff" },
{ id: "dark", label: "Dark", primary: "#7c3aed", primaryFg: "#fff", activeBg: "rgba(124,58,237,0.2)", activeFg: "#c084fc", ring: "rgba(124,58,237,0.3)", bg: "#09090b", cardBg: "#18181b", textColor: "#f4f4f5", borderColor: "#27272a", mutedText: "#71717a" },
{ id: "modern", label: "Modern", primary: "#06b6d4", primaryFg: "#fff", activeBg: "rgba(6,182,212,0.08)", activeFg: "#06b6d4", ring: "rgba(6,182,212,0.15)", bg: "#fff" },
];
export function MarketingHeroUI() {
const [theme, setTheme] = useState<ThemeColor>(HEROUI_MARKETING_THEMES[0]);
const isDark = theme.id === "dark";
const bg = theme.bg ?? "#fff";
const textColor = theme.textColor ?? "#18181b";
const mutedText = theme.mutedText ?? "#71717a";
const cardBg = theme.cardBg ?? "#fff";
const borderColor = theme.borderColor ?? "#f4f4f5";
return (
<div className="h-full font-sans" style={{ background: bg }}>
<nav className="flex items-center justify-between px-6 py-3" style={{ borderBottom:`1px solid ${borderColor}` }}>
<div className="flex items-center gap-2">
<div className="w-6 h-6 rounded-full" style={{ background: theme.primary }} />
<span className="font-bold text-xs" style={{ color: textColor }}>Acme</span>
</div>
<div className="flex gap-4 text-xs" style={{ color: mutedText }}>
{["Features","Pricing","Docs","Blog"].map(i=><span key={i}>{i}</span>)}
</div>
<div className="flex items-center gap-2">
<ThemeSwatches themes={HEROUI_MARKETING_THEMES} selected={theme} onSelect={setTheme} />
<button className="h-7 px-3 rounded-full text-[11px]" style={{ border:`1px solid ${borderColor}`, color: mutedText }}>Login</button>
<button className="h-7 px-3 rounded-full text-[11px] font-semibold text-white" style={{ background: theme.primary }}>Get started</button>
</div>
</nav>
<div className="px-10 pt-10 pb-4 text-center">
<div className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-[10px] font-semibold mb-4" style={{ background: theme.activeBg, color: theme.activeFg, border:`1px solid ${theme.ring}` }}>
🚀 {theme.label} theme v2.0
</div>
<h1 className="text-2xl font-black mb-2" style={{ color: theme.primary }}>
Build faster,<br />ship smarter
</h1>
<p className="text-xs mb-5 mx-auto" style={{ color: mutedText, maxWidth:280 }}>The all-in-one platform for teams that move fast.</p>
<div className="flex gap-2 justify-center mb-5">
<button className="h-9 px-5 rounded-full text-xs font-semibold shadow-lg" style={{ background: theme.primary, color: theme.primaryFg }}>Start for free</button>
<button className="h-9 px-5 rounded-full text-xs font-medium" style={{ border:`1px solid ${borderColor}`, color: mutedText }}>Live demo </button>
</div>
<div className="rounded-2xl mx-auto overflow-hidden shadow-xl" style={{ maxWidth:400, border:`1px solid ${borderColor}`, background: cardBg }}>
<div className="h-6 flex items-center gap-1.5 px-3" style={{ background: isDark ? "#27272a" : "#fafafa", borderBottom:`1px solid ${borderColor}` }}>
{["#ff5f56","#ffbd2e","#27c93f"].map(c=><div key={c} className="w-2 h-2 rounded-full" style={{ background:c }} />)}
</div>
<div className="p-4">
<div className="grid grid-cols-2 gap-2">
{["Revenue","Users","Growth","Churn"].map((m,i)=>(
<div key={m} className="rounded-xl p-2.5" style={{ background: theme.activeBg, border:`1px solid ${theme.ring}` }}>
<p className="text-[9px]" style={{ color: mutedText }}>{m}</p>
<p className="text-sm font-bold" style={{ color: textColor }}>{["$12k","2.8k","+24%","2.1%"][i]}</p>
</div>
))}
</div>
</div>
</div>
</div>
</div>
);
}
export function MarketingAceternity() {
return (
<div className="h-full font-sans" style={{ background:"#030303" }}>
<nav className="flex items-center justify-between px-6 py-3" style={{ borderBottom:"1px solid rgba(255,255,255,0.06)" }}>
<div className="flex items-center gap-2">
<div className="w-6 h-6 rounded" style={{ background:"linear-gradient(135deg,#a855f7,#3b82f6)" }} />
<span className="font-bold text-white text-sm">Acme</span>
</div>
<div className="flex gap-4 text-xs" style={{ color:"rgba(255,255,255,0.4)" }}>
{["Features","Pricing","Docs"].map(i=><span key={i}>{i}</span>)}
</div>
<button className="h-7 px-3 rounded text-[11px] font-medium text-white" style={{ background:"rgba(168,85,247,0.2)", border:"1px solid rgba(168,85,247,0.3)" }}>Get started</button>
</nav>
<div className="relative px-10 pt-10 text-center overflow-hidden">
<div className="absolute inset-0 pointer-events-none" style={{ background:"radial-gradient(ellipse 60% 40% at 50% 0%,rgba(168,85,247,0.15),transparent)" }} />
<div className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-[10px] font-medium mb-4" style={{ border:"1px solid rgba(168,85,247,0.3)", color:"rgba(168,85,247,0.9)" }}>
Open source · 12k GitHub stars
</div>
<h1 className="text-2xl font-black mb-2" style={{ background:"linear-gradient(180deg,#fff 0%,rgba(255,255,255,0.5) 100%)", WebkitBackgroundClip:"text", WebkitTextFillColor:"transparent" }}>
Build the future<br />of the web
</h1>
<p className="text-xs mb-6 mx-auto" style={{ color:"rgba(255,255,255,0.35)", maxWidth:260 }}>Beautifully crafted components built with Tailwind CSS and Framer Motion.</p>
<div className="flex gap-2 justify-center mb-6">
<button className="h-9 px-5 rounded text-xs font-semibold text-white relative overflow-hidden" style={{ background:"linear-gradient(135deg,#a855f7,#3b82f6)" }}>Get started </button>
<button className="h-9 px-5 rounded text-xs font-medium" style={{ border:"1px solid rgba(255,255,255,0.1)", color:"rgba(255,255,255,0.6)" }}>View components</button>
</div>
<div className="grid grid-cols-3 gap-3 mx-auto" style={{ maxWidth:480 }}>
{["Animated","Accessible","Open source"].map((f,i)=>(
<div key={f} className="p-3 rounded-xl text-left" style={{ background:"rgba(255,255,255,0.03)", border:"1px solid rgba(255,255,255,0.06)" }}>
<div className="w-6 h-6 rounded mb-1.5 flex items-center justify-center" style={{ background:["rgba(168,85,247,0.15)","rgba(59,130,246,0.15)","rgba(34,197,94,0.15)"][i] }}>
<div className="w-2.5 h-2.5 rounded-full" style={{ background:["#a855f7","#3b82f6","#22c55e"][i] }} />
</div>
<p className="text-[10px] font-semibold text-white mb-0.5">{f}</p>
<p className="text-[9px]" style={{ color:"rgba(255,255,255,0.3)" }}>Built for production</p>
</div>
))}
</div>
</div>
</div>
);
}
export function MarketingTailwind() {
return (
<div className="h-full font-sans bg-white">
<nav className="flex items-center justify-between px-6 py-3 border-b">
<span className="font-black text-sm text-zinc-900">acme</span>
<div className="flex gap-4 text-xs text-zinc-500">
{["Features","Pricing","Blog"].map(i=><span key={i}>{i}</span>)}
</div>
<div className="flex gap-2">
<button className="h-7 px-3 text-[11px] text-zinc-600">Log in</button>
<button className="h-7 px-3 rounded-md text-[11px] font-medium bg-zinc-900 text-white">Sign up</button>
</div>
</nav>
<div className="px-10 pt-10 pb-6">
<div className="max-w-sm">
<span className="text-[10px] font-semibold text-violet-600 tracking-widest uppercase">Now in public beta</span>
<h1 className="text-2xl font-black text-zinc-900 mt-1 mb-2 leading-tight">The platform<br />built for scale</h1>
<p className="text-xs text-zinc-500 mb-5 leading-relaxed">Everything your team needs to build, deploy, and monitor production applications.</p>
<div className="flex gap-2 mb-8">
<button className="h-8 px-4 rounded-md text-xs font-medium bg-zinc-900 text-white">Get started free</button>
<button className="h-8 px-4 rounded-md text-xs font-medium border border-zinc-200 text-zinc-600">Documentation </button>
</div>
<div className="grid grid-cols-2 gap-2">
{["99.9% uptime SLA","10ms avg latency","SOC2 compliant","GDPR ready"].map(f=>(
<div key={f} className="flex items-center gap-1.5 text-[10px] text-zinc-500">
<div className="w-3.5 h-3.5 rounded-full bg-zinc-900 flex items-center justify-center">
<div className="w-1.5 h-1 border-l border-b border-white -rotate-45 translate-y-px" />
</div>
{f}
</div>
))}
</div>
</div>
</div>
</div>
);
}
// ---------------------------------------------------------------------------
// ADMIN scaffolds
// ---------------------------------------------------------------------------
export function AdminMantine() { return <WebAppMantine />; }
export function AdminShadcn() { return <WebAppShadcn />; }
export function AdminTremor() { return <WebAppTremor />; }
// ---------------------------------------------------------------------------
// MOBILE scaffolds
// ---------------------------------------------------------------------------
function MobileFrame({ children }: { children: React.ReactNode }) {
return (
<div className="flex items-center justify-center h-full" style={{ background:"#f4f4f5" }}>
<div className="relative" style={{ width:200, height:380 }}>
<div className="absolute inset-0 rounded-3xl" style={{ background:"#1a1a1a", boxShadow:"0 20px 60px rgba(0,0,0,0.3)" }} />
<div className="absolute top-3 left-1/2 -translate-x-1/2 w-16 h-4 rounded-full bg-black z-10" />
<div className="absolute inset-2 rounded-3xl overflow-hidden bg-white">
{children}
</div>
</div>
</div>
);
}
export function MobileNativewind() {
return (
<MobileFrame>
<div className="h-full flex flex-col bg-white text-xs">
<div className="pt-6 pb-3 px-3" style={{ background:"#18181b" }}>
<p className="text-[8px] text-zinc-400">Good morning</p>
<p className="text-sm font-bold text-white">Dashboard</p>
</div>
<div className="flex-1 overflow-auto p-3 space-y-2" style={{ background:"#fafafa" }}>
<div className="grid grid-cols-2 gap-2">
{[{l:"Revenue",v:"$4.2k"},{l:"Users",v:"184"}].map(c=>(
<div key={c.l} className="bg-white rounded-xl p-2.5" style={{ border:"1px solid #e4e4e7" }}>
<p className="text-[8px] text-zinc-400">{c.l}</p>
<p className="text-sm font-bold text-zinc-900">{c.v}</p>
</div>
))}
</div>
{["Fix login bug","Update pricing","Review PR #42"].map((t,i)=>(
<div key={t} className="bg-white rounded-xl p-2.5 flex items-center gap-2" style={{ border:"1px solid #e4e4e7" }}>
<div className="w-4 h-4 rounded border border-zinc-300 shrink-0" style={i===0?{background:"#18181b",border:"none"}:{}} />
<p className="text-[9px] text-zinc-700" style={i===0?{textDecoration:"line-through",color:"#a1a1aa"}:{}}>{t}</p>
</div>
))}
</div>
<div className="flex border-t bg-white" style={{ padding:"6px 0 10px" }}>
{["Home","Projects","Chat","Profile"].map((l,i)=>(
<div key={l} className="flex-1 flex flex-col items-center gap-0.5">
<div className="w-4 h-4 rounded" style={{ background:i===0?"#18181b":"#e4e4e7" }} />
<span className="text-[7px]" style={{ color:i===0?"#18181b":"#a1a1aa" }}>{l}</span>
</div>
))}
</div>
</div>
</MobileFrame>
);
}
export function MobileGluestack() {
return (
<MobileFrame>
<div className="h-full flex flex-col text-xs">
<div className="pt-6 pb-3 px-3 flex items-center justify-between" style={{ background:"#1976d2" }}>
<p className="text-sm font-bold text-white">Dashboard</p>
<div className="w-5 h-5 rounded-full bg-white/20" />
</div>
<div className="flex-1 overflow-auto p-3 space-y-2" style={{ background:"#f5f5f5" }}>
<div className="grid grid-cols-2 gap-2">
{[{l:"Revenue",v:"$4.2k",c:"#1976d2"},{l:"Users",v:"184",c:"#7b1fa2"}].map(c=>(
<div key={c.l} className="rounded-lg p-2.5" style={{ background:c.c }}>
<p className="text-[8px] text-white/70">{c.l}</p>
<p className="text-sm font-bold text-white">{c.v}</p>
</div>
))}
</div>
{["Fix login bug","Update pricing","Review PR #42"].map((t,i)=>(
<div key={t} className="bg-white rounded-lg p-2.5 flex items-center gap-2 shadow-sm">
<div className="w-4 h-4 rounded-full border-2 shrink-0" style={i===0?{background:"#1976d2",borderColor:"#1976d2"}:{borderColor:"#bdbdbd"}} />
<p className="text-[9px]" style={{ color:i===0?"#9e9e9e":"#212121", textDecoration:i===0?"line-through":"none" }}>{t}</p>
</div>
))}
</div>
<div className="flex bg-white shadow-sm" style={{ padding:"6px 0 10px", borderTop:"1px solid #e0e0e0" }}>
{["Home","Tasks","Chat","Profile"].map((l,i)=>(
<div key={l} className="flex-1 flex flex-col items-center gap-0.5">
<div className="w-4 h-4 rounded" style={{ background:i===0?"#1976d2":"#e0e0e0" }} />
<span className="text-[7px]" style={{ color:i===0?"#1976d2":"#9e9e9e" }}>{l}</span>
</div>
))}
</div>
</div>
</MobileFrame>
);
}
// ---------------------------------------------------------------------------
// EMAIL scaffolds
// ---------------------------------------------------------------------------
export function EmailReactEmail() {
return (
<div className="flex items-start justify-center h-full py-6 font-sans" style={{ background:"#f6f9fc" }}>
<div className="w-full max-w-md" style={{ background:"#fff", borderRadius:8, boxShadow:"0 2px 8px rgba(0,0,0,0.08)" }}>
<div className="px-8 py-5" style={{ borderBottom:"1px solid #e6e6e6" }}>
<div className="flex items-center gap-2 mb-1">
<div className="w-5 h-5 rounded" style={{ background:"#000" }} />
<span className="font-bold text-xs text-zinc-900">Acme</span>
</div>
</div>
<div className="px-8 py-6">
<p className="text-base font-bold text-zinc-900 mb-2">Welcome to Acme! 🎉</p>
<p className="text-xs text-zinc-500 mb-4 leading-relaxed">Hi Alice, thanks for signing up. Your account is ready and you can start building right away.</p>
<div className="text-center mb-4">
<button className="h-9 px-6 rounded text-xs font-semibold text-white" style={{ background:"#000" }}>Get started </button>
</div>
<div className="rounded-lg p-3 mb-4" style={{ background:"#f6f9fc", border:"1px solid #e6e6e6" }}>
<p className="text-[10px] font-semibold text-zinc-700 mb-1">Your account details</p>
{["Plan: Starter","Workspace: alice-workspace","Status: Active"].map(d=>(
<p key={d} className="text-[10px] text-zinc-500">{d}</p>
))}
</div>
<p className="text-[10px] text-zinc-400 leading-relaxed">If you have any questions, reply to this email or visit our help center. We're here to help.</p>
</div>
<div className="px-8 py-4 text-center" style={{ borderTop:"1px solid #e6e6e6", background:"#fafafa" }}>
<p className="text-[9px] text-zinc-400">Acme Inc · 123 Main St · San Francisco CA · Unsubscribe</p>
</div>
</div>
</div>
);
}
// ---------------------------------------------------------------------------
// DOCS scaffolds
// ---------------------------------------------------------------------------
export function DocsNextra() {
return (
<div className="flex h-full font-sans text-xs bg-white">
<div className="w-44 border-r flex flex-col py-4 px-3" style={{ background:"#fafafa" }}>
<div className="mb-4">
<p className="text-[9px] font-semibold text-zinc-400 uppercase tracking-wide mb-2">Getting Started</p>
{["Introduction","Installation","Quick Start"].map((item,i)=>(
<div key={item} className={`px-2 py-1 rounded text-[10px] cursor-pointer mb-0.5 ${i===0?"bg-zinc-900 text-white font-medium":"text-zinc-500 hover:text-zinc-700"}`}>{item}</div>
))}
</div>
<div className="mb-4">
<p className="text-[9px] font-semibold text-zinc-400 uppercase tracking-wide mb-2">Components</p>
{["Button","Card","Input","Modal","Table"].map(item=>(
<div key={item} className="px-2 py-1 rounded text-[10px] cursor-pointer text-zinc-500 hover:text-zinc-700 mb-0.5">{item}</div>
))}
</div>
<div>
<p className="text-[9px] font-semibold text-zinc-400 uppercase tracking-wide mb-2">API Reference</p>
{["REST API","Webhooks"].map(item=>(
<div key={item} className="px-2 py-1 text-[10px] text-zinc-500 mb-0.5">{item}</div>
))}
</div>
</div>
<div className="flex-1 overflow-auto">
<div className="max-w-lg px-8 py-6">
<div className="flex items-center gap-1.5 text-[9px] text-zinc-400 mb-4">
<span>Docs</span><span>/</span><span>Getting Started</span><span>/</span><span className="text-zinc-600">Introduction</span>
</div>
<h1 className="text-base font-bold text-zinc-900 mb-2">Introduction</h1>
<p className="text-[11px] text-zinc-600 mb-3 leading-relaxed">Acme UI is a collection of re-usable components that you can copy and paste into your web apps. Built with Radix UI and Tailwind CSS.</p>
<div className="rounded-lg p-3 mb-3" style={{ background:"#18181b" }}>
<p className="text-[10px] font-mono" style={{ color:"#10b981" }}>$ npm install acme-ui</p>
</div>
<h2 className="text-sm font-semibold text-zinc-900 mb-1.5">Key features</h2>
{["Accessible","Customisable","Open source","TypeScript ready"].map(f=>(
<div key={f} className="flex items-center gap-1.5 text-[10px] text-zinc-600 mb-1">
<div className="w-1.5 h-1.5 rounded-full bg-zinc-400" />{f}
</div>
))}
</div>
</div>
</div>
);
}
export function DocsShadcnCustom() {
return (
<div className="flex h-full font-sans text-xs bg-white">
<div className="w-44 border-r flex flex-col py-4 px-3">
<div className="mb-4 pb-3 border-b">
<div className="flex items-center gap-2">
<div className="w-5 h-5 rounded bg-zinc-900" />
<span className="font-bold text-zinc-900 text-[11px]">Acme Docs</span>
</div>
</div>
{[{section:"Guides",items:["Introduction","Installation","Theming"]},{section:"Components",items:["Button","Input","Select","Dialog"]}].map(g=>(
<div key={g.section} className="mb-3">
<p className="text-[9px] font-semibold text-zinc-400 uppercase tracking-wide mb-1.5">{g.section}</p>
{g.items.map((item,i)=>(
<div key={item} className={`px-2 py-1 rounded-md text-[10px] mb-0.5 cursor-pointer ${i===0&&g.section==="Guides"?"bg-zinc-100 text-zinc-900 font-medium":"text-zinc-500"}`}>{item}</div>
))}
</div>
))}
</div>
<div className="flex-1 px-8 py-6 overflow-auto">
<h1 className="text-base font-bold text-zinc-900 mb-1">Introduction</h1>
<p className="text-[11px] text-zinc-500 mb-4 leading-relaxed">A set of beautifully designed components built with Radix UI and Tailwind CSS.</p>
<div className="rounded-lg border overflow-hidden mb-4">
<div className="flex items-center gap-2 px-3 py-2 border-b bg-zinc-50">
<span className="text-[9px] font-medium text-zinc-500">bash</span>
</div>
<div className="px-3 py-2.5 bg-zinc-950">
<p className="text-[10px] font-mono text-emerald-400">npx shadcn@latest init</p>
</div>
</div>
<div className="grid grid-cols-2 gap-2">
{["Button","Card","Input","Badge"].map(c=>(
<div key={c} className="rounded-lg border p-3 cursor-pointer hover:bg-zinc-50 transition-colors">
<p className="text-[10px] font-semibold text-zinc-700 mb-0.5">{c}</p>
<p className="text-[9px] text-zinc-400">View component </p>
</div>
))}
</div>
</div>
</div>
);
}
// ---------------------------------------------------------------------------
// Registry — maps surface+theme to scaffold component
// ---------------------------------------------------------------------------
export const SCAFFOLD_REGISTRY: Record<string, Record<string, React.ComponentType>> = {
"web-app": {
"shadcn": WebAppShadcn,
"mantine": WebAppMantine,
"hero-ui": WebAppHeroUI,
"tremor": WebAppTremor,
},
"marketing": {
"daisy-ui": MarketingDaisy,
"hero-ui": MarketingHeroUI,
"aceternity": MarketingAceternity,
"tailwind-only": MarketingTailwind,
},
"admin": {
"mantine": AdminMantine,
"shadcn": AdminShadcn,
"tremor": AdminTremor,
},
"mobile": {
"nativewind": MobileNativewind,
"gluestack": MobileGluestack,
},
"email": {
"react-email": EmailReactEmail,
},
"docs": {
"nextra": DocsNextra,
"shadcn": DocsShadcnCustom,
},
};