Fix MR sticky header flicker on stacked merge requests

What does this MR do?

Fixes the merge request header flickering in Chrome while scrolling. The sticky header uses a scroll-state(stuck: top) container query to switch to the compact layout, so the stuck and unstuck versions must have exactly the same height. If they don't, switching the layout changes the page height, which unsticks the header again, and that repeats on every frame.

Fix merge request sticky header flicker (!221487 - merged) fixed this once by bumping the wrapper min-height from 88px to 89px. This time it's caused by the stacked merge requests dropdown ("1 of 4"). It's a 24px button that is baseline-aligned in the header row, so it sits about 1px lower than the rest of the row and makes the unstuck header 90.18px tall. The stuck header stays at the 89px minimum. Only merge requests that are part of a stack are affected, which is why it reproduced on a single merge request only.

The fix:

  1. Center the stack dropdown so the row is exactly 40px unstuck and 28px stuck. This also removes the -2px margin we had for the stuck state.
  2. Use a fixed height on the wrapper instead of min-height, so the two states can't diverge again when someone changes the header content.

Measured on feat(app): component registry with ordered star... (gitlab-org/rust/labkit-rs!105 - merged):

Unstuck Stuck Page scroll height (unstuck / stuck)
Before 90.18px 89px 1854px / 1853px
After 89px 89px 1853px / 1853px

#582356 (closed)

Reproduction steps

  1. In Chrome, open a merge request that is part of a stack (it has a "1 of 4" dropdown in the header), for example gitlab-org/rust/labkit-rs!105 (809f6a13)
  2. Make the window wide enough for the header to become sticky.
  3. Slowly scroll down until the header sticks.
  4. Before the fix the header keeps flickering between the two layouts at that scroll position. After the fix it switches once.

🤖 Generated with Claude Code

Merge request reports

Loading
Loading