ui-kit
Shared components for Kuroko, Fuzen, EXT and the next tools. Built from the Figma “EXT System”, with light / dark, a blur mode for surfaces, and two motion feelings. Hover the ruler on the left to jump around.
Fuzen composer, rebuilt with the kit
Films that move
the way you do.
1Tokens
Tokens from the Figma variables, as CSS custom properties (--ui-*). Everything below switches with the toolbar.
Colors
bg-canvasbg-mutedbg-emphasisbg-inversesurface-raisedsurface-overlaytext-primarytext-secondarytext-tertiarytext-inverseborder-subtleborder-defaultborder-strongborder-focusfill-hoverfill-activesuccess-fgsuccess-bgdanger-fgdanger-bgwarning-fgwarning-bginfo-fginfo-bgType
SF Pro (system)--ui-text-h224 / 28 · 500--ui-text-h416 / 20 · 500--ui-text-body14 / 20 · 400--ui-text-label-l14 / 14 · 500--ui-text-label-m12 / 12 · 500--ui-text-label-s10 / 10 · 500--ui-text-caption12 / 16 · 400Spacing & radius
246810121620243240xssmmdlgxlfullMotion
Active: smooth · move 500msClick the track. Smooth = expo-out, Snappy = light spring. Tune both live with “Tune”.
Icons
Figma16px, 1.5px stroke, currentColor. Generated from the Figma export (pnpm icons). Click one to copy its name.
Set
32 iconsSurface
Panels, toolbars, popovers. The only element that turns to glass in Blur mode (translucent fill + backdrop-filter + light edge). Controls inside stay opaque, as in Figma.
Solid / Blur
Forced per side, whatever the toolbar saysInput
Figma36px text field. Focus = 1.5px border/focus outline (no shadow, no blur). Error = danger outline + helper in danger. The whole field focuses its input on click.
States
Texte d’aide
Live
Try typing anything
Visible to everyone in the workspace
Textarea
A multiline Input: same field, same focus ring. It grows with its content (the height eases with the move curve) between rows and maxRows. With a maxlength, a ring fills as you type, the count slides in at 80%, and the ring bumps at the limit.
States
Add a few more details
Live
Type past a line, and toward the limitGrows up to 8 lines
Select
An Input-looking trigger that opens a listbox (Figma Menu: raised surface, border, no blur). The chevron turns, the list opens from the trigger, one highlight glides between rows and starts on the selected one. ↑ ↓ Home End, or type to jump.
States
Live
Value: normal
Toggle
Figma28×16 switch for preferences (theme, public sharing). The knob glides with the move curve and stretches while pressed.
States
Live
The first one drives the page themeRange
Apple-style sliders. Dragging is relative (grab anywhere, nothing jumps), a tap eases to that point, pulling past an end stretches it like rubber and it springs back. Pressing grows it; steps show as dots and snap. Icon and value invert where the fill passes.
Pill
Control Center styleThin
With a knob; the value floats above while draggingInline edit
Rename in place: the text is the field. Click a name: a field grows out around it, the name is selected (without its extension), the width follows what you type. Enter folds the field back and the new name morphs from the old one, with a check; Esc cancels; a refused value shakes.
Folders
Duplicates are refusedAny typography
It takes the parent's fontSegmented
FigmaView switch (Grid / List) or pill tabs. Opaque track, never blurred. The selected pill is a single element that glides between items.
States
Glide vs stretch
thumb="stretch" · lag tunable in Tune (Segmented)Live
Arrow keys work tooChip
FigmaFilter or tag (Figma Chip: selected = active filter). With a color, it becomes a category chip, our take on Fuzen's Bug / Design / Animation buttons: the dot is the category, selecting spreads its tint across the chip from the dot, and the dot grows into a check.
States
Categories
One choice: mode="radio" in a radiogroup (Fuzen's composer)Filters
Several choices: mode="toggle", size S, with a countDrop zone
FigmaFigma Dropzone. Drag files over it: the dashes tighten and march, a light follows the pointer, the icon lifts, the title morphs. Drop: a ripple where you released, and each image flies from there into its slot, tilting as it lands. Uploads show a ring that closes into a check. Drag images from your desktop, or simulate a drop.
Images
v-model:items · @addCommand palette
⌘K anywhere on this page. Jump to any component, switch theme / blur / motion, open the motion tuner, copy the Nuxt setup or the skill install command. Fuzzy search (try “drwr”, “dark”, “stag”), matched letters underlined, recent commands first. One highlight glides between rows, the list unfolds and eases to its new height, the chosen row flashes before the palette closes.
Palette
⌘K / Ctrl+KPopover
Anything that opens next to its trigger: menus, small panels (a mini modal), tooltips. Native popover in the top layer but kept in place in the DOM, so it inherits the theme around it. Opens from the trigger (scale + slide with the move curve), closes faster, flips up when there's no room below.
Menu
Figma Menu · gliding highlight · keyboardPanel
A mini modal on its trigger: a Surface, glass in blur modeTooltip
Figma Tooltip · 500ms, then instant from one to the nextHint
A small popover that explains, in words, what the selected thing does: anchored to any element, opened by a shortcut or a click, with mini chips inside the sentence (a property with its icon, a duration drawn as an arc, an ease drawn as its curve). Hover the chips: the arc fills in that duration, a dot runs the curve with that ease.
Kuroko: select a tween, press H
Click a bar · H toggles · ← → move the selection · EscH explain the selected tween
.hero-title rises into view, line by line: Y from 100% to 0% and opacity from 0 to 1.
Lasts 0.9s with power3.out, which starts fast and slows down as it lands.
Starts at the beginning of the timeline, with 0.08s between lines.
Click version
The same hint on a triggerSmooth: everything follows expo.out over 0.5s. Movement leaves fast and lands softly, never overshooting.
Notification
FigmaFigma Toast: inverse, opaque, at the bottom. Toasts stack (the newest in front, the others peek behind), hovering unfolds the stack and pauses the timers, swiping one sideways throws it away. A toast can change in place: loading → success or error, the box, the icon and the text morph.
Tones
useToast().show / success / errorLoading → result
useToast().promiseStack
Then hover the stack, or swipe a toast awayModal
FigmaFigma Modal: raised surface, radius 16, over an opaque scrim (never a blur). Native dialog (focus trap, Escape). Given a `from` element, it morphs out of it: position with transform, size with clip-path, so nothing is stretched, and closes back into it.
Default
Morph from a card
Click a card · try SnappyDrawer
Sheets that you can throw. The sheet follows the pointer 1:1 (rubber band past the ends), the grip stretches with your speed, and on release it settles open or closed from position and velocity, carrying the gesture's speed into a spring in Snappy. Everything reads one number, --ui-drawer-p, also written on the parent: the page behind scales, dims and rounds in plain CSS.
Bottom sheet
Drag the strip up, flick it down · or use the buttonComments
Spacing under the nav looks tighter than in Figma.
Fixed in the last deploy, have a look.
The page behind uses scale(1 - p × 0.07), a radius and a dim from --ui-drawer-p: no JS on its side.
Side panel
An inspector that docks in and pushes the content · drag its edgeMorph
One container, several states: UiMorph tweens its size from one content to the next with the move curve while the contents cross-fade (the old one leaves fast, the new one arrives slightly blurred). Radius and colors per state are plain CSS on [data-state].
Button → form
The button becomes the field it asks forStatus
A pill that grows into what's happening, then shrinks backToolbar → composer
Fuzen: the toolbar turns into the ticket formState switch
KurokoA proposal for Kuroko's states bar. Click a name to edit that state (the element jumps to it, like in Kuroko). ● is where the page is; ▶ plays a state from there. The chip fills with the real animation's progress (the switch reads the WAAPI / GSAP animation it gets back), and ● lands when the element does.
Proposal
1-9 edit · ⇧1-9 play (focus the switch first)Editing open · page in closed
Split picker
ExperimentalA proposal for Kuroko's Split section: instead of three rows of buttons, you edit the split on the text itself. Drag the rail to change the granularity, toggle the mask under a stop, drag the stagger strip, click a piece to stagger from it, and pick properties from chips that preview themselves. Every change replays with the active motion preset, and the GSAP code comes out at the bottom.
Proposal
Panel sized like DialKit (360px)Or click a word in the text to start from it.
{
"animate": "words",
"mask": "lines",
"props": [
"y",
"opacity"
],
"stagger": {
"each": 0.04,
"from": "start"
}
}
The hero title jumps on load, can we fade it instead?