Household pattern
AutonomyLadder
The three-rung control every capability sits on: Do it, Ask first, Never.
States
Do it
Reorder a staple
Buys things you already buy regularly, when they're about to run out.
Ask first
Reorder a staple
Buys things you already buy regularly, when they're about to run out.
Never
Reorder a staple
Buys things you already buy regularly, when they're about to run out.
Changed from default
one-tap reset
Reorder a staple
Buys things you already buy regularly, when they're about to run out.
Changed from Do it.
With ceilings beneath
move it off Do it and the ceilings sleep
Reorder a staple
Buys things you already buy regularly, when they're about to run out.
Each order
Up to $40 an order
Each week
Up to $120 a week
Small
Reorder a staple
Buys things you already buy regularly, when they're about to run out.
Read-only
Reorder a staple
Buys things you already buy regularly, when they're about to run out.
Disabled
Reorder a staple
Buys things you already buy regularly, when they're about to run out.
Highlighted (linked to)
Reorder a staple
Buys things you already buy regularly, when they're about to run out.
When to use
- For every capability in a contract, one ladder each. It is the primary control in the editor.
- Read-only, wherever a capability's rung needs to be shown next to something it governed.
When not to
- For on/off settings that are not about autonomy. Use Toggle.
- For hard rules. A hard rule is never a rung; it is a HardRule.
- For anything with more or fewer than three options. The ladder is the ladder.
Props
| Name | Type | Notes |
|---|---|---|
| label* | string | The capability as a household member would say it: "Reorder a staple". |
| value* | "do" | "ask" | "never" | The current rung. |
| onChange | (value) => void | Omit for a display-only ladder; pass readOnly too. |
| defaultValue | Autonomy | The template default. Shows "Changed from Ask first" with a one-tap reset. |
| description | string | One plain sentence about what the capability covers. |
| id | string | Anchor id, `cap-<capabilityId>`, so contract links can scroll here. |
| children | ReactNode | Ceilings go here. They render beneath a divider. |
| disabled / readOnly / highlighted / size | boolean | "sm" | "md" | State flags. `highlighted` is for the moment a contract link lands here. |
* required
Accessibility invariants
- A radiogroup labelled with the capability. Each rung is a radio with a hidden hint ("Prepares it, then waits for you").
- Roving tabindex: Tab lands on the selected rung; arrow keys and Home/End move between rungs and change the value.
- Colour is never the only signal: the selected rung carries its glyph, and the label is bold.
- The moving thumb is decorative and respects reduced motion.
Agent instructions
For anything generating UI from this system
Render one AutonomyLadder per capability, in the order the template lists them. Always pass label and value; pass onChange unless the surface is read-only, in which case pass readOnly. Put that capability's Ceiling components as children so they sit under their rung. Give it id="cap-" + capability.id so links from the timeline can find it. Do not add extra options, colour the rungs yourself, or use it for anything that is not a capability's autonomy.