Files
vibn-frontend/design-templates/VIBN (2)/Vibn UI Showcase.html

688 lines
30 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vibn AI Templates — UI showcase</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=DM+Serif+Display:ital@0;1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="vibn-ai-templates/tokens.css">
<style>
html, body { margin: 0; padding: 0; min-height: 100%; background: #f0eee9; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif; }
</style>
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel" src="design-canvas.jsx"></script>
<script type="text/babel" src="vibn-ai-templates/icons.jsx"></script>
<script type="text/babel" src="vibn-ai-templates/components.jsx"></script>
<script type="text/babel" src="vibn-ai-templates/shells.jsx"></script>
<script type="text/babel">
const { DesignCanvas, DCSection, DCArtboard,
Button, IconButton, Field, Input, Textarea, Select, FieldGroup,
Checkbox, Radio, Switch, Card, CardHeader, Divider,
Badge, Avatar, AvatarStack, Tabs, Table, Modal, Banner, KBD, Spinner,
SidebarShell, TopbarShell, RailShell,
AuthCenteredShell, AuthSplitShell, AuthGlassShell,
Icon, icons, VibnMark } = window;
// ─── Section helpers ────────────────────────────────────────
const SubHeading = ({ children }) => (
<div style={{
fontSize: "var(--text-xs)", color: "var(--text-3)",
letterSpacing: "0.08em", textTransform: "uppercase",
fontWeight: 500, marginBottom: 10,
}}>{children}</div>
);
const ThemeFrame = ({ theme, children }) => (
// Themed wrapper — note: the artboard contents must be wrapped in
// a theme class so all CSS-var reads inside re-bind to that theme.
<div className={`theme-${theme}`} style={{ width: "100%", height: "100%" }}>
<div className="vibn-app" style={{ width: "100%", height: "100%", overflow: "auto" }}>
{children}
</div>
</div>
);
// ─── 1 · Foundations / token swatches ───────────────────────
const Foundations = ({ theme }) => (
<div style={{ padding: 32 }}>
<h1 style={{
margin: 0, fontFamily: "var(--font-display)",
fontSize: "var(--text-3xl)", letterSpacing: "-0.02em", fontWeight: 500,
}}>Theme · {theme}</h1>
<p style={{ color: "var(--text-2)", marginTop: 6, fontSize: "var(--text-md)" }}>
Same components, four CSS-variable themes. Tokens, type and surfaces.
</p>
<div style={{ marginTop: 28, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }}>
<Card>
<CardHeader title="Surface" subtitle="Page chrome + cards"/>
<div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 10 }}>
{[
["--bg", "Page bg"],
["--surface", "Card"],
["--surface-2", "Card alt"],
["--surface-alt", "Sidebar"],
["--border", "Border"],
].map(([v, l]) => (
<div key={v}>
<div style={{
height: 56, borderRadius: "var(--radius)",
background: `var(${v})`, border: "1px solid var(--border)",
}}/>
<div style={{ fontSize: 11, color: "var(--text-3)", marginTop: 6 }}>{l}</div>
<div style={{ fontSize: 10, fontFamily: "var(--font-mono)", color: "var(--text-3)" }}>{v}</div>
</div>
))}
</div>
</Card>
<Card>
<CardHeader title="Accents & semantics"/>
<div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 10 }}>
{[
["--accent", "Accent"],
["--accent-2", "Accent 2"],
["--success", "Success"],
["--warn", "Warn"],
["--danger", "Danger"],
].map(([v, l]) => (
<div key={v}>
<div style={{ height: 56, borderRadius: "var(--radius)", background: `var(${v})` }}/>
<div style={{ fontSize: 11, color: "var(--text-3)", marginTop: 6 }}>{l}</div>
<div style={{ fontSize: 10, fontFamily: "var(--font-mono)", color: "var(--text-3)" }}>{v}</div>
</div>
))}
</div>
</Card>
<Card>
<CardHeader title="Type scale"/>
<div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
{[
["Display · 38", { fontSize: 38, fontWeight: 500, fontFamily: "var(--font-display)", letterSpacing: "-0.02em" }],
["Heading · 22", { fontSize: 22, fontWeight: 600, letterSpacing: "-0.01em" }],
["Body · 13", { fontSize: 13 }],
["Caption · 11", { fontSize: 11, color: "var(--text-3)" }],
["Mono · 12", { fontFamily: "var(--font-mono)", fontSize: 12 }],
].map(([l, s], i) => (
<div key={i} style={{ ...s }}>{l} Modern SaaS, designed for everyone.</div>
))}
</div>
</Card>
<Card>
<CardHeader title="Radii, shadows, motion"/>
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 12, marginBottom: 14 }}>
{["sm", "", "lg"].map(s => (
<div key={s} style={{
height: 50,
background: "var(--surface-2)",
border: "1px solid var(--border)",
borderRadius: `var(--radius${s ? `-${s}` : ""})`,
display: "flex", alignItems: "center", justifyContent: "center",
fontSize: 11, color: "var(--text-3)",
}}>radius-{s || "default"}</div>
))}
</div>
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 12 }}>
{[
["shadow-sm", "var(--shadow-sm)"],
["shadow", "var(--shadow)"],
["shadow-lg", "var(--shadow-lg)"],
].map(([l, sh]) => (
<div key={l} style={{
height: 50, background: "var(--surface)",
border: "1px solid var(--border)", borderRadius: "var(--radius)",
boxShadow: sh, display: "flex", alignItems: "center", justifyContent: "center",
fontSize: 11, color: "var(--text-3)",
}}>{l}</div>
))}
</div>
</Card>
</div>
</div>
);
// ─── 2 · Form atoms ─────────────────────────────────────────
const FormAtoms = () => {
const [tab, setTab] = React.useState("Account");
const [sw1, setSw1] = React.useState(true);
const [sw2, setSw2] = React.useState(false);
const [chk, setChk] = React.useState(true);
const [seg, setSeg] = React.useState("Week");
return (
<div style={{ padding: 32 }}>
<h1 style={{
margin: 0, fontFamily: "var(--font-display)", fontSize: "var(--text-2xl)",
fontWeight: 500, letterSpacing: "-0.02em",
}}>Forms & buttons</h1>
<div style={{ marginTop: 24, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }}>
<Card>
<CardHeader title="Buttons" subtitle="Variants, sizes, states"/>
<SubHeading>Variants</SubHeading>
<div style={{ display: "flex", gap: 8, flexWrap: "wrap", marginBottom: 16 }}>
<Button>Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="destructive">Delete</Button>
<Button loading>Loading</Button>
<Button disabled>Disabled</Button>
</div>
<SubHeading>Sizes & icons</SubHeading>
<div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap" }}>
<Button size="sm" leadingIcon={<Icon name="plus" size={12}/>}>New deal</Button>
<Button>Sign in <Icon name="arrow" size={13}/></Button>
<Button size="lg" variant="secondary">Get a demo</Button>
<IconButton name="bell" label="Notifications"/>
<IconButton name="settings" variant="secondary" label="Settings"/>
</div>
</Card>
<Card>
<CardHeader title="Fields" subtitle="Input, hint, error, password"/>
<Field label="Work email" hint="We'll send a 6-digit code.">
<Input value="mira@acme.io" leadingIcon={<Icon name="inbox" size={14}/>} autofocus/>
</Field>
<Field label="Password">
<Input type="password" value="••••••••••"
trailingIcon={<Icon name="eye" size={14}/>}/>
</Field>
<Field label="Workspace name" error="That name is taken.">
<Input value="lattice" invalid/>
</Field>
<Field label="Notes" optional>
<Textarea placeholder="Anything we should know?" rows={3}/>
</Field>
<Field label="Role">
<Select value="Admin" options={["Owner", "Admin", "Member", "Guest"]}/>
</Field>
</Card>
<Card>
<CardHeader title="Controls"/>
<SubHeading>Switches</SubHeading>
<div style={{ display: "flex", flexDirection: "column", gap: 14, marginBottom: 14 }}>
<Switch checked={sw1} onChange={setSw1}
label="Email me digests" hint="Weekly summary every Monday at 9am."/>
<Switch checked={sw2} onChange={setSw2}
label="Show beta features"/>
</div>
<SubHeading>Checkboxes & radios</SubHeading>
<div style={{ display: "flex", flexDirection: "column", gap: 10, marginBottom: 14 }}>
<Checkbox checked={chk} onChange={setChk} label="I agree to the Terms" hint="And the Privacy Policy."/>
<Checkbox checked indeterminate label="Select some items"/>
<div style={{ display: "flex", gap: 16 }}>
<Radio checked={true} label="Monthly"/>
<Radio checked={false} label="Yearly · save 20%"/>
</div>
</div>
<SubHeading>Segmented</SubHeading>
<FieldGroup options={["Day", "Week", "Month", "Quarter"]} value={seg} onChange={setSeg}/>
</Card>
<Card>
<CardHeader title="Tabs"/>
<SubHeading>Underline</SubHeading>
<Tabs items={[
{ label: "Account" }, { label: "Members", count: 8 },
{ label: "Billing" }, { label: "API" },
]} active={tab} onChange={setTab}/>
<div style={{ marginTop: 14 }}>
<SubHeading>Pill</SubHeading>
<Tabs variant="pill" items={[
{ label: "Day" }, { label: "Week" }, { label: "Month" }, { label: "Year" },
]} active="Week"/>
</div>
</Card>
</div>
</div>
);
};
// ─── 3 · Display atoms ──────────────────────────────────────
const DisplayAtoms = () => {
const [modalOpen, setModalOpen] = React.useState(false);
return (
<div style={{ padding: 32 }}>
<h1 style={{
margin: 0, fontFamily: "var(--font-display)", fontSize: "var(--text-2xl)",
fontWeight: 500, letterSpacing: "-0.02em",
}}>Display & feedback</h1>
<div style={{ marginTop: 24, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }}>
<Card>
<CardHeader title="Badges & avatars"/>
<SubHeading>Tones</SubHeading>
<div style={{ display: "flex", gap: 8, flexWrap: "wrap", marginBottom: 16 }}>
<Badge>Neutral</Badge>
<Badge tone="accent" dot>Accent</Badge>
<Badge tone="success" dot>Active</Badge>
<Badge tone="warn" dot>Invited</Badge>
<Badge tone="danger" dot>Suspended</Badge>
<Badge tone="info">v4.2.1</Badge>
</div>
<SubHeading>Avatars</SubHeading>
<div style={{ display: "flex", gap: 14, alignItems: "center" }}>
<Avatar name="Mira Reyes" size={24}/>
<Avatar name="Theo Roux" size={32}/>
<Avatar name="Devi Patel" size={40} status="online"/>
<Avatar name="Sun Kim" size={48} status="busy"/>
<AvatarStack items={[
{name:"Mira Reyes"},{name:"Theo Roux"},{name:"Devi Patel"},
{name:"Sun Kim"},{name:"Ade Nwosu"},{name:"Linnea Berg"},
{name:"Jamal Frost"}
]}/>
</div>
</Card>
<Card>
<CardHeader title="Banners"/>
<Banner title="Workspace upgrade pending" tone="warn"
action={<Button size="sm" variant="secondary">Review</Button>}>
1 invitation hasn't been accepted yet — sent 3 days ago.
</Banner>
<div style={{ height: 10 }}/>
<Banner tone="success" title="Saved">Your changes were saved.</Banner>
<div style={{ height: 10 }}/>
<Banner tone="danger" title="Couldn't connect">Please check your network and try again.</Banner>
</Card>
<Card style={{ gridColumn: "span 2" }}>
<CardHeader title="Table" subtitle="Members of the workspace"
action={<Button size="sm" leadingIcon={<Icon name="plus" size={12}/>}>Invite</Button>}/>
<Table
columns={[
{ key: "name", label: "Name", render: r => (
<div style={{ display: "flex", alignItems: "center", gap: 10 }}>
<Avatar name={r.name} size={26}/>
<div>
<div style={{ fontWeight: 500 }}>{r.name}</div>
<div style={{ fontSize: 11, color: "var(--text-3)" }}>{r.email}</div>
</div>
</div>
)},
{ key: "role", label: "Role", render: r => <Badge tone="accent">{r.role}</Badge> },
{ key: "status", label: "Status", render: r =>
<Badge dot tone={r.status === "Active" ? "success" :
r.status === "Invited" ? "warn" : "danger"}>{r.status}</Badge> },
{ key: "last", label: "Last active" },
{ key: "act", label: "", align: "right", width: 32,
render: () => <IconButton name="more" size="sm" label="More"/> },
]}
rows={[
{ id: 1, name: "Mira Reyes", email: "mira@vibn.co", role: "Owner", status: "Active", last: "now" },
{ id: 2, name: "Theo Roux", email: "theo@vibn.co", role: "Admin", status: "Active", last: "12 min" },
{ id: 3, name: "Devi Patel", email: "devi@vibn.co", role: "Admin", status: "Active", last: "1 hour" },
{ id: 4, name: "Linnea Berg", email: "linnea@vibn.co", role: "Member", status: "Invited", last: "" },
{ id: 5, name: "Elin Roos", email: "elin@vibn.co", role: "Member", status: "Suspended", last: "14 days" },
]}
selectable
selected={[1, 2]}
/>
</Card>
<Card style={{ gridColumn: "span 2" }}>
<CardHeader title="Modal"/>
<div style={{ display: "flex", gap: 10, alignItems: "center" }}>
<Button onClick={() => setModalOpen(true)}>Open modal</Button>
<span style={{ fontSize: 12, color: "var(--text-3)" }}>
Press <KBD>⌘ + Enter</KBD> to confirm
</span>
</div>
<Modal
open={modalOpen} onClose={() => setModalOpen(false)}
title="Delete workspace?"
description="This will permanently remove all data in Lattice Studio. This action cannot be undone."
footer={<>
<Button variant="secondary" onClick={() => setModalOpen(false)}>Cancel</Button>
<Button variant="destructive">Yes, delete it</Button>
</>}
>
<Field label="Type the workspace name to confirm">
<Input placeholder="lattice-studio"/>
</Field>
</Modal>
</Card>
</div>
</div>
);
};
// ─── 4 · In-product shells ──────────────────────────────────
const SidebarDemo = () => (
<SidebarShell
brand={{ name: "Lattice Studio" }}
sections={[
{ items: [
{ id: "home", label: "Home", icon: "home" },
{ id: "inbox", label: "Inbox", icon: "inbox", count: 12 },
{ id: "tasks", label: "Tasks", icon: "check", count: 3 },
]},
{ title: "Views", items: [
{ id: "co", label: "Companies", icon: "building", active: true },
{ id: "people", label: "People", icon: "people" },
{ id: "deals", label: "Opportunities", icon: "target" },
]},
{ title: "Tools", items: [
{ id: "i", label: "Insights", icon: "bar" },
{ id: "f", label: "Automations", icon: "workflow"},
{ id: "d", label: "Docs", icon: "doc" },
]},
{ title: "Admin", items: [
{ id: "s", label: "Settings", icon: "settings" },
]},
]}
user={{ name: "Mira Reyes", email: "mira@vibn.co" }}
>
<div style={{ padding: 28 }}>
<h1 style={{ margin: 0, fontSize: 26, fontWeight: 600 }}>Companies</h1>
<p style={{ color: "var(--text-2)", fontSize: 13, marginTop: 6 }}>
248 records · last sync 4 minutes ago
</p>
<div style={{ marginTop: 18 }}>
<Banner tone="info" title="Vibn 4.0 is live">
Workspace-wide rollout begins next Monday. Read the changelog →
</Banner>
</div>
</div>
</SidebarShell>
);
const TopbarDemo = () => {
const [tab, setTab] = React.useState("Activity");
return (
<TopbarShell
brand={{ name: "Lattice" }}
breadcrumb={[
{ avatar: "Mira Reyes", label: "mira-reyes" },
{ label: "northstar-logistics", badge: "Pro" },
]}
tabs={[
{ label: "Overview" }, { label: "Activity", count: 18 },
{ label: "People" }, { label: "Notes" }, { label: "Files" },
]}
activeTab={tab}
onTabChange={setTab}
user={{ name: "Mira Reyes" }}
>
<div style={{ padding: 32 }}>
<h1 style={{ margin: 0, fontSize: 28, fontWeight: 600, letterSpacing: "-0.02em" }}>Northstar Logistics</h1>
<div style={{ display: "flex", gap: 8, marginTop: 8 }}>
<Badge tone="success" dot>Customer</Badge>
<Badge tone="accent">Tier 1</Badge>
<Badge>EMEA</Badge>
</div>
<div style={{ marginTop: 24, display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 16 }}>
{[
{ l: "Pipeline", v: "146k", s: "+12k 30d"},
{ l: "Closed-won", v: "220k", s: "lifetime"},
{ l: "Health", v: "82", s: "stable"},
].map(k => (
<Card key={k.l} padding={18}>
<div style={{ fontSize: 11, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: "0.06em" }}>{k.l}</div>
<div style={{ fontSize: 24, fontWeight: 600, marginTop: 6 }}>{k.v}</div>
<div style={{ fontSize: 11, color: "var(--text-2)", marginTop: 2 }}>{k.s}</div>
</Card>
))}
</div>
</div>
</TopbarShell>
);
};
const RailDemo = () => (
<RailShell
brand={{ name: "Vibn" }}
items={[
{ id: "home", icon: "home" },
{ id: "inbox", icon: "inbox", badge: 9 },
{ id: "co", icon: "building" },
{ id: "ppl", icon: "people" },
{ id: "deals", icon: "target", badge: 2 },
]}
activeRail="co"
secondaryTitle="Companies"
secondary={
<div>
{["Northstar Logistics", "Halcyon", "Kestrel", "Mossbank", "Verra", "Brooke Foods"].map((n, i) => (
<div key={n} style={{
padding: "8px 10px", borderRadius: "var(--radius-sm)", fontSize: 13,
background: i === 0 ? "var(--surface-alt)" : "transparent",
color: i === 0 ? "var(--text)" : "var(--text-2)",
display: "flex", alignItems: "center", gap: 10, cursor: "pointer",
}}>
<Avatar name={n} size={22}/>
<span style={{ flex: 1 }}>{n}</span>
{i === 0 && <Badge tone="success" dot>active</Badge>}
</div>
))}
</div>
}
user={{ name: "Mira Reyes" }}
>
<div style={{ padding: 32 }}>
<h1 style={{ margin: 0, fontSize: 24, fontWeight: 600 }}>Northstar Logistics</h1>
<p style={{ color: "var(--text-2)", fontSize: 13, marginTop: 6 }}>
Customer since Aug 2024 · 6 people · €146k pipeline
</p>
</div>
</RailShell>
);
// ─── 5 · Auth shells ────────────────────────────────────────
const SocialRow = () => (
<div style={{ display: "flex", gap: 8 }}>
<Button variant="secondary" full>Google</Button>
<Button variant="secondary" full>Microsoft</Button>
<Button variant="secondary" full>SSO</Button>
</div>
);
const AuthCenteredDemo = () => (
<AuthCenteredShell brand={{ name: "Lattice" }}>
<h1 style={{
margin: 0, fontFamily: "var(--font-display)",
fontSize: "var(--text-xl)", fontWeight: 600, letterSpacing: "-0.01em",
}}>Welcome back</h1>
<p style={{ fontSize: 13, color: "var(--text-2)", margin: "6px 0 22px" }}>
Sign in to your Lattice workspace.
</p>
<SocialRow/>
<Divider label="or with email"/>
<Field label="Email"><Input value="mira@lattice.co" autofocus/></Field>
<Field label="Password"><Input type="password" value=""
trailingIcon={<Icon name="eye" size={14}/>}/></Field>
<Button full>Sign in <Icon name="arrow" size={13}/></Button>
<div style={{ fontSize: 12, textAlign: "center", marginTop: 18, color: "var(--text-2)" }}>
New here? <span style={{ color: "var(--text)", fontWeight: 500 }}>Create an account</span>
</div>
</AuthCenteredShell>
);
const AuthSplitDemo = () => (
<AuthSplitShell
brand={{ name: "Lattice" }}
hero={{
badge: "Lattice 4.0 · agents that draft for you",
headline: "The workspace where good ideas compound.",
sub: "One luminous surface for docs, canvases, contacts and pipelines.",
quote: {
body: "Replaced three tools in our first week. Lattice is what every CRM should have been.",
author: "Devi Patel", role: "Head of Sales, Halcyon",
},
}}
>
<h1 style={{
margin: 0, fontFamily: "var(--font-display)", fontSize: 26,
fontWeight: 600, letterSpacing: "-0.02em",
}}>Sign in to Lattice</h1>
<p style={{ fontSize: 13, color: "var(--text-2)", margin: "6px 0 22px" }}>
Welcome back. Pick how you'd like to continue.
</p>
<SocialRow/>
<Divider label="or with email"/>
<Field label="Email"><Input value="mira@lattice.co" autofocus/></Field>
<Field label="Password"><Input type="password" value=""
trailingIcon={<Icon name="eye" size={14}/>}/></Field>
<Button full>Sign in <Icon name="arrow" size={13}/></Button>
<div style={{ marginTop: 18 }}>
<Banner tone="info" title="SAML / SSO for your company?"
action={<Button size="sm" variant="ghost">Use SSO →</Button>}>
Single sign-on is available on the Pro plan.
</Banner>
</div>
</AuthSplitShell>
);
const AuthGlassDemo = () => (
<AuthGlassShell brand={{ name: "Lattice" }} eyebrow="BETA · early access">
<h1 style={{
margin: 0, fontFamily: "var(--font-display)", fontSize: 32,
fontWeight: 500, letterSpacing: "-0.03em",
}}>Start your workspace.</h1>
<p style={{ fontSize: 14, color: "var(--text-2)", margin: "10px 0 22px" }}>
Free for 10 people. No card. 60 seconds to set up.
</p>
<SocialRow/>
<Divider label="or with email"/>
<Field label="Work email"><Input value="mira@lattice.co" autofocus/></Field>
<Field label="Password" hint="10+ chars · 1 number · 1 symbol">
<Input type="password" value="" trailingIcon={<Icon name="eye" size={14}/>}/>
</Field>
<Checkbox checked label="I agree to Vibn's Terms and Privacy Policy."
style={{ margin: "4px 0 16px" }}/>
<Button full>Create my workspace <Icon name="arrow" size={13}/></Button>
</AuthGlassShell>
);
// ─── App: design canvas with all 4 themes side-by-side ──────
const W = 1300, H = 800;
const themes = ["minimal", "dark", "glass", "editorial"];
function App() {
return (
<DesignCanvas>
<DCSection
id="foundations"
title="Foundations"
subtitle="The same token surfaces, in four themes. tokens.css is the source of truth."
>
{themes.map(t => (
<DCArtboard key={t} id={`f-${t}`} label={`${t}`} width={W} height={H}>
<ThemeFrame theme={t}><Foundations theme={t}/></ThemeFrame>
</DCArtboard>
))}
</DCSection>
<DCSection
id="forms"
title="Forms & buttons"
subtitle="Button variants, every field type, controls, tabs."
>
{themes.map(t => (
<DCArtboard key={t} id={`forms-${t}`} label={`${t}`} width={W} height={H}>
<ThemeFrame theme={t}><FormAtoms/></ThemeFrame>
</DCArtboard>
))}
</DCSection>
<DCSection
id="display"
title="Display & feedback"
subtitle="Badges, avatars, banners, table, modal."
>
{themes.map(t => (
<DCArtboard key={t} id={`display-${t}`} label={`${t}`} width={W} height={H + 100}>
<ThemeFrame theme={t}><DisplayAtoms/></ThemeFrame>
</DCArtboard>
))}
</DCSection>
<DCSection
id="shells-app"
title="In-product shells · Sidebar"
subtitle="One shell, four themes."
>
{themes.map(t => (
<DCArtboard key={t} id={`side-${t}`} label={`Sidebar · ${t}`} width={W} height={H}>
<ThemeFrame theme={t}><SidebarDemo/></ThemeFrame>
</DCArtboard>
))}
</DCSection>
<DCSection
id="shells-topbar"
title="In-product shells · Topbar"
subtitle="Breadcrumb + ⌘K + tabs."
>
{themes.map(t => (
<DCArtboard key={t} id={`top-${t}`} label={`Topbar · ${t}`} width={W} height={H}>
<ThemeFrame theme={t}><TopbarDemo/></ThemeFrame>
</DCArtboard>
))}
</DCSection>
<DCSection
id="shells-rail"
title="In-product shells · Rail"
subtitle="Icon rail + secondary panel."
>
{themes.map(t => (
<DCArtboard key={t} id={`rail-${t}`} label={`Rail · ${t}`} width={W} height={H}>
<ThemeFrame theme={t}><RailDemo/></ThemeFrame>
</DCArtboard>
))}
</DCSection>
<DCSection
id="auth-centered"
title="Auth shells · Centered card"
subtitle="Sign-in card on a soft background."
>
{themes.map(t => (
<DCArtboard key={t} id={`auth-c-${t}`} label={`Centered · ${t}`} width={W} height={H}>
<ThemeFrame theme={t}><AuthCenteredDemo/></ThemeFrame>
</DCArtboard>
))}
</DCSection>
<DCSection
id="auth-split"
title="Auth shells · Split hero"
subtitle="Storytelling panel on the left, form on the right."
>
{themes.map(t => (
<DCArtboard key={t} id={`auth-s-${t}`} label={`Split · ${t}`} width={W} height={H}>
<ThemeFrame theme={t}><AuthSplitDemo/></ThemeFrame>
</DCArtboard>
))}
</DCSection>
<DCSection
id="auth-glass"
title="Auth shells · Glass card"
subtitle="Frosted card on a vibrant backdrop."
>
{themes.map(t => (
<DCArtboard key={t} id={`auth-g-${t}`} label={`Glass · ${t}`} width={W} height={H}>
<ThemeFrame theme={t}><AuthGlassDemo/></ThemeFrame>
</DCArtboard>
))}
</DCSection>
</DesignCanvas>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>