# ADR-003: Long Lists Must Scroll the Root Document, Not a Nested Container

## Status

Accepted, 2026-06-25.

## Status History

```yaml
status_history:
  - date: 2026-06-25
    status: Proposed
    changed_by: hkl
    reason: Formalising pattern established after mobile scroll complaints
    changed_via: adr-kit (360lm)
  - date: 2026-06-25
    status: Accepted
    changed_by: hkl
    reason: Validated across PWAs with long lists and maps; no exceptions
    changed_via: adr-kit (360lm)
```

## Context

Early PWA implementations used `overflow: auto` on inner content `<div>` elements to create scrollable list areas below a sticky header and above a sticky footer. On mobile browsers (iOS Safari, Android Chrome) this causes two problems: (1) touch-scroll inside a nested overflow container is sluggish and sometimes unresponsive; (2) when a map or canvas is present alongside the list, the nested scroll clips visible rows and causes z-index conflicts. The browser's native momentum scrolling only works reliably on the root document.

## Decision

All long lists (store lists, ledgers, history screens, tour stop lists) MUST scroll the ROOT document. Chrome (`position: sticky`) must use `position: sticky` relative to the document root — not a parent overflow container. Never use `overflow: auto` or `overflow: scroll` on a container adjacent to a map or canvas widget.

**Decision Maker:** hkl

## Alternatives Considered

- **Nested overflow: auto div for list area.** Rejected: sluggish on mobile touch, clips rows adjacent to maps, requires explicit height calculations that break on different viewports.
- **Virtual scrolling (windowed list).** Rejected: over-engineered for current list sizes (< 500 rows in any PWA); introduces dependency and complexity not justified by performance needs at this scale. // ponytail: ceiling=500 rows, upgrade trigger=visible jank on real device
- **User-agent branching (different layout for mobile vs desktop).** Rejected: creates two code paths to maintain; root-document scroll works on both without branching.

## Consequences

**Positive:**
- Native momentum scrolling on all mobile browsers.
- Sticky header/footer works without explicit height calculations.
- Maps and canvas widgets render without z-index or clipping conflicts.

**Negative / Trade-offs:**
- Layout structure requires full-page design thinking (header + scrolling body + footer as siblings, not nested).
- Cannot use CSS `overflow: hidden` on `<body>` for modal effects without extra care.

**Risks and mitigations:**
- Modals that need to lock body scroll must use `body { overflow: hidden }` toggle — acceptable, established pattern used in hub and other PWAs.

## Related Decisions

- ADR-002 (safe-bottom CSS) — companion rule for mobile layout.

## References

- `memory/feedback_mobile_scroll.md` — original rule capture
