diff --git a/frontend/e2e/accessibility.spec.ts b/frontend/e2e/accessibility.spec.ts index 5e4b1f2d..3603f5db 100644 --- a/frontend/e2e/accessibility.spec.ts +++ b/frontend/e2e/accessibility.spec.ts @@ -6,9 +6,9 @@ import { test, expect } from '@playwright/test'; * Authenticated pages use the stored admin session from playwright.config.ts. * The login page test overrides to an unauthenticated context. * - * On first run: if violations are found they are logged with full details so - * that they can be either fixed or explicitly excluded here with a comment - * explaining the reason. + * Known exclusion: + * color-contrast — brand palette (ink-3, text-ink/60) does not meet AA contrast + * ratios. Requires a design review with Leonie before fixing. Tracked separately. */ const AUTHENTICATED_PAGES = [ @@ -17,13 +17,17 @@ const AUTHENTICATED_PAGES = [ { name: 'admin', path: '/admin' } ]; +function buildAxe(page: Parameters[0]['page']) { + return new AxeBuilder({ page }).withTags(['wcag2a', 'wcag2aa']).disableRules(['color-contrast']); +} + test.describe('Accessibility — authenticated pages', () => { for (const { name, path } of AUTHENTICATED_PAGES) { test(`${name} page has no critical wcag2a/wcag2aa violations`, async ({ page }) => { await page.goto(path); await page.waitForSelector('[data-hydrated]'); - const results = await new AxeBuilder({ page }).withTags(['wcag2a', 'wcag2aa']).analyze(); + const results = await buildAxe(page).analyze(); if (results.violations.length > 0) { const summary = results.violations @@ -44,7 +48,7 @@ test.describe('Accessibility — login page', () => { await page.goto('/login'); await expect(page.getByLabel('Benutzername')).toBeVisible(); - const results = await new AxeBuilder({ page }).withTags(['wcag2a', 'wcag2aa']).analyze(); + const results = await buildAxe(page).analyze(); if (results.violations.length > 0) { const summary = results.violations diff --git a/frontend/src/routes/+error.svelte b/frontend/src/routes/+error.svelte new file mode 100644 index 00000000..4d70d933 --- /dev/null +++ b/frontend/src/routes/+error.svelte @@ -0,0 +1,12 @@ + + + + Fehler – Familienarchiv + + +
+

{page.status}

+

{page.error?.message ?? 'Internal Error'}

+
diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte index 51146422..88d5b2e7 100644 --- a/frontend/src/routes/+page.svelte +++ b/frontend/src/routes/+page.svelte @@ -67,6 +67,10 @@ $effect(() => { }); + + Archiv + +
{ type="file" multiple accept=".pdf,.jpg,.jpeg,.png,.tif,.tiff" + aria-label={m.upload_label()} class="sr-only" onchange={handleFileSelect} /> diff --git a/frontend/src/routes/SearchFilterBar.svelte b/frontend/src/routes/SearchFilterBar.svelte index 7b471b89..daa59c60 100644 --- a/frontend/src/routes/SearchFilterBar.svelte +++ b/frontend/src/routes/SearchFilterBar.svelte @@ -44,6 +44,7 @@ let { oninput={onSearch} onfocus={onfocus} onblur={onblur} + aria-label={m.docs_search_placeholder()} placeholder={m.docs_search_placeholder()} class="block w-full border-line py-2.5 pr-10 pl-3 placeholder-ink-3 shadow-sm focus:border-ink focus:ring-ink" /> diff --git a/frontend/src/routes/admin/+page.svelte b/frontend/src/routes/admin/+page.svelte index 89e494f0..cf50d953 100644 --- a/frontend/src/routes/admin/+page.svelte +++ b/frontend/src/routes/admin/+page.svelte @@ -11,6 +11,10 @@ let { data, form } = $props(); let activeTab = $state('users'); + + Administration + +

{m.admin_heading()}

diff --git a/frontend/src/routes/login/+page.svelte b/frontend/src/routes/login/+page.svelte index 96f0c920..83e6e7a9 100644 --- a/frontend/src/routes/login/+page.svelte +++ b/frontend/src/routes/login/+page.svelte @@ -9,6 +9,10 @@ const localeMap = { DE: 'de', EN: 'en', ES: 'es' } as const; const activeLocale = $derived(getLocale().toUpperCase()); + + Anmelden + +
diff --git a/frontend/src/routes/persons/+page.svelte b/frontend/src/routes/persons/+page.svelte index 779eff5c..9b02628e 100644 --- a/frontend/src/routes/persons/+page.svelte +++ b/frontend/src/routes/persons/+page.svelte @@ -23,6 +23,10 @@ function handleSearch() { } + + Personen + +