# Custodian droid

A floating armoured custodian whose shell comes apart: armour segments on radial rails that bloom into a corona around a lit chassis, with a gimballed optic behind a bracket cage.

> For the complete index, see [llms.txt](https://robocn.dev/llms.txt). A Markdown version of any page is available by appending `.md` to its URL or by sending an `Accept: text/markdown` header.

## Install

```bash
bunx --bun shadcn@latest add https://robocn.dev/r/custodian-droid.json
```

Registry item: `custodian-droid` · [`https://robocn.dev/r/custodian-droid.json`](https://robocn.dev/r/custodian-droid.json)

## Notes

- Front elevation is the view it is drawn in. Every part is modelled once in world units — across the face, down it, and out of it — and projected, so the tipped cameras show real depth: how far the plates stand off the chassis, the rails between them, the cage standing proud of the lens. In profile and plan the face artwork is edge-on and gone, which is what a face looks like from the side.
- The shell is the mechanism. Each armour segment is a wedge of the casing outline riding its own rail, and the front edge travels further than the back, so opening blooms the corona rather than only dilating it. The lattice on the chassis is lit under the armour and shows through the gaps as the segments part.
- The optic is a body, not a pupil: it yaws and pitches about a pivot behind its own face, so aiming it foreshortens the bezel and slides the glass across the recess. It stays level while the shell rolls with the machine's drift, the way a gimballed optic does.
- Illustrative, not simulated: there is no thrust, mass or repulsor field, the float and roll are drift terms, the rails carry no stroke load, and there is no optics model — no exposure, no focus. Nothing infers state or starts a timer: voice lights cells because it was told to.
- An original archetype — a floating custodian unit — not a character. No franchise name, markings or paint scheme; the defaults are the theme's.

## Usage

```tsx
import { CustodianDroid } from "@/components/ui/custodian-droid"

<CustodianDroid behavior="survey" plates={6} onOpenChange={setOpen} />
```

## Props

| name | type | default | description |
| --- | --- | --- | --- |
| `view` | `"plan" | "front" | "profile" | "iso"` | `"front"` | Where the camera stands. One droid, four projections: straight down, straight on, side elevation, or three-quarter from above. |
| `open` | `number` | — | The shell, 0 seated to 1 run all the way out. Supplying it stops the loop; the rails extend with it either way. |
| `behavior` | `"watch" | "survey" | "alert" | "static"` | `"watch"` | Watch keeps the armour seated and station-keeps; survey runs the shell half out and breathes it; alert throws it wide, floats tight and fast, and talks. |
| `speed` | `number` | `0.3` | Cycles per second: one float, one sweep of the room. |
| `animate` | `boolean` | `true` | Off parks the machine at phase and stops rendering. A reduced-motion preference does the same. |
| `paused` | `boolean` | `false` | Freeze where it stands. |
| `phase` | `number` | `0` | Seconds of offset, so a row of machines breaks step. |
| `interactive` | `boolean` | `true` | Drag across it to work the shell, or use the arrow keys; Home seats the armour and End runs it wide. Release eases it back into the behaviour. |
| `onOpenChange` | `(open: number) => void` | — | The opening a drag or a key moved the shell to, reported in controlled mode too. |
| `look` | `Vec2 | null` | `null` | Controlled optic aim in −1..1; overrides pointer tracking. |
| `track` | `boolean` | `true` | The optic follows the page pointer while look is null. |
| `voice` | `number` | — | Lit cells in the ring round the lens, 0–1, filling out from the middle. Omit and the behaviour works it. |
| `plates` | `number` | `6` | Armour segments in the shell, clamped to 4–10. The segments are cut from the casing outline, so a higher count is finer armour rather than a bigger machine. |
| `variant` | `"solid" | "outline" | "blueprint" | "wire"` | `"solid"` | How the machine is painted. Geometry never changes between variants. |
| `size` | `"xs" | "sm" | "md" | "lg" | "xl" | number` | `"md"` | Rendered width in pixels, or a step on the scale. |
| `showGround` | `boolean` | `true` | Draw the contact line or shadow beneath the droid. |
| `signal` | `"idle" | "ready" | "warning"` | — | Status-lamp state using neutral, accent, or shell colour; each component documents its visual default in the demo. |
| `label` | `string` | — | Optional technical caption under the drawing. |
| `color` | `string` | `var(--robot-shell)` | Body panels — the colour the machine reads as. |
| `accent` | `string` | `var(--robot-accent)` | Status colour: tip light, live tool, readouts. |
| `metal` | `string` | `var(--robot-metal)` | Bare machined parts: collars, bolts, tool bodies. |
| `dark` | `string` | `var(--robot-dark)` | Cast joints, base, shadow side. |
| `palette` | `Partial<RobotPalette>` | — | Override any subset of roles at once, including glow and grid. |

## Source

- `src/components/ui/custodian-droid.tsx`
