-
- {named.map((n, i) => (
-
- ))}
-
-
- {[
- ["Danger", "#fef2f2", "#dc2626"],
- ["Success", "#f0fdf4", "#16a34a"],
- ["Warning", "#fffbeb", "#ca8a04"],
- ["Info", "#eff6ff", "#2563eb"],
- ].map(([label, bg, fg]) => (
-
- {label}
-
- ))}
-
-
Reference hues for tags & status (not overridden by accent).
-
- );
-}
-
-export function RadiusPanel({ tokens }: { tokens: ResolvedKitTokens }) {
- const rows = [
- { id: "radius-xs", px: tokens.radiusXs, use: "micro chips" },
- { id: "radius-sm", px: tokens.radiusSm, use: "inputs, buttons" },
- { id: "radius-md", px: tokens.radiusMdPx, use: "cards, dropdowns" },
- { id: "radius-xl", px: tokens.radiusXl, use: "large panels" },
- { id: "radius-xxl", px: tokens.radiusXxl, use: "hero surfaces" },
- { id: "radius-pill", px: 999, use: "tags" },
- { id: "radius-full", px: 100, use: "avatars" },
- ];
- const fill = tokens.accentScale[3] ?? "#eceeff";
- return (
-
- {rows.map((x) => (
-
-
= 100 ? "50%" : x.px,
- }}
- />
-
{x.id}
-
{x.use}
-
- ))}
-
- );
-}
-
-export function ShadowsPanel({ tokens }: { tokens: ResolvedKitTokens }) {
- const focus = tokens.accentHex;
- const cards = [
- { id: "shadow-light", desc: "Buttons, rows", shadow: "0 1px 2px rgba(0,0,0,0.05)" },
- { id: "shadow-strong", desc: "Dropdowns", shadow: "0 4px 16px rgba(0,0,0,0.08)" },
- { id: "shadow-super-heavy", desc: "Modals", shadow: "0 12px 48px rgba(0,0,0,0.12)" },
- { id: "shadow-underline", desc: "Focus line", shadow: `inset 0 -2px 0 ${focus}` },
- ];
- return (
-
- {cards.map((c) => (
-
- ))}
-
- );
-}
-
-export function SpacingPanel({ tokens }: { tokens: ResolvedKitTokens }) {
- const bar = tokens.accentScale[5] ?? "#9aa6ff";
- const steps = [
- [1, 4, "sibling gap min"],
- [2, 8, "button padding"],
- [3, 12, "sidebar gap"],
- [4, 16, "section padding"],
- [6, 24, "card padding"],
- [8, 32, "large gap"],
- [12, 48, "table row"],
- [16, 64, "section spacer"],
- ];
- return (
-
-
- SPACING — 4PX BASE · space(n) = n × 4px
-
- {steps.map(([n, px, note]) => (
-
-
space({n})
-
{px}px
-
-
{note}
-
- ))}
-
- );
-}
-
-export function ButtonsPanel({ tokens }: { tokens: ResolvedKitTokens }) {
- const a = tokens.accentScale;
- const md = tokens.radiusMdPx;
- const accent = a[8] ?? tokens.accentHex;
- return (
-
-
Primary
-
-
-
-
-
-
-
Secondary · outlined
-
-
-
-
-
Tertiary · text
-
-
-
-
-
- );
-}
-
-function Field({ label, children }: { label: string; children: ReactNode }) {
- return (
-
- );
-}
-
-export function InputsPanel({ tokens }: { tokens: ResolvedKitTokens }) {
- const accent = tokens.accentHex;
- const md = tokens.radiusMdPx;
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
-
-export function NavPanel({ tokens }: { tokens: ResolvedKitTokens }) {
- const rs = tokens.radiusSm;
- const pad = tokens.density === "compact" ? 6 : 8;
- const Item = ({ active, children }: { active?: boolean; children: ReactNode }) => (
-
- {children}
-
- );
- return (
-
-
-
MAIN
-
- People
-
- Companies
-
-
- Opportunities{" "}
- 12
-
-
- Inbox
-
WORKSPACE
-
- Workflows
-
- Tasks
-
-
-
Drawer preview uses kit neutrals + radius tokens.
-
Accent {tokens.accentHex} applies to links & focus off-nav.
-
-
- );
-}
-
-export function TagsPanel({ tokens }: { tokens: ResolvedKitTokens }) {
- const pills = [
- ["Active", "#dcfce7", "#166534"],
- ["Closed", "#fee2e2", "#991b1b"],
- ["In Progress", "#fef9c3", "#854d0e"],
- ["Draft", tokens.accentScale[2] ?? "#e0e7ff", tokens.accentScale[10] ?? "#3730a3"],
- ];
- return (
-
-
Pill tags · radius-full
-
- {pills.map(([label, bg, fg]) => (
-
- {label}
-
- ))}
-
-
- );
-}
-
-export function IllustrationsPanel({ tokens }: { tokens: ResolvedKitTokens }) {
- const icons = ["user", "mail", "calendar", "file", "link", "tag", "settings", "numbers"];
- const r = tokens.radiusMdPx;
- return (
-
-
- {icons.map((name) => (
-
- {name}
-
- ))}
-
-
- Replace with project SVGs · assets/illustrations/
-
-
- );
-}
-
-export function LogoPanel({ tokens }: { tokens: ResolvedKitTokens }) {
- const r = tokens.radiusMdPx;
- return (
-
- {["Logo light", "Logo dark", "Icon mark", "Workspace"].map((label) => (
-
- ))}
-
- );
-}
-
-const PANEL_COMPONENTS: Record
> = {
- fontWeights: FontWeightsPanel,
- typeScale: TypeScalePanel,
- accentScale: AccentScalePanel,
- grayScale: GrayScalePanel,
- semanticColors: SemanticColorsPanel,
- radius: RadiusPanel,
- shadows: ShadowsPanel,
- spacing: SpacingPanel,
- buttons: ButtonsPanel,
- inputs: InputsPanel,
- nav: NavPanel,
- tags: TagsPanel,
- illustrations: IllustrationsPanel,
- logo: LogoPanel,
-};
-
-export function renderKitPanel(panelKey: string, tokens: ResolvedKitTokens): ReactNode {
- const C = PANEL_COMPONENTS[panelKey];
- if (!C) return Unknown panel: {panelKey}
;
- return ;
-}
diff --git a/vibn-frontend/components/project/design-system-explorer.tsx b/vibn-frontend/components/project/design-system-explorer.tsx
deleted file mode 100644
index b95a0fe..0000000
--- a/vibn-frontend/components/project/design-system-explorer.tsx
+++ /dev/null
@@ -1,233 +0,0 @@
-"use client";
-
-import { useCallback, useEffect, useMemo, useState } from "react";
-import { useParams } from "next/navigation";
-import { Loader2, Check, Search, Eye, Sparkles, LayoutTemplate, Palette } from "lucide-react";
-import { toast } from "sonner";
-import { STARTER_KITS } from "@/lib/design-kits/registry";
-import { DEFAULT_DESIGN_KIT_ID } from "@/lib/design-kits/types";
-
-export function DesignSystemExplorer() {
- const params = useParams();
- const projectId = params.projectId as string;
-
- const [activeKitId, setActiveKitId] = useState(DEFAULT_DESIGN_KIT_ID);
- const [previewKitId, setPreviewKitId] = useState(DEFAULT_DESIGN_KIT_ID);
- const [previewMode, setPreviewMode] = useState<"showcase" | "tokens">("showcase");
- const [loading, setLoading] = useState(true);
- const [saving, setSaving] = useState(false);
- const [search, setSearch] = useState("");
-
- useEffect(() => {
- let cancelled = false;
- setLoading(true);
- fetch(`/api/projects/${projectId}/design-kit`, { credentials: "include" })
- .then((r) => {
- if (!r.ok) throw new Error(r.status === 401 ? "Sign in to load design kit" : `HTTP ${r.status}`);
- return r.json();
- })
- .then((d: { kitId?: string }) => {
- if (cancelled) return;
- if (d.kitId) {
- setActiveKitId(d.kitId);
- setPreviewKitId(d.kitId);
- }
- })
- .catch((e: Error) => {
- if (!cancelled) toast.error(e.message || "Failed to load design kit");
- })
- .finally(() => {
- if (!cancelled) setLoading(false);
- });
- return () => {
- cancelled = true;
- };
- }, [projectId]);
-
- const selectKit = useCallback(async (kitId: string) => {
- setSaving(true);
- try {
- const res = await fetch(`/api/projects/${projectId}/design-kit`, {
- method: "PATCH",
- credentials: "include",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({ kitId }),
- });
- if (!res.ok) throw new Error("Could not save kit");
- const data = await res.json();
- setActiveKitId(data.kitId || kitId);
- toast.success("Design System Updated", {
- description: "The AI agent now has full context of this design system's guidelines and tokens. Ask it to apply the theme in chat!",
- });
- } catch (err: any) {
- toast.error(err.message || "Failed to switch design system");
- } finally {
- setSaving(false);
- }
- }, [projectId]);
-
- const filteredKits = useMemo(() => {
- const s = search.toLowerCase();
- return STARTER_KITS.filter(k => k.name.toLowerCase().includes(s) || k.tagline.toLowerCase().includes(s));
- }, [search]);
-
- if (loading) {
- return (
-
-
-
- Loading design system...
-
-
- );
- }
-
- const previewKit = STARTER_KITS.find(k => k.id === previewKitId) || STARTER_KITS[0];
- const isActive = activeKitId === previewKitId;
-
- return (
-
-
- {/* LEFT SIDEBAR: Library & Search */}
-
-
-
-
- Vibn Design Library
-
-
-
- setSearch(e.target.value)}
- className="w-full pl-9 pr-4 py-2 bg-zinc-50 border border-zinc-200 rounded-lg text-xs focus:outline-none focus:ring-2 focus:ring-indigo-500/20 focus:border-indigo-500 transition-all"
- />
-
-
-
-
- {filteredKits.map((kit) => {
- const isSelected = previewKitId === kit.id;
- const isCurrentlyActive = activeKitId === kit.id;
- return (
-
- );
- })}
- {filteredKits.length === 0 && (
-
- No design systems found.
-
- )}
-
-
-
- {/* RIGHT MAIN AREA: Live Preview & Action Bar */}
-
- {/* Top Action Bar */}
-
-
-
-
-
- {previewKit.name}
-
-
-
-
-
- {previewKit.hasPreview && (
-
- )}
-
-
-
-
-
-
- {/* Live Iframe */}
-
-
-
-
- {previewKit.id}.{previewMode}.preview
-
-
-
-
-
-
-
-
- );
-}
diff --git a/vibn-frontend/components/project/project-icon-rail.tsx b/vibn-frontend/components/project/project-icon-rail.tsx
index ebbac26..69331df 100644
--- a/vibn-frontend/components/project/project-icon-rail.tsx
+++ b/vibn-frontend/components/project/project-icon-rail.tsx
@@ -35,7 +35,6 @@ interface RailItem {
const PRIMARY_ITEMS: RailItem[] = [
{ segment: "preview", label: "Preview", Icon: Eye },
{ segment: "plan", label: "Plan", Icon: ClipboardList },
- { segment: "design-system", label: "Design", Icon: Palette },
{ segment: "market", label: "Market", Icon: PlaneTakeoff },
{ segment: "product", label: "Code", Icon: Code2, aliases: ["code"] },
{ segment: "hosting", label: "Hosting", Icon: Globe },