Components.
Every primitive in norcel, with live previews, copyable code, and the same tokens you'd use in your own project. Build your next site by mixing these into your pages exactly as you see them here.
Foundations
4 componentsThe design tokens that power every component. Override these and the entire system re-skins.
Colors
Semantic tokens — designed for dark interfaces. Override the CSS custom properties to re-skin.
// Tailwind utility class
<div className="bg-canvas text-ink">…</div>
// Raw CSS variable
color: var(--color-ink);Typography
Geist + Geist Mono. Display sizes use negative tracking and the 600 weight ceiling.
<h1 className="text-display-xl font-semibold tracking-[-0.05em]">
Build and ship.
</h1>
<p className="font-mono text-[11px] uppercase tracking-[0.18em] text-white/55">
// technical label
</p>Spacing
Base unit 4px. The brand scale: xxs 4 · xs 8 · sm 12 · md 16 · lg 24 · xl 32 · 2xl 40 · 3xl 48 · 4xl 64 · 5xl 96.
<div className="flex gap-md p-lg">
<Button>Primary</Button>
<Button variant="secondary">Secondary</Button>
</div>Shadows
5-level stacked shadow ladder. Inset ring + 1–2 dark drops. Never a single heavy drop.
<div className="rounded-xl bg-white/[0.02] shadow-level-1">
Standard card
</div>
<div className="rounded-xl bg-ink shadow-level-5">
Featured card
</div>Marketing
6 componentsDrop-in sections for your marketing site. Mix and match to build any landing page.
CodeWindow
A faithful recreation of VS Code on macOS — title bar, tabs, breadcrumb, line numbers, status bar.
1// theme tokens2export const theme<CodeWindow
title="theme.ts — norcel"
tabs={[
{ label: "theme.ts", active: true },
{ label: "globals.css" },
]}
breadcrumbs={["norcel", "src", "theme.ts"]}
>
<CodeLines>
<CodeLine n={1}>
<span className="tk-comment">{"// theme tokens"}</span>
</CodeLine>
</CodeLines>
</CodeWindow>Reveal
IntersectionObserver-powered scroll reveal. Wraps content in opacity + 16 px translate, with stagger delays.
<Reveal delay={2}>
<div className="rounded-lg border border-white/[0.08] bg-white/[0.02] p-6">
I fade in when you scroll me into view.
</div>
</Reveal>SurfaceMockup
Real-looking miniature UI for a given surface. Variants: browser, phone, desktop, window.
// marketing
Ship a beautiful site.
Welcome back.
- Toggle theme⌘D
- New project⌘N
- Search docs⌘/
- Invite teammate⌘I
<SurfaceMockup variant="browser" className="aspect-[16/10]" />
<SurfaceMockup variant="phone" className="aspect-[3/4]" />
<SurfaceMockup variant="desktop" className="aspect-[16/10]" />
<SurfaceMockup variant="window" className="aspect-[16/10]" />SurfaceSwitcher
Interactive tabbed mockup picker. Each item is a real SurfaceMockup + feature list.
// dashboard
Dashboard.
Real-time metrics, charts, and tables — rendered with the same primitives as the marketing site.
- Sidebar with active-row indicator
- Stat cards with trend deltas
- Area chart with brand gradient
- Searchable, filterable data table
<SurfaceSwitcher
defaultId="dashboard"
items={[
{
id: "dashboard",
label: "Dashboard",
description: "...",
features: ["Sidebar", "Charts", "Tables"],
variant: "desktop",
hint: "src/app/dashboard/page.tsx",
},
// ...
]}
/>DeveloperExperience
2-column section: copy + checklist on the left, live VS Code preview on the right.
// developer experience
Built for the people who build.
Every component is a Server Component by default. Every API is fully typed. Every decision is documented.
- Server Components by defaultZero client JS until you opt in.
- Fully typed propsStrict TS, exported variants, IntelliSense.
- Tree-shakeableImport only what you ship.
- Zero runtime depsBuilt on Radix + CVA, that's it.
1import { Button, buttonVariants } from "@/components/ui/button";2import { cn } from "@/lib/utils";3 4export function PrimaryButton() {5 return (6 <Button7 variant="primary"8 size="lg"9 shape="pill"10 className={cn("shadow-level-1")}11 onClick={handleClick}12 >13 Get started14 </Button>15 )16}<DeveloperExperience />Hero
Top-of-page pitch with eyebrow + headline + CTAs + trust strip + stat grid.
/ for the live demo.<Hero
eyebrow={<span>// v2.0 — Live</span>}
title="Build and ship on a premium design system."
subtitle="..."
primaryCta={{ label: "Get started", href: "/components" }}
secondaryCta={{ label: "View components", href: "/components" }}
>
{/* stat grid, code preview, etc. */}
</Hero>Primitives
11 componentsThe building blocks. Buttons, inputs, cards, badges, avatars.
Input
Dark-first chrome: bg-white/[0.04] border-white/[0.08] with focus:ring-2 focus:ring-white/20.
<Input placeholder="you@company.com" prefix={<Mail />} />
<Input type="password" placeholder="••••••••" />
<Input invalid defaultValue="bad value" />Textarea
Same dark-first chrome as Input, multi-line.
<Textarea placeholder="Tell us what you're working on..." rows={4} />Label
The canonical text label that pairs with every form control.
<Label htmlFor="email">Email</Label>
<Input id="email" placeholder="you@company.com" />Card
DNA: white-tint surface + hairline border + stacked shadow + hover transition. Polarized 'featured' variant for highlights.
Default
White/[0.02] + hairline + shadow
Featured
<Card variant="default">
<CardHeader>
<CardTitle>Default card</CardTitle>
<CardDescription>White-tint surface with hairline.</CardDescription>
</CardHeader>
<CardContent>…</CardContent>
</Card>
<Card variant="featured">
<CardHeader>
<CardTitle>Featured card</CardTitle>
</CardHeader>
</Card>Badge
Eyebrow pill, status tag (mono caps), and section eyebrow variants.
/ the design language
<Badge>Default</Badge>
<Badge variant="primary">Primary</Badge>
<StatusTag tone="emerald">best</StatusTag>
<StatusTag tone="amber">free</StatusTag>
<Eyebrow>the design language</Eyebrow>IconContainer
The canonical 36×36 icon square with three tones: neutral, amber, ink.
<IconContainer>
<Sparkles className="h-4 w-4" />
</IconContainer>
<IconContainer tone="amber">
<Sparkles className="h-4 w-4" />
</IconContainer>Avatar
Circular image with fallback initials.
<Avatar>
<AvatarImage src="…" alt="…" />
<AvatarFallback>SC</AvatarFallback>
</Avatar>Separator
A 1px hairline divider. Use to break up sections without adding visual weight.
<Separator />Kbd
Inline keyboard shortcut chip. Mono caps, hairline border.
Press ⌘ K to open the command palette.
<p>Press <Kbd>⌘</Kbd> <Kbd>K</Kbd> to open the command palette.</p>Skeleton
Shimmer-loading placeholder. Use to indicate content is being fetched.
<div className="flex items-center space-x-4">
<Skeleton className="h-12 w-12 rounded-full" />
<div className="space-y-2">
<Skeleton className="h-4 w-[250px]" />
<Skeleton className="h-4 w-[200px]" />
</div>
</div>Forms
5 componentsSelection + input controls for every form pattern.
Checkbox
Polarity-flipped on dark. Hover lifts the border to white/14.
<Checkbox id="agree" defaultChecked />
<Label htmlFor="agree">I agree to the terms</Label>RadioGroup
Single-select with custom card-style options.
<RadioGroup defaultValue="comfortable">
<Label>Spacing</Label>
<RadioGroupItem value="default" id="default" />
<RadioGroupItem value="comfortable" id="comfortable" />
<RadioGroupItem value="compact" id="compact" />
</RadioGroup>Switch
iOS-style toggle. White on dark when active.
<Switch defaultChecked />
<Switch />Select
Native-feeling select with our dark chrome.
<Select>
<SelectTrigger>
<SelectValue placeholder="Select a fruit" />
</SelectTrigger>
<SelectContent>
<SelectItem value="apple">Apple</SelectItem>
<SelectItem value="banana">Banana</SelectItem>
</SelectContent>
</Select>Slider
Range input with white thumb and dark track.
<Slider defaultValue={[75]} max={100} step={1} />Overlays
8 componentsModals, menus, popovers, tooltips — the floating layer.
Alert
Semantic feedback with five tones (default, info, success, warning, error).
Heads up!
Saved
Expiring
Error
<Alert variant="info">
<Info className="h-4 w-4" />
<AlertTitle>Heads up!</AlertTitle>
<AlertDescription>This is an info alert.</AlertDescription>
</Alert>Dialog
Modal surface with the Level 5 shadow + backdrop blur.
<Dialog>
<DialogTrigger asChild>
<Button>Open dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Edit profile</DialogTitle>
<DialogDescription>Make changes to your profile.</DialogDescription>
</DialogHeader>
<DialogFooter>
<Button>Save changes</Button>
</DialogFooter>
</DialogContent>
</Dialog>DropdownMenu
Right-click / kebab / overflow menu. With checkbox items.
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="secondary">Open menu</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Settings</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>Sign out</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>Popover
Floating content panel anchored to a trigger.
<Popover>
<PopoverTrigger asChild>
<Button variant="secondary">Open</Button>
</PopoverTrigger>
<PopoverContent>
<h4 className="text-sm font-semibold">Dimensions</h4>
<p className="text-sm text-white/65">Set the dimensions for the panel.</p>
</PopoverContent>
</Popover>Tooltip
Hover-revealed micro-content. Wraps any trigger.
<Tooltip>
<TooltipTrigger asChild>
<Button variant="secondary">Hover me</Button>
</TooltipTrigger>
<TooltipContent>Helpful tip</TooltipContent>
</Tooltip>Sheet
Side-anchored drawer panel.
import { Sheet, SheetContent, … } from "@/components/ui/sheet"
<Sheet>
<SheetTrigger>Open</SheetTrigger>
<SheetContent side="right">…</SheetContent>
</Sheet>Drawer
Bottom-anchored sheet for mobile-first flows.
import { Drawer, … } from "@/components/ui/drawer"
<Drawer>
<DrawerTrigger>Open</DrawerTrigger>
<DrawerContent>…</DrawerContent>
</Drawer>Command
⌘K command palette — search any component / page / action.
- Press ⌘K to open
<CommandDialog open={open} onOpenChange={setOpen}>
<CommandInput placeholder="Type a command…" />
<CommandList>
<CommandGroup heading="Suggestions">
<CommandItem>New project</CommandItem>
<CommandItem>Search docs</CommandItem>
</CommandGroup>
</CommandList>
</CommandDialog>Layout
7 componentsStructural components for composing pages.
Tabs
Segmented content switcher with an active pill.
<Tabs defaultValue="overview">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
<TabsTrigger value="settings">Settings</TabsTrigger>
</TabsList>
<TabsContent value="overview">…</TabsContent>
</Tabs>Accordion
Vertically stacked, mutually exclusive content panels.
<Accordion type="single" collapsible>
<AccordionItem value="item-1">
<AccordionTrigger>Question?</AccordionTrigger>
<AccordionContent>Answer.</AccordionContent>
</AccordionItem>
</Accordion>Collapsible
Single panel that expands/collapses. Lower-level than Accordion.
<Collapsible>
<CollapsibleTrigger>Toggle</CollapsibleTrigger>
<CollapsibleContent>Hidden content</CollapsibleContent>
</Collapsible>Pagination
Numbered page navigation with prev/next.
<Pagination>
<PaginationContent>
<PaginationPrevious />
<PaginationItem><PaginationLink href="#">1</PaginationLink></PaginationItem>
<PaginationItem><PaginationLink href="#" isActive>2</PaginationLink></PaginationItem>
<PaginationItem><PaginationLink href="#">3</PaginationLink></PaginationItem>
<PaginationNext />
</PaginationContent>
</Pagination>Table
Data table with mono-caps headers and dividers.
| Name | Status | Role |
|---|---|---|
| Sarah Chen | active | Admin |
| Marcus Kim | active | Member |
| Priya Patel | pending | Member |
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Status</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>Jane</TableCell>
<TableCell>Active</TableCell>
</TableRow>
</TableBody>
</Table>ScrollArea
Custom scrollbar wrapper. Use inside dropdowns, sidebars, modals.
<ScrollArea className="h-48 w-48 rounded-md border">
<div className="p-4">…long content…</div>
</ScrollArea>Feedback
2 componentsToasts, progress bars, and other status indicators.
Toast
Sonner-powered. Stacks bottom-right. Auto-dismisses.
import { toast } from "@/components/ui/sonner"
toast.success("Saved!")
toast.error("Something went wrong.")
toast.info("New version available.")Progress
Horizontal progress bar with white fill on dark.
<Progress value={65} />Build something like this.
Every section on the marketing site — the hero, the surface switcher, the developer experience, the pricing, the FAQ, the testimonials, the CTA, the logo cloud, the code window — is a component you can copy into your own app. Same tokens, same primitives, same look.