Raxx · internal docs

internal · gated

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.