Reminder
Call the supplier about the delayed order
Idle
Reduced motion is on, so the intro is skipped and the orb moves slowly.
noui-orb · web component
<noui-orb> is the orange o from the mark as a live voice surface. This page is built only on the component's public API. Switch states, change what drives it, and tune the motion until it feels right.
Reminder
Call the supplier about the delayed order
Reduced motion is on, so the intro is skipped and the orb moves slowly.
Everything on this page is built with the calls below. <noui-orb> is a standard Web Component, so it works in plain HTML and in any framework. It is a scripted early release: it draws and reacts, it does not understand speech. Your app does the listening and the thinking and tells the orb what is happening.
Add the package, then import it once. Importing registers the <noui-orb> tag.
The orb fills its box, so size it from outside and keep it square. gestures turns on character motion (leaning, nodding, hopping). intro="auto" plays the logo-to-orb intro on load.
Set the state as your app moves through a turn. For work with known steps, give it progress and the ring fills; without progress it shows a spinning arc and never fakes a percentage.
You ask for the microphone and hand the orb the stream; it only listens to loudness and tone, and nothing leaves the page. Call this from a click or tap, on an HTTPS page. If you analyse audio yourself, push levels instead.
Gestures each mean one thing (see the vocabulary below). The orb nods by itself when it starts thinking and hops when a task finishes. Ask for others when your app knows better.
The orb is where your interface comes from. Ask it to emit, read where it is, and animate your element out of that point. Use place("aside") when the user starts working, and bring it back when they tap it.
Set object values like progress as properties and listen with addEventListener. React 19 passes objects and events straight through; React 18, Vue and Svelte notes are in the README. It is safe to import on a server, so Next.js works from a client component.
Reference: every attribute, property, method, event and number is in the spec. Questions or a rough edge? Open an issue.
Each gesture means one thing. Local signals trigger the instant ones; the backend's reply triggers the ones that need understanding.
| Gesture | Means | Triggered by | Source |
|---|---|---|---|
| Lean | I'm listening to you | Pointer or input position while listening | Device |
| Nod | Got it, or yes | End of the user's sentence; a yes in the reply | Device, backend |
| Shake | No, or can't do that | A no or a refused request | Backend |
| Huh | I didn't understand | Low-confidence understanding | Backend |
| Breath | About to speak | Half a second before reply audio | Device |
| Interrupt | Go ahead | User starts talking while the orb speaks | Device |
| Emit | Here's what you need | A new piece of interface is assembled | Backend |
| Point | Look here | An element that needs the user's action | Backend |
| Step aside | Your turn | User working in the assembled interface | Device |
| Wait | Take your time | A decision is pending; dims after a long silence | Device |
| Hop | Done | Task finished | Backend, app |
The orb shows energy: who is talking and how loudly. The ring shows time, and only appears when there is something to wait for.
| State | Orb | Ring | Driven by |
|---|---|---|---|
| Idle | Slow drift, slight breath, softer colour | Hidden | Time only |
| Listening | Waves travel inward; swell follows loudness | Hidden | Microphone |
| Thinking | Fast swirl, warmer core, soft pulse | Orbiting arc, because the wait has no known end | Time only |
| Working | Calm swirl, brief flash on completion | One segment per step; gaps close when done | Task progress |
| Speaking | Waves travel outward; swell follows loudness | Hidden | Reply audio |
| Error | Colour drains, motion nearly stops | Broken and grey | Connection status |