# Camel

Every other machine in the set stands on a line. This one's ground is a medium with a depth, and its feet go into it — as deep as what each is carrying, and less deep because the pad opens under the load and drops its own pressure. The hump is a store that slumps as it empties, and the roll is an output of the gait.

> 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/robot-camel.json
```

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

## Notes

- The ground is the new axis and it is the only floor in the registry with a depth. padSpread opens the pad under load and footSinkage turns the pressure that leaves into a depth, so each loaded foot sits as deep as what it carries — and an opening pad drops its own pressure, which is why the same animal on the same sand stays higher up than it would on a foot that did not open. The tests assert exactly that comparison.
- It is a proportional rule, not a soil model: no bearing capacity, no shear, no compaction, and the rim of disturbed ground around a sunk foot is drawn rather than displaced from anywhere.
- The hump is one outline bent rather than one drawing swapped for another: its base is pinned to the back and does not move, its height falls with the reserve, and past the halfway mark it leans over while the rear flank goes slack. It conserves no volume.
- The roll is an output of the gait. A pace is the lateral two-beat, so the whole weight is on one side and the roll swings to a full ±1 once each way per stride; a trot's support is diagonal, so all that is ever off-centre is the forehand's share against the hind end's — 0.16 of a body, exactly, whenever either diagonal is down. camelRoll is exported pure, and the test asserts that residual rather than eyeballing it.
- Illustrative kinematics throughout: the load is a static weight distribution, there is no impulse at footfall, the roll is a proportional rule rather than a moment about anything, and the animal never travels across its frame.

## Usage

```tsx
import { RobotCamel } from "@/components/ui/robot-camel"

<RobotCamel behavior="pace" />

// Or put it on rock and watch the feet come back up out of the ground.
<RobotCamel gait="pace" phase={0.2} ground={0} reserve={0.3} showContacts />
```

## Props

| name | type | default | description |
| --- | --- | --- | --- |
| `view` | `"plan" | "front" | "profile" | "iso"` | `"profile"` | Where the camera stands. One animal, four projections: straight down, straight on, side elevation, or three-quarter from above. |
| `behavior` | `"pace" | "walk" | "trot" | "couch" | "static"` | `"pace"` | What it does when phase is not supplied. pace is the signature — the lateral two-beat nothing else in the set uses — and trot is the control case for the roll. |
| `gait` | `"halt" | "walk" | "trot" | "pace" | "canter" | "gallop"` | — | Footfall pattern, overriding the one the behavior picked. |
| `ground` | `number` | — | What it is standing on, 0 rock to 1 dry sand. The loaded feet go into it. Omit and the behavior sets it. |
| `reserve` | `number` | — | How much is left in the hump, 1 full and upright to 0 empty and folded over. The base is held while the height goes. Omit and the behavior decides. |
| `phase` | `number` | — | Controlled cycle fraction. Supplying it stops the internal clock. |
| `speed` | `number` | `0.5` | Strides per second. |
| `offset` | `number` | `0` | Seconds of offset, so a string of them breaks step. |
| `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. |
| `arch` | `number` | — | Back curvature, −1 hollowed to 1 roached. Omit and the behavior sets it. |
| `crouch` | `number` | — | Leg fold, 0 standing tall to 1 couched. Omit and the behavior decides. |
| `neck` | `number` | — | Neck carriage, −1 head to the floor to 1 head high. Omit and the behavior sets it. |
| `tail` | `number` | — | Tail carriage, −1 clamped to 1 held out. |
| `ears` | `number` | — | Ears, −1 pinned back to 1 pricked forward. Omit and they prick at the pointer. |
| `gaze` | `number` | — | Head and eye aim, −1..1. Omit and it follows the pointer. |
| `interactive` | `boolean` | `true` | Drag up and down to work the ground — firm at the top of the frame, soft at the bottom, so dragging down is sinking — with arrows stepping 10% and shift 25%, Home on rock and End in sand. The head tracks the pointer. |
| `onGroundChange` | `(ground: number) => void` | — | Fired with the ground's softness, 0–1. |
| `showGround` | `boolean` | `true` | The ground line, and the band of yielding material under it. |
| `showContacts` | `boolean` | `false` | Mark the pads carrying weight, at the width the load has opened them to. |
| `label` | `string` | — | Caption underneath the animal. |
| `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. |
| `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/robot-camel.tsx`
