fix(map): welcome banner no longer sits under the floating search toolbar

The 'New here?' banner was a later sibling of the absolute toolbar inside the
same map container, so it became the first in-flow child at y=0 and the floating
toolbar painted over it — the search bar covered the banner.

Move the banner to be the container's first child (above the toolbar) and have
the toolbar drop into flow when the banner is shown, so it can't cover it while
still floating over the map otherwise. Desktop is unchanged (md:static).

Docs: AGENTS.md map-layout note.
This commit is contained in:
SkateSpots 2026-10-01 12:31:30 +07:00
parent 257ce05a25
commit c1bf6516f5
2 changed files with 55 additions and 38 deletions

View file

@ -710,6 +710,13 @@ session with **no other memory of this project**. So:
re-add a stacked toolbar or the footer subtraction. The "New here?" welcome
banner (logged-out only) still occupies ~69px *in flow* on first visit — it's
dismissible and the dismissal is persisted (`skatespots_welcome_dismissed`).
⚠️ **The banner MUST be the first child of the map container, ABOVE the
toolbar** (fixed 2026-10-01). The toolbar is `absolute top-0` inside the same
container, so as a later sibling the banner sat at the container's top and the
floating toolbar **painted over it** (owner screenshot: search bar covering the
banner). Now the banner is first and the toolbar **drops into flow**
(`showWelcomeBanner ? 'relative border-b bg-black/95' : 'absolute …gradient'`)
so it can't cover it; `md:static` is unchanged on desktop.
⚠️ The floating toolbar sits over Leaflet's default **top-left zoom control**,
so `MapPage` passes `className="h-full ss-map-floating-toolbar"` and
`index.css` offsets `.leaflet-top.leaflet-left` by `4.25rem` **only under

View file

@ -1051,11 +1051,57 @@ export default function MapPage() {
{/* Full-height map container: subtract header + bottom nav on mobile, header only on desktop */}
{/* 100dvh handles iOS Safari URL bar shrink correctly */}
<div className="relative h-[calc(100dvh-var(--header-mobile)-var(--bottom-nav))] md:h-[calc(100vh-4rem)] flex flex-col">
{/* Welcome Banner — shown once to logged-out visitors. It lives ABOVE
the toolbar (both in flow) because the toolbar floats over the map:
as a later sibling the banner would sit at the container's top and
the floating toolbar would paint over it. */}
{showWelcomeBanner && (
<div className="relative z-10 bg-gradient-to-r from-[#ff0040]/90 via-black/95 to-[#ccff00]/20 border-b border-[#ff0040]/40 backdrop-blur">
<div className="container px-4 py-2.5 flex items-center gap-3">
<span className="text-xl flex-shrink-0">🛹</span>
<div className="flex-1 min-w-0">
<p className="text-sm font-black text-white uppercase tracking-wide leading-tight">New here?</p>
<p className="text-xs text-white/70 leading-tight">Discover skate spots, events &amp; the community.</p>
</div>
{/* Desktop-only: grab the mobile app via Zapstore */}
<a
href="https://zapstore.dev/apps/org.skatespots.app"
target="_blank"
rel="noopener noreferrer"
className="hidden md:inline-flex flex-shrink-0 items-center gap-1.5 px-3 py-1.5 rounded-full border-2 border-[#ccff00]/50 text-[#ccff00] text-xs font-black uppercase tracking-wide hover:bg-[#ccff00]/10 active:scale-95 transition-all"
>
<Smartphone className="h-3.5 w-3.5" />
Get on Zapstore
</a>
<Link
to="/onboarding"
className="flex-shrink-0 px-3 py-1.5 rounded-full bg-[#ccff00] text-black text-xs font-black uppercase tracking-wide hover:bg-[#ccff00]/90 active:scale-95 transition-transform"
>
Get Started
</Link>
<button
onClick={() => setWelcomeDismissed(true)}
className="flex-shrink-0 w-7 h-7 flex items-center justify-center rounded-full hover:bg-white/10 text-white/40 hover:text-white transition-colors"
aria-label="Dismiss"
>
<X className="h-3.5 w-3.5" />
</button>
</div>
</div>
)}
{/* ── Toolbar ──
Mobile: floats OVER the map (absolute) so the map fills the whole
screen; the gradient fades into the map and the transparent wrapper
passes touches through to it. Desktop keeps the in-flow bar. */}
<div className="pointer-events-none absolute inset-x-0 top-0 z-[1000] bg-gradient-to-b from-black/85 via-black/55 to-transparent pb-5 md:static md:z-auto md:border-b md:border-white/8 md:bg-black/95 md:pb-0 md:backdrop-blur">
passes touches through to it. Desktop keeps the in-flow bar. With the
welcome banner present it drops into flow so it can't cover it. */}
<div className={cn(
'pointer-events-none inset-x-0 top-0 z-[1000]',
showWelcomeBanner
? 'relative border-b border-white/8 bg-black/95'
: 'absolute bg-gradient-to-b from-black/85 via-black/55 to-transparent pb-5',
'md:static md:z-auto md:border-b md:border-white/8 md:bg-black/95 md:pb-0 md:backdrop-blur',
)}>
<div className="pointer-events-auto px-3 py-2">
{/* Single row: search pill + view toggle + filter button */}
<div className="flex items-center gap-2">
@ -1581,42 +1627,6 @@ export default function MapPage() {
</div>
</div>
{/* Welcome Banner — shown once to logged-out visitors */}
{showWelcomeBanner && (
<div className="relative z-10 bg-gradient-to-r from-[#ff0040]/90 via-black/95 to-[#ccff00]/20 border-b border-[#ff0040]/40 backdrop-blur">
<div className="container px-4 py-2.5 flex items-center gap-3">
<span className="text-xl flex-shrink-0">🛹</span>
<div className="flex-1 min-w-0">
<p className="text-sm font-black text-white uppercase tracking-wide leading-tight">New here?</p>
<p className="text-xs text-white/70 leading-tight">Discover skate spots, events &amp; the community.</p>
</div>
{/* Desktop-only: grab the mobile app via Zapstore */}
<a
href="https://zapstore.dev/apps/org.skatespots.app"
target="_blank"
rel="noopener noreferrer"
className="hidden md:inline-flex flex-shrink-0 items-center gap-1.5 px-3 py-1.5 rounded-full border-2 border-[#ccff00]/50 text-[#ccff00] text-xs font-black uppercase tracking-wide hover:bg-[#ccff00]/10 active:scale-95 transition-all"
>
<Smartphone className="h-3.5 w-3.5" />
Get on Zapstore
</a>
<Link
to="/onboarding"
className="flex-shrink-0 px-3 py-1.5 rounded-full bg-[#ccff00] text-black text-xs font-black uppercase tracking-wide hover:bg-[#ccff00]/90 active:scale-95 transition-transform"
>
Get Started
</Link>
<button
onClick={() => setWelcomeDismissed(true)}
className="flex-shrink-0 w-7 h-7 flex items-center justify-center rounded-full hover:bg-white/10 text-white/40 hover:text-white transition-colors"
aria-label="Dismiss"
>
<X className="h-3.5 w-3.5" />
</button>
</div>
</div>
)}
{/* Main Content */}
{/* `isolate` creates a stacking context so the map's internal z-indexes
(Leaflet panes, our overlays up to z-[2000]) stay INSIDE the map. Without