feat: visual polish & UX — fade-in, theme toggle, scroll-to-top, footer, cursor, badge

- Add FadeIn component (IntersectionObserver scroll-reveal + load animation)
- Add dark/light theme toggle (useSyncExternalStore + localStorage)
- Add scroll-to-top button (appears after 300px scroll)
- Add configurable footer with social links (gallery.yaml)
- Add crosshair cursor on photo grid items
- Add 'X photos' count badge on subpage cover images
- Add light theme color palette in tokens.css
This commit is contained in:
ralksta
2026-02-14 11:47:26 +01:00
parent e26f091595
commit 52fa16c1c8
57 changed files with 4790 additions and 1984 deletions

View File

@@ -7,31 +7,23 @@ import Link from 'next/link';
import { immich } from '@/lib/immich';
export async function SubpageNav() {
const [subpages, standaloneAlbums] = await Promise.all([
immich.getSubpages(),
immich.getStandaloneAlbums(),
]);
const [subpages, standaloneAlbums] = await Promise.all([
immich.getSubpages(),
immich.getStandaloneAlbums(),
]);
return (
<>
{subpages.map((sp) => (
<Link
key={sp.slug}
href={`/${sp.slug}`}
className="header__nav-link"
>
{sp.name}
</Link>
))}
{standaloneAlbums.map((album) => (
<Link
key={album.id}
href={`/${album.slug}`}
className="header__nav-link"
>
{album.albumName}
</Link>
))}
</>
);
return (
<>
{subpages.map((sp) => (
<Link key={sp.slug} href={`/${sp.slug}`} className="header__nav-link">
{sp.name}
</Link>
))}
{standaloneAlbums.map((album) => (
<Link key={album.id} href={`/${album.slug}`} className="header__nav-link">
{album.albumName}
</Link>
))}
</>
);
}