Bug: popup tip behind active pin
The popup that labels the active cafe pin opens with its tip pointing down at the pin's anchor. The tip is rendering behind the pin's body, breaking the visual connection between popup and the marker it's labelling.
Reproduction: open any cafe card → popup opens → inspect the popup tip area against the pin.
Attempted fixes (live in worktree worktree-temporal-riding-pudding)
src/styles/maplibre.css:
/* Lift the active marker wrapper above neighbour markers. */
.maplibregl-marker:has(.cafe-pin--active) {
z-index: 1000 !important;
}
/* Lift the popup above the active marker so the tip is in front. */
.maplibregl-popup { z-index: 1001 !important; }
The bare `.cafe-pin--active { z-index: 2 }` rule that pre-existed is a no-op — `.cafe-pin` is intentionally `position: static` (making it relative breaks MapLibre's translate-based positioning), and z-index has no effect on statically-positioned elements. The wrapper is `position: absolute` inline, so z-index applies there, hence the `:has()` selector targeting the wrapper.
What's still happening
After hard-refresh + a fresh `npm run build && npm run preview`, the popup tip is still visually behind the pin. CSS is confirmed served (verified via curl on the dev module).
Why the fix should work but doesn't
- `.maplibregl-marker` and `.maplibregl-popup` both set `will-change: transform`, so each is its own stacking context.
- Both are descendants of `.maplibregl-map`. When their z-indexes are compared at the common stacking-context ancestor, 1001 should beat 1000.
- `.maplibregl-popup-tip` itself has `z-index: 1` inside the popup's stacking context, which orders the tip above popup-content but doesn't bleed up to compete with siblings outside the popup.
Suspected reason for the failure: MapLibre may append the popup to a different DOM container than expected (e.g. inside `.maplibregl-canvas-container` rather than directly under `.maplibregl-map`), so the two elements end up in stacking contexts that don't compare the way the spec says they should.
Next investigation steps
- Inspect a live popup tip in DevTools and document:
- Parent and grandparent of `.maplibregl-popup`
- Computed `z-index` on `.maplibregl-popup` and on the active `.maplibregl-marker`
- Whether either has `isolation`, transform, or filter applied that makes a new stacking context
- If popup is parented inside canvas-container alongside markers, set z-index on the popup's actual containing block instead.
- As a fallback: assign z-index inline on the marker wrapper from JS when toggling `.cafe-pin--active`, and set inline z-index on the popup element on open. Inline styles bypass any cascade or specificity surprises.
Related work in the same branch
This issue surfaced while investigating the broader "map drag feels laggy / drops inputs on mobile and Safari" problem. That investigation also produced:
- `touch-action: none !important` on `.map-wrap` (necessary because MapLibre's `.maplibregl-map { touch-action: pan-x pan-y pinch-zoom }` was winning the cascade by being declared later).
- A `pendingPanRender` flag in `Locator.astro` that skips `document.startViewTransition` for renders triggered by user pans, on the theory that the VT was snapshotting the map canvas and freezing it visually for ~250ms.
- Removal of `transition: transform 0.15s ease-out` on `.cafe-pin` (MapLibre rewrites the inline transform every frame during pan; the transition made pins ease-chase the map and never settle).
- A 7-test Playwright suite in `tests/touch-drag.spec.ts` and `tests/touch-drag-blocking.spec.ts` covering the drag pattern across 5 viewports × 2 engines.
Trace mining of the user-supplied `Trace-20260415T185934.json` (684MB) showed the perceived drag lag is not in our app code: the renderer main thread had no tasks over 50ms. The compositor thread (tid 5593) had three multi-second stalls totalling ~7s. Contributing factors observed in that trace: V8 debugger attached (843k Debugger:: events, DevTools open), browser extensions injecting input listeners (`webauthn-listeners.js` fired 650 times), and 13k–17k UpdateLayer events per stall window correlated with viewport rotations. The test suite exercises a clean repro path and is green, but the user can still reproduce on Safari preview build, which suggests a remaining issue we haven't isolated yet.
Bug: popup tip behind active pin
The popup that labels the active cafe pin opens with its tip pointing down at the pin's anchor. The tip is rendering behind the pin's body, breaking the visual connection between popup and the marker it's labelling.
Reproduction: open any cafe card → popup opens → inspect the popup tip area against the pin.
Attempted fixes (live in worktree
worktree-temporal-riding-pudding)src/styles/maplibre.css:The bare `.cafe-pin--active { z-index: 2 }` rule that pre-existed is a no-op — `.cafe-pin` is intentionally `position: static` (making it relative breaks MapLibre's translate-based positioning), and z-index has no effect on statically-positioned elements. The wrapper is `position: absolute` inline, so z-index applies there, hence the `:has()` selector targeting the wrapper.
What's still happening
After hard-refresh + a fresh `npm run build && npm run preview`, the popup tip is still visually behind the pin. CSS is confirmed served (verified via curl on the dev module).
Why the fix should work but doesn't
Suspected reason for the failure: MapLibre may append the popup to a different DOM container than expected (e.g. inside `.maplibregl-canvas-container` rather than directly under `.maplibregl-map`), so the two elements end up in stacking contexts that don't compare the way the spec says they should.
Next investigation steps
Related work in the same branch
This issue surfaced while investigating the broader "map drag feels laggy / drops inputs on mobile and Safari" problem. That investigation also produced:
Trace mining of the user-supplied `Trace-20260415T185934.json` (684MB) showed the perceived drag lag is not in our app code: the renderer main thread had no tasks over 50ms. The compositor thread (tid 5593) had three multi-second stalls totalling ~7s. Contributing factors observed in that trace: V8 debugger attached (843k Debugger:: events, DevTools open), browser extensions injecting input listeners (`webauthn-listeners.js` fired 650 times), and 13k–17k UpdateLayer events per stall window correlated with viewport rotations. The test suite exercises a clean repro path and is green, but the user can still reproduce on Safari preview build, which suggests a remaining issue we haven't isolated yet.