From fusebase-flow
Guidance for visual design, UI and UX in Fusebase-generated apps. Use when building or refining app UIs: pages, components, layouts, forms, feedback states, theming, or accessibility. Ensures consistent, clear, and distinctive interfaces using shadcn/ui.
How this skill is triggered — by the user, by Claude, or both
Slash command
/fusebase-flow:app-ui-designThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill guides UI/UX in **generated apps** (Fusebase Apps). Use **shadcn/ui** for all UI. Apply a clear design direction and avoid generic AI aesthetics.
This skill guides UI/UX in generated apps (Fusebase Apps). Use shadcn/ui for all UI. Apply a clear design direction and avoid generic AI aesthetics.
Clarity over decoration. Every visual choice supports hierarchy and scannability. Prefer one bold aesthetic direction (minimal, warm, editorial, etc.) and execute it consistently.
Apps use Tailwind CSS v4 (via @tailwindcss/postcss). Key differences from v3:
@import "tailwindcss" in globals.css (not @tailwind base/components/utilities).tailwind.config.js: Configuration is CSS-first. Use @theme in CSS to define custom tokens.@source "../path/**/*.tsx" to add extra directories.⚠️ CRITICAL — CSS variables in arbitrary values:
Do NOT define raw :root CSS variables and reference them via arbitrary value syntax. This is the most common Tailwind v4 pitfall:
/* ❌ BROKEN — variables are NOT available to Tailwind's arbitrary value resolver */
:root {
--card: #ffffff;
--foreground: #0f172a;
}
// ❌ BROKEN — these classes compile but resolve to empty/broken values
className="bg-[var(--card)] text-[var(--foreground)]"
Instead, use one of these approaches:
Use Tailwind's built-in color palette (preferred for most apps):
// ✅ Works — uses Tailwind's first-class utility classes
className="bg-white text-slate-900 border-slate-200"
className="text-indigo-500 bg-indigo-50"
Register custom tokens via @theme (only if you need custom colors):
@import "tailwindcss";
@theme {
--color-brand: #6366f1;
--color-surface: #ffffff;
}
// ✅ Works — registered via @theme
className="bg-surface text-brand"
Use @apply for reusable component classes (buttons, inputs):
.btn-primary {
@apply inline-flex items-center gap-2 px-5 py-2.5 text-sm font-semibold text-white rounded-xl;
background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);
}
Use inline style only for truly dynamic values (e.g. colors from API data):
// ✅ OK — color is runtime data, can't be a utility class
style={{ color: product.categoryColor, backgroundColor: `${product.categoryColor}18` }}
components/ui/ (copied into the project, not installed as a package). Import from @/components/ui/....--background, --foreground, etc.) are registered through its own theme system and work with utility classes like bg-background, text-foreground.<Button variant="outline" size="sm">) over ad-hoc Tailwind color overrides.cn() utility (from @/lib/utils) to merge Tailwind classes safely: cn("base-class", conditionalClass).⚠️ CRITICAL — Do NOT add a global * CSS reset:
Do NOT add * { margin: 0; padding: 0; box-sizing: border-box; } in globals.css. Tailwind v4's Preflight already applies proper resets. A manual * reset has equal specificity to Tailwind's utility classes and will override them when it appears later in the cascade, breaking padding (p-4, p-5, px-6, etc.) and margin utilities silently.
/* ❌ BROKEN — overrides Tailwind utilities like p-5, m-4 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* ✅ CORRECT — Tailwind v4 Preflight handles resets automatically */
@import "tailwindcss";
/* No manual * reset needed */
text-sm, text-base, text-lg, font-semibold, etc.) and keep heading/body consistent throughout the app.rounded-md for cards and inputs; rounded-full for pills/avatars).bg-background, text-foreground, bg-muted, text-muted-foreground, border) — these are pre-registered and work out of the box.bg-white, text-slate-900, bg-slate-100, text-slate-500, border-slate-200).bg-background in an app without shadcn/ui theming — it won't resolve. Reserve inline style for dynamic/computed colors only.Establish clear text hierarchy using the same approach as Colors above:
| Level | With shadcn/ui | Without shadcn/ui |
|---|---|---|
| Primary (main content) | text-foreground | text-slate-900 dark:text-slate-100 |
| Secondary (labels, metadata) | text-muted-foreground | text-slate-500 dark:text-slate-400 |
| Tertiary (timestamps, hints) | Smaller size + text-muted-foreground | Smaller size + text-slate-400 |
Reserve accent/brand color for CTAs and key UI, not body text.
disabled + a spinner on Button during submits.Skeleton sized to final content, or a Loader2 spinner from Lucide).gap-2/p-2 for inline, gap-4/p-4 for cards/sections, gap-6/py-6 for page rhythm).sm:, md:, lg:). Single column on mobile; sidebars/panels as toggles or Sheets (<Sheet>) on small screens. Use flex-wrap and min-w-0 to avoid overflow.max-w-2xl mx-auto) for readability on wide viewports.Button, Input, Card, Dialog, DropdownMenu, Select, Textarea, Badge, Skeleton, etc. Do not replace them with raw HTML for interactive elements.react-hook-form with zod for validation. Wrap inputs in <FormField>, <FormItem>, <FormLabel>, <FormControl>, <FormMessage> from @/components/ui/form.sonner (toast.success(...), toast.error(...)) or shadcn/ui's useToast hook. Prefer sonner for simplicity.onSubmit, onClose), not big config objects.lucide-react) consistently throughout the app. Apply text-muted-foreground or contextual color classes for icon meaning (e.g. status, category).disabled to the button and show a <Loader2 className="animate-spin" /> icon inside it while a request is in flight; use <Skeleton> for content placeholders.cursor-pointer to interactive elements (buttons, links, clickable cards) including shadcn/ui Button. For custom <button> elements or <div onClick> handlers, always include cursor-pointer in the Tailwind class list. For disabled states use cursor-not-allowed (and remove cursor-pointer).hover: utilities; avoid overriding styles on interactive elements without a clear reason.<FormMessage> and a toast or inline alert for API errors. See handling-authentication-errors for 401/token expiry.<label> for inputs, landmarks where relevant.<FormLabel> for all form inputs so labels are always associated.With shadcn/ui: Dark mode is toggled by adding/removing the dark class on <html>. Use CSS variable-based tokens (bg-background, text-foreground, etc.) which are registered through shadcn/ui's theme system.
Without shadcn/ui: Use Tailwind's dark: variant with the built-in palette: bg-white dark:bg-slate-900, text-slate-900 dark:text-slate-100. Do NOT create raw :root CSS variables and reference them via bg-[var(--name)] — this does not work in Tailwind v4 (see Tailwind CSS v4 section above).
npx claudepluginhub fusebase-dev/fusebase-flow --plugin fusebase-flowGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.