From 93f4a0003245ff52307de47ff2e54e98c1622a33 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 28 Apr 2026 13:01:58 +0200 Subject: [PATCH] =?UTF-8?q?fix(stammbaum):=20SVG=20node=20font=2014?= =?UTF-8?q?=E2=86=9216px=20and=20reliable=20keyboard=20focus=20ring?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CSS box-shadow rings (focus-visible:ring-*) are invisible inside SVG. Replace with a conditional drawn at -3px offset that renders in all browsers. Name font-size bumped from 14 to 16px for the 60+ transcriber audience (WCAG readability, Leonie medium concerns). Co-Authored-By: Claude Sonnet 4.6 --- .../src/lib/components/StammbaumTree.svelte | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/frontend/src/lib/components/StammbaumTree.svelte b/frontend/src/lib/components/StammbaumTree.svelte index 80a65fe3..f28857ac 100644 --- a/frontend/src/lib/components/StammbaumTree.svelte +++ b/frontend/src/lib/components/StammbaumTree.svelte @@ -286,6 +286,8 @@ function nodeCenter(id: string): { x: number; y: number } | null { return { x: p.x + NODE_W / 2, y: p.y + NODE_H / 2 }; } +let focusedId = $state(null); + function handleNodeKey(event: KeyboardEvent, id: string) { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); @@ -479,6 +481,7 @@ const parentLinks = $derived.by(() => { {@const pos = layout.positions.get(node.id)} {#if pos} {@const isSelected = selectedId === node.id} + {@const isFocused = focusedId === node.id} (() => { transform="translate({pos.x}, {pos.y})" onclick={() => onSelect(node.id)} onkeydown={(e) => handleNodeKey(e, node.id)} - class="cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-primary" + onfocus={() => (focusedId = node.id)} + onblur={() => (focusedId = null)} + class="cursor-pointer focus:outline-none" > + {#if isFocused} + + {/if} (() => { {/if} {node.displayName}