# Fox

The cat's back arches and the dog's shoulder swings; this one tips the whole animal about its hip. The brush is the first tail in the set that is an output rather than an input — its carriage is derived from the pitch — and the two ears pan independently onto one quarry, so their axes converge.

> 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-fox.json
```

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

## Notes

- pitch is a rigid rotation of the whole solved body about its hip, so every link length survives it exactly. The hip is the anchor and does not move; the withers, the shoulder, the head and the brush all swing about it, and the hind legs stay planted while the forelegs answer.
- Once the floor is past the foreleg's reach the limb folds instead of dangling at full stretch: the target comes back in along the same line to a fraction of the reach. The fold begins exactly at the reach limit and deepens with how far past it the body has taken the shoulder — a rule, but one keyed to the geometry rather than to the clock.
- The brush's carriage is derived, not driven: it opposes the pitch and the rate the pitch is changing at, and counterweight is the dial between that and the scripted carriage. The rate is taken analytically from the same pure stance function, so a controlled pitch or phase — a still — has no rate to answer and the brush works from the angle alone. It is a proportional rule and not an inertia tensor: no mass, no moment, no conservation.
- Each ear pans about its own axis onto one quarry from its own place on a fixed baseline, so the two axes converge and the disparity between them grows as the range closes. foxEarBearing is exported as a pure function and returns both pans, the disparity and the quarry. The ears are modelled in three space and projected, so plan and isometric show the convergence and the profile foreshortens it.
- The head does not yaw to the quarry; the ears carry that. The muzzle, the whiskers and the brush's plates are drawn, not solved. Illustrative trajectories throughout: no balance, no ground reaction, no impulse in the landing, and the animal never travels across the frame.

## Usage

```tsx
import { RobotFox } from "@/components/ui/robot-fox"

<RobotFox behavior="mouse" />

// Or tip the body yourself and let the brush answer for it.
<RobotFox pitch={0.8} counterweight={1} crouch={0.2} bearing={-0.5} range={0.9} />
```

## 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` | `"mouse" | "trot" | "listen" | "curl" | "static"` | `"mouse"` | What it does when phase is not supplied: stalk and pounce nose-first, trot on diagonal pairs, stand and work the ears, or curl up asleep. |
| `phase` | `number` | — | Controlled cycle fraction. Supplying it stops the internal clock. |
| `speed` | `number` | `0.5` | Cycles per second: one hunt per cycle mousing, one stride per cycle at a trot. |
| `offset` | `number` | `0` | Seconds of offset, so a pair 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. |
| `pitch` | `number` | — | Body attitude, −1 nose to the floor to 1 reared onto the hind legs. The whole animal turns about its hip, which is the one joint it does not move. Omit and the behavior sets it. |
| `arch` | `number` | — | Back curvature, −1 hollowed to 1 roached. Restrained the way the dog's is, because a fox holds a topline. |
| `crouch` | `number` | — | Leg fold, 0 standing tall to 1 flattened. Omit and the behavior decides. |
| `tail` | `number` | — | Scripted tail carriage, −1 tucked under to 1 straight up. What the counterweight overrides. |
| `counterweight` | `number` | — | How much of the carriage the body takes, 0 scripted to 1 pure counterweight. At 1 the brush is entirely an output of the pitch. Omit and the behavior decides. |
| `ears` | `number` | — | Ears, −1 folded back to 1 pricked forward. Omit and they prick at the pointer. |
| `bearing` | `number` | — | Where the quarry is across the nose axis, −1..1 over ±75°. Both ears pan onto it. Omit and the pointer is the quarry. |
| `range` | `number` | — | How close the quarry is, 0 far off to 1 right in front. It is what makes the two ear axes converge. Omit and the pointer's height sets it. |
| `gaze` | `number` | — | Head and eye aim, −1..1. Omit and it follows the pointer. |
| `interactive` | `boolean` | `true` | The eyes track the pointer, the pointer is the quarry the ears aim at, and a click dives. |
| `onDive` | `() => void` | — | Fired on the click that dives. |
| `showGround` | `boolean` | `true` | The ground line and the shadow, which shrinks as the animal leaves the floor. |
| `showContacts` | `boolean` | `false` | Mark the paws carrying weight. |
| `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-fox.tsx`
