Options Chain Redesign
Operator brief: "Options Chain is messy — clean it up, add row-action menu for Buy to Open / Sell to Open / Attach Strategy."
Screens mocked
| # | File | State |
|---|---|---|
| 1 | mockups/01-default-desktop.html |
Default desktop view — wide strike density, ITM highlighting, spot-pill marker |
| 2 | mockups/02-row-action-expanded.html |
$760 Call row selected — Pattern A inline action panel expanded |
| 3 | mockups/03-strategy-attach-picker.html |
"Attach Strategy" clicked — 3-card strategy sub-picker open; empty-state variant below |
| 4 | mockups/04-mobile-drawer.html |
Mobile 390px — Pattern B bottom sheet with full-width stacked action buttons |
Screenshots: screenshots/01-default-desktop.png through screenshots/04-mobile-drawer.png.
Key design decisions
Column reduction
Removed from the default view: CONTRACT, LAST, CHG, OI. Remaining per side:
CALLS: Bid | Ask | Vol | IV
STRIKE (center anchor)
PUTS: Bid | Ask | Vol | IV
Delta is dropped from the default column set — present in the existing implementation, but it requires a live Greeks feed that currently returns — for all rows. Hiding it avoids a wall of dashes. Can be added back as a column-toggle once data feeds are live.
CONTRACT moves from a main-grid column to a compact monospace badge inside the action panel. Power users who need the OCC symbol see it on row selection; the chain itself is no longer dominated by SPY26052900074000 strings.
OI can be added back via a column-toggle in a future pass.
Strike density
Default: Wide ($5 increments). A 3-way toggle [Wide] [Medium] [All] sits in the toolbar. "All" restores the current $1 density for power users who need it.
The spot marker becomes a dedicated moss-pill row — green dot + "Spot $757.56" — centered across the full table width with flanking ruled lines. Matches the moss-pill live-indicator brand pattern.
ITM / OTM visual treatment
ITM cells on each side get a moss-tinted background (rgba(91,140,90,0.10)). OTM cells are dimmed to --raxx-n-500 text, visually receding. The strike column always reads at full brightness; the ATM strike nearest spot reads in --raxx-moss-bright.
Bid prices use --raxx-loss (red). Ask prices use --raxx-gain (green). This is the conventional bid/ask color treatment — not loss/gain semantics — and is labeled as such in the column tooltips.
Row-action interaction pattern
Recommendation: hybrid — Pattern A on desktop, Pattern B on mobile.
Pattern A (desktop): Click a row → it highlights in moss-tint and immediately expands an inline sub-row directly below it. The sub-row shows: contract badge (OCC symbol), bid/ask quote detail, three action buttons. Pressing ✕ or clicking any other row collapses it. Zero modal overhead, fast.
Pattern B (mobile): Tap a row → a bottom sheet slides up with the contract title, a 4-cell quote grid (Bid, Ask, Vol, IV), and three full-width stacked action buttons. The bottom sheet pattern is standard touch-friendly disclosure and avoids the tiny-tap-target problem that an inline row expansion causes on 390px screens.
The three actions in both patterns:
| Button | Color | Action |
|---|---|---|
| Buy to Open | --raxx-gain green |
Routes to Order Ticket: ?contract=<OCC>&side=buy&action=open |
| Sell to Open | --raxx-loss red |
Routes to Order Ticket: ?contract=<OCC>&side=sell&action=open |
| Attach Strategy | --raxx-bronze-soft bronze |
Opens strategy sub-picker inline |
Strategy attachment
"Attach Strategy" expands a second tier within the same action panel (desktop) or pushes to a new bottom-sheet slide (mobile, not mocked — treat as a follow-up pass). The sub-picker renders the user's strategies as cards in a 3-column grid:
Name (bold)
Type pill (Neutral / Bullish / Protective / etc.)
1-2 line rule summary
Selecting a card highlights it; pressing "Attach + Route to Trade Window" navigates to:
/trade?strategy_id=<id>&contract=<OCC>&side=<buy|sell>&action=open
Empty state: if /api/strategies returns 0 strategies, the strategy picker renders a single empty-state card with a CTA button linking to /strategies. No grayed-out cards — per feedback_hide_dont_gray_unavailable_features.
CE skin
All colors use --raxx-* tokens from src/styles/brand.css. No hardcoded hex. The chain renders against --raxx-bg-2 (the app's card surface) with --raxx-bg-3 for the chain card body, matching the existing card elevation pattern in the shell.
The "today" expiry tab carries a moss-pill with a pulsing dot, matching the live-indicator brand pattern from feedback_moss_pill_live_indicator.
No predictions
Tooltips and labels describe mechanical facts only (Bid = price you receive if selling at market, etc.). Nothing in the design implies forward probability or outcome predictions.
Empty / loading / error states
The existing Options.js already handles:
- Loading spinner (no contracts yet)
- Error alert (dismissible)
- "No contracts returned" info alert
These states are not redesigned here; they inherit from the existing CE alert/spinner system and only need the column-reduction changes applied when the chain does load.
The one new empty state added: strategy picker with zero strategies — mocked in screen 3.
Interaction spec for feature-developer
Data shape assumptions
The mockups assume the current /api/options/contracts + buildOptionsChain() shape is unchanged. The new UI does not require new API endpoints.
// Per strike row (unchanged shape)
{
strike: number,
call: { symbol, bid, ask, volume, iv, tradable } | null,
put: { symbol, bid, ask, volume, iv, tradable } | null
}
The symbol field on call/put is the OCC code shown in the contract badge. Already present in the existing implementation.
Strategy attachment endpoint
Mockup assumes strategies are fetched from:
GET /api/strategies
→ [{ id, name, type, rules_summary, ... }]
If this endpoint doesn't exist yet, the "Attach Strategy" button must be gated on whether the strategies list endpoint is available (feature flag or empty-state handling).
URL routing on action buttons
Buy to Open: /trade?contract={OCC}&side=buy&action=open
Sell to Open: /trade?contract={OCC}&side=sell&action=open
Attach Strategy: /trade?contract={OCC}&side={buy|sell}&action=open&strategy_id={id}
The side for strategy attachment defaults to buy until the user specifies — the sub-picker could add a side toggle if needed. Current mockup assumes the user knows they're buying into the strategy.
State management
Selected row key: { expiration, strike, type } where type is call or put. The chain currently doesn't track side selection — this is new state the component needs.
Collapsing the inline panel: clicking another row, pressing Esc, or clicking ✕ closes the panel and clears selected row.
Column toggle (deferred)
OI and Delta can be re-added via a column visibility toggle (checkboxes in a gear popover). This is not part of the current mockup pass; treat as a follow-up.
Density toggle
The [Wide] [Medium] [All] toggle needs to filter currentChain.strikes by step:
- Wide: every 5th $1-increment strike (i.e., strike % 5 === 0)
- Medium: every 2nd (i.e., strike % 2 === 0)
- All: unchanged
Default: Wide.