Usage
@prepared911/ui/blocks/call-dock and its styles.css, plus the styles.css of each component the block composes (Box, Button, Icon, Separator, SizeHold, Skeleton, Text).
CallDock is the tray of the one active call, in a bar centered on the block-end edge of its shell. It is an inverted surface, light on a dark page and dark on a light page. The shell owns the frame and decides when it is there; a module (in the product, a module-federation remote) fills it. It slides in and out as a call starts and ends. There is no queue, and nothing in the API can express a minimized call or panel.
open is the whole presence rule. Derive it from the calls domain. The tray shows while it is true, even when the module renders nothing yet or fails, and renders nothing at all while it is false: no landmark, no empty bar, no reserved space, and no child mounted.open go false when the call ends; do not wrap it in call ? <CallDock … /> : null, which removes it without its exit.dir="rtl" with no prop.label is the landmark's name and stays the shell's. The glyph passed to CallDockError is imported once by the shell (@prepared911/ui/icons/error-circle); a block cannot import glyph modules.open turning true enters the tray from beyond the block-end edge on the glide spring with a short fade. open turning false makes the tray inert at once, holds its size, slides it back beyond the edge on the glide exit timing, and removes it from the tree after the exit. Opening again during the exit cancels it and releases the held size. A tray present on first render, or on the server, is at rest: nothing animates on first paint. Under reduced motion, from the operating system or from data-motion="reduced" on the html element, nothing travels and only the fade remains.
CallDockDetails and CallDockControls anywhere under the mount. The tray lays them out the same behind any number of display: contents wrappers (the mount wrapper, Suspense and error boundaries add none of their own), so the remote never needs to know what sits above it.CallDockControls; with only details, only CallDockDetails. The vertical rule leads the controls while the tray also holds details, and is not drawn otherwise.activeCallId goes null makes the controls vanish while the tray slides out. The tray holds its size for the exit, so an emptied remote cannot collapse it, but it still leaves empty. Hold the last call's data until the remote unmounts.open state or render the tray yourself; read the call through the calls domain.Foreground.Default, Subtle, Muted). The content is a theme region in the opposite appearance of the page, so Button, Text, Icon, Counter and Badge resolve their ordinary tokens for the inverted surface. The Transient* foregrounds name the page's inverted values and would resolve to the wrong appearance inside the region.CallDockSkeleton is the loading content: placeholders at the tray's block size (one row at the control height), hidden from assistive technology, pulsing like every Skeleton and static under reduced motion. Pass it as the loading of the mount.
CallDockError is the failure content while a call is active: a glyph, a short message and, with onRetry and retryLabel, a Retry Button. The glyph and message form one polite status region, announced once when the state appears; Retry is a tab stop of its own. Without onRetry there is no button. Pass it as the errorFallback of the mount.
A Tooltip or Menu opened from a dock control portals outside the dock, so it renders in the page appearance, not the inverted one. Tooltips are dark in either appearance. This is by design; there is no prop to carry the dock's appearance into a portal.
Both wrap inside the tray at narrow widths instead of scrolling sideways. Button, Text and the other children keep their own sizes: controls stay on the control-height scale.