diff --git a/frontend/src/lib/timeline/YearLetterStrip.svelte b/frontend/src/lib/timeline/YearLetterStrip.svelte
new file mode 100644
index 00000000..8409734c
--- /dev/null
+++ b/frontend/src/lib/timeline/YearLetterStrip.svelte
@@ -0,0 +1,52 @@
+
+
+
+
+ {m.timeline_letters_count({ count: letters.length })}
+
+
+
+
+
+ {#if expanded}
+
+ {#each letters as letter (letter.documentId)}
+
+ {/each}
+
+ {/if}
+
diff --git a/frontend/src/lib/timeline/YearLetterStrip.svelte.spec.ts b/frontend/src/lib/timeline/YearLetterStrip.svelte.spec.ts
new file mode 100644
index 00000000..4c78ea0e
--- /dev/null
+++ b/frontend/src/lib/timeline/YearLetterStrip.svelte.spec.ts
@@ -0,0 +1,42 @@
+import { describe, it, expect, afterEach } from 'vitest';
+import { cleanup, render } from 'vitest-browser-svelte';
+import { tick } from 'svelte';
+import YearLetterStrip from './YearLetterStrip.svelte';
+import { makeEntry } from './test-factories';
+
+afterEach(() => cleanup());
+
+function denseLetters(year: number, count: number) {
+ return Array.from({ length: count }, (_, i) =>
+ makeEntry({
+ eventDate: `${year}-${String((i % 12) + 1).padStart(2, '0')}-10`,
+ documentId: `doc-${i}`
+ })
+ );
+}
+
+describe('YearLetterStrip', () => {
+ it('shows the letter count and a 12-bar sparkline (REQ-012)', () => {
+ render(YearLetterStrip, { letters: denseLetters(1915, 30), year: 1915 });
+ expect(document.body.textContent).toContain('30');
+ const bars = document.querySelectorAll('[data-testid="sparkline-bar"]');
+ expect(bars).toHaveLength(12);
+ });
+
+ it('has a keyboard-focusable expand toggle of at least 44px (REQ-012)', () => {
+ render(YearLetterStrip, { letters: denseLetters(1915, 30), year: 1915 });
+ const toggle = document.querySelector('[data-testid="strip-expand"]') as HTMLButtonElement;
+ expect(toggle).not.toBeNull();
+ expect(toggle.tagName).toBe('BUTTON');
+ expect(toggle.getBoundingClientRect().height).toBeGreaterThanOrEqual(44);
+ });
+
+ it('reveals all letter cards when expanded (REQ-012)', async () => {
+ render(YearLetterStrip, { letters: denseLetters(1915, 30), year: 1915 });
+ expect(document.querySelectorAll('a').length).toBe(0);
+ const toggle = document.querySelector('[data-testid="strip-expand"]') as HTMLButtonElement;
+ toggle.click();
+ await tick();
+ expect(document.querySelectorAll('a').length).toBe(30);
+ });
+});