diff --git a/frontend/src/app.css b/frontend/src/app.css index 9cc6609..189ebaa 100644 --- a/frontend/src/app.css +++ b/frontend/src/app.css @@ -1 +1,18 @@ @import "./tailwind-theme.css"; + +/* + * Respect the OS "reduce motion" setting (WCAG 2.3.3 / 2.2.2). Neutralizes the + * decorative animations — Ken Burns zoom, slideshow crossfade, HeartBurst — and + * snaps transitions, which is a vestibular/migraine safeguard especially for the + * big-screen diashow. Auto-advance timing is additionally slowed in JS. + */ +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } +} diff --git a/frontend/src/app.html b/frontend/src/app.html index 7f3fa72..275bddd 100644 --- a/frontend/src/app.html +++ b/frontend/src/app.html @@ -2,7 +2,7 @@ - +
{#if comments.length === 0} -

Noch keine Kommentare.

+

Noch keine Kommentare.

{:else}
{#each comments as comment (comment.id)} @@ -173,7 +175,7 @@
{comment.uploader_name} {comment.body} -
{formatTime(comment.created_at)}
+
{formatTime(comment.created_at)}
{#if comment.user_id === userId}
{#if expiry} -

Sitzung gültig bis {formatDate(expiry)}

+

Sitzung gültig bis {formatDate(expiry)}

{/if}
@@ -334,7 +334,7 @@ style="width: {quotaPercent}%" > -

+

Geschätzt für {$quotaStore.active_uploaders} aktive Beitragende.

@@ -361,7 +361,7 @@ href="/recover" class="flex items-center gap-3 px-5 py-4 transition hover:bg-gray-50 dark:hover:bg-gray-700/50" > - + Gerät wechseln / PIN nutzen diff --git a/frontend/src/routes/admin/+page.svelte b/frontend/src/routes/admin/+page.svelte index f6adbe5..a8b68d8 100644 --- a/frontend/src/routes/admin/+page.svelte +++ b/frontend/src/routes/admin/+page.svelte @@ -412,7 +412,7 @@
{#if loading} -
Laden…
+
Laden…
{:else if error}
{error}
{:else} @@ -451,7 +451,7 @@ style="width: {diskPct(stats)}%" >
-

{formatBytes(stats.disk_free_bytes)} frei

+

{formatBytes(stats.disk_free_bytes)} frei

{/if} @@ -552,7 +552,7 @@ {#if exportJobs.length === 0} -

Noch keine Export-Jobs.

+

Noch keine Export-Jobs.

{:else}
{#each exportJobs as job} @@ -589,7 +589,7 @@
- +
{#if filteredUsers.length === 0} -

Keine Treffer.

+

Keine Treffer.

{:else}
{#each filteredUsers as user} @@ -618,7 +618,7 @@ Gesperrt {/if}
-

+

{user.upload_count} Upload{user.upload_count !== 1 ? 's' : ''} · {formatBytes(user.total_upload_bytes)}

diff --git a/frontend/src/routes/export/+page.svelte b/frontend/src/routes/export/+page.svelte index f97ab74..a23c58f 100644 --- a/frontend/src/routes/export/+page.svelte +++ b/frontend/src/routes/export/+page.svelte @@ -177,7 +177,7 @@
{#if loading} -
Laden…
+
Laden…
{:else if loadError}

Status konnte nicht geladen werden.

@@ -205,7 +205,7 @@

ZIP-Archiv

Alle Original-Fotos und Videos in strukturierten Ordnern.

-

+

{statusText(status.zip)}

@@ -232,7 +232,7 @@

HTML-Viewer

Schöne Offline-Galerie mit Filterung, Kommentaren und Likes — kein Internet nötig.

-

+

{statusText(status.html)}

diff --git a/frontend/src/routes/feed/+page.svelte b/frontend/src/routes/feed/+page.svelte index 10ca8a5..a7fe915 100644 --- a/frontend/src/routes/feed/+page.svelte +++ b/frontend/src/routes/feed/+page.svelte @@ -456,7 +456,7 @@
- + {item.value} @@ -590,7 +590,7 @@
{#if displayUploads.length === 0}
-

Keine Treffer für die gewählten Filter.

+

Keine Treffer für die gewählten Filter.

{:else} diff --git a/frontend/src/routes/host/+page.svelte b/frontend/src/routes/host/+page.svelte index de42bc5..d22f56d 100644 --- a/frontend/src/routes/host/+page.svelte +++ b/frontend/src/routes/host/+page.svelte @@ -288,7 +288,7 @@
{#if loading} -
Laden…
+
Laden…
{:else if error}
{error}
{:else if event} @@ -301,7 +301,7 @@ >

Statistiken

@@ -324,7 +324,7 @@

Uploads

-

+

{event.export_released ? 'Ja' : 'Nein'}

Freigegeben

@@ -341,7 +341,7 @@ >

Event-Einstellungen

@@ -376,7 +376,7 @@ >

Nutzerverwaltung

@@ -387,7 +387,7 @@
- +
{#if filteredUsers.length === 0} -

Keine Treffer.

+

Keine Treffer.

{:else}
{#each filteredUsers as user} @@ -416,7 +416,7 @@ Gesperrt {/if}
-

+

{user.upload_count} Upload{user.upload_count !== 1 ? 's' : ''} · {formatBytes(user.total_upload_bytes)}

diff --git a/frontend/src/routes/join/+page.svelte b/frontend/src/routes/join/+page.svelte index 3b434f4..d30b40e 100644 --- a/frontend/src/routes/join/+page.svelte +++ b/frontend/src/routes/join/+page.svelte @@ -100,10 +100,10 @@ // user doesn't have to chase the (now cosmetic) Anmelden button. function onRecoveryPinInput(e: Event) { const el = e.currentTarget as HTMLInputElement; - const cleaned = el.value.replace(/\D/g, '').slice(0, 4); + const cleaned = el.value.replace(/\D/g, '').slice(0, 6); if (cleaned !== el.value) el.value = cleaned; recoveryPin = cleaned; - if (recoveryPin.length === 4 && !recoveryLoading) { + if (recoveryPin.length === 6 && !recoveryLoading) { handleInlineRecover(); } } @@ -131,8 +131,9 @@ type="text" value={recoveryPin} oninput={onRecoveryPinInput} - placeholder="4-stelliger PIN" - maxlength={4} + aria-label="Wiederherstellungs-PIN" + placeholder="6-stelliger PIN" + maxlength={6} inputmode="numeric" pattern="[0-9]*" data-testid="recovery-pin-input" @@ -170,6 +171,7 @@

Keine Dateien ausgewählt

-

Geh zurück und tippe auf den Plus-Button.

+

Geh zurück und tippe auf den Plus-Button.