trackers: group cars, trains, planes and wildlife under one spotting tracker with /trackers/spotting landing page and category switcher
All checks were successful
Deploy production / deploy (push) Successful in 1m9s

This commit is contained in:
2026-10-25 12:08:38 +00:00
parent 5226ed7fec
commit d8490ce94f
14 changed files with 295 additions and 31 deletions

View File

@@ -0,0 +1,74 @@
<script lang="ts">
// Small switcher shown above the cars/trains/planes/wildlife pages (via their +layout),
// to hop between the spotting pokedexes or back to /trackers/spotting.
import { resolve } from '$app/paths';
import { page } from '$app/state';
import Binoculars from 'lucide-svelte/icons/binoculars';
import TrackerIcon from '#lib/components/TrackerIcon.svelte';
import { spottingTrackers } from '#lib/projects.js';
const active = $derived(
spottingTrackers.find(
(t) => page.url.pathname === t.href || page.url.pathname.startsWith(`${t.href}/`)
)?.name
);
</script>
<nav
aria-label="Spotting trackers"
class="relative mx-auto -mb-6 max-w-6xl px-4 pt-6 sm:-mb-8 sm:px-6 sm:pt-8"
>
<div class="flex flex-wrap items-center gap-1.5">
<a
href={resolve('/trackers/spotting')}
class="pill flex items-center gap-1.5 px-2.5 py-1.5 text-sm"
><Binoculars size={14} aria-hidden="true" class="text-[var(--site-muted)]" />spotting</a
>
<span class="mx-1 h-4 w-px bg-border" aria-hidden="true"></span>
{#each spottingTrackers as t (t.name)}
<a
href={resolve(t.href as '/')}
aria-current={active === t.name ? 'page' : undefined}
class="pill flex items-center gap-1.5 py-1 pr-2.5 pl-1 text-sm"
><TrackerIcon name={t.name} class="pill-icon size-6" />{t.name}</a
>
{/each}
</div>
</nav>
<style>
.pill {
border: 1px solid color-mix(in oklab, var(--foreground) 9%, transparent);
border-radius: 999px;
background: color-mix(in oklab, var(--foreground) 2%, transparent);
color: var(--foreground);
outline: none;
transition:
transform 160ms cubic-bezier(0.2, 0.8, 0.2, 1),
background-color 160ms ease,
border-color 160ms ease;
}
.pill:hover {
background: color-mix(in oklab, var(--foreground) 6%, transparent);
border-color: color-mix(in oklab, var(--foreground) 22%, transparent);
transform: translateY(-1px);
}
.pill:focus-visible {
outline: 2px solid var(--foreground);
outline-offset: 2px;
}
.pill[aria-current='page'] {
background: color-mix(in oklab, var(--foreground) 10%, transparent);
border-color: color-mix(in oklab, var(--foreground) 35%, transparent);
font-weight: 500;
}
.pill :global(.pill-icon) {
border-radius: 999px;
}
@media (prefers-reduced-motion: reduce) {
.pill,
.pill:hover {
transform: none;
}
}
</style>