# Transit bus

An articulated city bus. Steer the front axle and the rear section's angle is solved from the hitch, so the tail swings out of a turn and comes back straight on its own.

> 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/transit-bus.json
```

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

## Notes

- Solved: the articulation angle, from `hitchAngle()`. The pivot rides a circle behind the drive axle and the towed axle cannot slide sideways, which fixes the angle between the sections. It is a steady state with no history, so a bus that has been round a roundabout comes out of it straight rather than unwinding.
- The concertina ribs belong half to each section, so the fold genuinely opens on the outside of the bend. The plug doors stand off the side before their leaves part, and the wheels stop turning while they are open.
- Illustrated: the kneel is a stated drop and roll on the doors' own number. No tyre model, no load, no swept-path envelope, and nothing integrates a manoeuvre.

## Usage

```tsx
import { TransitBus } from "@/components/ui/transit-bus"

<TransitBus behavior="route" />

// Plan is where the articulation reads. A stop is one number.
<TransitBus view="plan" steer={30} />
<TransitBus doors={1} behavior="service" />
```

## Props

| name | type | default | description |
| --- | --- | --- | --- |
| `view` | `"plan" | "front" | "profile" | "iso"` | `"profile"` | Where the camera stands. One bus, four projections: straight down, straight on, side elevation, or three-quarter from above. |
| `steer` | `number` | — | Front-axle steering in degrees, positive to starboard, clamped to ±42. Omit it and the behaviour drives it. |
| `onSteerChange` | `(steer: number) => void` | — | The commanded angle, while a person is steering it. |
| `doors` | `number` | — | Doors, 0 shut to 1 open. The bus kneels — and stops — on the same number, because a bus kneels to open and a bus with its doors open is standing. Omit it and the behaviour works the stop. |
| `behavior` | `"route" | "service" | "static"` | `"route"` | Running a route, or working a stop: pull in, kneel, open, stand, shut, pull away. |
| `articulated` | `boolean` | `true` | A rear section on a turntable, or one rigid body. Turning it off removes the hitch and the concertina. |
| `speed` | `number` | `0.3` | Steering 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` | Press and drag across the bus to steer it; arrow keys turn the rack 3° at a time. |
| `showGround` | `boolean` | `true` | The carriageway, and the kerb it pulls up to. |
| `active` | `boolean` | — | Light the destination sign. Omit and it lights in service. |
| `label` | `string` | — | Caption underneath the bus. |
| `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/transit-bus.tsx`
