Correctness:
- MangaGridSkeleton: covers rendered 0px tall because height="0" is a
definite height that defeats aspect-ratio. Skeleton gains an `aspectRatio`
prop (height stays auto) so the 2/3 cover box is reserved and the grid no
longer shifts when real covers load.
- Move `.manga-card` layout into global tokens.css (it was scoped to
MangaCard, so the skeleton's cards inherited none of it). Both consumers
now share one definition.
- NavProgress: rebuilt as an idle/loading/done state machine. It now
completes to full and fades on settle (was snapping away instantly),
restarts the trickle when one navigation supersedes another (was parking
frozen near 90%), animates transform/opacity only with will-change gated to
the active phase, and hides itself in reader fullscreen.
- Skeleton: text-variant height resolved in one place (no inline style
shadowing a stylesheet rule); shimmer gradient/animation gated behind
prefers-reduced-motion: no-preference so reduced motion shows a flat block.
A11y:
- Home loading region announces via visually-hidden text instead of an
aria-label a live region won't reliably read.
Cleanup:
- Drop the fragile :first-child selector and index-keying ceremony in
MangaGridSkeleton; simplify Skeleton's style construction.
Tests: adds regression guards for the 0px cover collapse, the aspect-ratio
box, text-height defaulting, and the nav-progress complete/restart phases.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Most data routes run their load with ssr = false, so SvelteKit holds the
previous page on screen while the next one's data resolves — with no
feedback. NavProgress, mounted once in the root layout and driven by the
$navigating store, shows a thin top bar that trickles while a navigation is
pending and fades out on completion. Degrades to a static visible bar under
prefers-reduced-motion. New --z-nav-progress token sits above the fixed
header but below modals/toasts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>