Skip to content

prototype scenarios

Prototype Scenarios — side panel surfaced by /flows

Section titled “Prototype Scenarios — side panel surfaced by /flows”

When a prototype captures multiple branching states (station mismatch, payment failure, battery conflict, etc.) that would be tedious to reach through linear in-device navigation, declare those states as scenarios on the flow entry in site/src/data/products.ts. The /flows page renders them as a side grid panel beside the iframe — the prototype itself stays a clean device-only shell per DESIGN.md §0.

products.ts /flows page prototype iframe
───────────── ─────────── ────────────────
scenarios: [ renders grid on init:
{ slug, name, → [icon|label] tiles → params.get('scenario')
icon, group }, ↓ click ↓ jumpTo(slug)
... iframe.src = ?scenario= set up state
]

The panel is NOT part of the prototype. The prototype receives state via the ?scenario=<slug> URL param. This keeps the device-only hard rule intact and makes scenarios reusable across multiple surfaces (e.g. an alternate “scenario explorer” tool could read the same data).

In site/src/data/products.ts, add a scenarios array to the relevant flow:

{
slug: 'support-cases-v2',
name: 'Support Cases (v2)',
// ...
kind: 'mobile',
scenarios: [
{ slug: 'dashboard', name: 'Dashboard', group: 'flows', icon: 'grid' },
{ slug: 'station-mismatch', name: 'Station mismatch', group: 'scenarios', icon: 'alert' },
{ slug: 'swap-complete', name: 'Swap complete', group: 'end-states', icon: 'check-circle' },
{ slug: 'reset', name: 'Reset flow', reset: true },
],
}

Fields on Scenario:

  • slug — must match the value the prototype’s jumpTo() function expects.
  • name — display label under the tile. Keep short (≤ 18 chars).
  • group — optional bucket: 'flows' | 'scenarios' | 'end-states'. Renders a small group label above the cluster.
  • icon — optional icon name from the curated set in site/src/pages/flows.astro SCENARIO_ICONS. Omit for a label-only tile.
  • reset — marks the special reset action. Renders as a separate full-width dark button at the bottom (not in the grid).
  • Width: 360px on desktop, 280px under 1100px. The panel sits to the right of the centered iframe, with a 48px gap.
  • Tiles: white surface, 1px #EBEBEB border, 14px radius, 14px × 10px padding. Three-column grid, 10px gap. Icon (36px circle) above 11.5px / 500 label.
  • Active tile (current scenario): #dcfbe2 background, #01E46F border, icon disc turns brand-green with white glyph.
  • Group label: 11px / 600 uppercase #838383, 0.08em tracking. Sits above each cluster.
  • Reset button: full-width below the grid, #202020 background, white text, 12px radius.
  • Hover: subtle lift (translateY(-1px)), softer shadow.

The prototype itself owns the state setup. Implement a jumpTo(slug) function that:

  1. Resets transient state (active sheets, intermediate flags, timers)
  2. Sets scenarioMode to the captured branch (e.g. 'mismatch', 'payment', 'bat-release')
  3. Calls goto(<screenId>) for the right starting screen
  4. Pre-applies any “after X” state (alerts hidden, status-cards approved, continue buttons revealed)

On init, read ?scenario=<slug> and call jumpTo(slug) if present. Reference implementation: products/rechaj-swap-app/prototypes/support-cases-v2.html.

  • An external scenarios panel inside the prototype HTML itself. Use the scenarios array → /flows rendering path instead. The prototype must remain a device-only shell when opened standalone.
  • Icons or labels that drift from the data declaration. The grid panel is fully driven by the array — don’t hand-edit the rendered DOM.
  • Adding scenarios that have no corresponding jumpTo() branch. Clicking would noop and break trust.