- account/+page.svelte: remove `aria-hidden="true"` from the
leave-confirm and data-mode-warning bottom-sheet backdrops. The
attribute cascaded into the dialog children, making the inner
Abmelden/Aktivieren/Abbrechen buttons unreachable in the accessibility
tree (and to Playwright's `getByRole`). Discovered while writing the
E2E suite; the visual layout is unchanged.
- join/+page.svelte: bump the PIN-copy button from `py-1` (28px tall) to
`min-h-11 min-w-11 py-2` so it clears the ≥44px touch-target floor on
mobile. Touch-target audit revealed the gap.
- data-testid attributes on stable interactive elements (join name input,
join submit, PIN modal + copy + continue, recovery PIN + submit + try-
different-name, admin login password + submit + error, recover name +
PIN + submit + error, upload header submit + sticky submit + caption
textarea). Targeted at ~20 spots where semantic locators were ambiguous
(e.g. two "Hochladen" buttons on /upload, German strings that may iterate).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wires up everything from the previous commits into actual UI surfaces, and
applies Tailwind dark: variants throughout. All pages now support the
'system' / 'light' / 'dark' preference set in the onboarding step or in
Mein Konto → Design.
Layout & nav:
- routes/+layout.svelte: initTheme(), global pin-reset SSE handler that
filters by user_id and calls clearPin(), one-shot /me/context fetch
on boot to hydrate privacyNote + quota.
- components/BottomNav.svelte: dark variants on the frosted-glass bar.
- components/UploadSheet.svelte: dark variants on backdrop, sheet,
source buttons.
- components/OnboardingGuide.svelte: new "Helles oder dunkles Design?"
step (3-option custom-radio grid), reactive currentStep with proper
type narrowing, dark variants throughout. Privacy-note nudge appears
on the PIN step only when one is configured.
Feed:
- routes/feed/+page.svelte: diashow entry icon (tablet/desktop only),
long-press → ContextSheet (Löschen for own posts, Original anzeigen
for all), upload-deleted + feed-delta SSE handlers, dark variants on
header, search, autocomplete, filter chips, empty states.
- components/FeedListCard.svelte: long-press wireup, double-tap-to-like,
data-mode-aware mediaSrc via pickMediaUrl, kebab fallback for desktop,
isOwn prop, dark variants.
- components/FeedGrid.svelte: long-press wireup, dark variants.
- components/LightboxModal.svelte: data-mode-aware src, double-tap heart
burst, dark variants on card / comments / input.
- components/HashtagChips.svelte: dark variants.
Account:
- routes/account/+page.svelte: theme picker (3-button radio grid), data
mode picker (with confirm sheet for Original), live quota widget,
preformatted Datenschutzhinweis block, diashow tile (mobile only),
pin now sourced from the $currentPin store so a global pin-reset
clears it live, clearQueue() on explicit logout, dark variants
across every card + both bottom sheets.
Upload:
- routes/upload/+page.svelte: per-user quota progress bar above the
submit button, dark variants.
Host & Admin:
- routes/host/+page.svelte: PIN-reset confirm + one-time PIN modal,
hosts may demote other hosts, canResetPinFor() helper, dark variants
on all cards, modals, stats, toast.
- routes/admin/+page.svelte: Config form rebuilt as CONFIG_GROUPS with
per-field kind (number / bool / text), renders toggles for the
rate-limit + quota switches and a textarea for the privacy_note;
Nutzer tab gains PIN reset + hosts-may-demote-hosts wiring; same
one-time PIN modal; dark variants everywhere.
- routes/admin/login/+page.svelte: dark variants.
Join / Recover / Export:
- routes/join/+page.svelte: rename inline link to
"Ich habe bereits einen Account", dark variants.
- routes/recover/+page.svelte: dark variants.
- routes/export/+page.svelte: dark variants on status cards + HTML
guide modal.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Persistent bottom tab bar (Feed · FAB · Account) on all authenticated pages
- Upload FAB triggers bottom sheet (Galerie / Kamera) → navigates to composer
- Upload page redesigned as full-screen composer with thumbnail strip, textarea,
quick-tag chips, sticky submit button; bottom nav suppressed while composing
- Slim upload progress bar above bottom nav driven by queue state
- Feed: list/grid view toggle; list = chronological full-width FeedListCard;
grid = 3-col with search bar, autocomplete from loaded posts, filter chips
- Account page: role-gated dashboard links (Host / Admin); Konto section with
leave-confirm bottom sheet; no more per-page header nav icons
- Host dashboard: back arrow, collapsible sections, 2-col stats, user search
- Admin dashboard: back arrow, inner tab bar (Stats/Config/Export/Nutzer),
stacked config inputs with sticky save, new Nutzer tab
- BottomNav hidden on unauthenticated pages via isAuthenticated store
- FeedGrid: threeCol prop; OnboardingGuide upload step updated for FAB
- Concept docs added to docs/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add in-app camera capture to the upload flow. Guests can now take photos
and record videos directly via getUserMedia without leaving the app.
The captured media is immediately queued through the existing IndexedDB
upload pipeline alongside library-picked files.
- CameraCapture.svelte: fullscreen overlay with live preview, photo
capture (JPEG via canvas), video recording (WebM/MP4 via MediaRecorder),
front/back camera toggle, recording timer, and permission-denied error state
- Upload page: side-by-side "Gallery" and "Camera" pickers; shared
caption/hashtags fields apply to both sources; Blob→File conversion
with timestamped filename before enqueue
- .env.test: reference environment config for local testing
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>