Fabrication AI
Tokens, components, and patterns for building Fabrication AI, grouped by type and searchable. Built on Coss UI (Base UI + Tailwind v4) with our design tokens and Lucide.
Atomic design tokens from @fabrication-ai/ui/styles/tokens.css. Always consume them via Tailwind utilities (bg-primary, text-muted-foreground, font-heading, rounded-lg). Never hardcode values.
Headings: Geist (font-heading, auto-applied to h1-h6)
Operate with AI you can trust
Body & UI: Inter (font-sans, the document default)
The default paragraph size for prose and UI copy.
font-mono · const loop = ground(answer)
Logo only: Space Grotesk (font-display)
Fabrication AI
One icon family across the product. Outlined icons with a 2px stroke, currentColor, and existing control sizes. Import IconGlyph and named glyphs from @fabrication-ai/ui/icons.
The animated geodesic 'digital twin' and its building blocks. GeodesicSphere is a power-aware Canvas 2D renderer that pauses while hidden or idle; TwinGlyph/TwinAnchor/ProductMock compose it; ThreadMarker/HudCallout/RevealWord/TwinPlayer are its supporting UI. From @fabrication-ai/ui/graph.
Hero
A large, expressive entrance that still auto-rests.
High density · Auto-rest · Classic orb
Section
A decorative waypoint for a marketing section.
Balanced density · Auto-rest · Classic orb
Anchor
A compact, already-drawn mark that moves only when asked.
Low density · Move on interaction · Classic orb
Agents
A resting product state that communicates connected agents.
Balanced density · Move on interaction · Connected agents
Start with a use case
Choose the closest role, then refine only what the design needs.
Most designs should keep the preset values. Adjust these only to fit a specific composition.
What this configuration does
This high density orb shows the classic geodesic twin. It gently spins and automatically comes to rest. It is open to drag and tap and draws itself in when it first appears.
The labels above describe design intent; these are the corresponding component values.
<GeodesicSphere
detail="full"
motion="ambient"
mode="idle"
radiusFactor={0.36}
spinSpeed={0.11}
/>Company intelligence
The twin connects objectives, decisions, and evidence so every team can work from the same reality.
The glyph intentionally steps aside on smaller canvases.
Keep the section copy and calls to action; reveal this decorative composition at the xl breakpoint.
Decorative section companion · three short labels · desktop only
One supporting idea
Use one glyph beside one section message, never as page furniture.
Meaning stays in the copy
TwinGlyph is aria-hidden; the neighboring text must stand alone.
Reserve horizontal space
Labels extend outside the orb, so keep the complete motif in its own column.
Render this inside a desktop-only column; the section owns the responsive fallback.
<TwinGlyph
tags={["objectives", "decisions", "evidence"]}
tagSide="left"
className="size-40"
/>Generating design options…
Exploring layouts, type pairings, and semantic color tokens.
<BorderBeam size="md" colorVariant="colorful" strength={0.86}>
<Card>Content</Card>
</BorderBeam>The 'act here' signal: MetalFx wraps the one button or input a surface most wants the user to act on and paints an animated WebGL metal chrome over it (vendored from metal-fx). Interactive elements only, one per surface — metal drives the click, while the border beam (AiBeam) means AI is working; the two never swap roles. It normalizes the child's own border/background so the metal becomes the visible chrome, while the child keeps focus, typing, and a11y. Every instance shares one GL context — and one preset: the last-rendered instance's preset wins page-wide, so all examples below follow the playground's preset.
<MetalFx variant="button" preset="chromatic" strength={0.90} theme={theme}>
<Button variant="secondary" className="rounded-full px-6">Upgrade to Pro</Button>
</MetalFx>How Fabrication AI moves: the principles every animation must pass, the shared easing/duration tokens, and the AI activity beam. Distilled from Emil Kowalski's design-engineering skills — see the linked repo for the source material.
Every animation answers “why?” — feedback, state, spatial continuity, or preventing a jarring change. Frequency sets the budget: actions hit 100+ times a day (keyboard shortcuts, command palettes) get no animation; occasional UI (modals, toasts) gets the standard treatment; rare moments (first-run, success) may spend delight.
Entering or exiting → (start fast — use the strong curves, not the weak built-ins). Moving/morphing on screen → . Hover/color → . Constant loops → . Never ease-in on UI — it delays the exact moment the user is watching.
Press feedback (120ms) · dropdowns, toasts, panels (200ms) · modals, drawers, shell chrome (300ms). Marketing reveals may run 400–900ms (//) — product UI never borrows those tiers.
Nothing appears from — enter from 0.95–0.97 + fade. Popups scale from their trigger (); only centered modals are exempt. Anything reversible or rapidly re-triggered uses transitions (they retarget mid-flight), never keyframes; gestures use springs that keep the release velocity.
/// trigger layout every frame, and is never allowed. Tailwind v4 note: / set the native / properties, so transition lists must name them — , not .
Under , keep the opacity/color feedback and drop the movement: variants in CSS, (or ) in Motion code. Ambient loops stop; beams freeze to a static glow — the state signal survives.
JS tokens from ; CSS utilities register in . returns the standard marketing reveal, opacity-only under reduced motion.
The border beam is the product's AI activity signal: a beam on a surface means AI is active there, right now. Declare intent with — never decorate idle UI with it, and never compose by hand in product code. When a request starts, the input's pulse hands off to the destination surface's rotating beam.
Drafting the research plan…
Streaming panels, task cards, list rows.
Focus = ready pulse (“AI is listening”); send = the working beam.
Hover arms it; click shows “AI heard you” until the destination surface takes over.
Inputs, selection controls, and labels. Pair every control with a <Label> for accessibility.
Type, or press the mic to dictate.
Badges, avatars, cards, separators, skeletons, and progress for presenting content and state.
98.6%
Runs
184
Sources used
1,248
Cards should always sit on a background surface unless an exception is explicitly applied. The card edge is four stacked hairlines on the foreground token — light mode: top foreground/5, sides foreground/10, bottom foreground/15; dark mode inverts it (top foreground/25, sides foreground/15, bottom foreground/10). On interactive cards, hover doubles each line's opacity.
Alerts, tooltips, and spinners for communicating status.
Hover a beacon for guidance. The first mark coaches everyone; the other two are audience-gated — switch persona to see them swap.
The designed absence of content, and often a feature's first impression. Every empty state orients (what belongs here), motivates (why it matters to this person's job), and activates (one obvious next step). EmptyState's required kind prop picks the right design: first-use invests, cleared celebrates, no-results recovers. Full copy rules live in docs/DESIGN.md.
Product lead
Shapes what gets built
Turns a one-line idea into a reviewed, evidence-backed spec the team can commit to.
Give the agent a topic and each run streams in here, grounded in the twin.
Connect a source and every claim your agents make gets grounded against it. Drift shows up here the moment it happens.
Every drifted claim has been re-grounded. New drift lands here the moment it's detected.
Type something that matches nothing to hit the no-results state. The recovery action is the way out.
Every empty state says what belongs here, why filling it is worth the effort, and gives one obvious next step. Anchor on the value the user came for, never the mechanics of the feature.
is an onboarding moment: invest in it. is a small win: acknowledge it. is a dead end: always hand the user an exit. The prop is required so the choice always gets made.
“See which claims drift off-source” beats “Your dashboard is empty.” Write for the specific persona and the job they're accountable for, in their vocabulary; an empty state written for “the user” is written for no one. Short sentences, plain words, and never an em-dash.
Exactly one Button; everything else looks secondary ( / / ). The empty moment is when the user has the least context, so don't hand them a menu. And always give the empty state its own action, even when the page header offers the same one.
“You haven't added anything yet” blames the user; a gray “No data available” reads like an error. Describe the opportunity, and make the state look intentional so it's never mistaken for a bug or a loading failure.
People understand a feature by seeing it filled in: use with skeleton rows or miniature real components on first-use. Match tone to the moment: warm for first-use, brisk for no-results, a quiet win for cleared.
Coss Dialog (on Base UI) handles focus trapping, scroll lock, and Escape. DialogPopup is self-contained.
Loading indicators for async states — motion SVG spinners, pulse skeletons, terminal cursor, text shimmer, and the ThinkingOrb thought-orbs for AI/agent work (talking to the graph, fetching company knowledge, generating).
import { ThinkingOrb } from "@fabrication-ai/ui/loaders";
<ThinkingOrb state="working" size={64} />state="working"state="searching"state="solving"state="composing"Grounding in company knowledge…
Background treatments for pages and sections. DotGrid is a canvas-style dot grid (foreground dots, theme-aware opacity, edge fade, cursor-reactive squares) — drop it into any relative container.
Brand mark and lockups from @fabrication-ai/ui/app. LogoMark is the glyph alone; Logo composes mark + wordmark as a horizontal (default) or stacked lockup. Uses text-foreground / currentColor for light and dark. Size with sm / md / lg; stacked marks are 50% larger than horizontal. Pass compactOnMobile to hide the wordmark below md (mark-only in compact headers). Override the wordmark string for site-specific brands (e.g. design system).
The hex-nut mark is a placeholder drawn from a single path in @fabrication-ai/ui/brand, which also produces the favicons, app icons and preview tiles. The shared typography, surfaces, and components are the base system; approved brand artwork can replace the mark without changing component APIs.
Wordmark hides below the breakpoint — resize the viewport to see mark-only on small screens. Used in the marketing navbar.
Override the wordmark for site-specific brands. The design-system header uses this with .
Config-driven building blocks for the logged-in product shell. The WorkspaceSwitcher reads workspaces and routing from the app-shell config (or props) and stays on the current page when you switch. See every full-shell layout — live and walkable — in the App shell layouts gallery.
Preview every configuration and page template on a dedicated page — each a live, walkable, responsive instance with guidance on when and where to use it.
View app shell layoutsConventions for composing pages and the standards we hold to, so new work stays aligned with the system.
App pages live under inside : a collapsible left sidebar (workspace switcher → Company/Workbench tab → nav → notifications → profile), a sticky frosted header, and a right help panel. The shell mounts once; pages render through the .
Build every app page with — it owns the container width, the page title, and the / slots. is the title-only placeholder built on top of it.
Headings inside the app use with no negative letter-spacing — Geist already has the right spacing, so don't add . Reserve Semibold for emphasis, not headings.
Keep the outer border, but no divider lines inside a card. Separate a card's header, body, and footer with padding and spacing — never an internal /.
Use () for async results that aren't otherwise visible (saved, invited, deleted) and for non-blocking errors; pair reversible actions with an . Don't toast immediate UI feedback, validation (show inline), or blocking flows (use a dialog).
Build every empty surface with and the right : invests (preview + one primary action), celebrates, and always offers recovery. Lead with the outcome, never guilt the user, and pass the test: what belongs here, why it matters to their job, what to do next.
Product UI animates with and the tiers (never over 300ms); marketing reveals use and . The shell plays its intro once on load; navigating between tabs has no transition. Full rules, tokens, and the source material link live in the Motion section above.
A border beam means AI is active there, right now — on the surface where it streams, the input that drives it, and the trigger that starts it. Compose through ( + /), never by hand, and never decorate idle UI with it.
Liquid Metal () marks the one element to act on — the premium CTA or prompt bar a surface is built around. Interactive elements only, one per surface, and never a state signal: metal drives the click; the beam shows AI working — the two never swap roles.
Below the shell keeps the sidebar but switches to a push: opening a panel slides the page off-screen (dimmed + scroll-locked); the sidebar pushes right, the help panel pushes left. Tap the page to close.
Register power-user keys in (the source for the help dialog, opened from the profile menu): then / switch elevation, toggles the sidebar, the help panel, opens the list.
Wrap content in (adds the shared ) and lead with . The marketing surface uses the cream hero on white sections; the global renders once in .
Use the Coss for every CTA. For links, pass a router Link to : . Map primary→, subtle→.
Lucide only. Import glyphs and from . Use a 2px stroke and semantic colors. Icon-only buttons need an accessible name; decorative glyphs are hidden from assistive technology.
Tokens live in . Body = (Inter); headings (h1-h6) = (Geist); logo = (Space Grotesk). Consume colors via utilities, never hex.