> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sesameterminal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Price ladder

# Price ladder

A vertical book of one outcome's price levels where you place, move and cancel orders.
The same component appears in the desktop ladder dock (232 px column), in the market
view, inline in an expanded portfolio row, and as the mobile bottom sheet.

Phase 1 ships it read-only: same layout, clicks do nothing, no cursor tag, header
actions hidden.

## Model

* **Fixed levels.** One row per tick from the lowest to the highest valid price (tick
  0.01 → 99 rows, 1¢ to 99¢; tick 0.001 → 999 rows). Prices descend top to bottom. A
  price's row never moves; the book moves across the rows. Virtualised with a fixed row
  height (`--ladder-row-h`).
* **Columns:** P\&L-if-closed, Bid, Price, Ask. Bid sizes appear at levels at or below the
  best bid; ask sizes at or above the best ask. Rows in between are the spread.
* **Clicking a Bid cell buys at that row's price; clicking an Ask cell sells.** The
  colour of the column is the side you trade (tokens.md, "The colour rule"). A click at or
  through the touch fills against the book; the order is still a GTC limit at exactly
  that price.

## Desktop column (232 px wide, full dock height)

```
 ┌──────────────────────────────────────┐
 │ [LAL|BOS] Lakers v Celtics [pin] [x] │ 40  header row 1
 │ +120 sh at 41¢                +$4.80 │ 32  position row
 │ [Exit 39¢] [Hedge] [Cancel (3)]      │ 40  actions row
 │ Book live                   3s delay │ 28  status line (always present)
 │ (dot) 88–84 · Q3 4:12                │ 24  score line (game markets only)
 ├───────┬─────────┬───────┬────────────┤
 │  P&L  │   Bid   │ Price │    Ask     │ 24  column header (caption)
 ├───────┼─────────┼───────┼────────────┤
 │  +7.2 │         │   47  │ 820░░      │ 28
 │  +6.0 │         │   46  │ 1.4k░░░░   │ ← hovered row: [bell] at the P&L cell's left edge
 │  +4.8 │         │   45  │ 2.1k░░░░░░ │
 │  +3.6 │         │   44  │ 950░ [25]  │ ← your sell order chip, beside the size
 │  +2.4 │         │   43  │ 310░       │ ← best ask (weight 800)
 │  +1.2 │         │   42 |│            │ ← spread row (--muted bg), last trade notch
 │   0.0 │    ░░620│   41  │            │ ← best bid (weight 800)
 │  −1.2 │[25] ░1.8k   40  │            │ ← your buy order chip
 │  −2.4 │  ░░░░3.2k   39  │            │
 │  −3.6 │    ░░900│   38  │            │
 │   ...                                │
 ├──────────────────────────────────────┤
 │ [Stake $25]   Last 42¢    [crosshair]│ 32  footer
 └──────────────────────────────────────┘
   56       64        48       64    = 232
```

At 1440 × 900 with the bottom dock collapsed, the body shows about 22 levels
(820 − 196 px of header, column header and footer, at 28 px rows; a game market's score line
takes 24 px more).

### Header

| Row | Content | Details |
| - | - | - |
| 1 (40) | Outcome switch, market label, pin, close; controls at `--control-h` | Outcome switch first: one outlined segmented control for 2 outcomes (up to 3 on the phone sheet), a dropdown (at most 144 px) for more; the active segment is the only fill. Switching keeps the slot and re-centres. The segments take the room before the label: a game's outcomes read as team abbreviations (`LAL`, `BOS`) when the data has them, and a long name wraps to two lines before it truncates, with the full name in the tooltip. Market label (the market question) in `--muted-foreground` body-sm takes only the width left, truncated with the full question in the tooltip, and hides when under 48 px; click opens the market view. Pin (`[pin]` icon button) keeps the ladder from being replaced. Close (`[x]` icon button) |
| 2 (32) | Position and P\&L | `+120 sh at 41¢` (numeric), unrealised P\&L right-aligned, green or red and signed. `No position` in `--muted-foreground` when flat |
| 3 (40) | Actions, buttons at `--control-h` | **Exit 39¢**: the same action as the portfolio's Exit (one word for it everywhere, glossary.md): sell the whole position with a limit at the walk price (the lowest bid level needed to fill the size), and show that price; disabled when flat, stale or no bid. **Hedge**: buy the other outcome to lock P\&L; cursor tag shows `Buy 120 Celtics @ 57¢ · locks +$2.40`; two-outcome markets only (otherwise disabled with the reason). **Cancel (3)**: cancel all your orders in this market, `destructive-ghost`, disabled at 0 |
| Status line (28) | Always present, so nothing below it moves when its content changes | See below |
| Score line (24) | Game markets only: present for the ladder's whole life, whether the game is upcoming, live or over, so the rows never move | Score badge (compact): start time before the game; live dot, score and clock in play (`88–84 · Q3 4:12`); `Final` after. One line that never wraps or truncates: tennis shows every set without tiebreak points (`7-6, 6-7, 7-6, 6-7, 7-6 · S5 03:41`, 195 of 208 px), with the full score (`7-6(10-8), …`) in the tooltip; esports `Maps 1–1 · Bo5 · Map 3`. A stale score keeps its warning dot and muted text; the word `stale` goes to the status line, so the line never needs the width |

**Status line contents**, highest priority first. It shows one at a time; the delay text
sits on the right whenever the market has an in-play delay.

| Condition | Content | Style |
| - | - | - |
| Stale | `Stale 6s` | Warning fill |
| Orders wiped at start (5 min) | `3 orders cancelled at start` + `Re-post` + `[x]` (dismiss) | Warning fill |
| Pre-game with resting orders | `Starts in 8:04 · resting orders cancel at start` (the one start format: `in 12m` before the last 10 minutes) | Warning fill in the last 10 min, muted before |
| Tick change pending | `Tick now 0.001 · applies when pointer leaves` | Muted |
| Score stale (game markets, sports feed down) | `Score stale` | Muted |
| Otherwise | `Book live` | Muted |
| Delay (right side) | `3s delay` | Muted text, no box and no icon; it never shrinks, and the text on the left truncates first |

### Rows (28 px)

| Cell | Width | Content |
| - | - | - |
| P\&L | 56 | P\&L if your whole position closed at this price, before fees: `+4.8` / `−1.2` in compact dollars, green or red, right-aligned. Empty when flat, but **the column is always there**, so a fill never shifts the Bid and Ask columns. Its left 20 px hold the set-alert `[bell]` on the hovered row and the alert marker on levels with an alert ([alerts.md](alerts.md#from-a-ladder-level-one-click)); both are positioned absolutely and take no width from the value |
| Bid | 64 | Depth bar in `--bid-muted`, anchored to the right edge (`transform: scaleX`, origin right). Size right-aligned in `--bid`. Your buy chip at the left edge, beside the size in the same row: the two never overlap |
| Price | 48 | Centred, `--foreground`, no `¢`. Weight 800 on the best bid and best ask rows. Last trade: a small `--foreground` notch (5 × 8 px) at the price cell's right edge, vertically centred and pointing at the price |
| Ask | 64 | Mirror of Bid: bar anchored left, size left-aligned in `--ask`, your sell chip at the right edge |

* **Depth bar length** = level size ÷ the largest level within 20 ticks of the touch,
  capped at 1. It never tweens.
* Sizes and chips are compact in at most four characters (`1.2k`, `12k`, `66.7`), so a chip
  (at most 28 px) and a size (at most 27 px) fit a 64 px cell side by side; the exact sizes
  are in the row's accessible label and the orders table.
* Several of your orders at one level: one chip with the total. In the 64 px cells a second
  edge behind the chip, offset 2 px towards the cell's outer corner, marks it, and the tooltip
  says `2 orders`; the phone sheet's wider cells show `×2` after the size.
* Row states (hover, spread, stale, drag target) are in components.md.

### Footer (32)

`Stake $25` with `[chevron-down]` (a select: opens the preset list; same global stake as
the top bar), `Last 42¢`, and the re-centre button `[crosshair]` (icon button,
`--control-h`).

## Centring

* **On open:** centred instantly on the midpoint (or the last trade when one side is
  empty).
* **Manual:** `[crosshair]` button or `Space` (focused ladder). Instant jump, no smooth scroll.
* **Automatic (desktop only):** when the best bid or best ask comes within 3 rows of the
  visible edge or leaves the view, the ladder re-centres instantly, **only if** the
  pointer is not over the ladder and no drag is in progress. While the pointer is over
  it, the ladder stays put and an edge pill appears instead.
* **Edge pill:** 24 px, `--popover`, at the top or bottom of the body: `[arrow-up] Best ask 58¢`
  or `[arrow-down] Best bid 41¢`. Clicking it re-centres.
* **Mobile:** never re-centres by itself after opening. Only the edge pill and
  `[crosshair]`.
* **Tick size change:** the level grid is rebuilt. If the pointer is over the ladder (or
  a finger touched it in the last 1.5 s), the rebuild waits and the status line says
  so. Then it rebuilds and re-centres on the midpoint.

## Interactions

All input semantics are in [interactions.md](../interactions.md#ladder-desktop). In
short:

| Input | Action |
| - | - |
| Click Bid cell | Buy active stake at that price |
| Click Ask cell | Sell the stake's worth, capped at position |
| Shift+click Ask cell | Sell the whole position at that price |
| Click the `[bell]` on a hovered level, or Alt+click a Bid or Ask cell | Set a price alert at that level (one click; works in Safe) |
| Right-click a level with your orders | Cancel them |
| Drag your chip | Reprice |
| `B` `S` `Shift+B` `Shift+S` `F` `H` `C` `Space` `[` `]` `Delete` `1`–`6` `-` `=` | See the hotkey map |
| `↑` `↓` / `←` `→` / `Enter` / `Alt+Enter` / `Esc` | Move a keyboard cursor over levels / between Bid and Ask / act on that cell (armed) / set a price alert at its level / clear it |

Accessibility: each Bid and Ask cell is a `<button>` with a name such as
`Buy at 42 cents, stake $25, bid size 1,200`. The body uses a roving tabindex so the
ladder is one tab stop.

## Mobile bottom sheet (390 × 844)

Opens from a board card, watchlist row or portfolio card. The sheet's top sits under the
mobile header (y = top inset + 52), so Safe/Armed and Cancel all stay visible.

```
 ┌──────────────────────────────────────┐
 │ app header                           │ app header (not covered)
 ├──────────────────────────────────────┤ ← sheet top, --radius-xl corners
 │                (handle)              │ 20  handle
 │ [ Lakers | Celtics ]   [ellipsis] [x]│ 44  outcome switch, more, close
 │ +120 at 41¢ +$4.80    [Exit 39¢][x] 3│ 44  position + actions
 │ Book live                   3s delay │ 28  status line
 │ (dot) 88–84 · Q3 4:12                │ 24  score line (game markets only)
 ├──────┬───────────┬───────┬───────────┤
 │ P&L  │    Bid    │ Price │    Ask    │ 24
 ├──────┼───────────┼───────┼───────────┤
 │ +3.6 │           │  44   │ 950░ [25] │ 44
 │ +2.4 │           │  43   │ 310░      │ 44
 │ +1.2 │           │  42 | │           │ 44
 │  0.0 │      ░620 │  41   │           │ 44
 │ −1.2 │ [25] ░1.8k│  40   │           │ 44
 │ −2.4 │  ░░░░3.2k │  39   │           │ 44
 │  ...                                 │
 │     [arrow-down] Best bid 41¢        │ edge pill (when needed)
 ├──────────────────────────────────────┤
 │ [−] 40¢ [+]  [Add here]  [Cancel]    │ 44  order bar (only with a selected order; overlays the body)
 ├──────────────────────────────────────┤
 │ Stake $ [  10 |  25  |  50  | 100 ]  │ 44  stake bar
 │            (bottom safe area)        │
 └──────────────────────────────────────┘
   64       112        70       112  + 16 px side padding
```

* About 11 levels visible at 44 px rows on a 390 × 844 screen.
* Row 1 has no market label: the outcome switch takes the width beside `[ellipsis]` and
  `[x]`, with full outcome names. Row 2 buttons are 44 px tall. `[ellipsis]` opens an action
  sheet: Hedge, with its quote or the reason it is unavailable on the line under it, and
  Open market. Long-press a level for `Set alert at 42¢`.
* **Gestures:** the body scrolls natively; only the handle and header drag the sheet
  (vaul with handle-only dragging), so scrolling never dismisses it. Tap, long-press and
  the order bar are in interactions.md.
* The order bar overlays the bottom of the body instead of pushing it, so rows do not
  move when it appears.
* Closing: `[x]`, swipe down on the handle/header, or the system back gesture.
* Delay, pre-game and wipe states use the same status line as desktop.

## Stale, trading off and Safe

| State | Ladder |
| - | - |
| Stale | Status line `Stale 6s`; every row stale-styled; depth bars hidden; Bid/Ask clicks do nothing; Exit, Hedge and drag are disabled; **Cancel (N) and right-click cancel still work** |
| Safe | Normal look; clicks do nothing; cursor tag `Safe: arm to trade` |
| Trading off / geoblocked | Bid and Ask cells lose their hover fill, cursor `not-allowed`; header actions except Cancel disabled |
| Market resolved | Body replaced by the empty state `Resolved: Lakers`; header shows the position with `Claim on polymarket.com [external-link]` |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.