# Power lantern

A carried reservoir lantern in the old marine-lamp form — a ribbed prism barrel in a cage of bowed straps, with a round charge port on its face. Charge is moved rather than invented, the recital gates the transfer, the beam is paid for out of the reserve, and every part comes off in the reverse of the order it was fitted.

> 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/power-lantern.json
```

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

## Notes

- Charge is moved, not invented. `stepCharge` takes the reservoir, the ring's capacity and what the emitter is drawing, and what leaves one arrives in the other: the conduit is lit by what is actually flowing, which is why a full ring darkens it with the transfer still switched on.
- The `oath` behaviour solves its transfer rate from the ring's capacity and the length of the recital, so the ring is full on the last glyph rather than at a moment that was tuned to look right.
- The beam's reach is `√intensity` of full range, because illuminance falls off with the square of distance. Quarter power is half the distance, not a quarter of it. It leaves through the port, so it is a cone in the side and three-quarter views and a halo in the machine's own.
- Taking it apart is an ordered teardown, not a shell expanding: each part travels along the axis it was fitted along — the port and the ring forward off the face, the crown up, the cage straps out along their own radials — in the reverse of the order it was built in, and at exploded 0 every offset is exactly zero.
- One geometry through one camera: the exploded offsets are world vectors, and projection is linear, so the teardown is as truthful from iso as it is from the front elevation.
- Solved: the schedule, the transfer, the recital count, the gauge, the beam, the cage placement and its depth ordering. Illustrated: the glow, the glass, the knurl, the vents and the bolts. There is no thermal model and no discharge curve.
- The glyphs are abstract marks from a hash of the cell index — deterministic, and not language. An original archetype named for its job, with the proportions and the fittings taken from a period lantern rather than traced from it: no franchise name, insignia, oath or paint scheme here, in the demo, or in the defaults, and the emission colour is the theme's accent.

## Usage

```tsx
import { PowerLantern } from "@/components/ui/power-lantern"

<PowerLantern behavior="oath" ring="docked" />

// Take it apart: drag it, arrow-key it, or drive it yourself.
<PowerLantern exploded={0.65} view="iso" />
<PowerLantern interactive onExplodedChange={setApart} />

// Or put the drag on the reserve instead, and read the ring off the transfer.
<PowerLantern control="charge" interactive charge={reserve} cell={ring} />

// The emission colour is the theme's accent, and the accent is a prop.
<PowerLantern behavior="emit" accent="oklch(0.78 0.21 145)" />
```

## Props

| name | type | default | description |
| --- | --- | --- | --- |
| `view` | `"plan" | "front" | "profile" | "iso"` | `"front"` | Where the camera stands. One lantern, four projections: straight down, straight on, side elevation, or three-quarter from above. |
| `behavior` | `"charge" | "oath" | "emit" | "idle" | "service" | "static"` | `"charge"` | charge runs the transfer at a constant rate; oath gates it to the recital so the ring fills on the last glyph; emit runs the beam and pays for it; service takes the whole machine apart and puts it back; idle holds a reserve and breathes. |
| `charge` | `number` | — | Controlled reserve, 0 to 1. Supplying it pins the reservoir; the other channels keep running. |
| `onChargeChange` | `(charge: number) => void` | — | Fired through a drag or a key press while control is "charge", in controlled mode too. |
| `exploded` | `number` | — | Controlled teardown, 0 seated to 1 all the way apart. At 0 every part is exactly where it was assembled. |
| `onExplodedChange` | `(exploded: number) => void` | — | Fired through a drag or a key press while control is "exploded", in controlled mode too. |
| `ring` | `"none" | "presented" | "docked"` | `"docked"` | Where the ring is: away, held off the port, or seated in it. The port is on the machine’s face, so the ring reads head-on in the native view. Nothing docked closes the iris over the bore and stops the conduit. |
| `cell` | `number` | — | Controlled ring charge, 0 to 1 of the ring's own capacity — which is 12% of a full reservoir, because a ring is not a battery. |
| `recital` | `number` | — | Controlled recital, 0 to 1. It lights the collar a glyph at a time and gates the transfer. |
| `emission` | `number` | — | Controlled emitter power, 0 to 1. The reserve is the ceiling on it: an empty lantern emits nothing whatever it is asked for. |
| `ribs` | `number` | `8` | Straps in the cage, 4 to 12. They bow out over the barrel and a bay faces the front rather than a strap, so the port and the lit barrel are both visible. |
| `control` | `"exploded" | "charge"` | `"exploded"` | Which channel the drag and the arrow keys hold. The other goes on running off the behaviour. |
| `interactive` | `boolean` | `false` | Drag up to pull it apart (or to fill it); arrows step 5%, page keys 20%, Home seats it and End takes it all the way. Release eases back into the behaviour. |
| `speed` | `number` | `0.35` | 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. |
| `showGauge` | `boolean` | `true` | The segmented reserve gauge on the plinth. |
| `plate` | `string` | — | Stamped on the plinth nameplate, shown where the face is toward the camera. |
| `showGround` | `boolean` | `true` | Draw the contact shadow under the base. |
| `label` | `string` | — | Caption under the lantern. |
| `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/power-lantern.tsx`
