Purpose
Render a 2-3 option segmented control (e.g. Annual / Monthly) where the active option is highlighted by a sliding pill background. When the active option changes, the pill animates between option positions.
Params
{
"options": ["Annual", "Monthly"],
"active_index_keyframes": [
{ "atFrame": 0, "index": 0 },
{ "atFrame": 30, "index": 1 }
],
"container_bg": "#F5F3EE",
"container_radius_px": 28,
"container_padding_px": 6,
"pill_bg": "#0F0F0F", // contrasts container "pill_radius_px": 22,
"text_color_inactive": "#7A7A7A", "text_color_active": "#FFFFFF", "font_family": "Inter", "font_size_px": 22, "font_weight_active": 700, "font_weight_inactive": 500,
"slide_easing": "bezier(0.22, 1, 0.36, 1)", "slide_duration_frames": 14 }
## Behaviour
1. Render a horizontal flex container with N option `<span>`s and gap=0.
2. Compute each option's x-position from layout.
3. Render the pill as an absolutely-positioned `<div>` whose x animates between option positions per the keyframes.
4. Each option's text color animates between inactive/active states synchronized with the pill.
## Style pack overrides
- **SP-A (marshmallow)** — pricing scenes use this above the pricing cards.
- **SP-F (product-demo)** — UI panels often include this idiom.
## Quality Checks
- Pill width matches option width exactly (no overshoot beyond option text).
- Container padding equal on both sides of pill.
- Text color transition synchronizes with pill movement (active text becomes white as pill arrives).
## Failure Modes
- **Pill overshoots option bounds.** Use ease-out (not spring with bounce).
- **Text color flickers between states.** Use the same easing curve as pill x to sync transitions.
- **Pill renders below the text.** Z-index: text above pill, but text-color is light, pill-bg is dark.