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

# Dual slalom

> Two-lane head-to-head timing with role-per-device.

Dual slalom (and 4X-style formats) need two lanes timed independently with millisecond precision. Each device joins the same session with a **role**.

<img src="https://mintcdn.com/time2bike/gd86sIECJkXq3-wr/images/timing/dual-salom.png?fit=max&auto=format&n=gd86sIECJkXq3-wr&q=85&s=e1533af6a2aa65522fa0394df520e800" alt="Dual slalom" width="2498" height="1662" data-path="images/timing/dual-salom.png" />

## Roles per device

* **Starter** — top of course.
* **Finisher (red)** — bottom of the red lane.
* **Finisher (blue)** — bottom of the blue lane.
* (Optional) **Marshal** — admin device for status corrections.

Three or four phones is normal; one per role.

## Starter flow

The starter screen shows an **On deck** panel with two plate inputs (red, blue). The starter:

1. Types the red plate.
2. Types the blue plate.
3. Presses the big **START** button when the gate drops.

This emits a `lane_start` event with `{ run, laneAssignments: [{ lane: 'red', participantId }, { lane: 'blue', participantId }], startTimestamp }`.

## Finisher flow

The finisher screen is a **single giant FINISH button** labeled with lane color and live elapsed time. The finisher's only job is to press FINISH when their lane's rider crosses.

This emits `lane_finish` with `{ laneStartId, lane, finishTimestamp }`. No participant selection during a run — that already happened at start time.

## Self-correct

If the finisher pressed early, they tap **CLEAR**. This emits `lane_clear` referencing the previous `lane_finish` (same `clientEventId`). The reducer un-resolves that finish; the lane clock is "live" again until the next press.

## Matchup view

Tap the trophy icon to see the current bracket match with both lanes side-by-side, current elapsed time, and final time once both lanes have finished. The reducer pairs the two lanes into a "match leg" automatically.

## Pause semantics

For slalom you usually want **frozenClock** (set at session create). Pausing the race stops everyone's elapsed clock — useful when there's a course hold.

## Precision

Slalom typically uses `displayPrecisionMs: 10` (hundredths). Storage stays at 1 ms.
