# Blocking sled

Pads at a static equilibrium — the load's moment against a return spring's — on a frame that will not move at all until the drive beats the friction under its skids.

> 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/blocking-sled.json
```

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

## Notes

- The pad angle is a static equilibrium, found by bisection: the load's moment falls off as the cosine of the angle while the spring's climbs linearly, so there is exactly one crossing. That is why the last few degrees cost so much more than the first few.
- The frame is a threshold, not a ramp. Nothing happens until the drive beats the static friction under the skids; past that, the surplus is what accelerates it, and the readout says which side of the line the machine is on.
- Modelled once in the profile elevation and pushed through the camera, so the row of pads foreshortens from a raised camera rather than being redrawn per view.
- No impact and no impulse. The deflection is a static balance and the slide is a constant acceleration — a real hit is neither.

## Usage

```tsx
import { BlockingSled } from "@/components/ui/blocking-sled"

<BlockingSled behavior="drive" pads={5} />

// Controlled, or a sled you can lean on.
<BlockingSled load={0.8} stiffness={4000} weight={400} />
<BlockingSled interactive onLoadChange={setLoad} />
```

## Props

| name | type | default | description |
| --- | --- | --- | --- |
| `view` | `"plan" | "front" | "profile" | "iso"` | `"iso"` | Where the camera stands. One machine, four projections: straight down, straight on, side elevation, or three-quarter from above. |
| `load` | `number` | — | Controlled load on the pads, 0 to 1. Supplying it stops the loop. |
| `behavior` | `"drive" | "hit" | "recoil" | "idle" | "static"` | `"drive"` | What it does when load is not supplied. Recoil is a loaded pad let go, ringing back through its own spring. |
| `pads` | `number` | `3` | How many pads the frame carries, 1 to 5. |
| `stiffness` | `number` | `2600` | Return spring rate, torque per radian. Stiffer gives less ground for the same load. |
| `weight` | `number` | `220` | What the frame weighs, which is what has to be beaten before it moves at all. |
| `friction` | `number` | `0.62` | Static friction under the skids. |
| `speed` | `number` | `0.45` | Cycles per second. |
| `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` | `false` | Drag across to lean on it; let go and the springs take it back. |
| `onLoadChange` | `(load: number) => void` | — | The load throughout a drag or a key press. |
| `showGround` | `boolean` | `true` | Draw the contact shadow. |
| `label` | `string` | — | Caption below the readout. |
| `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/blocking-sled.tsx`
