From 2ff5cbd4f5f6345a59cdd082bb7bffa0e1842bdd Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 11 Jun 2026 21:00:13 +0000 Subject: [PATCH] fix(viewer): make sidebar, card actions, title, and toast keyboard/SR accessible Session rows are focusable role=button elements activated with Enter/Space, with a visible focus ring and focus preserved across sidebar re-renders. Hover-only actions (session delete, card open/delete) are now reachable by keyboard and touch and shown via :focus-within. The contenteditable session title gets role=textbox, an aria-label, and Escape-to-cancel. Snippet iframes carry the snippet title; the toast is a polite live region. Visual design for mouse users is unchanged. https://claude.ai/code/session_01CPrjGf4zMKuvx43Vg9cr2o --- CHANGELOG.md | 6 ++++++ viewer/index.html | 54 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fccf0da..c6e8aa6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,12 @@ All notable user-visible changes to this project are documented in this file. - Comments not attached to a snippet (e.g. `sideshow comment` without `--snippet`) were stored and delivered to agents but never shown in the viewer; they now render in the session thread. +- The viewer is now usable by keyboard and assistive tech: session rows are + focusable and activate with Enter/Space (focus survives live re-renders), + hover-only actions (session delete, card open/delete) are reachable and + shown on focus, the editable session title is labeled and Escape cancels + an edit, snippet iframes carry the snippet title, and toasts are announced + via a polite live region. ## [0.2.0] - 2026-06-11 diff --git a/viewer/index.html b/viewer/index.html index f67ee3b..68afcd3 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -98,6 +98,10 @@ .sess:hover { background: var(--hover); } + .sess:focus-visible { + outline: 2px solid var(--accent); + outline-offset: -2px; + } .sess.sel { background: var(--surface); box-shadow: 0 0 0 0.5px var(--border); @@ -132,7 +136,7 @@ position: absolute; top: 8px; right: 6px; - display: none; + opacity: 0; border: none; background: none; color: var(--faint); @@ -142,10 +146,12 @@ border-radius: 5px; font-family: inherit; } - .sess:hover .x { - display: block; + .sess:hover .x, + .sess:focus-within .x { + opacity: 1; } - .sess:hover .dot { + .sess:hover .dot, + .sess:focus-within .dot { display: none; } .sess .x:hover { @@ -259,7 +265,8 @@ opacity: 0; transition: opacity 0.15s; } - .card:hover .act { + .card:hover .act, + .card:focus-within .act { opacity: 1; } .card-head .act:hover { @@ -459,14 +466,20 @@

or try it yourself

-
+