Refined UI components with satisfying hover. A shadcn/ui registry of components, the systems they share, and blocks that compose them.
$ npx -y skills add mickadesign/fluid-functionalism --agent claude-code
Repo: mickadesign/fluid-functionalism
What's inside
───────────────────────────────────────
F L U I D F U N C T I O N A L I S M
───────────────────────────────────────
Refined UI components with satisfying hover.
A shadcn/ui registry of components, the systems they share, and blocks that compose them. Every transition exists to make a state change legible: springs instead of durations, one hover highlight that glides to the item nearest your cursor, and labels that get heavier without shifting the layout. Components that touch a primitive ship in two flavors, Radix and Base UI, with the same API on both.
Docs and demos · Browse components · Compare with shadcn/ui
Add the registry to your project once:
npx shadcn@latest registry add @fluid
Then install any component, system, or block by its registry name:
npx shadcn@latest add @fluid/button
Or install straight from the URL, without adding the registry:
npx shadcn@latest add https://www.fluidfunctionalism.com/r/button.json
Dependencies, shared libs, and hooks resolve on their own.
Every component that touches a primitive has both a Radix and a Base UI flavor. The bare name installs Radix. Put base/ in front of it for Base UI:
npx shadcn@latest add @fluid/base/button
The URL form is https://www.fluidfunctionalism.com/r/base/button.json. Dependencies follow the flavor you pick, so a Base UI dialog pulls in the Base UI button. Components built on top of a flavored one (AskUserQuestions, Banner, ColorPicker, CommandMenu, InputCopy, InputMessage, and the blocks) accept base/ too. Everything else has one source and installs from the bare name in either kind of project. The tables below list the names.
A stock shadcn project already has button.tsx, dialog.tsx, tooltip.tsx, and friends. This library installs under the same names, so pass --overwrite to replace them:
npx shadcn@latest add @fluid/dialog --overwrite
Without the flag the CLI asks per existing file, and a non-interactive shell (a coding agent, a CI job) exits at the first question.
Font weight animations use Inter's wght and opsz axes together: the heavier weight widens a label, a tighter optical size pulls it back, so text changes weight without moving its neighbours. Load the variable font with both axes.
Self-hosted, the way the docs site does it:
@font-face {
font-family: "Inter";
src: url("/fonts/InterVariable.ttf") format("truetype");
font-weight: 100 900;
font-display: swap;
}
With next/font/google, ask for the axis: Inter({ subsets: ["latin"], axes: ["opsz"] }).
Every doc page and playground has a Copy prompt button. The prompt is a self-contained brief: the install command, a usage snippet, the props, the built-in behaviors to compose around, and the docs URL. Paste it into your agent and it wires the component in without fetching anything.
For a whole project rather than one component, install the /fluid-functionalism skill:
npx skills add mickadesign/fluid-functionalism
The source lives in skills/fluid-functionalism. It reads the stack fresh on every run with a bundled script, so it installs the right flavor and leaves no audit file in your project. Alongside it sit the component catalog, the interaction-design decisions built into each component, and the rules for writing custom motion next to them.
Install with npx shadcn@latest add @fluid/<name>. A second name means the component has a Base UI flavor.
| Component | Registry name | What it does |
|---|---|---|
| Accordion | accordion · base/accordion | Collapsible sections with animated expand/collapse and fluid hover in grouped mode |
| AskUserQuestions | ask-user-questions · base/ask-user-questions | Stepped question flow with single/multi-select, an inline "other" input, skip, and multi-question navigation |
| Badge | badge | Compact label with solid and dot variants, the Tailwind color palette, and 2 sizes |
| Banner | banner · base/banner | Status message in 5 statuses and 2 contrasts with a status icon, up to 3 actions, a dismiss that collapses its height, and a fixed full-bleed variant |
| Button | button · base/button | Variants, sizes, loading state, icon slots, and a weight shift on hover |
| Card | card | shadcn's compositional card with stacked, inline, and grid layouts, borderless dividers, media/logo/feature slots, and 2-D fluid hover |
| CarouselDots | carousel-dots | Carousel dots, static or on autoplay, with fluid-hover click areas and a current pill that fills over each slide |
| ChatMessage | chat-message | Chat transcript bubble with baked-in motion, user/assistant alignment, and file attachments |
| CheckboxGroup | checkbox-group · base/checkbox-group | Checkbox group with merged backgrounds for contiguous selections |
| ColorPicker | color-picker · base/color-picker | HEX, RGB, HSL, and OKLCH formats with alpha, swatches, and eyedropper, inline or in a popover |
| Combobox | combobox · base/combobox | Type-to-filter field with keyboard highlight, fluid hover, chips for multiple selection, and a create-from-query row |
| CommandMenu | command-menu · base/command-menu | Type to filter a list of actions, arrow through them, press Enter: groups, shortcut caps, suggestions, and a dialog shell on ⌘K |
| Dialog | dialog · base/dialog | Modal with spring enter/exit and overlay in 3 widths, the largest a canvas for a sidebar |
| Dropdown | dropdown · base/dropdown | Menu-style dropdown with fluid hover, animated selection, submenus that hold their row across the safe area, and an optional search field in the popup |
| InputCopy | input-copy · base/input-copy | Read-only input with copy-to-clipboard and animated feedback |
| InputGroup | input-group | Input fields with fluid hover, animated labels, and validation |
| InputMessage | input-message · base/input-message | Chat-style composer with auto-resizing textarea, file drop, action slots, and a built-in send button |
| RadioGroup | radio-group · base/radio-group | Radio buttons with fluid hover and animated selection |
| Select | select · base/select | Animated select with bordered/borderless variants, typeahead, and optional icons |
| Sidebar | sidebar · base/sidebar | Composable app sidebar: drag its edge to resize, collapse it away or press [ or ], and a drawer on mobile |
| Slider | slider · base/slider | Spring-snapped thumb, step dots, range mode, and a click-to-edit value |
| Switch | switch · base/switch | Toggle with animated thumb and label |
| Table | table | Data table with fluid hover on rows and semantic markup |
| Tabs | tabs · base/tabs | Segmented control with sliding indicator and fluid hover |
| TabsSubtle | tabs-subtle · base/tabs-subtle | Tab navigation with an animated pill indicator |
| ThinkingIndicator | thinking-indicator | Animated status indicator with morphing SVG and cycling text |
| ThinkingSteps | thinking-steps · base/thinking-steps | Chain-of-thought display with sequential animation and collapsible steps |
| Tooltip | tooltip · base/tooltip | Spring-based floating tooltip with configurable placement |
The systems every component shares. Each installs as code, the same way.
| System | Registry name | What it does |
|---|---|---|
| Fluid Hover | use-fluid-hover | One hook and one highlight per list. The highlight glides to the item nearest your cursor and never blinks off between rows |
| Motion | springs | 3 spring speeds, fast, moderate, and slow, each with an exit one tier quicker than its entrance |
| Scrollbars | scroll-area · base/scroll-area | A scrollbar that stays out of the way but never disappears, with native scroll on touch |
| Sizes | size-context | 2 sizes, a 36px default and a 28px compact, shared by buttons, inputs, selects, tabs, and rows |
| Surfaces | elevated | 8 elevation levels so popovers, dropdowns, and dialogs stay visible at any depth, in light and dark |
| Typography | type-scale · typography | 6 type roles, each a size and a leading at both sizes, plus a prose sheet for rendered markdown with a builder to tune it |
Compositions that install as one item each, with every component they use.
| Block | Registry name | What it is |
|---|---|---|
| App Sidebar | sidebar-app · base/sidebar-app | A complete app shell: workspace header, search field, collapsible sections with badges, user footer, and an inset topbar |
| Settings Dialog | dialog-sidebar · base/dialog-sidebar | The xl Dialog as a canvas, a Sidebar of sections down its left edge, and a scrolling panel of controls |
| Queued message stack | queued-stack · base/queued-stack | Sonner-style stack of queued composer messages: fan out on hover, drag to reorder, morph into the sent message |
The Sidebar, Card, InputMessage, AskUserQuestions, Dropdown, Combobox, and CommandMenu playgrounds encode the configuration you build in the rail into a short code. Nothing is stored: the code is the configuration itself. Install it as one block that composes the component with the options you picked:
npx shadcn@latest add https://www.fluidfunctionalism.com/r/preset/<code>.json
Add ?preset=<code> to the doc page URL to reopen the playground as you left it, or to share it.
FAQ
fluid-functionalism is a Claude Code plugin with 1 hand-picked skill for frontend work, indexed on Flowy. Install it with the command on its page. It includes fluid-functionalism. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
Is this plugin yours?
Claim it with GitHubSubmit a pluginPromote it