# Safe Sticky Positioning

## Objective

Make sticky headers, bars, and panels behave consistently and stop fighting each other.

One shared approach to sticky elements, with a single source of truth for offsets and reserved space.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Inventory every element meant to stay put while its surroundings scroll — page headers, table header rows, section titles, filter bars, side panels, action bars — and route them all through one shared arrangement instead of the several that exist. The bottom-edge case is owned by Sticky Action Bar; this brief owns the mechanism and the offset arithmetic it draws on.
2. Keep a single source of truth for stacked offsets, so a header, a sub-header, and a sticky table row each know the measured height of what sits above them. A hardcoded pixel offset per screen guarantees drift the first time the header changes height.
3. Reserve the space a sticky element will occupy before it detaches, so nothing jumps at the moment it changes behaviour and no content is left hidden underneath it.
4. Below the narrow breakpoint, decide per element whether it stays, collapses to a smaller form, or unsticks entirely. On a short screen three stuck bars leave almost no room for the content they are framing.
5. Do not apply sticky positioning inside an ancestor that clips or scrolls its own overflow — the element will either be trapped or disappear. Detect that case during the audit and either fix the ancestor or move the element out of it.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- An ancestor with hidden or scrolling overflow silently breaks sticky positioning, and the symptom — an element that stays put on one page and scrolls away on another — is easy to misdiagnose as a styling problem.
- Without reserved space the page shifts by the element's height at the instant it sticks, which moves whatever the user was about to click.
- Two sticky elements that both claim the top edge will overlap. Offsets have to derive from measured heights so that a wrapping header or an incident banner pushes everything below it down.
- On a short viewport sticky chrome can consume most of the usable height, so measure the real visible area rather than assuming the window height, particularly with an on-screen keyboard open.
- Anchor navigation and in-page links must offset their scroll target by the sticky height, or the heading being jumped to lands underneath the header.
- Keyboard focus moving to an element just below a sticky header must not leave that element obscured; scrolling into view has to account for the occluded strip.
- A sticky element with a transparent or blurred background shows content sliding beneath it, which needs a deliberate treatment rather than being discovered in review.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] All sticky elements share one mechanism and one source of offsets.
- [ ] Stacked sticky elements never overlap, whatever height the header takes.
- [ ] Nothing shifts when an element transitions into or out of its stuck state.
- [ ] No sticky element sits inside an ancestor that clips or scrolls its overflow.
- [ ] Sticky behaviour is defined explicitly for narrow and for short viewports.
- [ ] Anchor links and focus scrolling land below the sticky chrome rather than under it.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
