diff --git a/frontend/messages/de.json b/frontend/messages/de.json
index 5642db93..8088ef6b 100644
--- a/frontend/messages/de.json
+++ b/frontend/messages/de.json
@@ -887,5 +887,11 @@
"bulk_edit_retry": "Erneut versuchen",
"bulk_edit_title": "Massenbearbeitung",
"bulk_edit_save_button": "Anwenden",
- "error_bulk_edit_too_many_ids": "Maximal 500 Dokumente pro Anfrage."
+ "error_bulk_edit_too_many_ids": "Maximal 500 Dokumente pro Anfrage.",
+ "form_label_archive_box": "Karton",
+ "form_helper_archive_box": "Welcher Karton im Archiv?",
+ "form_label_archive_folder": "Mappe",
+ "form_helper_archive_folder": "Welche Mappe innerhalb des Kartons?",
+ "bulk_edit_clear_selection": "Auswahl aufheben",
+ "bulk_edit_clear_hint_keyboard": "Esc: Auswahl aufheben"
}
diff --git a/frontend/messages/en.json b/frontend/messages/en.json
index 50f2399f..d5796dbf 100644
--- a/frontend/messages/en.json
+++ b/frontend/messages/en.json
@@ -887,5 +887,11 @@
"bulk_edit_retry": "Retry",
"bulk_edit_title": "Bulk edit",
"bulk_edit_save_button": "Apply",
- "error_bulk_edit_too_many_ids": "Maximum 500 documents per request."
+ "error_bulk_edit_too_many_ids": "Maximum 500 documents per request.",
+ "form_label_archive_box": "Box",
+ "form_helper_archive_box": "Which box in the archive?",
+ "form_label_archive_folder": "Folder",
+ "form_helper_archive_folder": "Which folder inside the box?",
+ "bulk_edit_clear_selection": "Clear selection",
+ "bulk_edit_clear_hint_keyboard": "Esc: clear selection"
}
diff --git a/frontend/messages/es.json b/frontend/messages/es.json
index 0cd956ab..2678eee0 100644
--- a/frontend/messages/es.json
+++ b/frontend/messages/es.json
@@ -887,5 +887,11 @@
"bulk_edit_retry": "Reintentar",
"bulk_edit_title": "Edición masiva",
"bulk_edit_save_button": "Aplicar",
- "error_bulk_edit_too_many_ids": "Máximo 500 documentos por solicitud."
+ "error_bulk_edit_too_many_ids": "Máximo 500 documentos por solicitud.",
+ "form_label_archive_box": "Caja",
+ "form_helper_archive_box": "¿Qué caja del archivo?",
+ "form_label_archive_folder": "Carpeta",
+ "form_helper_archive_folder": "¿Qué carpeta dentro de la caja?",
+ "bulk_edit_clear_selection": "Limpiar selección",
+ "bulk_edit_clear_hint_keyboard": "Esc: limpiar selección"
}
diff --git a/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte b/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte
index d9576c2c..57d21dd9 100644
--- a/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte
+++ b/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte
@@ -379,10 +379,12 @@ async function retrySave() {
>
{#if mode === 'edit'}
+ and that tags/receivers are added rather than replaced.
+ No aria-label — role=note + the visible text content is
+ self-describing; an aria-label would override that text for
+ AT users on non-DE locales. -->
diff --git a/frontend/src/lib/components/document/BulkSelectionBar.svelte b/frontend/src/lib/components/document/BulkSelectionBar.svelte
index 5a16897c..14e02c45 100644
--- a/frontend/src/lib/components/document/BulkSelectionBar.svelte
+++ b/frontend/src/lib/components/document/BulkSelectionBar.svelte
@@ -6,6 +6,7 @@ import { bulkSelectionStore } from '$lib/stores/bulkSelection.svelte';
let { canWrite }: { canWrite: boolean } = $props();
const count = $derived(bulkSelectionStore.size);
+const visible = $derived(canWrite && count > 0);
function openBulkEdit() {
goto('/documents/bulk-edit');
@@ -14,16 +15,37 @@ function openBulkEdit() {
function clearAll() {
bulkSelectionStore.clear();
}
+
+// Escape clears the selection — keyboard escape hatch when the user has
+// drilled into a 50-row selection and wants to bail without Tab-ing through
+// the whole footer (WCAG 2.1.1).
+function onEscape(e: KeyboardEvent) {
+ if (e.key === 'Escape' && visible) {
+ clearAll();
+ }
+}
-{#if canWrite && count > 0}
+
+
+{#if visible}
-
- {m.bulk_edit_n_selected({ count })}
-
+
+
+ {m.bulk_edit_n_selected({ count })}
+
+
+ {m.bulk_edit_clear_hint_keyboard()}
+
+
diff --git a/frontend/src/lib/components/document/FieldLabelBadge.svelte b/frontend/src/lib/components/document/FieldLabelBadge.svelte
index ac59e552..6a694dca 100644
--- a/frontend/src/lib/components/document/FieldLabelBadge.svelte
+++ b/frontend/src/lib/components/document/FieldLabelBadge.svelte
@@ -10,7 +10,7 @@ const text = $derived(
{text}
diff --git a/frontend/src/lib/components/document/FieldLabelBadge.svelte.spec.ts b/frontend/src/lib/components/document/FieldLabelBadge.svelte.spec.ts
index 9895e0c0..d52213ad 100644
--- a/frontend/src/lib/components/document/FieldLabelBadge.svelte.spec.ts
+++ b/frontend/src/lib/components/document/FieldLabelBadge.svelte.spec.ts
@@ -21,10 +21,8 @@ describe('FieldLabelBadge', () => {
.toHaveTextContent('wird ersetzt');
});
- it('uses text-gray-600 for WCAG-AA contrast on muted backgrounds', async () => {
+ it('uses the design-system text-ink-2 token (not raw Tailwind palette)', async () => {
render(FieldLabelBadge, { variant: 'replace' });
- await expect
- .element(page.getByTestId('field-label-badge-replace'))
- .toHaveClass(/text-gray-600/);
+ await expect.element(page.getByTestId('field-label-badge-replace')).toHaveClass(/text-ink-2/);
});
});
diff --git a/frontend/src/routes/documents/+page.svelte b/frontend/src/routes/documents/+page.svelte
index 4bc00f64..82effc6f 100644
--- a/frontend/src/routes/documents/+page.svelte
+++ b/frontend/src/routes/documents/+page.svelte
@@ -200,7 +200,13 @@ $effect(() => {
{m.nav_documents()} – Familienarchiv
-
+
+ 0 && data.canWrite}
+>
{m.nav_documents()}
-