Hierarchy, pairing open/close sounds, directional navigation, and notification tiers: applied Material choreography for sensory-ui.
How to combine sounds across a flow so the interface feels coherent. Adapted from Sound choreography and Applying sound to UI.
| Level | Roles | Character |
|---|---|---|
| Foreground | notification.*, hero.* | Longer (200–1900ms), carry meaning alone |
| Middleground | overlay.*, navigation.* | 40–270ms, structural |
| Background | interaction.* | 8–50ms transients, felt more than heard |
Rules:
notification.success, skip the button tap).hero.* is disabled by default (double opt-in: enable category + set sound prop).From Sound choreography: paired actions should be tonal inversions: same voice, opposite arc.
| Open | Close | Components |
|---|---|---|
overlay.open | overlay.close | Dialog, Sheet, Popover, Select |
overlay.expand | overlay.collapse | Accordion, Collapsible |
navigation.forward | navigation.backward | Carousel, Pagination |
// Overlay pattern: two props, one pair
<Dialog sound="overlay.open" closeSound="overlay.close">
...
</Dialog>
// Expand pattern
<Accordion expandSound="overlay.expand" collapseSound="overlay.collapse">
...
</Accordion>Don't mix pairs (e.g. overlay.open with overlay.collapse). Keep the metaphor consistent.
navigation.forward (rising sweep)navigation.backward (falling sweep, mirror of forward)navigation.tab (short pop)Material use cases distinguish info vs. success vs. warning vs. error by intensity:
| Role | Shape | When |
|---|---|---|
notification.info | Single soft chime | Passive update, FYI toast |
notification.success | Three ascending notes (C5–E5–G5) | Saved, completed, validated |
notification.warning | Two-note semitone ascent (A4 → A♯4) | Quota, confirm-needed, destructive preview |
notification.error | Filtered descending sweep (320 → 140 Hz) | Failed, disconnected, invalid |
Don't upgrade info to success for emphasis. Frequency of success sounds dilutes them.
From Sound attributes:
notification.warning) sit lower than confirmations.0.3–0.4; use per-component volume to push secondary actions down, never to push primary actions above the ceiling.| Don't | Why | Do instead |
|---|---|---|
| Sound on every hover | Fatigue, no user intent | Sound on click / commit only |
| Different tap per button | Breaks consistency | One interaction.tap everywhere, interaction.confirm for submits |
| Hero sound per session step | Celebration inflation | hero.complete once per milestone |
| Auto-play on mount | Blocked by browsers, surprises users | Trigger from click / keyboard only |
| Sound without visual change | Inaccessible | Pair every cue with visible state |
// 1. Shipping form: rewarded submit, not a plain tap
<Button sound="interaction.confirm">Continue to payment</Button>
// 2. Confirm dialog: paired open/close, no stacked button sound
<Dialog sound="overlay.open" closeSound="overlay.close">...</Dialog>
// 3. Payment success: foreground success suppresses the button tick
playSound("notification.success"); // skip the tap underneath
// 4. Order placed: the one moment worthy of a hero sound
playSound("hero.complete"); // categories.hero must be enabledEach step uses exactly one foreground sound. Compare with the taste rules and see it composed in the Timer + Confetti block.