> ## Documentation Index
> Fetch the complete documentation index at: https://hedgeem-api.qeetoto.com/llms.txt
> Use this file to discover all available pages before exploring further.

# F200v7 — Community Cards Scroll in Sync with Fences

> HEDGE-222: Community cards scroll in from the right at 400 px/s, docking next to their corresponding stage fence post (FLOP/TURN/RIVER).

# F200v7 — Community Cards Scroll in Sync with Fences

**Jira:** HEDGE-222
**Phase:** 3 (UI & Presentation)
**Status:** ✅ Implemented (V7 only)

***

## Business Rule

When the player advances to FLOP, TURN, or RIVER, the community cards for that stage
must visually arrive on screen in sync with the stage fence post. The player experiences
the cards "riding in" alongside the fence — reinforcing the metaphor that the board cards
are revealed as each hurdle is crossed.

* **FLOP:** 3 community cards arrive together (each docked to fence 3, the FLOP sign post)
* **TURN:** 1 community card arrives with the TURN sign post
* **RIVER:** 1 community card arrives with the RIVER sign post

Cards scroll in from off-screen right at the same 400 px/s as the fence posts. Each card
decelerates and docks at a fixed `x` position relative to its fence post's docked position.

***

## Technical Design

### DOM Structure

Five `.grass-card` elements are pre-created in `.posts-layer` at page load and hidden
(`display:none`). They are revealed and animated by `scrollInCard()` when the associated
fence reaches the viewport.

```
grassCardEls[0]  — FLOP card 1
grassCardEls[1]  — FLOP card 2
grassCardEls[2]  — FLOP card 3
grassCardEls[3]  — TURN card
grassCardEls[4]  — RIVER card
```

### Scroll Mechanism

`scrollInCard(cardEl, cardDockX)` attaches a `requestAnimationFrame` loop that moves the
card element leftward at `TRACK_PX_PER_SEC` (400 px/s) until it reaches `cardDockX`.
The card is placed in `.posts-layer`, which shares coordinate space with the fence rAF loop,
so both fence post and card travel at the same speed and appear anchored together.

```
startX = trackWidth (off-screen right edge)
each frame: x -= TRACK_PX_PER_SEC × dt
stop when: x <= cardDockX
```

### FLOP Sequence

FLOP spawns 3 fences sequentially, spaced `HORSE_GAP` (232 px) apart, to ensure horses
clear each fence before the next one appears:

| Fence index | Delay from Run click                               | Content                      | Card                 |
| ----------- | -------------------------------------------------- | ---------------------------- | -------------------- |
| 0           | 0ms                                                | Subtle semi-transparent post | —                    |
| 1           | `HORSE_GAP / TRACK_PX_PER_SEC × 1000` ms (\~580ms) | Subtle semi-transparent post | —                    |
| 2           | \~1160ms                                           | FLOP sign post (red)         | `grassCardEls[0..2]` |

All 3 FLOP cards scroll in simultaneously with fence 2.

### TURN / RIVER Sequence

Single fence spawned immediately on Run click:

| Stage | Post colour | Card element      |
| ----- | ----------- | ----------------- |
| TURN  | Orange      | `grassCardEls[3]` |
| RIVER | Blue        | `grassCardEls[4]` |

For RIVER, `spawnFinishFence()` is called \~580ms after the RIVER fence spawns, giving the
river card time to dock before the finish line arrives.

### onAllCleared Callback

Each stage fence is created with an `onAllCleared` callback. This fires when all active
(non-eliminated) horses have crossed the fence post. The callback triggers:

1. Horse probability positions updated from the new snapshot (`percentWin` values)
2. Eliminated horses (`percentWin <= 0`) begin their scroll-off sequence (F204v7)
3. `waitForHorsesSettled()` polling starts; Run button is re-enabled when horses settle

***

## Key Constants

| Constant            | Value             | Description                                                   |
| ------------------- | ----------------- | ------------------------------------------------------------- |
| `TRACK_PX_PER_SEC`  | `400`             | Scroll speed for fences, dirt tiles, and cards                |
| `HORSE_GAP`         | `232px`           | Gap between sequential FLOP fences (2 × horse SVG width)      |
| `POST_DOCK_X`       | `[98, 340, 474]`  | Docked x-position of FLOP / TURN / RIVER fence posts (px)     |
| `STAGE_CARD_END_PX` | `[332, 466, 600]` | Docked x-position of FLOP / TURN / RIVER community cards (px) |

***

## Acceptance Criteria

**AC1.** On FLOP Run click, 3 community card elements become visible and animate from the
right edge of the track toward `STAGE_CARD_END_PX[0]`.

**AC2.** All 3 FLOP cards begin their animation at the same time as fence 2 (the FLOP sign
post fence), not at fence 0 or fence 1.

**AC3.** Each FLOP card decelerates and stops precisely at its `STAGE_CARD_END_PX[0]`
position; it does not overshoot or continue scrolling.

**AC4.** On TURN Run click, 1 community card scrolls in and docks at `STAGE_CARD_END_PX[1]`
in sync with the TURN fence post.

**AC5.** On RIVER Run click, 1 community card scrolls in and docks at `STAGE_CARD_END_PX[2]`
in sync with the RIVER fence post.

**AC6.** The RIVER card finishes docking before the finish-line fence arrives (\~580ms later);
they do not visually collide.

**AC7.** Community cards and fence posts travel at exactly the same horizontal speed
(400 px/s); a card must never lead or trail its fence post horizontally during travel.

**AC8.** Community cards remain in their docked positions after the stage transition
completes; they are not removed or reset until the next HOLE (new round).
