feat(images): responsive <Image>, gated private images + prose

Build-time image optimization plus auth-gated private content.

- <Image> (src/lib/components/Image.svelte): wraps @sveltejs/enhanced-img
  for public images under src/lib/assets/images/ (AVIF/WebP, multiple
  widths, lazy by default), plus a `private` mode for auth-gated images.
- Private images: scripts/build-private-images.ts encodes sources from
  src/lib/assets/private-images/ into private-assets/ (outside the bundle)
  and a manifest; served only via the auth-checked /private-images/
  endpoint (X-Accel-Redirect in prod, disk read in dev).
- HikeImage gains a `src` prose mode: build-hikes encodes non-waypoint
  images referenced in .svx and exposes them by filename (imagesByName);
  a `private` attr routes them through the gated /hikes/<slug>/private/ path.
- <Private> (src/lib/components/Private.svelte): renders prose only to
  logged-in viewers (cosmetic gating — text still ships in the bundle).
- deploy.sh rsyncs private-assets/; prod needs an nginx internal
  /protected-images/ location.
This commit is contained in:
2026-05-24 20:53:22 +02:00
parent 530308033b
commit 38c3df8187
17 changed files with 870 additions and 30 deletions
+6
View File
@@ -19,6 +19,12 @@ static/shopping/cumulus.svg
static/hikes/
hikes-assets/
src/lib/data/hikes.generated.ts
# Private image build outputs (regenerated by scripts/build-private-images.ts).
# Sources are private + large, so they're ignored too — only the README is kept.
private-assets/
src/lib/data/privateImages.generated.ts
src/lib/assets/private-images/*
!src/lib/assets/private-images/README.md
# Build-script disk caches (Swisstopo identify, BRouter responses, ...)
scripts/.cache/
# Loose working-tree scratch files (notes, photos, prototypes) that aren't